ai-project-manage-cli 5.0.1 → 5.0.3

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 +59 -71
  2. package/package.json +2 -4
package/dist/index.js CHANGED
@@ -254,25 +254,28 @@ async function runLogin(opts) {
254
254
  );
255
255
  process.exit(1);
256
256
  }
257
- console.error(
258
- "[apm] \u8BF7\u6C42\u5931\u8D25:",
259
- raw instanceof Error ? raw.message : raw
260
- );
257
+ console.error("[apm] \u8BF7\u6C42\u5931\u8D25:", raw instanceof Error ? raw.message : raw);
261
258
  process.exit(1);
262
259
  }
263
- if (!data?.id || !data?.token) {
264
- console.error("[apm] \u54CD\u5E94\u7F3A\u5C11 id / token\uFF08\u8BF7\u786E\u8BA4\u670D\u52A1\u7AEF\u4E3A /api/auth/login\uFF09");
260
+ const userId = data?.user?.id;
261
+ const token = data?.token;
262
+ if (!userId || !token) {
263
+ console.error(
264
+ "[apm] \u54CD\u5E94\u7F3A\u5C11 user.id / token\uFF08\u8BF7\u786E\u8BA4\u670D\u52A1\u7AEF\u4E3A /api/auth/login\uFF09"
265
+ );
265
266
  process.exit(1);
266
267
  }
267
268
  const cfg = {
268
269
  baseUrl,
269
- userId: data.id,
270
- token: data.token,
270
+ userId,
271
+ token,
271
272
  email: opts.email
272
273
  };
273
274
  await writeApmConfig(cfg);
274
275
  console.error(`[apm] \u5DF2\u4FDD\u5B58\u767B\u5F55\u4FE1\u606F: ${APM_CONFIG_PATH}`);
275
- console.log(JSON.stringify({ userId: cfg.userId, baseUrl: cfg.baseUrl }, null, 2));
276
+ console.log(
277
+ JSON.stringify({ userId: cfg.userId, baseUrl: cfg.baseUrl }, null, 2)
278
+ );
276
279
  }
277
280
 
278
281
  // src/commands/branch.ts
@@ -280,37 +283,17 @@ import { execFile } from "child_process";
280
283
  import { resolve as resolve2 } from "path";
281
284
  import { promisify } from "util";
282
285
  var execFileAsync = promisify(execFile);
