@dadado/agent-kit-cli 5.15.0 → 5.16.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 (71) hide show
  1. package/dashboard/dashboard-data.mjs +69 -65
  2. package/dashboard/lib/guards.d.mts +5 -0
  3. package/dashboard/lib/guards.mjs +31 -0
  4. package/dashboard/lib/identity-probe.mjs +56 -0
  5. package/dashboard/lib/pipeline-cache.mjs +58 -0
  6. package/dashboard/lib/processes.mjs +71 -0
  7. package/dashboard/serve.mjs +43 -1
  8. package/dashboard/start-broadcast.mjs +2 -12
  9. package/dashboard/start.mjs +2 -13
  10. package/dist/add-7UMSGVWC.js +150 -0
  11. package/dist/chunk-2IPXQFJE.js +253 -0
  12. package/dist/chunk-2YU2H7I6.js +42 -0
  13. package/dist/chunk-4IWG5CVE.js +214 -0
  14. package/dist/chunk-5OXPNVCF.js +106 -0
  15. package/dist/chunk-5VCOWTTP.js +6 -0
  16. package/dist/chunk-6QV2BFGA.js +341 -0
  17. package/dist/chunk-77V75A7O.js +39 -0
  18. package/dist/chunk-7HDQEK6T.js +26 -0
  19. package/dist/chunk-CBCW5R5J.js +484 -0
  20. package/dist/chunk-CGTE7DHN.js +410 -0
  21. package/dist/chunk-DE3LQFSJ.js +18 -0
  22. package/dist/chunk-F6C3GFKV.js +57 -0
  23. package/dist/chunk-HFUH3HVS.js +282 -0
  24. package/dist/chunk-HS7LVVLO.js +74 -0
  25. package/dist/chunk-IHROBTNM.js +135 -0
  26. package/dist/chunk-KD2MYBB6.js +213 -0
  27. package/dist/chunk-KI6ZHBPV.js +332 -0
  28. package/dist/chunk-MAPOQEA2.js +43 -0
  29. package/dist/chunk-NQ7IQ5XT.js +26 -0
  30. package/dist/chunk-OUQZC744.js +1315 -0
  31. package/dist/chunk-OZ4QV6LM.js +1078 -0
  32. package/dist/chunk-PCCQUWE5.js +817 -0
  33. package/dist/chunk-PNFF6OU3.js +273 -0
  34. package/dist/chunk-QTON2GQX.js +203 -0
  35. package/dist/chunk-TFZ2JUXH.js +1081 -0
  36. package/dist/chunk-VGZBARQC.js +318 -0
  37. package/dist/chunk-VS2JD2XC.js +1453 -0
  38. package/dist/chunk-VY7MTPJ2.js +205 -0
  39. package/dist/chunk-WW3YZKHW.js +165 -0
  40. package/dist/chunk-XWPO3VYQ.js +53 -0
  41. package/dist/chunk-XZZAVHH4.js +503 -0
  42. package/dist/chunk-YGBBHKBE.js +82 -0
  43. package/dist/chunk-ZB43YMHW.js +20 -0
  44. package/dist/chunk-ZCTSUQRR.js +874 -0
  45. package/dist/chunk-ZXKZBTXE.js +17 -0
  46. package/dist/contribute-YKK6YCSI.js +367 -0
  47. package/dist/cursor-awareness-KTL2RGKD.js +77 -0
  48. package/dist/dashboard-YSNUGBFY.js +21 -0
  49. package/dist/dashboard-broadcast-M4CMW7RX.js +119 -0
  50. package/dist/diff-YTR7VOAN.js +74 -0
  51. package/dist/doctor-TA2FWREU.js +497 -0
  52. package/dist/dogfood-KKFVRWT6.js +366 -0
  53. package/dist/guard-EHXF76ID.js +530 -0
  54. package/dist/handoff-3UI6VKVG.js +302 -0
  55. package/dist/hook-MUV6Y7UW.js +1074 -0
  56. package/dist/index.js +62 -14068
  57. package/dist/init-TTTKGC4C.js +127 -0
  58. package/dist/install-ZMFJBPOI.js +34 -0
  59. package/dist/mission-control-LJACEVVN.js +89 -0
  60. package/dist/monitors-QV2IS3MP.js +176 -0
  61. package/dist/plan-index-JMC7Z4DW.js +44 -0
  62. package/dist/public-inbound-radar-WP3XF7GS.js +68 -0
  63. package/dist/remote-issues-SZ4HDQL5.js +44 -0
  64. package/dist/run-I3BFGULT.js +243 -0
  65. package/dist/run-plan-FO7CL4M3.js +118 -0
  66. package/dist/scan-NI2SWJ2E.js +33 -0
  67. package/dist/setup-global-JUVMJXJ5.js +340 -0
  68. package/dist/status-MVCUNCWX.js +138 -0
  69. package/dist/update-Q4EBIRUB.js +260 -0
  70. package/dist/validate-V2CW7J4B.js +201 -0
  71. package/package.json +1 -1
