@cursor/july 0.1.3 → 0.1.4

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 (134) hide show
  1. package/dist/bin/agent-serve.d.ts +1 -1
  2. package/dist/bin/agent-serve.js +40 -16
  3. package/dist/channels/slack/log.d.ts +1 -1
  4. package/dist/channels/slack/log.d.ts.map +1 -1
  5. package/dist/channels/slack/log.js +4 -5
  6. package/dist/channels/slack/setup.js +1 -1
  7. package/dist/channels/slack/socket-mode.d.ts.map +1 -1
  8. package/dist/channels/slack/socket-mode.js +10 -9
  9. package/dist/docs/404.html +2 -2
  10. package/dist/docs/ab.html +3 -3
  11. package/dist/docs/assets/{app.BR0RbIdx.js → app.DF-Yx4OP.js} +1 -1
  12. package/dist/docs/assets/chunks/@localSearchIndexroot.0XrheBv2.js +1 -0
  13. package/dist/docs/assets/chunks/{VPLocalSearchBox.qjsVTneI.js → VPLocalSearchBox.DSeJSudL.js} +1 -1
  14. package/dist/docs/assets/chunks/{theme.2Kg8jIp_.js → theme.DZVLTXOC.js} +2 -2
  15. package/dist/docs/assets/{index.md.m81y7TY7.js → index.md.Cylk70gg.js} +1 -1
  16. package/dist/docs/building-with-agents.html +3 -3
  17. package/dist/docs/concepts.html +3 -3
  18. package/dist/docs/deployment.html +3 -3
  19. package/dist/docs/evals.html +3 -3
  20. package/dist/docs/guides/agent-to-agent.html +3 -3
  21. package/dist/docs/guides/cloud-runtime.html +3 -3
  22. package/dist/docs/guides/github.html +3 -3
  23. package/dist/docs/guides/human-in-the-loop.html +3 -3
  24. package/dist/docs/guides/slack.html +3 -3
  25. package/dist/docs/guides/webhooks.html +3 -3
  26. package/dist/docs/hashmap.json +1 -1
  27. package/dist/docs/hillclimbing.html +3 -3
  28. package/dist/docs/index.html +5 -5
  29. package/dist/docs/quickstart.html +3 -3
  30. package/dist/docs/reference/agent-config.html +3 -3
  31. package/dist/docs/reference/channels.html +3 -3
  32. package/dist/docs/reference/cli.html +3 -3
  33. package/dist/docs/reference/connections.html +3 -3
  34. package/dist/docs/reference/hooks.html +3 -3
  35. package/dist/docs/reference/http-api.html +3 -3
  36. package/dist/docs/reference/instructions.html +3 -3
  37. package/dist/docs/reference/playground.html +3 -3
  38. package/dist/docs/reference/project-layout.html +3 -3
  39. package/dist/docs/reference/schedules.html +3 -3
  40. package/dist/docs/reference/sessions.html +3 -3
  41. package/dist/docs/reference/skills.html +3 -3
  42. package/dist/docs/reference/subagents.html +3 -3
  43. package/dist/docs/reference/tools.html +3 -3
  44. package/dist/docs/scaffolding-agents.html +3 -3
  45. package/dist/docs/storage.html +3 -3
  46. package/dist/docs/troubleshooting.html +3 -3
  47. package/dist/internal/ab-collector.js +3 -3
  48. package/dist/internal/ab-fold.js +1 -1
  49. package/dist/internal/cli-ax.d.ts +13 -5
  50. package/dist/internal/cli-ax.d.ts.map +1 -1
  51. package/dist/internal/cli-ax.js +41 -15
  52. package/dist/internal/cli-github.js +13 -13
  53. package/dist/internal/cursor/account-mcp.js +3 -3
  54. package/dist/internal/cursor/backend-client.js +1 -1
  55. package/dist/internal/cursor/credentials.d.ts +5 -3
  56. package/dist/internal/cursor/credentials.d.ts.map +1 -1
  57. package/dist/internal/cursor/credentials.js +9 -6
  58. package/dist/internal/cursor/github-credentials.js +3 -3
  59. package/dist/internal/cursor-event-relay.js +1 -1
  60. package/dist/internal/cursor-relay-core.d.ts +1 -1
  61. package/dist/internal/cursor-relay-core.d.ts.map +1 -1
  62. package/dist/internal/cursor-relay-core.js +2 -1
  63. package/dist/internal/cursor-slack-relay.js +1 -1
  64. package/dist/internal/distribution.d.ts +7 -0
  65. package/dist/internal/distribution.d.ts.map +1 -1
  66. package/dist/internal/distribution.js +7 -0
  67. package/dist/internal/docs-site.js +3 -3
  68. package/dist/internal/eval-run-store.d.ts.map +1 -1
  69. package/dist/internal/eval-run-store.js +8 -8
  70. package/dist/internal/github-fanout.js +2 -2
  71. package/dist/internal/host-platforms.js +5 -5
  72. package/dist/internal/mcp-endpoint.d.ts.map +1 -1
  73. package/dist/internal/mcp-endpoint.js +1 -1
  74. package/dist/internal/playground/toolchain.js +6 -6
  75. package/dist/internal/reminder-runner.d.ts.map +1 -1
  76. package/dist/internal/reminder-runner.js +11 -11
  77. package/dist/internal/resolve-prod-target.d.ts +2 -0
  78. package/dist/internal/resolve-prod-target.d.ts.map +1 -1
  79. package/dist/internal/resolve-prod-target.js +44 -21
  80. package/dist/internal/resolved-connections.js +5 -5
  81. package/dist/internal/schedule-runner.js +1 -1
  82. package/dist/internal/server.js +14 -14
  83. package/dist/internal/session-engine.d.ts.map +1 -1
  84. package/dist/internal/session-engine.js +13 -13
  85. package/dist/internal/sessions-client.d.ts +13 -0
  86. package/dist/internal/sessions-client.d.ts.map +1 -1
  87. package/dist/internal/sessions-client.js +25 -0
  88. package/dist/internal/storage-coordinator.js +6 -6
  89. package/dist/internal/update-check.d.ts +93 -0
  90. package/dist/internal/update-check.d.ts.map +1 -0
  91. package/dist/internal/update-check.js +431 -0
  92. package/dist/playground/assets/{index-D-vo2lV_.css → index-Ct_Usdm8.css} +1 -1
  93. package/dist/playground/assets/index-Dsyb-Vaj.js +319 -0
  94. package/dist/playground/index.html +2 -2
  95. package/dist/types.d.ts +3 -1
  96. package/dist/types.d.ts.map +1 -1
  97. package/docs/README.md +0 -1
  98. package/package.json +2 -1
  99. package/skills/setup-slack/SKILL.md +1 -1
  100. package/src/bin/agent-serve.ts +42 -16
  101. package/src/channels/slack/log.ts +5 -5
  102. package/src/channels/slack/setup.ts +1 -1
  103. package/src/channels/slack/socket-mode.ts +11 -9
  104. package/src/internal/ab-collector.ts +3 -3
  105. package/src/internal/ab-fold.ts +1 -1
  106. package/src/internal/cli-ax.ts +55 -16
  107. package/src/internal/cli-github.ts +13 -15
  108. package/src/internal/cursor/account-mcp.ts +3 -3
  109. package/src/internal/cursor/backend-client.ts +1 -1
  110. package/src/internal/cursor/credentials.ts +12 -7
  111. package/src/internal/cursor/github-credentials.ts +3 -3
  112. package/src/internal/cursor-event-relay.ts +1 -1
  113. package/src/internal/cursor-relay-core.ts +4 -2
  114. package/src/internal/cursor-slack-relay.ts +1 -1
  115. package/src/internal/distribution.ts +8 -0
  116. package/src/internal/docs-site.ts +3 -3
  117. package/src/internal/eval-run-store.ts +8 -10
  118. package/src/internal/github-fanout.ts +2 -2
  119. package/src/internal/host-platforms.ts +5 -5
  120. package/src/internal/mcp-endpoint.ts +1 -3
  121. package/src/internal/playground/toolchain.ts +6 -6
  122. package/src/internal/reminder-runner.ts +11 -17
  123. package/src/internal/resolve-prod-target.ts +55 -23
  124. package/src/internal/resolved-connections.ts +5 -5
  125. package/src/internal/schedule-runner.ts +1 -1
  126. package/src/internal/server.ts +14 -14
  127. package/src/internal/session-engine.ts +13 -15
  128. package/src/internal/sessions-client.ts +34 -0
  129. package/src/internal/storage-coordinator.ts +6 -6
  130. package/src/internal/update-check.ts +552 -0
  131. package/src/types.ts +3 -1
  132. package/dist/docs/assets/chunks/@localSearchIndexroot.DtIOQzGj.js +0 -1
  133. package/dist/playground/assets/index-x60b9q2j.js +0 -312
  134. /package/dist/docs/assets/{index.md.m81y7TY7.lean.js → index.md.Cylk70gg.lean.js} +0 -0
