agentplane 0.3.16 → 0.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/dist/.build-manifest.json +159 -54
  2. package/dist/backends/task-backend/redmine/backend-runtime.d.ts +4 -146
  3. package/dist/backends/task-backend/redmine/backend-runtime.d.ts.map +1 -1
  4. package/dist/backends/task-backend/redmine/backend-runtime.js +4 -258
  5. package/dist/backends/task-backend/redmine/mapping.js +1 -1
  6. package/dist/backends/task-backend/redmine/runtime-context.d.ts +98 -0
  7. package/dist/backends/task-backend/redmine/runtime-context.d.ts.map +1 -0
  8. package/dist/backends/task-backend/redmine/runtime-context.js +57 -0
  9. package/dist/backends/task-backend/redmine/runtime-methods.d.ts +33 -0
  10. package/dist/backends/task-backend/redmine/runtime-methods.d.ts.map +1 -0
  11. package/dist/backends/task-backend/redmine/runtime-methods.js +86 -0
  12. package/dist/backends/task-backend/redmine/runtime-operations.d.ts +19 -0
  13. package/dist/backends/task-backend/redmine/runtime-operations.d.ts.map +1 -0
  14. package/dist/backends/task-backend/redmine/runtime-operations.js +83 -0
  15. package/dist/backends/task-backend/redmine/runtime-state.d.ts +10 -0
  16. package/dist/backends/task-backend/redmine/runtime-state.d.ts.map +1 -0
  17. package/dist/backends/task-backend/redmine/runtime-state.js +45 -0
  18. package/dist/backends/task-backend/shared/constants.d.ts +1 -1
  19. package/dist/backends/task-backend/shared/constants.d.ts.map +1 -1
  20. package/dist/backends/task-backend/shared/constants.js +1 -1
  21. package/dist/backends/task-index.d.ts +0 -4
  22. package/dist/backends/task-index.d.ts.map +1 -1
  23. package/dist/backends/task-index.js +0 -33
  24. package/dist/cli/exit-codes.d.ts.map +1 -1
  25. package/dist/cli/exit-codes.js +1 -0
  26. package/dist/cli/http.d.ts.map +1 -1
  27. package/dist/cli/http.js +34 -15
  28. package/dist/cli/run-cli/command-loaders.d.ts +1 -5
  29. package/dist/cli/run-cli/command-loaders.d.ts.map +1 -1
  30. package/dist/cli/spec/errors.d.ts +5 -0
  31. package/dist/cli/spec/errors.d.ts.map +1 -1
  32. package/dist/cli/spec/errors.js +14 -1
  33. package/dist/cli/spec/parse.d.ts.map +1 -1
  34. package/dist/cli/spec/parse.js +8 -1
  35. package/dist/commands/branch/work-start.d.ts.map +1 -1
  36. package/dist/commands/branch/work-start.direct.d.ts +13 -0
  37. package/dist/commands/branch/work-start.direct.d.ts.map +1 -0
  38. package/dist/commands/branch/work-start.direct.js +75 -0
  39. package/dist/commands/branch/work-start.git.d.ts +3 -0
  40. package/dist/commands/branch/work-start.git.d.ts.map +1 -0
  41. package/dist/commands/branch/work-start.git.js +19 -0
  42. package/dist/commands/branch/work-start.hook-shim.d.ts +2 -0
  43. package/dist/commands/branch/work-start.hook-shim.d.ts.map +1 -0
  44. package/dist/commands/branch/work-start.hook-shim.js +38 -0
  45. package/dist/commands/branch/work-start.js +6 -235
  46. package/dist/commands/branch/work-start.materialize.d.ts +16 -0
  47. package/dist/commands/branch/work-start.materialize.d.ts.map +1 -0
  48. package/dist/commands/branch/work-start.materialize.js +110 -0
  49. package/dist/commands/doctor/fixes.d.ts +0 -5
  50. package/dist/commands/doctor/fixes.d.ts.map +1 -1
  51. package/dist/commands/doctor/fixes.js +0 -70
  52. package/dist/commands/doctor/workflow.d.ts.map +1 -1
  53. package/dist/commands/doctor/workflow.js +2 -23
  54. package/dist/commands/doctor.run.d.ts.map +1 -1
  55. package/dist/commands/doctor.run.js +1 -3
  56. package/dist/commands/hooks/index.d.ts +4 -20
  57. package/dist/commands/hooks/index.d.ts.map +1 -1
  58. package/dist/commands/hooks/index.js +4 -432
  59. package/dist/commands/hooks/install.d.ts +11 -0
  60. package/dist/commands/hooks/install.d.ts.map +1 -0
  61. package/dist/commands/hooks/install.js +136 -0
  62. package/dist/commands/hooks/run.commit-msg.d.ts +3 -0
  63. package/dist/commands/hooks/run.commit-msg.d.ts.map +1 -0
  64. package/dist/commands/hooks/run.commit-msg.js +67 -0
  65. package/dist/commands/hooks/run.d.ts +9 -0
  66. package/dist/commands/hooks/run.d.ts.map +1 -0
  67. package/dist/commands/hooks/run.js +45 -0
  68. package/dist/commands/hooks/run.post-merge.d.ts +3 -0
  69. package/dist/commands/hooks/run.post-merge.d.ts.map +1 -0
  70. package/dist/commands/hooks/run.post-merge.js +44 -0
  71. package/dist/commands/hooks/run.pre-commit.d.ts +3 -0
  72. package/dist/commands/hooks/run.pre-commit.d.ts.map +1 -0
  73. package/dist/commands/hooks/run.pre-commit.js +48 -0
  74. package/dist/commands/hooks/run.pre-push.d.ts +6 -0
  75. package/dist/commands/hooks/run.pre-push.d.ts.map +1 -0
  76. package/dist/commands/hooks/run.pre-push.js +88 -0
  77. package/dist/commands/hooks/shared.d.ts +7 -0
  78. package/dist/commands/hooks/shared.d.ts.map +1 -0
  79. package/dist/commands/hooks/shared.js +41 -0
  80. package/dist/commands/recipes/impl/index.d.ts.map +1 -1
  81. package/dist/commands/recipes/impl/index.js +13 -3
  82. package/dist/commands/task/hosted-close-pr.command.d.ts +2 -7
  83. package/dist/commands/task/hosted-close-pr.command.d.ts.map +1 -1
  84. package/dist/commands/task/hosted-close-pr.command.js +9 -373
  85. package/dist/commands/task/hosted-close-pr.execute.d.ts +3 -0
  86. package/dist/commands/task/hosted-close-pr.execute.d.ts.map +1 -0
  87. package/dist/commands/task/hosted-close-pr.execute.js +135 -0
  88. package/dist/commands/task/hosted-close-pr.postcheck.d.ts +3 -0
  89. package/dist/commands/task/hosted-close-pr.postcheck.d.ts.map +1 -0
  90. package/dist/commands/task/hosted-close-pr.postcheck.js +13 -0
  91. package/dist/commands/task/hosted-close-pr.precheck.d.ts +4 -0
  92. package/dist/commands/task/hosted-close-pr.precheck.d.ts.map +1 -0
  93. package/dist/commands/task/hosted-close-pr.precheck.js +288 -0
  94. package/dist/commands/task/hosted-close-pr.report.d.ts +4 -0
  95. package/dist/commands/task/hosted-close-pr.report.d.ts.map +1 -0
  96. package/dist/commands/task/hosted-close-pr.report.js +42 -0
  97. package/dist/commands/task/hosted-close-pr.types.d.ts +75 -0
  98. package/dist/commands/task/hosted-close-pr.types.d.ts.map +1 -0
  99. package/dist/commands/task/hosted-close-pr.types.js +1 -0
  100. package/dist/commands/upgrade/materialize.d.ts.map +1 -1
  101. package/dist/commands/upgrade/materialize.js +0 -7
  102. package/dist/commands/upgrade/source.d.ts +0 -1
  103. package/dist/commands/upgrade/source.d.ts.map +1 -1
  104. package/dist/commands/upgrade/source.js +1 -9
  105. package/dist/runner/context/base-prompts.d.ts.map +1 -1
  106. package/dist/runner/context/base-prompts.js +4 -0
  107. package/dist/runner/context/project-skill-prompt-blocks.d.ts +5 -0
  108. package/dist/runner/context/project-skill-prompt-blocks.d.ts.map +1 -0
  109. package/dist/runner/context/project-skill-prompt-blocks.js +57 -0
  110. package/dist/runner/process-supervision/run.d.ts.map +1 -1
  111. package/dist/runner/process-supervision/run.js +61 -59
  112. package/dist/shared/errors.d.ts +4 -1
  113. package/dist/shared/errors.d.ts.map +1 -1
  114. package/dist/shared/errors.js +6 -0
  115. package/dist/shared/workflow-artifacts.d.ts.map +1 -1
  116. package/dist/shared/workflow-artifacts.js +1 -8
  117. package/dist/workflow-runtime/file-ops.d.ts.map +1 -1
  118. package/dist/workflow-runtime/file-ops.js +1 -20
  119. package/dist/workflow-runtime/paths.d.ts.map +1 -1
  120. package/dist/workflow-runtime/paths.js +0 -1
  121. package/dist/workflow-runtime/types.d.ts +0 -1
  122. package/dist/workflow-runtime/types.d.ts.map +1 -1
  123. package/package.json +3 -3