@@ -0,0 +1,260 @@
1
+ import {
2
+ NON_INTERACTIVE_ROOT_ARGS,
3
+ syncFromManifest
4
+ } from "./chunk-5OXPNVCF.js";
5
+ import {
6
+ formatSkippedSymlinks,
7
+ logApplyStats
8
+ } from "./chunk-HS7LVVLO.js";
9
+ import {
10
+ REGISTRY_CLI_ARGS,
11
+ resolveRegistryFromCli
12
+ } from "./chunk-XWPO3VYQ.js";
13
+ import {
14
+ CLAUDE_SETTINGS_REL,
15
+ formatClaudeSettingsDrift,
16
+ planClaudeSettingsDrift,
17
+ writeClaudeSessionStartHook
18
+ } from "./chunk-CGTE7DHN.js";
19
+ import "./chunk-MAPOQEA2.js";
20
+ import {
21
+ withCliProgress
22
+ } from "./chunk-QTON2GQX.js";
23
+ import {
24
+ logger
25
+ } from "./chunk-ZB43YMHW.js";
26
+ import {
27
+ RootRefusedError,
28
+ confirmProjectRoot,
29
+ isNonInteractive,
30
+ syncPathCliToRuntime
31
+ } from "./chunk-VGZBARQC.js";
32
+ import "./chunk-4IWG5CVE.js";
33
+ import {
34
+ checkForUpdates,
35
+ compareSemver,
36
+ normalizeSemver,
37
+ readLocalKitVersion
38
+ } from "./chunk-XZZAVHH4.js";
39
+ import "./chunk-NQ7IQ5XT.js";
40
+ import "./chunk-YGBBHKBE.js";
41
+ import "./chunk-6QV2BFGA.js";
42
+ import {
43
+ buildManifest,
44
+ isProtectedPath,
45
+ loadAgentKitManifest,
46
+ resolveProtectedGlobs,
47
+ saveManifest,
48
+ seedManagedHashLedger
49
+ } from "./chunk-VS2JD2XC.js";
50
+ import "./chunk-5VCOWTTP.js";
51
+ import {
52
+ KIT_PACKAGE_SPEC,
53
+ KIT_VERSION
54
+ } from "./chunk-7HDQEK6T.js";
55
+ import "./chunk-77V75A7O.js";
56
+
57
+ // src/commands/update.ts
58
+ import { defineCommand } from "citty";
59
+ var updateCommand = defineCommand({
60
+ meta: {
61
+ name: "update",
62
+ description: "Re-apply L0/packs/skills from the registry (never overwrites L3). --check = notify-only."
63
+ },
64
+ args: {
65
+ cwd: {
66
+ type: "string",
67
+ default: process.cwd()
68
+ },
69
+ check: {
70
+ type: "boolean",
71
+ description: "Check-only: compare installed version to the resolved registry (public tags, or --registry local checkout); never apply L0 writes",
72
+ default: false
73
+ },
74
+ json: {
75
+ type: "boolean",
76
+ description: "Print machine-readable JSON (with --check)",
77
+ default: false
78
+ },
79
+ "respect-prefs": {
80
+ type: "boolean",
81
+ description: "Honor updateCheck.enabled and intervalDays from .cursor/context/config.json (hooks)",
82
+ default: false
83
+ },
84
+ stamp: {
85
+ type: "boolean",
86
+ description: "Persist updateCheck.lastCheckedAt after a network check",
87
+ default: false
88
+ },
89
+ "seed-overlay": {
90
+ type: "boolean",
91
+ description: "Seed the managed-hash ledger from current local overlay files before applying (factory/dogfood only; consumers should not use this)",
92
+ default: false
93
+ },
94
+ "allow-stale-cli": {
95
+ type: "boolean",
96
+ description: "Apply 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)",
97
+ default: false
98
+ },
99
+ claude: {
100
+ type: "boolean",
101
+ description: "Also apply the ledger-aware Claude settings merge (.claude/settings.json + ledger) with install --claude authority; operator opt-in, never from hooks or plan-loop",
102
+ default: false
103
+ },
104
+ ...NON_INTERACTIVE_ROOT_ARGS,
105
+ ...REGISTRY_CLI_ARGS
106
+ },
107
+ async run({ args }) {
108
+ if (args.check) {
109
+ const result = await checkForUpdates(args.cwd, {
110
+ respectPrefs: Boolean(args["respect-prefs"]),
111
+ stamp: Boolean(args.stamp),
112
+ publicRegistryUrl: typeof args.url === "string" && args.url ? args.url : void 0,
113
+ registryPath: typeof args.registry === "string" && args.registry ? args.registry : void 0
114
+ });
115
+ if (args.json) {
116
+ console.log(JSON.stringify(result, null, 2));
117
+ } else {
118
+ const line = `[${result.status}] ${result.message}`;
119
+ if (result.status === "error") logger.error(line);
120
+ else if (result.status === "update-available") logger.warn(line);
121
+ else if (result.status.startsWith("skipped-")) logger.warn(line);
122
+ else logger.info(line);
123
+ }
124
+ if (result.status === "error") process.exitCode = 2;
125
+ return;
126
+ }
127
+ const nonInteractive = args.yes || isNonInteractive();
128
+ let projectRoot;
129
+ try {
130
+ projectRoot = await confirmProjectRoot(args.cwd, {
131
+ nonInteractive,
132
+ command: "update",
133
+ forceRoot: args["force-root"]
134
+ });
135
+ } catch (err) {
136
+ if (err instanceof RootRefusedError) {
137
+ logger.error(err.message);
138
+ if (err.recovery) console.error(`
139
+ ${err.recovery}
140
+ `);
141
+ process.exitCode = 1;
142
+ return;
143
+ }
144
+ throw err;
145
+ }
146
+ const existing = await loadAgentKitManifest(projectRoot, { onWarning: logger.warn });
147
+ if (!existing) {
148
+ logger.warn("No .cursor/agent-kit.json \u2014 run agent-kit install first.");
149
+ return;
150
+ }
151
+ const registry = await resolveRegistryFromCli({
152
+ cwd: projectRoot,
153
+ registry: args.registry,
154
+ url: args.url,
155
+ ref: args.ref,
156
+ refresh: args.refresh,
157
+ manifest: existing
158
+ });
159
+ try {
160
+ logger.info(`Registry: ${registry.root} (${registry.source})`);
161
+ const registryVersionRaw = await readLocalKitVersion(registry.root);
162
+ const registryVersion = registryVersionRaw ? normalizeSemver(registryVersionRaw) : null;
163
+ const cliVersion = normalizeSemver(KIT_VERSION);
164
+ if (!registryVersion) {
165
+ logger.warn(
166
+ "Could not read a version from the registry checkout - skipping the CLI freshness check."
167
+ );
168
+ } else if (cliVersion && compareSemver(cliVersion, registryVersion) < 0 && !args["allow-stale-cli"]) {
169
+ logger.error(
170
+ `This CLI is v${cliVersion}, older than the registry it would apply (v${registryVersion}).`
171
+ );
172
+ console.error(
173
+ [
174
+ "",
175
+ "`agent-kit update` syncs registry content but stamps .cursor/agent-kit.json with the",
176
+ `version of the CLI running it, so applying now would write v${cliVersion} again, not v${registryVersion}.`,
177
+ "",
178
+ "Upgrade the binary first, then re-run:",
179
+ ` npm i -g ${KIT_PACKAGE_SPEC}@${registryVersion}`,
180
+ " agent-kit update",
181
+ "",
182
+ `If npm has no ${registryVersion} yet, the release is still mid-publish`,
183
+ "(content sync and npm publish run in parallel) - retry shortly.",
184
+ "",
185
+ "Factory/dev checkouts that intend to apply newer content with an older",
186
+ "binary can pass --allow-stale-cli.",
187
+ ""
188
+ ].join("\n")
189
+ );
190
+ process.exitCode = 1;
191
+ return;
192
+ }
193
+ const next = buildManifest({
194
+ version: KIT_VERSION,
195
+ profile: existing.profile,
196
+ packs: existing.packs,
197
+ skills: existing.skills,
198
+ protected: existing.protected,
199
+ // Restamp generatorVersion with the CLI that ran this apply so the two
200
+ // version fields in the manifest stop disagreeing after an update. The
201
+ // personalization result file itself is not regenerated here.
202
+ personalization: existing.personalization ? { ...existing.personalization, generatorVersion: KIT_VERSION } : void 0,
203
+ registryUrl: registry.url ?? existing.registry?.url,
204
+ registryRef: registry.ref ?? existing.registry?.ref
205
+ });
206
+ if (existing.overrides?.length) next.overrides = existing.overrides;
207
+ if (existing.unknownFields) next.unknownFields = existing.unknownFields;
208
+ if (next.version === existing.version && existing.installedAt) {
209
+ next.installedAt = existing.installedAt;
210
+ }
211
+ if (args["seed-overlay"]) {
212
+ await seedManagedHashLedger(projectRoot);
213
+ logger.info("Seeded managed-hash ledger from current local overlay files.");
214
+ }
215
+ const stats = await withCliProgress(
216
+ "update",
217
+ () => syncFromManifest(registry.root, projectRoot, next)
218
+ );
219
+ if (stats.skippedSymlink.length > 0) {
220
+ logApplyStats(stats);
221
+ logger.error(formatSkippedSymlinks(stats.skippedSymlink));
222
+ process.exitCode = 1;
223
+ return;
224
+ }
225
+ if (args.claude) {
226
+ const claude = await writeClaudeSessionStartHook(projectRoot, { authorized: true });
227
+ if (claude.status === "skipped-symlink") {
228
+ logApplyStats(stats);
229
+ logger.error(
230
+ `Claude settings not written: ${CLAUDE_SETTINGS_REL}, .claude/ or the ledger resolves outside the project (symlink). Nothing was changed there.`
231
+ );
232
+ process.exitCode = 1;
233
+ return;
234
+ }
235
+ if (claude.status === "unavailable") {
236
+ logger.warn(claude.instructions ?? `${CLAUDE_SETTINGS_REL} could not be merged.`);
237
+ } else {
238
+ console.log(`Claude settings ${claude.status}: ${claude.relativePath}`);
239
+ }
240
+ } else {
241
+ const drift = await planClaudeSettingsDrift(projectRoot);
242
+ if (drift) {
243
+ const protectedPath = isProtectedPath(CLAUDE_SETTINGS_REL, resolveProtectedGlobs(next));
244
+ for (const line of formatClaudeSettingsDrift(drift, { protectedPath })) console.log(line);
245
+ }
246
+ }
247
+ await saveManifest(projectRoot, next);
248
+ logApplyStats(stats);
249
+ const transition = next.version === existing.version ? `unchanged at v${next.version}` : `v${existing.version} \u2192 v${next.version}`;
250
+ logger.success(`Update complete: ${transition} (L3 protected paths left untouched).`);
251
+ const sync = await syncPathCliToRuntime({ runtimeVersion: KIT_VERSION });
252
+ for (const line of sync.lines) console.log(line);
253
+ } finally {
254
+ await registry.unlock?.();
255
+ }
256
+ }
257
+ });
258
+ export {
259
+ updateCommand
260
+ };
@@ -0,0 +1,201 @@
1
+ import {
2
+ validateHandoffText
3
+ } from "./chunk-2YU2H7I6.js";
4
+ import {
5
+ readStdinJson
6
+ } from "./chunk-DE3LQFSJ.js";
7
+ import {
8
+ checkHandoffGrowth
9
+ } from "./chunk-IHROBTNM.js";
10
+
11
+ // src/commands/validate.ts
12
+ import { readFile } from "fs/promises";
13
+ import path from "path";
14
+ import { defineCommand } from "citty";
15
+
16
+ // src/invariants/plan-schema.ts
17
+ var CITE = "agent-kit validate plan (.cursor/context/templates/plan.md)";
18
+ function validatePlanFrontmatterText(text) {
19
+ const warnings = [];
20
+ const match = text.match(/^---\n([\s\S]*?)\n---/);
21
+ if (!match?.[1]) {
22
+ warnings.push({
23
+ code: "missing-frontmatter",
24
+ message: "Plan file has no YAML frontmatter block.",
25
+ cite: CITE
26
+ });
27
+ return warnings;
28
+ }
29
+ const block = match[1];
30
+ if (!/^todos:\s*$/m.test(block) && !/^todos:\s*\[/m.test(block)) {
31
+ if (!/^todos:/m.test(block)) {
32
+ warnings.push({
33
+ code: "missing-todos",
34
+ message: "Plan frontmatter has no `todos:` key.",
35
+ cite: CITE
36
+ });
37
+ }
38
+ }
39
+ if (!/^name:\s*\S+/m.test(block)) {
40
+ warnings.push({
41
+ code: "missing-name",
42
+ message: "Plan frontmatter has no `name:` key.",
43
+ cite: CITE
44
+ });
45
+ }
46
+ const hasTodoItem = /^\s*- id:\s*\S+/m.test(block);
47
+ if (/^todos:/m.test(block) && !hasTodoItem && !/^todos:\s*\[\s*\]/m.test(block)) {
48
+ warnings.push({
49
+ code: "empty-todos",
50
+ message: "Plan frontmatter `todos:` has no `- id:` items.",
51
+ cite: CITE
52
+ });
53
+ }
54
+ return warnings;
55
+ }
56
+
57
+ // src/commands/validate.ts
58
+ async function resolveEditedPath(cwd, explicit) {
59
+ if (explicit) {
60
+ const filePath2 = path.resolve(cwd, explicit);
61
+ try {
62
+ return { filePath: filePath2, content: await readFile(filePath2, "utf8") };
63
+ } catch {
64
+ return null;
65
+ }
66
+ }
67
+ const payload = await readStdinJson();
68
+ const rel = typeof payload.file_path === "string" && payload.file_path || typeof payload.path === "string" && payload.path || typeof payload.file === "string" && payload.file || "";
69
+ if (!rel) return null;
70
+ const filePath = path.isAbsolute(rel) ? rel : path.resolve(cwd, rel);
71
+ try {
72
+ return { filePath, content: await readFile(filePath, "utf8") };
73
+ } catch {
74
+ return null;
75
+ }
76
+ }
77
+ function isHandoffPath(filePath) {
78
+ return filePath.replace(/\\/g, "/").endsWith(".cursor/HANDOFF.md");
79
+ }
80
+ function isPlanPath(filePath) {
81
+ const norm = filePath.replace(/\\/g, "/");
82
+ return norm.includes("/.cursor/plans/") && norm.endsWith(".plan.md");
83
+ }
84
+ var validateCommand = defineCommand({
85
+ meta: {
86
+ name: "validate",
87
+ description: "Advisory validators for HANDOFF / plan frontmatter (hook adapter)."
88
+ },
89
+ subCommands: {
90
+ handoff: defineCommand({
91
+ meta: { name: "handoff", description: "Validate HANDOFF machine fields" },
92
+ args: {
93
+ cwd: { type: "string", default: process.cwd() },
94
+ file: { type: "string", description: "Path to HANDOFF.md" },
95
+ json: { type: "boolean", default: true }
96
+ },
97
+ async run({ args }) {
98
+ const cwd = typeof args.cwd === "string" ? args.cwd : process.cwd();
99
+ const fileArg = typeof args.file === "string" ? args.file : void 0;
100
+ const filePath = fileArg ? path.resolve(cwd, fileArg) : path.join(path.resolve(cwd), ".cursor", "HANDOFF.md");
101
+ let content = "";
102
+ try {
103
+ content = await readFile(filePath, "utf8");
104
+ } catch {
105
+ console.log(JSON.stringify({ ok: true, warnings: [], note: "file missing" }));
106
+ return;
107
+ }
108
+ const warnings = [
109
+ ...validateHandoffText(content),
110
+ ...checkHandoffGrowth(content).map((w) => ({
111
+ ...w,
112
+ cite: "agent-kit handoff --prune (see .cursor/context/templates/handoff.md)"
113
+ }))
114
+ ];
115
+ console.log(JSON.stringify({ ok: warnings.length === 0, warnings }));
116
+ }
117
+ }),
118
+ plan: defineCommand({
119
+ meta: { name: "plan", description: "Validate plan frontmatter" },
120
+ args: {
121
+ cwd: { type: "string", default: process.cwd() },
122
+ file: { type: "string", description: "Path to *.plan.md" },
123
+ json: { type: "boolean", default: true }
124
+ },
125
+ async run({ args }) {
126
+ const cwd = typeof args.cwd === "string" ? args.cwd : process.cwd();
127
+ const fileArg = typeof args.file === "string" ? args.file : void 0;
128
+ if (!fileArg) {
129
+ console.log(JSON.stringify({ ok: false, warnings: [{ message: "file required" }] }));
130
+ process.exitCode = 2;
131
+ return;
132
+ }
133
+ const filePath = path.resolve(cwd, fileArg);
134
+ let content = "";
135
+ try {
136
+ content = await readFile(filePath, "utf8");
137
+ } catch {
138
+ console.log(JSON.stringify({ ok: true, warnings: [], note: "file missing" }));
139
+ return;
140
+ }
141
+ const warnings = validatePlanFrontmatterText(content);
142
+ console.log(JSON.stringify({ ok: warnings.length === 0, warnings }));
143
+ }
144
+ }),
145
+ "after-edit": defineCommand({
146
+ meta: {
147
+ name: "after-edit",
148
+ description: "Advisory afterFileEdit: annotate HANDOFF/plan issues (never block)"
149
+ },
150
+ args: {
151
+ cwd: { type: "string", default: process.cwd() }
152
+ },
153
+ async run({ args }) {
154
+ const cwd = typeof args.cwd === "string" ? args.cwd : process.cwd();
155
+ const resolved = await resolveEditedPath(path.resolve(cwd));
156
+ if (!resolved) {
157
+ console.log(JSON.stringify({}));
158
+ return;
159
+ }
160
+ const { filePath, content } = resolved;
161
+ if (isHandoffPath(filePath)) {
162
+ const warnings = [
163
+ ...validateHandoffText(content).map((w) => w.message),
164
+ ...checkHandoffGrowth(content).map((w) => w.message)
165
+ ];
166
+ if (!warnings.length) {
167
+ console.log(JSON.stringify({}));
168
+ return;
169
+ }
170
+ const msg = warnings.join(" ");
171
+ console.log(
172
+ JSON.stringify({
173
+ user_message: msg,
174
+ agent_message: `${msg} Cite: agent-kit validate handoff.`
175
+ })
176
+ );
177
+ return;
178
+ }
179
+ if (isPlanPath(filePath)) {
180
+ const warnings = validatePlanFrontmatterText(content);
181
+ if (!warnings.length) {
182
+ console.log(JSON.stringify({}));
183
+ return;
184
+ }
185
+ const msg = warnings.map((w) => w.message).join(" ");
186
+ console.log(
187
+ JSON.stringify({
188
+ user_message: msg,
189
+ agent_message: `${msg} Cite: agent-kit validate plan.`
190
+ })
191
+ );
192
+ return;
193
+ }
194
+ console.log(JSON.stringify({}));
195
+ }
196
+ })
197
+ }
198
+ });
199
+ export {
200
+ validateCommand
201
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dadado/agent-kit-cli",
3
- "version": "5.15.0",
3
+ "version": "5.16.0",
4
4
  "description": "Agent Kit CLI: HITL framework install and tooling for AI-assisted IDEs (rules, skills, plan/handoff, context).",
5
5
  "license": "PolyForm-Noncommercial-1.0.0",
6
6
  "type": "module",