@vibecompass/vibecompass 0.10.7 → 0.11.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/CHANGELOG.md +37 -1
- package/README.md +42 -1
- package/package.json +1 -1
- package/src/cli.js +602 -8
- package/src/compatibility.js +34 -1
- package/src/decision-index.js +386 -0
- package/src/decisions.js +195 -0
- package/src/docs-review.js +27 -27
- package/src/docs-update.js +459 -24
- package/src/generators/agent-files/index.js +8 -0
- package/src/generators/agent-files/template.js +6 -3
- package/src/git-binding.js +676 -0
- package/src/init.js +9 -0
- package/src/lane-marker.js +339 -0
- package/src/lane-runtime.js +254 -0
- package/src/manifest.js +19 -0
- package/src/project-memory.js +27 -1
- package/src/refresh-workflow.js +8 -0
- package/src/scaffold.js +24 -12
- package/src/serialization.js +205 -0
- package/src/session.js +955 -80
- package/src/simple-yaml.js +24 -4
- package/src/status.js +43 -5
- package/src/sync.js +5 -0
- package/src/workflow.js +39 -1
- package/src/workflows/registry.js +7 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,42 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 0.11.0 - 2026-07-03
|
|
4
|
+
|
|
5
|
+
Phase 8 concurrent multi-session lanes (stages S1–S4). Highlights: a per-root
|
|
6
|
+
serialization lock, per-session lane identity with no implicit current-lane
|
|
7
|
+
fallback, opt-in per-lane git branch/worktree binding, per-lane runtime
|
|
8
|
+
(port + temp-dir) isolation, and a structure-preserving grouped decision-index
|
|
9
|
+
generator. This release carries breaking changes to lane/root resolution and
|
|
10
|
+
lane-metadata shapes — see the `Breaking:` entries below.
|
|
11
|
+
|
|
12
|
+
- Add per-lane runtime assignment (D-282, D-284): every `start-session` computes, inside the memory-root lock, a lane port — the lowest `port_base + k * port_step` not recorded by any other active lane — and a lane temp directory `<tmp_base>/<root-key>/<lane-id>` (root-key: first 12 hex chars of the SHA-256 of the memory root's canonical realpath; defaults `port_base` 3100, `port_step` 1, `tmp_base` `os.tmpdir()/vibecompass-lanes`, overridable via a new validated top-level `runtime:` key in `project.yaml` whose invalid values warn and fall back). The assignment is recorded as a `runtime:` block map in the lane's `session.yaml` (local-only per D-278), projected presence-gated into `state/manifest.json.active_sessions` (pre-S4 lanes keep their shapes), printed by `start-session`, and consumed via the new `lane-env` command — D-277/D-280 lane resolution, POSIX `export` lines for `VIBECOMPASS_LANE_ID`/`VIBECOMPASS_LANE_PORT`/`VIBECOMPASS_LANE_TMPDIR` plus conventional `PORT`/`TMPDIR` aliases (`--no-conventional` omits them, `--json` for tooling), so `eval "$(vibecompass lane-env)"` makes unmodified dev servers pick up the lane's assignment. Assignment is lane coordination, not an OS-level reservation: no port is probed or bound, and process supervision stays out of scope. Because `lane-env` exports `TMPDIR=<laneTmpDir>` and `os.tmpdir()` reads it, the default temp base strips any `vibecompass-lanes` segment out of the resolved OS temp root before appending the namespace (D-284), so a lane started from inside a `lane-env` shell is a sibling of the exporting lane, never nested inside it — nesting would let closing the outer lane recursively remove the inner lane's active temp dir; a start-time warning surfaces the un-nesting. The temp dir is created before the first root write (a failure aborts with the root untouched), joins the git-binding rollback, and is removed at close only under D-279/D-281-style guards keyed to the recorded env-independent `<root-key>/<lane-id>` tail (`basename(dirname)` = root-key, final segment = lane id) plus absolute-path and cwd-outside checks — never a live-`os.tmpdir()` recompute, which the exported `TMPDIR` would poison (D-284); guard refusals keep the dir with a `Lane temp dir:` line plus guidance, a missing dir is benign crash residue, and lanes without a `runtime:` record close exactly as before.
|
|
13
|
+
- Add `refresh-decision-index` (D-283), a grouped structure-preserving generator for `decisions/INDEX.md`: the existing file is the source of structure — H1, preamble, rule blockquote, then `## <date> — <session>` groups each holding one `| # | Decision | Domain |` table — and anything the parser cannot round-trip byte-identically fails closed with named findings (the hand-maintained file is never "repaired"). Rows are collected from strict `### D-NNN — <title>` canonical headings (hyphen-only headings are reported, never silently dropped) and refresh appends only missing decisions, into the group matching the target label — default `<session_date> — Session <N> (<lane-id> lane)` from the D-277/D-280 lane resolution, or an explicit `--group` — creating the group at the tail when absent; a no-op refresh is byte-idempotent. `--check` validates canonical↔index correspondence (every canonical decision exactly once with matching title and domain link, no orphan or duplicate rows) without writing. `append-decision` now refreshes the index through this generator inside the same lock when a group label is determinable and otherwise keeps the hand-refresh reminder — the canonical append never fails because of an index refusal (a structural refusal or an fs-error throw both degrade to a named warning, so a retry can never duplicate the decision). `append-decision` and `refresh-decision-index` adopt the D-280 marker-supplied memory root when `--root` is omitted and resolve the group label tolerantly, but only the 2+-active-lane no-selection ambiguity degrades to "no label": an explicit `--session` naming a non-active lane, or a stale worktree marker, still fails the command closed (D-277/D-280) rather than silently appending. The docs-review flat `--refresh-index` generator (D-209) now refuses to overwrite an index that contains grouped `## ` headings and points at `refresh-decision-index` instead.
|
|
14
|
+
|
|
15
|
+
- Add opt-in per-lane git binding (D-279/D-281): `start-session --branch <name>` creates or reuses the branch in every bound `--repo` (branch state detected with two probes — `rev-parse --verify --quiet refs/heads/<name>` for existence and tip, `worktree list --porcelain` for checked-out state; branch names are normalized via `git check-ref-format --branch` and `@{` shorthand is rejected), and the boolean `--worktree` flag provisions per-repo worktrees under the fixed `<workspace>/worktrees/<lane-id>/<repo-id>` container with the lane marker written into the container. Preflight fails closed on undeclared or non-key-safe repo ids, non-repo or nested source dirs, unborn HEADs, branches checked out elsewhere (worktree mode), the D-266 memory-fork layouts in both containment directions, a workspace that itself sits inside a git work tree, an existing container, and a branch another active lane already binds on a shared repo; dirty sources, branch reuse, and cross-lane branch divergence warn. Ref creation is always its own command whose success establishes rollback ownership, so a branch that appears externally between preflight and provisioning — even at the same start commit — fails the create with no ownership record and is never deleted; a failed provision rolls back everything this call actually created (worktree remove with rm+prune fallback, `branch -D` only for owned refs, container/marker/lane files, CLAUDE.md and index restoration) so `start-session` stays atomic.
|
|
16
|
+
- Add close-side guarded worktree removal (D-281, replacing the interim close-session refusal): `close-session` removes a bound lane's recorded clean worktrees by default, licensed by the D-279/D-280 guards — the recorded path must sit inside the lane's recorded container, and the container marker must parse and match the lane's recorded token and lane id — so arbitrary path removal is refused. Removal is never forced: dirty worktrees, unverifiable containers, paths outside the container, and worktrees whose `git status` fails (a status failure counts as unknown, not clean) all survive with per-worktree guidance, and removal is skipped with guidance when the process cwd sits inside the target. Branches are never deleted at close. The container marker is removed token-matched only when no recorded worktree survives (otherwise it is kept as a fail-closed breadcrumb), the empty container is then removed non-recursively (a stray user file keeps it in place with a note, and a container the process cwd sits inside is never rmdirred), and recorded-but-missing worktrees remain benign crash residue. `close-session` also fails closed when the closing lane's `session.yaml` cannot be parsed — a null-degraded parse would hide recorded worktrees and destroy the removal-guard records while the worktrees survive. Relative recorded worktree paths are refused outright (guards and `git -C <source>` would resolve them differently). Note that gitignored files (e.g. `.env`) do not count as dirty — matching git's own unforced `worktree remove` semantics — and are deleted with a clean worktree; copy ignored local files out before closing. The close result and CLI print a `Worktree cleanup:` summary; marker-only lanes close exactly as before.
|
|
17
|
+
- Add the pre-close staleness set (A:192, D-281): `docs-update` now computes, for the selected lane, canonical decisions appended after the lane's frozen start-of-lane snapshot (named with their domain file), base revisions stale relative to the current source repo heads (bound repos compare against the recorded source checkout, not the lane worktree), finalized session notes materialized after lane start that mention the lane's declared scope (claimed paths matched against the note's backticked path references with repo scoping, feature slugs, or backticked `repo:path` references), and repo-scope-aware claimed-path overlap with other active lanes (an explicit `repo:` prefix pins a claim to that repo, an unprefixed claim can live in any repo its lane declares — `app:src/x` and `lib:src/x` never cross-flag). The set renders as a `Pre-close staleness set:` section in the docs-update plan (pieces that cannot be evaluated are named, not skipped), and `close-session` re-emits every entry as a `Pre-close staleness:` warning so mid-session and close-out see the same target set.
|
|
18
|
+
- Record git binding in lane metadata: `session.yaml` gains `branch`, `worktree_container`, `worktrees:`, `worktree_sources:`, and `base_revisions:` (captured at start for every claimed repo — bound repos record the created start point or reused branch tip, non-git dirs skip silently, unborn HEADs warn, non-key-safe repo ids fail closed instead of relaxing the parser); `state/manifest.json.active_sessions` lanes expose `branch` + `worktree_container` (omitted for unbound lanes); `write-lane-marker` refuses to rebind a lane that records a worktree container (D-281: a rebind would orphan the close-time removal guard).
|
|
19
|
+
- Breaking: root resolution for read-only surfaces and repo scans now matches lane-scoped commands (D-280): the compatibility preflight and `status` adopt the nearest valid marker's memory root when `--root` is omitted (previously always `cwd/.compass`, which emitted spurious warnings from marker-bound cwds), and `docs-update` resolves declared repo directories against the workspace (`dirname(rootDir)`) instead of the invoking cwd — from a worktree or nested cwd it previously scanned nonexistent paths and silently dropped every repo delta. `docs-update` also scans a git-bound lane's recorded worktrees (prefixed `repo-id:`) instead of the source checkouts for bound repos, and skips the unprefixed cwd scan when cwd is inside a recorded worktree.
|
|
20
|
+
- Quoted scalars in the simple-yaml subset now unescape symmetrically with the writers' `JSON.stringify` quoting (backslashes and embedded quotes round-trip; hand-authored non-JSON quoting keeps the historical naive slice).
|
|
21
|
+
|
|
22
|
+
- Add worktree lane markers (D-280): `.vibecompass-lane.yaml` written only by the new `write-lane-marker` command (S3 worktree provisioning becomes the second producer), recorded in the lane's `session.yaml` as a `lane_marker:` block map, token-matched for removal at `close-session`, and required to be path-disjoint from the memory root (ancestor, equal, and inside-root targets are refused).
|
|
23
|
+
- Breaking: resolve lane identity per D-277 in `close-session` and `docs-update`: an explicit `--session` wins (warning names both lanes when it overrides a marker; a non-active explicit lane now fails closed), then the nearest worktree lane marker walking up from cwd (stale markers fail closed, even when a single-lane fallback would have succeeded; mismatched-root markers are ignored with a warning), then the single active lane. `docs-update` / the exported `planDocsUpdate` previously succeeded at 2+ active lanes by silently using the root-global index pointer and now error without an explicit `--session` or marker.
|
|
24
|
+
- Breaking: `listProjectSessions().current` (and the `list-sessions` / `status` / `state/manifest.json.active_sessions` surfaces derived from it) can now be `null` when 2+ lanes are active and no valid pointer selects one, instead of fabricating the alphabetically-first lane.
|
|
25
|
+
- Infer the memory root from the marker when `--root` is omitted (explicit `--root` always wins; `cwd/.compass` remains the no-marker default), so lane-scoped commands run from a worktree cwd with neither `--root` nor `--session`; the tooling root follows the memory root's parent directory in that case.
|
|
26
|
+
- Remove the implicit current-lane defaults: `list-sessions`/status/state-manifest no longer fabricate a current lane from an unvalidated index pointer, and closing a lane never auto-promotes an alphabetical survivor — with 2+ survivors the pointer goes null until an explicit selection (a sole survivor is still promoted). This also fixes a partial-close crash when a stale pointer named a missing lane.
|
|
27
|
+
- Render the Current-session block as a derived multi-lane listing (one line per active lane plus the selected lane) whenever 2+ lanes are active, keeping the legacy five-field shape parse-compatible; generated agent/workflow guidance now teaches the D-277 resolution order and explicit reviewer lane selection (`review handoff <lane-id>`).
|
|
28
|
+
|
|
29
|
+
- Add a per-root serialization lock (mkdir-mutex under `state/` with owner tokens, release-only-own semantics, atomic rename-based reclaim of dead-process locks, and no stealing from live holders) so all package writers of shared project memory — session lifecycle, `refresh-workflow --apply`, docs-review apply paths, `apply-export`, `connect-hosted`, `sync-target`, state-manifest refresh, and managed agent-file sync — run one at a time per project-memory root (D-276).
|
|
30
|
+
- Add `append-decision`: an atomic append path that allocates the next D-number at write time from a staged `### D-NEXT — <title>` entry, plus `next-decision-id` as an advisory preview.
|
|
31
|
+
- Block `close-session` when duplicate decision IDs exist in canonical decision files; duplicates are surfaced for human repair, never auto-renumbered.
|
|
32
|
+
- Add `rebuild-active-index` to regenerate `sessions/active/index.yaml` from active lane directories with an explicit current-lane selection when multiple lanes are active (D-277).
|
|
33
|
+
|
|
34
|
+
## 0.10.8 - 2026-07-02
|
|
35
|
+
|
|
36
|
+
- Clarify generated docs-review workflow guidance so first passes establish breadth-first baseline coverage before optional scoped deepening.
|
|
37
|
+
- Add build-session guidance that tells builders to inspect relevant docs, decisions, coverage state, and source before feature work, then record, deepen, or explicitly defer documentation gaps before close-out.
|
|
38
|
+
- Print mode-aware hosted projection guidance during `close-session` / `end-session`: connected `local-primary` roots get an explicit `vibecompass push` reminder, `hosted-only` roots are directed through hosted/dashboard refresh, and `local-only` roots have no hosted push expectation.
|
|
39
|
+
- Expand close-session hosted guidance tests across local-primary with binding, local-primary without binding, hosted-only, and local-only modes.
|
|
4
40
|
|
|
5
41
|
## 0.10.7 - 2026-06-25
|
|
6
42
|
|
package/README.md
CHANGED
|
@@ -133,9 +133,41 @@ npx -y @vibecompass/vibecompass@latest switch-session auth-flow --root .compass
|
|
|
133
133
|
npx -y @vibecompass/vibecompass@latest docs-update --root .compass --session auth-flow
|
|
134
134
|
npx -y @vibecompass/vibecompass@latest close-session --root .compass --session auth-flow --title "Auth Flow" --completed "Built auth" --architecture-docs updated --decision-log not-needed --session-maintenance updated --next-step "Review"
|
|
135
135
|
|
|
136
|
+
# Optional git binding for a lane (D-281): create/reuse a branch in each bound
|
|
137
|
+
# repo; --worktree provisions per-repo worktrees under
|
|
138
|
+
# <workspace>/worktrees/<lane-id>/<repo-id> with the lane marker in the
|
|
139
|
+
# container, so commands run from inside a worktree need no --root/--session.
|
|
140
|
+
# At close, close-session removes the recorded worktrees when they are clean
|
|
141
|
+
# (guarded, never forced; branches are never deleted); dirty or in-use
|
|
142
|
+
# worktrees survive with guidance and the lane marker stays as a breadcrumb.
|
|
143
|
+
# Gitignored files (e.g. .env) do not count as dirty and are deleted with a
|
|
144
|
+
# clean worktree — copy ignored local files out before closing.
|
|
145
|
+
# close-session and docs-update also print a pre-close staleness set: new
|
|
146
|
+
# decisions since lane start, stale base revisions, newer finalized notes
|
|
147
|
+
# that mention the lane's scope, and claim overlap with other active lanes.
|
|
148
|
+
npx -y @vibecompass/vibecompass@latest start-session --id auth-flow --working-on "Auth flow" --repo app --branch feature/auth --worktree
|
|
149
|
+
|
|
150
|
+
# Per-lane runtime isolation (D-282): every lane gets its own port and temp
|
|
151
|
+
# dir at start (recorded in the lane's session.yaml; defaults configurable
|
|
152
|
+
# under project.yaml runtime: port_base/port_step/tmp_base). Export them into
|
|
153
|
+
# a shell — includes conventional PORT/TMPDIR aliases so unmodified dev
|
|
154
|
+
# servers pick them up — before running dev servers or build tools, so
|
|
155
|
+
# parallel lanes never fight over ports or temp paths. close-session removes
|
|
156
|
+
# the lane temp dir (guarded; the port record vanishes with the lane).
|
|
157
|
+
eval "$(npx -y @vibecompass/vibecompass@latest lane-env)"
|
|
158
|
+
|
|
136
159
|
# Agent instruction files
|
|
137
160
|
npx -y @vibecompass/vibecompass@latest sync-agents --root .compass
|
|
138
161
|
|
|
162
|
+
# Decision log maintenance: append-decision allocates the D-number at write
|
|
163
|
+
# time and refreshes the grouped decisions/INDEX.md when it can label the
|
|
164
|
+
# group from the lane context (D-283, structure-preserving — hand-authored
|
|
165
|
+
# session group headings are preserved verbatim; unparseable structure fails
|
|
166
|
+
# closed). refresh-decision-index --check validates the index against the
|
|
167
|
+
# canonical decision files without writing.
|
|
168
|
+
npx -y @vibecompass/vibecompass@latest append-decision --root .compass --target cross-cutting.md --entry staged-entry.md
|
|
169
|
+
npx -y @vibecompass/vibecompass@latest refresh-decision-index --root .compass --check
|
|
170
|
+
|
|
139
171
|
# Targeted and comprehensive architecture docs maintenance
|
|
140
172
|
npx -y @vibecompass/vibecompass@latest docs-update --root .compass --session auth-flow --changed app:src/auth/login.ts
|
|
141
173
|
npx -y @vibecompass/vibecompass@latest docs-review --root .compass --guided
|
|
@@ -180,11 +212,15 @@ After setup, use these phrases inside your AI coding tool:
|
|
|
180
212
|
- `planning mode`
|
|
181
213
|
- `review handoff`
|
|
182
214
|
- `address review`
|
|
215
|
+
- `docs update`
|
|
183
216
|
- `close session` / `end session`
|
|
184
217
|
- `docs review`
|
|
185
218
|
|
|
186
219
|
The npm package owns the file mechanics. Your AI session owns reading the
|
|
187
|
-
workflow files, updating handoffs, and applying reviewed changes.
|
|
220
|
+
workflow files, updating handoffs, and applying reviewed changes. Use
|
|
221
|
+
`docs review` for the broad baseline and scoped deepening work; use
|
|
222
|
+
`docs update` / `vibecompass docs-update` for ordinary session-delta
|
|
223
|
+
maintenance tied to the current lane.
|
|
188
224
|
|
|
189
225
|
## Hosted Sync
|
|
190
226
|
|
|
@@ -201,6 +237,11 @@ npx -y @vibecompass/vibecompass@latest connect-hosted \
|
|
|
201
237
|
npx -y @vibecompass/vibecompass@latest push --root .compass
|
|
202
238
|
```
|
|
203
239
|
|
|
240
|
+
After `close-session`, run `push` again when a connected local-primary root
|
|
241
|
+
changed canonical project-memory files and the hosted dashboard should catch
|
|
242
|
+
up. Hosted-only projects do not use a local authoritative push; update or
|
|
243
|
+
refresh them through the hosted dashboard/proposal flow.
|
|
244
|
+
|
|
204
245
|
### Multiple environments
|
|
205
246
|
|
|
206
247
|
One project can have named sync targets (for example a local dev server and
|