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,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Manifest system that classifies allhands files as distributable, internal, or gitignored to control what gets synced to target repositories"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Manifest and Distribution System
|
|
6
|
+
|
|
7
|
+
The manifest system is the gatekeeper for file distribution. Every file in the allhands source is classified into one of three categories, and only distributable files flow to target repositories.
|
|
8
|
+
|
|
9
|
+
## File Classification
|
|
10
|
+
|
|
11
|
+
```mermaid
|
|
12
|
+
flowchart TD
|
|
13
|
+
F[File in allhands root] --> G{gitignored?}
|
|
14
|
+
G -- Yes --> X1[Excluded: gitignored]
|
|
15
|
+
G -- No --> I{internal?}
|
|
16
|
+
I -- Yes --> X2[Excluded: internal-only]
|
|
17
|
+
I -- No --> D[Distributable]
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
[ref:src/lib/manifest.ts:Manifest:e06b487] loads two data sources at construction:
|
|
21
|
+
- **`.internal.json`** -- Lists glob patterns for internal-only files (not shipped to consumers)
|
|
22
|
+
- **`.gitignore` files** -- Parsed by [ref:src/lib/gitignore.ts:GitignoreFilter:0ee79f8] across the full directory tree
|
|
23
|
+
|
|
24
|
+
A file is distributable if and only if it passes both checks: `!isInternal(path) && !isGitignored(path)`.
|
|
25
|
+
|
|
26
|
+
## Gitignore Parsing
|
|
27
|
+
|
|
28
|
+
The gitignore system replicates git's own ignore semantics rather than shelling out to `git check-ignore`. This was a deliberate choice -- the allhands root may not itself be a git repository (e.g., when running from an npm package).
|
|
29
|
+
|
|
30
|
+
[ref:src/lib/gitignore.ts:parseGitignoreFile:0ee79f8] handles:
|
|
31
|
+
- Comment lines (`#`) and blank lines
|
|
32
|
+
- Negation patterns (`!pattern`)
|
|
33
|
+
- Directory-scoped patterns (trailing `/`)
|
|
34
|
+
- Root-relative patterns (leading `/`)
|
|
35
|
+
- Level-agnostic patterns (no slash -- matches at any depth via `**/` prefix)
|
|
36
|
+
|
|
37
|
+
[ref:src/lib/gitignore.ts:matchesPattern:0ee79f8] resolves each rule relative to the `.gitignore` file's directory, matching git's behavior where nested `.gitignore` files scope their rules to their own subtree.
|
|
38
|
+
|
|
39
|
+
[ref:src/lib/gitignore.ts:GitignoreFilter:0ee79f8] walks the entire directory tree, loading every `.gitignore` it encounters. The last-match-wins evaluation order mirrors git's precedence rules, with negation patterns able to re-include previously ignored paths.
|
|
40
|
+
|
|
41
|
+
## Byte-Level Comparison
|
|
42
|
+
|
|
43
|
+
[ref:src/lib/manifest.ts:filesAreDifferent:e06b487] performs an optimized two-step comparison:
|
|
44
|
+
1. **Size check** -- If file sizes differ, return `true` immediately (no I/O beyond stat)
|
|
45
|
+
2. **Content check** -- Full buffer comparison via `Buffer.equals`
|
|
46
|
+
|
|
47
|
+
This avoids timestamp-based false positives that would trigger unnecessary conflict resolution during sync.
|
|
48
|
+
|
|
49
|
+
## Directory Walking
|
|
50
|
+
|
|
51
|
+
[ref:src/lib/fs-utils.ts:walkDir:3041b62] provides the recursive traversal used by both the gitignore filter and dotfile restoration. It skips `.git` and `node_modules` directories -- these are never relevant for distribution or ignore-rule collection.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Allhands root path resolution that discovers the package source directory via ALLHANDS_PATH env var or import.meta.url-based package-relative traversal"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Path Resolution
|
|
6
|
+
|
|
7
|
+
[ref:src/lib/paths.ts:getAllhandsRoot:696872e] is the single function responsible for answering: "where are the allhands source files?" Every command depends on this answer to locate the manifest, distributable files, and configuration.
|
|
8
|
+
|
|
9
|
+
## Resolution Strategy
|
|
10
|
+
|
|
11
|
+
```mermaid
|
|
12
|
+
flowchart TD
|
|
13
|
+
A[getAllhandsRoot called] --> B{ALLHANDS_PATH env set?}
|
|
14
|
+
B -- Yes --> C{resolved path has .internal.json?}
|
|
15
|
+
C -- Yes --> D[Return env path]
|
|
16
|
+
C -- No --> E[Fall through to package discovery]
|
|
17
|
+
B -- No --> E
|
|
18
|
+
E --> F{__dirname/.. has .internal.json?}
|
|
19
|
+
F -- Yes --> G[Return parent of bin/]
|
|
20
|
+
F -- No --> H{__dirname/../.. has .internal.json?}
|
|
21
|
+
H -- Yes --> I[Return grandparent]
|
|
22
|
+
H -- No --> J[Throw Error]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Two Discovery Modes
|
|
26
|
+
|
|
27
|
+
| Mode | When | How |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| **Env var** | Local development, testing | `ALLHANDS_PATH` points directly to the repo root |
|
|
30
|
+
| **Package-relative** | Production (`npx` usage) | Walks up from the bundled `bin/cli.js` location |
|
|
31
|
+
|
|
32
|
+
The `.internal.json` file serves as a sentinel -- its presence confirms the directory is a valid allhands root. This avoids false positives from similarly-named directories.
|
|
33
|
+
|
|
34
|
+
## Package-Relative Traversal
|
|
35
|
+
|
|
36
|
+
After esbuild bundles the CLI into `bin/cli.js`, the runtime `import.meta.url` resolves to that file's location. The function tries two levels of parent traversal:
|
|
37
|
+
- One level up: handles `bin/cli.js` -> package root
|
|
38
|
+
- Two levels up: handles `dist/lib/paths.js` -> package root (unbundled development)
|
|
39
|
+
|
|
40
|
+
## Upstream Constants
|
|
41
|
+
|
|
42
|
+
[ref:src/lib/paths.ts:UPSTREAM_REPO:696872e] and [ref:src/lib/paths.ts:UPSTREAM_OWNER:696872e] define the canonical upstream repository coordinates. These are used exclusively by the push command for fork and PR operations. Hardcoding them (rather than reading from git remotes) ensures push always targets the correct upstream regardless of the user's remote configuration.
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "all-hands-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Agentic harness for model-first software development",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"all-hands": "./bin/sync-cli.js",
|
|
8
|
+
"allhands": "./bin/sync-cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "esbuild src/sync-cli.ts --bundle --platform=node --target=node18 --outfile=bin/sync-cli.js --format=esm --banner:js=\"#!/usr/bin/env node\"",
|
|
12
|
+
"dev": "npm run build -- --watch",
|
|
13
|
+
"prepublishOnly": "npm run build",
|
|
14
|
+
"format": "prettier --write ."
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"claude",
|
|
18
|
+
"agents",
|
|
19
|
+
"agentic",
|
|
20
|
+
"harness",
|
|
21
|
+
"sync-cli"
|
|
22
|
+
],
|
|
23
|
+
"author": "kalem-edlin",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/kalem-edlin/all-hands-cli"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^20.10.0",
|
|
34
|
+
"@types/yargs": "^17.0.32",
|
|
35
|
+
"esbuild": "^0.24.0",
|
|
36
|
+
"tsx": "^4.19.0",
|
|
37
|
+
"typescript": "^5.3.0"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"minimatch": "^10.0.1",
|
|
41
|
+
"yargs": "^17.7.2"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Install the ah shim to ~/.local/bin
|
|
3
|
+
# Run this during local development to set up the ah command
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
SHIM_DIR="$HOME/.local/bin"
|
|
8
|
+
SHIM_PATH="$SHIM_DIR/ah"
|
|
9
|
+
|
|
10
|
+
mkdir -p "$SHIM_DIR"
|
|
11
|
+
|
|
12
|
+
cat > "$SHIM_PATH" << 'EOF'
|
|
13
|
+
#!/bin/bash
|
|
14
|
+
# AllHands CLI shim - finds and executes project-local .allhands/ah
|
|
15
|
+
# Installed by: npx all-hands init
|
|
16
|
+
|
|
17
|
+
dir="$PWD"
|
|
18
|
+
while [ "$dir" != "/" ]; do
|
|
19
|
+
if [ -x "$dir/.allhands/ah" ]; then
|
|
20
|
+
exec "$dir/.allhands/ah" "$@"
|
|
21
|
+
fi
|
|
22
|
+
dir="$(dirname "$dir")"
|
|
23
|
+
done
|
|
24
|
+
|
|
25
|
+
echo "error: not in an all-hands project (no .allhands/ah found)" >&2
|
|
26
|
+
echo "hint: run 'npx all-hands init .' to initialize this project" >&2
|
|
27
|
+
exit 1
|
|
28
|
+
EOF
|
|
29
|
+
|
|
30
|
+
chmod +x "$SHIM_PATH"
|
|
31
|
+
|
|
32
|
+
echo "Installed: $SHIM_PATH"
|
|
33
|
+
|
|
34
|
+
# Check if in PATH
|
|
35
|
+
if [[ ":$PATH:" != *":$SHIM_DIR:"* ]]; then
|
|
36
|
+
echo ""
|
|
37
|
+
echo "⚠️ $SHIM_DIR is not in your PATH"
|
|
38
|
+
echo "Add this to your ~/.zshrc or ~/.bashrc:"
|
|
39
|
+
echo " export PATH=\"\$HOME/.local/bin:\$PATH\""
|
|
40
|
+
fi
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Pre-pack script: Rename dotfiles that npm hardcode-excludes
|
|
3
|
+
# Run this in CI before `npm pack`
|
|
4
|
+
# Only targets .claude/ directory (what we distribute)
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
DOTFILES=(".gitignore" ".npmrc" ".npmignore")
|
|
9
|
+
|
|
10
|
+
for dotfile in "${DOTFILES[@]}"; do
|
|
11
|
+
nodot="${dotfile#.}"
|
|
12
|
+
|
|
13
|
+
# Only rename within .claude/, excluding node_modules
|
|
14
|
+
# Use /usr/bin/find to avoid fd alias
|
|
15
|
+
/usr/bin/find .claude -name "$dotfile" \
|
|
16
|
+
-not -path "*/node_modules/*" \
|
|
17
|
+
-type f | while read -r file; do
|
|
18
|
+
dir=$(dirname "$file")
|
|
19
|
+
newname="$dir/$nodot"
|
|
20
|
+
echo "Renaming: $file -> $newname"
|
|
21
|
+
mv "$file" "$newname"
|
|
22
|
+
done
|
|
23
|
+
done
|
|
24
|
+
|
|
25
|
+
echo "Pre-pack dotfile rename complete"
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harness-maintenance-skill
|
|
3
|
+
domain_name: infrastructure
|
|
4
|
+
type: refactor
|
|
5
|
+
status: completed
|
|
6
|
+
dependencies: []
|
|
7
|
+
branch: refactor/harness-maintenance-skill
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Harness Maintenance Skill Restructure
|
|
11
|
+
|
|
12
|
+
## Motivation
|
|
13
|
+
|
|
14
|
+
The harness-maintenance skill currently serves as an architecture reference document — it describes the system but doesn't effectively guide agents through specific maintenance scenarios. Per **Knowledge Compounding**, maintenance knowledge needs to compound into every harness modification, not just exist as a passive reference.
|
|
15
|
+
|
|
16
|
+
The current state:
|
|
17
|
+
- The skill's SKILL.md is a monolithic reference doc (~375 lines) covering everything from TUI lifecycle to hook categories
|
|
18
|
+
- There are no reference subdocs — all knowledge lives in one file, violating **Context is Precious**
|
|
19
|
+
- Skill discovery is enumeration-only (`ah skills list`), so agents match via reasoning alone
|
|
20
|
+
- The existing `WRITING_HARNESS_FLOWS.md` shared flow contains valuable flow-authoring knowledge but is disconnected from the skill system
|
|
21
|
+
- `CREATE_VALIDATION_TOOLING_SPEC.md` contains validation suite creation knowledge that should be accessible as a reference, not only as a flow
|
|
22
|
+
- No flows exist for other maintenance domains (commands, hooks, MCP, orchestration, skills, knowledge/compounding)
|
|
23
|
+
|
|
24
|
+
Engineer desires a **hub-and-spoke model**: SKILL.md routes to domain-specific reference docs based on the maintenance scenario, with first principles and architectural invariants always front-loaded. Corresponding thin flows in `flows/harness/` serve as execution entry points that discover the skill automatically.
|
|
25
|
+
|
|
26
|
+
## Goals
|
|
27
|
+
|
|
28
|
+
### 1. Restructure the harness-maintenance skill directory
|
|
29
|
+
|
|
30
|
+
Engineer expects the skill to follow this structure:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
skills/harness-maintenance/
|
|
34
|
+
SKILL.md # Hub: principles, invariants, routing table
|
|
35
|
+
references/
|
|
36
|
+
writing-flows.md # Flow authoring best practices
|
|
37
|
+
tools-commands-mcp-hooks.md # Extending CLI capability surface
|
|
38
|
+
core-architecture.md # TUI, event loop, orchestration, prompt types, emergent
|
|
39
|
+
harness-skills.md # Creating and maintaining skills
|
|
40
|
+
validation-tooling.md # Creating validation suites and tooling specs
|
|
41
|
+
knowledge-compounding.md # Docs, knowledge indexes, solutions, memories
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 2. Restructure SKILL.md as a routing hub
|
|
45
|
+
|
|
46
|
+
Engineer expects SKILL.md to contain:
|
|
47
|
+
- Linked references to `.allhands/principles.md` and core pillar documents so they are always considered
|
|
48
|
+
- Architectural invariants that apply across all maintenance scenarios (concise, not exhaustive)
|
|
49
|
+
- A reference routing table mapping maintenance scenarios to specific reference docs
|
|
50
|
+
|
|
51
|
+
Engineer desires concise full coverage — no missed principles, but no bloat. The SKILL.md should be easy to maintain itself. Per **Context is Precious**, agents should only load the reference they need, not all of them.
|
|
52
|
+
|
|
53
|
+
### 3. Create reference docs with domain-specific knowledge
|
|
54
|
+
|
|
55
|
+
Each reference doc should provide:
|
|
56
|
+
- The core principles most relevant to that domain
|
|
57
|
+
- Concise full coverage of the domain's use cases, conventions, and patterns
|
|
58
|
+
- Grounded in codebase reality (file paths, schema fields, command examples)
|
|
59
|
+
- Easy to maintain — structured so updates are localized
|
|
60
|
+
|
|
61
|
+
Content sources:
|
|
62
|
+
- `writing-flows.md`: Migrate knowledge from current `WRITING_HARNESS_FLOWS.md` (the flow file remains but becomes thin)
|
|
63
|
+
- `tools-commands-mcp-hooks.md`: Extract from current SKILL.md sections on hooks, commands, and extension points. These are adjacent enough to share one reference since they all follow the auto-discovery pattern.
|
|
64
|
+
- `core-architecture.md`: Extract from current SKILL.md sections on TUI, event loop, agent profiles, schemas, hypothesis domains. Should capture both the architectural map (how things connect) and invariants (what must be preserved).
|
|
65
|
+
- `harness-skills.md`: New content covering the skill schema, directory conventions, discovery mechanism, and when/how to create new skills
|
|
66
|
+
- `validation-tooling.md`: Migrate knowledge from `CREATE_VALIDATION_TOOLING_SPEC.md` (research, tool validation, suite writing philosophy, evidence capture patterns)
|
|
67
|
+
- `knowledge-compounding.md`: New content covering documentation schema, knowledge indexes, solutions, memories, and the compounding principles for maintaining these
|
|
68
|
+
|
|
69
|
+
### 4. Create thin flows in `flows/harness/`
|
|
70
|
+
|
|
71
|
+
Each flow serves as an execution entry point for a specific maintenance domain:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
flows/harness/
|
|
75
|
+
WRITING_HARNESS_FLOWS.md
|
|
76
|
+
WRITING_HARNESS_TOOLS.md
|
|
77
|
+
WRITING_HARNESS_ORCHESTRATION.md
|
|
78
|
+
WRITING_HARNESS_SKILLS.md
|
|
79
|
+
WRITING_HARNESS_VALIDATION_TOOLING.md
|
|
80
|
+
WRITING_HARNESS_KNOWLEDGE.md
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Engineer expects each flow to be thin — its primary step is skill discovery via `ah skills` which routes to the correct reference. The flow provides the execution context (inputs, outputs, constraints), the skill reference provides the knowledge. This ensures the skill gets automatically loaded when agents enter any harness maintenance flow.
|
|
84
|
+
|
|
85
|
+
### 5. Migrate existing flow content
|
|
86
|
+
|
|
87
|
+
- `flows/shared/WRITING_HARNESS_FLOWS.md`: Deep knowledge moves to `references/writing-flows.md`. The flow becomes a thin entry point that discovers the skill. The existing CLAUDE.md reference to this file continues to work.
|
|
88
|
+
- `flows/shared/CREATE_VALIDATION_TOOLING_SPEC.md`: Research, tool validation, suite writing philosophy, and evidence capture knowledge moves to `references/validation-tooling.md`. Execution steps (spec creation, engineer interview, handoff) stay in the flow or move to the new `WRITING_HARNESS_VALIDATION_TOOLING.md`.
|
|
89
|
+
|
|
90
|
+
## Non-Goals
|
|
91
|
+
|
|
92
|
+
- Changing the skill schema itself (no new required frontmatter fields, no `tools` field). Schema improvements are a separate concern.
|
|
93
|
+
- Adding programmatic skill matching (`ah skills match`, `ah skills search`). Discovery improvements are out of scope.
|
|
94
|
+
- Bridging All Hands skills with Claude Code native skill features. That divergence is a separate architectural decision.
|
|
95
|
+
- Creating new validation suites or other non-maintenance skills. This milestone is about the maintenance skill only.
|
|
96
|
+
- Modifying the harness TypeScript source code. This is a content and organization change.
|
|
97
|
+
|
|
98
|
+
## Open Questions
|
|
99
|
+
|
|
100
|
+
- **Reference doc density calibration**: The validation-suite schema mandates 5 structured sections. Should reference docs follow a similar required-sections pattern, or stay flexible per **Frontier Models are Capable**? Architect should determine the right structure that balances maintainability with coverage.
|
|
101
|
+
- **CLAUDE.md routing update**: Currently CLAUDE.md points directly to `WRITING_HARNESS_FLOWS.md` in `flows/shared/`. Should this be updated to point to the new `flows/harness/WRITING_HARNESS_FLOWS.md`, or should the shared flow remain as a redirect? Architect should decide based on how other CLAUDE.md references work.
|
|
102
|
+
- **Existing SKILL.md content disposition**: The current SKILL.md has ~375 lines of architecture reference. Some of this maps cleanly to specific reference docs, but some cross-cuts (e.g., "Key Design Patterns" applies to multiple domains). Architect should decide how to decompose cross-cutting content — duplicate where relevant, or keep a minimal cross-cutting section in SKILL.md.
|
|
103
|
+
- **Flow location**: Engineer specified `flows/harness/` as the subdirectory. Existing convention uses `flows/shared/` for progressively disclosed flows with `<inputs>`/`<outputs>` tags. Architect should determine whether `flows/harness/` is a new convention or should follow `flows/shared/harness/`.
|
|
104
|
+
|
|
105
|
+
## Technical Considerations
|
|
106
|
+
|
|
107
|
+
- The existing `WRITING_HARNESS_FLOWS.md` is referenced in `CLAUDE.md` which is loaded at conversation start for every agent. Any path change must update that reference.
|
|
108
|
+
- Skill glob patterns in the current SKILL.md frontmatter already cover all `.allhands/` subdirectories. The restructured skill should maintain the same glob coverage so discovery still works for any harness file modification.
|
|
109
|
+
- The `ah schema skill` command defines minimal frontmatter (`name`, `description`, `globs`, optional `version`). The `references/` subdirectory pattern is a convention, not schema-enforced — the spec should establish clear conventions for reference doc naming and structure.
|
|
110
|
+
- `CREATE_VALIDATION_TOOLING_SPEC.md` is currently referenced by `ASSESS_VALIDATION_TOOLING.md` flow. This reference chain must be preserved or updated during migration.
|
|
111
|
+
- The skill currently has `version: 1.0.0`. This restructure should bump to `2.0.0` to signal the architectural change in how maintenance knowledge is organized.
|
|
112
|
+
|
|
113
|
+
## Implementation Reality
|
|
114
|
+
|
|
115
|
+
### What Was Implemented
|
|
116
|
+
|
|
117
|
+
All 5 spec goals were achieved across 14 prompts (3 planned, 5 emergent, 5 review-fix, 1 user-patch):
|
|
118
|
+
|
|
119
|
+
- **Goal 1 (Skill directory restructure)**: SKILL.md decomposed from 375 lines to 61-line routing hub + 6 domain-specific reference docs in `references/`. Version bumped to 2.0.0. Knowledge audit confirmed 95.7% preservation (45/47 units), 2 intentionally omitted.
|
|
120
|
+
- **Goal 2 (SKILL.md as routing hub)**: Single merged routing table with scenario and trigger columns. Principles reference, cross-cutting patterns, maintainer checklist, and cross-skill disambiguation all in hub.
|
|
121
|
+
- **Goal 3 (Reference docs)**: All 6 created with domain-specific content, cross-domain navigation footers, and flexible per-domain structure.
|
|
122
|
+
- **Goal 4 (Thin flows)**: All 6 flows created at 27 lines each in `flows/harness/`. Identical structural pattern with domain-specific `<goal>` principle citations.
|
|
123
|
+
- **Goal 5 (Flow migration)**: CLAUDE.md updated to reference skill directly (not a flow). `flows/shared/WRITING_HARNESS_FLOWS.md` thinned to 11-line redirect. `CREATE_VALIDATION_TOOLING_SPEC.md` deep knowledge migrated to skill reference.
|
|
124
|
+
|
|
125
|
+
### How Engineer Desires Evolved
|
|
126
|
+
|
|
127
|
+
- **CLAUDE.md routing**: Engineer chose to reference the skill itself rather than a specific flow — a more fundamental routing change than the spec anticipated. CLAUDE.md scope also broadened from `flows/` to all `.allhands/` files.
|
|
128
|
+
- **[ref:] anchors rejected**: Emergent prompt 04 added code reference anchors to ground docs in source. Engineer directed removal (prompt 12) because `ah docs validate`/`finalize` are scoped to `docs/` only — anchors in skill references silently go stale.
|
|
129
|
+
- **Audit artifacts rejected**: Knowledge completeness audit (prompt 06) was valuable as a process but engineer directed removal of the embedded HTML comment artifact from SKILL.md — stale metadata violates Context is Precious.
|
|
130
|
+
- **Consolidated routing**: Engineer preferred merging duplicate routing tables (Reference Routing + Maintenance Triggers) into a single table rather than maintaining parallel routing structures.
|
|
131
|
+
- **Naming consistency**: `harness_skills.md` (snake_case) renamed to `harness-skills.md` (kebab-case) — flagged independently by 3 jury reviewers.
|
|
132
|
+
|
|
133
|
+
### Key Technical Decisions
|
|
134
|
+
|
|
135
|
+
- **Hub-and-spoke with single hub table**: One routing table serves both scenario-based routing ("I'm working on flows") and change-based routing ("I changed a hook") via dual columns.
|
|
136
|
+
- **Cross-skill disambiguation**: Explicit Related Skills section resolves glob overlap between harness-maintenance and claude-code-patterns skills.
|
|
137
|
+
- **Scope guard for docs tooling**: Maintainer checklist explicitly prohibits `ah docs validate`/`finalize` on skill references.
|
|
138
|
+
- **Redirect flow preserved**: `flows/shared/WRITING_HARNESS_FLOWS.md` kept as 11-line redirect distinguishing knowledge source (skill reference) from execution source (harness flow).
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: git-spec-lifecycle-management
|
|
3
|
+
domain_name: infrastructure
|
|
4
|
+
type: milestone
|
|
5
|
+
status: roadmap
|
|
6
|
+
dependencies: []
|
|
7
|
+
branch: feature/git-spec-lifecycle-management
|
|
8
|
+
initial_workflow_domain: milestone
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Motivation
|
|
12
|
+
|
|
13
|
+
Git lifecycle management is the harness's primary pain point. The current implementation is fragile, inconsistent, and too complex. The CLI and TUI disagree on completion behavior (CLI moves specs to `specs/`, TUI moves to `specs/completed/`). There are zero `git fetch` or `git pull` operations anywhere in the codebase, so branches start stale and stay stale. The `switch-spec` action has no uncommitted changes guard. The `mark-completed` action runs destructive `git checkout -- . && git clean -fd` automatically — even if the preceding commit failed. `commitFilesToBranch` uses temp worktree tricks that introduce race conditions. `ah specs persist` bundles two distinct concerns (commit spec to main + create feature branch) into one command. Multiple worktrees create ambiguity about where a spec is actively being worked on, with no cross-worktree detection.
|
|
14
|
+
|
|
15
|
+
The engineer desires a model where the harness performs minimal, predictable git operations and the developer is responsible for being in the right state. Zero git errors from the harness. A mental model that fits on an index card.
|
|
16
|
+
|
|
17
|
+
## Goals
|
|
18
|
+
|
|
19
|
+
### Guiding Principles
|
|
20
|
+
|
|
21
|
+
1. **Developer preparedness over harness magic** — the harness does minimal, predictable git ops. The developer is responsible for being in the right state (on main, conflicts resolved).
|
|
22
|
+
2. **Forward-only lifecycle** — specs move from roadmap to completed. No resurrection, no clearing, no going backwards.
|
|
23
|
+
3. **Sync at critical junctures** — remote main is pulled at activation, PR creation, and completion. Not continuously, not silently.
|
|
24
|
+
4. **Errors are signals, not failures** — merge conflicts surface to the user (TUI modal or CLI error for agents). The system doesn't try to be clever about resolution yet.
|
|
25
|
+
5. **Kill what's unnecessary** — if it adds complexity without value, it goes.
|
|
26
|
+
|
|
27
|
+
### Spec Creation
|
|
28
|
+
|
|
29
|
+
- Engineer expects to be on the base branch (main) when creating specs. The harness enforces this — error if not on main.
|
|
30
|
+
- The spec file is written to `specs/roadmap/{name}.spec.md`, committed directly on main, and pushed to remote main.
|
|
31
|
+
- Only the newly added spec file is committed and pushed — not a blanket push of main.
|
|
32
|
+
- Spec creation no longer creates a feature branch. Branch creation happens at activation time.
|
|
33
|
+
|
|
34
|
+
### Spec Activation (Switching To)
|
|
35
|
+
|
|
36
|
+
- Activation pulls `origin main` first.
|
|
37
|
+
- If the spec's feature branch does not exist, it is created from the updated main.
|
|
38
|
+
- If the spec's feature branch already exists, main is merged into it to keep it current.
|
|
39
|
+
- If merge conflicts arise, the error is propagated: TUI shows a blocking warning modal describing the conflicts; CLI returns an error for agents to handle autonomously.
|
|
40
|
+
- Before activating, the harness checks all local git worktrees for an existing `.planning/` directory corresponding to this spec.
|
|
41
|
+
- If found in another worktree: TUI shows a warning modal with the worktree path, suggesting the user switch to that directory. CLI returns an error with the path for agents to handle.
|
|
42
|
+
- If not found elsewhere: proceeds with activation, creating `.planning/` in the current project if needed.
|
|
43
|
+
- The developer is checked out onto the feature branch after successful activation.
|
|
44
|
+
|
|
45
|
+
### Spec Completion
|
|
46
|
+
|
|
47
|
+
- Pulls `origin main` into the current feature branch.
|
|
48
|
+
- If merge conflicts exist: surfaces the conflicts to the user (TUI modal / CLI error) and aborts. The user must resolve conflicts and push to remote themselves, then retry completion.
|
|
49
|
+
- If no conflicts: moves the spec file from `specs/roadmap/{name}.spec.md` to `specs/{name}.spec.md` on the feature branch, updates frontmatter `status` to `completed`, commits, and pushes to remote.
|
|
50
|
+
- Assumes the feature branch will be merged back to main via PR, at which point main reflects the spec's completed status and all dependent branches see it.
|
|
51
|
+
- Engineer expects that no branch cleanup or `.planning/` cleanup occurs — that is the developer's responsibility.
|
|
52
|
+
|
|
53
|
+
### Ideation on Active Milestone
|
|
54
|
+
|
|
55
|
+
- When ideation detects a current milestone is selected (on a feature branch with an active spec), it enters a mode that builds upon the existing spec.
|
|
56
|
+
- The existing spec file is revised/appended with new ideation content.
|
|
57
|
+
- Any existing planning content (alignment docs, prompts) is treated as stale — the planner re-plans from the updated spec on the next planning run.
|
|
58
|
+
|
|
59
|
+
### Removals
|
|
60
|
+
|
|
61
|
+
- **Kill `specs/completed/` directory** — two directories only: `specs/roadmap/` for planned, `specs/` for completed. `loadAllSpecs` category logic simplifies accordingly.
|
|
62
|
+
- **Kill `ah specs persist` as a standalone command** — its responsibilities are split between creation (commit + push to main) and activation (branch creation + checkout + sync).
|
|
63
|
+
- **Kill `commitFilesToBranch`** — no more temp worktree commit tricks. Spec creation is a direct commit on main.
|
|
64
|
+
- **Kill `ah specs resurrect`** — specs move forward only. Once completed, they're done.
|
|
65
|
+
- **Kill TUI `clear-spec` action** — no deactivation concept. Developer manually checks out main if needed.
|
|
66
|
+
- **Kill destructive auto-cleanup** — no `git checkout -- . && git clean -fd` on completion. No `git stash` tricks.
|
|
67
|
+
|
|
68
|
+
## Technical Considerations
|
|
69
|
+
|
|
70
|
+
### Current Git Audit Findings (Grounded in Codebase Exploration)
|
|
71
|
+
|
|
72
|
+
- **Zero `git fetch`/`git pull` in the entire codebase** — the harness only pushes, never syncs from remote. This is a root cause of stale branches.
|
|
73
|
+
- **Raw `execSync` with string interpolation** — all git commands use unescaped string interpolation. Branch names from spec frontmatter could break commands. Shell escaping approach is an open question for the planner.
|
|
74
|
+
- **`hasUncommittedChanges` returns false on git failure** (`git.ts:155`) — if git itself fails, the function claims no uncommitted changes, potentially enabling destructive operations. This false-negative pattern needs fixing.
|
|
75
|
+
- **`switch-spec` has no uncommitted changes guard** — unlike other TUI actions, it does `git checkout` without checking dirty state first.
|
|
76
|
+
- **TUI `mark-completed` runs `git add -A specs/`** — stages all changes under `specs/`, not just the moved file. The new model should stage only the specific file.
|
|
77
|
+
- **Stash pop order bug in compaction.ts** — stashes files in forward order but pops LIFO, causing incorrect restoration order. Tangential to this milestone but worth noting.
|
|
78
|
+
- **No command injection protection** — branch names, spec IDs, and file paths are interpolated directly into shell commands without escaping.
|
|
79
|
+
|
|
80
|
+
### Remote Sync Points
|
|
81
|
+
|
|
82
|
+
The new model introduces `git fetch`/`git pull` at three junctures:
|
|
83
|
+
1. **Activation** — pull origin main into the feature branch
|
|
84
|
+
2. **PR creation** — pull origin main into the feature branch (Assuming PR submission workflow exists)
|
|
85
|
+
3. **Completion** — pull origin main into the feature branch, abort on conflicts
|
|
86
|
+
|
|
87
|
+
### Directory Structure Simplification
|
|
88
|
+
|
|
89
|
+
Current (three directories with confused semantics):
|
|
90
|
+
```
|
|
91
|
+
specs/roadmap/ -> planned specs
|
|
92
|
+
specs/ -> ambiguous (CLI completion target)
|
|
93
|
+
specs/completed/ -> TUI completion target
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
New (two directories with clear semantics):
|
|
97
|
+
```
|
|
98
|
+
specs/roadmap/ -> planned/in-progress specs
|
|
99
|
+
specs/ -> completed specs
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Conflict Resolution (Future TODO)
|
|
103
|
+
|
|
104
|
+
Engineer desires future agentic conflict resolution (potentially using open-code SDK with task context). For this milestone, merge conflicts are surfaced to the developer via TUI modals or CLI errors. This is explicitly marked as a future capability, not in scope for this milestone.
|
|
105
|
+
|
|
106
|
+
## Open Questions
|
|
107
|
+
|
|
108
|
+
- What shell escaping approach should be used for git command arguments? (e.g., `shell-escape` library, argument arrays with `spawnSync`, or manual escaping)
|
|
109
|
+
- Should the `git push` after spec creation be a `git push origin main` targeting just the spec commit, or a regular `git push`?
|
|
110
|
+
- How should the TUI modal for worktree detection be structured? (blocking vs dismissible, what information to show beyond the worktree path)
|
|
111
|
+
- When ideation revises an active spec, should it explicitly mark planning content as stale (e.g., a frontmatter flag), or does the planner infer staleness from spec file modification timestamps?
|
|
112
|
+
- How does the removal of `persist` affect the `CREATE_SPEC.md` flow and any other flows that call it?
|
|
113
|
+
- What happens if the developer is on main but main has uncommitted changes unrelated to the spec? Should spec creation refuse to commit, or only commit the spec file?
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sync-init-flag
|
|
3
|
+
domain_name: infrastructure
|
|
4
|
+
type: milestone
|
|
5
|
+
status: completed
|
|
6
|
+
dependencies: []
|
|
7
|
+
branch: feature/sync-init-flag
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Sync CLI `--init` Flag
|
|
11
|
+
|
|
12
|
+
## Motivation
|
|
13
|
+
|
|
14
|
+
The sync command currently treats all distributable files identically — every sync overwrites the target repo's copies. This works for harness internals (flows, agents, schemas) that should always match the source, but is destructive for files that target repos are expected to customize: project settings, hook configuration, validation suites, and non-core skills.
|
|
15
|
+
|
|
16
|
+
Engineers syncing harness updates to a target repo lose their repo-specific `.allhands/settings.json`, `.claude/settings.json` (all hooks), `.tldr/config.json`, validation suites, and any custom skills. The only workaround is manual backup and restore after every sync.
|
|
17
|
+
|
|
18
|
+
The harness needs a clean separation between "always ship" files (harness internals) and "init-only" files (target-repo-owned configuration seeded once as defaults).
|
|
19
|
+
|
|
20
|
+
## Goals
|
|
21
|
+
|
|
22
|
+
### 1. `--init` Flag on the `sync` Command
|
|
23
|
+
|
|
24
|
+
Engineer expects a `--init` flag on the sync command (`src/commands/sync.ts`). Behavior:
|
|
25
|
+
|
|
26
|
+
- **Without `--init`**: Init-only files are withheld from sync. Target repo customizations are preserved. This is the common-case operation.
|
|
27
|
+
- **With `--init`**: Init-only files are included in sync, following the existing replace flow (conflict detection, backup, overwrite). This is for first-time setup or resetting to defaults.
|
|
28
|
+
|
|
29
|
+
The `push` command never ships init-only files regardless of flags — PRs contain only always-shipped files.
|
|
30
|
+
|
|
31
|
+
### 2. `.internal.json` Restructure
|
|
32
|
+
|
|
33
|
+
Engineer expects `.internal.json` to move from a flat glob list to a two-key structure:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"internal": ["src/**", "bin/**", "...existing patterns..."],
|
|
38
|
+
"initOnly": [
|
|
39
|
+
".allhands/skills/**",
|
|
40
|
+
"!.allhands/skills/claude-code-patterns/**",
|
|
41
|
+
"!.allhands/skills/harness-maintenance/**",
|
|
42
|
+
".allhands/validation/**",
|
|
43
|
+
".allhands/settings.json",
|
|
44
|
+
".allhands/docs.json",
|
|
45
|
+
".tldr/config.json",
|
|
46
|
+
".claude/settings.json"
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Resolution logic:
|
|
52
|
+
1. Matches `internal` → never ship
|
|
53
|
+
2. Matches `initOnly` → ship only with `--init` on `sync`, never on `push`
|
|
54
|
+
3. Everything else → always ship
|
|
55
|
+
|
|
56
|
+
The `initOnly` list supports negation patterns (`!` prefix) to carve out exceptions. Skills use this: `.allhands/skills/**` makes all skills init-only, while `!.allhands/skills/claude-code-patterns/**` and `!.allhands/skills/harness-maintenance/**` exempt the two core skills so they always ship.
|
|
57
|
+
|
|
58
|
+
New skills added to `.allhands/skills/` automatically become init-only without manual configuration.
|
|
59
|
+
|
|
60
|
+
### 3. `docs.json` Moves to Init-Only
|
|
61
|
+
|
|
62
|
+
Engineer expects `docs.json` to move from the `internal` list (never distributed) to the `initOnly` list. This means target repos receive it on first `--init` sync as a default, then own it independently. The existing JSON schema at `harness/src/schemas/docs.schema.json` is sufficient — no schema changes needed.
|
|
63
|
+
|
|
64
|
+
### 4. Manifest System Updates
|
|
65
|
+
|
|
66
|
+
The `Manifest` class (`src/lib/manifest.ts`) needs to understand the new `.internal.json` structure. Engineer expects:
|
|
67
|
+
|
|
68
|
+
- Parsing of the two-key format with negation pattern support in `initOnly`
|
|
69
|
+
- An API surface that distinguishes "not distributable" (internal), "init-only", and "always distributable"
|
|
70
|
+
- The `push` command's `collectFilesToPush` uses the manifest to exclude both `internal` and `initOnly` files
|
|
71
|
+
- The `sync` command conditionally includes `initOnly` files based on the `--init` flag
|
|
72
|
+
|
|
73
|
+
### 5. Remove Dead `fullReplace` Code
|
|
74
|
+
|
|
75
|
+
`src/lib/full-replace.ts` exports `fullReplace()` but it is not imported or called anywhere in the codebase. Engineer expects it removed as dead code cleanup.
|
|
76
|
+
|
|
77
|
+
### 6. README Documentation
|
|
78
|
+
|
|
79
|
+
Engineer expects the README to document the `--init` flag: its purpose, when to use it (first-time setup), and that regular syncs preserve target-repo configuration.
|
|
80
|
+
|
|
81
|
+
## Non-Goals
|
|
82
|
+
|
|
83
|
+
- **Auto-detection of first-time setup** — The sync command does not infer whether `--init` is needed. Documentation guides the engineer.
|
|
84
|
+
- **Merge strategies for config files** — No partial merging of settings or hooks. Init-only files are all-or-nothing per the existing replace flow.
|
|
85
|
+
- **Changes to the `pull-manifest` command** — The pull-manifest scaffolding is unaffected.
|
|
86
|
+
- **New validation suites or skills** — This milestone establishes the init-only gate, not new content.
|
|
87
|
+
|
|
88
|
+
## Open Questions
|
|
89
|
+
|
|
90
|
+
- **Manifest class API design** — How should the Manifest class expose the init-only concept? Options include a new `isInitOnly(path)` method alongside `isDistributable(path)`, or a single method returning a tri-state (`internal | initOnly | distributable`). Architect should determine the cleanest API that serves both `sync` and `push` consumers.
|
|
91
|
+
- **Negation pattern implementation** — The `initOnly` list needs gitignore-style negation. The codebase already uses `GitignoreFilter` (from `src/lib/gitignore.ts`) for gitignore parsing. Architect should determine whether to reuse that infrastructure or use a lighter pattern matcher for the `initOnly` patterns.
|
|
92
|
+
- **Backward compatibility of `.internal.json`** — Existing consumer repos may have tooling that reads `.internal.json` as a flat array. Architect should assess whether a migration path is needed or if the restructure is safe given the file's internal-only nature.
|
|
93
|
+
|
|
94
|
+
## Technical Considerations
|
|
95
|
+
|
|
96
|
+
- The sync command (`src/commands/sync.ts`) currently calls `manifest.getDistributableFiles()` which returns all non-internal, non-gitignored files. The `--init` flag adds a conditional filter step on the returned set based on `initOnly` patterns.
|
|
97
|
+
- The push command (`src/commands/push.ts`) uses `collectFilesToPush()` which already has a multi-stage filtering pipeline (distributable set → blocklist → include/exclude → gitignore → byte-diff). Adding `initOnly` exclusion is an additional filter stage.
|
|
98
|
+
- `fullReplace` in `src/lib/full-replace.ts` is dead code — exported but never imported. Safe removal with no downstream impact.
|
|
99
|
+
- The `GitignoreFilter` class in `src/lib/gitignore.ts` already handles glob pattern matching with the `ignore` npm package, which natively supports negation patterns. This may be reusable for `initOnly` pattern resolution.
|
|
100
|
+
- `.internal.json` is itself listed in the `internal` array (self-referencing to prevent distribution). This must be preserved in the restructured format.
|
|
101
|
+
|
|
102
|
+
## Implementation Reality
|
|
103
|
+
|
|
104
|
+
**What was implemented**: All 6 goals delivered as specified. No deviations from the original plan.
|
|
105
|
+
|
|
106
|
+
**Open Questions resolved**:
|
|
107
|
+
- **Manifest API**: `isInitOnly(path)` method alongside existing `isDistributable()` — simpler two-method approach over tri-state, since consumers (sync/push) only need a boolean gate
|
|
108
|
+
- **Negation patterns**: Standalone minimatch loop with last-match-wins semantics, not `GitignoreFilter` — appropriate for small, simple root-relative pattern set
|
|
109
|
+
- **Backward compatibility**: Non-issue — `.internal.json` is in its own `internal` list and never distributed to consumer repos
|
|
110
|
+
|
|
111
|
+
**Execution profile**: 4 planned prompts + 1 review-fix (Gemini Code Assist feedback to pre-compile minimatch patterns). All first-attempt. No emergent prompts, no reverts. Prompts 02/03 parallelized successfully after 01 completed.
|
|
112
|
+
|
|
113
|
+
**Key technical decisions**:
|
|
114
|
+
- `getDistributableFiles()` unchanged — still returns init-only files. Filtering happens downstream in sync/push consumers
|
|
115
|
+
- Sync filters by mutating the distributable `Set` in-place before conflict detection
|
|
116
|
+
- Push places init-only guard as the first filter in both Phase 1 and Phase 2 loops, unconditionally excluding init-only files even from `--include` patterns
|
|
117
|
+
- `docs.json` moved from `internal` to `initOnly`, enabling first-time distribution to target repos
|