agent-orchestrator-kit 0.13.0 → 0.14.1
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 +26 -0
- package/README.md +24 -4
- package/bin/agent-orchestrator.js +469 -136
- package/bin/claude-cost-estimate.js +51 -0
- package/bin/spend-collect.js +76 -13
- package/package.json +2 -1
- package/profiles/generic/orchestrator.yaml +3 -0
- package/profiles/mvp/orchestrator.yaml +3 -0
- package/profiles/node/orchestrator.yaml +3 -0
- package/profiles/vue3/orchestrator.yaml +3 -0
- package/templates/.agents/commands/opsx-propose.md +6 -0
- package/templates/.agents/commands/opsx-review.md +35 -11
- package/templates/.agents/rules/session-handoff.mdc +2 -2
- package/templates/.agents/skills/agent-orchestration/SKILL.md +5 -4
- package/templates/.agents/skills/openspec-propose/SKILL.md +6 -0
- package/templates/.agents/subagents/openspec-guide.md +3 -2
- package/templates/.agents/subagents/session-handoff.md +2 -1
- package/templates/.agents/subagents/spec-architect.md +6 -1
- package/templates/.agents/subagents/spec-archiver.md +2 -1
- package/templates/.agents/subagents/spec-reviewer.md +5 -1
- package/templates/AGENTS.md +1 -1
- package/templates/orchestrator.yaml +3 -0
- package/templates/scripts/cursor-spend-collect.cjs +129 -67
- package/templates/scripts/sync-local-agent-skills.sh +27 -0
- package/templates/.cursor/memory.json +0 -11
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,32 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
### Fixed
|
|
8
|
+
- **Cache-split cost estimates survive the session recompute.** `applyCollectedSessionFields` recomputed `byModel[].costUsdEstimated` from `inputTokens` + `outputTokens` alone and overwrote the value the adapters had already produced. Since `inputTokens` includes `cache_read_*` / `cache_creation_*`, every cached token was billed at the full input rate: a real Claude change with 3.5M tokens estimated `$30.11` instead of `$5.16`, and Cursor rows lost their own rate table to the Claude `$3/$15` fallback. The recompute now only fills rows that have no adapter estimate, so ESTIMATE-ALL still covers Amp rows without `Cost:` while `claude-opus-5` with 100k input + 900k cache read + 10k output stays at `$1.20`.
|
|
9
|
+
|
|
10
|
+
## [0.14.1] - 2026-09-08
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **Memory graph survives `handoff` persist.** `loadMemoryItems` classified a memory file by its first character, so every JSONL graph (the format `@modelcontextprotocol/server-memory` reads and writes) was treated as an aggregate `{entities, relations}` document, failed to parse, and returned `[]` — the next persist then overwrote the whole file with just the current change's two entities. Everything the Memory MCP server had accumulated — all `Decision:*`, every other change, and all relations — was destroyed on each persist, leaving cross-session memory permanently one change deep. Detection is now by shape, `handoff --restore` reads JSONL graphs again instead of reporting "Memory JSON empty or missing", and a line that cannot be parsed is preserved verbatim rather than dropped.
|
|
14
|
+
- **`/opsx:*` commands reach the IDEs.** `.agents/commands/` was installed and documented but synced nowhere. `sync` now writes `.cursor/commands/opsx-<phase>.md` (flat, `/opsx-<phase>`) and `.claude/commands/opsx/<phase>.md` (namespaced, so the documented `/opsx:<phase>` exists in Claude Code), with the same stale-file deletion as skills and subagents. `sync-local-agent-skills.sh` matches.
|
|
15
|
+
- **`status` readiness mirrors the archive gates.** "ready to archive" was computed from `tasks.md` checkboxes alone, so it appeared on a change `archive` would refuse for a missing or non-APPROVE verdict. It now applies `require_spec_review` / `require_design_brief` and names the blockers.
|
|
16
|
+
- **`gate-check` no longer passes silently.** When the git diff cannot be computed (shallow clone, missing base ref, no commits) the review gate is verified instead of skipped.
|
|
17
|
+
- The next-thread prompt renders `- Change: <name>` instead of `- Change: - name: <name>`.
|
|
18
|
+
|
|
19
|
+
### Removed
|
|
20
|
+
- `templates/.cursor/memory.json` — an unused snapshot of the kit's own development memory. It was referenced by nothing (`init` writes an empty `.cursor/memory.json`), gitignored so it never showed up in a diff, yet the `files` allowlist still published it to npm. `files` now excludes `templates/.cursor` so it cannot ship again.
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- `pipeline.src_glob` in `orchestrator.yaml` — the paths `gate-check` treats as product code. The hardcoded `src/` default silently disabled the review gate in repos whose code lives elsewhere; `--src-glob` still overrides.
|
|
24
|
+
|
|
25
|
+
## [0.14.0] - 2026-09-07
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- **BREAKING: compact metrics schema v2.** Sessions persist `sourceIds`, `sourceTotals`, and `byModel` instead of `sources`; v1 remains readable and `metrics --migrate` performs a schema-only rewrite.
|
|
29
|
+
- Collection now has bounded persist/leftover windows, thread-scoped Amp usage totals and fresh Cost, Claude message dedup/subagent capture, and static Claude/Amp cost estimates.
|
|
30
|
+
- Added `metrics --summary-json` as the aggregate dashboard contract; phase bounds come from `phases.*`, never git history.
|
|
31
|
+
- Kit templates require an exhaustive Tier 2 punch list (full scan before the verdict; schema Checklist / Findings / Required Before Apply / Previous findings). After REQUEST CHANGES the next command is `/opsx:propose`; `openspec-guide` no longer maps RC back to review. Metric: Spec review discovery loops ≤ 2.
|
|
32
|
+
|
|
7
33
|
## [0.13.0] - 2026-09-04
|
|
8
34
|
|
|
9
35
|
### Fixed
|
package/README.md
CHANGED
|
@@ -74,7 +74,7 @@ npx agent-orchestrator-kit@latest init --profile generic --ci gitlab --spec-veri
|
|
|
74
74
|
|
|
75
75
|
See [Installation](#installation) for profile/CI options.
|
|
76
76
|
|
|
77
|
-
**🔄 Already have the kit installed? Upgrade to latest (
|
|
77
|
+
**🔄 Already have the kit installed? Upgrade to latest (v0.14.1 fixes a `handoff` persist that wiped the Memory graph, syncs the `/opsx:*` commands into Cursor and Claude Code, and stops `status` / `gate-check` from reporting a gate as met when it is not):**
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
80
|
npx agent-orchestrator-kit@latest update
|
|
@@ -189,7 +189,7 @@ your-project/
|
|
|
189
189
|
|----------|----------|
|
|
190
190
|
| Orchestration | 5-role pipeline, `AGENTS.md`, `orchestrator.yaml`, review command |
|
|
191
191
|
| OpenSpec skills | All 7 skills for `/opsx:*` workflow |
|
|
192
|
-
| IDE sync | Cursor + Claude Code sync script (`--delete` semantics — removes stale skills/subagents) |
|
|
192
|
+
| IDE sync | Cursor + Claude Code sync script (`--delete` semantics — removes stale skills/subagents/commands) |
|
|
193
193
|
| Subagents | 12 exclusive routes: guide/setup/session-handoff, explore/design/propose/review/archive stage agents, and apply implementation/test/code-review agents — native in Cursor + Claude Code, isolated Amp `subagent-*` wrappers |
|
|
194
194
|
| CLI gates | `npx agent-orchestrator-kit status` / `gate-check` / `archive` / `handoff` / `metrics` / `memory-setup` — deterministic review-gate, archive, session-handoff, and change metrics (always via `npx`; see `cli-via-npm.mdc`) |
|
|
195
195
|
| CI | `agent-verify.yml` — GitHub (default) or GitLab fragment + `prebuild` hook, both run `gate-check` |
|
|
@@ -801,13 +801,15 @@ Persist with `runtime: cloud` prints those four steps on stderr; stdout stays th
|
|
|
801
801
|
|
|
802
802
|
Every change accumulates git-tracked `openspec/changes/<name>/metrics.json` — the data source for planning the next feature: how long each phase took, how many sessions it needed, what it cost.
|
|
803
803
|
|
|
804
|
+
Schema v2 stores compact `sourceIds`, `sourceTotals`, and `byModel` per session instead of `sessions[].sources`. This is **BREAKING** for readers of the old event arrays. v1 files are normalized in memory without rewriting; run `npx agent-orchestrator-kit metrics <name> --migrate` for a schema-only rewrite that preserves existing numeric fields and aggregates.
|
|
805
|
+
|
|
804
806
|
- **`## Metrics` self-report** — Session Exit fills `handoff.md` with `platform`, `model`, `input_tokens`, `output_tokens`, `cost_usd`, `amp_credits`, `spend_source` (`unknown` when missing). Persist reads that section; `metrics.json` is the source of truth for what landed. CLI flags do not rewrite the section.
|
|
805
807
|
- **`session.model`** — source product id wins when any collected source has a model; `--model` / `## Metrics: model` / `AOK_MODEL` apply only when sources have no model. Never a Closed role.
|
|
806
808
|
- **Session start** — `handoff --restore` writes a `pending` marker (`startedAt`, expected role).
|
|
807
|
-
- **Session end** — `handoff <name>` closes the pending session
|
|
809
|
+
- **Session end** — `handoff <name>` closes the pending session. Its collect lower bound is `--started-at` or `pending.startedAt` minus 120 seconds; without either it is the previous `endedAt`, or `createdAt` for the first session, with no open-ended scan. Amp usage totals and fresh Cost are authoritative; Claude JSONL is deduplicated by `message.id`, includes subagents, and accepts cwd descendants. Claude uses a versioned Anthropic list-price estimate with cache split; Amp without Cost uses the same model table or the $3/$15 fallback. Estimates never enter billed `costUsd`.
|
|
808
810
|
- **Archive** — successful `archive <name>` always creates or finalizes `metrics.json`, sets `archivedAt`, appends an Archiver session, collects the locked client (Cursor hook / Amp export+usage / Claude JSONL) in `[pending.startedAt, now]` plus leftover of the previous session, and prints the same human summary as `metrics <name>`. `--collect` still runs all three adapters. Leftover apply `## Metrics` that repeats the previous session is ignored so those tokens are not counted twice.
|
|
809
811
|
- **`sessionEnd` leftover** — `scripts/cursor-spend-collect.cjs` also reads the newest `openspec/changes/archive/*-<name>/metrics.json` when the active change folder is gone, so a late hook after archive still attaches. `stop` / `afterAgentResponse` run the same leftover after a successful jsonl append. When `last.threadId` is non-empty, leftover keeps only rows whose `conversationId` matches that id (empty/`null` threadId stays time-only). In a multi-root window leftover walks every candidate that has `openspec/changes`, reading that root’s jsonl. Aggregates write `costUsdEstimated` with 4 decimal places. Each `phases.<phase>` stores `startedAt` / `endedAt` / `leadTimeMs` from that phase’s sessions; `durationMs` stays the work-time sum and does not clone `totals.leadTimeMs`.
|
|
810
|
-
- **Leftover without `--collect`** — Scopes to `last.platform` and
|
|
812
|
+
- **Leftover without `--collect`** — Scopes to `last.platform` and Amp thread identity from `threadId` or `sourceIds`. Sessions without a thread id are capped at `endedAt + 120s`; identified sessions may continue to the next pending boundary. Fresh Amp usage totals, Models, and Cost replace cached values.
|
|
811
813
|
- **Cursor `conversationId`** — restore writes `CURSOR_CONVERSATION_ID` into `pending.threadId`; Cursor collect and sessionEnd leftover skip rows whose `conversationId` does not match when a filter id is present (`last.threadId` on leftover).
|
|
812
814
|
- **Canonical role** — `session.role` and `pending.role` store the first known token (`Explorer`, `Architect`, `Spec Reviewer`, `Implementer`, `Archiver`, `Design Intake`); Closed role in `handoff.md` MAY keep a sentence after `—`.
|
|
813
815
|
- **Platform** — `--platform` → `## Metrics: platform` → `AOK_PLATFORM` → **pending client from `--restore`** → host env (Amp / Cursor / Claude Code) → collected sources (`cursor|claude|amp` only). Invalid `--platform` fails before persist/move.
|
|
@@ -834,9 +836,15 @@ npx agent-orchestrator-kit handoff add-thing
|
|
|
834
836
|
npx agent-orchestrator-kit handoff add-thing --collect # optional: Claude JSONL / Amp threads / Cursor hook
|
|
835
837
|
npx agent-orchestrator-kit metrics add-thing # human summary: phases, tokens, cost, roles / models
|
|
836
838
|
npx agent-orchestrator-kit metrics add-thing --json # raw metrics.json (works for archived changes too)
|
|
839
|
+
npx agent-orchestrator-kit metrics add-thing --summary-json # compact dashboard contract
|
|
840
|
+
npx agent-orchestrator-kit metrics add-thing --migrate # rewrite v1 → v2 without numeric recompute
|
|
837
841
|
npx agent-orchestrator-kit archive add-thing --sync # finalize + the same tables as metrics
|
|
838
842
|
```
|
|
839
843
|
|
|
844
|
+
#### Для дашбордів
|
|
845
|
+
|
|
846
|
+
Use only `phases.<phase>.startedAt`, `endedAt`, and `durationMs` for phase boundaries and duration. Use `totals.leadTimeMs` only for the whole change. Git log MUST NOT be used for phase boundaries; the kit does not provide per-phase commit counts. `metrics <name> --summary-json` returns only aggregate `totals`, `phases`, and spend maps, without sessions or commits.
|
|
847
|
+
|
|
840
848
|
Recording is on by default and never a persist/archive/`gate-check` gate; opt out per persist with `--no-metrics`. Persist and archive collect the locked client without `--collect`; `--collect` runs every adapter. Flags (`--model`, `--platform`, `--input-tokens`, …) override session totals in `metrics.json` and do not rewrite the `## Metrics` section.
|
|
841
849
|
|
|
842
850
|
### Skill inventory
|
|
@@ -978,11 +986,13 @@ npx agent-orchestrator-kit metrics [change-name] [--json] [--collect]
|
|
|
978
986
|
skills/ # Synced from .agents/skills/
|
|
979
987
|
rules/ # Synced from .agents/rules/
|
|
980
988
|
agents/ # Synced from .agents/subagents/
|
|
989
|
+
commands/ # Synced from .agents/commands/ (flat — /opsx-apply)
|
|
981
990
|
memory.json # Memory MCP data
|
|
982
991
|
|
|
983
992
|
.claude/ # Local only — Claude Code runtime
|
|
984
993
|
skills/ # Synced from .agents/skills/
|
|
985
994
|
agents/ # Synced from .agents/subagents/
|
|
995
|
+
commands/opsx/ # Synced from .agents/commands/ (namespaced — /opsx:apply)
|
|
986
996
|
CLAUDE.md # Synced from root CLAUDE.md
|
|
987
997
|
|
|
988
998
|
.amp/ # Local only — Amp config
|
|
@@ -1007,6 +1017,16 @@ Phase bounds and non-goals: [`openspec/specs/agentic-factory-roadmap/spec.md`](o
|
|
|
1007
1017
|
|
|
1008
1018
|
## Changelog
|
|
1009
1019
|
|
|
1020
|
+
### 0.14.1
|
|
1021
|
+
- **Memory graph survives `handoff` persist** — JSONL graphs were misread as an aggregate document and returned empty, so each persist overwrote the file with only the current change; all `Decision:*`, other changes, and relations were lost
|
|
1022
|
+
- `/opsx:*` commands now sync to `.cursor/commands/` (flat) and `.claude/commands/opsx/` (namespaced), so the documented slash commands exist in both IDEs
|
|
1023
|
+
- `status` applies `require_spec_review` / `require_design_brief` before saying "ready to archive"; `gate-check` verifies the gate instead of exiting 0 when the diff is unknown, and reads `pipeline.src_glob` for code outside `src/`
|
|
1024
|
+
|
|
1025
|
+
### 0.14.0
|
|
1026
|
+
- **BREAKING: compact metrics schema v2** — sessions persist `sourceIds` / `sourceTotals` / `byModel` instead of `sources`; `metrics --migrate` is schema-only; `metrics --summary-json` for dashboards
|
|
1027
|
+
- Bounded persist/leftover windows, thread-scoped Amp usage + fresh Cost, Claude dedup/subagent capture, static Claude/Amp estimates
|
|
1028
|
+
- Exhaustive Tier 2 punch list in kit templates; after REQUEST CHANGES next command is `/opsx:propose`; Spec review discovery loops ≤ 2
|
|
1029
|
+
|
|
1010
1030
|
### 0.13.0
|
|
1011
1031
|
- Amp Cost-once rollup: `Cost: $N` once per qualifying session into `spend` / `spendByPlatform.amp` / `phases` (not ×N sources; several sessions accumulate)
|
|
1012
1032
|
- Restore without Amp parent locks a fresh `session.json` `lastThreadId` as `amp-session-last`
|