agentplane 0.2.1 → 0.2.2

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.
@@ -9,15 +9,37 @@ export type UpgradeFlags = {
9
9
  backup: boolean;
10
10
  yes: boolean;
11
11
  };
12
+ type GitHubRelease = {
13
+ assets?: {
14
+ name?: string;
15
+ browser_download_url?: string;
16
+ }[];
17
+ tarball_url?: string;
18
+ };
12
19
  export declare function normalizeFrameworkSourceForUpgrade(source: string): {
13
20
  source: string;
14
21
  owner: string;
15
22
  repo: string;
16
23
  migrated: boolean;
17
24
  };
25
+ export declare function resolveUpgradeDownloadFromRelease(opts: {
26
+ release: GitHubRelease;
27
+ owner: string;
28
+ repo: string;
29
+ assetName: string;
30
+ checksumName: string;
31
+ }): {
32
+ kind: "assets";
33
+ bundleUrl: string;
34
+ checksumUrl: string;
35
+ } | {
36
+ kind: "tarball";
37
+ tarballUrl: string;
38
+ };
18
39
  export declare function cmdUpgradeParsed(opts: {
19
40
  cwd: string;
20
41
  rootOverride?: string;
21
42
  flags: UpgradeFlags;
22
43
  }): Promise<number>;
44
+ export {};
23
45
  //# sourceMappingURL=upgrade.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAuBA,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAmBF,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,MAAM,GAAG;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB,CAWA;AAkOD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,YAAY,CAAC;CACrB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuQlB"}
1
+ {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAuBA,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,oBAAoB,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAmBF,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,MAAM,GAAG;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB,CAWA;AAED,wBAAgB,iCAAiC,CAAC,IAAI,EAAE;IACtD,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB,GACG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAqB1C;AAkOD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,YAAY,CAAC;CACrB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgSlB"}
@@ -42,6 +42,27 @@ export function normalizeFrameworkSourceForUpgrade(source) {
42
42
  }
43
43
  return { source: `https://github.com/${owner}/${repo}`, owner, repo, migrated: false };
44
44
  }
