agentplane 0.2.16 → 0.2.17

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.
@@ -446,6 +446,7 @@ async function cmdInit(opts) {
446
446
  }
447
447
  if (hooks) {
448
448
  await cmdHooksInstall({ cwd: opts.cwd, rootOverride: opts.rootOverride, quiet: true });
449
+ installPaths.push(".agentplane/bin/agentplane");
449
450
  }
450
451
  const ideRes = await maybeSyncIde({
451
452
  cwd: opts.cwd,
@@ -1 +1 @@
1
- {"version":3,"file":"apply.command.d.ts","sourceRoot":"","sources":["../../../src/commands/release/apply.command.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAS1E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AA0KnD,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CAwE5D,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,kBAAkB,CA+H9D,CAAC"}
1
+ {"version":3,"file":"apply.command.d.ts","sourceRoot":"","sources":["../../../src/commands/release/apply.command.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAU1E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AAuOnD,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CAwE5D,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,kBAAkB,CA6H9D,CAAC"}
@@ -1,11 +1,12 @@
1
1
  import { readFile, writeFile, readdir } from "node:fs/promises";
2
2
  import path from "node:path";
3
- import { resolveProject } from "@agentplaneorg/core";
3
+ import { resolveProject, loadConfig } from "@agentplaneorg/core";
4
4
  import { usageError } from "../../cli/spec/errors.js";
5
5
  import { exitCodeForError } from "../../cli/exit-codes.js";
6
6
  import { CliError } from "../../shared/errors.js";
7
7
  import { execFileAsync, gitEnv } from "../shared/git.js";
8
8
  import { GitContext } from "../shared/git-context.js";
9
+ import { ensureNetworkApproved } from "../shared/network-approval.js";
9
10
  async function fileExists(p) {
10
11
  try {
11
12
  await readFile(p, "utf8");
@@ -154,6 +155,63 @@ async function maybeUpdateBunLockfile(gitRoot) {
154
155
  });
155
156
  }
156
157
  }
158
+ async function ensureCleanTrackedTree(gitRoot) {
159
+ const { stdout } = await execFileAsync("git", ["status", "--short", "--untracked-files=no"], {
160
+ cwd: gitRoot,
161
+ env: gitEnv(),
162
+ maxBuffer: 10 * 1024 * 1024,
163
+ });
164
+ const dirty = String(stdout ?? "")
165
+ .split(/\r?\n/u)
166
+ .map((line) => line.trimEnd())
167
+ .filter((line) => line.length > 0);
168
+ if (dirty.length === 0)
169
+ return;
170
+ throw new CliError({
171
+ exitCode: exitCodeForError("E_GIT"),
172
+ code: "E_GIT",
173
+ message: "Release apply requires a clean tracked working tree.\n" +
174
+ `Found tracked changes:\n${dirty.map((line) => ` ${line}`).join("\n")}`,
175
+ });
176
+ }
177
+ async function ensureTagDoesNotExist(gitRoot, tag) {
178
+ try {
179
+ await execFileAsync("git", ["rev-parse", "-q", "--verify", `refs/tags/${tag}`], {
180
+ cwd: gitRoot,
181
+ env: gitEnv(),
182
+ });
183
+ throw new CliError({
184
+ exitCode: exitCodeForError("E_GIT"),
185
+ code: "E_GIT",
186
+ message: `Tag already exists: ${tag}`,
187
+ });
188
+ }
189
+ catch (err) {
190
+ const code = err?.code;
191
+ if (code !== 1)
192
+ throw err;
193
+ }
194
+ }
195
+ async function ensureNpmVersionsAvailable(gitRoot, version) {
196
+ const scriptPath = path.join(gitRoot, "scripts", "check-npm-version-availability.mjs");
197
+ try {
198
+ await execFileAsync("node", [scriptPath, "--version", version], {
199
+ cwd: gitRoot,
200
+ env: process.env,
201
+ maxBuffer: 10 * 1024 * 1024,
202
+ });
203
+ }
204
+ catch (err) {
205
+ const details = String(err?.stderr ?? "").trim();
206
+ throw new CliError({
207
+ exitCode: exitCodeForError("E_VALIDATION"),
208
+ code: "E_VALIDATION",
209
+ message: `Pre-publish npm check failed for version ${version}. ` +
210
+ "Ensure this version is not already published for @agentplaneorg/core and agentplane." +
211
+ (details ? `\n\n${details}` : ""),
212
+ });
213
+ }
214
+ }
157
215
  export const releaseApplySpec = {
158
216
  id: ["release", "apply"],
159
217
  group: "Release",
@@ -276,6 +334,18 @@ export const runReleaseApply = async (ctx, flags) => {
276
334
  });
277
335
  }
278
336
  const git = new GitContext({ gitRoot });
337
+ await ensureCleanTrackedTree(gitRoot);
338
+ await ensureTagDoesNotExist(gitRoot, plan.nextTag);
339
+ if (flags.push) {
340
+ const loaded = await loadConfig(resolved.agentplaneDir);
341
+ await ensureNetworkApproved({
342
+ config: loaded.config,
343
+ yes: flags.yes,
344
+ reason: "release apply --push validates npm version availability and pushes over network",
345
+ interactive: Boolean(process.stdin.isTTY),
346
+ });
347
+ await ensureNpmVersionsAvailable(gitRoot, plan.nextVersion);
348
+ }
279
349
  if (coreVersion === plan.prevVersion) {
280
350
  await Promise.all([
281
351
  replacePackageVersionInFile(corePkgPath, plan.nextVersion),
@@ -309,23 +379,6 @@ export const runReleaseApply = async (ctx, flags) => {
309
379
  const subject = `✨ release: ${plan.nextTag}`;
310
380
  await git.commit({ message: subject, env: cleanHookEnv() });
311
381
  }
312
- // Create tag (idempotency: refuse to overwrite).
313
- try {
314
- await execFileAsync("git", ["rev-parse", "-q", "--verify", `refs/tags/${plan.nextTag}`], {
315
- cwd: gitRoot,
316
- env: gitEnv(),
317
- });
318
- throw new CliError({
319
- exitCode: exitCodeForError("E_GIT"),
320
- code: "E_GIT",
321
- message: `Tag already exists: ${plan.nextTag}`,
322
- });
323
- }
324
- catch (err) {
325
- const code = err?.code;
326
- if (code !== 1)
327
- throw err;
328
- }
329
382
  await execFileAsync("git", ["tag", plan.nextTag], { cwd: gitRoot, env: gitEnv() });
330
383
  process.stdout.write(`Release tag created: ${plan.nextTag}\n`);
331
384
  if (flags.push) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentplane",
3
- "version": "0.2.16",
3
+ "version": "0.2.17",
4
4
  "description": "Agent Plane CLI for task workflows, recipes, and project automation.",
5
5
  "keywords": [
6
6
  "agentplane",