@dadado/agent-kit-cli 6.2.0 → 6.4.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 (45) hide show
  1. package/dashboard/dashboard-data.mjs +14 -2
  2. package/dashboard/dashboard.html +139 -4
  3. package/dashboard/lib/chat-sessions.d.mts +63 -0
  4. package/dashboard/lib/chat-sessions.mjs +430 -0
  5. package/dashboard/serve.mjs +5 -1
  6. package/dist/{add-Y2426TGU.js → add-HFDX3U3R.js} +2 -2
  7. package/dist/{chunk-TW4BF5OE.js → chunk-3OM7JODZ.js} +2 -2
  8. package/dist/{chunk-TGNFGMPV.js → chunk-6OTJEQEC.js} +90 -5
  9. package/dist/{chunk-MAPOQEA2.js → chunk-6RRG3WOE.js} +8 -1
  10. package/dist/{chunk-NSSXSZLL.js → chunk-7BEHUBEJ.js} +5 -1
  11. package/dist/{chunk-CWDXNBEU.js → chunk-ANPSYWQO.js} +2 -2
  12. package/dist/{chunk-BEKQ6PVD.js → chunk-AXLXEAVJ.js} +1 -1
  13. package/dist/{chunk-X45O2AIE.js → chunk-E465FAWM.js} +1 -1
  14. package/dist/{chunk-C2SJDYAM.js → chunk-H46W7NHC.js} +1 -1
  15. package/dist/{chunk-SPYIP76F.js → chunk-HHR56LJQ.js} +64 -28
  16. package/dist/{chunk-IR7FFPUU.js → chunk-IMIVTDMK.js} +43 -8
  17. package/dist/chunk-IRTS7WEA.js +374 -0
  18. package/dist/{chunk-MO63KZBP.js → chunk-KX3OUY4W.js} +8 -6
  19. package/dist/chunk-MWTXI6C5.js +223 -0
  20. package/dist/{chunk-JEI6HACW.js → chunk-NJVWTROP.js} +24 -377
  21. package/dist/{chunk-CER2APV2.js → chunk-Q4PCMRM5.js} +1 -1
  22. package/dist/{chunk-GUQYNUV4.js → chunk-R7DA4KXG.js} +1 -1
  23. package/dist/{chunk-VO73OL5V.js → chunk-SE7ZIRLX.js} +2 -2
  24. package/dist/{chunk-KVY425NM.js → chunk-TZ5XYIEF.js} +4 -2
  25. package/dist/{chunk-Z7ABX5QI.js → chunk-WOHZ4T5V.js} +4 -2
  26. package/dist/{chunk-YRFSTHR5.js → chunk-XEEB4YSA.js} +13 -219
  27. package/dist/{chunk-QTBTKEXK.js → chunk-ZPZVROS5.js} +1 -1
  28. package/dist/{contribute-TVST3CJO.js → contribute-PP7HMPW7.js} +3 -3
  29. package/dist/{countdown-QXJD6TDB.js → countdown-LAUZMI7U.js} +10 -8
  30. package/dist/{diff-MECE5RZB.js → diff-HYWC4G6Y.js} +4 -4
  31. package/dist/{doctor-VLZNXJNA.js → doctor-2X3HBRJJ.js} +8 -8
  32. package/dist/engine-info-4ZWEIHSX.js +89 -0
  33. package/dist/{ground-control-NMYYIVCV.js → ground-control-WKV2BMOW.js} +5 -4
  34. package/dist/{guard-EHXF76ID.js → guard-ZZRQW3DJ.js} +107 -8
  35. package/dist/{hook-XCZWX462.js → hook-UEYR4M3Z.js} +10 -4
  36. package/dist/index.js +26 -22
  37. package/dist/{init-HKMRU2V4.js → init-UF5VEIJX.js} +11 -11
  38. package/dist/{install-X2J6KWZ5.js → install-6ILVA22C.js} +11 -11
  39. package/dist/{run-R66G276Q.js → run-2EKD2BEC.js} +12 -9
  40. package/dist/{run-plan-24Z5K4P3.js → run-plan-G72XMC5Z.js} +11 -7
  41. package/dist/sessions-O7MYEMCT.js +343 -0
  42. package/dist/{setup-global-ADJFMOZX.js → setup-global-ZZEY5KWE.js} +5 -5
  43. package/dist/{status-UB6NL3Q3.js → status-4LK2QXVQ.js} +6 -6
  44. package/dist/{update-PFBFY7GT.js → update-FPR2NZND.js} +33 -43
  45. package/package.json +1 -1
