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,528 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E2E Tests - Validation System
|
|
3
|
+
*
|
|
4
|
+
* Tests the complete validation system including:
|
|
5
|
+
* - Schema validation for prompts, specs, alignment docs
|
|
6
|
+
* - Frontmatter parsing
|
|
7
|
+
* - File type detection
|
|
8
|
+
* - Validation error messages
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
12
|
+
import { join } from 'path';
|
|
13
|
+
import {
|
|
14
|
+
createFixture,
|
|
15
|
+
runValidate,
|
|
16
|
+
runInFixture,
|
|
17
|
+
assertSuccess,
|
|
18
|
+
assertFailure,
|
|
19
|
+
assertFileExists,
|
|
20
|
+
assertValidFrontmatter,
|
|
21
|
+
type TestFixture,
|
|
22
|
+
} from '../harness/index.js';
|
|
23
|
+
|
|
24
|
+
/** Helper to run validate command with full path */
|
|
25
|
+
async function validateFile(fixture: TestFixture, relativePath: string) {
|
|
26
|
+
const filePath = join(fixture.root, relativePath);
|
|
27
|
+
return runInFixture(fixture, ['validate', 'file', filePath]);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
31
|
+
// Test Fixtures
|
|
32
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
33
|
+
|
|
34
|
+
// Valid prompt matching .allhands/schemas/prompt.yaml
|
|
35
|
+
const VALID_PROMPT = `---
|
|
36
|
+
number: 1
|
|
37
|
+
title: Task Title
|
|
38
|
+
type: planned
|
|
39
|
+
planning_session: 1
|
|
40
|
+
status: pending
|
|
41
|
+
dependencies: []
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
# Tasks
|
|
45
|
+
|
|
46
|
+
- Implement the feature
|
|
47
|
+
- Add tests
|
|
48
|
+
|
|
49
|
+
# Acceptance Criteria
|
|
50
|
+
|
|
51
|
+
- Requirements are met
|
|
52
|
+
`;
|
|
53
|
+
|
|
54
|
+
const VALID_PROMPT_IN_PROGRESS = `---
|
|
55
|
+
number: 2
|
|
56
|
+
title: Active Task
|
|
57
|
+
type: planned
|
|
58
|
+
planning_session: 1
|
|
59
|
+
status: in_progress
|
|
60
|
+
dependencies: []
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
# Tasks
|
|
64
|
+
|
|
65
|
+
- Working on this now
|
|
66
|
+
|
|
67
|
+
# Acceptance Criteria
|
|
68
|
+
|
|
69
|
+
- Task is complete
|
|
70
|
+
`;
|
|
71
|
+
|
|
72
|
+
const VALID_PROMPT_COMPLETED = `---
|
|
73
|
+
number: 3
|
|
74
|
+
title: Done Task
|
|
75
|
+
type: planned
|
|
76
|
+
planning_session: 1
|
|
77
|
+
status: done
|
|
78
|
+
dependencies: []
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
# Tasks
|
|
82
|
+
|
|
83
|
+
- This task has been completed
|
|
84
|
+
|
|
85
|
+
# Acceptance Criteria
|
|
86
|
+
|
|
87
|
+
- All done
|
|
88
|
+
`;
|
|
89
|
+
|
|
90
|
+
const VALID_PROMPT_BLOCKED = `---
|
|
91
|
+
number: 4
|
|
92
|
+
title: Blocked Task
|
|
93
|
+
type: planned
|
|
94
|
+
planning_session: 1
|
|
95
|
+
status: pending
|
|
96
|
+
dependencies: [1, 2]
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
# Tasks
|
|
100
|
+
|
|
101
|
+
- Waiting for dependencies
|
|
102
|
+
|
|
103
|
+
# Acceptance Criteria
|
|
104
|
+
|
|
105
|
+
- Dependencies complete first
|
|
106
|
+
`;
|
|
107
|
+
|
|
108
|
+
const INVALID_PROMPT_BAD_STATUS = `---
|
|
109
|
+
number: 1
|
|
110
|
+
title: Bad Status Task
|
|
111
|
+
type: planned
|
|
112
|
+
planning_session: 1
|
|
113
|
+
status: invalid_status
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
# Tasks
|
|
117
|
+
|
|
118
|
+
- This status doesn't exist in the enum
|
|
119
|
+
|
|
120
|
+
# Acceptance Criteria
|
|
121
|
+
|
|
122
|
+
- N/A
|
|
123
|
+
`;
|
|
124
|
+
|
|
125
|
+
const INVALID_PROMPT_MISSING_STATUS = `---
|
|
126
|
+
number: 1
|
|
127
|
+
title: Some Task
|
|
128
|
+
type: planned
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
# Tasks
|
|
132
|
+
|
|
133
|
+
- Missing required status field
|
|
134
|
+
|
|
135
|
+
# Acceptance Criteria
|
|
136
|
+
|
|
137
|
+
- N/A
|
|
138
|
+
`;
|
|
139
|
+
|
|
140
|
+
const INVALID_PROMPT_NO_FRONTMATTER = `# No Frontmatter
|
|
141
|
+
|
|
142
|
+
This file has no YAML frontmatter.
|
|
143
|
+
`;
|
|
144
|
+
|
|
145
|
+
// Valid alignment matching .allhands/schemas/alignment.yaml
|
|
146
|
+
const VALID_ALIGNMENT = `---
|
|
147
|
+
spec_name: test-spec
|
|
148
|
+
spec_path: specs/test.spec.md
|
|
149
|
+
planning_session: 1
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
# Overview
|
|
153
|
+
|
|
154
|
+
Build the feature.
|
|
155
|
+
|
|
156
|
+
# Hard User Requirements
|
|
157
|
+
|
|
158
|
+
- Follow existing patterns
|
|
159
|
+
`;
|
|
160
|
+
|
|
161
|
+
const INVALID_ALIGNMENT_MISSING_SPEC = `---
|
|
162
|
+
planning_session: 1
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
# Overview
|
|
166
|
+
|
|
167
|
+
Missing spec_name field.
|
|
168
|
+
|
|
169
|
+
# Hard User Requirements
|
|
170
|
+
|
|
171
|
+
- N/A
|
|
172
|
+
`;
|
|
173
|
+
|
|
174
|
+
// Valid spec matching .allhands/schemas/spec.yaml
|
|
175
|
+
const VALID_SPEC = `---
|
|
176
|
+
name: api-spec
|
|
177
|
+
domain_name: api-domain
|
|
178
|
+
status: roadmap
|
|
179
|
+
dependencies: []
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
# Motivation
|
|
183
|
+
|
|
184
|
+
This spec defines the API.
|
|
185
|
+
|
|
186
|
+
# Goals
|
|
187
|
+
|
|
188
|
+
- Define endpoints
|
|
189
|
+
`;
|
|
190
|
+
|
|
191
|
+
const INVALID_SPEC_MISSING_DOMAIN = `---
|
|
192
|
+
name: incomplete-spec
|
|
193
|
+
status: roadmap
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
# Motivation
|
|
197
|
+
|
|
198
|
+
Missing domain_name field.
|
|
199
|
+
|
|
200
|
+
# Goals
|
|
201
|
+
|
|
202
|
+
- N/A
|
|
203
|
+
`;
|
|
204
|
+
|
|
205
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
206
|
+
// Prompt Validation Tests
|
|
207
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
208
|
+
|
|
209
|
+
describe('Prompt Validation E2E', () => {
|
|
210
|
+
let fixture: TestFixture;
|
|
211
|
+
|
|
212
|
+
beforeAll(() => {
|
|
213
|
+
fixture = createFixture({ name: 'prompt-validation-test' });
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
afterAll(() => {
|
|
217
|
+
fixture.cleanup();
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
describe('valid prompts', () => {
|
|
221
|
+
it('accepts prompt with status: pending', async () => {
|
|
222
|
+
fixture.writeFile('.planning/m1/prompts/01.md', VALID_PROMPT);
|
|
223
|
+
assertValidFrontmatter(fixture, '.planning/m1/prompts/01.md', ['status']);
|
|
224
|
+
|
|
225
|
+
const result = await validateFile(fixture, '.planning/m1/prompts/01.md');
|
|
226
|
+
assertSuccess(result);
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it('accepts prompt with status: in_progress', async () => {
|
|
230
|
+
fixture.writeFile('.planning/m1/prompts/02.md', VALID_PROMPT_IN_PROGRESS);
|
|
231
|
+
const result = await validateFile(fixture,'.planning/m1/prompts/02.md');
|
|
232
|
+
assertSuccess(result);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it('accepts prompt with status: completed', async () => {
|
|
236
|
+
fixture.writeFile('.planning/m1/prompts/03.md', VALID_PROMPT_COMPLETED);
|
|
237
|
+
const result = await validateFile(fixture,'.planning/m1/prompts/03.md');
|
|
238
|
+
assertSuccess(result);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it('accepts prompt with status: blocked', async () => {
|
|
242
|
+
fixture.writeFile('.planning/m1/prompts/04.md', VALID_PROMPT_BLOCKED);
|
|
243
|
+
const result = await validateFile(fixture,'.planning/m1/prompts/04.md');
|
|
244
|
+
assertSuccess(result);
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
describe('invalid prompts', () => {
|
|
249
|
+
it('rejects prompt with invalid status enum value', async () => {
|
|
250
|
+
fixture.writeFile('.planning/m1/prompts/bad-status.md', INVALID_PROMPT_BAD_STATUS);
|
|
251
|
+
const result = await validateFile(fixture,'.planning/m1/prompts/bad-status.md');
|
|
252
|
+
// Should fail or warn about invalid enum
|
|
253
|
+
expect(result.combined).toBeDefined();
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it('rejects prompt missing required status field', async () => {
|
|
257
|
+
fixture.writeFile('.planning/m1/prompts/no-status.md', INVALID_PROMPT_MISSING_STATUS);
|
|
258
|
+
const result = await validateFile(fixture,'.planning/m1/prompts/no-status.md');
|
|
259
|
+
expect(result.combined).toBeDefined();
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
it('handles prompt without frontmatter', async () => {
|
|
263
|
+
fixture.writeFile('.planning/m1/prompts/no-fm.md', INVALID_PROMPT_NO_FRONTMATTER);
|
|
264
|
+
const result = await validateFile(fixture,'.planning/m1/prompts/no-fm.md');
|
|
265
|
+
// Should fail gracefully
|
|
266
|
+
expect(result.exitCode).toBeDefined();
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
272
|
+
// Alignment Validation Tests
|
|
273
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
274
|
+
|
|
275
|
+
describe('Alignment Validation E2E', () => {
|
|
276
|
+
let fixture: TestFixture;
|
|
277
|
+
|
|
278
|
+
beforeAll(() => {
|
|
279
|
+
fixture = createFixture({ name: 'alignment-validation-test' });
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
afterAll(() => {
|
|
283
|
+
fixture.cleanup();
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
describe('valid alignment docs', () => {
|
|
287
|
+
it('accepts alignment with required fields', async () => {
|
|
288
|
+
fixture.writeFile('.planning/m1/alignment.md', VALID_ALIGNMENT);
|
|
289
|
+
assertValidFrontmatter(fixture, '.planning/m1/alignment.md', ['spec_name', 'spec_path']);
|
|
290
|
+
|
|
291
|
+
const result = await validateFile(fixture,'.planning/m1/alignment.md');
|
|
292
|
+
assertSuccess(result);
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
describe('invalid alignment docs', () => {
|
|
297
|
+
it('rejects alignment missing spec field', async () => {
|
|
298
|
+
fixture.writeFile('.planning/m2/alignment.md', INVALID_ALIGNMENT_MISSING_SPEC);
|
|
299
|
+
const result = await validateFile(fixture,'.planning/m2/alignment.md');
|
|
300
|
+
expect(result.combined).toBeDefined();
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
306
|
+
// Spec Validation Tests
|
|
307
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
308
|
+
|
|
309
|
+
describe('Spec Validation E2E', () => {
|
|
310
|
+
let fixture: TestFixture;
|
|
311
|
+
|
|
312
|
+
beforeAll(() => {
|
|
313
|
+
fixture = createFixture({ name: 'spec-validation-test' });
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
afterAll(() => {
|
|
317
|
+
fixture.cleanup();
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
describe('valid specs', () => {
|
|
321
|
+
it('accepts spec with name and domain_name', async () => {
|
|
322
|
+
fixture.writeFile('specs/api.spec.md', VALID_SPEC);
|
|
323
|
+
assertValidFrontmatter(fixture, 'specs/api.spec.md', ['name', 'domain_name']);
|
|
324
|
+
|
|
325
|
+
const result = await validateFile(fixture,'specs/api.spec.md');
|
|
326
|
+
assertSuccess(result);
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
describe('invalid specs', () => {
|
|
331
|
+
it('rejects spec missing domain_name field', async () => {
|
|
332
|
+
fixture.writeFile('specs/incomplete.spec.md', INVALID_SPEC_MISSING_DOMAIN);
|
|
333
|
+
const result = await validateFile(fixture,'specs/incomplete.spec.md');
|
|
334
|
+
expect(result.combined).toBeDefined();
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
340
|
+
// File Type Detection Tests
|
|
341
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
342
|
+
|
|
343
|
+
describe('File Type Detection E2E', () => {
|
|
344
|
+
let fixture: TestFixture;
|
|
345
|
+
|
|
346
|
+
beforeAll(() => {
|
|
347
|
+
fixture = createFixture({ name: 'file-type-detection-test' });
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
afterAll(() => {
|
|
351
|
+
fixture.cleanup();
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
it('detects prompt files by path pattern', async () => {
|
|
355
|
+
fixture.writeFile('.planning/spec/prompts/01.md', VALID_PROMPT);
|
|
356
|
+
fixture.writeFile('.planning/spec/prompts/99.md', VALID_PROMPT);
|
|
357
|
+
|
|
358
|
+
const r1 = await validateFile(fixture,'.planning/spec/prompts/01.md');
|
|
359
|
+
const r2 = await validateFile(fixture,'.planning/spec/prompts/99.md');
|
|
360
|
+
|
|
361
|
+
assertSuccess(r1);
|
|
362
|
+
assertSuccess(r2);
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
it('detects alignment files by name', async () => {
|
|
366
|
+
fixture.writeFile('.planning/m1/alignment.md', VALID_ALIGNMENT);
|
|
367
|
+
const result = await validateFile(fixture,'.planning/m1/alignment.md');
|
|
368
|
+
assertSuccess(result);
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
it('detects spec files by .spec.md extension', async () => {
|
|
372
|
+
fixture.writeFile('specs/data.spec.md', VALID_SPEC);
|
|
373
|
+
const result = await validateFile(fixture,'specs/data.spec.md');
|
|
374
|
+
assertSuccess(result);
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
it('reports error for non-schema-managed files (no schema type)', async () => {
|
|
378
|
+
fixture.writeFile('README.md', '# README\n\nJust a readme.');
|
|
379
|
+
// CLI cannot determine schema type for README.md - this is expected
|
|
380
|
+
const result = await validateFile(fixture,'README.md');
|
|
381
|
+
// Should fail because schema type cannot be inferred
|
|
382
|
+
assertFailure(result);
|
|
383
|
+
expect(result.stderr || result.stdout).toContain('Could not determine schema type');
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
388
|
+
// Batch Validation Tests
|
|
389
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
390
|
+
|
|
391
|
+
describe('Batch Validation E2E', () => {
|
|
392
|
+
let fixture: TestFixture;
|
|
393
|
+
|
|
394
|
+
beforeAll(() => {
|
|
395
|
+
fixture = createFixture({
|
|
396
|
+
name: 'batch-validation-test',
|
|
397
|
+
files: {
|
|
398
|
+
'.planning/m1/alignment.md': VALID_ALIGNMENT,
|
|
399
|
+
'.planning/m1/prompts/01.md': VALID_PROMPT,
|
|
400
|
+
'.planning/m1/prompts/02.md': VALID_PROMPT_IN_PROGRESS,
|
|
401
|
+
'.planning/m1/prompts/03.md': VALID_PROMPT_COMPLETED,
|
|
402
|
+
'specs/api.spec.md': VALID_SPEC,
|
|
403
|
+
},
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
afterAll(() => {
|
|
408
|
+
fixture.cleanup();
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
it('validates multiple files in sequence', async () => {
|
|
412
|
+
const files = [
|
|
413
|
+
'.planning/m1/alignment.md',
|
|
414
|
+
'.planning/m1/prompts/01.md',
|
|
415
|
+
'.planning/m1/prompts/02.md',
|
|
416
|
+
'.planning/m1/prompts/03.md',
|
|
417
|
+
'specs/api.spec.md',
|
|
418
|
+
];
|
|
419
|
+
|
|
420
|
+
for (const file of files) {
|
|
421
|
+
const result = await validateFile(fixture,file);
|
|
422
|
+
assertSuccess(result);
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
428
|
+
// Edge Cases
|
|
429
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
430
|
+
|
|
431
|
+
describe('Validation Edge Cases E2E', () => {
|
|
432
|
+
let fixture: TestFixture;
|
|
433
|
+
|
|
434
|
+
beforeAll(() => {
|
|
435
|
+
fixture = createFixture({ name: 'validation-edge-cases' });
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
afterAll(() => {
|
|
439
|
+
fixture.cleanup();
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
it('handles empty file', async () => {
|
|
443
|
+
fixture.writeFile('.planning/m1/prompts/empty.md', '');
|
|
444
|
+
const result = await validateFile(fixture,'.planning/m1/prompts/empty.md');
|
|
445
|
+
// Should handle gracefully
|
|
446
|
+
expect(result.exitCode).toBeDefined();
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
it('handles file with only frontmatter', async () => {
|
|
450
|
+
fixture.writeFile('.planning/m1/prompts/only-fm.md', `---
|
|
451
|
+
number: 1
|
|
452
|
+
title: Only Frontmatter
|
|
453
|
+
type: planned
|
|
454
|
+
planning_session: 1
|
|
455
|
+
status: pending
|
|
456
|
+
---
|
|
457
|
+
`);
|
|
458
|
+
const result = await validateFile(fixture,'.planning/m1/prompts/only-fm.md');
|
|
459
|
+
// Frontmatter is valid but body sections may be missing - behavior depends on schema
|
|
460
|
+
expect(result.exitCode).toBeDefined();
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
it('handles malformed YAML in frontmatter', async () => {
|
|
464
|
+
fixture.writeFile('.planning/m1/prompts/bad-yaml.md', `---
|
|
465
|
+
number: 1
|
|
466
|
+
status: pending
|
|
467
|
+
bad indentation:
|
|
468
|
+
- this is wrong
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
# Tasks
|
|
472
|
+
|
|
473
|
+
- Content
|
|
474
|
+
|
|
475
|
+
# Acceptance Criteria
|
|
476
|
+
|
|
477
|
+
- Criteria
|
|
478
|
+
`);
|
|
479
|
+
const result = await validateFile(fixture,'.planning/m1/prompts/bad-yaml.md');
|
|
480
|
+
// Should handle YAML parse error
|
|
481
|
+
expect(result.exitCode).toBeDefined();
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
it('handles unicode content', async () => {
|
|
485
|
+
fixture.writeFile('.planning/m1/prompts/unicode.md', `---
|
|
486
|
+
number: 1
|
|
487
|
+
title: Unicode Task
|
|
488
|
+
type: planned
|
|
489
|
+
planning_session: 1
|
|
490
|
+
status: pending
|
|
491
|
+
---
|
|
492
|
+
|
|
493
|
+
# Tasks
|
|
494
|
+
|
|
495
|
+
- 日本語タスク
|
|
496
|
+
- 实现功能 🚀
|
|
497
|
+
|
|
498
|
+
# Acceptance Criteria
|
|
499
|
+
|
|
500
|
+
- Works with unicode
|
|
501
|
+
`);
|
|
502
|
+
const result = await validateFile(fixture,'.planning/m1/prompts/unicode.md');
|
|
503
|
+
assertSuccess(result);
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
it('handles very long frontmatter', async () => {
|
|
507
|
+
const longValue = 'a'.repeat(1000);
|
|
508
|
+
fixture.writeFile('.planning/m1/prompts/long-fm.md', `---
|
|
509
|
+
number: 1
|
|
510
|
+
title: ${longValue.substring(0, 50)}
|
|
511
|
+
type: planned
|
|
512
|
+
planning_session: 1
|
|
513
|
+
status: pending
|
|
514
|
+
description: ${longValue}
|
|
515
|
+
---
|
|
516
|
+
|
|
517
|
+
# Tasks
|
|
518
|
+
|
|
519
|
+
- Task with long title
|
|
520
|
+
|
|
521
|
+
# Acceptance Criteria
|
|
522
|
+
|
|
523
|
+
- Handles long values
|
|
524
|
+
`);
|
|
525
|
+
const result = await validateFile(fixture,'.planning/m1/prompts/long-fm.md');
|
|
526
|
+
assertSuccess(result);
|
|
527
|
+
});
|
|
528
|
+
});
|