@sabaiway/agent-workflow-kit 14.19.1 → 14.21.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/README.md +1 -1
  3. package/SKILL.md +1 -1
  4. package/bridges/antigravity-cli-bridge/SKILL.md +45 -50
  5. package/bridges/antigravity-cli-bridge/bin/agy-model-posture.test.mjs +257 -0
  6. package/bridges/antigravity-cli-bridge/bin/agy-review-harness.test.mjs +10 -3
  7. package/bridges/antigravity-cli-bridge/bin/agy-review-honesty.test.mjs +20 -21
  8. package/bridges/antigravity-cli-bridge/bin/agy-review-model-screen.test.mjs +4 -4
  9. package/bridges/antigravity-cli-bridge/bin/agy-review.sh +120 -48
  10. package/bridges/antigravity-cli-bridge/bin/agy-review.test.mjs +22 -62
  11. package/bridges/antigravity-cli-bridge/bin/agy.sh +109 -16
  12. package/bridges/antigravity-cli-bridge/bin/agy.test.mjs +5 -5
  13. package/bridges/antigravity-cli-bridge/capability.json +14 -7
  14. package/bridges/antigravity-cli-bridge/references/driving-agy.md +16 -20
  15. package/bridges/antigravity-cli-bridge/references/models-and-flags.md +10 -27
  16. package/bridges/codex-cli-bridge/SKILL.md +57 -49
  17. package/bridges/codex-cli-bridge/bin/codex-exec.sh +145 -46
  18. package/bridges/codex-cli-bridge/bin/codex-exec.test.mjs +28 -55
  19. package/bridges/codex-cli-bridge/bin/codex-model-posture.test.mjs +371 -0
  20. package/bridges/codex-cli-bridge/bin/codex-review.sh +134 -36
  21. package/bridges/codex-cli-bridge/bin/codex-review.test.mjs +33 -45
  22. package/bridges/codex-cli-bridge/capability.json +22 -8
  23. package/bridges/codex-cli-bridge/references/driving-codex.md +18 -15
  24. package/bridges/codex-cli-bridge/references/sandbox-and-flags.md +16 -12
  25. package/bridges/codex-cli-bridge/setup/README.md +3 -3
  26. package/capability.json +1 -1
  27. package/package.json +1 -1
  28. package/references/modes/bridge-settings.md +10 -7
  29. package/references/modes/jev.md +3 -2
  30. package/references/modes/recipes.md +1 -1
  31. package/references/modes/recommendations.md +2 -1
  32. package/references/modes/review-state.md +1 -1
  33. package/references/vendor/typesafe-ai/LICENSE +21 -0
  34. package/references/vendor/typesafe-ai/SKILL.md.pinned +149 -0
  35. package/tools/ack-store.mjs +2 -0
  36. package/tools/bridge-catalog.mjs +114 -0
  37. package/tools/bridge-posture.mjs +11 -2
  38. package/tools/bridge-settings-read.mjs +41 -5
  39. package/tools/bridge-settings.mjs +111 -23
  40. package/tools/detect-backends.mjs +6 -6
  41. package/tools/family-registry.mjs +3 -3
  42. package/tools/jev-facts.mjs +101 -4
  43. package/tools/jev-guide.mjs +31 -12
  44. package/tools/jev-skill.mjs +231 -0
  45. package/tools/manifest/schema.md +1 -1
  46. package/tools/manifest/validate.mjs +3 -2
  47. package/tools/procedures.mjs +3 -3
  48. package/tools/recipes.mjs +2 -2
  49. package/tools/recommendations.mjs +49 -4
  50. package/tools/review-state.mjs +1 -1
