@sabaiway/agent-workflow-kit 1.25.0 → 1.27.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/bin/install.mjs CHANGED
@@ -23,8 +23,10 @@
23
23
  // member — the memory substrate (`npx @sabaiway/agent-workflow-memory@latest init`, best-effort: a
24
24
  // failure is a loud DEGRADED success, never silent — skippable with `--no-memory`) and the
25
25
  // methodology engine the kit reads live (`npx @sabaiway/agent-workflow-engine@latest init`, fatal —
26
- // the live read STOPs without it — skippable with `--no-engine`). The bridges are NOT installed by
27
- // `init` (placed by `/agent-workflow-kit setup`). No tracking either way.
26
+ // the live read STOPs without it — skippable with `--no-engine`). The bridges are never PLACED by
27
+ // `init` (first placement stays `/agent-workflow-kit setup`, opt-in); once placed, `init` REFRESHES
28
+ // them from this package's own bundled copies — a purely LOCAL copy, no third server contact —
29
+ // skippable with `--no-bridges`. No tracking either way.
28
30
  //
29
31
  // Dependency-free, Node >= 18.
30
32
 
@@ -35,11 +37,22 @@ import { fileURLToPath } from 'node:url';
35
37
  import { homedir } from 'node:os';
36
38
  import { spawnSync } from 'node:child_process';
37
39
  import { copyTreeRefresh } from '../tools/fs-safe.mjs';
40
+ // Dependency-free semver, shared with the family registry's bridge freshness probe (one leaf, no
41
+ // second drifting copy). The null-on-unparseable contract is load-bearing here: legacy installs
42
+ // predate any version stamp, so an unparseable side means "no gate", never a false ordering.
43
+ import { compareSemver } from '../tools/semver-lite.mjs';
38
44
  // The ONE registry of family members (npm packages, kinds). The init-refresh cascade derives its
39
45
  // membership from this table — no second source of "who gets refreshed" — so it can't drift from the
40
46
  // manifests (a drift-guard test pins the derivation). Imported from the DATA LEAF (family-members.mjs),
41
- // NOT family-registry.mjs, so the npx cold-start path stays lean (no status/presenter graph pulled in).
47
+ // NOT family-registry.mjs. Leanness note: the bridge-refresh driver below does pull in the backend
48
+ // detector + the manifest validator (setup-backends' imports), but still NOT the status/presenter
49
+ // graph (family-registry, renderers, recipes) — the npx cold-start path stays presenter-free.
42
50
  import { FAMILY_MEMBERS } from '../tools/family-members.mjs';
51
+ // The refresh-only bridge driver (shared with `/agent-workflow-kit setup --refresh-placed` and the
52
+ // upgrade reconcile): refreshes ONLY a bridge `setup` already placed — an absent bridge is a stated
53
+ // skip (never a first placement, AD-009/AD-011) and a placed bridge newer than this kit's bundled
54
+ // mirror is a stated skip too (never a downgrade). Every line it returns is tool-composed.
55
+ import { refreshPlacedBridges } from '../tools/setup-backends.mjs';
43
56
 
44
57
  const __dirname = dirname(fileURLToPath(import.meta.url));
45
58
  const PKG_ROOT = resolve(__dirname, '..');
@@ -81,22 +94,6 @@ const readVersion = async () => {
81
94
  }
82
95
  };
83
96
 
84
- // Dependency-free semver: parse the leading `x.y.z` (prerelease/build ignored — kit versions are
85
- // plain). compareSemver returns -1 | 0 | 1, or null when either side is unparseable (legacy installs
86
- // predate any version stamp). No `let`: a small functional comparison (AGENTS.md §2.3).
87
- const parseSemver = (str) => {
88
- const m = typeof str === 'string' ? str.trim().match(/^(\d+)\.(\d+)\.(\d+)/) : null;
89
- return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;
90
- };
91
-
92
- const compareSemver = (a, b) => {
93
- const pa = parseSemver(a);
94
- const pb = parseSemver(b);
95
- if (!pa || !pb) return null;
96
- const firstDiff = [0, 1, 2].map((i) => (pa[i] === pb[i] ? 0 : pa[i] < pb[i] ? -1 : 1)).find((c) => c !== 0);
97
- return firstDiff ?? 0;
98
- };
99
-
100
97
  // Extract the version that is a DIRECT child of the top-level `metadata:` key — never a top-level