@@ -252,7 +252,7 @@ export class StorageCoordinator {
252
252
  // Index entry without its record (e.g. the record write was shed
253
253
  // under at-most-once). The session is unrecoverable; treat as a miss
254
254
  // so the conversation can continue rather than failing forever.
255
- this.logger(`[agent-serve] storage continuation entry points at missing session ${sessionId}; treating as a miss`);
255
+ this.logger(`[agentkit] storage continuation entry points at missing session ${sessionId}; treating as a miss`);
256
256
  return undefined;
257
257
  }
258
258
  // The sink must answer for the exact key it was asked about — a
@@ -383,7 +383,7 @@ export class StorageCoordinator {
383
383
  return value == null ? undefined : value;
384
384
  }
385
385
  catch (error) {
386
- this.logger(`[agent-serve] storage get(ab-snapshot) failed: ${describeError(error)}`);
386
+ this.logger(`[agentkit] storage get(ab-snapshot) failed: ${describeError(error)}`);
387
387
  return undefined;
388
388
  }
389
389
  });
@@ -415,7 +415,7 @@ export class StorageCoordinator {
415
415
  ]);
416
416
  clearTimeout(timer);
417
417
  if (!drained) {
418
- this.logger(`[agent-serve] storage shutdown drain timed out after ${CLOSE_DRAIN_TIMEOUT_MS}ms with ${this.pending} write(s) undelivered`);
418
+ this.logger(`[agentkit] storage shutdown drain timed out after ${CLOSE_DRAIN_TIMEOUT_MS}ms with ${this.pending} write(s) undelivered`);
419
419
  }
