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 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 (Amp Cost-once rollup + `amp-session-last` + leftover thread-scope in v0.13.0; Cursor leftover race + multi-root + per-phase clock in v0.12.0; session attribution + Cursor estimate/dedup in v0.11.0; Cursor fallback estimate + first-class `costUsdEstimated` in v0.10.0; UTC timestamps + Amp stamp parse, Amp billed `$`, Cursor API estimate, archive auto-collect in v0.9.0; locked Amp/Cursor client in v0.8.0; `## Metrics` self-report + opt-in `--collect` in v0.7.0 **BREAKING:** `--no-collect` is gone; change metrics in v0.5.0+, factory phases 1–3 in v0.4.0+, lean pipeline / archive CLI in v0.3.0+, handoff CLI in v0.1.14+, Figma PAT in v0.1.11+):**
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: duration, closed role, mapped phase (`explore` / `design` / `spec` / `review` / `apply` / `archive`), runtime (local/cloud), tasks snapshot (`n/m`), and spend from flags → self-report → adapters. Persist collect window is `[pending.startedAt, endedAt]`; a late hook after persist goes to leftover of that session, not the next persist. `--input-tokens` / `--output-tokens` / `--total-tokens` / `--cost-usd` override session totals only and do not wipe `spendByPlatform` / `spendByModel`. Amp billed USD comes from `amp threads usage --details` (`Cost: $N` only; missing line → `costUsd: null`), not from converting credits. After persist/recompute, that Cost is a **Cost-once rollup**: once **per qualifying session** into `spend.costUsd` / `spendByPlatform.amp.costUsd` / `phases.*.costUsd` when that session’s `sources[].costUsd` are all null never copied onto each source (not ×N); several Amp sessions accumulate. Cursor always writes a labeled `costUsdEstimated` when tokens exist: grok-4.6/4.5 use xAI API rates (`costSource: api-estimate`, including `-fast` and the 200k cliff); other models use a versioned fallback of $3/1M input + $15/1M output (or $3.50/1M when only `totalTokens` is present, `costSource: api-estimate-fallback`). That estimate is **not** the Cursor invoice and is never added into billed `costUsd`. Timestamps are ISO-8601 UTC (`…Z`). No restore marker? Pass `--started-at <iso>` or the duration stays honestly `null`.
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, for Amp, leftover **thread-scope**: the session thread id or the `T-…` prefix from `sources[].id` (`T-apply:8` `T-apply`). An explicit `ampThreadId` does not also add the env thread. After `amp-usage`, leftover **token resync** sums tokens from all sources and keeps billed Cost (`spendSource: amp-usage`). `usageModels` stay unique to that thread.
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`