101
98
  // or deeper-nested decoy `version:` (mirrors the manifest validator's rigor; the kit ships manifest
102
99
  // fixtures that probe exactly those decoys). Pure string walk over the frontmatter block, no deps.
@@ -157,6 +154,7 @@ const parseArgs = (argv) => {
157
154
  noLaunchers: argv.includes('--no-launchers'),
158
155
  noMemory: argv.includes('--no-memory'),
159
156
  noEngine: argv.includes('--no-engine'),
157
+ noBridges: argv.includes('--no-bridges'),
160
158
  force: argv.includes('--force'),
161
159
  allowDowngrade: argv.includes('--allow-downgrade'),
162
160
  dir: dirFlag >= 0 ? argv[dirFlag + 1] : undefined,
@@ -278,7 +276,7 @@ const printHelp = (version) => {
278
276
  console.log(`agent-workflow-kit ${version}
279
277
 
280
278
  Usage:
281
- npx @sabaiway/agent-workflow-kit@latest init [--dir <path>] [--no-launchers] [--no-memory] [--no-engine] [--force] [--allow-downgrade]
279
+ npx @sabaiway/agent-workflow-kit@latest init [--dir <path>] [--no-launchers] [--no-memory] [--no-engine] [--no-bridges] [--force] [--allow-downgrade]
282
280
  npx @sabaiway/agent-workflow-kit@latest --version
283
281
  npx @sabaiway/agent-workflow-kit@latest --help
284
282
 
@@ -294,8 +292,10 @@ Installs/refreshes the kit at ~/.claude/skills/agent-workflow-kit
294
292
  stale, refresh it yourself + restart — a miss is otherwise a non-fatal degraded success,
295
293
  never the engine's hard STOP); --no-engine skips the engine install (the live methodology
296
294
  read then STOPs until you install it by hand); --force replaces a pre-existing non-kit
297
- launcher file (backed up first). The bridges are NOT installed by init (placed by
298
- /agent-workflow-kit setup). init is additive it never deletes your settings. If the
295
+ launcher file (backed up first). The bridges are never PLACED by init (first placement
296
+ stays /agent-workflow-kit setup, opt-in); once placed, init refreshes them from the kit's
297
+ own bundled copies — local files only, never a downgrade — and --no-bridges skips that
298
+ refresh. init is additive — it never deletes your settings. If the
299
299
  installed kit is newer than the version you ran, init refuses (no network — it compares
300
300
  the version on disk) and points you at @latest; --allow-downgrade overrides that
301
301
  refusal (distinct from --force, which is launcher-only).
@@ -376,15 +376,26 @@ const main = async () => {
376
376
  console.log(`[agent-workflow-kit] removed retired file ${tildify(retired)} (now read live from the engine).`);
377
377
  }
378
378
  }
379
- console.log(`[agent-workflow-kit] ${wasPresent ? 'updated the kit to' : 'installed'} v${version} -> ${tildify(target)}`);
380
-
381
- // No-op re-run: the install just refreshed the skill with the SAME version it already had. For a
382
- // user who ran `init` expecting an upgrade, that almost always means npx reused a cached build —
383
- // say so explicitly and point at @latest (the no-network signal that catches the reported scenario).
379
+ // Verb keyed on the OBSERVED version relation (cmp), never on mere presence: null (fresh install,
380
+ // or a legacy/unstamped one whose prior version is unknowable) → "installed"; -1 → a real update;
381
+ // 0 already current (the copy still ran see the note below); 1 is reachable only under
382
+ // --allow-downgrade (the gate above refused otherwise) and says so plainly. One message contract
383
+ // with the engine installer (same shapes, member noun differs).
384
+ const verb =
385
+ cmp === 0 ? 'refreshed the already-current kit'
386
+ : cmp === 1 ? 'downgraded the kit to'
387
+ : cmp === -1 ? 'updated the kit to'
388
+ : 'installed';
389
+ console.log(`[agent-workflow-kit] ${verb} v${version} -> ${tildify(target)}`);
390
+
391
+ // Same-version re-run: state observable facts only. The copy DID run (repair-on-rerun is a feature —
392
+ // it restores locally modified/deleted files), and whether npx served a cached build is NOT
393
+ // observable here (no network), so the note never claims it; the @latest hint is conditional.
384
394
  if (cmp === 0) {
385
395
  console.log(
386
- `[agent-workflow-kit] note: no version change — the kit was already v${version}. If you expected ` +
387
- `an update, npx likely served a cached build; re-run bypassing the cache:\n` +
396
+ `[agent-workflow-kit] note: the kit was already v${version} the copy still ran, restoring ` +
397
+ `any locally modified or deleted kit file to this version's packaged contents. If you ` +
398
+ `expected a NEWER version, invoke the @latest tag explicitly:\n` +
388
399
  ` npx @sabaiway/agent-workflow-kit@latest init`,
389
400
  );
390
401
  }
@@ -404,6 +415,40 @@ const main = async () => {
404
415
  }
405
416
  }
