all-hands-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.allhands/README.md +75 -0
- package/.allhands/agents/compounder.yaml +15 -0
- package/.allhands/agents/coordinator.yaml +17 -0
- package/.allhands/agents/documentor.yaml +15 -0
- package/.allhands/agents/e2e-test-planner.yaml +17 -0
- package/.allhands/agents/emergent.yaml +22 -0
- package/.allhands/agents/executor.yaml +14 -0
- package/.allhands/agents/ideation.yaml +11 -0
- package/.allhands/agents/initiative-steering.yaml +19 -0
- package/.allhands/agents/judge.yaml +13 -0
- package/.allhands/agents/planner.yaml +19 -0
- package/.allhands/agents/pr-reviewer.yaml +15 -0
- package/.allhands/docs.json +5 -0
- package/.allhands/docs.local.json +26 -0
- package/.allhands/flows/COMPOUNDING.md +203 -0
- package/.allhands/flows/COORDINATION.md +89 -0
- package/.allhands/flows/CORE.md +87 -0
- package/.allhands/flows/DOCUMENTATION.md +218 -0
- package/.allhands/flows/E2E_TEST_PLAN_BUILDING.md +140 -0
- package/.allhands/flows/EMERGENT_PLANNING.md +57 -0
- package/.allhands/flows/IDEATION_SCOPING.md +154 -0
- package/.allhands/flows/INITIATIVE_STEERING.md +110 -0
- package/.allhands/flows/JUDGE_REVIEWING.md +79 -0
- package/.allhands/flows/PROMPT_TASK_EXECUTION.md +68 -0
- package/.allhands/flows/PR_REVIEWING.md +43 -0
- package/.allhands/flows/SPEC_PLANNING.md +216 -0
- package/.allhands/flows/harness/WRITING_HARNESS_FLOWS.md +27 -0
- package/.allhands/flows/harness/WRITING_HARNESS_KNOWLEDGE.md +27 -0
- package/.allhands/flows/harness/WRITING_HARNESS_ORCHESTRATION.md +27 -0
- package/.allhands/flows/harness/WRITING_HARNESS_SKILLS.md +27 -0
- package/.allhands/flows/harness/WRITING_HARNESS_TOOLS.md +27 -0
- package/.allhands/flows/harness/WRITING_HARNESS_VALIDATION_TOOLING.md +27 -0
- package/.allhands/flows/shared/CODEBASE_UNDERSTANDING.md +72 -0
- package/.allhands/flows/shared/CREATE_HARNESS_SPEC.md +48 -0
- package/.allhands/flows/shared/CREATE_SPEC.md +41 -0
- package/.allhands/flows/shared/CREATE_VALIDATION_TOOLING_SPEC.md +70 -0
- package/.allhands/flows/shared/DOCUMENTATION_DISCOVERY.md +123 -0
- package/.allhands/flows/shared/DOCUMENTATION_WRITER.md +101 -0
- package/.allhands/flows/shared/EMERGENT_REFINEMENT_ANALYSIS.md +76 -0
- package/.allhands/flows/shared/EXTERNAL_TECH_GUIDANCE.md +97 -0
- package/.allhands/flows/shared/IDEATION_CODEBASE_GROUNDING.md +49 -0
- package/.allhands/flows/shared/PLAN_DEEPENING.md +152 -0
- package/.allhands/flows/shared/PROMPT_TASKS_CURATION.md +113 -0
- package/.allhands/flows/shared/PROMPT_VALIDATION_REVIEW.MD +99 -0
- package/.allhands/flows/shared/QUICK_PREMORTEM.md +70 -0
- package/.allhands/flows/shared/RESEARCH_GUIDANCE.md +38 -0
- package/.allhands/flows/shared/REVIEW_OPTIONS_BREAKDOWN.md +68 -0
- package/.allhands/flows/shared/SKILL_EXTRACTION.md +84 -0
- package/.allhands/flows/shared/SPEC_FLOW_ANALYSIS.md +119 -0
- package/.allhands/flows/shared/TDD_WORKFLOW.md +109 -0
- package/.allhands/flows/shared/UTILIZE_VALIDATION_TOOLING.md +84 -0
- package/.allhands/flows/shared/WRITING_HARNESS_FLOWS.md +11 -0
- package/.allhands/flows/shared/WRITING_HARNESS_MCP_TOOLS.md +84 -0
- package/.allhands/flows/shared/jury/ARCHITECTURE_REVIEW.md +91 -0
- package/.allhands/flows/shared/jury/BEST_PRACTICES_REVIEW.md +80 -0
- package/.allhands/flows/shared/jury/CLAIM_VERIFICATION_REVIEW.md +101 -0
- package/.allhands/flows/shared/jury/EXPECTATIONS_FIT_REVIEW.md +78 -0
- package/.allhands/flows/shared/jury/MAINTAINABILITY_REVIEW.md +110 -0
- package/.allhands/flows/shared/jury/PROMPTS_EXPECTATIONS_FIT.md +74 -0
- package/.allhands/flows/shared/jury/PROMPTS_FLOW_ANALYSIS.md +92 -0
- package/.allhands/flows/shared/jury/PROMPTS_YAGNI.md +78 -0
- package/.allhands/flows/shared/jury/PROMPT_PREMORTEM.md +125 -0
- package/.allhands/flows/shared/jury/SECURITY_REVIEW.md +86 -0
- package/.allhands/flows/shared/jury/YAGNI_REVIEW.md +82 -0
- package/.allhands/flows/wip/DEBUG_INVESTIGATION.md +162 -0
- package/.allhands/flows/wip/MEMORY_RECALL.md +62 -0
- package/.allhands/harness/ah +131 -0
- package/.allhands/harness/package-lock.json +5292 -0
- package/.allhands/harness/package.json +52 -0
- package/.allhands/harness/src/__tests__/e2e/commands.test.ts +307 -0
- package/.allhands/harness/src/__tests__/e2e/event-loop.test.ts +539 -0
- package/.allhands/harness/src/__tests__/e2e/hooks.test.ts +427 -0
- package/.allhands/harness/src/__tests__/e2e/new-initiative-routing.test.ts +137 -0
- package/.allhands/harness/src/__tests__/e2e/run-e2e.ts +109 -0
- package/.allhands/harness/src/__tests__/e2e/specs-type.test.ts +210 -0
- package/.allhands/harness/src/__tests__/e2e/validation-hooks.test.ts +669 -0
- package/.allhands/harness/src/__tests__/e2e/validation-path-consistency.test.ts +354 -0
- package/.allhands/harness/src/__tests__/e2e/validation.test.ts +528 -0
- package/.allhands/harness/src/__tests__/harness/assertions.ts +318 -0
- package/.allhands/harness/src/__tests__/harness/cli-runner.ts +359 -0
- package/.allhands/harness/src/__tests__/harness/fixture.ts +384 -0
- package/.allhands/harness/src/__tests__/harness/hook-runner.ts +411 -0
- package/.allhands/harness/src/__tests__/harness/index.ts +122 -0
- package/.allhands/harness/src/cli.ts +36 -0
- package/.allhands/harness/src/commands/complexity.ts +177 -0
- package/.allhands/harness/src/commands/context7.ts +202 -0
- package/.allhands/harness/src/commands/docs.ts +557 -0
- package/.allhands/harness/src/commands/hooks.ts +24 -0
- package/.allhands/harness/src/commands/index.ts +51 -0
- package/.allhands/harness/src/commands/knowledge.ts +382 -0
- package/.allhands/harness/src/commands/memories.ts +302 -0
- package/.allhands/harness/src/commands/notify.ts +61 -0
- package/.allhands/harness/src/commands/oracle.ts +158 -0
- package/.allhands/harness/src/commands/perplexity.ts +220 -0
- package/.allhands/harness/src/commands/planning.ts +245 -0
- package/.allhands/harness/src/commands/schema.ts +73 -0
- package/.allhands/harness/src/commands/skills.ts +128 -0
- package/.allhands/harness/src/commands/solutions.ts +353 -0
- package/.allhands/harness/src/commands/spawn.ts +158 -0
- package/.allhands/harness/src/commands/specs.ts +532 -0
- package/.allhands/harness/src/commands/tavily.ts +226 -0
- package/.allhands/harness/src/commands/tools.ts +579 -0
- package/.allhands/harness/src/commands/trace.ts +327 -0
- package/.allhands/harness/src/commands/tui.ts +960 -0
- package/.allhands/harness/src/commands/validate.ts +143 -0
- package/.allhands/harness/src/commands/validation-tools.ts +108 -0
- package/.allhands/harness/src/hooks/context.ts +1442 -0
- package/.allhands/harness/src/hooks/enforcement.ts +170 -0
- package/.allhands/harness/src/hooks/index.ts +54 -0
- package/.allhands/harness/src/hooks/lifecycle.ts +229 -0
- package/.allhands/harness/src/hooks/notification.ts +104 -0
- package/.allhands/harness/src/hooks/observability.ts +551 -0
- package/.allhands/harness/src/hooks/session.ts +88 -0
- package/.allhands/harness/src/hooks/shared.ts +815 -0
- package/.allhands/harness/src/hooks/transcript-parser.ts +208 -0
- package/.allhands/harness/src/hooks/validation.ts +617 -0
- package/.allhands/harness/src/lib/__tests__/ctags.test.ts +244 -0
- package/.allhands/harness/src/lib/__tests__/docs-validation.test.ts +344 -0
- package/.allhands/harness/src/lib/__tests__/mcp-runtime.test.ts +190 -0
- package/.allhands/harness/src/lib/__tests__/schema.test.ts +861 -0
- package/.allhands/harness/src/lib/base-command.ts +198 -0
- package/.allhands/harness/src/lib/cli-daemon.ts +343 -0
- package/.allhands/harness/src/lib/compaction.ts +313 -0
- package/.allhands/harness/src/lib/ctags.ts +497 -0
- package/.allhands/harness/src/lib/docs-validation.ts +907 -0
- package/.allhands/harness/src/lib/event-loop.ts +662 -0
- package/.allhands/harness/src/lib/flows.ts +155 -0
- package/.allhands/harness/src/lib/git.ts +276 -0
- package/.allhands/harness/src/lib/knowledge-worker.ts +72 -0
- package/.allhands/harness/src/lib/knowledge.ts +810 -0
- package/.allhands/harness/src/lib/llm.ts +255 -0
- package/.allhands/harness/src/lib/mcp-client.ts +432 -0
- package/.allhands/harness/src/lib/mcp-daemon.ts +486 -0
- package/.allhands/harness/src/lib/mcp-runtime.ts +418 -0
- package/.allhands/harness/src/lib/notification.ts +115 -0
- package/.allhands/harness/src/lib/opencode/index.ts +70 -0
- package/.allhands/harness/src/lib/opencode/profiles.ts +300 -0
- package/.allhands/harness/src/lib/opencode/prompts/codesearch.md +98 -0
- package/.allhands/harness/src/lib/opencode/prompts/knowledge-aggregator.md +67 -0
- package/.allhands/harness/src/lib/opencode/runner.ts +281 -0
- package/.allhands/harness/src/lib/oracle.ts +926 -0
- package/.allhands/harness/src/lib/planning-utils.ts +150 -0
- package/.allhands/harness/src/lib/planning.ts +605 -0
- package/.allhands/harness/src/lib/pr-review.ts +225 -0
- package/.allhands/harness/src/lib/prompts.ts +522 -0
- package/.allhands/harness/src/lib/schema.ts +418 -0
- package/.allhands/harness/src/lib/schemas/agent-profile.ts +141 -0
- package/.allhands/harness/src/lib/schemas/template-vars.ts +138 -0
- package/.allhands/harness/src/lib/session.ts +164 -0
- package/.allhands/harness/src/lib/specs.ts +348 -0
- package/.allhands/harness/src/lib/tldr.ts +829 -0
- package/.allhands/harness/src/lib/tmux.ts +1051 -0
- package/.allhands/harness/src/lib/trace-store.ts +714 -0
- package/.allhands/harness/src/mcp/__tests__/index.test.ts +46 -0
- package/.allhands/harness/src/mcp/_template.ts +47 -0
- package/.allhands/harness/src/mcp/filesystem.ts +33 -0
- package/.allhands/harness/src/mcp/index.ts +69 -0
- package/.allhands/harness/src/mcp/playwright.ts +34 -0
- package/.allhands/harness/src/mcp/xcodebuild.ts +29 -0
- package/.allhands/harness/src/schemas/docs.schema.json +44 -0
- package/.allhands/harness/src/schemas/settings.schema.json +214 -0
- package/.allhands/harness/src/tui/actions.ts +227 -0
- package/.allhands/harness/src/tui/file-viewer-modal.ts +270 -0
- package/.allhands/harness/src/tui/index.ts +1574 -0
- package/.allhands/harness/src/tui/modal.ts +232 -0
- package/.allhands/harness/src/tui/prompts-pane.ts +186 -0
- package/.allhands/harness/src/tui/status-pane.ts +434 -0
- package/.allhands/harness/tsconfig.json +22 -0
- package/.allhands/harness/vitest.config.ts +13 -0
- package/.allhands/pillars.md +33 -0
- package/.allhands/principles.md +88 -0
- package/.allhands/schemas/alignment.yaml +51 -0
- package/.allhands/schemas/documentation.yaml +10 -0
- package/.allhands/schemas/prompt.yaml +92 -0
- package/.allhands/schemas/skill.yaml +34 -0
- package/.allhands/schemas/solution.yaml +131 -0
- package/.allhands/schemas/spec.yaml +67 -0
- package/.allhands/schemas/validation-suite.yaml +49 -0
- package/.allhands/schemas/workflow.yaml +51 -0
- package/.allhands/settings.json +57 -0
- package/.allhands/skills/claude-code-patterns/SKILL.md +60 -0
- package/.allhands/skills/claude-code-patterns/docs/context-hygiene.md +19 -0
- package/.allhands/skills/harness-maintenance/SKILL.md +449 -0
- package/.allhands/skills/harness-maintenance/references/core-architecture.md +187 -0
- package/.allhands/skills/harness-maintenance/references/harness-skills.md +87 -0
- package/.allhands/skills/harness-maintenance/references/knowledge-compounding.md +78 -0
- package/.allhands/skills/harness-maintenance/references/tools-commands-mcp-hooks.md +115 -0
- package/.allhands/skills/harness-maintenance/references/validation-tooling.md +77 -0
- package/.allhands/skills/harness-maintenance/references/writing-flows.md +84 -0
- package/.allhands/validation/browser-automation.md +109 -0
- package/.allhands/validation/xcode-automation.md +195 -0
- package/.allhands/workflows/documentation.md +86 -0
- package/.allhands/workflows/investigation.md +81 -0
- package/.allhands/workflows/milestone.md +91 -0
- package/.allhands/workflows/optimization.md +85 -0
- package/.allhands/workflows/refactor.md +99 -0
- package/.allhands/workflows/triage.md +81 -0
- package/.claude/README.md +1 -0
- package/.claude/agents/explorer.md +10 -0
- package/.claude/agents/researcher.md +11 -0
- package/.claude/agents/task-runner.md +8 -0
- package/.claude/settings.json +231 -0
- package/.env.ai.example +7 -0
- package/.github/workflows/npm-publish.yml +69 -0
- package/.internal.json +45 -0
- package/.tldr/config.json +11 -0
- package/.tldrignore +90 -0
- package/CLAUDE.md +6 -0
- package/README.md +98 -0
- package/bin/sync-cli.js +7552 -0
- package/concerns.md +7 -0
- package/docs/README.md +41 -0
- package/docs/agents/README.md +24 -0
- package/docs/agents/agent-configuration-system.md +86 -0
- package/docs/agents/execution-agents.md +50 -0
- package/docs/agents/knowledge-agents.md +61 -0
- package/docs/agents/orchestration-agent.md +57 -0
- package/docs/agents/planning-agents.md +84 -0
- package/docs/agents/quality-review-agents.md +67 -0
- package/docs/agents/workflow-agent-orchestration.md +69 -0
- package/docs/flows/README.md +44 -0
- package/docs/flows/compounding.md +126 -0
- package/docs/flows/coordination.md +72 -0
- package/docs/flows/core-harness-integration.md +63 -0
- package/docs/flows/documentation-orchestration.md +98 -0
- package/docs/flows/e2e-test-plan-building.md +83 -0
- package/docs/flows/emergent-refinement.md +104 -0
- package/docs/flows/flow-authoring-and-mcp-tools.md +89 -0
- package/docs/flows/judge-reviewing.md +112 -0
- package/docs/flows/plan-deepening-and-research.md +107 -0
- package/docs/flows/plan-review-jury.md +114 -0
- package/docs/flows/pr-reviewing.md +54 -0
- package/docs/flows/prompt-task-execution.md +119 -0
- package/docs/flows/spec-planning.md +162 -0
- package/docs/flows/type-specific-scoping-flows.md +49 -0
- package/docs/flows/validation-and-skills-integration.md +145 -0
- package/docs/flows/wip/wip-flows.md +102 -0
- package/docs/harness/README.md +23 -0
- package/docs/harness/agent-profiles.md +84 -0
- package/docs/harness/cli/README.md +24 -0
- package/docs/harness/cli/cli-entry-and-command-discovery.md +91 -0
- package/docs/harness/cli/docs-command.md +87 -0
- package/docs/harness/cli/knowledge-command.md +91 -0
- package/docs/harness/cli/minor-cli-commands.md +65 -0
- package/docs/harness/cli/oracle-command.md +113 -0
- package/docs/harness/cli/planning-command.md +95 -0
- package/docs/harness/cli/schema-and-validation-commands.md +154 -0
- package/docs/harness/cli/search-commands.md +97 -0
- package/docs/harness/cli/spawn-command.md +136 -0
- package/docs/harness/cli/specs-command.md +102 -0
- package/docs/harness/cli/tools-command.md +122 -0
- package/docs/harness/cli/trace-command.md +122 -0
- package/docs/harness/cli-daemon.md +92 -0
- package/docs/harness/event-loop.md +184 -0
- package/docs/harness/hooks/README.md +15 -0
- package/docs/harness/hooks/context-hooks.md +96 -0
- package/docs/harness/hooks/lifecycle-and-observability-hooks.md +135 -0
- package/docs/harness/hooks/validation-hooks.md +97 -0
- package/docs/harness/test-harness.md +149 -0
- package/docs/harness/tui.md +176 -0
- package/docs/memories.md +20 -0
- package/docs/solutions/agentic-issues/premature-agent-deletion-tui-action-dependency-20260130.md +49 -0
- package/docs/solutions/agentic-issues/ref-anchor-scope-mismatch-skill-references-20260131.md +55 -0
- package/docs/solutions/agentic-issues/tautological-tests-routing-20260131.md +52 -0
- package/docs/solutions/integration_issue/blocktool-output-format-mismatch-hook-runner-20260130.md +52 -0
- package/docs/solutions/integration_issue/dual-validation-path-divergence-schema-20260130.md +66 -0
- package/docs/solutions/security-issues/unsanitized-domain-path-join-20260131.md +52 -0
- package/docs/solutions/test-failures/event-loop-mock-ordering-checkAgentWindows-20260130.md +63 -0
- package/docs/sync-cli/README.md +19 -0
- package/docs/sync-cli/cli-entrypoint-and-commands.md +39 -0
- package/docs/sync-cli/commands/README.md +11 -0
- package/docs/sync-cli/commands/pull-manifest-command.md +36 -0
- package/docs/sync-cli/commands/push-command.md +84 -0
- package/docs/sync-cli/commands/sync-command.md +71 -0
- package/docs/sync-cli/systems/README.md +14 -0
- package/docs/sync-cli/systems/git-and-github-integration.md +49 -0
- package/docs/sync-cli/systems/interactive-ui.md +43 -0
- package/docs/sync-cli/systems/manifest-and-distribution.md +51 -0
- package/docs/sync-cli/systems/path-resolution.md +42 -0
- package/package.json +46 -0
- package/scripts/install-shim.sh +40 -0
- package/scripts/pre-pack.sh +25 -0
- package/specs/harness-maintenance-skill.spec.md +138 -0
- package/specs/roadmap/git-spec-lifecycle-management.spec.md +113 -0
- package/specs/sync-init-flag.spec.md +117 -0
- package/specs/unified-workflow-orchestration.spec.md +250 -0
- package/specs/validation-tooling-practice.spec.md +98 -0
- package/specs/workflow-domain-configuration.spec.md +265 -0
- package/src/commands/pull-manifest.ts +31 -0
- package/src/commands/push.ts +344 -0
- package/src/commands/sync.ts +289 -0
- package/src/lib/constants.ts +10 -0
- package/src/lib/dotfiles.ts +36 -0
- package/src/lib/fs-utils.ts +18 -0
- package/src/lib/gh.ts +40 -0
- package/src/lib/git.ts +63 -0
- package/src/lib/gitignore.ts +167 -0
- package/src/lib/manifest.ts +121 -0
- package/src/lib/marker-sync.ts +39 -0
- package/src/lib/paths.ts +38 -0
- package/src/lib/target-lines.ts +66 -0
- package/src/lib/ui.ts +78 -0
- package/src/sync-cli.ts +120 -0
- package/target-lines.json +23 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Hooks for schema validation of frontmatter, language-specific diagnostics (pyright, ruff, tsc), and code formatting enforcement on file writes."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Validation Hooks
|
|
6
|
+
|
|
7
|
+
Validation hooks enforce structural correctness at write time. They intercept file creation and editing to run schema checks, type diagnostics, and formatting rules, surfacing errors to agents before bad content reaches the repository.
|
|
8
|
+
|
|
9
|
+
## Diagnostics Pipeline
|
|
10
|
+
|
|
11
|
+
[ref:.allhands/harness/src/hooks/validation.ts:runDiagnostics:0e448c6] is the orchestrator. It dispatches to language-specific diagnostic runners based on file extension:
|
|
12
|
+
|
|
13
|
+
| Language | Runner | Tool | File Extensions |
|
|
14
|
+
|----------|--------|------|----------------|
|
|
15
|
+
| Python | [ref:.allhands/harness/src/hooks/validation.ts:runPyrightDiagnostics:0e448c6] | pyright | `.py` |
|
|
16
|
+
| Python | [ref:.allhands/harness/src/hooks/validation.ts:runRuffDiagnostics:0e448c6] | ruff | `.py` |
|
|
17
|
+
| TypeScript | [ref:.allhands/harness/src/hooks/validation.ts:runTscDiagnostics:0e448c6] | tsc | `.ts`, `.tsx` |
|
|
18
|
+
|
|
19
|
+
Each runner:
|
|
20
|
+
1. Checks tool availability via [ref:.allhands/harness/src/hooks/validation.ts:isToolAvailable:0e448c6]
|
|
21
|
+
2. Executes the tool against the target file
|
|
22
|
+
3. Returns a `DiagnosticResult` with severity, message, and location
|
|
23
|
+
|
|
24
|
+
For TypeScript, [ref:.allhands/harness/src/hooks/validation.ts:findTsConfig:0e448c6] walks up the directory tree to locate the nearest `tsconfig.json`, ensuring diagnostics respect project-level compiler settings.
|
|
25
|
+
|
|
26
|
+
[ref:.allhands/harness/src/hooks/validation.ts:formatDiagnosticsContext:0e448c6] transforms diagnostic results into agent-readable markdown, grouping by severity and providing file:line references agents can act on.
|
|
27
|
+
|
|
28
|
+
## Schema Validation
|
|
29
|
+
|
|
30
|
+
Schema validation targets frontmatter in markdown files used by the harness (prompts, specs, alignment docs, flow files).
|
|
31
|
+
|
|
32
|
+
### Delegation Architecture
|
|
33
|
+
|
|
34
|
+
Schema parsing and validation logic lives in [ref:.allhands/harness/src/lib/schema.ts::c65e65d]. The hooks layer (`validation.ts`) delegates all core operations there:
|
|
35
|
+
|
|
36
|
+
- **Frontmatter extraction** -- [ref:.allhands/harness/src/lib/schema.ts:extractFrontmatter:c65e65d] (imported into hooks)
|
|
37
|
+
- **Schema loading** -- [ref:.allhands/harness/src/lib/schema.ts:loadSchema:c65e65d] (imported as `loadSchemaFromLib`)
|
|
38
|
+
- **Frontmatter validation** -- [ref:.allhands/harness/src/lib/schema.ts:validateFrontmatter:c65e65d] (imported as `validateFrontmatterFromLib`)
|
|
39
|
+
|
|
40
|
+
This consolidation eliminated 4 behavioral divergences that existed when hooks had their own implementations:
|
|
41
|
+
|
|
42
|
+
1. Frontmatter parsing regex required a trailing newline after the closing `---` in hooks but not in lib
|
|
43
|
+
2. Hooks were missing `boolean`, `date`, and `object` type validation branches
|
|
44
|
+
3. Return type shape differences between hooks and lib validation results
|
|
45
|
+
4. Schema field fallback behavior (`schema.fields` vs `schema.frontmatter`) was inconsistent
|
|
46
|
+
|
|
47
|
+
```mermaid
|
|
48
|
+
flowchart TD
|
|
49
|
+
A[File written] --> B{detectSchemaTypeLocal}
|
|
50
|
+
B -->|prompt| C[lib/schema.ts: loadSchema]
|
|
51
|
+
B -->|spec| C
|
|
52
|
+
B -->|flow| C
|
|
53
|
+
B -->|unknown| F[Skip validation]
|
|
54
|
+
C --> G[lib/schema.ts: extractFrontmatter]
|
|
55
|
+
G --> H{Valid YAML?}
|
|
56
|
+
H -->|No| I[Report parse error]
|
|
57
|
+
H -->|Yes| J[lib/schema.ts: validateFrontmatter]
|
|
58
|
+
J --> K{Skill file?}
|
|
59
|
+
K -->|Yes| L[validateSkillSpecificRules]
|
|
60
|
+
K -->|No| M[formatSchemaErrors]
|
|
61
|
+
L --> M
|
|
62
|
+
M --> N[Return to agent]
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Key Functions
|
|
66
|
+
|
|
67
|
+
- [ref:.allhands/harness/src/hooks/validation.ts:detectSchemaTypeLocal:0e448c6] -- Thin wrapper over [ref:.allhands/harness/src/lib/schema.ts:detectSchemaType:c65e65d], determines which schema applies based on file path patterns
|
|
68
|
+
- [ref:.allhands/harness/src/hooks/validation.ts:validateSkillSpecificRules:0e448c6] -- Additional validation for skill folders via [ref:.allhands/harness/src/hooks/validation.ts:extractSkillFolderName:0e448c6] (skill name must match containing folder)
|
|
69
|
+
- [ref:.allhands/harness/src/hooks/validation.ts:runSchemaValidation:0e448c6] -- Full pipeline: detect type, delegate to lib for schema load/parse/validate, then apply skill-specific rules
|
|
70
|
+
- [ref:.allhands/harness/src/hooks/validation.ts:runSchemaValidationOnContent:0e448c6] -- Same pipeline but accepts content string instead of reading from disk (used for PreToolUse interception before the file is written)
|
|
71
|
+
- [ref:.allhands/harness/src/hooks/validation.ts:formatSchemaErrors:0e448c6] -- Formats validation errors with the schema type for agent display
|
|
72
|
+
|
|
73
|
+
### Pre vs Post Validation
|
|
74
|
+
|
|
75
|
+
Two hook entry points handle the timing difference:
|
|
76
|
+
|
|
77
|
+
- [ref:.allhands/harness/src/hooks/validation.ts:validateSchemaPre:0e448c6] -- **PreToolUse**: Validates content _before_ it reaches disk. Uses `runSchemaValidationOnContent` on the proposed file content from `tool_input`. Blocks the write if schema violations are found.
|
|
78
|
+
- [ref:.allhands/harness/src/hooks/validation.ts:validateSchema:0e448c6] -- **PostToolUse**: Validates the file _after_ it has been written. Uses `runSchemaValidation` on the persisted file. Reports errors as context for the agent to fix.
|
|
79
|
+
|
|
80
|
+
The pre-validation path is stricter -- it can prevent invalid content from being committed. Post-validation is a safety net that catches issues from tools that bypass pre-hooks.
|
|
81
|
+
|
|
82
|
+
## Formatting Enforcement
|
|
83
|
+
|
|
84
|
+
[ref:.allhands/harness/src/hooks/validation.ts:runFormat:0e448c6] enforces code formatting after file writes. It reads format configuration from project settings via [ref:.allhands/harness/src/hooks/shared.ts:loadProjectSettings:ca0caaf] and dispatches to the appropriate formatter.
|
|
85
|
+
|
|
86
|
+
[ref:.allhands/harness/src/hooks/validation.ts:getFormatCommand:0e448c6] maps file extensions to format commands from the project's `FormatConfig`. If a formatter is configured for the file type, it runs the command and reports any changes made.
|
|
87
|
+
|
|
88
|
+
## Design Decision: Deny vs Context
|
|
89
|
+
|
|
90
|
+
Schema validation uses [ref:.allhands/harness/src/hooks/shared.ts:denyTool:ca0caaf] for pre-write validation (prevents the tool call) and [ref:.allhands/harness/src/hooks/shared.ts:outputContext:ca0caaf] for post-write diagnostics (informs the agent). This distinction matters: pre-write denial is cheap (no disk I/O wasted), while post-write context lets the agent decide how to remediate.
|
|
91
|
+
|
|
92
|
+
## Test Coverage
|
|
93
|
+
|
|
94
|
+
Two e2e test suites verify schema validation behavior:
|
|
95
|
+
|
|
96
|
+
- [ref:.allhands/harness/src/__tests__/e2e/validation-hooks.test.ts::363c496] -- **28 tests** covering PreToolUse (Write/Edit interception), PostToolUse (file-on-disk validation), and the contract suite verifying hook registration and schema discovery.
|
|
97
|
+
- [ref:.allhands/harness/src/__tests__/e2e/validation-path-consistency.test.ts::d19007e] -- **17 tests** documenting the 4 behavioral divergences that existed before delegation consolidation. These tests pin the now-unified behavior: trailing newline handling, boolean/date/object type validation, return type shapes, and schema field fallback paths. Both the lib path and hooks path are exercised to confirm they produce identical results.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "E2E test infrastructure providing fixture creation with realistic planning directories, a CLI runner that spawns the harness as a child process, a hook runner for testing hook contracts with typed inputs/outputs, and assertion libraries for CLI results, hook decisions, files, and git state."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Test Harness
|
|
6
|
+
|
|
7
|
+
The test harness enables headless end-to-end testing of the `ah` CLI and its hook system. It creates isolated test environments, executes commands against them, and provides domain-specific assertions that understand hook protocols and harness conventions.
|
|
8
|
+
|
|
9
|
+
## Four Layers
|
|
10
|
+
|
|
11
|
+
```mermaid
|
|
12
|
+
graph TB
|
|
13
|
+
T[Test File] --> A[Assertions]
|
|
14
|
+
T --> H[Hook Runner]
|
|
15
|
+
T --> C[CLI Runner]
|
|
16
|
+
T --> F[Fixtures]
|
|
17
|
+
H --> C
|
|
18
|
+
C --> F
|
|
19
|
+
A --> H
|
|
20
|
+
A --> C
|
|
21
|
+
A --> F
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Each layer builds on the ones below. Tests compose fixtures, runners, and assertions to verify end-to-end behavior.
|
|
25
|
+
|
|
26
|
+
## Fixtures
|
|
27
|
+
|
|
28
|
+
Fixtures create temporary directories that replicate the harness's expected file structure.
|
|
29
|
+
|
|
30
|
+
[ref:.allhands/harness/src/__tests__/harness/fixture.ts:createFixture:507b666] is the base factory. It:
|
|
31
|
+
- Creates a temp directory with a random suffix
|
|
32
|
+
- Initializes a git repository
|
|
33
|
+
- Copies the real `.allhands/harness` directory from the project (via [ref:.allhands/harness/src/__tests__/harness/fixture.ts:getRealHarnessDir:507b666]) so hooks and CLI resolve correctly
|
|
34
|
+
- Accepts `FixtureOptions` to customize initial files, planning structure, and project settings
|
|
35
|
+
- Returns a `TestFixture` with `dir` (path), `cleanup()` (removes temp dir), and helper methods
|
|
36
|
+
|
|
37
|
+
[ref:.allhands/harness/src/__tests__/harness/fixture.ts:createSpecFixture:507b666] creates a fixture pre-populated with a spec and N prompt files (default 3), simulating a project mid-planning. Prompts use the `PROMPT_TEMPLATE` with proper frontmatter.
|
|
38
|
+
|
|
39
|
+
[ref:.allhands/harness/src/__tests__/harness/fixture.ts:createMultiSpecFixture:507b666] creates a fixture with multiple specs, useful for testing spec switching and cross-spec operations.
|
|
40
|
+
|
|
41
|
+
### Fixture Pooling
|
|
42
|
+
|
|
43
|
+
[ref:.allhands/harness/src/__tests__/harness/fixture.ts:getPooledFixture:507b666] caches fixtures by name, reusing them across tests in a suite. [ref:.allhands/harness/src/__tests__/harness/fixture.ts:cleanupPool:507b666] tears down all pooled fixtures, typically called in `afterAll`. This avoids recreating expensive fixtures (git init, file copy) for every test.
|
|
44
|
+
|
|
45
|
+
### Built-in Templates
|
|
46
|
+
|
|
47
|
+
The fixture module exports templates for common file types:
|
|
48
|
+
- `PROMPT_TEMPLATE` -- Markdown prompt with valid frontmatter
|
|
49
|
+
- `ALIGNMENT_TEMPLATE` -- Alignment document structure
|
|
50
|
+
- `SPEC_TEMPLATE` -- Spec file with required fields
|
|
51
|
+
- `PYTHON_SAMPLE` / `TYPESCRIPT_SAMPLE` -- Source files for diagnostics testing
|
|
52
|
+
|
|
53
|
+
## CLI Runner
|
|
54
|
+
|
|
55
|
+
[ref:.allhands/harness/src/__tests__/harness/cli-runner.ts:runCli:432baa6] spawns the `ah` CLI as a child process using `tsx` for TypeScript execution. It captures stdout, stderr, and exit code into a `RunResult`. Supports timeout, stdin piping, environment overrides, and JSON output parsing.
|
|
56
|
+
|
|
57
|
+
[ref:.allhands/harness/src/__tests__/harness/cli-runner.ts:runInFixture:432baa6] wraps `runCli` with a fixture's directory as `cwd`, the most common test pattern.
|
|
58
|
+
|
|
59
|
+
### Specialized Runners
|
|
60
|
+
|
|
61
|
+
| Runner | Purpose |
|
|
62
|
+
|--------|---------|
|
|
63
|
+
| [ref:.allhands/harness/src/__tests__/harness/cli-runner.ts:runKnowledgeSearch:432baa6] | Executes `ah knowledge search` with query, optional path and k |
|
|
64
|
+
| [ref:.allhands/harness/src/__tests__/harness/cli-runner.ts:runValidate:432baa6] | Executes `ah validate` against a file path |
|
|
65
|
+
| [ref:.allhands/harness/src/__tests__/harness/cli-runner.ts:runCodeSearch:432baa6] | Executes code search with optional budget |
|
|
66
|
+
| [ref:.allhands/harness/src/__tests__/harness/cli-runner.ts:runToolsList:432baa6] | Lists available tools |
|
|
67
|
+
| [ref:.allhands/harness/src/__tests__/harness/cli-runner.ts:runSpecsList:432baa6] | Lists available specs |
|
|
68
|
+
|
|
69
|
+
[ref:.allhands/harness/src/__tests__/harness/cli-runner.ts:runBatch:432baa6] executes multiple commands sequentially against the same fixture, returning results in order. Useful for testing multi-step workflows.
|
|
70
|
+
|
|
71
|
+
[ref:.allhands/harness/src/__tests__/harness/cli-runner.ts:debugResult:432baa6] prints a formatted summary of a `RunResult` for test debugging.
|
|
72
|
+
|
|
73
|
+
## Hook Runner
|
|
74
|
+
|
|
75
|
+
[ref:.allhands/harness/src/__tests__/harness/hook-runner.ts:runHook:c357c05] executes a hook by building the correct CLI subcommand, piping `HookInput` as stdin JSON, and parsing the output as a `HookResult` with typed fields for `decision`, `reason`, `context`, and `output`.
|
|
76
|
+
|
|
77
|
+
### Specialized Hook Runners
|
|
78
|
+
|
|
79
|
+
| Runner | Hook | Input |
|
|
80
|
+
|--------|------|-------|
|
|
81
|
+
| [ref:.allhands/harness/src/__tests__/harness/hook-runner.ts:runContextHook:c357c05] | Any context hook | `PreToolUseInput` |
|
|
82
|
+
| [ref:.allhands/harness/src/__tests__/harness/hook-runner.ts:runEditInject:c357c05] | `edit-inject` | File path |
|
|
83
|
+
| [ref:.allhands/harness/src/__tests__/harness/hook-runner.ts:runReadEnforcer:c357c05] | `read-enforcer` | File path + optional offset/limit |
|
|
84
|
+
| [ref:.allhands/harness/src/__tests__/harness/hook-runner.ts:runSearchRouter:c357c05] | `search-router` | Search pattern |
|
|
85
|
+
| [ref:.allhands/harness/src/__tests__/harness/hook-runner.ts:runTldrInject:c357c05] | `tldr-inject` | Prompt text |
|
|
86
|
+
| [ref:.allhands/harness/src/__tests__/harness/hook-runner.ts:runValidationHook:c357c05] | Any validation hook | `PreToolUseInput` or `PostToolUseInput` |
|
|
87
|
+
| [ref:.allhands/harness/src/__tests__/harness/hook-runner.ts:runSchemaCheck:c357c05] | Schema validation | File path + content |
|
|
88
|
+
| [ref:.allhands/harness/src/__tests__/harness/hook-runner.ts:runLifecycleHook:c357c05] | Any lifecycle hook | `HookInput` |
|
|
89
|
+
| [ref:.allhands/harness/src/__tests__/harness/hook-runner.ts:runStopHook:c357c05] | Stop hook | Session ID |
|
|
90
|
+
|
|
91
|
+
### Contract Testing
|
|
92
|
+
|
|
93
|
+
[ref:.allhands/harness/src/__tests__/harness/hook-runner.ts:testHookContract:c357c05] verifies that a hook adheres to a declared contract -- a `HookContract` specifying the hook name, input, and expected output properties (decision, required context strings, timing bounds). Returns a `ContractResult` with pass/fail and specific failure messages.
|
|
94
|
+
|
|
95
|
+
[ref:.allhands/harness/src/__tests__/harness/hook-runner.ts:testHookContracts:c357c05] runs an array of contracts in sequence, collecting all results. Combined with [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertContractsPassed:51c46b6], this enables declarative hook testing:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
Define contract -> Run contract -> Assert all passed
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
[ref:.allhands/harness/src/__tests__/harness/hook-runner.ts:debugHookResult:c357c05] prints a formatted hook result for debugging failures.
|
|
102
|
+
|
|
103
|
+
## Assertions
|
|
104
|
+
|
|
105
|
+
The assertion library uses vitest's `expect` under the hood, adding domain-specific checks.
|
|
106
|
+
|
|
107
|
+
### CLI Assertions
|
|
108
|
+
|
|
109
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertSuccess:51c46b6] -- Exit code 0
|
|
110
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertFailure:51c46b6] -- Non-zero exit code
|
|
111
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertStdoutContains:51c46b6] / [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertStderrContains:51c46b6] -- Substring match in output
|
|
112
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertStdoutMatches:51c46b6] -- Regex match in stdout
|
|
113
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertJsonOutput:51c46b6] -- Parse stdout as JSON and run a validator function
|
|
114
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertTimedWithin:51c46b6] -- Execution completed within a time budget
|
|
115
|
+
|
|
116
|
+
### Hook Assertions
|
|
117
|
+
|
|
118
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertHookAllowed:51c46b6] -- Hook returned allow decision
|
|
119
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertHookDenied:51c46b6] -- Hook returned deny decision
|
|
120
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertHookBlocked:51c46b6] -- Hook returned block decision
|
|
121
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertHookInjectedContext:51c46b6] -- Hook output contains `additionalContext`
|
|
122
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertHookContextContains:51c46b6] -- Injected context contains a specific substring
|
|
123
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertDenialReasonContains:51c46b6] -- Denial reason contains expected text
|
|
124
|
+
|
|
125
|
+
### Fixture Assertions
|
|
126
|
+
|
|
127
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertFileExists:51c46b6] / [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertFileNotExists:51c46b6] -- File presence in fixture
|
|
128
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertFileContains:51c46b6] / [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertFileMatches:51c46b6] -- File content checks
|
|
129
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertValidFrontmatter:51c46b6] -- Parses YAML frontmatter and checks required fields
|
|
130
|
+
|
|
131
|
+
### Git Assertions
|
|
132
|
+
|
|
133
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertGitTracked:51c46b6] -- File is tracked by git
|
|
134
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertGitDirty:51c46b6] -- File has uncommitted changes
|
|
135
|
+
|
|
136
|
+
### Composite Assertions
|
|
137
|
+
|
|
138
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertWorkflowSuccess:51c46b6] -- All results in a named sequence succeeded
|
|
139
|
+
- [ref:.allhands/harness/src/__tests__/harness/assertions.ts:assertContractsPassed:51c46b6] -- All hook contracts passed
|
|
140
|
+
|
|
141
|
+
## Barrel Export
|
|
142
|
+
|
|
143
|
+
[ref:.allhands/harness/src/__tests__/harness/index.ts::c1cd207] re-exports everything from all four layers. Tests import from this single entry point:
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
import { createFixture, runInFixture, runHook, assertSuccess } from '../harness/index.js';
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
This keeps test files clean and decoupled from internal module structure.
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Terminal UI built on blessed providing a three-pane layout for agent orchestration: actions pane with new initiative spec type selection, prompts pane for tracking prompt status, status pane for monitoring active agents, and two toggles (Loop, Parallel) for controlling the unified event loop."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Terminal User Interface (TUI)
|
|
6
|
+
|
|
7
|
+
The TUI is the primary operator interface for the harness. It renders a three-pane terminal layout using the blessed library, integrates with the event loop for real-time state updates, and manages agent lifecycles through tmux window orchestration.
|
|
8
|
+
|
|
9
|
+
## Layout Architecture
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
+-------------------+-------------------+-------------------+
|
|
13
|
+
| HEADER | ALL HANDS | AGENTIC HARNESS |
|
|
14
|
+
+-------------------+-------------------+-------------------+
|
|
15
|
+
| | | |
|
|
16
|
+
| Actions Pane | Prompts Pane | Status Pane |
|
|
17
|
+
| | | |
|
|
18
|
+
| [1] Coordinator | * 01: Task A | Spec: api-v2 |
|
|
19
|
+
| [2] New Initiative > 02: Task B | Branch: feat/api |
|
|
20
|
+
| [3] Planner | - 03: Task C | |
|
|
21
|
+
| [4] Review Jury | | Agents: |
|
|
22
|
+
| [5] E2E Test Plan| | executor-01 [run] |
|
|
23
|
+
| [6] PR Action | | planner [run] |
|
|
24
|
+
| ... | | |
|
|
25
|
+
| -- Toggles -- | | Activity Log: |
|
|
26
|
+
| [O] Loop | | [12:30] Index ok |
|
|
27
|
+
| [P] Parallel | | [12:31] Spawned |
|
|
28
|
+
| | | |
|
|
29
|
+
+-------------------+-------------------+-------------------+
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Pane Components
|
|
33
|
+
|
|
34
|
+
**Actions Pane** -- [ref:.allhands/harness/src/tui/actions.ts:createActionsPane:17c53c1]
|
|
35
|
+
Renders agent spawn buttons, toggle switches, and control actions. All actions are always visible -- agents exit early if preconditions are not met. [ref:.allhands/harness/src/tui/actions.ts:buildActionItems:17c53c1] constructs the full item list; [ref:.allhands/harness/src/tui/actions.ts:getSelectableItems:17c53c1] filters to navigable items.
|
|
36
|
+
|
|
37
|
+
The complete action list:
|
|
38
|
+
|
|
39
|
+
| Key | Action | Description |
|
|
40
|
+
|-----|--------|-------------|
|
|
41
|
+
| 1 | Coordinator | Spawn coordinator agent |
|
|
42
|
+
| 2 | New Initiative | Spec type selection modal, routes to ideation |
|
|
43
|
+
| 3 | Planner | Spawn planner agent |
|
|
44
|
+
| 4 | Review Jury | Spawn review jury |
|
|
45
|
+
| 5 | E2E Test Plan | Spawn E2E test planner |
|
|
46
|
+
| 6 | PR Action | Create PR / Rerun PR Review (state-dependent label) |
|
|
47
|
+
| 7 | Address PR Review | Spawn PR review agent |
|
|
48
|
+
| 8 | Compound | Spawn compound operation |
|
|
49
|
+
| 9 | Complete | Mark spec as completed |
|
|
50
|
+
| 0 | Switch Workspace | Open spec selection modal |
|
|
51
|
+
| - | Custom Flow | Open flow selection modal |
|
|
52
|
+
|
|
53
|
+
Two toggles follow the action list:
|
|
54
|
+
|
|
55
|
+
| Key | Toggle | Description |
|
|
56
|
+
|-----|--------|-------------|
|
|
57
|
+
| O | Loop | Enable/disable the prompt execution loop |
|
|
58
|
+
| P | Parallel | Enable/disable multi-executor parallel mode |
|
|
59
|
+
|
|
60
|
+
**Prompts Pane** -- [ref:.allhands/harness/src/tui/prompts-pane.ts:createPromptsPane:822e9a7]
|
|
61
|
+
Displays all prompts sorted by status: in_progress first, then pending, then done. Each prompt shows its number, title, and status icon via [ref:.allhands/harness/src/tui/prompts-pane.ts:getStatusIcon:822e9a7]. Selecting a prompt opens the file viewer.
|
|
62
|
+
|
|
63
|
+
**Status Pane** -- [ref:.allhands/harness/src/tui/status-pane.ts:createStatusPane:ada300c]
|
|
64
|
+
Shows the current spec, branch, base branch, active agents, and a scrolling activity log. [ref:.allhands/harness/src/tui/status-pane.ts:getSelectableItems:ada300c] builds a navigable list of spec, alignment doc, E2E test plan, and running agents. [ref:.allhands/harness/src/tui/status-pane.ts:formatAgentStatus:ada300c] renders each agent's running state.
|
|
65
|
+
|
|
66
|
+
## Navigation
|
|
67
|
+
|
|
68
|
+
The TUI uses vim-style keyboard navigation defined in the [ref:.allhands/harness/src/tui/index.ts:TUI:5e4554b] class:
|
|
69
|
+
|
|
70
|
+
| Key | Action |
|
|
71
|
+
|-----|--------|
|
|
72
|
+
| Tab / Shift-Tab | Cycle between panes |
|
|
73
|
+
| j / k | Navigate up/down within focused pane |
|
|
74
|
+
| u / d | Page up/down (10 items) |
|
|
75
|
+
| Space / Enter | Select current item |
|
|
76
|
+
| Escape | Close active modal or file viewer |
|
|
77
|
+
| x | Delete selected agent (status pane only) |
|
|
78
|
+
| 1-9, 0, - | Hotkeys for action items |
|
|
79
|
+
| O, P | Toggle Loop, Parallel |
|
|
80
|
+
| Q, R, V, C | Quit, Refresh, View Logs, Clear Logs |
|
|
81
|
+
|
|
82
|
+
Focused pane borders highlight in bright purple (`#a78bfa`); unfocused panes use muted purple (`#4A34C5`).
|
|
83
|
+
|
|
84
|
+
## Modals and File Viewer
|
|
85
|
+
|
|
86
|
+
[ref:.allhands/harness/src/tui/modal.ts:createModal:8c117c4] renders overlay modals with navigable item lists. Used for spec selection, log viewing, flow selection, and spec type selection (New Initiative). Supports optional `onClear` for deselection and `scrollable` mode for long content.
|
|
87
|
+
|
|
88
|
+
[ref:.allhands/harness/src/tui/file-viewer-modal.ts:createFileViewer:812eabd] opens files in a read-only scrollable overlay. Used for viewing prompts, specs, alignment docs, and E2E test plans. [ref:.allhands/harness/src/tui/file-viewer-modal.ts:getPlanningFilePath:812eabd] resolves planning artifacts by branch and type. [ref:.allhands/harness/src/tui/file-viewer-modal.ts:getSpecFilePath:812eabd] locates spec files by ID.
|
|
89
|
+
|
|
90
|
+
## State Management
|
|
91
|
+
|
|
92
|
+
[ref:.allhands/harness/src/tui/index.ts:TUI:5e4554b] maintains a `TUIState` object tracking:
|
|
93
|
+
- **Toggle states**: `loopEnabled`, `parallelEnabled`
|
|
94
|
+
- **Prompt state**: Array of `PromptItem` with number, title, status, path
|
|
95
|
+
- **Agent state**: Array of `AgentInfo` with name, type, running status
|
|
96
|
+
- **Spec/branch context**: Current spec ID, branch name, base branch
|
|
97
|
+
- **PR workflow**: `PRActionState` progresses through `create-pr` -> `awaiting-review` -> `rerun-pr-review`
|
|
98
|
+
- **Custom flow counter**: Tracks custom flow window numbering
|
|
99
|
+
|
|
100
|
+
State updates flow through `updateState()` which rebuilds action items and triggers re-render.
|
|
101
|
+
|
|
102
|
+
## New Initiative Action
|
|
103
|
+
|
|
104
|
+
Selecting **New Initiative** (key `2`) opens a spec type selection modal presenting 6 types:
|
|
105
|
+
|
|
106
|
+
| Type | Description |
|
|
107
|
+
|------|-------------|
|
|
108
|
+
| milestone | Feature development with deep ideation |
|
|
109
|
+
| investigation | Debug / diagnose issues |
|
|
110
|
+
| optimization | Performance / efficiency work |
|
|
111
|
+
| refactor | Cleanup / tech debt |
|
|
112
|
+
| documentation | Coverage gaps |
|
|
113
|
+
| triage | External signal analysis |
|
|
114
|
+
|
|
115
|
+
On selection, the TUI dispatches a `new-initiative` action with the chosen `specType`. [ref:.allhands/harness/src/commands/tui.ts:handleAction:4ca2008] routes this through the ideation agent with an optional `flowOverride`:
|
|
116
|
+
|
|
117
|
+
- **Milestone** gets `null` flow override (uses the ideation agent's default profile flow)
|
|
118
|
+
- **All other types** get a scoping flow path resolved via [ref:.allhands/harness/src/commands/tui.ts:SCOPING_FLOW_MAP:4ca2008]
|
|
119
|
+
|
|
120
|
+
`SCOPING_FLOW_MAP` is exported as `Record<SpecType, string | null>`:
|
|
121
|
+
|
|
122
|
+
| SpecType | Flow File |
|
|
123
|
+
|----------|-----------|
|
|
124
|
+
| milestone | `null` (profile default) |
|
|
125
|
+
| investigation | `INVESTIGATION_SCOPING.md` |
|
|
126
|
+
| optimization | `OPTIMIZATION_SCOPING.md` |
|
|
127
|
+
| refactor | `REFACTOR_SCOPING.md` |
|
|
128
|
+
| documentation | `DOCUMENTATION_SCOPING.md` |
|
|
129
|
+
| triage | `TRIAGE_SCOPING.md` |
|
|
130
|
+
|
|
131
|
+
[ref:.allhands/harness/src/tui/actions.ts:buildActionItems:17c53c1] is exported for testability alongside `SCOPING_FLOW_MAP`.
|
|
132
|
+
|
|
133
|
+
## Uncommitted Changes Guards
|
|
134
|
+
|
|
135
|
+
Three actions check for a dirty working tree before proceeding:
|
|
136
|
+
- **create-pr** -- Warns that uncommitted changes will not be included in the PR
|
|
137
|
+
- **rerun-pr-review** -- Warns that uncommitted changes will not be included in the PR
|
|
138
|
+
- **mark-completed** -- Warns that uncommitted changes will not be included in the final push
|
|
139
|
+
|
|
140
|
+
All three use the shared `confirmProceedWithUncommittedChanges()` helper in [ref:.allhands/harness/src/commands/tui.ts:handleAction:4ca2008], which calls [ref:.allhands/harness/src/lib/git.ts:hasUncommittedChanges:d6d6363] and shows a confirmation modal via `tui.showConfirmation()`. The user can press Enter to proceed or Escape to cancel.
|
|
141
|
+
|
|
142
|
+
## Event Loop Integration
|
|
143
|
+
|
|
144
|
+
The TUI constructor starts an [ref:.allhands/harness/src/lib/event-loop.ts:EventLoop:940f18a] instance that monitors external state. Callback bindings connect event loop events to TUI state:
|
|
145
|
+
|
|
146
|
+
- `onBranchChange` -- Updates branch/spec context and reloads prompts for the new planning directory
|
|
147
|
+
- `onAgentsChange` -- Updates the active agents display
|
|
148
|
+
- `onSpawnExecutor` -- Delegates to TUI options for executor spawning
|
|
149
|
+
- `onSpawnEmergentPlanning` -- Delegates to TUI options for hypothesis planner spawning (no prompt argument)
|
|
150
|
+
- `onPromptsChange` -- Updates prompt list and rebuilds action items
|
|
151
|
+
- `onPRReviewFeedback` -- Transitions PR action state and unlocks Review PR
|
|
152
|
+
- `onLoopStatus` -- Appends status messages to the activity log
|
|
153
|
+
|
|
154
|
+
## CLI Daemon Integration
|
|
155
|
+
|
|
156
|
+
When enabled in project settings (default: true), the TUI starts a [ref:.allhands/harness/src/lib/cli-daemon.ts:CLIDaemon:e269aee] for fast hook execution. This eliminates Node.js startup overhead for every hook invocation during active development.
|
|
157
|
+
|
|
158
|
+
## Launch and Teardown
|
|
159
|
+
|
|
160
|
+
[ref:.allhands/harness/src/commands/tui.ts:launchTUI:4ca2008] initializes the TUI with the working directory, loads initial state from git branch and planning directory, and starts background indexing (semantic index, call graph, knowledge bases, doc validation).
|
|
161
|
+
|
|
162
|
+
[ref:.allhands/harness/src/commands/tui.ts:handleAction:4ca2008] dispatches TUI actions to their implementations: spawning agents via [ref:.allhands/harness/src/commands/tui.ts:spawnAgentsForAction:4ca2008], managing PR workflows, switching specs, and running compound operations.
|
|
163
|
+
|
|
164
|
+
On destroy, the TUI kills all spawned tmux windows (tracked by the session registry), stops the event loop and CLI daemon, clears session state, and restores stdout/stderr interceptors with a 100ms delay to catch deferred terminal output.
|
|
165
|
+
|
|
166
|
+
## Background Indexing
|
|
167
|
+
|
|
168
|
+
On startup, the TUI runs a non-blocking indexing pipeline:
|
|
169
|
+
1. Ensures the TLDR daemon is running
|
|
170
|
+
2. Builds or rebuilds the semantic index (branch-aware via [ref:.allhands/harness/src/lib/tldr.ts:needsSemanticRebuild:702ae0d])
|
|
171
|
+
3. Warms the call graph cache
|
|
172
|
+
4. Validates agent profiles via [ref:.allhands/harness/src/lib/opencode/profiles.ts:loadAllProfiles:ef20442]
|
|
173
|
+
5. Indexes knowledge bases (roadmap, docs) with incremental updates from git
|
|
174
|
+
6. Validates documentation references
|
|
175
|
+
|
|
176
|
+
All indexing errors are caught and logged to the activity pane -- they never crash the TUI.
|
package/docs/memories.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Lightweight learnings from past sessions, searchable via `ah memories search`. Captures technical patterns, engineer preferences, and harness behavior discoveries."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Memories
|
|
6
|
+
|
|
7
|
+
Per **Knowledge Compounding**, this file captures lightweight learnings from past sessions. For detailed technical solutions, see `docs/solutions/`.
|
|
8
|
+
|
|
9
|
+
| Name | Domain | Source | Description |
|
|
10
|
+
|------|--------|--------|-------------|
|
|
11
|
+
| Motivation-driven suite documentation | validation | user-steering | Engineer reversed detailed CLI command documentation in browser-automation suite after hands-on testing. Commands are discoverable via `--help`; validation suite value is teaching agents HOW TO THINK about using a tool, not replicating command references. |
|
|
12
|
+
| Stochastic terminology preference | planning | user-steering | Engineer chose "stochastic" over "heuristic" for the validation dimension taxonomy. Deterministic/stochastic is an established CS pair. All harness docs must use this terminology consistently. |
|
|
13
|
+
| blockTool output format mismatch (resolved) | harness-tooling | agent-inferred | `blockTool()` in `hooks/shared.ts` outputs `{ decision: 'block', reason }`. Hook-runner now handles both `{ continue: false }` and `{ decision: 'block' }` formats for `assertHookBlocked`. Fixed during compounding. |
|
|
14
|
+
| Dual validation path divergence | harness-tooling | agent-inferred | Before consolidation, [ref:hooks/validation.ts] and [ref:lib/schema.ts] had 4 behavioral divergences: (1) frontmatter regex trailing newline requirement, (2) hooks missing boolean/date/object type branches, (3) return type shape differences, (4) schema.fields fallback behavior. Consolidation in Jury Review resolved all 4 by delegating hooks to lib. |
|
|
15
|
+
| validation-tools path resolution | harness-tooling | agent-inferred | `validation-tools list` resolves file paths relative to source code (`__dirname`), not the working directory. Fixture-based testing cannot simulate empty validation directories — use invariant tests (structure, types) instead. |
|
|
16
|
+
| Array item-type validation gap | harness-tooling | agent-inferred | Schema enforcement for array fields originally only checked `Array.isArray(value)` without validating item types against `items` specification. `tools: [123]` would pass when `items: string`. Fixed in both [ref:hooks/validation.ts] and [ref:lib/schema.ts]. |
|
|
17
|
+
| Pre-existing test failures baseline | validation | agent-inferred | 10 pre-existing test failures persisted throughout the spec: spec `branch` field validation, search-router hook contracts, command timeout. Confirmed identical across all prompts via `git stash` comparison. These are not regressions from this spec. |
|
|
18
|
+
| Emergent testing compounds value | implementation | agent-inferred | 5 emergent prompts (06-10) were all kept, producing 147 new tests for previously untested infrastructure. Prompt 10 divergence documentation directly enabled Jury Review dual-path consolidation. Emergent work chains (06→07→10, 08→09) compound — each builds on discoveries from prior. |
|
|
19
|
+
| TypeScript unit testing suite gap | validation | agent-inferred | No TypeScript unit testing validation suite exists for the harness. Flagged by Prompt 06 for CREATE_VALIDATION_TOOLING follow-up. Tests were written manually without suite guidance. |
|
|
20
|
+
| ENV credential guidance declined | planning | user-steering | Engineer chose not to add secret-sourcing guidance to browser-automation.md ENV Configuration section. ENV docs document variables and their purpose, not how to securely source credentials. |
|
package/docs/solutions/agentic-issues/premature-agent-deletion-tui-action-dependency-20260130.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Solution for premature agent profile deletion breaking TUI compound action due to undetected tui_action field dependency between co-dependent agent profiles."
|
|
3
|
+
title: "Premature agent profile deletion breaks TUI action that depends on tui_action field"
|
|
4
|
+
date: "2026-01-30"
|
|
5
|
+
milestone: "feature/unified-workflow-orchestration"
|
|
6
|
+
problem_type: agentic_issue
|
|
7
|
+
component: "tui-actions"
|
|
8
|
+
symptoms:
|
|
9
|
+
- "Compound TUI action spawns only one agent instead of two"
|
|
10
|
+
- "Agent profile deleted during cleanup but still referenced by tui_action handler"
|
|
11
|
+
- "Missing agent in multi-agent TUI action"
|
|
12
|
+
root_cause: agentic_miscommunication
|
|
13
|
+
severity: high
|
|
14
|
+
tags:
|
|
15
|
+
- agent-profile-deletion
|
|
16
|
+
- tui-action-dependency
|
|
17
|
+
- compound-action
|
|
18
|
+
- documentor-agent
|
|
19
|
+
- workflow-cleanup
|
|
20
|
+
- cross-file-dependency
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Problem
|
|
24
|
+
|
|
25
|
+
During workflow cleanup (Prompt 07), the agent deleted [ref:.allhands/agents/documentor.yaml] and [ref:.allhands/flows/DOCUMENTATION.md] as part of consolidating documentation orchestration into the hypothesis planner model. The compound TUI action relies on scanning all agent profiles with `tui_action: compound` to determine which agents to spawn. Both `compounder.yaml` and `documentor.yaml` had this field, so deleting `documentor.yaml` silently reduced the compound action to spawning only the compounder.
|
|
26
|
+
|
|
27
|
+
## Root Cause
|
|
28
|
+
|
|
29
|
+
The prompt's cleanup task ("Remove documentor.yaml agent profile and DOCUMENTATION.md flow") was scoped by architectural reasoning (documentation now handled by hypothesis planner) without verifying downstream references to the `tui_action` field. The `typescript-typecheck` validation suite and `ah validate agents` both passed because the deletion was structurally valid — no TypeScript imports referenced the YAML file, and the remaining agent profiles were individually valid.
|
|
30
|
+
|
|
31
|
+
## Solution
|
|
32
|
+
|
|
33
|
+
User-patch Prompt 17 restored both files with exact content from `main` branch using `git show main:<path>`.
|
|
34
|
+
|
|
35
|
+
## Prevention
|
|
36
|
+
|
|
37
|
+
Before deleting any agent profile:
|
|
38
|
+
1. Check the `tui_action` field value in the profile being deleted
|
|
39
|
+
2. Search for other profiles with the same `tui_action` value — if multiple profiles share a `tui_action`, they are co-dependencies for that TUI action
|
|
40
|
+
3. Verify the TUI action handler logic to understand if it expects multiple agents
|
|
41
|
+
|
|
42
|
+
## Failed Approaches
|
|
43
|
+
|
|
44
|
+
- Relying on `npx tsc --noEmit` — YAML files are not part of the TypeScript dependency graph
|
|
45
|
+
- Relying on `ah validate agents` — validates individual profiles, not cross-profile action dependencies
|
|
46
|
+
|
|
47
|
+
## Related
|
|
48
|
+
|
|
49
|
+
None yet.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "[ref:] anchors silently go stale in skill reference docs"
|
|
3
|
+
date: "2026-01-31"
|
|
4
|
+
milestone: refactor/harness-maintenance-skill
|
|
5
|
+
problem_type: agentic_issue
|
|
6
|
+
component: harness-maintenance-skill
|
|
7
|
+
symptoms:
|
|
8
|
+
- "[ref:] anchors added to skill reference docs with git hashes"
|
|
9
|
+
- "ah docs validate reports frontmatter errors on skill reference files"
|
|
10
|
+
- "Git hashes in [ref:] anchors become stale after any source file change"
|
|
11
|
+
- "ah docs finalize cannot resolve directory-level [ref:] anchors"
|
|
12
|
+
root_cause: wrong_api_usage
|
|
13
|
+
severity: medium
|
|
14
|
+
tags:
|
|
15
|
+
- ref-anchors
|
|
16
|
+
- docs-validate
|
|
17
|
+
- docs-finalize
|
|
18
|
+
- skill-references
|
|
19
|
+
- stale-metadata
|
|
20
|
+
- harness-maintenance
|
|
21
|
+
- scope-limitation
|
|
22
|
+
- context-is-precious
|
|
23
|
+
source: agent-inferred
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Problem
|
|
27
|
+
|
|
28
|
+
During the harness-maintenance skill restructure, an agent added `[ref:]` code reference anchors (with git hashes) to `core-architecture.md` (6 anchors) and `tools-commands-mcp-hooks.md` (10 occurrences). These anchors are designed to be validated by `ah docs validate` and finalized by `ah docs finalize`.
|
|
29
|
+
|
|
30
|
+
The problem: both `ah docs validate` and `ah docs finalize` are scoped to the `docs/` directory only (hardcoded default in `harness/src/commands/docs.ts`). Skill reference docs live in `.allhands/skills/*/references/`, which is outside the docs tooling scope. The anchors were:
|
|
31
|
+
- Never validated automatically
|
|
32
|
+
- Contained git hashes that would silently go stale on any source file change
|
|
33
|
+
- Created false confidence that references were current
|
|
34
|
+
- Added noise to files loaded every agent session (violating Context is Precious)
|
|
35
|
+
|
|
36
|
+
## Investigation
|
|
37
|
+
|
|
38
|
+
1. Agent ran `ah docs validate --path .allhands/skills/harness-maintenance/references/ --json` — it processed the files but reported frontmatter validation errors (skill references don't have standard doc frontmatter)
|
|
39
|
+
2. Agent ran `ah docs finalize` — it resolved 9 file-level anchors to hashed refs but failed on 8 directory-level anchors (directories don't have git blob hashes)
|
|
40
|
+
3. The partial success masked the fundamental issue: even "finalized" anchors would go stale because no automated pipeline re-validates skill reference docs
|
|
41
|
+
|
|
42
|
+
## Solution
|
|
43
|
+
|
|
44
|
+
Engineer directed stripping all `[ref:]` anchors and reverting to plain-text backtick paths:
|
|
45
|
+
- 6 anchors stripped from `core-architecture.md`
|
|
46
|
+
- 10 anchors stripped from `tools-commands-mcp-hooks.md`
|
|
47
|
+
- Scope guard added to SKILL.md maintainer checklist: "NEVER run `ah docs validate`/`finalize` on skill references — those commands are scoped to `docs/` only"
|
|
48
|
+
|
|
49
|
+
Plain backtick paths (`\`.allhands/harness/src/cli.ts\``) are more readable and don't create false freshness guarantees.
|
|
50
|
+
|
|
51
|
+
## Prevention
|
|
52
|
+
|
|
53
|
+
- **Scope guard**: The harness-maintenance SKILL.md maintainer checklist now explicitly prohibits running docs-validate/finalize on skill references
|
|
54
|
+
- **Rule of thumb**: Only use `[ref:]` anchors in files under `docs/` where the docs pipeline automatically validates and re-finalizes them
|
|
55
|
+
- **Broader principle**: Never embed metadata that requires external tooling validation in files outside that tooling's scope — the metadata will silently rot
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Agent-generated tautological tests assert constants against themselves"
|
|
3
|
+
date: "2026-01-31"
|
|
4
|
+
milestone: feature/workflow-domain-configuration
|
|
5
|
+
problem_type: agentic_issue
|
|
6
|
+
component: harness-tests
|
|
7
|
+
symptoms:
|
|
8
|
+
- "Tests pass but exercise no real code paths"
|
|
9
|
+
- "Assertions compare constructed values against identical constructions"
|
|
10
|
+
- "Test coverage appears high but is hollow"
|
|
11
|
+
root_cause: agentic_hallucination
|
|
12
|
+
severity: medium
|
|
13
|
+
tags:
|
|
14
|
+
- tautological-tests
|
|
15
|
+
- self-asserting
|
|
16
|
+
- agentic-hallucination
|
|
17
|
+
- test-quality
|
|
18
|
+
- hollow-coverage
|
|
19
|
+
- routing-tests
|
|
20
|
+
- vitest
|
|
21
|
+
source: review-fix
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Problem
|
|
25
|
+
|
|
26
|
+
During Prompt 05 (TUI Integration & Execution Gating), the agent generated 3 routing tests in `new-initiative-routing.test.ts` that passed but verified nothing:
|
|
27
|
+
|
|
28
|
+
1. **Self-asserting path construction**: Built a path with `path.join()` then asserted it equals the same `path.join()` call
|
|
29
|
+
2. **Guaranteed-unique set**: Created a `Set` from a literal array and asserted `set.size === array.length` — tautologically true for any array of distinct literals
|
|
30
|
+
3. **Config-shape-you-just-built**: Constructed a config object then asserted its shape matched the literal used to build it
|
|
31
|
+
|
|
32
|
+
All 3 tests passed on every run, creating an illusion of coverage.
|
|
33
|
+
|
|
34
|
+
## Investigation
|
|
35
|
+
|
|
36
|
+
The 7-member jury review's YAGNI reviewer flagged these as "tautological — they assert constants against themselves, never exercise real code." The agent had followed a pattern of writing tests that structurally resemble valid tests but contain no meaningful assertions.
|
|
37
|
+
|
|
38
|
+
## Solution
|
|
39
|
+
|
|
40
|
+
Prompt 12 replaced all 3 tests with assertions that exercise real artifacts:
|
|
41
|
+
|
|
42
|
+
- **Filesystem existence checks**: For each of the 6 workflow domain configs, assert the file exists at the expected path using `existsSync()`
|
|
43
|
+
- **Runtime output assertion**: Call `buildActionItems()` and assert the output includes `initiative-steering` — exercises real code that constructs action items
|
|
44
|
+
|
|
45
|
+
The replacement tests use `getFlowsDirectory()` parent for correct path resolution in the vitest execution environment.
|
|
46
|
+
|
|
47
|
+
## Prevention
|
|
48
|
+
|
|
49
|
+
- After writing tests, verify each assertion's left-hand and right-hand sides come from **different sources** — one from code under test, one from expected values
|
|
50
|
+
- Assertions where both sides are computed from constants or literals are suspect
|
|
51
|
+
- Prefer assertions against runtime behavior (function calls, filesystem state, API responses) over assertions against values you just constructed
|
|
52
|
+
- Jury review's YAGNI dimension reliably catches this pattern — include it for infrastructure specs
|