@@ -5,7 +5,7 @@ import {
5
5
  DEFAULT_REGISTRY_REF,
6
6
  DEFAULT_REGISTRY_URL,
7
7
  resolveRegistryRoot
8
- } from "./chunk-NSSXSZLL.js";
8
+ } from "./chunk-7BEHUBEJ.js";
9
9
 
10
10
  // src/lifecycle/resolve-cli.ts
11
11
  async function resolveRegistryFromCli(options) {
@@ -1,6 +1,7 @@
1
1
  import {
2
+ INTERACTIVE_ALLOW_RULES,
2
3
  INTERACTIVE_DENY_RULES
3
- } from "./chunk-MAPOQEA2.js";
4
+ } from "./chunk-6RRG3WOE.js";
4
5
  import {
5
6
  assertRealContained,
6
7
  assertRealParentContained,
@@ -10,7 +11,7 @@ import {
10
11
  resolveContained,
11
12
  saveManagedHashLedger,
12
13
  shouldPreserveCustomizedOverlay
13
- } from "./chunk-NSSXSZLL.js";
14
+ } from "./chunk-7BEHUBEJ.js";
14
15
  import {
15
16
  ensureDir,
16
17
  fileExists
@@ -149,17 +150,18 @@ var ClaudeSettingsLedgerInvalidError = class extends Error {
149
150
  path;
150
151
  };
151
152
  function emptyLedger() {
152
- return { schemaVersion: 1, denyRowsWritten: [], hookEntriesWritten: [] };
153
+ return { schemaVersion: 1, denyRowsWritten: [], allowRowsWritten: [], hookEntriesWritten: [] };
153
154
  }
154
155
  function hookKey(r) {
155
156
  return `${r.event}\0${r.marker}`;
156
157
  }
157
- function normalize(denyRows, hooks) {
158
+ function normalize(denyRows, allowRows, hooks) {
158
159
  const seen = /* @__PURE__ */ new Map();
159
160
  for (const h of hooks) seen.set(hookKey(h), { event: h.event, marker: h.marker });
160
161
  return {
161
162
  schemaVersion: 1,
162
163
  denyRowsWritten: [...new Set(denyRows)].sort(),
164
+ allowRowsWritten: [...new Set(allowRows)].sort(),
163
165
  hookEntriesWritten: [...seen.values()].sort(
164
166
  (a, b) => a.event.localeCompare(b.event) || a.marker.localeCompare(b.marker)
165
167
  )
@@ -178,6 +180,8 @@ function parseLedger(raw) {
178
180
  if (!Array.isArray(o.denyRowsWritten) || !o.denyRowsWritten.every((r) => typeof r === "string")) {
179
181
  return null;
180
182
  }
183
+ const allowRows = o.allowRowsWritten ?? [];
184
+ if (!Array.isArray(allowRows) || !allowRows.every((r) => typeof r === "string")) return null;
181
185
  if (!Array.isArray(o.hookEntriesWritten)) return null;
182
186
  const hooks = [];
183
187
  for (const h of o.hookEntriesWritten) {
@@ -189,7 +193,7 @@ function parseLedger(raw) {
189
193
  marker: h.marker
190
194
  });
191
195
  }
192
- return normalize(o.denyRowsWritten, hooks);
196
+ return normalize(o.denyRowsWritten, allowRows, hooks);
193
197
  }
194
198
  async function readState(root) {
195
199
  const abs = resolveContained(root, CLAUDE_SETTINGS_LEDGER_REL);
@@ -224,6 +228,7 @@ async function saveClaudeSettingsLedger(root, additions, opts = {}) {
224
228
  const base = state.kind === "ok" ? state.ledger : emptyLedger();
225
229
  const merged = normalize(
226
230
  [...base.denyRowsWritten, ...additions.denyRowsWritten ?? []],
231
+ [...base.allowRowsWritten, ...additions.allowRowsWritten ?? []],
227
232
  [...base.hookEntriesWritten, ...additions.hookEntriesWritten ?? []]
228
233
  );
229
234
  await mkdir(path2.dirname(abs), { recursive: true });
@@ -300,8 +305,12 @@ function mergeSessionStartHookIntoSettings(existingRaw, opts = {}) {
300
305
  };
301
306
  }
302
307
  }
303
- const pending = { denyRows: [], hookEntries: [] };
304
- const additions = { denyRowsWritten: [], hookEntriesWritten: [] };
308
+ const pending = { denyRows: [], allowRows: [], hookEntries: [] };
309
+ const additions = {
310
+ denyRowsWritten: [],
311
+ allowRowsWritten: [],
312
+ hookEntriesWritten: []
313
+ };
305
314
  const hooks = isPlainObject(root.hooks) ? { ...root.hooks } : {};
306
315
  const sessionStart = Array.isArray(hooks.SessionStart) ? [...hooks.SessionStart] : [];
307
316
  const preToolUse = Array.isArray(hooks.PreToolUse) ? [...hooks.PreToolUse] : [];
@@ -342,8 +351,17 @@ function mergeSessionStartHookIntoSettings(existingRaw, opts = {}) {
342
351
  (acc, next, i) => i === 0 ? next : combineStatus(acc, next),
343
352
  "unchanged"
344
353
  );
345
- const denyAdded = mergeKitDenyRules(root, { ledger, authorized }, pending, additions);
346
- const finalStatus = denyAdded && status === "unchanged" ? "refreshed" : status;
354
+ const ctx = { ledger, authorized };
355
+ const denyAdded = mergeKitRuleRows(root, "deny", INTERACTIVE_DENY_RULES, ctx, pending, additions);
356
+ const allowAdded = mergeKitRuleRows(
357
+ root,
358
+ "allow",
359
+ INTERACTIVE_ALLOW_RULES,
360
+ ctx,
361
+ pending,
362
+ additions
363
+ );
364
+ const finalStatus = (denyAdded || allowAdded) && status === "unchanged" ? "refreshed" : status;
347
365
  return {
348
366
  content: `${JSON.stringify(root, null, 2)}
349
367
  `,
@@ -355,23 +373,25 @@ function mergeSessionStartHookIntoSettings(existingRaw, opts = {}) {
355
373
  function combineStatus(a, b) {
356
374
  return a === "unchanged" && b !== "unchanged" ? "refreshed" : a;
357
375
  }
358
- function mergeKitDenyRules(root, ctx, pending, additions) {
376
+ function mergeKitRuleRows(root, kind, rules, ctx, pending, additions) {
359
377
  if (root.permissions !== void 0 && !isPlainObject(root.permissions)) return false;
360
378
  const permissions = isPlainObject(root.permissions) ? { ...root.permissions } : {};
361
- if (permissions.deny !== void 0 && !Array.isArray(permissions.deny)) return false;
362
- const deny = Array.isArray(permissions.deny) ? [...permissions.deny] : [];
363
- const written = new Set(ctx.ledger?.denyRowsWritten ?? []);
364
- for (const rule of INTERACTIVE_DENY_RULES) {
365
- if (deny.includes(rule)) additions.denyRowsWritten.push(rule);
366
- }
367
- const missing = INTERACTIVE_DENY_RULES.filter(
368
- (rule) => !deny.includes(rule) && !written.has(rule)
379
+ if (permissions[kind] !== void 0 && !Array.isArray(permissions[kind])) return false;
380
+ const list = Array.isArray(permissions[kind]) ? [...permissions[kind]] : [];
381
+ const pendingRows = kind === "deny" ? pending.denyRows : pending.allowRows;
382
+ const written = kind === "deny" ? additions.denyRowsWritten : additions.allowRowsWritten;
383
+ const ledgerRows = new Set(
384
+ (kind === "deny" ? ctx.ledger?.denyRowsWritten : ctx.ledger?.allowRowsWritten) ?? []
369
385
  );
386
+ for (const rule of rules) {
387
+ if (list.includes(rule)) written.push(rule);
388
+ }
389
+ const missing = rules.filter((rule) => !list.includes(rule) && !ledgerRows.has(rule));
370
390
  const toAdd = ctx.ledger === null && !ctx.authorized ? [] : missing;
371
- if (ctx.ledger === null && !ctx.authorized) pending.denyRows.push(...missing);
391
+ if (ctx.ledger === null && !ctx.authorized) pendingRows.push(...missing);
372
392
  if (toAdd.length === 0) return false;
373
- additions.denyRowsWritten.push(...toAdd);
374
- permissions.deny = [...deny, ...toAdd];
393
+ written.push(...toAdd);
394
+ permissions[kind] = [...list, ...toAdd];
375
395
  root.permissions = permissions;
376
396
  return true;
377
397
  }
@@ -425,7 +445,7 @@ async function writeClaudeSessionStartHook(rootDir, opts = {}) {
425
445
  relativePath: CLAUDE_SETTINGS_REL,
426
446
  status: merged.status
427
447
  };
428
- if (merged.pending && (merged.pending.denyRows.length || merged.pending.hookEntries.length)) {
448
+ if (merged.pending && (merged.pending.denyRows.length || merged.pending.allowRows.length || merged.pending.hookEntries.length)) {
429
449
  result.pending = merged.pending;
430
450
  }
431
451
  if (authorized && merged.ledgerAdditions && ledgerGrows(ledger, merged.ledgerAdditions)) {
@@ -437,8 +457,9 @@ async function writeClaudeSessionStartHook(rootDir, opts = {}) {
437
457
  function ledgerGrows(ledger, add) {
438
458
  if (ledger === null) return true;
439
459
  const rows = new Set(ledger.denyRowsWritten);
460
+ const allowRows = new Set(ledger.allowRowsWritten);
440
461
  const hooks = new Set(ledger.hookEntriesWritten.map((h) => `${h.event}\0${h.marker}`));
441
- return add.denyRowsWritten.some((r) => !rows.has(r)) || add.hookEntriesWritten.some((h) => !hooks.has(`${h.event}\0${h.marker}`));
462
+ return add.denyRowsWritten.some((r) => !rows.has(r)) || add.allowRowsWritten.some((r) => !allowRows.has(r)) || add.hookEntriesWritten.some((h) => !hooks.has(`${h.event}\0${h.marker}`));
442
463
  }
443
464
  async function planClaudeSettingsDrift(rootDir) {
444
465
  const abs = resolveContained(rootDir, CLAUDE_SETTINGS_REL);
@@ -477,17 +498,23 @@ async function planClaudeSettingsDrift(rootDir) {
477
498
  const merged = mergeSessionStartHookIntoSettings(raw, { ledger, authorized: false });
478
499
  if (merged.content === null) return null;
479
500
  const next = JSON.parse(merged.content);
480
- const deny = (r) => isPlainObject(r.permissions) && Array.isArray(r.permissions.deny) ? r.permissions.deny.filter((x) => typeof x === "string") : [];
481
- const had = new Set(deny(existing));
482
- const denyRows = deny(next).filter((r) => !had.has(r));
501
+ const rowsOf = (r, kind) => {
502
+ const list = isPlainObject(r.permissions) ? r.permissions[kind] : void 0;
503
+ return Array.isArray(list) ? list.filter((x) => typeof x === "string") : [];
504
+ };
505
+ const hadDeny = new Set(rowsOf(existing, "deny"));
506
+ const hadAllow = new Set(rowsOf(existing, "allow"));
507
+ const denyRows = rowsOf(next, "deny").filter((r) => !hadDeny.has(r));
508
+ const allowRows = rowsOf(next, "allow").filter((r) => !hadAllow.has(r));
483
509
  const ambiguousDenyRows = merged.pending?.denyRows ?? [];
510
+ const ambiguousAllowRows = merged.pending?.allowRows ?? [];
484
511
  const missingEntries = kitEntries.filter((e) => !present.includes(e));
485
512
  const ledgerHas = (e) => Boolean(ledger?.hookEntriesWritten.some((h) => h.event === e.event && h.marker === e.marker));
486
513
  const hookEntries = missingEntries.filter((e) => !ledgerHas(e));
487
- if (denyRows.length === 0 && ambiguousDenyRows.length === 0 && hookEntries.length === 0) {
514
+ if (denyRows.length === 0 && ambiguousDenyRows.length === 0 && allowRows.length === 0 && ambiguousAllowRows.length === 0 && hookEntries.length === 0) {
488
515
  return null;
489
516
  }
490
- return { denyRows, ambiguousDenyRows, hookEntries };
517
+ return { denyRows, ambiguousDenyRows, allowRows, ambiguousAllowRows, hookEntries };
491
518
  }
492
519
  function formatClaudeSettingsDrift(report, opts) {
493
520
  const rows = [...report.denyRows, ...report.ambiguousDenyRows];
@@ -502,6 +529,15 @@ function formatClaudeSettingsDrift(report, opts) {
502
529
  );
503
530
  }
504
531
  }
532
+ const allowRows = [...report.allowRows, ...report.ambiguousAllowRows];
533
+ if (allowRows.length > 0) {
534
+ lines.push("Add to permissions.allow:", JSON.stringify(allowRows, null, 2));
535
+ if (report.ambiguousAllowRows.length > 0) {
536
+ lines.push(
537
+ `(${report.ambiguousAllowRows.length} row(s) ambiguous: no ${CLAUDE_SETTINGS_LEDGER_REL} ledger, so a deliberate deletion cannot be told apart.)`
538
+ );
539
+ }
540
+ }
505
541
  if (report.hookEntries.length > 0) {
506
542
  lines.push("Missing hook entries (add by hand or use the command below):");
507
543
  for (const e of report.hookEntries) lines.push(` ${e.event}: ${e.marker}`);
@@ -1,8 +1,12 @@
1
1
  import {
2
2
  NON_INTERACTIVE_ROOT_ARGS,
3
+ StaleCliError,
4
+ detectStaleCli,
5
+ formatRerunFlags,
6
+ formatStaleCliRefusal,
3
7
  installL0,
4
8
  syncFromManifest
5
- } from "./chunk-TGNFGMPV.js";
9
+ } from "./chunk-6OTJEQEC.js";
6
10
  import {
7
11
  SkippedSymlinkError,
8
12
  formatPersonalizationSkippedSymlinks,
@@ -11,11 +15,11 @@ import {
11
15
  import {
12
16
  REGISTRY_CLI_ARGS,
13
17
  resolveRegistryFromCli
14
- } from "./chunk-C2SJDYAM.js";
18
+ } from "./chunk-H46W7NHC.js";
15
19
  import {
16
20
  assessClaudeCommandAdapters,
17
21
  executeSafeReadinessFixes
18
- } from "./chunk-BEKQ6PVD.js";
22
+ } from "./chunk-AXLXEAVJ.js";
19
23
  import {
20
24
  writeReadinessSnapshot
21
25
  } from "./chunk-HAFRAXGV.js";
@@ -23,7 +27,7 @@ import {
23
27
  CLAUDE_HITL_FALLBACK,
24
28
  generateClaudeCommandAdapters,
25
29
  writeClaudeSessionStartHook
26
- } from "./chunk-SPYIP76F.js";
30
+ } from "./chunk-HHR56LJQ.js";
27
31
  import {
28
32
  shouldUseWelcomeColor,
29
33
  withCliProgress
@@ -50,13 +54,13 @@ import {
50
54
  npxPinned,
51
55
  pathCliStatus,
52
56
  syncPathCliToRuntime
53
- } from "./chunk-VO73OL5V.js";
57
+ } from "./chunk-SE7ZIRLX.js";
54
58
  import {
55
59
  assessEnvironment
56
60
  } from "./chunk-B3VR5YBQ.js";
57
61
  import {
58
62
  warnIfRunningCliBehindNpm
59
- } from "./chunk-TW4BF5OE.js";
63
+ } from "./chunk-3OM7JODZ.js";
60
64
  import {
61
65
  DOMAIN_PACK_IDS,
62
66
  allPacks,
@@ -73,7 +77,7 @@ import {
73
77
  resolveProtectedGlobs,
74
78
  saveManifest,
75
79
  skillTargetDir
76
- } from "./chunk-NSSXSZLL.js";
80
+ } from "./chunk-7BEHUBEJ.js";
77
81
  import {
78
82
  KIT_VERSION,
79
83
  pinnedCliSpec
@@ -791,6 +795,8 @@ async function performInstall(options) {
791
795
  manifest: existing
792
796
  });
793
797
  try {
798
+ const stale = await detectStaleCli(registry.root, { warn: logger.warn });
799
+ if (stale && !options.allowStaleCli) throw new StaleCliError(stale);
794
800
  const draft = buildManifest({
795
801
  version: KIT_VERSION,
796
802
  profile: options.profile ?? existing?.profile ?? "default",
@@ -856,6 +862,17 @@ async function performInstall(options) {
856
862
  await registry.unlock?.();
857
863
  }
858
864
  }
865
+ var INSTALL_RERUN_FLAGS = [
866
+ "pack",
867
+ "claude",
868
+ "yes",
869
+ "force-root",
870
+ "cwd",
871
+ "registry",
872
+ "url",
873
+ "ref",
874
+ "refresh"
875
+ ];
859
876
  var installCommand = defineCommand({
860
877
  meta: {
861
878
  name: "install",
@@ -872,6 +889,11 @@ var installCommand = defineCommand({
872
889
  description: `Comma-separated L1 pack ids (e.g. cybersec,devops). Known: ${DOMAIN_PACK_IDS.join(", ")}`
873
890
  },
874
891
  ...NON_INTERACTIVE_ROOT_ARGS,
892
+ "allow-stale-cli": {
893
+ type: "boolean",
894
+ description: "Install even when this CLI is older than the registry it is syncing from; the manifest is then stamped with this CLI's version, not the registry's (factory/dev only)",
895
+ default: false
896
+ },
875
897
  claude: {
876
898
  type: "boolean",
877
899
  description: "Opt-in: generate .claude/commands/*.md thin pointer adapters for the installed .cursor/commands set, and merge a SessionStart context hook into .claude/settings.json (default install behavior is unchanged without this flag)",
@@ -926,7 +948,8 @@ ${err.recovery}
926
948
  url: args.url,
927
949
  ref: args.ref,
928
950
  refresh: args.refresh,
929
- claudeAdapters: args.claude
951
+ claudeAdapters: args.claude,
952
+ allowStaleCli: args["allow-stale-cli"]
930
953
  })
931
954
  );
932
955
  logApplyStats(result.stats);
@@ -941,6 +964,18 @@ ${result.claudeSessionStartInstructions}
941
964
  }
942
965
  if (result.claudeAdapterHint) logger.info(result.claudeAdapterHint);
943
966
  } catch (err) {
967
+ if (err instanceof StaleCliError) {
968
+ const profile = typeof args.profile === "string" && args.profile ? `${args.profile} ` : "";
969
+ const refusal = formatStaleCliRefusal({
970
+ command: "install",
971
+ stale: err.stale,
972
+ rerun: `${profile}${formatRerunFlags(args, INSTALL_RERUN_FLAGS)}`.trim()
973
+ });
974
+ logger.error(refusal.error);
975
+ console.error(refusal.recovery);
976
+ process.exitCode = 1;
977
+ return;
978
+ }
944
979
  if (err instanceof SkippedSymlinkError) {
945
980
  logApplyStats(err.stats);
946
981
  logger.error(err.message);