Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion hooks/hooks.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@
},
{
"type": "command",
"command": "node \"$CLAUDE_PLUGIN_ROOT\"/scripts/run.cjs \"$CLAUDE_PLUGIN_ROOT\"/scripts/persistent-mode.cjs",
"command": "node \"$CLAUDE_PLUGIN_ROOT\"/scripts/run.cjs \"$CLAUDE_PLUGIN_ROOT\"/scripts/persistent-mode.mjs",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep Stop hook on feature-parity implementation

Changing the Stop hook target to scripts/persistent-mode.mjs removes continuation safeguards for active Skill-tool workflows, because that script currently lacks the skill-active-state.json blocking path that exists in scripts/persistent-mode.cjs (the cjs implementation still enforces reinforcements before allowing stop). In sessions where skills like plan, code-review, or tdd are mid-flight, Stop can now pass through early and terminate the run before the skill finishes.

Useful? React with 👍 / 👎.

"timeout": 10
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { describe, expect, it } from 'vitest';
import { readFileSync } from 'fs';
import { join } from 'path';
import { ULTRAWORK_MESSAGE } from '../installer/hooks.js';

describe('issue #2652 runtime wiring and output contract', () => {
it('ships the Stop hook through persistent-mode.mjs', () => {
const hooksJsonPath = join(process.cwd(), 'hooks', 'hooks.json');
const hooks = JSON.parse(readFileSync(hooksJsonPath, 'utf-8')) as {
hooks?: Record<string, Array<{ hooks?: Array<{ command?: string }> }>>;
};

const stopCommands = (hooks.hooks?.Stop ?? [])
.flatMap((entry) => entry.hooks ?? [])
.map((hook) => hook.command ?? '');

expect(stopCommands.some((command) => command.includes('/scripts/persistent-mode.mjs'))).toBe(true);
expect(stopCommands.some((command) => command.includes('/scripts/persistent-mode.cjs'))).toBe(false);
});

it('ultrawork mode instructs spawned agents to keep outputs concise', () => {
expect(ULTRAWORK_MESSAGE).toContain('CONCISE OUTPUTS');
expect(ULTRAWORK_MESSAGE).toContain('under 100 words');
expect(ULTRAWORK_MESSAGE).toContain('files touched');
expect(ULTRAWORK_MESSAGE).toContain('verification status');
});
});
1 change: 1 addition & 0 deletions src/__tests__/ralph-prd-mandatory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ describe('Ralph PRD-Mandatory', () => {
expect(prompt).toContain('Are ALL requirements from the original task met?');
expect(prompt).toContain('Is the implementation complete, not partial?');
expect(prompt).not.toContain('Verify EACH acceptance criterion');
expect(prompt).toContain('concise review summary under 100 words');
});

it('should fall back to generic prompt when story is undefined', () => {
Expand Down
3 changes: 3 additions & 0 deletions src/hooks/autopilot/__tests__/pipeline.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ describe('Stage Adapters', () => {
expect(prompt).toContain('Team Mode');
expect(prompt).toContain('TeamCreate');
expect(prompt).toContain(EXECUTION_COMPLETION_SIGNAL);
expect(prompt).toContain('short execution summary under 100 words');
});

it('should generate solo prompt for solo mode', () => {
Expand All @@ -143,6 +144,7 @@ describe('Stage Adapters', () => {
});
expect(prompt).toContain('Solo Mode');
expect(prompt).toContain(EXECUTION_COMPLETION_SIGNAL);
expect(prompt).toContain('short execution summary under 100 words');
});
});

Expand All @@ -166,6 +168,7 @@ describe('Stage Adapters', () => {
});
expect(prompt).toContain('50');
expect(prompt).toContain(RALPH_COMPLETION_SIGNAL);
expect(prompt).toContain('concise review summary under 100 words');
});
});

Expand Down
14 changes: 14 additions & 0 deletions src/hooks/autopilot/__tests__/prompts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ describe("Prompt Generation", () => {
expect(prompt).toContain("Ralph");
expect(prompt).toContain("Ultrawork");
});

it("should require concise executor summaries", () => {
const prompt = getExecutionPrompt("plan.md");
expect(prompt).toContain("concise execution summary under 100 words");
expect(prompt).toContain("files touched");
expect(prompt).toContain("verification status");
});
});