@@ -0,0 +1,45 @@
1
+ import { mapBackendError } from "../../cli/error-map.js";
2
+ import { CliError } from "../../shared/errors.js";
3
+ import { runCommitMsgHook } from "./run.commit-msg.js";
4
+ import { runPostMergeHook } from "./run.post-merge.js";
5
+ import { runPreCommitHook } from "./run.pre-commit.js";
6
+ import { runPrePushHook } from "./run.pre-push.js";
7
+ async function runHook(opts) {
8
+ switch (opts.hook) {
9
+ case "commit-msg": {
10
+ return await runCommitMsgHook(opts);
11
+ }
12
+ case "pre-commit": {
13
+ return await runPreCommitHook(opts);
14
+ }
15
+ case "pre-push": {
16
+ return await runPrePushHook(opts);
17
+ }
18
+ case "post-merge": {
19
+ return await runPostMergeHook(opts);
20
+ }
21
+ }
22
+ }
23
+ export async function cmdHooksRun(opts) {
24
+ try {
25
+ return await runHook(opts);
26
+ }
27
+ catch (err) {
28
+ const status = err?.status;
29
+ const stdout = err?.stdout;
30
+ const stderr = err?.stderr;
31
+ if (typeof stdout === "string" && stdout.length > 0)
32
+ process.stdout.write(stdout);
33
+ if (typeof stderr === "string" && stderr.length > 0)
34
+ process.stderr.write(stderr);
35
+ if (typeof status === "number" && Number.isInteger(status) && status >= 0) {
36
+ return status;
37
+ }
38
+ if (err instanceof CliError)
39
+ throw err;
40
+ throw mapBackendError(err, {
41
+ command: `hooks run ${opts.hook}`,
42
+ root: opts.rootOverride ?? null,
43
+ });
44
+ }
45
+ }
@@ -0,0 +1,3 @@
1
+ import type { HooksRunOptions } from "./run.js";
2
+ export declare function runPostMergeHook(opts: HooksRunOptions): Promise<number>;
3
+ //# sourceMappingURL=run.post-merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.post-merge.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks/run.post-merge.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAuC7E"}
@@ -0,0 +1,44 @@
1
+ import { resolveBaseBranch } from "@agentplaneorg/core";
2
+ import { cmdCleanupMerged } from "../branch/index.js";
3
+ import { gitCurrentBranch } from "../shared/git-ops.js";
4
+ import { loadCommandContext } from "../shared/task-backend.js";
5
+ export async function runPostMergeHook(opts) {
6
+ try {
7
+ const ctx = await loadCommandContext({
8
+ cwd: opts.cwd,
9
+ rootOverride: opts.rootOverride ?? null,
10
+ });
11
+ if (ctx.config.workflow_mode !== "branch_pr")
12
+ return 0;
13
+ const baseBranch = await resolveBaseBranch({
14
+ cwd: opts.cwd,
15
+ rootOverride: opts.rootOverride ?? null,
16
+ cliBaseOpt: null,
17
+ mode: ctx.config.workflow_mode,
18
+ });
19
+ if (!baseBranch)
20
+ return 0;
21
+ const currentBranch = await gitCurrentBranch(ctx.resolvedProject.gitRoot);
22
+ if (currentBranch !== baseBranch)
23
+ return 0;
24
+ return await cmdCleanupMerged({
25
+ ctx,
26
+ cwd: opts.cwd,
27
+ rootOverride: opts.rootOverride,
28
+ base: baseBranch,
29
+ yes: true,
30
+ archive: false,
31
+ deleteRemoteBranches: false,
32
+ fetch: false,
33
+ quiet: true,
34
+ skipUnsafeWorktrees: true,
35
+ });
36
+ }
37
+ catch (error) {
38
+ const message = error instanceof Error && error.message.trim().length > 0
39
+ ? error.message.trim()
40
+ : String(error);
41
+ process.stderr.write(`warning: post-merge cleanup skipped: ${message}\n`);
42
+ return 0;
43
+ }
44
+ }
@@ -0,0 +1,3 @@
1
+ import type { HooksRunOptions } from "./run.js";
2
+ export declare function runPreCommitHook(opts: HooksRunOptions): Promise<number>;
3
+ //# sourceMappingURL=run.pre-commit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.pre-commit.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks/run.pre-commit.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAMhD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAwC7E"}
@@ -0,0 +1,48 @@
1
+ import { loadConfig, resolveBaseBranch, resolveProject } from "@agentplaneorg/core";
2
+ import { evaluatePolicy } from "../../policy/evaluate.js";
3
+ import { GitContext } from "../shared/git-context.js";
4
+ import { gitCurrentBranch } from "../shared/git-ops.js";
5
+ import { throwIfPolicyDenied } from "../shared/policy-deny.js";
6
+ function envFlag(name) {
7
+ return (process.env[name] ?? "").trim() === "1";
8
+ }
9
+ export async function runPreCommitHook(opts) {
10
+ const resolved = await resolveProject({
11
+ cwd: opts.cwd,
12
+ rootOverride: opts.rootOverride ?? null,
13
+ });
14
+ const staged = await new GitContext({ gitRoot: resolved.gitRoot }).statusStagedPaths();
15
+ if (staged.length === 0)
16
+ return 0;
17
+ const loaded = await loadConfig(resolved.agentplaneDir);
18
+ const inBranchPr = loaded.config.workflow_mode === "branch_pr";
19
+ const baseBranch = inBranchPr
20
+ ? await resolveBaseBranch({
21
+ cwd: opts.cwd,
22
+ rootOverride: opts.rootOverride ?? null,
23
+ cliBaseOpt: null,
24
+ mode: loaded.config.workflow_mode,
25
+ })
26
+ : null;
27
+ const currentBranch = inBranchPr ? await gitCurrentBranch(resolved.gitRoot) : undefined;
28
+ const res = evaluatePolicy({
29
+ action: "hook_pre_commit",
30
+ config: loaded.config,
31
+ taskId: (process.env.AGENTPLANE_TASK_ID ?? "").trim(),
32
+ git: {
33
+ stagedPaths: staged,
34
+ currentBranch,
35
+ baseBranch,
36
+ },
37
+ allow: {
38
+ allowTasks: envFlag("AGENTPLANE_ALLOW_TASKS"),
39
+ allowBase: envFlag("AGENTPLANE_ALLOW_BASE"),
40
+ allowPolicy: envFlag("AGENTPLANE_ALLOW_POLICY"),
41
+ allowConfig: envFlag("AGENTPLANE_ALLOW_CONFIG"),
42
+ allowHooks: envFlag("AGENTPLANE_ALLOW_HOOKS"),
43
+ allowCI: envFlag("AGENTPLANE_ALLOW_CI"),
44
+ },
45
+ });
46
+ throwIfPolicyDenied(res);
47
+ return 0;
48
+ }
@@ -0,0 +1,6 @@
1
+ import type { HooksRunOptions } from "./run.js";
2
+ export declare function resolvePrePushHookScriptPath(gitRoot: string, opts?: {
3
+ bundledScriptPath?: string;
4
+ }): Promise<string | null>;
5
+ export declare function runPrePushHook(opts: HooksRunOptions): Promise<number>;
6
+ //# sourceMappingURL=run.pre-push.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.pre-push.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks/run.pre-push.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAMhD,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,MAAM,EACf,IAAI,GAAE;IAAE,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAAO,GACxC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAMxB;AA4CD,wBAAsB,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAgC3E"}
@@ -0,0 +1,88 @@
1
+ import { runProcessSync, resolveProject } from "@agentplaneorg/core";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { fileExists } from "../../cli/fs-utils.js";
5
+ import { CliError } from "../../shared/errors.js";
6
+ function resolveBundledPrePushHookScriptPath() {
7
+ return fileURLToPath(new URL("../../../../../scripts/run-pre-push-hook.mjs", import.meta.url));
8
+ }
9
+ export async function resolvePrePushHookScriptPath(gitRoot, opts = {}) {
10
+ const repoScriptPath = path.join(gitRoot, "scripts", "run-pre-push-hook.mjs");
11
+ if (await fileExists(repoScriptPath))
12
+ return repoScriptPath;
13
+ const bundledScriptPath = opts.bundledScriptPath ?? resolveBundledPrePushHookScriptPath();
14
+ if (await fileExists(bundledScriptPath))
15
+ return bundledScriptPath;
16
+ return null;
17
+ }
18
+ async function readHookStdinUtf8(timeoutMs = 25) {
19
+ if (process.stdin.isTTY)
20
+ return "";
21
+ const chunks = [];
22
+ const consume = () => {
23
+ let chunk = process.stdin.read();
24
+ while (chunk !== null) {
25
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
26
+ chunk = process.stdin.read();
27
+ }
28
+ };
29
+ consume();
30
+ if (chunks.length > 0 || process.stdin.readableEnded) {
31
+ return Buffer.concat(chunks).toString("utf8");
32
+ }
33
+ await new Promise((resolve) => {
34
+ const finish = () => {
35
+ clearTimeout(timer);
36
+ process.stdin.off("readable", onReadable);
37
+ process.stdin.off("end", onEnd);
38
+ resolve();
39
+ };
40
+ const onReadable = () => {
41
+ consume();
42
+ finish();
43
+ };
44
+ const onEnd = () => {
45
+ consume();
46
+ finish();
47
+ };
48
+ const timer = setTimeout(finish, timeoutMs);
49
+ process.stdin.on("readable", onReadable);
50
+ process.stdin.on("end", onEnd);
51
+ process.stdin.resume();
52
+ });
53
+ consume();
54
+ return Buffer.concat(chunks).toString("utf8");
55
+ }
56
+ export async function runPrePushHook(opts) {
57
+ const resolved = await resolveProject({
58
+ cwd: opts.cwd,
59
+ rootOverride: opts.rootOverride ?? null,
60
+ });
61
+ const scriptPath = await resolvePrePushHookScriptPath(resolved.gitRoot);
62
+ if (!scriptPath) {
63
+ throw new CliError({
64
+ exitCode: 2,
65
+ code: "E_USAGE",
66
+ message: [
67
+ "Missing pre-push hook script: scripts/run-pre-push-hook.mjs",
68
+ "The pre-push hook needs a repository-local script or an installed CLI bundle that ships the fallback.",
69
+ "Fix:",
70
+ " 1) Restore scripts/run-pre-push-hook.mjs in this repository, or",
71
+ " 2) Run `agentplane hooks uninstall` if this repository should not use the agentplane pre-push gate.",
72
+ ].join("\n"),
73
+ });
74
+ }
75
+ const result = runProcessSync({
76
+ command: "node",
77
+ args: [scriptPath],
78
+ cwd: resolved.gitRoot,
79
+ env: process.env,
80
+ encoding: "utf8",
81
+ input: await readHookStdinUtf8(),
82
+ stdin: "pipe",
83
+ stdout: "inherit",
84
+ stderr: "inherit",
85
+ reject: false,
86
+ });
87
+ return result.exitCode ?? (result.signal ? 1 : 0);
88
+ }
@@ -0,0 +1,7 @@
1
+ export declare const HOOK_MARKER = "agentplane-hook";
2
+ export declare const SHIM_MARKER = "agentplane-hook-shim";
3
+ export declare const HOOK_NAMES: readonly ["commit-msg", "pre-commit", "pre-push", "post-merge"];
4
+ export type HookName = (typeof HOOK_NAMES)[number];
5
+ export declare function resolveGitHooksDir(cwd: string): Promise<string>;
6
+ export declare function fileIsManaged(filePath: string, marker: string): Promise<boolean>;
7
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks/shared.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,WAAW,oBAAoB,CAAC;AAC7C,eAAO,MAAM,WAAW,yBAAyB,CAAC;AAClD,eAAO,MAAM,UAAU,iEAAkE,CAAC;AAC1F,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BrE;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOtF"}
@@ -0,0 +1,41 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { gitRevParse } from "../shared/git-ops.js";
4
+ import { isPathWithin } from "../shared/path.js";
5
+ import { CliError } from "../../shared/errors.js";
6
+ export const HOOK_MARKER = "agentplane-hook";
7
+ export const SHIM_MARKER = "agentplane-hook-shim";
8
+ export const HOOK_NAMES = ["commit-msg", "pre-commit", "pre-push", "post-merge"];
9
+ export async function resolveGitHooksDir(cwd) {
10
+ const repoRoot = await gitRevParse(cwd, ["--show-toplevel"]);
11
+ const commonDirRaw = await gitRevParse(cwd, ["--git-common-dir"]);
12
+ const hooksRaw = await gitRevParse(cwd, ["--git-path", "hooks"]);
13
+ const commonDir = path.resolve(path.isAbsolute(commonDirRaw) ? commonDirRaw : path.join(repoRoot, commonDirRaw));
14
+ const hooksDir = path.resolve(path.isAbsolute(hooksRaw) ? hooksRaw : path.join(repoRoot, hooksRaw));
15
+ const resolvedRoot = path.resolve(repoRoot);
16
+ if (!isPathWithin(resolvedRoot, hooksDir) && !isPathWithin(commonDir, hooksDir)) {
17
+ throw new CliError({
18
+ exitCode: 5,
19
+ code: "E_GIT",
20
+ message: [
21
+ "Refusing to manage git hooks outside the repository.",
22
+ `hooks_path=${hooksDir}`,
23
+ `repo_root=${resolvedRoot}`,
24
+ `common_dir=${commonDir}`,
25
+ "Fix:",
26
+ " 1) Use a repo-relative core.hooksPath (e.g., .git/hooks)",
27
+ " 2) Re-run `agentplane hooks install`",
28
+ ].join("\n"),
29
+ });
30
+ }
31
+ return hooksDir;
32
+ }
33
+ export async function fileIsManaged(filePath, marker) {
34
+ try {
35
+ const content = await readFile(filePath, "utf8");
36
+ return content.includes(marker);
37
+ }
38
+ catch {
39
+ return false;
40
+ }
41
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAyB,MAAM,wBAAwB,CAAC;AAsIlF,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB,GAAG,OAAO,CAAC,YAAY,CAAC,CA0BxB;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAGV"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAyB,MAAM,wBAAwB,CAAC;AA2JlF,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB,GAAG,OAAO,CAAC,YAAY,CAAC,CA0BxB;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAGV"}
@@ -8,6 +8,10 @@ import { isRecord } from "../../../shared/guards.js";
8
8
  import { writeJsonStableIfChanged, writeTextIfChanged } from "../../../shared/write-if-changed.js";
