messages
Provides configuration instructions for adding custom message types to the safe-output system.
Install
mkdir -p .claude/skills/messages && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/5777" && unzip -o skill.zip -d .claude/skills/messages && rm skill.zipInstalls to .claude/skills/messages
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Add new safe-output message types and wire validation/rendering.Key capabilities
- →Define new safe-output message schemas
- →Update Go compiler structs for messages
- →Create JavaScript rendering modules
- →Register message modules in Go embeddings
How it works
The skill guides the user through a multi-step process involving JSON schema updates, Go struct modifications, and JavaScript module creation.
Inputs & outputs
When to use messages
- →Add new message schema
- →Extend safe-output system
- →Define communication protocol updates
About this skill
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/compiler.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: Update the parser if needed
If the message needs custom parsing logic, update the workflow parser in pkg/workflow/safe_outputs.go or the relevant config block. Most simple string fields will be wired automatically by the existing reflection-based parser.
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/.
When not to use it
- →When modifying existing message logic without adding new types
Limitations
- →Requires manual build and test execution
How it compares
It provides a structured, verified workflow for extending the message protocol, ensuring consistency across the compiler and frontend.
Compared to similar skills
messages side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| messages (this skill) | 1 | 4mo | Review | Advanced |
| godot | 1,044 | 7mo | Review | Intermediate |
| software-architecture | 333 | 8mo | No flags | Intermediate |
| drizzle | 238 | 3mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by githubnext
View all by githubnext →You might also like
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
software-architecture
davila7
Guide for quality focused software architecture. This skill should be used when users want to write code, design architecture, analyze code, in any case that relates to software development.
drizzle
lobehub
Drizzle ORM schema and database guide. Use when working with database schemas (src/database/schemas/*), defining tables, creating migrations, or database model code. Triggers on Drizzle schema definition, database migrations, or ORM usage questions.
screenshot-to-code
OneWave-AI
Convert UI screenshots into working HTML/CSS/React/Vue code. Detects design patterns, components, and generates responsive layouts. Use this when users provide screenshots of websites, apps, or UI designs and want code implementation.
zustand
lobehub
Zustand state management guide. Use when working with store code (src/store/**), implementing actions, managing state, or creating slices. Triggers on Zustand store development, state management questions, or action implementation.
codex
Lucklyric
Invoke Codex CLI for complex coding tasks requiring high reasoning capabilities. This skill should be invoked when users explicitly mention "Codex", request complex implementation challenges, advanced reasoning, or need high-reasoning model assistance. Automatically triggers on codex-related requests and supports session continuation for iterative development.