agentplane 0.2.19 → 0.2.21
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.
- package/assets/AGENTS.md +4 -3
- package/bin/agentplane.js +24 -0
- package/dist/backends/task-backend/load.d.ts +2 -0
- package/dist/backends/task-backend/load.d.ts.map +1 -1
- package/dist/backends/task-backend/load.js +38 -18
- package/dist/cli/command-guide.d.ts.map +1 -1
- package/dist/cli/command-guide.js +12 -11
- package/dist/cli/run-cli/command-catalog.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog.js +12 -1
- package/dist/cli/run-cli/commands/core.d.ts +9 -1
- package/dist/cli/run-cli/commands/core.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/core.js +268 -8
- package/dist/cli/run-cli/commands/init/write-config.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/write-config.js +2 -0
- package/dist/cli/run-cli/commands/init/write-gitignore.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/write-gitignore.js +3 -18
- package/dist/cli/run-cli/commands/init.d.ts +1 -0
- package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init.js +55 -30
- package/dist/cli/run-cli.d.ts.map +1 -1
- package/dist/cli/run-cli.js +85 -14
- package/dist/commands/commit.command.d.ts.map +1 -1
- package/dist/commands/commit.command.js +2 -0
- package/dist/commands/commit.spec.d.ts +2 -0
- package/dist/commands/commit.spec.d.ts.map +1 -1
- package/dist/commands/commit.spec.js +26 -0
- package/dist/commands/doctor.run.d.ts.map +1 -1
- package/dist/commands/doctor.run.js +15 -6
- package/dist/commands/finish.run.d.ts.map +1 -1
- package/dist/commands/finish.run.js +2 -0
- package/dist/commands/finish.spec.d.ts +2 -0
- package/dist/commands/finish.spec.d.ts.map +1 -1
- package/dist/commands/finish.spec.js +36 -0
- package/dist/commands/guard/impl/allow.d.ts.map +1 -1
- package/dist/commands/guard/impl/allow.js +33 -7
- package/dist/commands/guard/impl/commands.d.ts +2 -0
- package/dist/commands/guard/impl/commands.d.ts.map +1 -1
- package/dist/commands/guard/impl/commands.js +24 -4
- package/dist/commands/guard/impl/comment-commit.d.ts +1 -0
- package/dist/commands/guard/impl/comment-commit.d.ts.map +1 -1
- package/dist/commands/guard/impl/comment-commit.js +16 -24
- package/dist/commands/release/apply.command.d.ts.map +1 -1
- package/dist/commands/release/apply.command.js +51 -3
- package/dist/commands/release/plan.command.d.ts.map +1 -1
- package/dist/commands/release/plan.command.js +25 -1
- package/dist/commands/shared/task-backend.d.ts +3 -0
- package/dist/commands/shared/task-backend.d.ts.map +1 -1
- package/dist/commands/shared/task-backend.js +4 -1
- package/dist/commands/task/block.d.ts.map +1 -1
- package/dist/commands/task/block.js +12 -9
- package/dist/commands/task/close-duplicate.command.d.ts +14 -0
- package/dist/commands/task/close-duplicate.command.d.ts.map +1 -0
- package/dist/commands/task/close-duplicate.command.js +102 -0
- package/dist/commands/task/close-duplicate.d.ts +14 -0
- package/dist/commands/task/close-duplicate.d.ts.map +1 -0
- package/dist/commands/task/close-duplicate.js +90 -0
- package/dist/commands/task/close-noop.command.d.ts +14 -0
- package/dist/commands/task/close-noop.command.d.ts.map +1 -0
- package/dist/commands/task/close-noop.command.js +77 -0
- package/dist/commands/task/close-noop.d.ts +13 -0
- package/dist/commands/task/close-noop.d.ts.map +1 -0
- package/dist/commands/task/close-noop.js +77 -0
- package/dist/commands/task/finish.d.ts +2 -0
- package/dist/commands/task/finish.d.ts.map +1 -1
- package/dist/commands/task/finish.js +52 -10
- package/dist/commands/task/index.d.ts +3 -0
- package/dist/commands/task/index.d.ts.map +1 -1
- package/dist/commands/task/index.js +3 -0
- package/dist/commands/task/new.d.ts.map +1 -1
- package/dist/commands/task/new.js +34 -6
- package/dist/commands/task/new.spec.js +1 -1
- package/dist/commands/task/plan.d.ts.map +1 -1
- package/dist/commands/task/plan.js +2 -3
- package/dist/commands/task/set-status.d.ts.map +1 -1
- package/dist/commands/task/set-status.js +12 -9
- package/dist/commands/task/shared.d.ts +19 -0
- package/dist/commands/task/shared.d.ts.map +1 -1
- package/dist/commands/task/shared.js +137 -0
- package/dist/commands/task/start-ready.command.d.ts +14 -0
- package/dist/commands/task/start-ready.command.d.ts.map +1 -0
- package/dist/commands/task/start-ready.command.js +77 -0
- package/dist/commands/task/start-ready.d.ts +13 -0
- package/dist/commands/task/start-ready.d.ts.map +1 -0
- package/dist/commands/task/start-ready.js +46 -0
- package/dist/commands/task/start.d.ts.map +1 -1
- package/dist/commands/task/start.js +13 -11
- package/dist/commands/task/update.command.d.ts +1 -0
- package/dist/commands/task/update.command.d.ts.map +1 -1
- package/dist/commands/task/update.command.js +8 -0
- package/dist/commands/task/update.d.ts +1 -0
- package/dist/commands/task/update.d.ts.map +1 -1
- package/dist/commands/task/update.js +19 -3
- package/dist/shared/errors.d.ts +9 -1
- package/dist/shared/errors.d.ts.map +1 -1
- package/dist/shared/errors.js +3 -1
- package/dist/shared/runtime-artifacts.d.ts +3 -0
- package/dist/shared/runtime-artifacts.d.ts.map +1 -0
- package/dist/shared/runtime-artifacts.js +18 -0
- package/dist/usecases/context/resolve-context.d.ts +3 -0
- package/dist/usecases/context/resolve-context.d.ts.map +1 -1
- package/dist/usecases/context/resolve-context.js +6 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write-config.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/init/write-config.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC;IACpD,gBAAgB,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC5C,WAAW,EAAE;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,yCAAyC,EAAE,MAAM,EAAE,CAAC;CACrD,CAAC;AAEF,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,OAAO,GAAG,SAAS,GAC3B,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,GAAG,WAAW,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,sBAAsB,EAAE,OAAO,CAAC;IAChC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,SAAS,EAAE,mBAAmB,CAAC;CAChC,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"write-config.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/init/write-config.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC;IACpD,gBAAgB,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC5C,WAAW,EAAE;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,yCAAyC,EAAE,MAAM,EAAE,CAAC;CACrD,CAAC;AAEF,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,OAAO,GAAG,SAAS,GAC3B,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,GAAG,WAAW,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,sBAAsB,EAAE,OAAO,CAAC;IAChC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,SAAS,EAAE,mBAAmB,CAAC;CAChC,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBhB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBhB"}
|
|
@@ -13,6 +13,8 @@ export async function ensureAgentplaneDirs(agentplaneDir, backend) {
|
|
|
13
13
|
export async function writeInitConfig(opts) {
|
|
14
14
|
const rawConfig = defaultConfig();
|
|
15
15
|
setByDottedKey(rawConfig, "workflow_mode", opts.workflow);
|
|
16
|
+
setByDottedKey(rawConfig, "status_commit_policy", opts.workflow === "branch_pr" ? "confirm" : "warn");
|
|
17
|
+
setByDottedKey(rawConfig, "finish_auto_status_commit", String(opts.workflow === "branch_pr"));
|
|
16
18
|
setByDottedKey(rawConfig, "tasks_backend.config_path", path.relative(opts.gitRoot, opts.backendConfigPathAbs));
|
|
17
19
|
setByDottedKey(rawConfig, "agents.approvals.require_plan", String(opts.requirePlanApproval));
|
|
18
20
|
setByDottedKey(rawConfig, "agents.approvals.require_network", String(opts.requireNetworkApproval));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write-gitignore.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/init/write-gitignore.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"write-gitignore.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/init/write-gitignore.ts"],"names":[],"mappings":"AAmBA,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,uBAAuB,EAAE,OAAO,CAAC;CAClC,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBhB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { AGENT_PROMPT_GITIGNORE_LINES, RUNTIME_GITIGNORE_LINES, } from "../../../../shared/runtime-artifacts.js";
|
|
3
4
|
import { writeTextIfChanged } from "../../../../shared/write-if-changed.js";
|
|
4
5
|
async function readTextIfExists(filePath) {
|
|
5
6
|
try {
|
|
@@ -12,28 +13,12 @@ async function readTextIfExists(filePath) {
|
|
|
12
13
|
throw err;
|
|
13
14
|
}
|
|
14
15
|
}
|
|
15
|
-
const RUNTIME_IGNORE_LINES = [
|
|
16
|
-
"# agentplane: ignore runtime/transient workspace artifacts",
|
|
17
|
-
".env",
|
|
18
|
-
".agentplane/worktrees",
|
|
19
|
-
".agentplane/cache",
|
|
20
|
-
".agentplane/recipes-cache",
|
|
21
|
-
".agentplane/.upgrade",
|
|
22
|
-
".agentplane/.release",
|
|
23
|
-
".agentplane/upgrade",
|
|
24
|
-
".agentplane/tasks.json",
|
|
25
|
-
];
|
|
26
|
-
const AGENT_PROMPT_IGNORE_LINES = [
|
|
27
|
-
"# agentplane: ignore local agent prompts/templates",
|
|
28
|
-
"AGENTS.md",
|
|
29
|
-
".agentplane/agents/",
|
|
30
|
-
];
|
|
31
16
|
export async function ensureInitGitignore(opts) {
|
|
32
17
|
const gitignorePath = path.join(opts.gitRoot, ".gitignore");
|
|
33
18
|
const existing = (await readTextIfExists(gitignorePath)) ?? "";
|
|
34
19
|
const ensuredLines = opts.includeAgentPromptFiles
|
|
35
|
-
? [...
|
|
36
|
-
: [...
|
|
20
|
+
? [...RUNTIME_GITIGNORE_LINES, ...AGENT_PROMPT_GITIGNORE_LINES]
|
|
21
|
+
: [...RUNTIME_GITIGNORE_LINES];
|
|
37
22
|
const existingLines = existing.split(/\r?\n/);
|
|
38
23
|
const existingSet = new Set(existingLines.map((line) => line.trimEnd()));
|
|
39
24
|
const missing = ensuredLines.filter((line) => !existingSet.has(line));
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { CommandHandler, CommandSpec } from "../../spec/spec.js";
|
|
2
2
|
import { type ExecutionProfile } from "@agentplaneorg/core";
|
|
3
3
|
type InitFlags = {
|
|
4
|
+
setupProfile?: "prod" | "dev";
|
|
4
5
|
ide?: "codex" | "cursor" | "windsurf";
|
|
5
6
|
workflow?: "direct" | "branch_pr";
|
|
6
7
|
backend?: "local" | "redmine";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../src/cli/run-cli/commands/init.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItE,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAC;AAa7B,KAAK,SAAS,GAAG;IACf,GAAG,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;IACtC,QAAQ,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAsBF,KAAK,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,CAAC;AAE5D,eAAO,MAAM,QAAQ,EAAE,WAAW,CAAC,UAAU,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../src/cli/run-cli/commands/init.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItE,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAC;AAa7B,KAAK,SAAS,GAAG;IACf,YAAY,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC9B,GAAG,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;IACtC,QAAQ,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAsBF,KAAK,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,CAAC;AAE5D,eAAO,MAAM,QAAQ,EAAE,WAAW,CAAC,UAAU,CAoL5C,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,cAAc,CAAC,UAAU,CACmB,CAAC"}
|
|
@@ -45,6 +45,13 @@ export const initSpec = {
|
|
|
45
45
|
summary: "Initialize agentplane project files under .agentplane/.",
|
|
46
46
|
description: "Creates .agentplane/ config, backend stubs, and agent templates in the target directory. If the target directory is not a git repository, it initializes one and (by default) writes an initial install commit. Use --gitignore-agents to keep agent templates local (gitignored) and skip the install commit. In interactive mode it prompts for missing inputs; use --yes for non-interactive mode.",
|
|
47
47
|
options: [
|
|
48
|
+
{
|
|
49
|
+
kind: "string",
|
|
50
|
+
name: "setup-profile",
|
|
51
|
+
valueHint: "<prod|dev>",
|
|
52
|
+
choices: ["prod", "dev"],
|
|
53
|
+
description: "Interactive preset. prod asks only essential questions; dev asks the full setup questionnaire.",
|
|
54
|
+
},
|
|
48
55
|
{
|
|
49
56
|
kind: "string",
|
|
50
57
|
name: "ide",
|
|
@@ -167,6 +174,7 @@ export const initSpec = {
|
|
|
167
174
|
const requireVerifyRaw = raw.opts["require-verify-approval"];
|
|
168
175
|
const recipesRaw = raw.opts.recipes;
|
|
169
176
|
return {
|
|
177
|
+
setupProfile: raw.opts["setup-profile"],
|
|
170
178
|
ide: raw.opts.ide,
|
|
171
179
|
workflow: raw.opts.workflow,
|
|
172
180
|
backend: raw.opts.backend,
|
|
@@ -226,6 +234,7 @@ async function cmdInit(opts) {
|
|
|
226
234
|
let requireVerifyApproval = flags.requireVerifyApproval ?? defaults.requireVerifyApproval;
|
|
227
235
|
let executionProfile = flags.executionProfile ?? defaults.executionProfile;
|
|
228
236
|
let strictUnsafeConfirm = flags.strictUnsafeConfirm ?? defaults.strictUnsafeConfirm;
|
|
237
|
+
let setupProfile = flags.setupProfile ?? "prod";
|
|
229
238
|
const isInteractive = process.stdin.isTTY && !flags.yes;
|
|
230
239
|
if (!process.stdin.isTTY &&
|
|
231
240
|
!flags.yes &&
|
|
@@ -257,9 +266,13 @@ async function cmdInit(opts) {
|
|
|
257
266
|
return result;
|
|
258
267
|
};
|
|
259
268
|
process.stdout.write(renderInitWelcome());
|
|
269
|
+
process.stdout.write(renderInitSection("Setup Profile", "Choose how much init should ask. prod keeps the flow compact; dev exposes full controls."));
|
|
270
|
+
if (!flags.setupProfile) {
|
|
271
|
+
setupProfile = (await askChoice("Setup profile", ["prod", "dev"], setupProfile));
|
|
272
|
+
}
|
|
260
273
|
process.stdout.write(renderInitSection("Workflow", "Choose how branches/backends/approvals should be initialized for this repository."));
|
|
261
274
|
ide = flags.ide ?? defaults.ide;
|
|
262
|
-
if (!flags.workflow) {
|
|
275
|
+
if (!flags.workflow && setupProfile === "dev") {
|
|
263
276
|
const choice = await askChoice("Workflow mode", ["direct", "branch_pr"], workflow);
|
|
264
277
|
workflow = choice === "branch_pr" ? "branch_pr" : "direct";
|
|
265
278
|
}
|
|
@@ -267,36 +280,48 @@ async function cmdInit(opts) {
|
|
|
267
280
|
const choice = await askChoice("Task backend", ["local", "redmine"], backend);
|
|
268
281
|
backend = choice === "redmine" ? "redmine" : "local";
|
|
269
282
|
}
|
|
270
|
-
if (
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
283
|
+
if (setupProfile === "dev") {
|
|
284
|
+
if (flags.hooks === undefined) {
|
|
285
|
+
hooks = await askYesNo("Install managed git hooks now?", hooks);
|
|
286
|
+
}
|
|
287
|
+
process.stdout.write(renderInitSection("Execution Profile", "Set default autonomy/effort for agents. You can change this later in config."));
|
|
288
|
+
if (!flags.executionProfile) {
|
|
289
|
+
executionProfile = (await askChoice("Execution profile", ["conservative", "balanced", "aggressive"], executionProfile));
|
|
290
|
+
}
|
|
291
|
+
if (flags.strictUnsafeConfirm === undefined) {
|
|
292
|
+
strictUnsafeConfirm = await askYesNo("Require strict explicit confirmation for extra unsafe actions?", strictUnsafeConfirm);
|
|
293
|
+
}
|
|
294
|
+
process.stdout.write(renderInitSection("Approvals", "Control whether plan/network/verification actions require explicit approval by default."));
|
|
295
|
+
if (flags.requirePlanApproval === undefined) {
|
|
296
|
+
requirePlanApproval = await askYesNo("Require plan approval before work starts?", requirePlanApproval);
|
|
297
|
+
}
|
|
298
|
+
if (flags.requireNetworkApproval === undefined) {
|
|
299
|
+
requireNetworkApproval = await askYesNo("Require explicit approval for network actions?", requireNetworkApproval);
|
|
300
|
+
}
|
|
301
|
+
if (flags.requireVerifyApproval === undefined) {
|
|
302
|
+
requireVerifyApproval = await askYesNo("Require explicit approval before recording verification?", requireVerifyApproval);
|
|
303
|
+
}
|
|
304
|
+
process.stdout.write(renderInitSection("Recipes", "Optional: install recipe packs now (comma-separated IDs) or choose none."));
|
|
305
|
+
if (!flags.recipes) {
|
|
306
|
+
process.stdout.write(`${renderBundledRecipesHint()}\n`);
|
|
307
|
+
const answer = await askInput("Install optional recipes (comma separated, or none): ");
|
|
308
|
+
recipes = answer
|
|
309
|
+
? answer
|
|
310
|
+
.split(",")
|
|
311
|
+
.map((item) => item.trim())
|
|
312
|
+
.filter(Boolean)
|
|
313
|
+
: [];
|
|
314
|
+
}
|
|
289
315
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
: [];
|
|
316
|
+
else {
|
|
317
|
+
hooks = flags.hooks ?? defaults.hooks;
|
|
318
|
+
recipes = flags.recipes ?? defaults.recipes;
|
|
319
|
+
requirePlanApproval = flags.requirePlanApproval ?? defaults.requirePlanApproval;
|
|
320
|
+
requireNetworkApproval = flags.requireNetworkApproval ?? defaults.requireNetworkApproval;
|
|
321
|
+
requireVerifyApproval = flags.requireVerifyApproval ?? defaults.requireVerifyApproval;
|
|
322
|
+
executionProfile = flags.executionProfile ?? defaults.executionProfile;
|
|
323
|
+
strictUnsafeConfirm = flags.strictUnsafeConfirm ?? defaults.strictUnsafeConfirm;
|
|
324
|
+
process.stdout.write(renderInitSection("Defaults Applied", "Using compact prod defaults for hooks, approvals, execution profile, and recipes."));
|
|
300
325
|
}
|
|
301
326
|
}
|
|
302
327
|
if (flags.yes) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-cli.d.ts","sourceRoot":"","sources":["../../src/cli/run-cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-cli.d.ts","sourceRoot":"","sources":["../../src/cli/run-cli.ts"],"names":[],"mappings":"AAibA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAmL5D"}
|
package/dist/cli/run-cli.js
CHANGED
|
@@ -134,9 +134,9 @@ function matchCommandCatalog(tokens) {
|
|
|
134
134
|
return best;
|
|
135
135
|
}
|
|
136
136
|
function writeError(err, jsonErrors) {
|
|
137
|
-
const
|
|
137
|
+
const guidance = resolveErrorGuidance(err);
|
|
138
138
|
if (jsonErrors) {
|
|
139
|
-
process.stdout.write(`${formatJsonError(err)}\n`);
|
|
139
|
+
process.stdout.write(`${formatJsonError(err, { hint: guidance.hint, nextAction: guidance.nextAction })}\n`);
|
|
140
140
|
}
|
|
141
141
|
else {
|
|
142
142
|
const header = `error [${err.code}]`;
|
|
@@ -146,8 +146,11 @@ function writeError(err, jsonErrors) {
|
|
|
146
146
|
else {
|
|
147
147
|
process.stderr.write(`${header}: ${err.message}\n`);
|
|
148
148
|
}
|
|
149
|
-
if (hint) {
|
|
150
|
-
process.stderr.write(`hint: ${hint}\n`);
|
|
149
|
+
if (guidance.hint) {
|
|
150
|
+
process.stderr.write(`hint: ${guidance.hint}\n`);
|
|
151
|
+
}
|
|
152
|
+
if (guidance.nextAction) {
|
|
153
|
+
process.stderr.write(`next_action: ${guidance.nextAction.command} (${guidance.nextAction.reason})\n`);
|
|
151
154
|
}
|
|
152
155
|
}
|
|
153
156
|
}
|
|
@@ -158,33 +161,92 @@ function resolveAgentplaneHome() {
|
|
|
158
161
|
return overridden;
|
|
159
162
|
return path.join(os.homedir(), ".agentplane");
|
|
160
163
|
}
|
|
161
|
-
function
|
|
164
|
+
function resolveErrorGuidance(err) {
|
|
162
165
|
const command = typeof err.context?.command === "string" ? err.context.command : undefined;
|
|
163
166
|
const usage = command ? `agentplane help ${command} --compact` : "agentplane help";
|
|
164
167
|
switch (err.code) {
|
|
165
168
|
case "E_USAGE": {
|
|
166
|
-
return
|
|
169
|
+
return {
|
|
170
|
+
hint: `See \`${usage}\` for usage.`,
|
|
171
|
+
nextAction: {
|
|
172
|
+
command: usage,
|
|
173
|
+
reason: "inspect required arguments and flags",
|
|
174
|
+
reasonCode: "usage_help",
|
|
175
|
+
},
|
|
176
|
+
};
|
|
167
177
|
}
|
|
168
178
|
case "E_GIT": {
|
|
169
179
|
if (command?.startsWith("branch")) {
|
|
170
|
-
return
|
|
180
|
+
return {
|
|
181
|
+
hint: "Check git repo/branch; run `git branch` or pass --root <path>.",
|
|
182
|
+
nextAction: {
|
|
183
|
+
command: "git branch",
|
|
184
|
+
reason: "inspect repository branch state",
|
|
185
|
+
reasonCode: "git_branch_state",
|
|
186
|
+
},
|
|
187
|
+
};
|
|
171
188
|
}
|
|
172
189
|
if (command === "guard commit" || command === "commit") {
|
|
173
|
-
return
|
|
190
|
+
return {
|
|
191
|
+
hint: "Check git status/index; stage changes and retry.",
|
|
192
|
+
nextAction: {
|
|
193
|
+
command: "git status --short",
|
|
194
|
+
reason: "inspect staged/unstaged changes before commit",
|
|
195
|
+
reasonCode: "git_index_state",
|
|
196
|
+
},
|
|
197
|
+
};
|
|
174
198
|
}
|
|
175
|
-
return
|
|
199
|
+
return {
|
|
200
|
+
hint: "Check git repo context; pass --root <path> if needed.",
|
|
201
|
+
nextAction: {
|
|
202
|
+
command: "git status --short --untracked-files=no",
|
|
203
|
+
reason: "confirm repository context and tracked changes",
|
|
204
|
+
reasonCode: "git_context",
|
|
205
|
+
},
|
|
206
|
+
};
|
|
176
207
|
}
|
|
177
208
|
case "E_NETWORK": {
|
|
178
|
-
return
|
|
209
|
+
return {
|
|
210
|
+
hint: "Check network access and credentials.",
|
|
211
|
+
nextAction: {
|
|
212
|
+
command: "agentplane preflight --json",
|
|
213
|
+
reason: "recheck approvals and network requirements",
|
|
214
|
+
reasonCode: "network_gate",
|
|
215
|
+
},
|
|
216
|
+
};
|
|
179
217
|
}
|
|
180
218
|
case "E_BACKEND": {
|
|
181
219
|
if (command?.includes("sync")) {
|
|
182
|
-
return
|
|
220
|
+
return {
|
|
221
|
+
hint: "Check backend config under .agentplane/backends and retry.",
|
|
222
|
+
nextAction: {
|
|
223
|
+
command: "agentplane config show",
|
|
224
|
+
reason: "verify backend config path and active settings",
|
|
225
|
+
reasonCode: "backend_sync_config",
|
|
226
|
+
},
|
|
227
|
+
};
|
|
183
228
|
}
|
|
184
|
-
return
|
|
229
|
+
return {
|
|
230
|
+
hint: "Check backend config under .agentplane/backends.",
|
|
231
|
+
nextAction: {
|
|
232
|
+
command: "agentplane config show",
|
|
233
|
+
reason: "inspect backend configuration",
|
|
234
|
+
reasonCode: "backend_config",
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
case "E_VALIDATION": {
|
|
239
|
+
return {
|
|
240
|
+
hint: "Fix invalid config/input shape and rerun.",
|
|
241
|
+
nextAction: {
|
|
242
|
+
command: "agentplane preflight --json",
|
|
243
|
+
reason: "pinpoint validation failure in one report",
|
|
244
|
+
reasonCode: "validation_preflight",
|
|
245
|
+
},
|
|
246
|
+
};
|
|
185
247
|
}
|
|
186
248
|
default: {
|
|
187
|
-
return
|
|
249
|
+
return {};
|
|
188
250
|
}
|
|
189
251
|
}
|
|
190
252
|
}
|
|
@@ -395,7 +457,16 @@ export async function runCli(argv) {
|
|
|
395
457
|
});
|
|
396
458
|
let ctxPromise = null;
|
|
397
459
|
const getCtx = async (commandForErrorContext) => {
|
|
398
|
-
ctxPromise ??=
|
|
460
|
+
ctxPromise ??= (async () => {
|
|
461
|
+
const resolvedProject = await getResolvedProject(commandForErrorContext);
|
|
462
|
+
const loadedConfig = await getLoadedConfig(commandForErrorContext);
|
|
463
|
+
return await resolveContext({
|
|
464
|
+
cwd,
|
|
465
|
+
rootOverride: globals.root ?? null,
|
|
466
|
+
resolvedProject,
|
|
467
|
+
config: loadedConfig.config,
|
|
468
|
+
});
|
|
469
|
+
})();
|
|
399
470
|
try {
|
|
400
471
|
return await ctxPromise;
|
|
401
472
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit.command.d.ts","sourceRoot":"","sources":["../../src/commands/commit.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAI/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IACrE,KAAK,UAAU,EAAE,GAAG,YAAY,KAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"commit.command.d.ts","sourceRoot":"","sources":["../../src/commands/commit.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAI/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IACrE,KAAK,UAAU,EAAE,GAAG,YAAY,KAAG,OAAO,CAAC,MAAM,CAAC,CAsBjE"}
|
|
@@ -13,6 +13,8 @@ export type CommitParsed = {
|
|
|
13
13
|
allowCI: boolean;
|
|
14
14
|
requireClean: boolean;
|
|
15
15
|
quiet: boolean;
|
|
16
|
+
closeUnstageOthers: boolean;
|
|
17
|
+
closeCheckOnly: boolean;
|
|
16
18
|
};
|
|
17
19
|
export declare const commitSpec: CommandSpec<CommitParsed>;
|
|
18
20
|
//# sourceMappingURL=commit.spec.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit.spec.d.ts","sourceRoot":"","sources":["../../src/commands/commit.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGvD,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"commit.spec.d.ts","sourceRoot":"","sources":["../../src/commands/commit.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGvD,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,kBAAkB,EAAE,OAAO,CAAC;IAC5B,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CAmJhD,CAAC"}
|
|
@@ -18,6 +18,18 @@ export const commitSpec = {
|
|
|
18
18
|
default: false,
|
|
19
19
|
description: "Generate a deterministic close commit message from task snapshot + verification + recorded implementation commit; stages only the task README.",
|
|
20
20
|
},
|
|
21
|
+
{
|
|
22
|
+
kind: "boolean",
|
|
23
|
+
name: "unstage-others",
|
|
24
|
+
default: false,
|
|
25
|
+
description: "With --close: unstage any currently staged paths before staging the task README.",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
kind: "boolean",
|
|
29
|
+
name: "check-only",
|
|
30
|
+
default: false,
|
|
31
|
+
description: "With --close: run preflight checks and print the planned close commit subject without creating a commit.",
|
|
32
|
+
},
|
|
21
33
|
{
|
|
22
34
|
kind: "string",
|
|
23
35
|
name: "allow",
|
|
@@ -92,6 +104,18 @@ export const commitSpec = {
|
|
|
92
104
|
message: "Use either --message or --close (not both).",
|
|
93
105
|
});
|
|
94
106
|
}
|
|
107
|
+
if (!close && raw.opts["unstage-others"] === true) {
|
|
108
|
+
throw usageError({
|
|
109
|
+
spec: commitSpec,
|
|
110
|
+
message: "--unstage-others requires --close.",
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
if (!close && raw.opts["check-only"] === true) {
|
|
114
|
+
throw usageError({
|
|
115
|
+
spec: commitSpec,
|
|
116
|
+
message: "--check-only requires --close.",
|
|
117
|
+
});
|
|
118
|
+
}
|
|
95
119
|
const allow = raw.opts.allow;
|
|
96
120
|
if (Array.isArray(allow) && allow.some((s) => typeof s === "string" && s.trim() === "")) {
|
|
97
121
|
throw usageError({ spec: commitSpec, message: "Invalid value for --allow: empty." });
|
|
@@ -115,5 +139,7 @@ export const commitSpec = {
|
|
|
115
139
|
allowCI: raw.opts["allow-ci"] === true,
|
|
116
140
|
requireClean: raw.opts["require-clean"] === true,
|
|
117
141
|
quiet: raw.opts.quiet === true,
|
|
142
|
+
closeUnstageOthers: raw.opts["unstage-others"] === true,
|
|
143
|
+
closeCheckOnly: raw.opts["check-only"] === true,
|
|
118
144
|
}),
|
|
119
145
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.run.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.run.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.run.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.run.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAK1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAsPrD,eAAO,MAAM,SAAS,EAAE,cAAc,CAAC,YAAY,CAwBlD,CAAC"}
|
|
@@ -2,6 +2,7 @@ import fs from "node:fs/promises";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { resolveProject } from "@agentplaneorg/core";
|
|
4
4
|
import { warnMessage, successMessage } from "../cli/output.js";
|
|
5
|
+
import { RUNTIME_GITIGNORE_LINES } from "../shared/runtime-artifacts.js";
|
|
5
6
|
import { execFileAsync, gitEnv } from "./shared/git.js";
|
|
6
7
|
import { loadCommandContext } from "./shared/task-backend.js";
|
|
7
8
|
async function listTsFiles(rootDir) {
|
|
@@ -132,13 +133,21 @@ async function safeFixGitignore(repoRoot) {
|
|
|
132
133
|
return { changed: false, note: "Skip: .gitignore not found." };
|
|
133
134
|
}
|
|
134
135
|
const lines = existing.split(/\r?\n/);
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
const existingSet = new Set(lines.map((line) => line.trimEnd()));
|
|
137
|
+
const missing = RUNTIME_GITIGNORE_LINES.filter((line) => !existingSet.has(line));
|
|
138
|
+
if (missing.length === 0) {
|
|
139
|
+
return { changed: false, note: "OK: .gitignore already contains agentplane runtime ignores." };
|
|
140
|
+
}
|
|
141
|
+
const nextLines = [...lines];
|
|
142
|
+
if (nextLines.length > 0 && nextLines.at(-1) !== "")
|
|
143
|
+
nextLines.push("");
|
|
144
|
+
nextLines.push(...missing, "");
|
|
145
|
+
const next = `${nextLines.join("\n")}`.replaceAll(/\n{2,}$/g, "\n");
|
|
140
146
|
await fs.writeFile(gitignorePath, next, "utf8");
|
|
141
|
-
return {
|
|
147
|
+
return {
|
|
148
|
+
changed: true,
|
|
149
|
+
note: `Fixed: added agentplane runtime ignores to .gitignore (${missing.length} lines).`,
|
|
150
|
+
};
|
|
142
151
|
}
|
|
143
152
|
async function safeFixTaskIndex(repoRoot) {
|
|
144
153
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"finish.run.d.ts","sourceRoot":"","sources":["../../src/commands/finish.run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG/D,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEjE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IACrE,KAAK,UAAU,EAAE,GAAG,YAAY,KAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"finish.run.d.ts","sourceRoot":"","sources":["../../src/commands/finish.run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG/D,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEjE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IACrE,KAAK,UAAU,EAAE,GAAG,YAAY,KAAG,OAAO,CAAC,MAAM,CAAC,CAsCjE"}
|
|
@@ -35,6 +35,8 @@ export function makeRunFinishHandler(getCtx) {
|
|
|
35
35
|
statusCommitAutoAllow: p.statusCommitAutoAllow,
|
|
36
36
|
statusCommitRequireClean: p.statusCommitRequireClean,
|
|
37
37
|
confirmStatusCommit: p.confirmStatusCommit,
|
|
38
|
+
closeCommit: p.closeCommit,
|
|
39
|
+
closeUnstageOthers: p.closeUnstageOthers,
|
|
38
40
|
quiet: p.quiet,
|
|
39
41
|
});
|
|
40
42
|
};
|
|
@@ -21,6 +21,8 @@ export type FinishParsed = {
|
|
|
21
21
|
statusCommitAutoAllow: boolean;
|
|
22
22
|
statusCommitRequireClean: boolean;
|
|
23
23
|
confirmStatusCommit: boolean;
|
|
24
|
+
closeCommit: boolean;
|
|
25
|
+
closeUnstageOthers: boolean;
|
|
24
26
|
quiet: boolean;
|
|
25
27
|
};
|
|
26
28
|
export declare const finishSpec: CommandSpec<FinishParsed>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"finish.spec.d.ts","sourceRoot":"","sources":["../../src/commands/finish.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAKvD,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,wBAAwB,EAAE,OAAO,CAAC;IAClC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"finish.spec.d.ts","sourceRoot":"","sources":["../../src/commands/finish.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAKvD,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,wBAAwB,EAAE,OAAO,CAAC;IAClC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CAqPhD,CAAC"}
|
|
@@ -136,6 +136,18 @@ export const finishSpec = {
|
|
|
136
136
|
default: false,
|
|
137
137
|
description: "Confirm status commit creation when status_commit_policy=confirm (used with --commit-from-comment or --status-commit).",
|
|
138
138
|
},
|
|
139
|
+
{
|
|
140
|
+
kind: "boolean",
|
|
141
|
+
name: "close-commit",
|
|
142
|
+
default: false,
|
|
143
|
+
description: "After finishing, run a deterministic close commit for the task README (single-task only).",
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
kind: "boolean",
|
|
147
|
+
name: "close-unstage-others",
|
|
148
|
+
default: false,
|
|
149
|
+
description: "With --close-commit: unstage any currently staged paths before staging the task README.",
|
|
150
|
+
},
|
|
139
151
|
{ kind: "boolean", name: "quiet", default: false, description: "Suppress output." },
|
|
140
152
|
],
|
|
141
153
|
examples: [
|
|
@@ -160,6 +172,28 @@ export const finishSpec = {
|
|
|
160
172
|
message: "--commit-from-comment/--status-commit requires exactly one task id",
|
|
161
173
|
});
|
|
162
174
|
}
|
|
175
|
+
if (raw.opts["close-commit"] === true && taskIds.length !== 1) {
|
|
176
|
+
throw usageError({
|
|
177
|
+
spec: finishSpec,
|
|
178
|
+
command: "finish",
|
|
179
|
+
message: "--close-commit requires exactly one task id",
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
if (raw.opts["close-commit"] === true &&
|
|
183
|
+
(raw.opts["commit-from-comment"] === true || raw.opts["status-commit"] === true)) {
|
|
184
|
+
throw usageError({
|
|
185
|
+
spec: finishSpec,
|
|
186
|
+
command: "finish",
|
|
187
|
+
message: "--close-commit cannot be combined with --commit-from-comment/--status-commit",
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
if (raw.opts["close-unstage-others"] === true && raw.opts["close-commit"] !== true) {
|
|
191
|
+
throw usageError({
|
|
192
|
+
spec: finishSpec,
|
|
193
|
+
command: "finish",
|
|
194
|
+
message: "--close-unstage-others requires --close-commit",
|
|
195
|
+
});
|
|
196
|
+
}
|
|
163
197
|
const hasMeta = typeof raw.opts.result === "string" ||
|
|
164
198
|
typeof raw.opts.risk === "string" ||
|
|
165
199
|
raw.opts.breaking === true;
|
|
@@ -195,6 +229,8 @@ export const finishSpec = {
|
|
|
195
229
|
statusCommitAutoAllow: raw.opts["status-commit-auto-allow"] === true,
|
|
196
230
|
statusCommitRequireClean: raw.opts["status-commit-require-clean"] === true,
|
|
197
231
|
confirmStatusCommit: raw.opts["confirm-status-commit"] === true,
|
|
232
|
+
closeCommit: raw.opts["close-commit"] === true,
|
|
233
|
+
closeUnstageOthers: raw.opts["close-unstage-others"] === true,
|
|
198
234
|
quiet: raw.opts.quiet === true,
|
|
199
235
|
}),
|
|
200
236
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"allow.d.ts","sourceRoot":"","sources":["../../../../src/commands/guard/impl/allow.ts"],"names":[],"mappings":"AAMA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"allow.d.ts","sourceRoot":"","sources":["../../../../src/commands/guard/impl/allow.ts"],"names":[],"mappings":"AAMA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAkBvF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAe9D;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAOpB;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBhB;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,GAAG,EAAE,cAAc,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA2CpB"}
|
|
@@ -4,18 +4,37 @@ import { gitPathIsUnderPrefix, normalizeGitPathPrefix } from "../../../shared/gi
|
|
|
4
4
|
import { CliError } from "../../../shared/errors.js";
|
|
5
5
|
import { GitContext } from "../../shared/git-context.js";
|
|
6
6
|
import { loadCommandContext } from "../../shared/task-backend.js";
|
|
7
|
+
function normalizeAllowPrefixes(prefixes) {
|
|
8
|
+
const unique = [
|
|
9
|
+
...new Set(prefixes.map((prefix) => normalizeGitPathPrefix(prefix)).filter(Boolean)),
|
|
10
|
+
].toSorted((a, b) => (a.length === b.length ? a.localeCompare(b) : a.length - b.length));
|
|
11
|
+
// "." is repo-wide and makes all other prefixes redundant.
|
|
12
|
+
if (unique.includes("."))
|
|
13
|
+
return ["."];
|
|
14
|
+
const compact = [];
|
|
15
|
+
for (const prefix of unique) {
|
|
16
|
+
if (compact.some((existing) => gitPathIsUnderPrefix(prefix, existing)))
|
|
17
|
+
continue;
|
|
18
|
+
compact.push(prefix);
|
|
19
|
+
}
|
|
20
|
+
return compact;
|
|
21
|
+
}
|
|
7
22
|
export function suggestAllowPrefixes(paths) {
|
|
8
23
|
const out = new Set();
|
|
9
24
|
for (const filePath of paths) {
|
|
10
25
|
if (!filePath)
|
|
11
26
|
continue;
|
|
12
|
-
const
|
|
13
|
-
if (
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
27
|
+
const trimmed = filePath.trim();
|
|
28
|
+
if (!trimmed)
|
|
29
|
+
continue;
|
|
30
|
+
const idx = trimmed.lastIndexOf("/");
|
|
31
|
+
const rawPrefix = idx <= 0 ? trimmed : trimmed.slice(0, idx);
|
|
32
|
+
const normalized = normalizeGitPathPrefix(rawPrefix);
|
|
33
|
+
if (!normalized)
|
|
34
|
+
continue;
|
|
35
|
+
out.add(rawPrefix.startsWith("/") && !normalized.startsWith("/") ? `/${normalized}` : normalized);
|
|
17
36
|
}
|
|
18
|
-
return [...out].toSorted((a, b) => a.localeCompare(b));
|
|
37
|
+
return [...out].filter(Boolean).toSorted((a, b) => a.localeCompare(b));
|
|
19
38
|
}
|
|
20
39
|
export async function gitStatusChangedPaths(opts) {
|
|
21
40
|
const resolved = await resolveProject({
|
|
@@ -55,7 +74,14 @@ export async function stageAllowlist(opts) {
|
|
|
55
74
|
message: "No changes to stage (working tree clean)",
|
|
56
75
|
});
|
|
57
76
|
}
|
|
58
|
-
const allow = opts.allow
|
|
77
|
+
const allow = normalizeAllowPrefixes(opts.allow);
|
|
78
|
+
if (allow.length === 0) {
|
|
79
|
+
throw new CliError({
|
|
80
|
+
exitCode: 2,
|
|
81
|
+
code: "E_USAGE",
|
|
82
|
+
message: "Provide at least one allowed prefix",
|
|
83
|
+
});
|
|
84
|
+
}
|
|
59
85
|
const denied = new Set();
|
|
60
86
|
if (!opts.allowTasks)
|
|
61
87
|
denied.add(opts.tasksPath);
|