9
9
  import { DEFAULT_RECIPES_INDEX_URL, RECIPES_INDEX_PUBLIC_KEYS, RECIPES_INDEX_PUBLIC_KEYS_ENV, } from "./constants.js";
10
10
  import { resolveRecipesIndexCachePath, resolveRecipesIndexCacheSigPath } from "./paths.js";
11
+ const DEFAULT_RECIPES_INDEX_SIGNATURE_ALGORITHM = "ed25519";
12
+ const recipesIndexSignatureVerifiers = {
13
+ ed25519: verifyRecipesIndexEd25519Signature,
14
+ };
11
15
  function loadRecipesIndexPublicKeys() {
12
16
  const raw = process.env[RECIPES_INDEX_PUBLIC_KEYS_ENV];
13
17
  if (!raw)
@@ -36,13 +40,19 @@ function validateRecipesIndexSignature(raw) {
36
40
  if (!keyId || !signature) {
37
41
  throw new Error(invalidFieldMessage("recipes index signature", "key_id, signature"));
38
42
  }
39
- const algorithm = typeof raw.algorithm === "string" ? raw.algorithm.trim() : undefined;
43
+ const algorithm = typeof raw.algorithm === "string" && raw.algorithm.trim() ? raw.algorithm.trim() : undefined;
40
44
  return { schema_version: 1, key_id: keyId, signature, algorithm };
41
45
  }
42
46
  function verifyRecipesIndexSignature(indexText, signature) {
43
- if (signature.algorithm && signature.algorithm !== "ed25519") {
44
- throw new Error(invalidFieldMessage("recipes index signature.algorithm", "ed25519"));
47
+ const algorithm = signature.algorithm ?? DEFAULT_RECIPES_INDEX_SIGNATURE_ALGORITHM;
48
+ const verifier = recipesIndexSignatureVerifiers[algorithm];
49
+ if (!verifier) {
50
+ const supportedAlgorithms = Object.keys(recipesIndexSignatureVerifiers).toSorted().join(", ");
51
+ throw new Error(`Unsupported recipes index signature algorithm "${algorithm}". Supported algorithms: ${supportedAlgorithms}`);
45
52
  }
53
+ verifier(indexText, signature);
54
+ }
55
+ function verifyRecipesIndexEd25519Signature(indexText, signature) {
46
56
  const keys = loadRecipesIndexPublicKeys();
47
57
  const publicKey = keys[signature.key_id];
48
58
  if (!publicKey) {
@@ -1,11 +1,6 @@
1
1
  import type { CommandCtx, CommandSpec } from "../../cli/spec/spec.js";
2
- import { type CommandContext } from "../shared/task-backend.js";
3
- type TaskHostedClosePrParsed = {
4
- taskIds: string[];
5
- branch: string | null;
6
- repo: string | null;
7
- };
2
+ import type { CommandContext } from "../shared/task-backend.js";
3
+ import type { TaskHostedClosePrParsed } from "./hosted-close-pr.types.js";
8
4
  export declare const taskHostedClosePrSpec: CommandSpec<TaskHostedClosePrParsed>;
9
5
  export declare function makeRunTaskHostedClosePrHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: TaskHostedClosePrParsed) => Promise<number>;
10
- export {};
11
6
  //# sourceMappingURL=hosted-close-pr.command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hosted-close-pr.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/hosted-close-pr.command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAStE,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AASnC,KAAK,uBAAuB,GAAG;IAC7B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAAC;AAgBF,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,uBAAuB,CAoEtE,CAAC;AA4cF,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAChF,KAAK,UAAU,EAAE,GAAG,uBAAuB,KAAG,OAAO,CAAC,MAAM,CAAC,CAsB5E"}
1
+ {"version":3,"file":"hosted-close-pr.command.d.ts","sourceRoot":"","sources":["../../../src/commands/task/hosted-close-pr.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAItE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAShE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAE1E,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,uBAAuB,CAoEtE,CAAC;AAqBF,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAChF,KAAK,UAAU,EAAE,GAAG,uBAAuB,KAAG,OAAO,CAAC,MAAM,CAAC,CAsB5E"}