@agent-compose/cli 0.2.0 → 0.2.1

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 (2) hide show
  1. package/dist/index.js +139 -8
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { createRequire } from "node:module";
3
3
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
4
4
 
5
5
  // src/index.ts
6
- import { readFileSync as readFileSync4 } from "node:fs";
6
+ import { readFileSync as readFileSync5 } from "node:fs";
7
7
  import { fileURLToPath as fileURLToPath2 } from "node:url";
8
8
  import { program } from "commander";
9
9
 
@@ -227,7 +227,7 @@ var registerCommand = new Command("register").description("Register a workflow w
227
227
  while (Date.now() < deadline) {
228
228
  const { status } = await client.getStatus(runId);
229
229
  if (status === "success") {
230
- console.log(`✓ Snapshot ready other workflows can now reference \`snapshots: { bootFrom: { workflow: "${name}" } }\``);
230
+ console.log(`✓ Snapshot ready. Run \`agentc snapshot list --factory ${opts.factory ?? "default"} --workflow ${name}\` to find the snapshot id, then reference it as \`snapshots: { bootFrom: { snapshotId: "<id>" } }\` on another workflow.`);
231
231
  return;
232
232
  }
233
233
  if (status === "failed" || status === "abandoned") {
@@ -240,11 +240,7 @@ var registerCommand = new Command("register").description("Register a workflow w
240
240
  process.exit(1);
241
241
  });
242
242
  function formatBootFrom(b) {
243
- if (b.snapshotId)
244
- return `snapshot ${b.snapshotId}`;
245
- if (b.workflow)
246
- return b.version ? `${b.workflow}@${b.version}` : `${b.workflow} (latest)`;
247
- return "(unknown)";
243
+ return `snapshot ${b.snapshotId}`;
248
244
  }
249
245
 
250
246
  // src/commands/invoke.ts
@@ -1163,9 +1159,144 @@ var listCommand2 = new Command13("list").description("List events for a run, or
1163
1159
  });
1164
1160
  var eventsCommand = new Command13("events").description("Send or list run events (Events API)").addCommand(sendCommand).addCommand(listCommand2);
1165
1161
 
1162
+ // src/update-check.ts
1163
+ import { spawnSync } from "node:child_process";
1164
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync } from "node:fs";
1165
+ import { homedir as homedir3 } from "node:os";
1166
+ import { join as join3 } from "node:path";
1167
+ import { createInterface } from "node:readline/promises";
1168
+ import pc4 from "picocolors";
1169
+ var PACKAGE_NAME = "@agent-compose/cli";
1170
+ var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
1171
+ var FETCH_TIMEOUT_MS = 2000;
1172
+ function cachePath() {
1173
+ const xdg = process.env.XDG_CONFIG_HOME?.trim();
1174
+ return join3(xdg && xdg.length > 0 ? xdg : join3(homedir3(), ".config"), "agentc", "update-check.json");
1175
+ }
1176
+ function shouldSkip() {
1177
+ if (process.env.AGENTC_NO_UPDATE_CHECK === "1")
1178
+ return true;
1179
+ if (process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true" || process.env.BUILDKITE === "true" || process.env.CIRCLECI === "true" || process.env.GITLAB_CI === "true" || process.env.JENKINS_URL !== undefined)
1180
+ return true;
1181
+ return false;
1182
+ }
1183
+ function isNewer(latest, current) {
1184
+ const parse = (v) => {
1185
+ const m = v.match(/^(\d+)\.(\d+)\.(\d+)$/);
1186
+ if (!m)
1187
+ return null;
1188
+ return [Number(m[1]), Number(m[2]), Number(m[3])];
1189
+ };
1190
+ const a = parse(latest);
1191
+ const b = parse(current);
1192
+ if (!a || !b)
1193
+ return false;
1194
+ for (let i = 0;i < 3; i++) {
1195
+ if (a[i] > b[i])
1196
+ return true;
1197
+ if (a[i] < b[i])
1198
+ return false;
1199
+ }
1200
+ return false;
1201
+ }
1202
+ function readCache() {
1203
+ try {
1204
+ const raw = readFileSync4(cachePath(), "utf8");
1205
+ const parsed = JSON.parse(raw);
1206
+ if (typeof parsed.checkedAt !== "number")
1207
+ return null;
1208
+ return {
1209
+ checkedAt: parsed.checkedAt,
1210
+ latestVersion: typeof parsed.latestVersion === "string" ? parsed.latestVersion : null
1211
+ };
1212
+ } catch {
1213
+ return null;
1214
+ }
1215
+ }
1216
+ function writeCache(entry) {
1217
+ try {
1218
+ const path = cachePath();
1219
+ mkdirSync2(join3(path, ".."), { recursive: true });
1220
+ writeFileSync(path, JSON.stringify(entry, null, 2) + `
1221
+ `, "utf8");
1222
+ } catch {}
1223
+ }
1224
+ async function fetchLatest() {
1225
+ const controller = new AbortController;
1226
+ const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
1227
+ try {
1228
+ const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, {
1229
+ signal: controller.signal,
1230
+ headers: { Accept: "application/json" }
1231
+ });
1232
+ if (!res.ok)
1233
+ return null;
1234
+ const body = await res.json();
1235
+ return typeof body.version === "string" ? body.version : null;
1236
+ } catch {
1237
+ return null;
1238
+ } finally {
1239
+ clearTimeout(timeout);
1240
+ }
1241
+ }
1242
+ async function promptYesNo(question) {
1243
+ const rl = createInterface({ input: process.stdin, output: process.stderr });
1244
+ try {
1245
+ const answer = (await rl.question(question)).trim().toLowerCase();
1246
+ return answer === "y" || answer === "yes";
1247
+ } finally {
1248
+ rl.close();
1249
+ }
1250
+ }
1251
+ async function resolveLatest() {
1252
+ const cached = readCache();
1253
+ if (cached && Date.now() - cached.checkedAt < CHECK_INTERVAL_MS) {
1254
+ return cached.latestVersion;
1255
+ }
1256
+ const latest = await fetchLatest();
1257
+ writeCache({ checkedAt: Date.now(), latestVersion: latest });
1258
+ return latest;
1259
+ }
1260
+ async function checkForUpdate(currentVersion) {
1261
+ if (shouldSkip())
1262
+ return;
1263
+ const latest = await resolveLatest();
1264
+ if (!latest || !isNewer(latest, currentVersion))
1265
+ return;
1266
+ const headline = `${pc4.yellow("●")} agentc ${pc4.bold(latest)} is available (you have ${currentVersion}).`;
1267
+ process.stderr.write(`${headline}
1268
+ `);
1269
+ if (!process.stdin.isTTY) {
1270
+ process.stderr.write(` Run ${pc4.cyan("npm install -g " + PACKAGE_NAME + "@latest")} to update.
1271
+ `);
1272
+ return;
1273
+ }
1274
+ const confirm = await promptYesNo(` Install now? [y/${pc4.bold("N")}] `);
1275
+ if (!confirm)
1276
+ return;
1277
+ process.stderr.write(` Running ${pc4.cyan("npm install -g " + PACKAGE_NAME + "@latest")} …
1278
+ `);
1279
+ const result = spawnSync("npm", ["install", "-g", `${PACKAGE_NAME}@latest`], {
1280
+ stdio: "inherit"
1281
+ });
1282
+ if (result.status !== 0) {
1283
+ process.stderr.write(`${pc4.red("✗")} Install failed. Run the command above manually.
1284
+ `);
1285
+ return;
1286
+ }
1287
+ process.stderr.write(`${pc4.green("✓")} Installed ${pc4.bold(`agentc ${latest}`)}. ` + `Re-run your command to use the new version.
1288
+ `);
1289
+ process.exit(0);
1290
+ }
1291
+
1166
1292
  // src/index.ts
1167
- var pkg = JSON.parse(readFileSync4(fileURLToPath2(new URL("../package.json", import.meta.url)), "utf8"));
1293
+ var pkg = JSON.parse(readFileSync5(fileURLToPath2(new URL("../package.json", import.meta.url)), "utf8"));
1168
1294
  program.name("agentc").description("CLI for agent-compose — register, invoke, and monitor workflows").version(pkg.version);
1295
+ program.hook("preAction", async () => {
1296
+ try {
1297
+ await checkForUpdate(pkg.version);
1298
+ } catch {}
1299
+ });
1169
1300
  program.addCommand(registerCommand);
1170
1301
  program.addCommand(invokeCommand);
1171
1302
  program.addCommand(listCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-compose/cli",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Command-line interface for agent-compose — register, invoke, and monitor workflows from your terminal.",
5
5
  "license": "MIT",
6
6
  "repository": {