420
420
  });
421
421
  }
@@ -455,7 +455,7 @@ export class StorageCoordinator {
455
455
  return Array.isArray(entries) ? entries : [];
456
456
  }
457
457
  catch (error) {
458
- this.logger(`[agent-serve] storage list(${prefix}) failed: ${describeError(error)}`);
458
+ this.logger(`[agentkit] storage list(${prefix}) failed: ${describeError(error)}`);
459
459
  return [];
460
460
  }
461
461
  });
@@ -467,7 +467,7 @@ export class StorageCoordinator {
467
467
  if (this.pending + ops.length > MAX_PENDING_OPS) {
468
468
  this.dropped += ops.length;
469
469
  if (this.dropped <= ops.length || this.dropped % 1000 < ops.length) {
470
- this.logger(`[agent-serve] storage queue full (${MAX_PENDING_OPS} pending writes); dropped ${this.dropped} write(s) so far — the sink is too slow for the traffic`);
470
+ this.logger(`[agentkit] storage queue full (${MAX_PENDING_OPS} pending writes); dropped ${this.dropped} write(s) so far — the sink is too slow for the traffic`);
471
471
  }
472
472
  return;
473
473
  }
@@ -485,7 +485,7 @@ export class StorageCoordinator {
485
485
  }
486
486
  }
487
487
  catch (error) {
488
- this.logger(`[agent-serve] storage ${op.op}(${op.key}) failed: ${describeError(error)}`);
488
+ this.logger(`[agentkit] storage ${op.op}(${op.key}) failed: ${describeError(error)}`);
489
489
  }