406
417
 
418
+ // Placed-bridge refresh — AFTER the kit copy (the bundled bridges/ just landed), BEFORE the two
419
+ // network cascade steps (this one is LOCAL files only: bundle → placed copy). Refresh-only, so the
420
+ // AD-009/AD-011 honesty claim survives as "init never PLACES bridges; it refreshes what setup
421
+ // already placed" — an absent bridge is a stated skip, a placed-newer one a stated skip too (never
422
+ // a downgrade). Best-effort in the memory DEGRADED shape: any miss is a loud warning + a
423
+ // host-runnable recovery composed from the RESOLVED target (a --dir / AGENT_WORKFLOW_KIT_DIR
424
+ // install must get a line that runs) + exit 0 — never silent, never the engine's hard STOP.
425
+ const bridgeRefreshCmd = `node ${tildify(resolve(target, 'tools/setup-backends.mjs'))} --refresh-placed`;
426
+ if (args.noBridges) {
427
+ console.log(
428
+ `[agent-workflow-kit] --no-bridges: skipped refreshing the placed bridges. If one is stale, ` +
429
+ `refresh it yourself:\n ${bridgeRefreshCmd}`,
430
+ );
431
+ } else if (process.platform === 'win32') {
432
+ console.log('[agent-workflow-kit] Windows: skipped the placed-bridge refresh (POSIX wrappers — refresh under WSL).');
433
+ } else {
434
+ console.log('[agent-workflow-kit] refreshing the bridges setup already placed (an absent bridge is never placed here):');
435
+ try {
436
+ const results = refreshPlacedBridges();
437
+ for (const r of results) console.log(r.line);
438
+ if (results.some((r) => r.outcome === 'failed')) {
439
+ console.warn(
440
+ `[agent-workflow-kit] could not refresh every placed bridge — continuing; the kit itself IS ` +
441
+ `installed and works. Re-run the refresh yourself:\n ${bridgeRefreshCmd}`,
442
+ );
443
+ }
444
+ } catch (err) {
445
+ console.warn(
446
+ `[agent-workflow-kit] could not refresh the placed bridges (${err.message}) — continuing; the ` +
447
+ `kit itself IS installed and works. Re-run the refresh yourself:\n ${bridgeRefreshCmd}`,
448
+ );
449
+ }
450
+ }
451
+
407
452
  // Memory substrate refresh — AFTER the kit + launchers, BEFORE the (fatal) engine and the success
408
453
  // block, so a returning `init` leaves no stale memory. Unlike the engine, a memory miss is a
409
454
  // DEGRADED success: warn with the exact recovery command + the on-disk version (read crash-proof)
package/capability.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "schema": 1,
4
4
  "name": "agent-workflow-kit",
5
5
  "kind": "composition-root",
6
- "version": "1.25.0",
6
+ "version": "1.27.0",
7
7
  "provides": [],
8
8
  "roles": {},
9
9
  "detect": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sabaiway/agent-workflow-kit",
3
- "version": "1.25.0",
3
+ "version": "1.27.0",
4
4
  "description": "Portable, cross-agent memory & workflow for AI coding agents — Claude Code, Codex, Cursor, Devin Desktop. One command deploys an AGENTS.md entry point + docs/ai context with cap/archive/index enforcement into any repo.",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: changelog-skeleton