@@ -95,6 +95,7 @@ import {
95
95
  ACKS_COVERAGE_DOMAIN_KEY,
96
96
  ACKS_SOURCE_SIZE_COPY_KEY,
97
97
  ACKS_JEV_CONNECT_KEY,
98
+ ACKS_JEV_SKILL_KEY,
98
99
  ACK_LANES,
99
100
  factFingerprint,
100
101
  readAckValue,
@@ -102,12 +103,14 @@ import {
102
103
  import { ADOPTION, STORE_DIR_REL as SPEC_STORE_DIR_REL, SPEC_ADOPTION_LANE, declineFingerprint, readDeclineAck, surveySpecAdoption } from './spec-adoption.mjs';
103
104
  import { ENSURE_OPS } from './ensure-vocabulary.mjs';
104
105
  import { composeProfileGapScreen } from './profile-gap-screen.mjs';
105
- import { connectLine, keySet, placeOf } from './jev-facts.mjs';
106
+ import { NO_APPLY_LINE, SKILL_PINS, claudeDirOf, connectLine, keySet, placeOf, printable, skillLine, skillState, skillTargets } from './jev-facts.mjs';
106
107
 
107
108
  // The upgrade ensure that seeds the spec store — the not-adopted item's apply; pinned to the vocabulary.
108
109
  const SPEC_LAYER_ENSURE = ENSURE_OPS.includes('specs') ? 'specs' : null;
109
110
  const JEV_CONNECT_DECLINED = 'jev-connect:declined';
110
111
  const JEV_CONNECT_DECLINE = factFingerprint(JEV_CONNECT_DECLINED);
112
+ // The skill decline names the pin it declined, so a pin move brings the update offer back once.
113
+ const JEV_SKILL_DECLINED = 'jev-skill:declined:';
111
114
 
112
115
  export { ACKS_FILE, ACKS_LANE_KEY, ACKS_WORKTREES_DIR_KEY, ACKS_COVERAGE_DOMAIN_KEY, ACKS_SOURCE_SIZE_COPY_KEY, ACK_LANES, factFingerprint };
113
116
 
@@ -206,6 +209,8 @@ export const SEVERITIES = Object.freeze({
206
209
  'spec-adoption': SEVERITY_OPTIONAL,
207
210
  'profile-gap': SEVERITY_OPTIONAL,
208
211
  'jev-connect': SEVERITY_OPTIONAL,
212
+ 'jev-skill': SEVERITY_OPTIONAL,
213
+ 'jev-skill.earlier': SEVERITY_OPTIONAL,
209
214
  'spec-adoption.adopting': SEVERITY_OPTIONAL,
210
215
  });
211
216
  // The per-item render tags (frozen presentation data, same language contract as the templates).
@@ -284,6 +289,8 @@ export const WHATS = Object.freeze({
284
289
  'spec-adoption': 'feature-spec store absent (docs/ai/specs) — no feature contract can govern a plan here yet; seed the store, or record the decline',
285
290
  'profile-gap': '{what}',
286
291
  'jev-connect': 'Jev (TypeSafe) is not connected: TYPESAFE_API_KEY is not in the environment the agent\'s commands run in',
292
+ 'jev-skill': 'Jev\'s vendor skill is not installed for every agent here: a skill root the kit fills is absent or behind the kit\'s pin',
293
+ 'jev-skill.earlier': 'Jev\'s vendor skill in the agent skill roots is at {old}, behind the kit\'s pin {new}; only copies matching a kit pin change',
287
294
  'spec-adoption.adopting': 'feature-spec store: {n} draft spec(s), no live contract — nothing governs a plan through it yet; land a live contract, or record the decline',
288
295
  });
289
296
 
@@ -346,6 +353,7 @@ export const BENEFITS = Object.freeze({
346
353
  'spec-adoption': 'contracts — a plan names the contract it builds to, and a change to a governed slice is visible at review instead of after it',
347
354
  'profile-gap': 'full flow — each difference from the reference profile is previewed by its own writer; a declined one returns only at a lineage step',
348
355
  'jev-connect': 'decisions — a typed choice with a confidence in under a second for your code and the agent\'s scripts, once for every project here',
356
+ 'jev-skill': 'the TypeSafe skill for Claude Code, Codex and Antigravity CLI, one pinned verified copy per agent root, from one command you run',
349
357
  });
350
358
 
351
359
  // ── the CLOSED opt-in capability registry (OPT-IN-SHIPS-INVISIBLE) ──────────────────────────────
@@ -394,6 +402,7 @@ export const OPT_IN_CAPABILITIES = Object.freeze([
394
402
  { id: 'spec-adoption', mode: 'upgrade', advisorKey: 'spec-adoption' },
395
403
  { id: 'full-flow-profile', mode: 'upgrade', advisorKey: 'profile-gap' },
396
404
  { id: 'jev-connect', mode: 'jev', advisorKey: 'jev-connect' },
405
+ { id: 'jev-skill', mode: 'jev', advisorKey: 'jev-skill' },
397
406
  { id: 'adr-store-migration', mode: 'migrate-adr-store', advisorKey: 'adr-store-migration' },
398
407
  { id: 'review-recipe', mode: 'set-recipe', advisorKey: 'review-recipe' },
399
408
  // The execute slot is a DISTINCT opt-in from the review slot, and the same probe reports both —
@@ -1313,7 +1322,7 @@ const readReadLaneToggle = (root, deps) => {
1313
1322
  // D3: the risk-marked keys — every key here has a per-item posture note in the mode doc, surfaced
1314
1323
  // at the consent moment; the static contract test asserts EXACT bidirectional coverage
1315
1324
  // (risk-marked keys == mode-doc note keys — a dropped note goes red, not silent).
1316
- export const RISK_NOTED_KEYS = Object.freeze(['sandbox-lane', 'read-lane', 'worktrees-dir', 'adr-store-migration', 'gates-inert', 'source-size', 'gate-hook', 'mcp-channel', 'spec-adoption', 'enforcement', 'profile-gap', 'jev-connect']);
1325
+ export const RISK_NOTED_KEYS = Object.freeze(['sandbox-lane', 'read-lane', 'worktrees-dir', 'adr-store-migration', 'gates-inert', 'source-size', 'gate-hook', 'mcp-channel', 'spec-adoption', 'enforcement', 'profile-gap', 'jev-connect', 'jev-skill']);
1317
1326
 
1318
1327
  // The feature-spec layer's adoption state (contract: kit/spec-adoption). The canon lets a plan cite
1319
1328
  // zero governing specs while a project adopts the layer, and nothing ever said whether adoption had
@@ -1625,6 +1634,40 @@ export const probeJevConnect = ({ root, deps, add, skip }) => {
1625
1634
  }
1626
1635
  };
1627
1636
 
1637
+ // The Jev skill offer (contract: kit/jev-guide, part jev-offer): only once the key is set, so one jev item shows at a time.
1638
+ // Each target is judged by the facts leaf's one state rule; the apply is the skill command the USER runs (HAND-APPLY).
1639
+ export const probeJevSkill = ({ root, deps, add, skip }) => {
1640
+ try {
1641
+ const env = deps.getenv ?? {};
1642
+ if (!keySet(env)) return;
1643
+ const host = deps.jevHost ?? {};
1644
+ if (typeof host.home !== 'string' || host.home === '') return;
1645
+ const pins = deps.jevPins ?? SKILL_PINS;
1646
+ const { dir, note } = claudeDirOf(env, host.home, host.platform);
1647
+ const io = { lstat: deps.lstat ?? lstatSync, readdir: deps.readdir ?? readdirSync, readFile: deps.readFile ?? readFileSync, pins };
1648
+ const judged = skillTargets({ home: host.home, claudeDir: dir }).map((target) => ({ ...target, ...skillState(target, io) }));
1649
+ if (!judged.some(({ state }) => state === 'absent' || state === 'earlier')) return;
1650
+ const decline = factFingerprint(`${JEV_SKILL_DECLINED}${pins[0].tag}`);
1651
+ if (readAckValue(root, deps, ACKS_JEV_SKILL_KEY) === decline) return;
1652
+ const line = skillLine(HERE, host.platform, dir);
1653
+ if (line === '') {
1654
+ skip('jev-skill', new Error(NO_APPLY_LINE));
1655
+ return;
1656
+ }
1657
+ const place = placeOf({ env, platform: host.platform, hostname: host.hostname, container: host.container });
1658
+ const behind = judged.filter(({ state }) => state === 'earlier').map(({ tag }) => pins.findIndex((pin) => pin.tag === tag));
1659
+ const what = behind.length ? fillTemplate(WHATS['jev-skill.earlier'], { old: pins[Math.max(...behind)].tag, new: pins[0].tag })
1660
+ : WHATS['jev-skill'];
1661
+ const untouched = judged.filter(({ state }) => state === 'foreign')
1662
+ .map(({ path, reason }) => `left untouched: ${printable(path)} — ${printable(reason)}; `).join('');
1663
+ const record = `node ${q(toolPath('ack-write.mjs'))} --lane jev-skill --fingerprint ${decline} --cwd ${q(root)}`;
1664
+ add('jev-skill', what, `HAND-APPLY: ${line}`, behind.length ? 'jev-skill.earlier' : 'jev-skill',
1665
+ `${place ? `run the apply in ${place}; ` : ''}${untouched}${note ? `${note}; ` : ''}HAND-APPLY alternative (instead of the apply, never after it): decline the offer by recording it — ${record}`);
1666
+ } catch (err) {
1667
+ skip('jev-skill', err);
1668
+ }
1669
+ };
1670
+
1628
1671
  export const probeProfileGaps = ({ root, deps, add, skip }) => {
1629
1672
  try {
1630
1673
  const { gaps, skips } = composeProfileGapScreen({ root, deps });
@@ -1658,6 +1701,7 @@ const PROBES = Object.freeze([
1658
1701
  probeMcpChannel,
1659
1702
  probeSpecAdoption,
1660
1703
  probeJevConnect,
1704
+ probeJevSkill,
1661
1705
  probeProfileGaps,
1662
1706
  ]);
1663
1707
 
@@ -1760,9 +1804,10 @@ the consent-gated ack writer into docs/ai/acks.json (never a security key).
1760
1804
  Read-only: never writes, never commits, never runs a subscription CLI. Exit codes: 0 report
1761
1805
  rendered (items or empty); 1 error; 2 usage.`;
1762
1806
 
1763
- // The host facts of the key offer's place: the platform, the hostname (a throw reads as none), /.dockerenv a regular file.
1807
+ // The host facts of the key and skill offers: the platform, the hostname (a throw reads as none), /.dockerenv a regular file, the home.
1764
1808
  const hostFacts = () => ({ platform: process.platform, hostname: (() => { try { return hostname(); } catch { return ''; } })(),
1765
- container: (() => { try { return statSync('/.dockerenv').isFile(); } catch { return false; } })() });
1809
+ container: (() => { try { return statSync('/.dockerenv').isFile(); } catch { return false; } })(),
1810
+ home: (() => { try { return homedir(); } catch { return ''; } })() });
1766
1811
 
1767
1812
  export const main = (argv, ctx = {}) => {
1768
1813
  try {
@@ -48,7 +48,7 @@
48
48
  // (artifact ≠ "code") and continuations (fresh:false — agy --continue/--conversation cannot attest
49
49
  // a folded tree; only a fresh grounded re-run mints a gate-satisfying receipt).
50
50
  // PROBE receipts never satisfy either (BRIDGE-MODES-CATALOG, D3): a CODEX_PROBE=1 / AGY_PROBE=1
51
- // review runs with the frontier-model/max-effort guard OFF, so the wrappers stamp `probe:true` and
51
+ // review is the one route to a one-off model or effort, so the wrappers stamp `probe:true` and
52
52
  // this checker drops those receipts — PER RECEIPT, so a normal receipt at the same fingerprint still
53
53
  // satisfies, and a backend whose ONLY current receipts are probes fails with its own stated reason
54
54
  // (never the stale one). Every receipt from a marker-aware wrapper SELF-DECLARES — `probe` is written