mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-11 02:33:51 +08:00
feat(flow-coordinator): add slashCommand/slashArgs support for unified workflow
- Add buildNodeInstruction() to construct instructions from slashCommand field
- Support slashArgs with {{variable}} interpolation
- Append additional instruction as context when slashCommand is set
- Update unified-workflow-spec.md with slashCommand/slashArgs documentation
This enables frontend orchestrator JSON to be directly consumed by
flow-coordinator skill in Claude client.
This commit is contained in:
@@ -43,6 +43,8 @@ Execution Modes:
|
|||||||
|
|
||||||
**Unified PromptTemplate Model**: All workflow steps are natural language instructions with:
|
**Unified PromptTemplate Model**: All workflow steps are natural language instructions with:
|
||||||
- `instruction`: What to execute (natural language)
|
- `instruction`: What to execute (natural language)
|
||||||
|
- `slashCommand`: Optional slash command name (e.g., "workflow:plan")
|
||||||
|
- `slashArgs`: Optional arguments for slash command (supports {{variable}})
|
||||||
- `outputName`: Name for output reference
|
- `outputName`: Name for output reference
|
||||||
- `contextRefs`: References to previous step outputs
|
- `contextRefs`: References to previous step outputs
|
||||||
- `tool`: Optional CLI tool (gemini/qwen/codex/claude)
|
- `tool`: Optional CLI tool (gemini/qwen/codex/claude)
|
||||||
@@ -137,18 +139,14 @@ async function executeDAG(workflow, order, state, statusPath) {
|
|||||||
continue; // Will be executed when dependencies complete
|
continue; // Will be executed when dependencies complete
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve context references
|
// Build instruction from slashCommand or raw instruction
|
||||||
const resolvedInstruction = resolveContextRefs(
|
let instruction = buildNodeInstruction(data, state.outputs);
|
||||||
data.instruction,
|
|
||||||
data.contextRefs || [],
|
|
||||||
state.outputs
|
|
||||||
);
|
|
||||||
|
|
||||||
// Execute based on mode
|
// Execute based on mode
|
||||||
state.nodeStates[nodeId] = { status: 'running' };
|
state.nodeStates[nodeId] = { status: 'running' };
|
||||||
write(statusPath, JSON.stringify(state, null, 2));
|
write(statusPath, JSON.stringify(state, null, 2));
|
||||||
|
|
||||||
const result = await executeNode(resolvedInstruction, data.tool, data.mode);
|
const result = await executeNode(instruction, data.tool, data.mode);
|
||||||
|
|
||||||
// Store output for downstream nodes
|
// Store output for downstream nodes
|
||||||
state.nodeStates[nodeId] = { status: 'completed', result };
|
state.nodeStates[nodeId] = { status: 'completed', result };
|
||||||
@@ -162,6 +160,36 @@ async function executeDAG(workflow, order, state, statusPath) {
|
|||||||
write(statusPath, JSON.stringify(state, null, 2));
|
write(statusPath, JSON.stringify(state, null, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build node instruction from slashCommand or raw instruction
|
||||||
|
* Handles slashCommand/slashArgs fields from frontend orchestrator
|
||||||
|
*/
|
||||||
|
function buildNodeInstruction(data, outputs) {
|
||||||
|
const refs = data.contextRefs || [];
|
||||||
|
|
||||||
|
// If slashCommand is set, construct instruction from it
|
||||||
|
if (data.slashCommand) {
|
||||||
|
// Resolve variables in slashArgs
|
||||||
|
const args = data.slashArgs
|
||||||
|
? resolveContextRefs(data.slashArgs, refs, outputs)
|
||||||
|
: '';
|
||||||
|
|
||||||
|
// Build slash command instruction
|
||||||
|
let instruction = `/${data.slashCommand}${args ? ' ' + args : ''}`;
|
||||||
|
|
||||||
|
// Append additional instruction if provided
|
||||||
|
if (data.instruction) {
|
||||||
|
const additionalInstruction = resolveContextRefs(data.instruction, refs, outputs);
|
||||||
|
instruction = `${instruction}\n\n${additionalInstruction}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return instruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: use raw instruction with context refs resolved
|
||||||
|
return resolveContextRefs(data.instruction || '', refs, outputs);
|
||||||
|
}
|
||||||
|
|
||||||
function resolveContextRefs(instruction, refs, outputs) {
|
function resolveContextRefs(instruction, refs, outputs) {
|
||||||
let resolved = instruction;
|
let resolved = instruction;
|
||||||
for (const ref of refs) {
|
for (const ref of refs) {
|
||||||
|
|||||||
@@ -48,6 +48,10 @@ interface PromptTemplateNodeData {
|
|||||||
label: string; // Display label in editor
|
label: string; // Display label in editor
|
||||||
instruction: string; // Natural language instruction
|
instruction: string; // Natural language instruction
|
||||||
|
|
||||||
|
// === Slash Command (optional, overrides instruction) ===
|
||||||
|
slashCommand?: string; // Slash command name (e.g., "workflow:plan")
|
||||||
|
slashArgs?: string; // Arguments for slash command (supports {{variable}})
|
||||||
|
|
||||||
// === Data Flow ===
|
// === Data Flow ===
|
||||||
outputName?: string; // Name for output reference
|
outputName?: string; // Name for output reference
|
||||||
contextRefs?: string[]; // References to previous outputs
|
contextRefs?: string[]; // References to previous outputs
|
||||||
@@ -63,6 +67,10 @@ interface PromptTemplateNodeData {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Instruction Resolution Priority**:
|
||||||
|
1. If `slashCommand` is set: `/{slashCommand} {slashArgs}` + optional `instruction` as context
|
||||||
|
2. Otherwise: `instruction` directly
|
||||||
|
|
||||||
### FlowEdge
|
### FlowEdge
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
|
|||||||
Reference in New Issue
Block a user