490
490
  finally {
491
491
  this.pending -= 1;
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Outdated-version warning + `agentkit update`.
3
+ *
4
+ * Every CLI run of a published install compares its own version against the
5
+ * npm registry's `latest` dist-tag and warns on stderr when behind. The
6
+ * registry lookup is cached under the config dir
7
+ * (`~/.config/agent-serve/update-check.json`) so most runs never touch the
8
+ * network; a stale cache refreshes inline under a short timeout, and any
9
+ * network failure is silent (the warning is best-effort, never a blocker).
10
+ *
11
+ * `agentkit update` re-runs the lookup fresh, figures out how this copy was
12
+ * installed (global npm/pnpm/yarn/bun, or a project dependency), and runs the
13
+ * matching install command.
14
+ */
15
+ import { z } from "zod";
16
+ /**
17
+ * Semver-style ordering: negative when `a < b`, 0 when equal, positive when
18
+ * `a > b`. Unparseable versions compare equal (never warn on garbage).
19
+ */
20
+ export declare function compareVersions(a: string, b: string): number;
21
+ /**
22
+ * Latest published version of the package, from the registry's `latest`
23
+ * dist-tag. Returns undefined on any failure (offline, 404 pre-publish, …).
24
+ */
25
+ export declare function fetchLatestPublishedVersion(options?: {
26
+ fetchImpl?: typeof fetch;
27
+ timeoutMs?: number;
28
+ packageName?: string;
29
+ }): Promise<string | undefined>;
30
+ declare const cacheSchema: z.ZodObject<{
31
+ checkedAt: z.ZodNumber;
32
+ latestVersion: z.ZodOptional<z.ZodString>;
33
+ }, "strip">;
34
+ export type UpdateCheckCache = z.infer<typeof cacheSchema>;
35
+ export declare function updateCheckCachePath(configDir?: string): string;
36
+ export declare function readUpdateCheckCache(configDir?: string): Promise<UpdateCheckCache | undefined>;
37
+ export declare function writeUpdateCheckCache(cache: UpdateCheckCache, configDir?: string): Promise<void>;
38
+ export interface WarnIfOutdatedOptions {
39
+ /** Defaults to the running package's own version. */
40
+ currentVersion?: string;
41
+ /** Test seam; defaults to the shared config dir. */
42
+ configDir?: string;
43
+ fetchImpl?: typeof fetch;
44
+ /** Test seam; defaults to Date.now(). */
45
+ now?: number;
46
+ env?: NodeJS.ProcessEnv;
47
+ /** Defaults to process.stderr.write. */
48
+ err?: (text: string) => void;
49
+ /** Skip the source-checkout guard (tests exercise the full path). */
50
+ force?: boolean;
51
+ }
52
+ /**
53
+ * Print an outdated-version warning to stderr when a newer release exists.
54
+ *
55
+ * Never throws and never blocks longer than {@link WARN_FETCH_TIMEOUT_MS}.
56
+ * Suppressed on source-checkout runs (there is no installed copy to update),
57
+ * in CI, and via NO_UPDATE_NOTIFIER / AGENT_SERVE_NO_UPDATE_CHECK.
58
+ */
59
+ export declare function warnIfOutdated(options?: WarnIfOutdatedOptions): Promise<void>;
60
+ export interface UpdateCommand {
61
+ cmd: string;
62
+ args: string[];
63
+ /** Working directory for local project installs. */
64
+ cwd?: string;
65
+ /** One-line human description of what will run and why. */
66
+ reason: string;
67
+ }
68
+ /**
69
+ * Figure out how the running copy was installed and which command upgrades
70
+ * it. Detection is path-shape based (global stores have recognizable
71
+ * layouts), then falls back to walking up to the project that declares the
72
+ * dependency. Returns undefined for layouts we cannot safely upgrade
73
+ * (npx cache, unrecognized stores).
74
+ */
75
+ export declare function detectUpdateCommand(args: {
76
+ packageRoot: string;
77
+ packageName?: string;
78
+ }): Promise<UpdateCommand | undefined>;
79
+ export interface UpdateCliOptions {
80
+ /** Test seams. */
81
+ fetchImpl?: typeof fetch;
82
+ currentVersion?: string;
83
+ packageRoot?: string;
84
+ configDir?: string;
85
+ runCommand?: (command: UpdateCommand) => Promise<number>;
86
+ compiled?: boolean;
87
+ out?: (text: string) => void;
88
+ err?: (text: string) => void;
89
+ }
90
+ /** `agentkit update` — upgrade this install to the latest published version. */
91
+ export declare function cmdUpdate(options?: UpdateCliOptions): Promise<number>;
92
+ export {};
93
+ //# sourceMappingURL=update-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../../src/internal/update-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,431 @@
1
+ /**
2
+ * Outdated-version warning + `agentkit update`.
3
+ *
4
+ * Every CLI run of a published install compares its own version against the
5
+ * npm registry's `latest` dist-tag and warns on stderr when behind. The
6
+ * registry lookup is cached under the config dir
7
+ * (`~/.config/agent-serve/update-check.json`) so most runs never touch the
8
+ * network; a stale cache refreshes inline under a short timeout, and any
9
+ * network failure is silent (the warning is best-effort, never a blocker).
10
+ *
11
+ * `agentkit update` re-runs the lookup fresh, figures out how this copy was
12
+ * installed (global npm/pnpm/yarn/bun, or a project dependency), and runs the
13
+ * matching install command.
14
+ */
15
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
16
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
17
+ return new (P || (P = Promise))(function (resolve, reject) {
18
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
19
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
20
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
21
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
22
+ });
23
+ };
24
+ import { spawn } from "node:child_process";
25
+ import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
26
+ import { dirname, join, sep } from "node:path";
27
+ import { z } from "zod";
28
+ import { configDirPath } from "./cursor/credentials.js";
29
+ import { describeError } from "./describe-error.js";
30
+ import { CLI_COMMAND_NAME, isCompiledDistribution, PACKAGE_NAME, packageRootDir, packageVersion, } from "./distribution.js";
31
+ import { stderrPalette } from "./terminal-style.js";
32
+ const NPM_REGISTRY_URL = "https://registry.npmjs.org";
33
+ /** Refresh the registry lookup at most this often. */
34
+ const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
35
+ /** Inline refresh budget; a slow registry must not stall the command. */
36
+ const WARN_FETCH_TIMEOUT_MS = 1500;
37
+ /** `agentkit update` runs interactively, so it can afford a real timeout. */
38
+ const UPDATE_FETCH_TIMEOUT_MS = 10000;
39
+ function parseVersion(version) {
40
+ const match = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+.*)?$/.exec(version.trim());
41
+ if (match === null) {
42
+ return undefined;
43
+ }
44
+ return {
45
+ release: [Number(match[1]), Number(match[2]), Number(match[3])],
46
+ prerelease: match[4] === undefined ? [] : match[4].split("."),
47
+ };
48
+ }
49
+ /**
50
+ * Semver-style ordering: negative when `a < b`, 0 when equal, positive when
51
+ * `a > b`. Unparseable versions compare equal (never warn on garbage).
52
+ */
53
+ export function compareVersions(a, b) {
54
+ const pa = parseVersion(a);
55
+ const pb = parseVersion(b);
56
+ if (pa === undefined || pb === undefined) {
57
+ return 0;
58
+ }
59
+ for (let i = 0; i < 3; i++) {
60
+ const diff = pa.release[i] - pb.release[i];
61
+ if (diff !== 0) {
62
+ return diff;
63
+ }
64
+ }
65
+ // A release outranks any prerelease of the same triple.
66
+ if (pa.prerelease.length === 0 || pb.prerelease.length === 0) {
67
+ return pb.prerelease.length - pa.prerelease.length;
68
+ }
69
+ const len = Math.max(pa.prerelease.length, pb.prerelease.length);
70
+ for (let i = 0; i < len; i++) {
71
+ const ia = pa.prerelease[i];
72
+ const ib = pb.prerelease[i];
73
+ // A longer prerelease list outranks its prefix (1.0.0-a.1 > 1.0.0-a).
74
+ if (ia === undefined) {
75
+ return -1;
76
+ }
77
+ if (ib === undefined) {
78
+ return 1;
79
+ }
80
+ const na = /^\d+$/.test(ia) ? Number(ia) : undefined;
81
+ const nb = /^\d+$/.test(ib) ? Number(ib) : undefined;
82
+ if (na !== undefined && nb !== undefined) {
83
+ if (na !== nb) {
84
+ return na - nb;
85
+ }
86
+ }
87
+ else if (na !== undefined) {
88
+ return -1; // numeric identifiers sort before alphanumeric ones
89
+ }
90
+ else if (nb !== undefined) {
91
+ return 1;
92
+ }
93
+ else if (ia !== ib) {
94
+ return ia < ib ? -1 : 1;
95
+ }
96
+ }
97
+ return 0;
98
+ }
99
+ // ============================================================================
100
+ // Registry lookup
101
+ // ============================================================================
102
+ const distTagResponseSchema = z.object({ version: z.string() });
103
+ /**
104
+ * Latest published version of the package, from the registry's `latest`
105
+ * dist-tag. Returns undefined on any failure (offline, 404 pre-publish, …).
106
+ */
107
+ export function fetchLatestPublishedVersion(options) {
108
+ return __awaiter(this, void 0, void 0, function* () {
109
+ var _a, _b, _c;
110
+ const fetchImpl = (_a = options === null || options === void 0 ? void 0 : options.fetchImpl) !== null && _a !== void 0 ? _a : fetch;
111
+ const packageName = (_b = options === null || options === void 0 ? void 0 : options.packageName) !== null && _b !== void 0 ? _b : PACKAGE_NAME;
112
+ // Scoped names keep the `@` but encode the `/` for the registry path.
113
+ const url = `${NPM_REGISTRY_URL}/${packageName.replace("/", "%2F")}/latest`;
114
+ try {
115
+ const response = yield fetchImpl(url, {
116
+ headers: { accept: "application/json" },
117
+ signal: AbortSignal.timeout((_c = options === null || options === void 0 ? void 0 : options.timeoutMs) !== null && _c !== void 0 ? _c : WARN_FETCH_TIMEOUT_MS),
118
+ });
119
+ if (!response.ok) {
120
+ return undefined;
121
+ }
122
+ const body = distTagResponseSchema.safeParse(yield response.json());
123
+ if (!body.success || parseVersion(body.data.version) === undefined) {
124
+ return undefined;
125
+ }
126
+ return body.data.version;
127
+ }
128
+ catch (_d) {
129
+ return undefined;
130
+ }
131
+ });
132
+ }
133
+ // ============================================================================
134
+ // Cache (one JSON file next to credentials.json)
135
+ // ============================================================================
136
+ const cacheSchema = z.object({
137
+ /** Epoch ms of the last registry lookup attempt (success or not). */
138
+ checkedAt: z.number(),
139
+ /** Last version the registry reported; absent when lookups keep failing. */
140
+ latestVersion: z.string().optional(),
141
+ });
142
+ export function updateCheckCachePath(configDir) {
143
+ return join(configDir !== null && configDir !== void 0 ? configDir : configDirPath(), "update-check.json");
144
+ }
145
+ export function readUpdateCheckCache(configDir) {
146
+ return __awaiter(this, void 0, void 0, function* () {
147
+ let raw;
148
+ try {
149
+ raw = yield readFile(updateCheckCachePath(configDir), "utf8");
150
+ }
151
+ catch (_a) {
152
+ return undefined;
153
+ }
154
+ try {
155
+ const parsed = cacheSchema.safeParse(JSON.parse(raw));
156
+ return parsed.success ? parsed.data : undefined;
157
+ }
158
+ catch (_b) {
159
+ return undefined;
160
+ }
161
+ });
162
+ }
163
+ export function writeUpdateCheckCache(cache, configDir) {
164
+ return __awaiter(this, void 0, void 0, function* () {
165
+ const path = updateCheckCachePath(configDir);
166
+ try {
167
+ yield mkdir(dirname(path), { recursive: true, mode: 0o700 });
168
+ yield writeFile(path, `${JSON.stringify(cache, null, 2)}\n`);
169
+ }
170
+ catch (_a) {
171
+ // Best-effort; a read-only config dir just means re-checking next run.
172
+ }
173
+ });
174
+ }
175
+ /**
176
+ * Print an outdated-version warning to stderr when a newer release exists.
177
+ *
178
+ * Never throws and never blocks longer than {@link WARN_FETCH_TIMEOUT_MS}.
179
+ * Suppressed on source-checkout runs (there is no installed copy to update),
180
+ * in CI, and via NO_UPDATE_NOTIFIER / AGENT_SERVE_NO_UPDATE_CHECK.
181
+ */
182
+ export function warnIfOutdated(options) {
183
+ return __awaiter(this, void 0, void 0, function* () {
184
+ var _a, _b, _c, _d;
185
+ const env = (_a = options === null || options === void 0 ? void 0 : options.env) !== null && _a !== void 0 ? _a : process.env;
186
+ if (isTruthyEnv(env.AGENT_SERVE_NO_UPDATE_CHECK) ||
187
+ isTruthyEnv(env.NO_UPDATE_NOTIFIER) ||
188
+ isTruthyEnv(env.CI)) {
189
+ return;
190
+ }
191
+ if ((options === null || options === void 0 ? void 0 : options.force) !== true && !isCompiledDistribution()) {
192
+ return;
193
+ }
194
+ const now = (_b = options === null || options === void 0 ? void 0 : options.now) !== null && _b !== void 0 ? _b : Date.now();
195
+ const currentVersion = (_c = options === null || options === void 0 ? void 0 : options.currentVersion) !== null && _c !== void 0 ? _c : packageVersion();
196
+ const cached = yield readUpdateCheckCache(options === null || options === void 0 ? void 0 : options.configDir);
197
+ let latestVersion = cached === null || cached === void 0 ? void 0 : cached.latestVersion;
198
+ const fresh = cached !== undefined && now - cached.checkedAt < CHECK_INTERVAL_MS;
199
+ if (!fresh) {
200
+ const fetched = yield fetchLatestPublishedVersion({
201
+ fetchImpl: options === null || options === void 0 ? void 0 : options.fetchImpl,
202
+ timeoutMs: WARN_FETCH_TIMEOUT_MS,
203
+ });
204
+ latestVersion = fetched !== null && fetched !== void 0 ? fetched : latestVersion;
205
+ // checkedAt always advances so a flaky registry backs off to one
206
+ // attempt per interval instead of one per command.
207
+ yield writeUpdateCheckCache({ checkedAt: now, latestVersion }, options === null || options === void 0 ? void 0 : options.configDir);
208
+ }
209
+ if (latestVersion === undefined ||
210
+ compareVersions(currentVersion, latestVersion) >= 0) {
211
+ return;
212
+ }
213
+ const c = stderrPalette();
214
+ const err = (_d = options === null || options === void 0 ? void 0 : options.err) !== null && _d !== void 0 ? _d : ((text) => void process.stderr.write(text));
215
+ err(`${c.yellow("warning:")} ${CLI_COMMAND_NAME} ${currentVersion} is outdated (latest is ${latestVersion}). Run \`${CLI_COMMAND_NAME} update\` to upgrade.\n`);
216
+ });
217
+ }
218
+ function isTruthyEnv(value) {
219
+ return value !== undefined && value !== "" && value !== "0";
220
+ }
221
+ /**
222
+ * Figure out how the running copy was installed and which command upgrades
223
+ * it. Detection is path-shape based (global stores have recognizable
224
+ * layouts), then falls back to walking up to the project that declares the
225
+ * dependency. Returns undefined for layouts we cannot safely upgrade
226
+ * (npx cache, unrecognized stores).
227
+ */
228
+ export function detectUpdateCommand(args) {
229
+ return __awaiter(this, void 0, void 0, function* () {
230
+ var _a;
231
+ const packageName = (_a = args.packageName) !== null && _a !== void 0 ? _a : PACKAGE_NAME;
232
+ const spec = `${packageName}@latest`;
233
+ const posixRoot = args.packageRoot.split(sep).join("/");
234
+ // npx / pnpm dlx caches are ephemeral; a fresh `npx agentkit` already
235
+ // resolves latest, and upgrading the cache entry in place helps nobody.
236
+ if (posixRoot.includes("/_npx/") || posixRoot.includes("/.pnpm-store/")) {
237
+ return undefined;
238
+ }
239
+ if (posixRoot.includes("/pnpm/global/")) {
240
+ return {
241
+ cmd: "pnpm",
242
+ args: ["add", "-g", spec],
243
+ reason: "installed with pnpm --global",
244
+ };
245
+ }
246
+ if (posixRoot.includes("/.bun/install/global/")) {
247
+ return {
248
+ cmd: "bun",
249
+ args: ["add", "-g", spec],
250
+ reason: "installed with bun --global",
251
+ };
252
+ }
253
+ if (posixRoot.includes("/yarn/global/") ||
254
+ posixRoot.includes("/.config/yarn/global/")) {
255
+ return {
256
+ cmd: "yarn",
257
+ args: ["global", "add", spec],
258
+ reason: "installed with yarn global",
259
+ };
260
+ }
261
+ // A project that depends on the package: upgrade the dependency there,
262
+ // with whichever package manager the lockfile says the project uses.
263
+ const projectDir = yield findDependingProjectDir(args.packageRoot, packageName);
264
+ if (projectDir !== undefined) {
265
+ const pm = yield detectProjectPackageManager(projectDir);
266
+ const command = pm === "pnpm"
267
+ ? { cmd: "pnpm", args: ["add", spec] }
268
+ : pm === "yarn"
269
+ ? { cmd: "yarn", args: ["add", spec] }
270
+ : pm === "bun"
271
+ ? { cmd: "bun", args: ["add", spec] }
272
+ : { cmd: "npm", args: ["install", spec] };
273
+ return Object.assign(Object.assign({}, command), { cwd: projectDir, reason: `project dependency in ${projectDir}` });
274
+ }
275
+ // Global npm layout: <prefix>/lib/node_modules/<name> (or <prefix>\
276
+ // node_modules\<name> on Windows), with no depending project above it.
277
+ if (posixRoot.includes("/node_modules/")) {
278
+ return {
279
+ cmd: "npm",
280
+ args: ["install", "-g", spec],
281
+ reason: "installed with npm --global",
282
+ };
283
+ }
284
+ return undefined;
285
+ });
286
+ }
287
+ /**
288
+ * Nearest ancestor with a package.json that declares `packageName` as a
289
+ * dependency. Skips directories inside node_modules (pnpm's virtual store
290
+ * nests package.json files that are not the user's project).
291
+ */
292
+ function findDependingProjectDir(packageRoot, packageName) {
293
+ return __awaiter(this, void 0, void 0, function* () {
294
+ let dir = dirname(packageRoot);
295
+ for (let depth = 0; depth < 30; depth++) {
296
+ const parent = dirname(dir);
297
+ if (parent === dir) {
298
+ return undefined;
299
+ }
300
+ const inNodeModules = dir
301
+ .split(sep)
302
+ .some((part) => part === "node_modules" || part === ".pnpm");
303
+ if (!inNodeModules && (yield declaresDependency(dir, packageName))) {
304
+ return dir;
305
+ }
306
+ dir = parent;
307
+ }
308
+ return undefined;
309
+ });
310
+ }
311
+ function declaresDependency(dir, packageName) {
312
+ return __awaiter(this, void 0, void 0, function* () {
313
+ var _a, _b;
314
+ let raw;
315
+ try {
316
+ raw = yield readFile(join(dir, "package.json"), "utf8");
317
+ }
318
+ catch (_c) {
319
+ return false;
320
+ }
321
+ const manifestSchema = z.object({
322
+ dependencies: z.record(z.string()).optional(),
323
+ devDependencies: z.record(z.string()).optional(),
324
+ });
325
+ try {
326
+ const parsed = manifestSchema.safeParse(JSON.parse(raw));
327
+ if (!parsed.success) {
328
+ return false;
329
+ }
330
+ return (((_a = parsed.data.dependencies) === null || _a === void 0 ? void 0 : _a[packageName]) !== undefined ||
331
+ ((_b = parsed.data.devDependencies) === null || _b === void 0 ? void 0 : _b[packageName]) !== undefined);
332
+ }
333
+ catch (_d) {
334
+ return false;
335
+ }
336
+ });
337
+ }
338
+ function detectProjectPackageManager(projectDir) {
339
+ return __awaiter(this, void 0, void 0, function* () {
340
+ const exists = (file) => __awaiter(this, void 0, void 0, function* () {
341
+ try {
342
+ yield stat(join(projectDir, file));
343
+ return true;
344
+ }
345
+ catch (_a) {
346
+ return false;
347
+ }
348
+ });
349
+ if (yield exists("pnpm-lock.yaml")) {
350
+ return "pnpm";
351
+ }
352
+ if (yield exists("yarn.lock")) {
353
+ return "yarn";
354
+ }
355
+ if ((yield exists("bun.lock")) || (yield exists("bun.lockb"))) {
356
+ return "bun";
357
+ }
358
+ return "npm";
359
+ });
360
+ }
361
+ /** `agentkit update` — upgrade this install to the latest published version. */
362
+ export function cmdUpdate(options) {
363
+ return __awaiter(this, void 0, void 0, function* () {
364
+ var _a, _b, _c, _d, _e, _f;
365
+ const c = stderrPalette();
366
+ const out = (_a = options === null || options === void 0 ? void 0 : options.out) !== null && _a !== void 0 ? _a : ((text) => void process.stdout.write(text));
367
+ const err = (_b = options === null || options === void 0 ? void 0 : options.err) !== null && _b !== void 0 ? _b : ((text) => void process.stderr.write(text));
368
+ const compiled = (_c = options === null || options === void 0 ? void 0 : options.compiled) !== null && _c !== void 0 ? _c : isCompiledDistribution();
369
+ if (!compiled) {
370
+ err(`${CLI_COMMAND_NAME} is running from a source checkout, not an installed package; update it with git instead.\n`);
371
+ return 1;
372
+ }
373
+ const currentVersion = (_d = options === null || options === void 0 ? void 0 : options.currentVersion) !== null && _d !== void 0 ? _d : packageVersion();
374
+ const latestVersion = yield fetchLatestPublishedVersion({
375
+ fetchImpl: options === null || options === void 0 ? void 0 : options.fetchImpl,
376
+ timeoutMs: UPDATE_FETCH_TIMEOUT_MS,
377
+ });
378
+ if (latestVersion === undefined) {
379
+ err(`Could not reach the npm registry to look up the latest ${PACKAGE_NAME} version. Check your network and retry.\n`);
380
+ return 1;
381
+ }
382
+ if (compareVersions(currentVersion, latestVersion) >= 0) {
383
+ out(`${CLI_COMMAND_NAME} ${currentVersion} is already the latest version.\n`);
384
+ yield writeUpdateCheckCache({ checkedAt: Date.now(), latestVersion }, options === null || options === void 0 ? void 0 : options.configDir);
385
+ return 0;
386
+ }
387
+ const command = yield detectUpdateCommand({
388
+ packageRoot: (_e = options === null || options === void 0 ? void 0 : options.packageRoot) !== null && _e !== void 0 ? _e : packageRootDir(),
389
+ });
390
+ if (command === undefined) {
391
+ err(`${CLI_COMMAND_NAME} ${currentVersion} is outdated (latest is ${latestVersion}), but this install's layout was not recognized.\nUpgrade it yourself, e.g. \`npm install -g ${PACKAGE_NAME}@latest\` for a global install, or bump the ${PACKAGE_NAME} dependency in your project.\n`);
392
+ return 1;
393
+ }
394
+ const rendered = [command.cmd, ...command.args].join(" ");
395
+ err(c.dim(`Updating ${CLI_COMMAND_NAME} ${currentVersion} → ${latestVersion} (${command.reason}):\n ${rendered}\n`));
396
+ const run = (_f = options === null || options === void 0 ? void 0 : options.runCommand) !== null && _f !== void 0 ? _f : runUpdateCommand;
397
+ let code;
398
+ try {
399
+ code = yield run(command);
400
+ }
401
+ catch (error) {
402
+ err(`\`${rendered}\` failed: ${describeError(error)}\n`);
403
+ return 1;
404
+ }
405
+ if (code !== 0) {
406
+ err(`\`${rendered}\` exited with code ${code}.\n`);
407
+ return code;
408
+ }
409
+ yield writeUpdateCheckCache({ checkedAt: Date.now(), latestVersion }, options === null || options === void 0 ? void 0 : options.configDir);
410
+ out(`Updated ${CLI_COMMAND_NAME} to ${latestVersion}. New commands run the new version.\n`);
411
+ return 0;
412
+ });
413
+ }
414
+ function runUpdateCommand(command) {
415
+ return new Promise((resolve, reject) => {
416
+ // Windows-only shell: npm/pnpm/yarn/bun are .cmd shims there, and Node
417
+ // refuses to spawn .cmd files without a shell (EINVAL, CVE-2024-27980
418
+ // hardening). Injection-safe: cmd and args are module-level constants
419
+ // from detectUpdateCommand (never user or registry input).
420
+ // nosemgrep: javascript.lang.security.audit.spawn-shell-true.spawn-shell-true
421
+ const child = spawn(command.cmd, command.args, {
422
+ stdio: "inherit",
423
+ cwd: command.cwd,
424
+ shell: process.platform === "win32",
425
+ });
426
+ child.on("error", reject);
427
+ child.on("close", (code) => {
428
+ resolve(code !== null && code !== void 0 ? code : 1);
429
+ });
430
+ });
431
+ }