283
- async function fetchBaselineBranchFromApi(sessionId, cwd) {
284
- const cfg = await ensureLoggedConfig();
285
- const api = createApmApiClient(cfg);
286
- const workdirPath = resolve2(cwd);
287
- const res = await api.cli.branchBaseline({
288
- sessionId,
289
- workdirPath
290
- });
291
- if (!res.repositoryId) {
292
- throw new Error(
293
- `[apm] \u672A\u5728\u5E73\u53F0\u627E\u5230\u4E0E\u5F53\u524D\u76EE\u5F55\u5339\u914D\u7684\u5DE5\u4F5C\u76EE\u5F55\u767B\u8BB0\uFF1A${workdirPath}
294
- \u8BF7\u5148\u5728\u5E73\u53F0\u767B\u8BB0\u8BE5\u8DEF\u5F84\u5BF9\u5E94\u7684\u5DE5\u4F5C\u76EE\u5F55\u4E0E\u4ED3\u5E93\u3002`
295
- );
296
- }
297
- const name = (res.defaultBranch ?? "").trim();
298
- if (!name) {
299
- throw new Error("[apm] \u5E73\u53F0\u8FD4\u56DE\u7684\u57FA\u7EBF\u5206\u652F\u540D\u4E3A\u7A7A");
300
- }
301
- return name;
302
- }
303
- function branchNameForRequirement(requirementId) {
304
- const id = requirementId.trim();
286
+ function branchNameForSession(sessionId) {
287
+ const id = sessionId.trim();
305
288
  if (!id) {
306
- throw new Error("[apm] \u9700\u6C42 ID \u4E0D\u80FD\u4E3A\u7A7A");
289
+ throw new Error("[apm] \u4F1A\u8BDD ID \u4E0D\u80FD\u4E3A\u7A7A");
307
290
  }
308
291
  if (/[\s/\\]/.test(id)) {
309
292
  throw new Error(
310
- "[apm] \u9700\u6C42 ID \u4E0D\u80FD\u5305\u542B\u7A7A\u767D\u6216\u8DEF\u5F84\u5206\u9694\u7B26\uFF0C\u8BF7\u4F7F\u7528\u5B57\u6BCD\u3001\u6570\u5B57\u3001._- \u7B49"
293
+ "[apm] \u4F1A\u8BDD ID \u4E0D\u80FD\u5305\u542B\u7A7A\u767D\u6216\u8DEF\u5F84\u5206\u9694\u7B26\uFF0C\u8BF7\u4F7F\u7528\u5B57\u6BCD\u3001\u6570\u5B57\u3001._- \u7B49"
311
294
  );
312
295
  }
313
- return `feat/req-${id}`;
296
+ return `feat/session-${id}`;
314
297
  }
315
298
  async function execGit(cwd, args, quiet) {
316
299
  try {
@@ -373,10 +356,15 @@ async function commitWorkingTreeIfDirty(cwd, message) {
373
356
  console.log(`[apm] \u5DF2\u63D0\u4EA4\u5DE5\u4F5C\u533A\u53D8\u66F4: ${commitMessage}`);
374
357
  return true;
375
358
  }
376
- async function ensureFeatureBranch(branch, options, fetchBaseline) {
359
+ async function ensureFeatureBranch(branch, baselineBranch, options) {
377
360
  const cwd = options.cwd ?? process.cwd();
378
361
  const commitMessage = options.message?.trim() || `chore(apm): \u540C\u6B65\u5DE5\u4F5C\u533A (${branch})`;
379
362
  await ensureGitRepo(cwd);
363
+ if (!await remoteHeadBranchExists(cwd, baselineBranch)) {
364
+ throw new Error(
365
+ `[apm] \u8FDC\u7A0B\u4E0D\u5B58\u5728\u57FA\u7EBF\u5206\u652F ${baselineBranch}\uFF0C\u8BF7\u786E\u8BA4\u4ED3\u5E93\u9ED8\u8BA4\u5206\u652F\u5DF2\u63A8\u9001\u5230 origin`
366
+ );
367
+ }
380
368
  const current = await getCurrentBranch(cwd);
381
369
  const dirty = await isWorkingTreeDirty(cwd);
382
370
  if (dirty) {
@@ -392,34 +380,29 @@ async function ensureFeatureBranch(branch, options, fetchBaseline) {
392
380
  ]);
393
381
  }
394
382
  }
395
- const remoteExists = await remoteHeadBranchExists(cwd, branch);
396
- if (remoteExists) {
397
- await execGit(cwd, ["fetch", "origin", branch]);
398
- const hasLocal = await localBranchExists(cwd, branch);
399
- if (hasLocal) {
400
- await execGit(cwd, ["checkout", branch]);
401
- await execGit(cwd, ["pull", "--no-edit"]);
402
- } else {
403
- await execGit(cwd, ["checkout", "-b", branch, `origin/${branch}`]);
404
- }
383
+ const onTargetBranch = await getCurrentBranch(cwd) === branch;
384
+ if (onTargetBranch) {
385
+ await execGit(cwd, ["fetch", "origin", baselineBranch]);
386
+ await execGit(cwd, ["merge", `origin/${baselineBranch}`, "--no-edit"]);
405
387
  } else {
406
- const onBranch = await getCurrentBranch(cwd) === branch;
407
- if (!onBranch) {
408
- const hasLocal = await localBranchExists(cwd, branch);
409
- if (hasLocal) {
410
- await execGit(cwd, ["checkout", branch]);
411
- } else {
412
- const baselineBranch = await fetchBaseline();
413
- await execGit(cwd, ["fetch", "origin", baselineBranch]);
414
- await execGit(cwd, [
415
- "checkout",
416
- "-b",
417
- branch,
418
- `origin/${baselineBranch}`
419
- ]);
420
- }
388
+ const remoteExists = await remoteHeadBranchExists(cwd, branch);
389
+ if (remoteExists) {
390
+ await execGit(cwd, ["fetch", "origin", branch]);
391
+ await execGit(cwd, ["checkout", "-B", branch, `origin/${branch}`]);
392
+ } else if (await localBranchExists(cwd, branch)) {
393
+ throw new Error(
394
+ `[apm] \u8FDC\u7A0B\u4E0D\u5B58\u5728\u5206\u652F ${branch}\uFF0C\u4F46\u672C\u5730\u5DF2\u5B58\u5728\u8BE5\u5206\u652F\uFF0C\u8BF7\u5148\u63A8\u9001\u6216\u5220\u9664\u672C\u5730\u5206\u652F`
395
+ );
396
+ } else {
397
+ await execGit(cwd, ["fetch", "origin", baselineBranch]);
398
+ await execGit(cwd, [
399
+ "checkout",
400
+ "-b",
401
+ branch,
402
+ `origin/${baselineBranch}`
403
+ ]);
404
+ await execGit(cwd, ["push", "-u", "origin", branch]);
421
405
  }
422
- await execGit(cwd, ["push", "-u", "origin", branch]);
423
406
  }
424
407
  console.log(`[apm] \u5DF2\u5C31\u7EEA\u5206\u652F ${branch}`);
425
408
  return branch;
@@ -433,16 +416,23 @@ async function runBranch(sessionId, options = {}) {
433
416
  const cfg = await ensureLoggedConfig();
434
417
  const api = createApmApiClient(cfg);
435
418
  const cwd = options.cwd ?? process.cwd();
419
+ const workdirPath = resolve2(cwd);
436
420
  const baseline = await api.cli.branchBaseline({
437
421
  sessionId: trimmedSessionId,
438
- workdirPath: resolve2(cwd)
422
+ workdirPath
439
423
  });
440
- const branch = branchNameForRequirement(baseline.requirementId);
441
- return ensureFeatureBranch(
442
- branch,
443
- options,
444
- () => fetchBaselineBranchFromApi(trimmedSessionId, cwd)
445
- );
424
+ if (!baseline.repositoryId) {
425
+ throw new Error(
426
+ `[apm] \u672A\u5728\u5E73\u53F0\u627E\u5230\u4E0E\u5F53\u524D\u76EE\u5F55\u5339\u914D\u7684\u5DE5\u4F5C\u76EE\u5F55\u767B\u8BB0\uFF1A${workdirPath}
427
+ \u8BF7\u5148\u5728\u5E73\u53F0\u767B\u8BB0\u8BE5\u8DEF\u5F84\u5BF9\u5E94\u7684\u5DE5\u4F5C\u76EE\u5F55\u4E0E\u4ED3\u5E93\u3002`
428
+ );
429
+ }
430
+ const baselineBranch = (baseline.defaultBranch ?? "").trim();
431
+ if (!baselineBranch) {
432
+ throw new Error("[apm] \u5E73\u53F0\u8FD4\u56DE\u7684\u57FA\u7EBF\u5206\u652F\u540D\u4E3A\u7A7A");
433
+ }
434
+ const branch = branchNameForSession(trimmedSessionId);
435
+ return ensureFeatureBranch(branch, baselineBranch, options);
446
436
  }
447
437
 
448
438
  // src/commands/pull.ts
@@ -1792,9 +1782,7 @@ function buildProgram() {
1792
1782
  program.command("update-message-status").description("\u66F4\u65B0\u5E73\u53F0\u4F1A\u8BDD\u6D88\u606F\u72B6\u6001").requiredOption("--id <messageId>", "\u6D88\u606F ID").requiredOption("--status <status>", "CREATED | TYPING | SUCCESS | FAILED").action(async (opts) => {
1793
1783
  await runUpdateMessageStatus(opts);
1794
1784
  });
1795
- program.command("branch").description(
1796
- "\u5207\u6362\u6216\u521B\u5EFA\u9700\u6C42\u5206\u652F feat/req-<requirementId>\uFF08\u7531 sessionId \u89E3\u6790\u9700\u6C42\uFF09"
1797
- ).argument("<sessionId>", "\u6C9F\u901A\u7FA4 ID").option(
1785
+ program.command("branch").description("\u5207\u6362\u6216\u521B\u5EFA\u4F1A\u8BDD\u5206\u652F feat/session-<sessionId>").argument("<sessionId>", "\u6C9F\u901A\u7FA4 ID").option(
1798
1786
  "-m, --message <text>",
1799
1787
  "\u5DF2\u5728\u76EE\u6807\u5206\u652F\u4E14\u9700\u63D0\u4EA4\u672C\u5730\u6539\u52A8\u65F6\u4F7F\u7528\u7684\u63D0\u4EA4\u8BF4\u660E"
1800
1788
  ).action(async (sessionId, opts) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-project-manage-cli",
3
- "version": "5.0.1",
3
+ "version": "5.0.3",
4
4
  "description": "命令行工具:后续用于调用平台后端 API 完成运维与自动化操作",
5
5
  "type": "module",
6
6
  "private": false,
@@ -15,9 +15,7 @@
15
15
  ],
16
16
  "scripts": {
17
17
  "build": "rm -rf dist && esbuild src/index.ts --bundle --platform=node --format=esm --packages=external --outfile=dist/index.js && tsc --noEmit -p tsconfig.json",
18
- "prepublishOnly": "npm run build",
19
- "test": "vitest run",
20
- "test:watch": "vitest"
18
+ "prepublishOnly": "npm run build"
21
19
  },
22
20
  "devDependencies": {
23
21
  "@types/node": "^22.0.0",