describe("getQAPrompt", () => {
Expand All @@ -96,6 +103,13 @@ describe("Prompt Generation", () => {
expect(prompt).toContain("Security");
expect(prompt).toContain("Quality");
});

it("should require concise reviewer summaries", () => {
const prompt = getValidationPrompt("spec.md");
expect(prompt).toContain("concise review summary under 100 words");
expect(prompt).toContain("evidence highlights");
expect(prompt).toContain("files checked");
});
});

describe("getPhasePrompt", () => {
Expand Down
8 changes: 8 additions & 0 deletions src/hooks/autopilot/adapters/execution-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ Use the Team orchestrator to execute tasks in parallel:
4. **Monitor progress** as teammates complete tasks
5. **Coordinate** dependencies between tasks

### Output Contract

Every teammate response must stay concise: return ONLY a short execution summary under 100 words covering what changed, files touched, verification status, and blockers. Store bulky logs/details in files or artifacts and reference them briefly.

### Agent Selection

Match agent types to task complexity:
Expand Down Expand Up @@ -92,6 +96,10 @@ Execute tasks sequentially (or with limited parallelism via background agents):
3. Use executor agents for independent tasks that can run in parallel
4. Track progress in the TODO list

### Output Contract

Every spawned executor response must return ONLY a short execution summary under 100 words covering what changed, files touched, verification status, and blockers. Store bulky logs/details in files or artifacts and reference them briefly.

### Agent Spawning

\`\`\`
Expand Down
2 changes: 2 additions & 0 deletions src/hooks/autopilot/adapters/ralph-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ Verify the implementation against the specification using the Ralph verification
Spawn parallel verification reviewers:
Each reviewer must return ONLY a concise review summary under 100 words covering verdict, evidence highlights, files checked, and blockers. Avoid dumping long logs or transcripts into the main session.
\`\`\`
// Functional Completeness Review
Task(
Expand Down
3 changes: 3 additions & 0 deletions src/hooks/autopilot/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ Ralph and Ultrawork are now active. Execute tasks in parallel where possible.
- Spawn multiple executor agents for parallel work
- Track progress in the TODO list
- Use appropriate agent tiers based on task complexity
- Every spawned agent must return ONLY a concise execution summary under 100 words covering: what changed, files touched, verification status, and blockers. Do not paste long logs inline; write bulky output to files/artifacts and reference them briefly.

### Agent Spawning Pattern

Expand Down Expand Up @@ -316,6 +317,8 @@ Spawn parallel validation architects for comprehensive review.

Spawn all three architects in parallel:

Each reviewer must return ONLY a concise review summary under 100 words with verdict, evidence highlights, files checked, and blockers. Do not paste long transcripts or logs into the main session.

\`\`\`
// Functional Completeness Review
Task(
Expand Down
1 change: 1 addition & 0 deletions src/hooks/ralph/verifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ ${getVerificationAgentStep(state.critic_mode)}
- Are there any obvious bugs or issues?
- Does the code compile/run without errors?
- Are tests passing (if applicable)?
- Return ONLY a concise review summary under 100 words with verdict, evidence highlights, files checked, and blockers. Do not paste long logs inline.

3. **Based on ${criticLabel}'s response:**
- If APPROVED: Output the exact correlated approval tag \`${approvalTag}\`, then run \`/oh-my-claudecode:cancel\` to cleanly exit
Expand Down
1 change: 1 addition & 0 deletions src/installer/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ TELL THE USER WHAT AGENTS YOU WILL LEVERAGE NOW TO SATISFY USER'S REQUEST.
- **TODO**: Track EVERY step. Mark complete IMMEDIATELY after each.
- **PARALLEL**: Fire independent agent calls simultaneously via Task(run_in_background=true) - NEVER wait sequentially.
- **BACKGROUND FIRST**: Use Task tool for exploration/document-specialist agents (10+ concurrent if needed).
- **CONCISE OUTPUTS**: Every Task/Agent result must return ONLY a short execution summary (target: under 100 words) covering what changed, files touched, verification status, and blockers. Do not paste long logs into the main session; put bulky details in files/artifacts and reference them briefly.
- **VERIFY**: Re-read request after completion. Check ALL requirements met before reporting done.
- **DELEGATE**: Don't do everything yourself - orchestrate specialized agents for their strengths.

Expand Down
Loading