messages
Add new safe-output message types and wire validation/rendering.
- License 许可
- MIT
- 所属仓库
- github/gh-aw
- 最近更新
- 2026-11-11
- Stars
- ★ 5.6k
- Forks
- 626
01 前言 Front Matter
- name
- messages
- description
- Add new safe-output message types and wire validation/rendering.
02 资源文件 4
- 参考文档sections/manifest.json676 B
- 参考文档sections/proposal-and-preview.md20.9 KB
- 其他sections/proposal-and-preview.md.tmpl16.0 KB
- 其他SKILL.md.tmpl9.3 KB
03 SKILL.md 正文
Adding New Message Types Guide
Use this guide to add a new safe-output message type so it works in the current gh-aw pipeline: frontmatter → schema → Go compiler → JavaScript modules → action/workflow build output.
Overview
The messages system lets workflow authors customize safe-output messages. The current architecture does not rely on the old pkg/workflow/js.go embedding registry for runtime shipping.
Current flow:
- Frontmatter (YAML)
- JSON Schema
- Go Compiler
- JavaScript module under
pkg/workflow/js/oractions/setup/js/ - Action/workflow bundle generation via
make actions-buildor the relevant workflow build path
Step 1: Update JSON Schema
Add the new message field to pkg/parser/schemas/main_workflow_schema.json in the messages object:
{
"messages": {
"properties": {
"my-new-message": {
"type": "string",
"description": "Description of when this message is used. Available placeholders: {placeholder1}, {placeholder2}.",
"examples": [
"Example message with {placeholder1}"
]
}
}
}
}
Key points:
- Use
kebab-casefor the YAML field name (for examplemy-new-message) - Document placeholders in the description
- Provide helpful examples
- Rebuild the schema-backed binary or run the relevant compile checks after changes
Step 2: Update Go Struct
Add the field to SafeOutputMessagesConfig in pkg/workflow/safe_outputs_config_types.go:
type SafeOutputMessagesConfig struct {
// ... existing fields ...
MyNewMessage string `yaml:"my-new-message,omitempty" json:"myNewMessage,omitempty"`
}
Key points:
- Use
CamelCasefor Go field names - Use
kebab-casefor YAML tags - Use
camelCasefor JSON tags - Add
omitemptyto both tags
Step 3: Wire the field in the parser
Add the field to parseMessagesConfig in pkg/workflow/safe_outputs_messages_config.go. Each field is mapped explicitly; simple string fields use extractStringFromMap:
config.MyNewMessage = extractStringFromMap(messagesMap, "my-new-message", nil)
Step 4: Create the JavaScript message module
Create the new module in the current shared JS location, typically pkg/workflow/js/:
// @ts-check
/// <reference types="@actions/github-script" />
const { getMessages, renderTemplate, toSnakeCase } = require("./messages_core.cjs");
/**
* @typedef {Object} MyNewMessageContext
* @property {string} placeholder1 - Description of placeholder1
* @property {string} placeholder2 - Description of placeholder2
*/
function getMyNewMessage(ctx) {
const messages = getMessages();
const templateContext = toSnakeCase(ctx);
const defaultMessage = "Default message with {placeholder1} and {placeholder2}";
return messages?.myNewMessage
? renderTemplate(messages.myNewMessage, templateContext)
: renderTemplate(defaultMessage, templateContext);
}
module.exports = {
getMyNewMessage,
};
Key points:
- File naming:
messages_<category>.cjs - Reuse
./messages_core.cjsfor shared helpers - Use JSDoc for types and default behavior
- Keep the default message sensible and deterministic
Step 5: Add tests
Create a matching test file, for example pkg/workflow/js/messages_my_new.test.cjs:
import { describe, it, expect, beforeEach, vi } from "vitest";
const mockCore = { warning: vi.fn() };
global.core = mockCore;
describe("getMyNewMessage", () => {
beforeEach(() => {
vi.clearAllMocks();
delete process.env.GH_AW_SAFE_OUTPUT_MESSAGES;
});
it("returns the default message when no custom template is configured", async () => {
const { getMyNewMessage } = await import("./messages_my_new.cjs");
const result = getMyNewMessage({ placeholder1: "value1", placeholder2: "value2" });
expect(result).toBe("Default message with value1 and value2");
});
it("uses the custom template when configured", async () => {
process.env.GH_AW_SAFE_OUTPUT_MESSAGES = JSON.stringify({ myNewMessage: "Custom: {placeholder1}" });
const { getMyNewMessage } = await import("./messages_my_new.cjs");
const result = getMyNewMessage({ placeholder1: "test", placeholder2: "ignored" });
expect(result).toContain("Custom: test");
});
});
Run the relevant tests with make test-js or the targeted Vitest file.
Step 6: Update the core JS type metadata and exports
Update the SafeOutputMessages typedef and the return object in pkg/workflow/js/messages_core.cjs, and re-export the message helper from pkg/workflow/js/messages.cjs.
Step 7: Wire it into the real build path
Do not add any new //go:embed entries to pkg/workflow/js.go for a normal message module. The current system packages JavaScript through the action-generation/build path.
Instead:
- keep the JS module in
pkg/workflow/js/or the relevant action folder, - update the action dependency map or action source if needed,
- rebuild the action bundle with
make actions-build.
Step 8: Use the message in consumer scripts
const { getMyNewMessage } = require("./messages_my_new.cjs");
const message = getMyNewMessage({
placeholder1: actualValue1,
placeholder2: actualValue2,
});
Step 9: Update documentation
Document the new message in the repo’s relevant safe-output docs, and keep the examples aligned with the current action-based JavaScript build flow.
Verification Checklist
Before committing a message change:
- [ ] Frontmatter and schema updated
- [ ] Go config/struct updated if needed
- [ ] JS module created under the correct source tree
- [ ] Tests added and passing
- [ ]
messages_core.cjsandmessages.cjsupdated if relevant - [ ] Generated action/build output refreshed when required
- [ ] No stale embedding instructions are introduced for the current action-based JS build flow
References
actions/README.md- current action-generation/build workflowpkg/workflow/js/messages_core.cjs- shared safe-output message helperspkg/workflow/js/messages.cjs- message exportspkg/parser/schemas/main_workflow_schema.json- schema source of truth
Update the Message Module Architecture table:
| Module | Purpose | Exported Functions |
|--------|---------|-------------------|
| `messages_my_new.cjs` | My new message description | `getMyNewMessage` |
Notes
For current gh-aw work, keep message modules aligned with the action-generation flow instead of the historical Go-embed pattern. If you need an example, review the existing safe-output modules under pkg/workflow/js/ and the generated action files under actions/.
04 同仓库更多 Skills
GitHub Agentic Workflows
GitHub Agentic Workflows (`gh-aw`) is a GitHub CLI extension for writing Agentic Workflows in markdown and compiling them to GitHub Actions.
windows-compatibility
Cross-platform path handling and command patterns
versioning-policy
Semver versioning rules for Squad SDK and CLI — prevents prerelease version incidents
tiered-memory
Three-tier agent memory model (hot/cold/wiki) for context reduction per spawn
test-discipline
Update tests when changing APIs — no exceptions
squad
Squad's command catalog and interactive menu. Invoke via /squad (slash command) or natural language ("squad commands", "what can squad do", "show me squad options"). Presents categorized operations (Install & Upgrade, Team Management, Issues & PRs, Plugins & Skills, Model & Cost, Sessions & State) as an interactive picker. Routes to the right squad CLI command or the Squad coordinator agent.