@entelligentsia/forgecli 0.10.0 → 0.11.2
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/CHANGELOG.md +95 -0
- package/README.md +21 -3
- package/dist/CHANGELOG-forge-plugin.md +90 -0
- package/dist/bin/config.js +6 -0
- package/dist/bin/config.js.map +1 -1
- package/dist/extensions/forgecli/add-pipeline.d.ts +19 -0
- package/dist/extensions/forgecli/add-pipeline.js +143 -0
- package/dist/extensions/forgecli/add-pipeline.js.map +1 -0
- package/dist/extensions/forgecli/add-task.d.ts +20 -0
- package/dist/extensions/forgecli/add-task.js +154 -0
- package/dist/extensions/forgecli/add-task.js.map +1 -0
- package/dist/extensions/forgecli/calibrate.d.ts +61 -0
- package/dist/extensions/forgecli/calibrate.js +488 -0
- package/dist/extensions/forgecli/calibrate.js.map +1 -0
- package/dist/extensions/forgecli/fix-bug.d.ts +9 -1
- package/dist/extensions/forgecli/fix-bug.js +155 -45
- package/dist/extensions/forgecli/fix-bug.js.map +1 -1
- package/dist/extensions/forgecli/forge-commands.js +15 -22
- package/dist/extensions/forgecli/forge-commands.js.map +1 -1
- package/dist/extensions/forgecli/forge-subagent.d.ts +16 -1
- package/dist/extensions/forgecli/forge-subagent.js +45 -8
- package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
- package/dist/extensions/forgecli/forge-update-command.d.ts +9 -0
- package/dist/extensions/forgecli/forge-update-command.js +106 -7
- package/dist/extensions/forgecli/forge-update-command.js.map +1 -1
- package/dist/extensions/forgecli/health-check.d.ts +22 -1
- package/dist/extensions/forgecli/health-check.js +177 -4
- package/dist/extensions/forgecli/health-check.js.map +1 -1
- package/dist/extensions/forgecli/hook-dispatcher.d.ts +25 -1
- package/dist/extensions/forgecli/hook-dispatcher.js +104 -9
- package/dist/extensions/forgecli/hook-dispatcher.js.map +1 -1
- package/dist/extensions/forgecli/hooks/check-update.d.ts +81 -0
- package/dist/extensions/forgecli/hooks/check-update.js +308 -0
- package/dist/extensions/forgecli/hooks/check-update.js.map +1 -0
- package/dist/extensions/forgecli/hooks/forge-permissions.d.ts +32 -0
- package/dist/extensions/forgecli/hooks/forge-permissions.js +119 -0
- package/dist/extensions/forgecli/hooks/forge-permissions.js.map +1 -0
- package/dist/extensions/forgecli/hooks/triage-error.d.ts +23 -0
- package/dist/extensions/forgecli/hooks/triage-error.js +62 -0
- package/dist/extensions/forgecli/hooks/triage-error.js.map +1 -0
- package/dist/extensions/forgecli/hooks/write-guard.d.ts +28 -0
- package/dist/extensions/forgecli/hooks/write-guard.js +225 -0
- package/dist/extensions/forgecli/hooks/write-guard.js.map +1 -0
- package/dist/extensions/forgecli/index.js +60 -0
- package/dist/extensions/forgecli/index.js.map +1 -1
- package/dist/extensions/forgecli/init-context.d.ts +1 -1
- package/dist/extensions/forgecli/init-context.js +21 -6
- package/dist/extensions/forgecli/init-context.js.map +1 -1
- package/dist/extensions/forgecli/materialize.d.ts +16 -0
- package/dist/extensions/forgecli/materialize.js +195 -0
- package/dist/extensions/forgecli/materialize.js.map +1 -0
- package/dist/extensions/forgecli/migrate.d.ts +19 -0
- package/dist/extensions/forgecli/migrate.js +258 -0
- package/dist/extensions/forgecli/migrate.js.map +1 -0
- package/dist/extensions/forgecli/migration-engine.d.ts +111 -0
- package/dist/extensions/forgecli/migration-engine.js +533 -0
- package/dist/extensions/forgecli/migration-engine.js.map +1 -0
- package/dist/extensions/forgecli/quiz-agent.d.ts +17 -0
- package/dist/extensions/forgecli/quiz-agent.js +98 -0
- package/dist/extensions/forgecli/quiz-agent.js.map +1 -0
- package/dist/extensions/forgecli/remove-command.d.ts +17 -0
- package/dist/extensions/forgecli/remove-command.js +124 -0
- package/dist/extensions/forgecli/remove-command.js.map +1 -0
- package/dist/extensions/forgecli/report-bug.d.ts +25 -0
- package/dist/extensions/forgecli/report-bug.js +159 -0
- package/dist/extensions/forgecli/report-bug.js.map +1 -0
- package/dist/extensions/forgecli/retrospective.d.ts +19 -0
- package/dist/extensions/forgecli/retrospective.js +156 -0
- package/dist/extensions/forgecli/retrospective.js.map +1 -0
- package/dist/extensions/forgecli/run-sprint.js +36 -3
- package/dist/extensions/forgecli/run-sprint.js.map +1 -1
- package/dist/extensions/forgecli/run-task.d.ts +9 -1
- package/dist/extensions/forgecli/run-task.js +66 -13
- package/dist/extensions/forgecli/run-task.js.map +1 -1
- package/dist/extensions/forgecli/session-registry.d.ts +40 -2
- package/dist/extensions/forgecli/session-registry.js +71 -1
- package/dist/extensions/forgecli/session-registry.js.map +1 -1
- package/dist/extensions/forgecli/status-command.d.ts +19 -0
- package/dist/extensions/forgecli/status-command.js +140 -0
- package/dist/extensions/forgecli/status-command.js.map +1 -0
- package/dist/extensions/forgecli/store-query.d.ts +22 -0
- package/dist/extensions/forgecli/store-query.js +107 -0
- package/dist/extensions/forgecli/store-query.js.map +1 -0
- package/dist/extensions/forgecli/store-repair.d.ts +17 -0
- package/dist/extensions/forgecli/store-repair.js +123 -0
- package/dist/extensions/forgecli/store-repair.js.map +1 -0
- package/dist/extensions/forgecli/test-orchestrate.js +1 -0
- package/dist/extensions/forgecli/test-orchestrate.js.map +1 -1
- package/dist/extensions/forgecli/thread-switcher.js +286 -41
- package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
- package/dist/extensions/forgecli/transition-guard.js +7 -2
- package/dist/extensions/forgecli/transition-guard.js.map +1 -1
- package/dist/extensions/forgecli/update-tools.d.ts +23 -0
- package/dist/extensions/forgecli/update-tools.js +136 -0
- package/dist/extensions/forgecli/update-tools.js.map +1 -0
- package/dist/extensions/forgecli/viewport-events.js +10 -0
- package/dist/extensions/forgecli/viewport-events.js.map +1 -1
- package/dist/extensions/forgecli/viewport-renderer.d.ts +18 -0
- package/dist/extensions/forgecli/viewport-renderer.js +27 -0
- package/dist/extensions/forgecli/viewport-renderer.js.map +1 -1
- package/dist/extensions/forgecli/viewport-theme.js +4 -0
- package/dist/extensions/forgecli/viewport-theme.js.map +1 -1
- package/dist/extensions/forgecli/whats-new-widget.d.ts +13 -8
- package/dist/extensions/forgecli/whats-new-widget.js +111 -42
- package/dist/extensions/forgecli/whats-new-widget.js.map +1 -1
- package/dist/forge-payload/.base-pack/workflows/architect_approve.md +29 -3
- package/dist/forge-payload/.base-pack/workflows/commit_task.md +15 -8
- package/dist/forge-payload/.base-pack/workflows/fix_bug.md +327 -185
- package/dist/forge-payload/.base-pack/workflows/implement_plan.md +18 -10
- package/dist/forge-payload/.base-pack/workflows/plan_task.md +15 -9
- package/dist/forge-payload/.base-pack/workflows/review_code.md +14 -6
- package/dist/forge-payload/.base-pack/workflows/review_plan.md +18 -10
- package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
- package/dist/forge-payload/.schemas/bug.schema.json +3 -2
- package/dist/forge-payload/.schemas/config.schema.json +83 -0
- package/dist/forge-payload/.schemas/migrations.json +2049 -0
- package/dist/forge-payload/commands/regenerate.md +17 -1
- package/dist/forge-payload/meta/personas/README.md +16 -0
- package/dist/forge-payload/meta/personas/meta-architect.md +70 -0
- package/dist/forge-payload/meta/personas/meta-bug-fixer.md +73 -0
- package/dist/forge-payload/meta/personas/meta-collator.md +72 -0
- package/dist/forge-payload/meta/personas/meta-engineer.md +70 -0
- package/dist/forge-payload/meta/personas/meta-orchestrator.md +71 -0
- package/dist/forge-payload/meta/personas/meta-product-manager.md +82 -0
- package/dist/forge-payload/meta/personas/meta-qa-engineer.md +91 -0
- package/dist/forge-payload/meta/personas/meta-supervisor.md +92 -0
- package/dist/forge-payload/meta/skill-recommendations.md +154 -0
- package/dist/forge-payload/meta/skills/meta-architect-skills.md +43 -0
- package/dist/forge-payload/meta/skills/meta-bug-fixer-skills.md +43 -0
- package/dist/forge-payload/meta/skills/meta-collator-skills.md +41 -0
- package/dist/forge-payload/meta/skills/meta-engineer-skills.md +43 -0
- package/dist/forge-payload/meta/skills/meta-generic-skills.md +58 -0
- package/dist/forge-payload/meta/skills/meta-qa-engineer-skills.md +46 -0
- package/dist/forge-payload/meta/skills/meta-supervisor-skills.md +43 -0
- package/dist/forge-payload/meta/store-schema/bug.schema.md +71 -0
- package/dist/forge-payload/meta/store-schema/event.schema.md +76 -0
- package/dist/forge-payload/meta/store-schema/feature.schema.md +65 -0
- package/dist/forge-payload/meta/store-schema/sprint.schema.md +64 -0
- package/dist/forge-payload/meta/store-schema/task.schema.md +78 -0
- package/dist/forge-payload/meta/templates/meta-code-review.md +26 -0
- package/dist/forge-payload/meta/templates/meta-plan-review.md +28 -0
- package/dist/forge-payload/meta/templates/meta-plan.md +28 -0
- package/dist/forge-payload/meta/templates/meta-progress.md +25 -0
- package/dist/forge-payload/meta/templates/meta-retrospective.md +28 -0
- package/dist/forge-payload/meta/templates/meta-sprint-manifest.md +26 -0
- package/dist/forge-payload/meta/templates/meta-sprint-requirements.md +91 -0
- package/dist/forge-payload/meta/templates/meta-task-prompt.md +26 -0
- package/dist/forge-payload/meta/tool-specs/collate.spec.md +88 -0
- package/dist/forge-payload/meta/tool-specs/generation-manifest.spec.md +139 -0
- package/dist/forge-payload/meta/tool-specs/manage-config.spec.md +143 -0
- package/dist/forge-payload/meta/tool-specs/seed-store.spec.md +91 -0
- package/dist/forge-payload/meta/tool-specs/store-cli.spec.md +328 -0
- package/dist/forge-payload/meta/tool-specs/validate-store.spec.md +191 -0
- package/dist/forge-payload/meta/workflows/_fragments/context-injection.md +75 -0
- package/dist/forge-payload/meta/workflows/_fragments/event-emission-schema.md +73 -0
- package/dist/forge-payload/meta/workflows/_fragments/finalize.md +13 -0
- package/dist/forge-payload/meta/workflows/_fragments/friction-emit.md +73 -0
- package/dist/forge-payload/meta/workflows/_fragments/progress-reporting.md +38 -0
- package/dist/forge-payload/meta/workflows/_fragments/store-cli-verbs.md +39 -0
- package/dist/forge-payload/meta/workflows/meta-approve.md +119 -0
- package/dist/forge-payload/meta/workflows/meta-collate.md +89 -0
- package/dist/forge-payload/meta/workflows/meta-commit.md +93 -0
- package/dist/forge-payload/meta/workflows/meta-enhance.md +286 -0
- package/dist/forge-payload/meta/workflows/meta-fix-bug.md +501 -0
- package/dist/forge-payload/meta/workflows/meta-implement.md +132 -0
- package/dist/forge-payload/meta/workflows/meta-migrate.md +455 -0
- package/dist/forge-payload/meta/workflows/meta-orchestrate.md +993 -0
- package/dist/forge-payload/meta/workflows/meta-plan-task.md +133 -0
- package/dist/forge-payload/meta/workflows/meta-quiz-agent.md +135 -0
- package/dist/forge-payload/meta/workflows/meta-retrospective.md +65 -0
- package/dist/forge-payload/meta/workflows/meta-review-implementation.md +119 -0
- package/dist/forge-payload/meta/workflows/meta-review-plan.md +108 -0
- package/dist/forge-payload/meta/workflows/meta-review-sprint-completion.md +65 -0
- package/dist/forge-payload/meta/workflows/meta-sprint-intake.md +76 -0
- package/dist/forge-payload/meta/workflows/meta-sprint-plan.md +147 -0
- package/dist/forge-payload/meta/workflows/meta-update-implementation.md +76 -0
- package/dist/forge-payload/meta/workflows/meta-update-plan.md +76 -0
- package/dist/forge-payload/meta/workflows/meta-validate.md +111 -0
- package/dist/forge-payload/tools/check-structure.cjs +344 -0
- package/dist/forge-payload/tools/collate.cjs +34 -9
- package/dist/forge-payload/tools/list-skills.js +76 -0
- package/dist/forge-payload/tools/parse-gates.cjs +8 -2
- package/dist/forge-payload/tools/store-cli.cjs +56 -11
- package/dist/forge-payload/tools/store.cjs +61 -0
- package/dist/forge-payload/tools/substitute-placeholders.cjs +60 -8
- package/dist/forge-payload/tools/validate-store.cjs +6 -2
- package/dist/forge-payload/tools/verify-integrity.cjs +86 -0
- package/package.json +2 -2
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Tool Spec: generation-manifest
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Track and verify the integrity of Forge-generated files via content hashes.
|
|
6
|
+
Distinguishes between files that are pristine (unchanged since generation) and
|
|
7
|
+
files that have been manually modified. Used by regeneration, migration, and
|
|
8
|
+
health checks to avoid silently overwriting user edits.
|
|
9
|
+
|
|
10
|
+
## Manifest file
|
|
11
|
+
|
|
12
|
+
Stored at `.forge/generation-manifest.json`. Committed to version control so
|
|
13
|
+
the whole team shares the same baseline. Structure:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"files": {
|
|
18
|
+
".forge/workflows/plan_task.md": {
|
|
19
|
+
"hash": "sha256:a3f9...",
|
|
20
|
+
"generatedAt": "2026-04-06T10:00:00.000Z",
|
|
21
|
+
"generatedByVersion": "0.5.0"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Inputs
|
|
28
|
+
|
|
29
|
+
- `.forge/generation-manifest.json` — the manifest file (read/write)
|
|
30
|
+
- CLI arguments — subcommand and target path
|
|
31
|
+
|
|
32
|
+
## Outputs
|
|
33
|
+
|
|
34
|
+
- Modified `.forge/generation-manifest.json` in-place (write subcommands)
|
|
35
|
+
- Printed status or tables to stdout (read subcommands)
|
|
36
|
+
- Exit codes (see per-subcommand below)
|
|
37
|
+
|
|
38
|
+
## CLI Interface
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
generation-manifest record <path>
|
|
42
|
+
```
|
|
43
|
+
Hash the file at `<path>` and store/update its entry in the manifest.
|
|
44
|
+
Records `hash`, `generatedAt` (ISO timestamp), and `generatedByVersion`
|
|
45
|
+
(read from `.forge/config.json → version`, or `"unknown"`).
|
|
46
|
+
Exit 0 on success.
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
generation-manifest record-all
|
|
50
|
+
```
|
|
51
|
+
Re-hash every file currently listed in the manifest. Skips missing files
|
|
52
|
+
with a `△ Missing` note. Prints a summary line on completion.
|
|
53
|
+
Exit 0 always (missing files are not an error).
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
generation-manifest check <path>
|
|
57
|
+
```
|
|
58
|
+
Compare the current content hash of `<path>` against the stored hash.
|
|
59
|
+
|
|
60
|
+
| Exit code | Meaning |
|
|
61
|
+
|-----------|---------|
|
|
62
|
+
| 0 | Pristine — content matches the stored hash |
|
|
63
|
+
| 1 | Modified — content has changed since it was recorded |
|
|
64
|
+
| 2 | Untracked — file is not in the manifest |
|
|
65
|
+
| 3 | File not found on disk |
|
|
66
|
+
|
|
67
|
+
Output one status line to stdout regardless of exit code.
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
generation-manifest list [--modified]
|
|
71
|
+
```
|
|
72
|
+
Print a markdown pipe table of all tracked files with columns
|
|
73
|
+
`Status | File | Version | Date`.
|
|
74
|
+
With `--modified`: only show modified and missing files.
|
|
75
|
+
If all files are pristine, print `〇 All tracked files are pristine.`
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
generation-manifest status
|
|
79
|
+
```
|
|
80
|
+
Print a compact summary: total tracked count, and counts per status
|
|
81
|
+
(pristine / modified / missing). No table.
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
generation-manifest remove <path>
|
|
85
|
+
```
|
|
86
|
+
Remove a file from the manifest without touching the file itself.
|
|
87
|
+
Exit 1 if the file is not tracked.
|
|
88
|
+
|
|
89
|
+
## Hash algorithm
|
|
90
|
+
|
|
91
|
+
SHA-256 of normalised content:
|
|
92
|
+
1. Normalise line endings to LF (`\r\n` → `\n`)
|
|
93
|
+
2. Strip trailing whitespace from each line
|
|
94
|
+
3. Hash the resulting UTF-8 string
|
|
95
|
+
4. Prefix the hex digest with `"sha256:"`
|
|
96
|
+
|
|
97
|
+
This prevents false positives from editor-inserted trailing spaces or
|
|
98
|
+
CRLF/LF differences across platforms.
|
|
99
|
+
|
|
100
|
+
## What to track
|
|
101
|
+
|
|
102
|
+
Record hashes for files that Forge generates and might overwrite on
|
|
103
|
+
regeneration, but that users may legitimately customise:
|
|
104
|
+
|
|
105
|
+
| Category | Pattern |
|
|
106
|
+
|----------|---------|
|
|
107
|
+
| Workflows | `.forge/workflows/*.md` |
|
|
108
|
+
| Templates | `.forge/templates/*.md` |
|
|
109
|
+
| Generated commands | `.claude/commands/{forge-generated}.md` |
|
|
110
|
+
|
|
111
|
+
Do NOT track:
|
|
112
|
+
- Knowledge base files (`engineering/architecture/`, `stack-checklist.md`) — expected to evolve via writeback
|
|
113
|
+
- Collated views (`MASTER_INDEX.md`, `TIMESHEET.md`) — rebuilt from the store
|
|
114
|
+
- Store JSON files (`.forge/store/`) — data, not generated artifacts
|
|
115
|
+
|
|
116
|
+
## Status symbols
|
|
117
|
+
|
|
118
|
+
| Symbol | Meaning |
|
|
119
|
+
|--------|---------|
|
|
120
|
+
| 〇 | Pristine — matches stored hash |
|
|
121
|
+
| △ | Modified — diverged from stored hash |
|
|
122
|
+
| × | Missing — file not found on disk |
|
|
123
|
+
|
|
124
|
+
## Error handling
|
|
125
|
+
|
|
126
|
+
- Wrap entry point in `process.on('uncaughtException')` — all errors print to
|
|
127
|
+
stderr prefixed with `×` and exit 1. No unhandled exceptions or stack traces.
|
|
128
|
+
- If `.forge/generation-manifest.json` is missing, treat it as an empty manifest
|
|
129
|
+
(no files tracked) — do not error.
|
|
130
|
+
- If `.forge/generation-manifest.json` contains invalid JSON, exit 1 with a
|
|
131
|
+
parse error message.
|
|
132
|
+
- Write atomically: temp file + rename. Never leave a partial write.
|
|
133
|
+
|
|
134
|
+
## Formatting rules
|
|
135
|
+
|
|
136
|
+
- `list` output: markdown pipe table, status column shows `{symbol} {status}`
|
|
137
|
+
- `check` output: one line to stdout: `{symbol} {relpath}: {status-description}`
|
|
138
|
+
- `status` output: one line per non-zero count, prefixed with symbol
|
|
139
|
+
- Success messages prefixed with `〇`; warnings with `△`; errors with `×`
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Tool Spec: manage-config
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Read and write `.forge/config.json` safely. Deterministic — no AI needed.
|
|
6
|
+
Preserves key order, indentation, and all fields not explicitly modified.
|
|
7
|
+
|
|
8
|
+
## Inputs
|
|
9
|
+
|
|
10
|
+
- `.forge/config.json` — the config file to read or modify
|
|
11
|
+
- CLI arguments — subcommand and options (see CLI Interface)
|
|
12
|
+
|
|
13
|
+
## Outputs
|
|
14
|
+
|
|
15
|
+
- Modified `.forge/config.json` in-place (write subcommands)
|
|
16
|
+
- Printed values or reports to stdout (read subcommands)
|
|
17
|
+
- Exit 0 on success, 1 on validation error, 2 on usage error
|
|
18
|
+
|
|
19
|
+
## CLI Interface
|
|
20
|
+
|
|
21
|
+
### Read subcommands
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
<tool> manage-config get <key.path>
|
|
25
|
+
```
|
|
26
|
+
Print the value at the dot-notation path (e.g., `project.prefix`,
|
|
27
|
+
`pipelines.measure-conversion`). Exit 1 if the path does not exist.
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
<tool> manage-config list-pipelines
|
|
31
|
+
```
|
|
32
|
+
Print a table of all pipeline names, their descriptions, and phase counts.
|
|
33
|
+
If no `pipelines` key exists, print `── No pipelines configured.` and exit 0.
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
<tool> manage-config pipeline get <name>
|
|
37
|
+
```
|
|
38
|
+
Print the full detail of a named pipeline as a markdown phase table with
|
|
39
|
+
columns `# | Role | Command | Workflow | Model | maxIter`.
|
|
40
|
+
Exit 1 with `× Pipeline '{name}' not found` if the name does not exist.
|
|
41
|
+
|
|
42
|
+
### Write subcommands
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
<tool> manage-config pipeline add <name> --description <text> --phases <json>
|
|
46
|
+
```
|
|
47
|
+
Add or replace a named pipeline. `--phases` accepts a JSON array string of
|
|
48
|
+
phase objects, each with `command` and `role` (required), and optionally
|
|
49
|
+
`model`, `maxIterations`, `on_revision`, and `workflow`.
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
<tool> manage-config pipeline remove <name>
|
|
53
|
+
```
|
|
54
|
+
Remove a named pipeline. Exit 1 if the name does not exist.
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
<tool> manage-config set <key.path> <json-value>
|
|
58
|
+
```
|
|
59
|
+
Set an arbitrary dot-notation path to a JSON value. Creates intermediate
|
|
60
|
+
objects as needed. Intended for first-party Forge tooling only — not
|
|
61
|
+
advertised in user-facing help.
|
|
62
|
+
|
|
63
|
+
## Validation Rules
|
|
64
|
+
|
|
65
|
+
Applied before any write. Exit 1 and print a clear error if any rule fails.
|
|
66
|
+
|
|
67
|
+
### Pipeline phases
|
|
68
|
+
- Each phase must have `command` (non-empty string) and `role` (string).
|
|
69
|
+
- `role` must be one of: `plan`, `review-plan`, `implement`, `review-code`,
|
|
70
|
+
`approve`, `commit`.
|
|
71
|
+
- `maxIterations` must be a positive integer when present.
|
|
72
|
+
- `workflow` (optional string) — path to a custom workflow file. When present,
|
|
73
|
+
the orchestrator invokes this file directly instead of the built-in workflow
|
|
74
|
+
for the command name. Used for custom phase commands in `engineering/commands/`.
|
|
75
|
+
- At least one phase is required per pipeline.
|
|
76
|
+
|
|
77
|
+
### Pipeline name
|
|
78
|
+
- Must be a non-empty string containing only `[a-z0-9_-]`.
|
|
79
|
+
- The name `default` is valid and overrides the hardcoded default pipeline.
|
|
80
|
+
|
|
81
|
+
### File integrity
|
|
82
|
+
- If `.forge/config.json` is not valid JSON, exit 1 with a parse error.
|
|
83
|
+
Never overwrite a corrupt file.
|
|
84
|
+
|
|
85
|
+
## Algorithm
|
|
86
|
+
|
|
87
|
+
### Read path (`get`)
|
|
88
|
+
1. Read and parse `.forge/config.json`.
|
|
89
|
+
2. Traverse the dot-notation path.
|
|
90
|
+
3. Print the value as JSON (pretty-printed if object/array, bare if scalar).
|
|
91
|
+
|
|
92
|
+
### Write path (`pipeline add`)
|
|
93
|
+
1. Read and parse `.forge/config.json`. Fail fast on parse error.
|
|
94
|
+
2. Run validation rules against the incoming phases. Fail fast on error.
|
|
95
|
+
3. Ensure `config.pipelines` key exists (create empty object if absent).
|
|
96
|
+
4. Merge the new pipeline entry under `config.pipelines[name]`.
|
|
97
|
+
5. Serialise back to JSON with the same indentation as the source file
|
|
98
|
+
(detect indent from the first indented line; default to 2 spaces).
|
|
99
|
+
6. Write atomically: write to a temp file alongside `config.json`, then
|
|
100
|
+
rename over the original. Never leave a partial write.
|
|
101
|
+
|
|
102
|
+
### Write path (`pipeline remove`)
|
|
103
|
+
1. Read and parse `.forge/config.json`.
|
|
104
|
+
2. Check `config.pipelines[name]` exists; exit 1 if not.
|
|
105
|
+
3. Delete the key.
|
|
106
|
+
4. If `config.pipelines` is now empty, remove the `pipelines` key entirely.
|
|
107
|
+
5. Serialise and write atomically (same indent detection as above).
|
|
108
|
+
|
|
109
|
+
## Error Handling
|
|
110
|
+
|
|
111
|
+
- Wrap the entire entry point in a top-level exception handler.
|
|
112
|
+
- On unexpected errors (file I/O failures, JSON parse errors, unhandled
|
|
113
|
+
exceptions), print a clear one-line message to stderr and exit 1.
|
|
114
|
+
- Never let the tool crash with an unhandled exception or stack trace visible
|
|
115
|
+
to the caller — all errors are caught and reported cleanly.
|
|
116
|
+
- Python pattern:
|
|
117
|
+
```python
|
|
118
|
+
if __name__ == "__main__":
|
|
119
|
+
try:
|
|
120
|
+
sys.exit(main())
|
|
121
|
+
except Exception as e:
|
|
122
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
123
|
+
sys.exit(1)
|
|
124
|
+
```
|
|
125
|
+
- JS/TS pattern:
|
|
126
|
+
```js
|
|
127
|
+
process.on('uncaughtException', (e) => {
|
|
128
|
+
process.stderr.write(`Error: ${e.message}\n`);
|
|
129
|
+
process.exit(1);
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Formatting Rules
|
|
134
|
+
|
|
135
|
+
- Preserve the original indentation of the file.
|
|
136
|
+
- Do not reorder top-level keys.
|
|
137
|
+
- Do not add or remove trailing newlines beyond what was present.
|
|
138
|
+
- `list-pipelines` output: markdown pipe table with columns
|
|
139
|
+
`Name | Description | Phases`. Print `(none)` when description is absent.
|
|
140
|
+
- `pipeline get` output: optional description line prefixed with `──`, then
|
|
141
|
+
a markdown pipe table with columns `# | Role | Command | Workflow | Model | maxIter`.
|
|
142
|
+
Print `(built-in)` when `workflow` is absent; `—` when `maxIterations` is absent.
|
|
143
|
+
- Success messages prefixed with `〇`; errors prefixed with `×`; neutral info with `──`.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Tool Spec: seed-store
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Bootstrap the JSON store from an existing `engineering/` directory structure.
|
|
6
|
+
Used when a project already has sprint/task artifacts but no JSON store.
|
|
7
|
+
|
|
8
|
+
## Inputs
|
|
9
|
+
|
|
10
|
+
- `.forge/config.json` — project prefix, paths
|
|
11
|
+
- `engineering/sprints/` — existing sprint directories
|
|
12
|
+
- `engineering/bugs/` — existing bug directories
|
|
13
|
+
|
|
14
|
+
## Outputs
|
|
15
|
+
|
|
16
|
+
- `.forge/store/sprints/*.json` — one per discovered sprint
|
|
17
|
+
- `.forge/store/tasks/*.json` — one per discovered task
|
|
18
|
+
- `.forge/store/bugs/*.json` — one per discovered bug
|
|
19
|
+
|
|
20
|
+
## CLI Interface
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
<tool> seed-store # scan and create
|
|
24
|
+
<tool> seed-store --dry-run # preview what would be created
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Exit 0 on success, 1 on error.
|
|
28
|
+
|
|
29
|
+
## Output Field Schema
|
|
30
|
+
|
|
31
|
+
All JSON files use **camelCase** field names to match `validate-store`.
|
|
32
|
+
|
|
33
|
+
**Sprint** (`.forge/store/sprints/<ID>.json`):
|
|
34
|
+
```json
|
|
35
|
+
{ "sprintId": "PREFIX-S01", "title": "...", "status": "active" }
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Task** (`.forge/store/tasks/<ID>.json`):
|
|
39
|
+
```json
|
|
40
|
+
{ "taskId": "PREFIX-S01-1", "sprintId": "PREFIX-S01", "title": "...", "status": "planned" }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Bug** (`.forge/store/bugs/<ID>.json`):
|
|
44
|
+
```json
|
|
45
|
+
{ "bugId": "PREFIX-B01", "title": "...", "severity": "medium", "status": "reported" }
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Status defaults: sprint → `"active"`, task → `"planned"`, bug → `"reported"`.
|
|
49
|
+
Infer a better status from artifact presence when possible (e.g. PROGRESS.md
|
|
50
|
+
with "committed" → `"committed"`).
|
|
51
|
+
|
|
52
|
+
## Error Handling
|
|
53
|
+
|
|
54
|
+
- Wrap the entire entry point in a top-level exception handler.
|
|
55
|
+
- On unexpected errors (missing config, unreadable directories, unhandled
|
|
56
|
+
exceptions), print a clear one-line message to stderr and exit 1.
|
|
57
|
+
- Never let the tool crash with an unhandled exception or stack trace visible
|
|
58
|
+
to the caller — all errors are caught and reported cleanly.
|
|
59
|
+
- Python pattern:
|
|
60
|
+
```python
|
|
61
|
+
if __name__ == "__main__":
|
|
62
|
+
try:
|
|
63
|
+
sys.exit(main())
|
|
64
|
+
except Exception as e:
|
|
65
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
66
|
+
sys.exit(1)
|
|
67
|
+
```
|
|
68
|
+
- JS/TS pattern:
|
|
69
|
+
```js
|
|
70
|
+
process.on('uncaughtException', (e) => {
|
|
71
|
+
process.stderr.write(`Error: ${e.message}\n`);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Algorithm
|
|
77
|
+
|
|
78
|
+
1. Read `.forge/config.json` for prefix and paths
|
|
79
|
+
2. Scan `engineering/sprints/` for sprint directories (pattern: S{NN})
|
|
80
|
+
3. For each sprint directory:
|
|
81
|
+
a. Create sprint JSON using the camelCase schema above
|
|
82
|
+
b. Scan for task directories (pattern: T{NN})
|
|
83
|
+
c. For each task directory:
|
|
84
|
+
- Read PLAN.md, PROGRESS.md if they exist
|
|
85
|
+
- Extract title, status from artifact content
|
|
86
|
+
- Create task JSON using the camelCase schema above
|
|
87
|
+
4. Scan `engineering/bugs/` for bug directories
|
|
88
|
+
5. For each bug directory:
|
|
89
|
+
a. Read available artifacts
|
|
90
|
+
b. Create bug JSON using the camelCase schema above
|
|
91
|
+
6. Report: N sprints, N tasks, N bugs seeded
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
# Tool Spec: store-cli
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Deterministic store custodian CLI — the sole authorized gateway for the
|
|
6
|
+
probabilistic layer to read and write the JSON store at `.forge/store/`.
|
|
7
|
+
Wraps `store.cjs` facade, enforces schema validation on every write, and
|
|
8
|
+
enforces status transition rules on `update-status`. Deterministic — no AI
|
|
9
|
+
needed.
|
|
10
|
+
|
|
11
|
+
## Inputs
|
|
12
|
+
|
|
13
|
+
- `.forge/config.json` — paths (specifically `paths.forgeRoot` for schema resolution)
|
|
14
|
+
- `.forge/schemas/*.schema.json` — canonical JSON Schema files (primary source)
|
|
15
|
+
- `forge/schemas/*.schema.json` — in-tree source schemas (fallback for dogfooding)
|
|
16
|
+
- CLI arguments — command, entity type, JSON payload, flags
|
|
17
|
+
|
|
18
|
+
## Outputs
|
|
19
|
+
|
|
20
|
+
- Entity records written to `.forge/store/` (via `store.cjs` facade)
|
|
21
|
+
- Event records written to `.forge/store/events/{sprintId}/`
|
|
22
|
+
- Sidecar files written to `.forge/store/events/{sprintId}/_{eventId}_usage.json`
|
|
23
|
+
- `COLLATION_STATE.json` written to `.forge/store/`
|
|
24
|
+
- JSON results to stdout on success
|
|
25
|
+
- Per-field error messages to stderr on failure
|
|
26
|
+
- Exit 0 on success, 1 on failure
|
|
27
|
+
|
|
28
|
+
## CLI Interface
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
<tool> store-cli write <entity> '<json>' Write a full entity record
|
|
32
|
+
<tool> store-cli read <entity> <id> [--json] Read an entity record
|
|
33
|
+
<tool> store-cli list <entity> [key=value ...] List entities with optional filter
|
|
34
|
+
<tool> store-cli delete <entity> <id> Delete an entity record
|
|
35
|
+
<tool> store-cli update-status <entity> <id> <field> <value> [--force]
|
|
36
|
+
Update status/enum field with transition check
|
|
37
|
+
<tool> store-cli emit <sprintId> '<json>' [--sidecar] Write an event (or sidecar)
|
|
38
|
+
<tool> store-cli merge-sidecar <sprintId> <eventId> Merge sidecar into canonical event
|
|
39
|
+
<tool> store-cli purge-events <sprintId> Delete all events for a sprint
|
|
40
|
+
<tool> store-cli write-collation-state '<json>' Write COLLATION_STATE.json
|
|
41
|
+
<tool> store-cli validate <entity> '<json>' Validate against schema without writing
|
|
42
|
+
<tool> store-cli nlp '<intent>' Query store by natural language intent (NLP)
|
|
43
|
+
<tool> store-cli query [--sprint|--task|--bug|--feature <id>] [--status <s>]
|
|
44
|
+
[--keyword <term>] [--type <entity>] [flags]
|
|
45
|
+
Query store by exact flags or intent
|
|
46
|
+
<tool> store-cli query --mode strict|nlp|off [flags] Explicit mode control (strict=exact flags only)
|
|
47
|
+
<tool> store-cli schema Dump entity schemas, status enums, NLP grammar
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Entity types: `sprint`, `task`, `bug`, `event`, `feature`
|
|
51
|
+
|
|
52
|
+
Flags:
|
|
53
|
+
- `--dry-run` — validate and preview without writing (applies to all write commands)
|
|
54
|
+
- `--force` — bypass transition check on `update-status` (emits warning)
|
|
55
|
+
- `--json` — output raw JSON on `read` (no pretty-print)
|
|
56
|
+
- `--sidecar` — write as sidecar file on `emit` (ephemeral, `_`-prefixed)
|
|
57
|
+
- `--sprint <id>` — filter query by sprint ID (e.g. `S12`)
|
|
58
|
+
- `--task <id>` — query a specific task by ID
|
|
59
|
+
- `--bug <id>` — query a specific bug by ID
|
|
60
|
+
- `--feature <id>` — query a specific feature by ID
|
|
61
|
+
- `--status <value>` — filter query by status value
|
|
62
|
+
- `--keyword <term>` — keyword search on entity titles
|
|
63
|
+
- `--type <entity>` — restrict `--keyword` to `sprints|tasks|bugs|features`
|
|
64
|
+
- `--with-blockers` — follow `blockedBy` FK on tasks
|
|
65
|
+
- `--with-blocked-tasks` — follow `blocksTask` FK on bugs
|
|
66
|
+
- `--with-sprint` — follow `sprintId` FK on results
|
|
67
|
+
- `--with-feature` — follow `featureId` FK on results
|
|
68
|
+
- `--no-excerpts` — omit INDEX.md excerpts from results
|
|
69
|
+
- `--mode strict|nlp|off` — engine mode (`strict`/`off` = exact flags only; `nlp` = intent parse)
|
|
70
|
+
|
|
71
|
+
Exit codes: 0 on success, 1 on failure.
|
|
72
|
+
|
|
73
|
+
## Entity Types
|
|
74
|
+
|
|
75
|
+
| Entity | ID Field | Required Fields (minimal) | Store Path |
|
|
76
|
+
|--------|----------|---------------------------|------------|
|
|
77
|
+
| sprint | `sprintId` | `sprintId`, `title`, `status`, `taskIds`, `createdAt` | `.forge/store/sprints/{sprintId}.json` |
|
|
78
|
+
| task | `taskId` | `taskId`, `sprintId`, `title`, `status`, `path` | `.forge/store/tasks/{taskId}.json` |
|
|
79
|
+
| bug | `bugId` | `bugId`, `title`, `severity`, `status`, `path`, `reportedAt` | `.forge/store/bugs/{bugId}.json` |
|
|
80
|
+
| event | `eventId` | `eventId`, `taskId`, `sprintId`, `role`, `action`, `phase`, `iteration`, `startTimestamp`, `endTimestamp`, `durationMinutes`, `model` | `.forge/store/events/{sprintId}/{eventId}.json` |
|
|
81
|
+
| feature | `id` | `id`, `title`, `status`, `created_at` | `.forge/store/features/{id}.json` |
|
|
82
|
+
|
|
83
|
+
Note: `feature` uses `id` (not `feature_id`) as its primary key. The
|
|
84
|
+
`feature_id` field on sprint/task is a foreign key pointing to `feature.id`.
|
|
85
|
+
|
|
86
|
+
Nullable fields (accepted as `null` without error): `sprintId`, `taskId`,
|
|
87
|
+
`endTimestamp`, `durationMinutes`, `feature_id`, `description`, `completedAt`,
|
|
88
|
+
`resolvedAt`.
|
|
89
|
+
|
|
90
|
+
## Schema Validation
|
|
91
|
+
|
|
92
|
+
The CLI validates every write payload against the canonical JSON Schema before
|
|
93
|
+
writing. Schemas are loaded from:
|
|
94
|
+
|
|
95
|
+
1. `.forge/schemas/{type}.schema.json` (project-installed, primary)
|
|
96
|
+
2. `forge/schemas/{type}.schema.json` (in-tree source, for dogfooding)
|
|
97
|
+
3. Minimal built-in fallback (required fields only, with stderr warning)
|
|
98
|
+
|
|
99
|
+
Validation rules:
|
|
100
|
+
- All `required` fields must be present and non-null (except nullable fields)
|
|
101
|
+
- Field types must match schema declarations (including multi-type)
|
|
102
|
+
- Enum values must be in the declared set
|
|
103
|
+
- `additionalProperties: false` — reject records with undeclared fields
|
|
104
|
+
- `minimum` constraints enforced for numeric fields
|
|
105
|
+
|
|
106
|
+
On validation failure: exit 1, one error per line on stderr (prefixed with
|
|
107
|
+
field name), no partial write.
|
|
108
|
+
|
|
109
|
+
## Status Transitions
|
|
110
|
+
|
|
111
|
+
The `update-status` command enforces legal state transitions. Illegal
|
|
112
|
+
transitions are rejected (exit 1 with `"Illegal transition: ..."` on stderr).
|
|
113
|
+
Use `--force` to bypass (emits warning).
|
|
114
|
+
|
|
115
|
+
### Task
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
draft -> planned -> plan-approved -> implementing -> implemented
|
|
119
|
+
-> review-approved -> approved -> committed
|
|
120
|
+
|
|
121
|
+
Failed states (enterable from any non-terminal state):
|
|
122
|
+
plan-revision-required, code-revision-required, blocked, escalated, abandoned
|
|
123
|
+
|
|
124
|
+
Terminal states (no transitions out):
|
|
125
|
+
committed, abandoned
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Sprint
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
planning -> active -> completed -> retrospective-done
|
|
132
|
+
|
|
133
|
+
Failed states:
|
|
134
|
+
blocked, partially-completed, abandoned
|
|
135
|
+
|
|
136
|
+
Terminal states:
|
|
137
|
+
retrospective-done, abandoned
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Bug
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
reported -> triaged -> in-progress -> fixed
|
|
144
|
+
|
|
145
|
+
Terminal state:
|
|
146
|
+
fixed
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The architect-approve verdict for bugs travels through
|
|
150
|
+
`bug.summaries.approve.verdict` (read by `read-verdict.cjs §
|
|
151
|
+
BUG_PHASE_VERDICT_SOURCE`), not `bug.status`. Earlier revisions of this
|
|
152
|
+
spec listed `approved` and `verified` between `fixed` and the terminal;
|
|
153
|
+
they were removed because no workflow phase wrote them and their presence
|
|
154
|
+
in the enum invited LLM-translated task workflows to attempt
|
|
155
|
+
`update-status bug ... approved` — the trap that produced FORGE-BUG-002.
|
|
156
|
+
|
|
157
|
+
### Feature
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
draft -> active -> shipped / retired
|
|
161
|
+
|
|
162
|
+
Terminal states:
|
|
163
|
+
shipped, retired
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Sidecar Pattern
|
|
167
|
+
|
|
168
|
+
Events support a sidecar mechanism for passing out-of-band data from subagents
|
|
169
|
+
back to the orchestrator.
|
|
170
|
+
|
|
171
|
+
### `emit --sidecar`
|
|
172
|
+
|
|
173
|
+
Writes a `_{eventId}_usage.json` ephemeral file alongside the canonical event.
|
|
174
|
+
Sidecar files require only an `eventId` field at minimum. Accepted fields:
|
|
175
|
+
|
|
176
|
+
| Field | Notes |
|
|
177
|
+
|-------|-------|
|
|
178
|
+
| `eventId` | Required — matches the canonical event |
|
|
179
|
+
| `inputTokens` | Token count |
|
|
180
|
+
| `outputTokens` | Token count |
|
|
181
|
+
| `cacheReadTokens` | Cache hit tokens |
|
|
182
|
+
| `cacheWriteTokens` | Cache miss tokens (alias: `cacheCreationTokens`) |
|
|
183
|
+
| `estimatedCostUSD` | Cost estimate (alias: `cost`) |
|
|
184
|
+
| `model` | Full model identifier |
|
|
185
|
+
| `durationMinutes` | Decimal minutes |
|
|
186
|
+
| `startTimestamp` | ISO 8601 |
|
|
187
|
+
| `endTimestamp` | ISO 8601 |
|
|
188
|
+
| `tokenSource` | `reported` or `estimated` |
|
|
189
|
+
|
|
190
|
+
Alias mapping at merge time: `cacheCreationTokens` -> `cacheWriteTokens`,
|
|
191
|
+
`cost` -> `estimatedCostUSD`.
|
|
192
|
+
|
|
193
|
+
### `merge-sidecar`
|
|
194
|
+
|
|
195
|
+
Reads the sidecar, merges token fields into the canonical event via
|
|
196
|
+
`store.writeEvent()`, and deletes the sidecar file. Fails if either file is
|
|
197
|
+
missing.
|
|
198
|
+
|
|
199
|
+
## Error Handling
|
|
200
|
+
|
|
201
|
+
- Wrap the entire entry point in a top-level exception handler.
|
|
202
|
+
- On unexpected errors (missing store files, bad JSON, unhandled exceptions),
|
|
203
|
+
print a clear one-line message to stderr and exit 1.
|
|
204
|
+
- Never let the tool crash with an unhandled exception or stack trace visible
|
|
205
|
+
to the caller — all errors are caught and reported cleanly.
|
|
206
|
+
- JS/TS pattern:
|
|
207
|
+
```js
|
|
208
|
+
process.on('uncaughtException', (e) => {
|
|
209
|
+
process.stderr.write(`Error: ${e.message}\n`);
|
|
210
|
+
process.exit(1);
|
|
211
|
+
});
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Algorithm
|
|
215
|
+
|
|
216
|
+
### `write`
|
|
217
|
+
1. Parse entity type and JSON payload from CLI args.
|
|
218
|
+
2. Validate entity type is one of: sprint, task, bug, event, feature.
|
|
219
|
+
3. Parse JSON payload (exit 1 on parse error).
|
|
220
|
+
4. Validate payload against schema for the entity type.
|
|
221
|
+
5. If `--dry-run`, report what would be written and exit 0.
|
|
222
|
+
6. Write entity via `store.write{Entity}()` facade.
|
|
223
|
+
|
|
224
|
+
### `read`
|
|
225
|
+
1. Parse entity type and ID from CLI args.
|
|
226
|
+
2. For events, scan sprint directories to locate the event file.
|
|
227
|
+
3. Output the record (pretty-print or `--json` raw).
|
|
228
|
+
4. Exit 1 if entity not found.
|
|
229
|
+
|
|
230
|
+
### `list`
|
|
231
|
+
1. Parse entity type and optional key=value filter pairs.
|
|
232
|
+
2. List entities via `store.list{Entities}()` with filter.
|
|
233
|
+
3. Output JSON array.
|
|
234
|
+
|
|
235
|
+
### `update-status`
|
|
236
|
+
1. Read the current record via `store.get{Entity}()`.
|
|
237
|
+
2. Check that `current[field] -> new` is a legal transition.
|
|
238
|
+
3. If `--force`, bypass with warning on stderr.
|
|
239
|
+
4. Apply the update and write back via `store.write{Entity}()`.
|
|
240
|
+
5. Output JSON result with `from`/`to` fields.
|
|
241
|
+
|
|
242
|
+
### `emit`
|
|
243
|
+
1. Parse sprintId and JSON payload.
|
|
244
|
+
2. If `--sidecar`: write `_{eventId}_usage.json` file directly.
|
|
245
|
+
3. If canonical: validate against event schema, write via `store.writeEvent()`.
|
|
246
|
+
4. Output JSON result.
|
|
247
|
+
|
|
248
|
+
### `merge-sidecar`
|
|
249
|
+
1. Read sidecar file. Read canonical event file.
|
|
250
|
+
2. Merge token fields from sidecar into event (with alias resolution).
|
|
251
|
+
3. Write updated event via `store.writeEvent()`.
|
|
252
|
+
4. Delete sidecar file.
|
|
253
|
+
|
|
254
|
+
### `validate`
|
|
255
|
+
1. Parse entity type and JSON payload.
|
|
256
|
+
2. Validate against schema (same logic as `write`).
|
|
257
|
+
3. Exit 1 on errors (no write), exit 0 with `{"ok":true,"valid":true}`.
|
|
258
|
+
|
|
259
|
+
### `nlp '<intent>'`
|
|
260
|
+
1. Spawn `store-query.cjs nlp` with the intent string.
|
|
261
|
+
2. Output JSON to stdout: `{query, path, traversalTrace, results, relatedFileRefs, meta}`.
|
|
262
|
+
3. `results[]` contains: `{id, title, status, type, relationships, fileRefs, excerpt}`.
|
|
263
|
+
|
|
264
|
+
### `query [flags|intent]`
|
|
265
|
+
1. If exact entity flags present (`--sprint/--task/--bug/--feature`), run exact-args path.
|
|
266
|
+
2. If `--keyword` present, run keyword search path.
|
|
267
|
+
3. If intent string present (no flags), run NLP path.
|
|
268
|
+
4. `--mode strict|off` rejects intent strings; `--mode nlp` forces NLP path.
|
|
269
|
+
5. Returns same JSON structure as `nlp`.
|
|
270
|
+
|
|
271
|
+
### `schema`
|
|
272
|
+
1. Load project config (prefix, paths).
|
|
273
|
+
2. Return entity schemas, status/severity enums, FK relationships, and NLP grammar vocabulary.
|
|
274
|
+
3. Output: `{project, entities, entitySynonyms, statusSynonyms, grammar}`.
|
|
275
|
+
|
|
276
|
+
## Query Output Schema
|
|
277
|
+
|
|
278
|
+
```json
|
|
279
|
+
{
|
|
280
|
+
"query": "<input string>",
|
|
281
|
+
"path": "exact | keyword | intent-nlp",
|
|
282
|
+
"traversalTrace": ["<step descriptions>"],
|
|
283
|
+
"results": [
|
|
284
|
+
{
|
|
285
|
+
"id": "<entity ID>",
|
|
286
|
+
"title": "<entity title>",
|
|
287
|
+
"status": "<current status>",
|
|
288
|
+
"type": "task | bug | sprint | feature",
|
|
289
|
+
"relationships": {
|
|
290
|
+
"sprintId": "<sprint ID>",
|
|
291
|
+
"featureId": "<feature ID>",
|
|
292
|
+
"blockedBy": ["<bug IDs>"],
|
|
293
|
+
"blocksTask": ["<task IDs>"]
|
|
294
|
+
},
|
|
295
|
+
"fileRefs": {
|
|
296
|
+
"json": "<store JSON path>",
|
|
297
|
+
"md": "<INDEX.md path>"
|
|
298
|
+
},
|
|
299
|
+
"storeRef": "<store JSON path>",
|
|
300
|
+
"indexRef": "<INDEX.md path>",
|
|
301
|
+
"excerpt": "<first 4 sentences from INDEX.md, or null>"
|
|
302
|
+
}
|
|
303
|
+
],
|
|
304
|
+
"relatedFileRefs": ["<all md and json paths>"],
|
|
305
|
+
"totalMatched": 7,
|
|
306
|
+
"returned": 3,
|
|
307
|
+
"limit": 3,
|
|
308
|
+
"sort": "desc",
|
|
309
|
+
"meta": {
|
|
310
|
+
"mode": "auto | strict | nlp | off",
|
|
311
|
+
"engineVersion": "1.0.0",
|
|
312
|
+
"totalTimeMs": 42
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Count mode response (when intent contains `how many`, `count of`, etc.):
|
|
318
|
+
|
|
319
|
+
```json
|
|
320
|
+
{
|
|
321
|
+
"query": "how many open bugs",
|
|
322
|
+
"path": "intent-nlp",
|
|
323
|
+
"traversalTrace": ["..."],
|
|
324
|
+
"count": 7,
|
|
325
|
+
"results": [],
|
|
326
|
+
"totalMatched": 7
|
|
327
|
+
}
|
|
328
|
+
```
|