3
+ description: Cheap-lane changelog fact-skeleton — drafts the factual bones of a changelog or release-notes entry from diff/log facts. The orchestrator (frontier) writes the lead and owns the final text; use only for the mechanical draft, never for persuasive copy.
4
+ model: haiku
5
+ effort: low
6
+ tools: Read, Grep, Glob
7
+ ---
8
+
9
+ You are a changelog-skeleton drafter on the cheap lane (L1). You turn diff facts the orchestrator
10
+ gives you (changed files, commit subjects, version bumps, test counts) into the FACTUAL BONES of
11
+ a changelog entry. The orchestrator writes the lead sentence and all user-facing framing — the
12
+ final wording is never yours (asymmetric pairing: cheap drafts, frontier signs).
13
+
14
+ Rules:
15
+ - Only facts present in the provided input or the files you are pointed at; every claim must be
16
+ traceable to a named file, commit, or diff hunk. Never invent a feature, a motivation, or an
17
+ impact statement.
18
+ - Structure: grouped bullet lists (Added / Changed / Fixed / Internal), each bullet naming the
19
+ artifact (`path`, tool, mode, version) it describes.
20
+ - Versions, package names, commands, and paths are quoted verbatim from the input.
21
+ - Mark anything uncertain as `VERIFY:` rather than asserting it.
22
+ - No superlatives, no persuasion, no summary paragraph — that is the frontier's red-line work.
23
+ - Read-only: you never modify files.
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: gate-triage
3
+ description: Cheap-lane gate-failure triage — reads failing gate/test output and produces a structured classification (which gate, first real error, implicated files) for the orchestrator to act on. Use to digest long failing output, never to fix code or decide what to do.
4
+ model: haiku
5
+ effort: low
6
+ tools: Read, Grep, Glob
7
+ ---
8
+
9
+ You are a gate-triage agent on the cheap lane (L1). You digest FAILING verification output (a
10
+ gate runner table, a test-suite log, a validator report) into a compact, structured triage the
11
+ orchestrator can act on. You never fix anything and never decide what to do next.
12
+
13
+ Rules:
14
+ - For each failing gate/test, report: the gate/test id · the FIRST real error line (quoted
15
+ verbatim) · the implicated `file:line` if the output names one · the failure class
16
+ (assertion / crash / timeout / missing-file / config).
17
+ - Separate signal from noise: strip repeated stack frames and progress spam; keep the shortest
18
+ quote that still identifies the failure.
19
+ - Preserve counts exactly as printed (`N passed, M failed`) — never recompute or estimate.
20
+ - If output is truncated or ambiguous, say so (`TRUNCATED` / `AMBIGUOUS`) — never guess a cause.
21
+ - Output: one section per failing gate, ordered as the run reported them. No fix suggestions,
22
+ no root-cause speculation beyond the failure class, no code.
23
+ - Read-only: you never modify files, never re-run commands.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: mechanical-sweep
3
+ description: Cheap-lane extraction sweeps — inventories, session-record extraction, doc checklists, multi-file fact collection. Use for mechanical reading at scale, never for judgment, code review, or writing code.
4
+ model: haiku
5
+ effort: low
6
+ tools: Read, Grep, Glob
7
+ ---
8
+
9
+ You are a mechanical extraction agent on the cheap lane (L1). Your job is READING AT SCALE and
10
+ returning structured facts — never conclusions, never opinions, never code.
11
+
12
+ Rules:
13
+ - Extract exactly what was asked: inventories, lists, counts, quoted lines, checklist states.
14
+ - Cite every fact as `file:line` (or `file` for whole-file facts) so the orchestrator can verify
15
+ it deterministically. A fact you cannot cite does not go in the output.
16
+ - Quote verbatim; never paraphrase an identifier, version, command, or path.
17
+ - If a requested item is absent, say `ABSENT` explicitly — never guess, never fill gaps.
18
+ - Output format: the structure the prompt asks for (list / table / JSON). No preamble, no
19
+ commentary, no recommendations — the orchestrator applies judgment, you supply facts.
20
+ - Read-only: you never modify files, never run commands, never propose edits.
@@ -26,6 +26,7 @@ diverge:
26
26
  | Pattern | Owner | Kind | Commit-risk name? | Note |
27
27
  |---|---|---|---|---|
28
28
  | `/.claude/skills/` | Claude Code | dir | no | local-dev skills; absorbs the AD-013 one-off |
29
+ | `/.claude/agents/` | Claude Code | dir | no | project subagent definitions (incl. the kit-placed cheap-lane vehicles) |
29
30
  | `/.cursor/rules/` | Cursor | dir | no | project rule files |
30
31
  | `/.cursorrules` | Cursor (legacy) | file | **yes** | legacy single-file rules |
31
32
  | `/.codeium/` | Codeium/Windsurf | dir | no | home-scoped launchers live under `~/`, out of scope |