@uoyo/mvtt 2.0.0-beta.6 → 2.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/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -6
- package/dist/cli.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +28 -16
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +64 -59
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/uninstall.js +58 -25
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +31 -20
- package/dist/commands/update.js.map +1 -1
- package/dist/fs/materialize.d.ts.map +1 -1
- package/dist/fs/materialize.js +3 -2
- package/dist/fs/materialize.js.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/scripts/epic-update.cjs +32 -14
- package/dist/scripts/epic-update.md +57 -0
- package/dist/scripts/plan-update.cjs +54 -23
- package/dist/scripts/plan-update.md +59 -0
- package/dist/scripts/session-update.cjs +36 -17
- package/dist/types/platform.d.ts +1 -1
- package/dist/types/platform.d.ts.map +1 -1
- package/dist/types/platform.js +12 -0
- package/dist/types/platform.js.map +1 -1
- package/dist/util/bilingual.d.ts +10 -0
- package/dist/util/bilingual.d.ts.map +1 -0
- package/dist/util/bilingual.js +14 -0
- package/dist/util/bilingual.js.map +1 -0
- package/dist/util/cancel.d.ts +2 -0
- package/dist/util/cancel.d.ts.map +1 -0
- package/dist/util/cancel.js +6 -0
- package/dist/util/cancel.js.map +1 -0
- package/dist/util/color.d.ts +9 -6
- package/dist/util/color.d.ts.map +1 -1
- package/dist/util/color.js +10 -10
- package/dist/util/color.js.map +1 -1
- package/dist/util/spinner.d.ts +8 -0
- package/dist/util/spinner.d.ts.map +1 -0
- package/dist/util/spinner.js +17 -0
- package/dist/util/spinner.js.map +1 -0
- package/install-manifest.yaml +4 -0
- package/package.json +4 -3
- package/registry.yaml +72 -72
- package/sources/defaults/config.yaml +5 -0
- package/sources/scripts/epic-update.js +3 -21
- package/sources/scripts/epic-update.md +57 -0
- package/sources/scripts/plan-update.js +30 -20
- package/sources/scripts/plan-update.md +59 -0
- package/sources/scripts/session-update.js +7 -23
- package/sources/sections/activation-load-config.md +7 -10
- package/sources/sections/activation-load-context.md +15 -25
- package/sources/sections/activation-preflight.md +1 -1
- package/sources/sections/footer-next-steps.md +1 -1
- package/sources/sections/language-constraint.md +11 -0
- package/sources/sections/output-format-constraint.md +11 -14
- package/sources/sections/project-context-profile.md +29 -29
- package/sources/sections/script-usage-rule.md +32 -0
- package/sources/sections/session-update.md +24 -110
- package/sources/skills/mvt-analyze/business.md +1 -1
- package/sources/skills/mvt-analyze/manifest.yaml +7 -7
- package/sources/skills/mvt-analyze-code/manifest.yaml +7 -7
- package/sources/skills/mvt-bug-detect/manifest.yaml +3 -0
- package/sources/skills/mvt-check-context/manifest.yaml +3 -0
- package/sources/skills/mvt-cleanup/business.md +9 -0
- package/sources/skills/mvt-cleanup/manifest.yaml +6 -6
- package/sources/skills/mvt-config/business.md +1 -0
- package/sources/skills/mvt-config/manifest.yaml +4 -0
- package/sources/skills/mvt-create-skill/business.md +1 -1
- package/sources/skills/mvt-create-skill/manifest.yaml +1 -1
- package/sources/skills/mvt-decompose/business.md +18 -9
- package/sources/skills/mvt-decompose/manifest.yaml +7 -7
- package/sources/skills/mvt-design/business.md +34 -43
- package/sources/skills/mvt-design/manifest.yaml +7 -7
- package/sources/skills/mvt-fix/manifest.yaml +6 -6
- package/sources/skills/mvt-help/business.md +19 -9
- package/sources/skills/mvt-help/manifest.yaml +6 -14
- package/sources/skills/mvt-implement/business.md +27 -34
- package/sources/skills/mvt-implement/manifest.yaml +8 -14
- package/sources/skills/mvt-init/manifest.yaml +6 -6
- package/sources/skills/mvt-manage-context/manifest.yaml +1 -1
- package/sources/skills/mvt-plan-dev/business.md +12 -2
- package/sources/skills/mvt-plan-dev/manifest.yaml +7 -7
- package/sources/skills/mvt-quick-dev/manifest.yaml +1 -1
- package/sources/skills/mvt-refactor/manifest.yaml +1 -1
- package/sources/skills/mvt-resume/manifest.yaml +3 -0
- package/sources/skills/mvt-review/business.md +3 -9
- package/sources/skills/mvt-review/manifest.yaml +7 -7
- package/sources/skills/mvt-status/business.md +2 -12
- package/sources/skills/mvt-status/manifest.yaml +3 -0
- package/sources/skills/mvt-sync-context/business.md +1 -1
- package/sources/skills/mvt-sync-context/manifest.yaml +6 -6
- package/sources/skills/mvt-template/manifest.yaml +3 -0
- package/sources/skills/mvt-test/business.md +2 -10
- package/sources/skills/mvt-test/manifest.yaml +7 -7
- package/sources/skills/mvt-update-plan/business.md +12 -27
- package/sources/skills/mvt-update-plan/manifest.yaml +12 -6
- package/sources/templates/analyze-output/body.md +41 -0
- package/sources/templates/decompose-output/body.md +36 -0
- package/sources/templates/design-output/body.md +48 -0
- package/sources/templates/implement-output/body.md +48 -3
- package/sources/templates/project-context/body.md +45 -0
- package/sources/templates/review-output/body.md +59 -0
- package/sources/templates/test-output/body.md +72 -0
- package/sources/sections/output-language-constraint.md +0 -11
|
@@ -11,27 +11,9 @@
|
|
|
11
11
|
* esbuild bundles it into a zero-dependency single file deployed to
|
|
12
12
|
* .ai-agents/scripts/epic-update.cjs.
|
|
13
13
|
*
|
|
14
|
-
* Usage:
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* --complete-child <change_id>
|
|
18
|
-
*
|
|
19
|
-
* node .ai-agents/scripts/epic-update.cjs \
|
|
20
|
-
* --epic <path> \
|
|
21
|
-
* --set-child-status <change_id> --child-status <status>
|
|
22
|
-
*
|
|
23
|
-
* node .ai-agents/scripts/epic-update.cjs \
|
|
24
|
-
* --epic <path> \
|
|
25
|
-
* --switch-active <change_id>
|
|
26
|
-
*
|
|
27
|
-
* node .ai-agents/scripts/epic-update.cjs \
|
|
28
|
-
* --epic <path> \
|
|
29
|
-
* --add-child <id> --child-title "<t>" --child-scope "<s>" \
|
|
30
|
-
* [--child-depends-on "dep1,dep2"] \
|
|
31
|
-
* [--add-child <id2> --child-title "<t2>" ...]
|
|
32
|
-
*
|
|
33
|
-
* node .ai-agents/scripts/epic-update.cjs \
|
|
34
|
-
* --validate <path-to-epic.yaml>
|
|
14
|
+
* Usage: see the "Script Usage Rule" section in any skill that references
|
|
15
|
+
* sections/script-usage-rule.md, or read the full reference at
|
|
16
|
+
* .ai-agents/scripts/epic-update.md.
|
|
35
17
|
*
|
|
36
18
|
* Output:
|
|
37
19
|
* Success (exit 0): one-line JSON on stdout
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Epic Update Script — Full Reference
|
|
2
|
+
|
|
3
|
+
> **This file is the authoritative usage reference for `epic-update.cjs`.**
|
|
4
|
+
> Read this file before calling the script. Do NOT read the `.cjs` or `.js` source to learn flag names or semantics.
|
|
5
|
+
|
|
6
|
+
The script has five modes — use exactly one mode per invocation:
|
|
7
|
+
|
|
8
|
+
## Commands
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
# Mode 1 — Complete the current child and advance to the next sub-change
|
|
12
|
+
node .ai-agents/scripts/epic-update.cjs --epic <epic_path> --complete-child <change_id>
|
|
13
|
+
|
|
14
|
+
# Mode 2 — Set a child's status without advancing current_change
|
|
15
|
+
node .ai-agents/scripts/epic-update.cjs --epic <epic_path> --set-child-status <change_id> --child-status <active|pending|done|abandoned>
|
|
16
|
+
|
|
17
|
+
# Mode 3 — Switch the active child to a different one (reorder)
|
|
18
|
+
node .ai-agents/scripts/epic-update.cjs --epic <epic_path> --switch-active <change_id>
|
|
19
|
+
|
|
20
|
+
# Mode 4 — Add one or more children to an existing epic
|
|
21
|
+
node .ai-agents/scripts/epic-update.cjs --epic <epic_path> \
|
|
22
|
+
--add-child <id> --child-title "<title>" --child-scope "<scope>" [--child-depends-on "dep1,dep2"] \
|
|
23
|
+
[--add-child <id2> --child-title "<title2>" --child-scope "<scope2>" ...]
|
|
24
|
+
|
|
25
|
+
# Mode 5 — Validate an epic.yaml (read-only, no write)
|
|
26
|
+
node .ai-agents/scripts/epic-update.cjs --validate <epic_path>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Argument values
|
|
30
|
+
|
|
31
|
+
| Argument | Value source | Example |
|
|
32
|
+
|----------|-------------|---------|
|
|
33
|
+
| `--epic` | `active_epic.epic_path` resolved from session.yaml | `".ai-agents/workspace/artifacts/epic-20260608-ecommerce-platform/epic.yaml"` |
|
|
34
|
+
| `--complete-child` | `active_change.id` of the child whose plan is fully done | `20260608-sub` |
|
|
35
|
+
| `--set-child-status` | target child `change_id` to re-status | `20260608-sub` |
|
|
36
|
+
| `--child-status` | new status (with `--set-child-status`): `active` / `pending` / `done` / `abandoned` | `done` |
|
|
37
|
+
| `--switch-active` | target child `change_id` to make the active one | `20260609-sub2` |
|
|
38
|
+
| `--add-child` | new child id (repeatable for multiple children in one invocation) | `20260620-sub3` |
|
|
39
|
+
| `--child-title` | title for the child added by the preceding `--add-child` | `"Cart"` |
|
|
40
|
+
| `--child-scope` | scope description for the child added by the preceding `--add-child` | `"Shopping cart CRUD and checkout flow"` |
|
|
41
|
+
| `--child-depends-on` | optional; comma-separated prerequisite child `change_id` values | `"20260608-sub"` |
|
|
42
|
+
| `--validate` | path to an `epic.yaml` to validate (read-only) | same as `--epic` |
|
|
43
|
+
|
|
44
|
+
## Parameter semantics
|
|
45
|
+
|
|
46
|
+
| Argument | When to use | Effect on `epic.yaml` |
|
|
47
|
+
|----------|-------------|------------------------|
|
|
48
|
+
| `--complete-child` | A child change's plan is fully done and the epic should advance | Sets the child `status: done`, advances `current_change` to the next `pending` child whose `depends_on` are all `done` (DAG-based). |
|
|
49
|
+
| `--set-child-status` + `--child-status` | Mark a child `done` or `abandoned` without advancing `current_change` (e.g. defer mode) | Sets the child's status only; `current_change` unchanged. |
|
|
50
|
+
| `--switch-active` | Reorder to a different child (dependencies permitting) | Sets the target child `active`, others `pending`, updates `current_change`. Rejects if the target's `depends_on` have unfinished prerequisites. |
|
|
51
|
+
| `--add-child` (+ `--child-title` / `--child-scope` / `--child-depends-on`) | Append one or more children to an existing epic | Adds entries to `children[]`; validates id uniqueness + DAG; defaults `project` to the sole project name when single-project. |
|
|
52
|
+
| `--validate` | Verify `epic.yaml` integrity (e.g. after `/mvt-decompose` writes it) | Read-only check; no write. Reports DAG/structure errors on stderr. |
|
|
53
|
+
|
|
54
|
+
## Output interpretation
|
|
55
|
+
|
|
56
|
+
- **Exit 0**: success. stdout is a single-line JSON object (mirrors `plan-update.cjs` protocol). Use the fields directly to render output. The file is already written — do NOT read it back to verify.
|
|
57
|
+
- **Exit 1**: failure. stderr carries a plain-text error (unknown mode, child not found, dependency unsatisfied, validation failure, parse/write error). The file was **not** modified. Report the error to the user and do not fabricate a success summary.
|
|
@@ -19,16 +19,9 @@
|
|
|
19
19
|
* esbuild bundles it into a zero-dependency single file deployed to
|
|
20
20
|
* .ai-agents/scripts/plan-update.cjs.
|
|
21
21
|
*
|
|
22
|
-
* Usage:
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* --task <task_id> \
|
|
26
|
-
* --status <pending|in_progress|done|blocked|skipped> \
|
|
27
|
-
* [--projects "web,api"] \
|
|
28
|
-
* [--artifacts "<comma,separated,paths>"] \
|
|
29
|
-
* [--notes "<free-form text>"] \
|
|
30
|
-
* [--deliverables-pointer current] \
|
|
31
|
-
* [--mark-deliverable-stale <task_id>[,task_id2,...]]
|
|
22
|
+
* Usage: see the "Script Usage Rule" section in any skill that references
|
|
23
|
+
* sections/script-usage-rule.md, or read the full reference at
|
|
24
|
+
* .ai-agents/scripts/plan-update.md.
|
|
32
25
|
*
|
|
33
26
|
* Output:
|
|
34
27
|
* Success (exit 0): one-line JSON on stdout, e.g.
|
|
@@ -126,8 +119,15 @@ function parseArgs(argv) {
|
|
|
126
119
|
function validateArgs(args) {
|
|
127
120
|
if (!args.plan || args.plan === true) return ERRORS.MISSING_PLAN();
|
|
128
121
|
if (!args.task || args.task === true) return ERRORS.MISSING_TASK();
|
|
129
|
-
|
|
130
|
-
|
|
122
|
+
const hasStatus = args.status && args.status !== true;
|
|
123
|
+
const hasMutation = hasStatus ||
|
|
124
|
+
(args.artifacts && args.artifacts !== true) ||
|
|
125
|
+
(args.notes && args.notes !== true) ||
|
|
126
|
+
(args["deliverables-pointer"] && args["deliverables-pointer"] !== true) ||
|
|
127
|
+
(args["mark-deliverable-stale"] && args["mark-deliverable-stale"] !== true);
|
|
128
|
+
if (!hasMutation) return ERRORS.MISSING_STATUS();
|
|
129
|
+
if (args.status === true) return ERRORS.MISSING_STATUS();
|
|
130
|
+
if (hasStatus && !VALID_STATUSES.includes(args.status)) return ERRORS.INVALID_STATUS(args.status);
|
|
131
131
|
return null;
|
|
132
132
|
}
|
|
133
133
|
|
|
@@ -136,7 +136,9 @@ function applyUpdate(plan, args, now) {
|
|
|
136
136
|
const task = plan.tasks.find((t) => t.id === args.task);
|
|
137
137
|
|
|
138
138
|
const oldStatus = task.status;
|
|
139
|
-
|
|
139
|
+
if (args.status && args.status !== true) {
|
|
140
|
+
task.status = args.status;
|
|
141
|
+
}
|
|
140
142
|
|
|
141
143
|
if (args.artifacts && args.artifacts !== true) {
|
|
142
144
|
const incoming = args.artifacts
|
|
@@ -164,11 +166,13 @@ function applyUpdate(plan, args, now) {
|
|
|
164
166
|
task.notes = args.notes;
|
|
165
167
|
}
|
|
166
168
|
|
|
167
|
-
// completed_at consistency: set only on
|
|
168
|
-
if (args.status
|
|
169
|
-
task.completed_at
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
// completed_at consistency: set only on status updates.
|
|
170
|
+
if (args.status && args.status !== true) {
|
|
171
|
+
if (args.status === "done" && !task.completed_at) {
|
|
172
|
+
task.completed_at = now;
|
|
173
|
+
} else if (args.status !== "done") {
|
|
174
|
+
task.completed_at = null;
|
|
175
|
+
}
|
|
172
176
|
}
|
|
173
177
|
|
|
174
178
|
// --deliverables-pointer current
|
|
@@ -201,7 +205,7 @@ function applyUpdate(plan, args, now) {
|
|
|
201
205
|
|
|
202
206
|
plan.updated_at = now;
|
|
203
207
|
|
|
204
|
-
return { id: task.id, title: task.title || "", old_status: oldStatus, new_status:
|
|
208
|
+
return { id: task.id, title: task.title || "", old_status: oldStatus, new_status: task.status };
|
|
205
209
|
}
|
|
206
210
|
|
|
207
211
|
// -- current_tasks recomputation (per-project independent advancement) --
|
|
@@ -576,7 +580,13 @@ function main() {
|
|
|
576
580
|
process.stderr.write(taskChange.error + "\n");
|
|
577
581
|
process.exit(1);
|
|
578
582
|
}
|
|
579
|
-
|
|
583
|
+
let warning = null;
|
|
584
|
+
let switchNotif = null;
|
|
585
|
+
if (args.status && args.status !== true) {
|
|
586
|
+
const recomputed = recomputeCurrentTasks(plan, args.task, projectList);
|
|
587
|
+
warning = recomputed.warning;
|
|
588
|
+
switchNotif = recomputed.project_switch;
|
|
589
|
+
}
|
|
580
590
|
|
|
581
591
|
const validationErrors = validatePlan(plan, projectList);
|
|
582
592
|
if (validationErrors.length) {
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Plan Update Script — Full Reference
|
|
2
|
+
|
|
3
|
+
> **This file is the authoritative usage reference for `plan-update.cjs`.**
|
|
4
|
+
> Read this file before calling the script. Do NOT read the `.cjs` or `.js` source to learn flag names or semantics.
|
|
5
|
+
|
|
6
|
+
## Command
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
node .ai-agents/scripts/plan-update.cjs \
|
|
10
|
+
--plan "<active_change.plan_path>" \
|
|
11
|
+
--task <task_id> \
|
|
12
|
+
--projects "<comma,separated,project,names>" \
|
|
13
|
+
[--status <pending|in_progress|done|blocked|skipped>] \
|
|
14
|
+
[--artifacts "<comma,separated,paths>"] \
|
|
15
|
+
[--notes "<free-form text>"] \
|
|
16
|
+
[--deliverables-pointer current] \
|
|
17
|
+
[--mark-deliverable-stale <task_id>[,task_id2,...]]
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Include `--artifacts`, `--notes`, `--deliverables-pointer`, and `--mark-deliverable-stale` only when the skill's logic determines they apply; omit each flag otherwise.
|
|
21
|
+
|
|
22
|
+
## Argument values
|
|
23
|
+
|
|
24
|
+
| Argument | Value source | Example |
|
|
25
|
+
|----------|-------------|---------|
|
|
26
|
+
| `--plan` | `active_change.plan_path` resolved from session.yaml | `".ai-agents/workspace/artifacts/chg-001/plan.yaml"` |
|
|
27
|
+
| `--task` | the `task_id` being updated (resolved by the skill's Step 1) | `t1` |
|
|
28
|
+
| `--status` | optional; the new status: `pending` / `in_progress` / `done` / `blocked` / `skipped` | `done` |
|
|
29
|
+
| `--projects` | comma-separated project names from `project-context.yaml > projects[].name` (single-project: the sole project name) | `"web,api"` |
|
|
30
|
+
| `--artifacts` | optional; comma-separated paths to append (the script de-duplicates) | `"src/auth.ts,src/auth.test.ts"` |
|
|
31
|
+
| `--notes` | optional; overwrites the task's `notes` | `"blocked on API spec"` |
|
|
32
|
+
| `--deliverables-pointer` | optional; set to `current` to record that this task's deliverables section is written | `current` |
|
|
33
|
+
| `--mark-deliverable-stale` | optional; comma-separated downstream task ids whose deliverables are now stale | `"t3,t4"` |
|
|
34
|
+
|
|
35
|
+
## Parameter semantics
|
|
36
|
+
|
|
37
|
+
| Argument | When to use | Effect on `plan.yaml` |
|
|
38
|
+
|----------|-------------|------------------------|
|
|
39
|
+
| `--task` + optional `--status` | Use `--status` for status transitions; omit it for metadata-only updates such as deliverables freshness | When present, sets the task status; sets `completed_at` to now when `done`, else `null`; refreshes `plan.updated_at`. When omitted, status, `completed_at`, DAG advancement, and `current_tasks` are left unchanged. |
|
|
40
|
+
| `--projects` | Always (per-project validation) | Drives per-project DAG advancement of `current_tasks` and per-project validation. Required for correct multi-project plans. |
|
|
41
|
+
| `--artifacts` | Task produced or touched files | Appends + de-duplicates paths into the task's `artifacts.files`; handles `artifacts: null`. |
|
|
42
|
+
| `--notes` | Task needs a free-form note | Overwrites the task's existing `notes`. |
|
|
43
|
+
| `--deliverables-pointer` + `--mark-deliverable-stale` | Task wrote its deliverables section (e.g. `/mvt-implement` Step 8) | Records the deliverables pointer on the task; marks the listed downstream tasks' deliverables as stale so `/mvt-resume` and `/mvt-status` surface a warning. Use both flags together in a single invocation. |
|
|
44
|
+
|
|
45
|
+
## What the script does (deterministically)
|
|
46
|
+
|
|
47
|
+
1. **Apply**: when `--status` is present, sets the task status and `completed_at`; appends + de-duplicates `--artifacts`; overwrites `--notes`; refreshes `plan.updated_at`.
|
|
48
|
+
2. **Recompute `current_tasks`** only when `--status` is present (per-project independent advancement): for each project, finds the `in_progress` task or advances the first `pending` task whose `depends_on` are all in `resolvedIds` (done + skipped; blocked does NOT satisfy). Detects `project_switch` when advancement crosses a project boundary. Plan done -> `current_tasks = {}`.
|
|
49
|
+
3. **Validate** the mutated plan (unique ids, valid `depends_on` references, DAG/no-cycle per project, one `in_progress` per project, every task has acceptance, `completed_at` consistency, `current_tasks` validity, project naming constraint, task project membership).
|
|
50
|
+
4. **Write atomically** (temp + rename) only if validation passes.
|
|
51
|
+
|
|
52
|
+
## Output interpretation
|
|
53
|
+
|
|
54
|
+
- **Exit 0**: success. stdout is a single-line JSON object, e.g.:
|
|
55
|
+
```json
|
|
56
|
+
{"ok":true,"task":{"id":"t1","title":"...","old_status":"in_progress","new_status":"done"},"current_tasks":{"default":"t2"},"plan_status":"in_progress","progress":{"done":1,"total":4},"warning":null,"project_switch":null}
|
|
57
|
+
```
|
|
58
|
+
Use these fields directly to render output. The file is already written — do NOT read it back to verify. If `warning` is non-null, surface it. If `project_switch` is non-null, note the project boundary crossing.
|
|
59
|
+
- **Exit 1**: failure. stderr carries the error (invalid status, task not found, validation failure, parse/write error). The file was **not** modified. Report the error to the user and do not fabricate a success summary.
|
|
@@ -10,25 +10,8 @@
|
|
|
10
10
|
* pipeline, esbuild bundles it into a zero-dependency single file that
|
|
11
11
|
* gets deployed to .ai-agents/scripts/session-update.cjs.
|
|
12
12
|
*
|
|
13
|
-
* Usage:
|
|
14
|
-
*
|
|
15
|
-
* --skill <name> \
|
|
16
|
-
* --summary <text> \
|
|
17
|
-
* [--change-id <id>] \
|
|
18
|
-
* [--new-change <title>] \
|
|
19
|
-
* [--set-initialized] \
|
|
20
|
-
* [--update-change] \
|
|
21
|
-
* [--set-plan-path <path>] \
|
|
22
|
-
* [--close-change] \
|
|
23
|
-
* [--set-change-status <status>] \
|
|
24
|
-
* [--no-change] \
|
|
25
|
-
* [--set-synced] \
|
|
26
|
-
* [--truncate-history <n>] \
|
|
27
|
-
* [--new-epic <title> --epic-id <id>] \
|
|
28
|
-
* [--set-epic-path <path>] \
|
|
29
|
-
* [--set-epic-status <status>] \
|
|
30
|
-
* [--close-epic] \
|
|
31
|
-
* [--epic-id <id>] (with --new-change, links sub-change to epic)
|
|
13
|
+
* Usage: see the "State Update" section in any skill that references
|
|
14
|
+
* sections/session-update.md (rendered with per-skill flag parameters).
|
|
32
15
|
*
|
|
33
16
|
* Output:
|
|
34
17
|
* Success (exit 0): {"ok":true}
|
|
@@ -226,12 +209,13 @@ function main() {
|
|
|
226
209
|
}
|
|
227
210
|
}
|
|
228
211
|
|
|
229
|
-
// Now set new active_change
|
|
212
|
+
// Now set new active_change (preserve fields only when re-invoking on same change)
|
|
213
|
+
const isSameChange = session.active_change.id === args["change-id"];
|
|
230
214
|
session.active_change.id = args["change-id"];
|
|
231
215
|
session.active_change.title = args["new-change"];
|
|
232
|
-
session.active_change.created_at = now;
|
|
233
|
-
session.active_change.plan_path = "";
|
|
234
|
-
session.active_change.epic_id = args["epic-id"] || "";
|
|
216
|
+
session.active_change.created_at = isSameChange ? (session.active_change.created_at || now) : now;
|
|
217
|
+
session.active_change.plan_path = isSameChange ? (session.active_change.plan_path || "") : "";
|
|
218
|
+
session.active_change.epic_id = args["epic-id"] || session.active_change.epic_id || "";
|
|
235
219
|
}
|
|
236
220
|
|
|
237
221
|
// --set-initialized
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
###
|
|
2
|
-
Read `.ai-agents/config.yaml` and enforce
|
|
1
|
+
### Stage 4: Load Config & Apply Preferences (Config Foundation)
|
|
2
|
+
Read `.ai-agents/config.yaml` and enforce it for the whole session:
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
- `preferences.
|
|
6
|
-
- `preferences.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- `preferences.output.no_emojis` → If true, never use emojis
|
|
10
|
-
- `preferences.output.data_format` → Use this format for data sections in artifacts
|
|
11
|
-
- `preferences.context_routing.relevance_threshold` → Used by `/mvt-manage-context add` for AI routing (default 70 if missing)
|
|
4
|
+
- `preferences.interaction_language`: language for chat, prompts, status lines, tables, and summaries.
|
|
5
|
+
- `preferences.document_output_language`: language for files written to disk.
|
|
6
|
+
- `preferences.output.no_emojis`: if true, never use emojis.
|
|
7
|
+
- `preferences.output.data_format`: format for artifact data sections.
|
|
8
|
+
- `preferences.context_routing.relevance_threshold`: AI routing threshold for `/mvt-manage-context add` (default 70).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
## Activation Protocol
|
|
2
2
|
|
|
3
|
-
###
|
|
4
|
-
Load
|
|
3
|
+
### Stage 1: Load Context
|
|
4
|
+
Load foundational context:
|
|
5
5
|
- `.ai-agents/workspace/project-context.yaml` -- Project index (structural info)
|
|
6
6
|
- `.ai-agents/registry.yaml` -- Available skills registry and knowledge declarations
|
|
7
7
|
{{?extended_context}}
|
|
@@ -12,43 +12,33 @@ Extended context for this skill:
|
|
|
12
12
|
- {{.}}
|
|
13
13
|
{{/extended_context}}
|
|
14
14
|
|
|
15
|
-
###
|
|
15
|
+
### Stage 2: Resolve Project Scope (PS)
|
|
16
16
|
|
|
17
17
|
Read `project-context.yaml > projects[]`.
|
|
18
18
|
|
|
19
|
-
**Single project** (`projects.length == 1`):
|
|
19
|
+
**Single project** (`projects.length == 1`): PS = [sole project name]; skip the rest of this step.
|
|
20
20
|
|
|
21
21
|
**Multi-project** (`projects.length > 1`):
|
|
22
22
|
**Mode A -- Plan-driven** (active plan exists and skill operates on plan tasks):
|
|
23
|
-
1. **Plan signal**: PS = current task
|
|
24
|
-
2. **Path match**: Match current
|
|
25
|
-
3. **Prompt**: If
|
|
23
|
+
1. **Plan signal**: PS = current task `project` values from plan `current_tasks`; drop names absent from `projects[]`.
|
|
24
|
+
2. **Path match**: Match current paths against `projects[].path` and `source_paths`.
|
|
25
|
+
3. **Prompt**: If unresolved, list candidates and ask user. Never silently load all projects.
|
|
26
26
|
|
|
27
27
|
**Mode B -- Non-plan** (no active plan or ad-hoc changes):
|
|
28
|
-
Defer PS to execution: identify change target, match against `projects[].path` and `source_paths`, load project-specific knowledge on demand (
|
|
28
|
+
Defer PS to execution: identify change target, match against `projects[].path` and `source_paths`, load project-specific knowledge on demand (Stage 3).
|
|
29
29
|
|
|
30
|
-
###
|
|
30
|
+
### Stage 3: Load Knowledge
|
|
31
31
|
|
|
32
|
-
Registry
|
|
32
|
+
Registry knowledge maps are project-keyed; `_all` is reserved for all projects. This applies to top-level `knowledge` and `skills.<name>.knowledge`.
|
|
33
33
|
|
|
34
34
|
**Knowledge Loading Protocol**:
|
|
35
|
-
For each knowledge entry
|
|
36
|
-
1.
|
|
37
|
-
2.
|
|
38
|
-
3.
|
|
39
|
-
- `files: [a.md, b.md]` → load `.ai-agents/{source_value}/a.md`, `.ai-agents/{source_value}/b.md`.
|
|
40
|
-
- `files_from_manifest: true` → read `.ai-agents/{source_value}/manifest.yaml`, load entries with `auto_load: true`.
|
|
35
|
+
For each registry knowledge entry:
|
|
36
|
+
1. Read its `source` field, e.g. `knowledge/project/_generated/`.
|
|
37
|
+
2. Base dir = `.ai-agents/` + `source`, e.g. `.ai-agents/knowledge/project/_generated/`.
|
|
38
|
+
3. Load `files` entries from that base dir; if `files_from_manifest: true`, read `manifest.yaml` there and load entries with `auto_load: true`.
|
|
41
39
|
4. **Skip non-existent paths** silently (do not error or warn).
|
|
42
40
|
|
|
43
|
-
|
|
44
|
-
Given this registry entry:
|
|
45
|
-
```yaml
|
|
46
|
-
- id: project-context
|
|
47
|
-
source: knowledge/project/_generated/
|
|
48
|
-
files:
|
|
49
|
-
- project-context.md
|
|
50
|
-
```
|
|
51
|
-
Resolution: `.ai-agents/` + `knowledge/project/_generated/` + `project-context.md` = `.ai-agents/knowledge/project/_generated/project-context.md`
|
|
41
|
+
Example: `source: knowledge/project/_generated/` + `files: [project-context.md]` resolves to `.ai-agents/knowledge/project/_generated/project-context.md`.
|
|
52
42
|
|
|
53
43
|
**Anti-pattern -- DO NOT**:
|
|
54
44
|
- Guess or hardcode base directories (e.g., `.ai-agents/workspace/`).
|
|
@@ -24,7 +24,7 @@ Match the current state to one of the conditions below. If none match, use `defa
|
|
|
24
24
|
|
|
25
25
|
Infer 2-3 suggestions, choosing **only** from the skills declared under `skills` in `registry.yaml`:
|
|
26
26
|
- `history` in `session.yaml`
|
|
27
|
-
-
|
|
27
|
+
- Skill names and `description` fields in `registry.yaml`
|
|
28
28
|
- The current `active_change` state (if in progress)
|
|
29
29
|
- The standard workflow order (analyze → design → implement → review → test)
|
|
30
30
|
{{/conditional_suggestions}}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## Language Constraint (Mandatory)
|
|
2
|
+
|
|
3
|
+
This governs **all language output**. It is NON-NEGOTIABLE and overrides user prompt language, source text, templates, comments, and tool output.
|
|
4
|
+
|
|
5
|
+
### Interactive Output (spoken to the user)
|
|
6
|
+
|
|
7
|
+
Use `preferences.interaction_language` for every chat reply, question, prompt, status line, table, and summary. Re-assert it every turn, including long sessions. If absent, use `en-US`. Only an explicit user request to switch language overrides it.
|
|
8
|
+
|
|
9
|
+
### Persisted Document Output (files written to disk)
|
|
10
|
+
|
|
11
|
+
Use `preferences.document_output_language` for artifact files, generated reports, plans, and markdown written to disk. If absent, fall back to `interaction_language`. Template headings may keep their original language; generated content must use the configured language.
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
## Output Format Constraint (Mandatory)
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
**
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
**Notes**:
|
|
13
|
-
- If a diagram genuinely cannot be expressed in mermaid (e.g. a precise spatial/pixel layout), state that explicitly and prefer a Markdown table or prose description over ASCII art.
|
|
14
|
-
- This constraint is NON-NEGOTIABLE and overrides formatting habits inferred from templates or source material.
|
|
1
|
+
## Output Format Constraint (Mandatory)
|
|
2
|
+
|
|
3
|
+
Persisted markdown output MUST follow these rendering rules. Scope: artifact files, generated reports, plans, design documents, and any markdown written to disk. Chat output is out of scope.
|
|
4
|
+
|
|
5
|
+
**Rules**:
|
|
6
|
+
- **Diagrams**: Use fenced `mermaid` blocks for flowcharts, architecture, sequence, and structure diagrams. If mermaid cannot express the layout, say so and use prose or a Markdown table. Never use ASCII art.
|
|
7
|
+
- **Tables**: Use Markdown tables (`| col | col |`), not aligned spaces or tabs.
|
|
8
|
+
- **Code**: Use fenced blocks with language tags for code, commands, and config snippets.
|
|
9
|
+
- **Headings**: Use Markdown heading hierarchy (`#` -> `##` -> `###`) without skipping levels; do not replace headings with bold text.
|
|
10
|
+
|
|
11
|
+
This constraint is NON-NEGOTIABLE and overrides formatting habits inferred from templates or source material.
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
## Document Profile: project-context.md
|
|
2
|
-
|
|
3
|
-
Before writing to `project-context.md`, understand what this document IS and IS NOT.
|
|
4
|
-
|
|
5
|
-
### Identity
|
|
6
|
-
`project-context.md` is the project's **long-term semantic ground truth** -- a self-contained knowledge base consumed by AI skills to make decisions. It is NOT a copy of design documents, NOT a changelog, NOT an ADR index.
|
|
7
|
-
|
|
8
|
-
### Audience
|
|
9
|
-
The readers are AI skill instances (implementer, designer, tester, reviewer), NOT humans reading for reference. They use this document to make **binary decisions** (is this import legal? does this test cover this rule?) -- not to trace design rationale.
|
|
10
|
-
|
|
11
|
-
### Content Quality Standards
|
|
12
|
-
Every piece of content written into `project-context.md` must satisfy ALL of the following:
|
|
13
|
-
|
|
14
|
-
1. **Self-contained**: understandable without consulting any external document, artifact, or ADR.
|
|
15
|
-
2. **Actionable**: usable by an AI skill to make a yes/no decision or produce a concrete output (e.g., a test case).
|
|
16
|
-
3. **Atomic**: each item is independently meaningful -- not a fragment of a larger argument that only makes sense in its source document.
|
|
17
|
-
4. **Lean**: the token budget for this document is <= 4000 (healthy threshold). Content that does not directly serve a decision should be excluded.
|
|
18
|
-
5. **Stable**: only persist knowledge with long-term reference value. Transient state (change metadata, in-progress decisions, temporary workarounds) belongs in session.yaml or artifacts.
|
|
19
|
-
|
|
20
|
-
### Governing Principle (What Does NOT Belong)
|
|
21
|
-
**If a reader must consult an external document to understand an entry, that entry -- or its reference marker -- does not belong here.**
|
|
22
|
-
|
|
23
|
-
Strip any cross-reference marker (pointers to ADRs, design-document section numbers, internal rule labels, etc.). Remove only the *reference marker*, NEVER the *substantive content* it annotates.
|
|
24
|
-
|
|
25
|
-
- ✅ `idempotency key or exists-or-skip semantics (ADR-06, §12.4)` → `idempotency key or exists-or-skip semantics`
|
|
26
|
-
- ✅ `B-1: resume() degrades to rebuild on protocol error` → `resume() degrades to rebuild on protocol error`
|
|
27
|
-
- ❌ `Subscriber Idempotency Contract` -- this is the term itself, keep it.
|
|
28
|
-
|
|
29
|
-
> This profile applies ONLY when the target document is `project-context.md`. Other knowledge files (principle/, project/, core/user/, etc.) are not governed by it.
|
|
1
|
+
## Document Profile: project-context.md
|
|
2
|
+
|
|
3
|
+
Before writing to `project-context.md`, understand what this document IS and IS NOT.
|
|
4
|
+
|
|
5
|
+
### Identity
|
|
6
|
+
`project-context.md` is the project's **long-term semantic ground truth** -- a self-contained knowledge base consumed by AI skills to make decisions. It is NOT a copy of design documents, NOT a changelog, NOT an ADR index.
|
|
7
|
+
|
|
8
|
+
### Audience
|
|
9
|
+
The readers are AI skill instances (implementer, designer, tester, reviewer), NOT humans reading for reference. They use this document to make **binary decisions** (is this import legal? does this test cover this rule?) -- not to trace design rationale.
|
|
10
|
+
|
|
11
|
+
### Content Quality Standards
|
|
12
|
+
Every piece of content written into `project-context.md` must satisfy ALL of the following:
|
|
13
|
+
|
|
14
|
+
1. **Self-contained**: understandable without consulting any external document, artifact, or ADR.
|
|
15
|
+
2. **Actionable**: usable by an AI skill to make a yes/no decision or produce a concrete output (e.g., a test case).
|
|
16
|
+
3. **Atomic**: each item is independently meaningful -- not a fragment of a larger argument that only makes sense in its source document.
|
|
17
|
+
4. **Lean**: the token budget for this document is <= 4000 (healthy threshold). Content that does not directly serve a decision should be excluded.
|
|
18
|
+
5. **Stable**: only persist knowledge with long-term reference value. Transient state (change metadata, in-progress decisions, temporary workarounds) belongs in session.yaml or artifacts.
|
|
19
|
+
|
|
20
|
+
### Governing Principle (What Does NOT Belong)
|
|
21
|
+
**If a reader must consult an external document to understand an entry, that entry -- or its reference marker -- does not belong here.**
|
|
22
|
+
|
|
23
|
+
Strip any cross-reference marker (pointers to ADRs, design-document section numbers, internal rule labels, etc.). Remove only the *reference marker*, NEVER the *substantive content* it annotates.
|
|
24
|
+
|
|
25
|
+
- ✅ `idempotency key or exists-or-skip semantics (ADR-06, §12.4)` → `idempotency key or exists-or-skip semantics`
|
|
26
|
+
- ✅ `B-1: resume() degrades to rebuild on protocol error` → `resume() degrades to rebuild on protocol error`
|
|
27
|
+
- ❌ `Subscriber Idempotency Contract` -- this is the term itself, keep it.
|
|
28
|
+
|
|
29
|
+
> This profile applies ONLY when the target document is `project-context.md`. Other knowledge files (principle/, project/, core/user/, etc.) are not governed by it.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
## Script Usage Rule
|
|
2
|
+
|
|
3
|
+
{{#uses_plan_update}}To mutate `plan.yaml`, call `plan-update.cjs`. Do NOT hand-edit `plan.yaml` or choose `current_tasks`.
|
|
4
|
+
|
|
5
|
+
**Minimal command** (always required flags):
|
|
6
|
+
```bash
|
|
7
|
+
node .ai-agents/scripts/plan-update.cjs --plan "<active_change.plan_path>" --task <task_id> --status <new_status> --projects "<project_list>"
|
|
8
|
+
```
|
|
9
|
+
For flags, argument sources, or output not rendered here, read `.ai-agents/scripts/plan-update.md`. Do NOT read `.cjs`/`.js` source.
|
|
10
|
+
|
|
11
|
+
{{/uses_plan_update}}
|
|
12
|
+
{{#plan_update_inline_command_only}}To mutate `plan.yaml`, use the exact `plan-update.cjs` command rendered in this skill's workflow. Do NOT hand-edit `plan.yaml`, choose `current_tasks`, or read `.cjs`/`.js` source.
|
|
13
|
+
|
|
14
|
+
{{/plan_update_inline_command_only}}
|
|
15
|
+
{{#plan_update_project_reminder}}When calling `plan-update.cjs` for a project-attributed plan, pass `--projects` with the relevant project list. Do NOT hand-edit `plan.yaml` or read `.cjs`/`.js` source. For flags or value sources not rendered here, read `.ai-agents/scripts/plan-update.md`.
|
|
16
|
+
|
|
17
|
+
{{/plan_update_project_reminder}}
|
|
18
|
+
{{#uses_epic_update}}To mutate `epic.yaml` (complete a child, set child status, switch active, add children, or validate), call `epic-update.cjs`. Do NOT hand-edit `epic.yaml` or advance `current_change`.
|
|
19
|
+
|
|
20
|
+
**Minimal command** (most common mode — complete child):
|
|
21
|
+
```bash
|
|
22
|
+
node .ai-agents/scripts/epic-update.cjs --epic "<active_epic.epic_path>" --complete-child <active_change.id>
|
|
23
|
+
```
|
|
24
|
+
For modes not rendered here, read `.ai-agents/scripts/epic-update.md`. Do NOT read `.cjs`/`.js` source.
|
|
25
|
+
|
|
26
|
+
{{/uses_epic_update}}
|
|
27
|
+
{{#epic_update_inline_modes_only}}To mutate `epic.yaml`, use the exact `epic-update.cjs` mode commands rendered in this skill's workflow. Do NOT hand-edit `epic.yaml`, advance `current_change`, or read `.cjs`/`.js` source.
|
|
28
|
+
|
|
29
|
+
{{/epic_update_inline_modes_only}}
|
|
30
|
+
{{#epic_update_fallback_for_unrendered_modes}}To mutate `epic.yaml`, use the `epic-update.cjs` mode commands rendered in this skill's workflow. Do NOT hand-edit `epic.yaml`, advance `current_change`, or read `.cjs`/`.js` source. For modes or flags not rendered here, read `.ai-agents/scripts/epic-update.md`.
|
|
31
|
+
|
|
32
|
+
{{/epic_update_fallback_for_unrendered_modes}}
|