agentplane 0.2.23 → 0.2.25

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 (58) hide show
  1. package/assets/AGENTS.md +44 -30
  2. package/assets/agents/CODER.json +1 -1
  3. package/assets/agents/DOCS.json +1 -1
  4. package/assets/agents/ORCHESTRATOR.json +10 -9
  5. package/assets/agents/PLANNER.json +9 -4
  6. package/assets/agents/TESTER.json +1 -1
  7. package/dist/cli/command-guide.js +7 -7
  8. package/dist/cli/run-cli/commands/init.d.ts +1 -1
  9. package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
  10. package/dist/cli/run-cli/commands/init.js +80 -37
  11. package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
  12. package/dist/cli/run-cli.test-helpers.js +4 -5
  13. package/dist/commands/block.spec.d.ts.map +1 -1
  14. package/dist/commands/block.spec.js +23 -2
  15. package/dist/commands/commit.spec.d.ts.map +1 -1
  16. package/dist/commands/commit.spec.js +18 -6
  17. package/dist/commands/finish.spec.d.ts.map +1 -1
  18. package/dist/commands/finish.spec.js +53 -4
  19. package/dist/commands/guard/commit.command.d.ts.map +1 -1
  20. package/dist/commands/guard/commit.command.js +26 -20
  21. package/dist/commands/guard/impl/allow.d.ts.map +1 -1
  22. package/dist/commands/guard/impl/allow.js +8 -1
  23. package/dist/commands/guard/impl/commands.d.ts.map +1 -1
  24. package/dist/commands/guard/impl/commands.js +7 -15
  25. package/dist/commands/guard/impl/comment-commit.d.ts.map +1 -1
  26. package/dist/commands/guard/impl/comment-commit.js +8 -17
  27. package/dist/commands/hooks/index.d.ts.map +1 -1
  28. package/dist/commands/hooks/index.js +20 -6
  29. package/dist/commands/release/apply.command.d.ts.map +1 -1
  30. package/dist/commands/release/apply.command.js +18 -3
  31. package/dist/commands/release/plan.command.js +1 -1
  32. package/dist/commands/scenario/impl/commands.d.ts +18 -0
  33. package/dist/commands/scenario/impl/commands.d.ts.map +1 -1
  34. package/dist/commands/scenario/impl/commands.js +37 -5
  35. package/dist/commands/shared/pr-meta.d.ts +5 -0
  36. package/dist/commands/shared/pr-meta.d.ts.map +1 -1
  37. package/dist/commands/shared/pr-meta.js +11 -1
  38. package/dist/commands/start.spec.d.ts.map +1 -1
  39. package/dist/commands/start.spec.js +23 -2
  40. package/dist/commands/task/finish.d.ts.map +1 -1
  41. package/dist/commands/task/finish.js +32 -10
  42. package/dist/commands/task/new.d.ts.map +1 -1
  43. package/dist/commands/task/new.js +110 -7
  44. package/dist/commands/task/new.spec.d.ts.map +1 -1
  45. package/dist/commands/task/new.spec.js +2 -1
  46. package/dist/commands/task/set-status.command.d.ts.map +1 -1
  47. package/dist/commands/task/set-status.command.js +22 -2
  48. package/dist/commands/task/shared.d.ts +5 -0
  49. package/dist/commands/task/shared.d.ts.map +1 -1
  50. package/dist/commands/task/shared.js +68 -4
  51. package/dist/commands/task/update.d.ts.map +1 -1
  52. package/dist/commands/task/update.js +6 -1
  53. package/dist/policy/rules/allowlist.d.ts.map +1 -1
  54. package/dist/policy/rules/allowlist.js +9 -0
  55. package/dist/shared/allow-prefix-policy.d.ts +3 -0
  56. package/dist/shared/allow-prefix-policy.d.ts.map +1 -0
  57. package/dist/shared/allow-prefix-policy.js +8 -0
  58. package/package.json +2 -2
@@ -1,4 +1,5 @@
1
1
  import { usageError } from "../cli/spec/errors.js";
2
+ import { findRepoWideAllowPrefixes, repoWideAllowPrefixMessage, } from "../shared/allow-prefix-policy.js";
2
3
  import { toStringList } from "../cli/spec/parse-utils.js";