45
+ export function resolveUpgradeDownloadFromRelease(opts) {
46
+ const assets = Array.isArray(opts.release.assets) ? opts.release.assets : [];
47
+ const asset = assets.find((a) => a?.name === opts.assetName);
48
+ const checksumAsset = assets.find((a) => a?.name === opts.checksumName);
49
+ if (asset?.browser_download_url && checksumAsset?.browser_download_url) {
50
+ return {
51
+ kind: "assets",
52
+ bundleUrl: asset.browser_download_url,
53
+ checksumUrl: checksumAsset.browser_download_url,
54
+ };
55
+ }
56
+ const tarballUrl = typeof opts.release.tarball_url === "string" ? opts.release.tarball_url : "";
57
+ if (!tarballUrl) {
58
+ throw new CliError({
59
+ exitCode: exitCodeForError("E_NETWORK"),
60
+ code: "E_NETWORK",
61
+ message: `Upgrade assets not found in ${opts.owner}/${opts.repo} release`,
62
+ });
63
+ }
64
+ return { kind: "tarball", tarballUrl };
65
+ }
45
66
  async function resolveUpgradeRoot(extractedDir) {
46
67
  const entries = await readdir(extractedDir, { withFileTypes: true });
47
68
  const dirs = entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
@@ -293,6 +314,9 @@ export async function cmdUpgradeParsed(opts) {
293
314
  tempRoot = await mkdtemp(path.join(os.tmpdir(), "agentplane-upgrade-"));
294
315
  let bundlePath = "";
295
316
  let checksumPath = "";
317
+ // GitHub release tarballs contain the full repository. When we fall back to tarball_url,
318
+ // we must ignore non-upgrade paths instead of failing validation.
319
+ let allowNonUpgradePaths = false;
296
320
  if (flags.bundle) {
297
321
  const isUrl = flags.bundle.startsWith("http://") || flags.bundle.startsWith("https://");
298
322
  bundlePath = isUrl ? path.join(tempRoot, "bundle.tar.gz") : path.resolve(flags.bundle);
@@ -316,39 +340,47 @@ export async function cmdUpgradeParsed(opts) {
316
340
  ? `https://api.github.com/repos/${owner}/${repo}/releases/tags/${flags.tag}`
317
341
  : `https://api.github.com/repos/${owner}/${repo}/releases/latest`;
318
342
  await ensureApproved("upgrade fetches release metadata and downloads assets from the network");
319
- const release = (await fetchJson(releaseUrl));
320
- const assets = Array.isArray(release.assets) ? release.assets : [];
321
343
  const assetName = flags.asset ?? DEFAULT_UPGRADE_ASSET;
322
344
  const checksumName = flags.checksumAsset ?? DEFAULT_UPGRADE_CHECKSUM_ASSET;
323
- const asset = assets.find((entry) => entry.name === assetName);
324
- const checksumAsset = assets.find((entry) => entry.name === checksumName);
325
- if (!asset?.browser_download_url || !checksumAsset?.browser_download_url) {
345
+ const release = (await fetchJson(releaseUrl));
346
+ const download = resolveUpgradeDownloadFromRelease({
347
+ release,
348
+ owner,
349
+ repo,
350
+ assetName,
351
+ checksumName,
352
+ });
353
+ if (download.kind === "assets") {
354
+ bundlePath = path.join(tempRoot, assetName);
355
+ checksumPath = path.join(tempRoot, checksumName);
356
+ await downloadToFile(download.bundleUrl, bundlePath);
357
+ await downloadToFile(download.checksumUrl, checksumPath);
358
+ }
359
+ else {
360
+ process.stderr.write(`${warnMessage(`upgrade release does not include ${assetName}/${checksumName}; falling back to tarball_url without checksum verification`)}\n`);
361
+ allowNonUpgradePaths = true;
362
+ bundlePath = path.join(tempRoot, "source.tar.gz");
363
+ await downloadToFile(download.tarballUrl, bundlePath);
364
+ checksumPath = "";
365
+ }
366
+ }
367
+ if (checksumPath) {
368
+ const expected = parseSha256Text(await readFile(checksumPath, "utf8"));
369
+ if (!expected) {
326
370
  throw new CliError({
327
- exitCode: exitCodeForError("E_NETWORK"),
328
- code: "E_NETWORK",
329
- message: `Upgrade assets not found in ${owner}/${repo} release`,
371
+ exitCode: 3,
372
+ code: "E_VALIDATION",
373
+ message: "Upgrade checksum file is empty or invalid",
374
+ });
375
+ }
376
+ const actual = await sha256File(bundlePath);
377
+ if (actual !== expected) {
378
+ throw new CliError({
379
+ exitCode: 3,
380
+ code: "E_VALIDATION",
381
+ message: `Upgrade checksum mismatch (expected ${expected}, got ${actual})`,
330
382
  });
331
383
  }
332
- bundlePath = path.join(tempRoot, assetName);
333
- checksumPath = path.join(tempRoot, checksumName);
334
- await downloadToFile(asset.browser_download_url, bundlePath);
335
- await downloadToFile(checksumAsset.browser_download_url, checksumPath);
336
- }
337
- const expected = parseSha256Text(await readFile(checksumPath, "utf8"));
338
- if (!expected) {
339
- throw new CliError({
340
- exitCode: 3,
341
- code: "E_VALIDATION",
342
- message: "Upgrade checksum file is empty or invalid",
343
- });
344
- }
345
- const actual = await sha256File(bundlePath);
346
- if (actual !== expected) {
347
- throw new CliError({
348
- exitCode: 3,
349
- code: "E_VALIDATION",
350
- message: `Upgrade checksum mismatch (expected ${expected}, got ${actual})`,
351
- });
352
384
  }
353
385
  extractRoot = await mkdtemp(path.join(os.tmpdir(), "agentplane-upgrade-extract-"));
354
386
  await extractArchive({
@@ -387,6 +419,9 @@ export async function cmdUpgradeParsed(opts) {
387
419
  });
388
420
  }
389
421
  if (!isAllowedUpgradePath(rel)) {
422
+ if (allowNonUpgradePaths) {
423
+ continue;
424
+ }
390
425
  throw new CliError({
391
426
  exitCode: 3,
392
427
  code: "E_VALIDATION",
@@ -452,6 +487,13 @@ export async function cmdUpgradeParsed(opts) {
452
487
  }
453
488
  }
454
489
  }
490
+ if (fileContents.size === 0) {
491
+ throw new CliError({
492
+ exitCode: 3,
493
+ code: "E_VALIDATION",
494
+ message: "Upgrade bundle contains no applicable files (expected AGENTS.md and/or .agentplane/).",
495
+ });
496
+ }
455
497
  if (flags.dryRun) {
456
498
  process.stdout.write(`Upgrade dry-run: ${additions.length} add, ${updates.length} update, ${skipped.length} unchanged\n`);
457
499
  for (const rel of additions)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentplane",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Agent Plane CLI for task workflows, recipes, and project automation.",
5
5
  "keywords": [
6
6
  "agentplane",
@@ -54,7 +54,7 @@
54
54
  "prepublishOnly": "npm run prepack"
55
55
  },
56
56
  "dependencies": {
57
- "@agentplaneorg/core": "0.2.1",
57
+ "@agentplaneorg/core": "0.2.2",
58
58
  "yauzl": "^2.10.0"
59
59
  },
60
60
  "devDependencies": {