3
4
  export const blockSpec = {
4
5
  id: ["block"],
@@ -44,13 +45,14 @@ export const blockSpec = {
44
45
  name: "commit-allow",
45
46
  valueHint: "<path-prefix>",
46
47
  repeatable: true,
47
- description: "Repeatable. Allowlist path prefixes to stage for the status commit (used with --commit-from-comment).",
48
+ description: "Repeatable. Allowlist path prefixes to stage for the status commit (used with --commit-from-comment). Use minimal prefixes; '.' is rejected.",
48
49
  },
49
50
  {
50
51
  kind: "boolean",
51
52
  name: "commit-auto-allow",
52
53
  default: false,
53
- description: "Auto-allow inferred allowlist paths if none are provided (used with --commit-from-comment).",
54
+ description: "Deprecated. Disabled for safety; pass explicit --commit-allow prefixes.",
55
+ deprecated: "disabled",
54
56
  },
55
57
  {
56
58
  kind: "boolean",
@@ -99,10 +101,29 @@ export const blockSpec = {
99
101
  validateRaw: (raw) => {
100
102
  const author = typeof raw.opts.author === "string" ? raw.opts.author.trim() : "";
101
103
  const body = typeof raw.opts.body === "string" ? raw.opts.body.trim() : "";
104
+ const commitAllow = toStringList(raw.opts["commit-allow"]);
102
105
  if (!author)
103
106
  throw usageError({ spec: blockSpec, message: "Invalid value for --author: empty." });
104
107
  if (!body)
105
108
  throw usageError({ spec: blockSpec, message: "Invalid value for --body: empty." });
109
+ if (findRepoWideAllowPrefixes(commitAllow).length > 0) {
110
+ throw usageError({
111
+ spec: blockSpec,
112
+ message: repoWideAllowPrefixMessage("--commit-allow"),
113
+ });
114
+ }
115
+ if (raw.opts["commit-auto-allow"] === true) {
116
+ throw usageError({
117
+ spec: blockSpec,
118
+ message: "--commit-auto-allow is disabled; pass explicit --commit-allow <path-prefix>.",
119
+ });
120
+ }
121
+ if (raw.opts["commit-from-comment"] === true && commitAllow.length === 0) {
122
+ throw usageError({
123
+ spec: blockSpec,
124
+ message: "--commit-from-comment requires --commit-allow <path-prefix> (tip: `agentplane guard suggest-allow --format args`).",
125
+ });
126
+ }
106
127
  },
107
128
  parse: (raw) => ({
108
129
  taskId: typeof raw.args["task-id"] === "string" ? raw.args["task-id"] : "",
@@ -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;IACf,kBAAkB,EAAE,OAAO,CAAC;IAC5B,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CAmJhD,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;AAOvD,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,CA8JhD,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { usageError } from "../cli/spec/errors.js";
2
+ import { findRepoWideAllowPrefixes, repoWideAllowPrefixMessage, } from "../shared/allow-prefix-policy.js";
2
3
  export const commitSpec = {
3
4
  id: ["commit"],
4
5
  group: "Guard",
@@ -35,13 +36,14 @@ export const commitSpec = {
35
36
  name: "allow",
36
37
  valueHint: "<path-prefix>",
37
38
  repeatable: true,
38
- description: "Repeatable. Allowed path prefix (git-path).",
39
+ description: "Repeatable. Allowed path prefix (git-path). Use minimal prefixes; repo-wide '.' is rejected (tip: `agentplane guard suggest-allow --format args`).",
39
40
  },
40
41
  {
41
42
  kind: "boolean",
42
43
  name: "auto-allow",
43
44
  default: false,
44
- description: "Infer --allow prefixes from staged paths (only when no explicit --allow is provided).",
45
+ description: "Deprecated. Disabled for safety; pass explicit --allow prefixes.",
46
+ deprecated: "disabled",
45
47
  },
46
48
  {
47
49
  kind: "boolean",
@@ -77,10 +79,6 @@ export const commitSpec = {
77
79
  cmd: 'agentplane commit 202602030608-F1Q8AB -m "✨ F1Q8AB task: implement allowlist guard" --allow packages/agentplane',
78
80
  why: "Create a commit after validating allowlist and subject policy.",
79
81
  },
80
- {
81
- cmd: 'agentplane commit 202602030608-F1Q8AB -m "✨ F1Q8AB task: implement allowlist guard" --auto-allow',
82
- why: "Infer allowlist prefixes from staged paths.",
83
- },
84
82
  {
85
83
  cmd: "agentplane commit 202602030608-F1Q8AB --close",
86
84
  why: "Create a close commit for the task README using a deterministic message builder.",
@@ -120,6 +118,20 @@ export const commitSpec = {
120
118
  if (Array.isArray(allow) && allow.some((s) => typeof s === "string" && s.trim() === "")) {
121
119
  throw usageError({ spec: commitSpec, message: "Invalid value for --allow: empty." });
122
120
  }
121
+ const allowList = Array.isArray(allow)
122
+ ? allow
123
+ : typeof allow === "string"
124
+ ? [allow]
125
+ : [];
126
+ if (findRepoWideAllowPrefixes(allowList).length > 0) {
127
+ throw usageError({ spec: commitSpec, message: repoWideAllowPrefixMessage("--allow") });
128
+ }
129
+ if (raw.opts["auto-allow"] === true) {
130
+ throw usageError({
131
+ spec: commitSpec,
132
+ message: "--auto-allow is disabled; pass explicit --allow <path-prefix>.",
133
+ });
134
+ }
123
135
  },
124
136
  parse: (raw) => ({
125
137
  taskId: String(raw.args["task-id"]),
@@ -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,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"}
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;AASvD,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,CAsShD,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { usageError } from "../cli/spec/errors.js";
2
2
  import { toStringList } from "../cli/spec/parse-utils.js";
3
+ import { findRepoWideAllowPrefixes, repoWideAllowPrefixMessage, } from "../shared/allow-prefix-policy.js";
3
4
  export const finishSpec = {
4
5
  id: ["finish"],
5
6
  group: "Lifecycle",
@@ -77,13 +78,14 @@ export const finishSpec = {
77
78
  name: "commit-allow",
78
79
  valueHint: "<path-prefix>",
79
80
  repeatable: true,
80
- description: "Repeatable. Allowlist path prefixes to stage for the commit (used with --commit-from-comment).",
81
+ description: "Repeatable. Allowlist path prefixes to stage for the commit (used with --commit-from-comment). Use minimal prefixes; '.' is rejected.",
81
82
  },
82
83
  {
83
84
  kind: "boolean",
84
85
  name: "commit-auto-allow",
85
86
  default: false,
86
- description: "Auto-allow inferred allowlist paths if none are provided (used with --commit-from-comment).",
87
+ description: "Deprecated. Disabled for safety; pass explicit --commit-allow prefixes.",
88
+ deprecated: "disabled",
87
89
  },
88
90
  {
89
91
  kind: "boolean",
@@ -116,13 +118,14 @@ export const finishSpec = {
116
118
  name: "status-commit-allow",
117
119
  valueHint: "<path-prefix>",
118
120
  repeatable: true,
119
- description: "Repeatable. Allowlist path prefixes to stage for the status commit (used with --status-commit).",
121
+ description: "Repeatable. Allowlist path prefixes to stage for the status commit (used with --status-commit). Use minimal prefixes; '.' is rejected.",
120
122
  },
121
123
  {
122
124
  kind: "boolean",
123
125
  name: "status-commit-auto-allow",
124
126
  default: false,
125
- description: "Auto-allow inferred allowlist paths if none are provided (used with --status-commit).",
127
+ description: "Deprecated. Disabled for safety; pass explicit --status-commit-allow prefixes.",
128
+ deprecated: "disabled",
126
129
  },
127
130
  {
128
131
  kind: "boolean",
@@ -165,6 +168,38 @@ export const finishSpec = {
165
168
  const taskIds = Array.isArray(ids) ? ids : [];
166
169
  const commitFromComment = raw.opts["commit-from-comment"] === true;
167
170
  const statusCommit = raw.opts["status-commit"] === true;
171
+ const commitAllow = toStringList(raw.opts["commit-allow"]);
172
+ const statusCommitAllow = toStringList(raw.opts["status-commit-allow"]);
173
+ const commitAutoAllow = raw.opts["commit-auto-allow"] === true;
174
+ const statusCommitAutoAllow = raw.opts["status-commit-auto-allow"] === true;
175
+ if (findRepoWideAllowPrefixes(commitAllow).length > 0) {
176
+ throw usageError({
177
+ spec: finishSpec,
178
+ command: "finish",
179
+ message: repoWideAllowPrefixMessage("--commit-allow"),
180
+ });
181
+ }
182
+ if (findRepoWideAllowPrefixes(statusCommitAllow).length > 0) {
183
+ throw usageError({
184
+ spec: finishSpec,
185
+ command: "finish",
186
+ message: repoWideAllowPrefixMessage("--status-commit-allow"),
187
+ });
188
+ }
189
+ if (commitAutoAllow) {
190
+ throw usageError({
191
+ spec: finishSpec,
192
+ command: "finish",
193
+ message: "--commit-auto-allow is disabled; pass explicit --commit-allow <path-prefix>.",
194
+ });
195
+ }
196
+ if (statusCommitAutoAllow) {
197
+ throw usageError({
198
+ spec: finishSpec,
199
+ command: "finish",
200
+ message: "--status-commit-auto-allow is disabled; pass explicit --status-commit-allow <path-prefix>.",
201
+ });
202
+ }
168
203
  if ((commitFromComment || statusCommit) && taskIds.length !== 1) {
169
204
  throw usageError({
170
205
  spec: finishSpec,
@@ -172,6 +207,20 @@ export const finishSpec = {
172
207
  message: "--commit-from-comment/--status-commit requires exactly one task id",
173
208
  });
174
209
  }
210
+ if (commitFromComment && commitAllow.length === 0) {
211
+ throw usageError({
212
+ spec: finishSpec,
213
+ command: "finish",
214
+ message: "--commit-from-comment requires --commit-allow <path-prefix> (tip: `agentplane guard suggest-allow --format args`).",
215
+ });
216
+ }
217
+ if (statusCommit && statusCommitAllow.length === 0) {
218
+ throw usageError({
219
+ spec: finishSpec,
220
+ command: "finish",
221
+ message: "--status-commit requires --status-commit-allow <path-prefix> (tip: `agentplane guard suggest-allow --format args`).",
222
+ });
223
+ }
175
224
  if (raw.opts["close-commit"] === true && taskIds.length !== 1) {
176
225
  throw usageError({
177
226
  spec: finishSpec,
@@ -1 +1 @@
1
- {"version":3,"file":"commit.command.d.ts","sourceRoot":"","sources":["../../../src/commands/guard/commit.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIhE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,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;CAChB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,iBAAiB,CA+F1D,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAC1E,KAAK,UAAU,EAAE,GAAG,iBAAiB,KAAG,OAAO,CAAC,MAAM,CAAC,CAkCtE"}
1
+ {"version":3,"file":"commit.command.d.ts","sourceRoot":"","sources":["../../../src/commands/guard/commit.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAOtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIhE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,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;CAChB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,iBAAiB,CA0G1D,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAC1E,KAAK,UAAU,EAAE,GAAG,iBAAiB,KAAG,OAAO,CAAC,MAAM,CAAC,CA2BtE"}
@@ -1,6 +1,7 @@
1
1
  import { usageError } from "../../cli/spec/errors.js";
2
2
  import { CliError } from "../../shared/errors.js";
3
- import { cmdGuardCommit, suggestAllowPrefixes } from "./index.js";
3
+ import { findRepoWideAllowPrefixes, repoWideAllowPrefixMessage, } from "../../shared/allow-prefix-policy.js";
4
+ import { cmdGuardCommit } from "./index.js";
4
5
  export const guardCommitSpec = {
5
6
  id: ["guard", "commit"],
6
7
  group: "Guard",
@@ -20,13 +21,14 @@ export const guardCommitSpec = {
20
21
  name: "allow",
21
22
  valueHint: "<path-prefix>",
22
23
  repeatable: true,
23
- description: "Repeatable. Allowed path prefix (git-path).",
24
+ description: "Repeatable. Allowed path prefix (git-path). Use minimal prefixes; repo-wide '.' is rejected (tip: `agentplane guard suggest-allow --format args`).",
24
25
  },
25
26
  {
26
27
  kind: "boolean",
27
28
  name: "auto-allow",
28
29
  default: false,
29
- description: "Infer --allow prefixes from staged paths (only when no explicit --allow is provided).",
30
+ description: "Deprecated. Disabled for safety; pass explicit --allow prefixes.",
31
+ deprecated: "disabled",
30
32
  },
31
33
  {
32
34
  kind: "boolean",
@@ -62,10 +64,6 @@ export const guardCommitSpec = {
62
64
  cmd: 'agentplane guard commit 202602030608-F1Q8AB -m "✨ F1Q8AB task: implement allowlist guard" --allow packages/agentplane',
63
65
  why: "Validate staged changes are covered by allowlist and policy.",
64
66
  },
65
- {
66
- cmd: 'agentplane guard commit 202602030608-F1Q8AB -m "✨ F1Q8AB task: implement allowlist guard" --auto-allow',
67
- why: "Infer allowlist prefixes from staged paths.",
68
- },
69
67
  ],
70
68
  validateRaw: (raw) => {
71
69
  const msg = typeof raw.opts.message === "string" ? raw.opts.message.trim() : "";
@@ -76,6 +74,20 @@ export const guardCommitSpec = {
76
74
  if (Array.isArray(allow) && allow.some((s) => typeof s === "string" && s.trim() === "")) {
77
75
  throw usageError({ spec: guardCommitSpec, message: "Invalid value for --allow: empty." });
78
76
  }
77
+ const allowList = Array.isArray(allow)
78
+ ? allow
79
+ : typeof allow === "string"
80
+ ? [allow]
81
+ : [];
82
+ if (findRepoWideAllowPrefixes(allowList).length > 0) {
83
+ throw usageError({ spec: guardCommitSpec, message: repoWideAllowPrefixMessage("--allow") });
84
+ }
85
+ if (raw.opts["auto-allow"] === true) {
86
+ throw usageError({
87
+ spec: guardCommitSpec,
88
+ message: "--auto-allow is disabled; pass explicit --allow <path-prefix>.",
89
+ });
90
+ }
79
91
  },
80
92
  parse: (raw) => ({
81
93
  taskId: String(raw.args["task-id"]),
@@ -99,18 +111,12 @@ export const guardCommitSpec = {
99
111
  export function makeRunGuardCommitHandler(getCtx) {
100
112
  return async (ctx, p) => {
101
113
  const cmdCtx = await getCtx("guard commit");
102
- let allow = p.allow;
103
- if (p.autoAllow && allow.length === 0) {
104
- const staged = await cmdCtx.git.statusStagedPaths();
105
- const prefixes = suggestAllowPrefixes(staged);
106
- if (prefixes.length === 0) {
107
- throw new CliError({
108
- exitCode: 5,
109
- code: "E_GIT",
110
- message: "No staged files (git index empty)",
111
- });
112
- }
113
- allow = prefixes;
114
+ if (p.autoAllow) {
115
+ throw new CliError({
116
+ exitCode: 2,
117
+ code: "E_USAGE",
118
+ message: "--auto-allow is disabled; pass explicit --allow <path-prefix>.",
119
+ });
114
120
  }
115
121
  return await cmdGuardCommit({
116
122
  ctx: cmdCtx,
@@ -118,7 +124,7 @@ export function makeRunGuardCommitHandler(getCtx) {
118
124
  rootOverride: ctx.rootOverride,
119
125
  taskId: p.taskId,
120
126
  message: p.message,
121
- allow,
127
+ allow: p.allow,
122
128
  allowBase: p.allowBase,
123
129
  allowTasks: p.allowTasks,
124
130
  allowPolicy: p.allowPolicy,
@@ -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;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"}
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,CAkDpB"}
@@ -82,6 +82,13 @@ export async function stageAllowlist(opts) {
82
82
  message: "Provide at least one allowed prefix",
83
83
  });
84
84
  }
85
+ if (allow.includes(".")) {
86
+ throw new CliError({
87
+ exitCode: 2,
88
+ code: "E_USAGE",
89
+ message: "Repo-wide allowlist ('.') is not allowed; choose minimal prefixes (tip: `agentplane guard suggest-allow --format args`).",
90
+ });
91
+ }
85
92
  const denied = new Set();
86
93
  if (!opts.allowTasks)
87
94
  denied.add(opts.tasksPath);
@@ -98,7 +105,7 @@ export async function stageAllowlist(opts) {
98
105
  throw new CliError({
99
106
  exitCode: 2,
100
107
  code: "E_USAGE",
101
- message: "No changes matched allowed prefixes (use --commit-auto-allow or update --commit-allow)",
108
+ message: "No changes matched allowed prefixes (update --commit-allow)",
102
109
  });
103
110
  }
104
111
  // `git add <pathspec>` is not reliable for staging deletes/renames across versions/configs.
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../src/commands/guard/impl/commands.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAOvF,OAAO,EAAoB,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAyDxE,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsBlB;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBlB;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAS9E;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE;IACpC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,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,GAAG,OAAO,CAAC,MAAM,CAAC,CAyJlB"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../src/commands/guard/impl/commands.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAOvF,OAAO,EAAoB,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAyDxE,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsBlB;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBlB;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAS9E;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE;IACpC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,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,GAAG,OAAO,CAAC,MAAM,CAAC,CAgJlB"}
@@ -201,20 +201,12 @@ export async function cmdCommit(opts) {
201
201
  }
202
202
  return 0;
203
203
  }
204
- let allow = opts.allow;
205
- if (opts.autoAllow && allow.length === 0) {
206
- const ctx = opts.ctx ??
207
- (await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
208
- const staged = await ctx.git.statusStagedPaths();
209
- const prefixes = suggestAllowPrefixes(staged);
210
- if (prefixes.length === 0) {
211
- throw new CliError({
212
- exitCode: 5,
213
- code: "E_GIT",
214
- message: "No staged files (git index empty)",
215
- });
216
- }
217
- allow = prefixes;
204
+ if (opts.autoAllow) {
205
+ throw new CliError({
206
+ exitCode: 2,
207
+ code: "E_USAGE",
208
+ message: "--auto-allow is disabled; pass explicit --allow <path-prefix>.",
209
+ });
218
210
  }
219
211
  await guardCommitCheck({
220
212
  ctx: opts.ctx,
@@ -222,7 +214,7 @@ export async function cmdCommit(opts) {
222
214
  rootOverride: opts.rootOverride,
223
215
  taskId: opts.taskId,
224
216
  message: opts.message,
225
- allow,
217
+ allow: opts.allow,
226
218
  allowBase: opts.allowBase,
227
219
  allowTasks: opts.allowTasks,
228
220
  allowPolicy: opts.allowPolicy,
@@ -1 +1 @@
1
- {"version":3,"file":"comment-commit.d.ts","sourceRoot":"","sources":["../../../../src/commands/guard/impl/comment-commit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAS/E,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAiEvF,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,gBAAgB,CAAC;CAC1B,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA+F/D"}
1
+ {"version":3,"file":"comment-commit.d.ts","sourceRoot":"","sources":["../../../../src/commands/guard/impl/comment-commit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAQ/E,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAiEvF,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,gBAAgB,CAAC;CAC1B,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAyF/D"}
@@ -2,10 +2,9 @@ import { extractTaskSuffix } from "@agentplaneorg/core";
2
2
  import { invalidValueMessage, successMessage } from "../../../cli/output.js";
3
3
  import { CliError } from "../../../shared/errors.js";
4
4
  import { formatCommentBodyForCommit, normalizeCommentBodyForCommit, } from "../../../shared/comment-format.js";
5
- import { protectedPathKindForFile } from "../../../shared/protected-paths.js";
6
5
  import { loadCommandContext } from "../../shared/task-backend.js";
7
6
  import { buildGitCommitEnv } from "./env.js";
8
- import { stageAllowlist, suggestAllowPrefixes } from "./allow.js";
7
+ import { stageAllowlist } from "./allow.js";
9
8
  import { guardCommitCheck } from "./policy.js";
10
9
  function deriveCommitMessageFromComment(opts) {
11
10
  const prefix = opts.emoji.trim();
@@ -49,27 +48,19 @@ function deriveCommitBodyFromComment(opts) {
49
48
  export async function commitFromComment(opts) {
50
49
  const ctx = opts.ctx ??
51
50
  (await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
52
- let allowPrefixes = opts.allow.map((prefix) => prefix.trim()).filter(Boolean);
53
- if (opts.autoAllow && allowPrefixes.length === 0) {
54
- const changed = await ctx.git.statusChangedPaths();
55
- const tasksPath = opts.config.paths.tasks_path;
56
- // Auto-allow is for ergonomic status commits. It must never silently
57
- // broaden into policy/config/CI changes (those require explicit intent).
58
- const eligible = changed.filter((filePath) => {
59
- const kind = protectedPathKindForFile({ filePath, tasksPath });
60
- if (!kind)
61
- return true;
62
- if (kind === "tasks")
63
- return opts.allowTasks;
64
- return false;
51
+ if (opts.autoAllow) {
52
+ throw new CliError({
53
+ exitCode: 2,
54
+ code: "E_USAGE",
55
+ message: "--commit-auto-allow is disabled; pass explicit --commit-allow <path-prefix>.",
65
56
  });
66
- allowPrefixes = suggestAllowPrefixes(eligible);
67
57
  }
58
+ let allowPrefixes = opts.allow.map((prefix) => prefix.trim()).filter(Boolean);
68
59
  if (allowPrefixes.length === 0) {
69
60
  throw new CliError({
70
61
  exitCode: 2,
71
62
  code: "E_USAGE",
72
- message: "Provide at least one --commit-allow prefix or enable --commit-auto-allow",
63
+ message: "Provide at least one --commit-allow prefix",
73
64
  });
74
65
  }
75
66
  const staged = await stageAllowlist({
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks/index.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,UAAU,mDAAoD,CAAC;AAgG5E,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmClB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BlB;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8HlB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks/index.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,UAAU,mDAAoD,CAAC;AA8G5E,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmClB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BlB;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8HlB"}
@@ -53,9 +53,14 @@ function hookScriptText(hook) {
53
53
  "#!/usr/bin/env sh",
54
54
  `# ${HOOK_MARKER} (do not edit)`,
55
55
  "set -e",
56
+ 'REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"',
57
+ 'SHIM="$REPO_ROOT/.agentplane/bin/agentplane"',
58
+ 'if [ -x "$SHIM" ]; then',
59
+ ' exec "$SHIM" hooks run ' + hook + ' "$@"',
60
+ "fi",
56
61
  "if ! command -v agentplane >/dev/null 2>&1; then",
57
- ' echo "agentplane hooks: agentplane not found in PATH" >&2',
58
- " exit 1",
62
+ ' echo "agentplane hooks: runner not found (PATH missing and shim unavailable)." >&2',
63
+ " exit 127",
59
64
  "fi",
60
65
  "exec agentplane hooks run " + hook + ' "$@"',
61
66
  "",
@@ -66,11 +71,20 @@ function shimScriptText() {
66
71
  "#!/usr/bin/env sh",
67
72
  `# ${SHIM_MARKER} (do not edit)`,
68
73
  "set -e",
69
- "if ! command -v agentplane >/dev/null 2>&1; then",
70
- ' echo "agentplane shim: agentplane not found in PATH" >&2',
71
- " exit 1",
74
+ 'SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"',
75
+ 'REPO_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"',
76
+ 'LOCAL_BIN="$REPO_ROOT/packages/agentplane/bin/agentplane.js"',
77
+ 'if command -v node >/dev/null 2>&1 && [ -f "$LOCAL_BIN" ]; then',
78
+ ' exec node "$LOCAL_BIN" "$@"',
79
+ "fi",
80
+ "if command -v npx >/dev/null 2>&1; then",
81
+ ' exec npx --yes agentplane "$@"',
82
+ "fi",
83
+ "if command -v agentplane >/dev/null 2>&1; then",
84
+ ' exec agentplane "$@"',
72
85
  "fi",
73
- 'exec agentplane "$@"',
86
+ 'echo "agentplane shim: runner not found (need node+npx or agentplane in PATH)." >&2',
87
+ " exit 127",
74
88
  "",
75
89
  ].join("\n");
76
90
  }
@@ -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;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;AAsVnD,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CAwE5D,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,kBAAkB,CAuK9D,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;AAsVnD,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CAiF5D,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,kBAAkB,CA+K9D,CAAC"}
@@ -146,11 +146,11 @@ async function validateReleaseNotes(notesPath) {
146
146
  });
147
147
  }
148
148
  const bulletCount = content.split(/\r?\n/u).filter((line) => /^\s*[-*]\s+\S+/u.test(line)).length;
149
- if (bulletCount < 3) {
149
+ if (bulletCount < 1) {
150
150
  throw new CliError({
151
151
  exitCode: exitCodeForError("E_VALIDATION"),
152
152
  code: "E_VALIDATION",
153
- message: `Release notes must include at least 3 bullet points in ${notesPath}.`,
153
+ message: `Release notes must include at least one bullet point in ${notesPath}.`,
154
154
  });
155
155
  }
156
156
  if (/[\u0400-\u04FF]/u.test(content)) {
@@ -301,7 +301,8 @@ export const releaseApplySpec = {
301
301
  kind: "boolean",
302
302
  name: "push",
303
303
  default: false,
304
- description: "Push the release commit and tag to the remote (requires --yes).",
304
+ description: "Mandatory for real releases: push commit and tag so GitHub publish workflow can publish to npm " +
305
+ "(requires --yes). Local tests can skip with AGENTPLANE_RELEASE_DRY_RUN=1.",
305
306
  },
306
307
  {
307
308
  kind: "string",
@@ -325,6 +326,13 @@ export const releaseApplySpec = {
325
326
  };
326
327
  },
327
328
  validate: (p) => {
329
+ if (!p.push && process.env.AGENTPLANE_RELEASE_DRY_RUN !== "1") {
330
+ throw usageError({
331
+ spec: releaseApplySpec,
332
+ command: "release apply",
333
+ message: "Release publish is mandatory. Run `agentplane release apply --push --yes`.",
334
+ });
335
+ }
328
336
  if (p.push && p.yes !== true) {
329
337
  throw usageError({
330
338
  spec: releaseApplySpec,
@@ -356,6 +364,13 @@ export const releaseApplySpec = {
356
364
  ],
357
365
  };
358
366
  export const runReleaseApply = async (ctx, flags) => {
367
+ if (!flags.push && process.env.AGENTPLANE_RELEASE_DRY_RUN !== "1") {
368
+ throw usageError({
369
+ spec: releaseApplySpec,
370
+ command: "release apply",
371
+ message: "Release publish is mandatory. Run `agentplane release apply --push --yes`.",
372
+ });
373
+ }
359
374
  const resolved = await resolveProject({ cwd: ctx.cwd, rootOverride: ctx.rootOverride ?? null });
360
375
  const gitRoot = resolved.gitRoot;
361
376
  const planDir = flags.plan ? path.resolve(gitRoot, flags.plan) : await findLatestPlanDir(gitRoot);
@@ -104,7 +104,7 @@ function releaseInstructions(opts) {
104
104
  `Write English release notes as \`docs/releases/${opts.nextTag}.md\`.\n\n` +
105
105
  `Rules:\n` +
106
106
  `- Use human-readable bullets focused on outcomes and user-facing improvements.\n` +
107
- `- Minimum: 3 bullet points.\n` +
107
+ `- Include as many bullets as needed; do not enforce a fixed bullet count.\n` +
108
108
  `- Do not include Cyrillic.\n` +
109
109
  `- Use \`docs/releases/TEMPLATE.md\` as the structure.\n\n` +
110
110
  `Inputs:\n` +
@@ -1,4 +1,10 @@
1
1
  import { resolveProject } from "@agentplaneorg/core";
2
+ type RecipeToolRuntime = "node" | "bash";
3
+ type RecipeToolInvocation = {
4
+ command: string;
5
+ args: string[];
6
+ };
7
+ export declare function resolveRecipeToolInvocation(runtime: RecipeToolRuntime, entrypoint: string, args: string[]): RecipeToolInvocation;
2
8
  export declare function cmdScenarioListParsed(opts: {
3
9
  cwd: string;
4
10
  rootOverride?: string;
@@ -9,6 +15,17 @@ export declare function cmdScenarioInfoParsed(opts: {
9
15
  recipeId: string;
10
16
  scenarioId: string;
11
17
  }): Promise<number>;
18
+ export declare function executeRecipeTool(opts: {
19
+ runtime: RecipeToolRuntime;
20
+ entrypoint: string;
21
+ args: string[];
22
+ cwd: string;
23
+ env: Record<string, string>;
24
+ }): Promise<{
25
+ exitCode: number;
26
+ stdout: string;
27
+ stderr: string;
28
+ }>;
12
29
  export declare function cmdScenarioRunParsed(opts: {
13
30
  cwd: string;
14
31
  rootOverride?: string;
@@ -16,4 +33,5 @@ export declare function cmdScenarioRunParsed(opts: {
16
33
  scenarioId: string;
17
34
  resolved?: Awaited<ReturnType<typeof resolveProject>>;
18
35
  }): Promise<number>;
36
+ export {};
19
37
  //# sourceMappingURL=commands.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../src/commands/scenario/impl/commands.ts"],"names":[],"mappings":"AAKA,OAAO,EAAmB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAgCtE,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoDlB;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoElB;AAkCD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC;CACvD,GAAG,OAAO,CAAC,MAAM,CAAC,CAqNlB"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../src/commands/scenario/impl/commands.ts"],"names":[],"mappings":"AAKA,OAAO,EAAmB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAgCtE,KAAK,iBAAiB,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzC,KAAK,oBAAoB,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,CAAC;AAEF,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EAAE,GACb,oBAAoB,CAQtB;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoDlB;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoElB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,OAAO,EAAE,iBAAiB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA2ChE;AAMD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC;CACvD,GAAG,OAAO,CAAC,MAAM,CAAC,CAuNlB"}