agentplane 0.3.6 → 0.3.7

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 (120) hide show
  1. package/dist/.build-manifest.json +106 -96
  2. package/dist/adapters/task-backend/task-backend-adapter.d.ts +2 -2
  3. package/dist/adapters/task-backend/task-backend-adapter.d.ts.map +1 -1
  4. package/dist/adapters/task-backend/task-backend-adapter.js +2 -2
  5. package/dist/backends/task-backend/local-backend.d.ts +7 -5
  6. package/dist/backends/task-backend/local-backend.d.ts.map +1 -1
  7. package/dist/backends/task-backend/local-backend.js +79 -7
  8. package/dist/backends/task-backend/redmine/env.d.ts +1 -1
  9. package/dist/backends/task-backend/redmine/env.d.ts.map +1 -1
  10. package/dist/backends/task-backend/redmine/env.js +3 -0
  11. package/dist/backends/task-backend/redmine/inspect.d.ts +11 -0
  12. package/dist/backends/task-backend/redmine/inspect.d.ts.map +1 -0
  13. package/dist/backends/task-backend/redmine/inspect.js +75 -0
  14. package/dist/backends/task-backend/redmine/mapping.d.ts.map +1 -1
  15. package/dist/backends/task-backend/redmine/mapping.js +21 -2
  16. package/dist/backends/task-backend/redmine/state.d.ts +17 -0
  17. package/dist/backends/task-backend/redmine/state.d.ts.map +1 -0
  18. package/dist/backends/task-backend/redmine/state.js +95 -0
  19. package/dist/backends/task-backend/redmine-backend.d.ts +10 -16
  20. package/dist/backends/task-backend/redmine-backend.d.ts.map +1 -1
  21. package/dist/backends/task-backend/redmine-backend.js +205 -15
  22. package/dist/backends/task-backend/shared/constants.d.ts +1 -1
  23. package/dist/backends/task-backend/shared/constants.js +1 -1
  24. package/dist/backends/task-backend/shared/record.d.ts.map +1 -1
  25. package/dist/backends/task-backend/shared/record.js +20 -1
  26. package/dist/backends/task-backend/shared/types.d.ts +42 -4
  27. package/dist/backends/task-backend/shared/types.d.ts.map +1 -1
  28. package/dist/backends/task-backend/shared.d.ts +1 -1
  29. package/dist/backends/task-backend/shared.d.ts.map +1 -1
  30. package/dist/backends/task-backend.d.ts +1 -1
  31. package/dist/backends/task-backend.d.ts.map +1 -1
  32. package/dist/backends/task-index.d.ts.map +1 -1
  33. package/dist/backends/task-index.js +1 -0
  34. package/dist/cli/run-cli/command-catalog/project.d.ts +1 -1
  35. package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -1
  36. package/dist/cli/run-cli/command-catalog/project.js +3 -1
  37. package/dist/cli/run-cli/command-catalog.d.ts +1 -1
  38. package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
  39. package/dist/cli/run-cli/commands/init/write-env.d.ts.map +1 -1
  40. package/dist/cli/run-cli/commands/init/write-env.js +12 -0
  41. package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
  42. package/dist/cli/run-cli.test-helpers.js +2 -0
  43. package/dist/commands/backend/sync.command.d.ts +5 -1
  44. package/dist/commands/backend/sync.command.d.ts.map +1 -1
  45. package/dist/commands/backend/sync.command.js +67 -3
  46. package/dist/commands/backend.d.ts +22 -0
  47. package/dist/commands/backend.d.ts.map +1 -1
  48. package/dist/commands/backend.js +110 -1
  49. package/dist/commands/commit.spec.d.ts.map +1 -1
  50. package/dist/commands/commit.spec.js +30 -6
  51. package/dist/commands/doctor/workspace.d.ts +8 -0
  52. package/dist/commands/doctor/workspace.d.ts.map +1 -1
  53. package/dist/commands/doctor/workspace.js +127 -3
  54. package/dist/commands/guard/commit.command.d.ts.map +1 -1
  55. package/dist/commands/guard/commit.command.js +30 -6
  56. package/dist/commands/guard/impl/allow.d.ts +4 -0
  57. package/dist/commands/guard/impl/allow.d.ts.map +1 -1
  58. package/dist/commands/guard/impl/allow.js +14 -3
  59. package/dist/commands/guard/impl/commands.d.ts.map +1 -1
  60. package/dist/commands/guard/impl/commands.js +11 -2
  61. package/dist/commands/shared/task-backend.d.ts +1 -1
  62. package/dist/commands/shared/task-backend.d.ts.map +1 -1
  63. package/dist/commands/shared/task-backend.js +9 -0
  64. package/dist/commands/shared/task-store.d.ts +61 -2
  65. package/dist/commands/shared/task-store.d.ts.map +1 -1
  66. package/dist/commands/shared/task-store.js +298 -60
  67. package/dist/commands/task/block.d.ts.map +1 -1
  68. package/dist/commands/task/block.js +58 -37
  69. package/dist/commands/task/close-shared.d.ts.map +1 -1
  70. package/dist/commands/task/close-shared.js +17 -20
  71. package/dist/commands/task/comment.d.ts.map +1 -1
  72. package/dist/commands/task/comment.js +14 -19
  73. package/dist/commands/task/derive.command.d.ts +1 -0
  74. package/dist/commands/task/derive.command.d.ts.map +1 -1
  75. package/dist/commands/task/derive.command.js +15 -2
  76. package/dist/commands/task/derive.d.ts +1 -0
  77. package/dist/commands/task/derive.d.ts.map +1 -1
  78. package/dist/commands/task/derive.js +27 -4
  79. package/dist/commands/task/doc.d.ts.map +1 -1
  80. package/dist/commands/task/doc.js +16 -5
  81. package/dist/commands/task/finish.d.ts.map +1 -1
  82. package/dist/commands/task/finish.js +41 -41
  83. package/dist/commands/task/migrate-doc.d.ts +15 -0
  84. package/dist/commands/task/migrate-doc.d.ts.map +1 -1
  85. package/dist/commands/task/migrate-doc.js +126 -35
  86. package/dist/commands/task/new.d.ts.map +1 -1
  87. package/dist/commands/task/new.js +3 -1
  88. package/dist/commands/task/plan.js +28 -28
  89. package/dist/commands/task/set-status.d.ts.map +1 -1
  90. package/dist/commands/task/set-status.js +104 -61
  91. package/dist/commands/task/shared/dependencies.d.ts +1 -0
  92. package/dist/commands/task/shared/dependencies.d.ts.map +1 -1
  93. package/dist/commands/task/shared/dependencies.js +10 -0
  94. package/dist/commands/task/shared/docs.js +1 -1
  95. package/dist/commands/task/shared/transitions.d.ts +17 -0
  96. package/dist/commands/task/shared/transitions.d.ts.map +1 -1
  97. package/dist/commands/task/shared/transitions.js +20 -7
  98. package/dist/commands/task/shared.d.ts +2 -2
  99. package/dist/commands/task/shared.d.ts.map +1 -1
  100. package/dist/commands/task/shared.js +2 -2
  101. package/dist/commands/task/start.d.ts.map +1 -1
  102. package/dist/commands/task/start.js +33 -28
  103. package/dist/commands/task/verify-record.d.ts.map +1 -1
  104. package/dist/commands/task/verify-record.js +32 -32
  105. package/dist/commands/upgrade/apply.d.ts +2 -0
  106. package/dist/commands/upgrade/apply.d.ts.map +1 -1
  107. package/dist/commands/upgrade/apply.js +33 -1
  108. package/dist/commands/upgrade.command.d.ts.map +1 -1
  109. package/dist/commands/upgrade.command.js +25 -0
  110. package/dist/commands/upgrade.d.ts +1 -0
  111. package/dist/commands/upgrade.d.ts.map +1 -1
  112. package/dist/commands/upgrade.js +34 -0
  113. package/dist/policy/rules/allowlist.d.ts.map +1 -1
  114. package/dist/policy/rules/allowlist.js +12 -9
  115. package/dist/ports/task-backend-port.d.ts +2 -2
  116. package/dist/ports/task-backend-port.d.ts.map +1 -1
  117. package/dist/shared/protected-paths.d.ts +10 -0
  118. package/dist/shared/protected-paths.d.ts.map +1 -1
  119. package/dist/shared/protected-paths.js +33 -0
  120. package/package.json +2 -2
@@ -20,6 +20,12 @@ const REDMINE_ENV_TEMPLATE = [
20
20
  comment: "Project identifier (numeric ID or project slug).",
21
21
  required: true,
22
22
  },
23
+ {
24
+ key: "AGENTPLANE_REDMINE_CUSTOM_FIELDS_TASK_ID",
25
+ value: "1",
26
+ comment: "Required Redmine custom field ID that stores the agentplane task id.",
27
+ required: true,
28
+ },
23
29
  {
24
30
  key: "AGENTPLANE_REDMINE_OWNER_AGENT",
25
31
  value: "REDMINE",
@@ -32,6 +38,12 @@ const REDMINE_ENV_TEMPLATE = [
32
38
  comment: "Optional assignee numeric ID.",
33
39
  required: false,
34
40
  },
41
+ {
42
+ key: "AGENTPLANE_REDMINE_CUSTOM_FIELDS_CANONICAL_STATE",
43
+ value: "",
44
+ comment: "Optional Redmine custom field ID for structured canonical task state JSON.",
45
+ required: false,
46
+ },
35
47
  ];
36
48
  async function readTextIfExists(filePath) {
37
49
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"run-cli.test-helpers.d.ts","sourceRoot":"","sources":["../../src/cli/run-cli.test-helpers.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAiD/D,wBAAgB,sBAAsB,IAAI,IAAI,CA8C7C;AAED,wBAAgB,+BAA+B,IAAI,IAAI,CAYtD;AAED,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAEjD;AAED,wBAAgB,YAAY;;;;EAgC3B;AAED,wBAAgB,YAAY,IAAI,MAAM,IAAI,CAkBzC;AAED,wBAAgB,eAAe,CAAC,SAAS,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CAmBjF;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAOlE;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAMrD;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAIjD;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKpE;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,GACvC,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC,CAKhE;AAED,wBAAsB,mBAAmB,CAAC,IAAI,CAAC,EAAE;IAC/C,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CA8JtE;AAED,wBAAsB,+BAA+B,CAAC,IAAI,EAAE;IAC1D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBlB;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAE;IACpD,MAAM,EAAE,KAAK,GAAG,KAAK,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6GlB;AA6DD,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;IAChF,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC,CAqDD;AAED,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI7E;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGlE;AAED,wBAAgB,WAAW,IAAI,MAAM,CAAC,UAAU,CAS/C;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnE;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAYpF;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5E;AAED,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIzE"}
1
+ {"version":3,"file":"run-cli.test-helpers.d.ts","sourceRoot":"","sources":["../../src/cli/run-cli.test-helpers.ts"],"names":[],"mappings":"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"}
@@ -169,6 +169,8 @@ export function stubTaskBackend(overrides = {}) {
169
169
  projection: "canonical",
170
170
  reads_from_projection_by_default: false,
171
171
  writes_task_readmes: true,
172
+ supports_task_revisions: true,
173
+ supports_revision_guarded_writes: true,
172
174
  may_access_network_on_read: false,
173
175
  may_access_network_on_write: false,
174
176
  supports_projection_refresh: false,
@@ -1,13 +1,17 @@
1
1
  import type { CommandCtx, CommandSpec } from "../../cli/spec/spec.js";
2
2
  import type { CommandContext } from "../shared/task-backend.js";
3
- import { type BackendSyncParsed } from "../backend.js";
3
+ import { type BackendInspectParsed, type BackendMigrateCanonicalStateParsed, type BackendSyncParsed } from "../backend.js";
4
4
  type BackendRootParsed = {
5
5
  cmd: string[];
6
6
  };
7
7
  export declare const backendSpec: CommandSpec<BackendRootParsed>;
8
8
  export declare const backendSyncSpec: CommandSpec<BackendSyncParsed>;
9
+ export declare const backendMigrateCanonicalStateSpec: CommandSpec<BackendMigrateCanonicalStateParsed>;
10
+ export declare const backendInspectSpec: CommandSpec<BackendInspectParsed>;
9
11
  declare function runBackendRootGroup(_ctx: CommandCtx, p: BackendRootParsed): Promise<number>;
10
12
  export declare function makeRunBackendHandler(_getCtx: (cmd: string) => Promise<CommandContext>): typeof runBackendRootGroup;
11
13
  export declare function makeRunBackendSyncHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: BackendSyncParsed) => Promise<number>;
14
+ export declare function makeRunBackendInspectHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: BackendInspectParsed) => Promise<number>;
15
+ export declare function makeRunBackendMigrateCanonicalStateHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: BackendMigrateCanonicalStateParsed) => Promise<number>;
12
16
  export {};
13
17
  //# sourceMappingURL=sync.command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sync.command.d.ts","sourceRoot":"","sources":["../../../src/commands/backend/sync.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAItE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAwB,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE7E,KAAK,iBAAiB,GAAG;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAE3C,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,iBAAiB,CAQtD,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,iBAAiB,CAuC1D,CAAC;AAEF,iBAAS,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAUpF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,8BAEtF;AAED,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,CAStE"}
1
+ {"version":3,"file":"sync.command.d.ts","sourceRoot":"","sources":["../../../src/commands/backend/sync.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAItE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAIL,KAAK,oBAAoB,EACzB,KAAK,kCAAkC,EACvC,KAAK,iBAAiB,EACvB,MAAM,eAAe,CAAC;AAEvB,KAAK,iBAAiB,GAAG;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAE3C,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,iBAAiB,CAStD,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,iBAAiB,CAuC1D,CAAC;AAEF,eAAO,MAAM,gCAAgC,EAAE,WAAW,CAAC,kCAAkC,CAoB5F,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,oBAAoB,CAoBhE,CAAC;AAEF,iBAAS,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAUpF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,8BAEtF;AAED,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,CAStE;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAC7E,KAAK,UAAU,EAAE,GAAG,oBAAoB,KAAG,OAAO,CAAC,MAAM,CAAC,CASzE;AAED,wBAAgB,0CAA0C,CACxD,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAElC,KAAK,UAAU,EAAE,GAAG,kCAAkC,KAAG,OAAO,CAAC,MAAM,CAAC,CASvF"}
@@ -1,12 +1,12 @@
1
1
  import { COMMAND_SNIPPETS } from "../../cli/command-snippets.js";
2
2
  import { usageError } from "../../cli/spec/errors.js";
3
3
  import { suggestOne } from "../../cli/spec/suggest.js";
4
- import { cmdBackendSyncParsed } from "../backend.js";
4
+ import { cmdBackendInspectParsed, cmdBackendMigrateCanonicalStateParsed, cmdBackendSyncParsed, } from "../backend.js";
5
5
  export const backendSpec = {
6
6
  id: ["backend"],
7
7
  group: "Backend",
8
8
  summary: "Backend-related operations.",
9
- description: "This is a command group. Use a subcommand such as `agentplane backend sync ...`.",
9
+ description: "This is a command group. Use a subcommand such as `agentplane backend sync ...`, `agentplane backend inspect ...`, or `agentplane backend migrate-canonical-state ...`.",
10
10
  args: [{ name: "cmd", required: false, variadic: true, valueHint: "<cmd>" }],
11
11
  examples: [{ cmd: COMMAND_SNIPPETS.backendSync.pullLocal, why: "Sync the backend." }],
12
12
  parse: (raw) => ({ cmd: (raw.args.cmd ?? []) }),
@@ -51,9 +51,51 @@ export const backendSyncSpec = {
51
51
  quiet: raw.opts.quiet === true,
52
52
  }),
53
53
  };
54
+ export const backendMigrateCanonicalStateSpec = {
55
+ id: ["backend", "migrate-canonical-state"],
56
+ group: "Backend",
57
+ summary: "Backfill canonical_state for issues in the configured backend.",
58
+ args: [{ name: "id", required: true, valueHint: "<id>", description: "Configured backend id." }],
59
+ options: [
60
+ { kind: "boolean", name: "yes", default: false, description: "Auto-approve network access." },
61
+ { kind: "boolean", name: "quiet", default: false, description: "Reduce output noise." },
62
+ ],
63
+ examples: [
64
+ {
65
+ cmd: "agentplane backend migrate-canonical-state redmine --yes",
66
+ why: "Backfill structured canonical_state into legacy Redmine issues.",
67
+ },
68
+ ],
69
+ parse: (raw) => ({
70
+ backendId: String(raw.args.id),
71
+ yes: raw.opts.yes === true,
72
+ quiet: raw.opts.quiet === true,
73
+ }),
74
+ };
75
+ export const backendInspectSpec = {
76
+ id: ["backend", "inspect"],
77
+ group: "Backend",
78
+ summary: "Inspect visible backend readiness facts without mutating remote state.",
79
+ args: [{ name: "id", required: true, valueHint: "<id>", description: "Configured backend id." }],
80
+ options: [
81
+ { kind: "boolean", name: "yes", default: false, description: "Auto-approve network access." },
82
+ { kind: "boolean", name: "quiet", default: false, description: "Reduce output noise." },
83
+ ],
84
+ examples: [
85
+ {
86
+ cmd: "agentplane backend inspect redmine --yes",
87
+ why: "Inspect visible Redmine custom fields and canonical_state readiness without remote writes.",
88
+ },
89
+ ],
90
+ parse: (raw) => ({
91
+ backendId: String(raw.args.id),
92
+ yes: raw.opts.yes === true,
93
+ quiet: raw.opts.quiet === true,
94
+ }),
95
+ };
54
96
  function runBackendRootGroup(_ctx, p) {
55
97
  const input = p.cmd.join(" ");
56
- const suggestion = suggestOne(input, ["sync"]);
98
+ const suggestion = suggestOne(input, ["sync", "inspect", "migrate-canonical-state"]);
57
99
  const suffix = suggestion ? ` Did you mean: ${suggestion}?` : "";
58
100
  const msg = p.cmd.length === 0 ? "Missing subcommand." : `Unknown subcommand: ${p.cmd[0]}.`;
59
101
  throw usageError({
@@ -76,3 +118,25 @@ export function makeRunBackendSyncHandler(getCtx) {
76
118
  });
77
119
  };
78
120
  }
121
+ export function makeRunBackendInspectHandler(getCtx) {
122
+ return async (ctx, p) => {
123
+ const commandCtx = await getCtx("backend inspect");
124
+ return await cmdBackendInspectParsed({
125
+ ctx: commandCtx,
126
+ cwd: ctx.cwd,
127
+ rootOverride: ctx.rootOverride,
128
+ flags: p,
129
+ });
130
+ };
131
+ }
132
+ export function makeRunBackendMigrateCanonicalStateHandler(getCtx) {
133
+ return async (ctx, p) => {
134
+ const commandCtx = await getCtx("backend migrate-canonical-state");
135
+ return await cmdBackendMigrateCanonicalStateParsed({
136
+ ctx: commandCtx,
137
+ cwd: ctx.cwd,
138
+ rootOverride: ctx.rootOverride,
139
+ flags: p,
140
+ });
141
+ };
142
+ }
@@ -13,6 +13,16 @@ export type SyncParsed = {
13
13
  yes: boolean;
14
14
  quiet: boolean;
15
15
  };
16
+ export type BackendMigrateCanonicalStateParsed = {
17
+ backendId: string;
18
+ yes: boolean;
19
+ quiet: boolean;
20
+ };
21
+ export type BackendInspectParsed = {
22
+ backendId: string;
23
+ yes: boolean;
24
+ quiet: boolean;
25
+ };
16
26
  export declare function cmdBackendSyncParsed(opts: {
17
27
  ctx?: CommandContext;
18
28
  cwd: string;
@@ -25,4 +35,16 @@ export declare function cmdSyncParsed(opts: {
25
35
  rootOverride?: string;
26
36
  flags: SyncParsed;
27
37
  }): Promise<number>;
38
+ export declare function cmdBackendMigrateCanonicalStateParsed(opts: {
39
+ ctx?: CommandContext;
40
+ cwd: string;
41
+ rootOverride?: string;
42
+ flags: BackendMigrateCanonicalStateParsed;
43
+ }): Promise<number>;
44
+ export declare function cmdBackendInspectParsed(opts: {
45
+ ctx?: CommandContext;
46
+ cwd: string;
47
+ rootOverride?: string;
48
+ flags: BackendInspectParsed;
49
+ }): Promise<number>;
28
50
  //# sourceMappingURL=backend.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/commands/backend.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAGnF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,eAAe,GAAG,MAAM,CAAC;IAC7D,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,eAAe,GAAG,MAAM,CAAC;IAC7D,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,iBAAiB,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,CAAC,CAyClB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,UAAU,CAAC;CACnB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyClB"}
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/commands/backend.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAGnF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,eAAe,GAAG,MAAM,CAAC;IAC7D,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,eAAe,GAAG,MAAM,CAAC;IAC7D,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,iBAAiB,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,CAAC,CAyClB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,UAAU,CAAC;CACnB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyClB;AAED,wBAAsB,qCAAqC,CAAC,IAAI,EAAE;IAChE,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,kCAAkC,CAAC;CAC3C,GAAG,OAAO,CAAC,MAAM,CAAC,CA2DlB;AAED,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAClD,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,oBAAoB,CAAC;CAC7B,GAAG,OAAO,CAAC,MAAM,CAAC,CAkElB"}
@@ -1,4 +1,4 @@
1
- import { backendNotSupportedMessage } from "../cli/output.js";
1
+ import { backendNotSupportedMessage, successMessage, warnMessage } from "../cli/output.js";
2
2
  import { mapBackendError } from "../cli/error-map.js";
3
3
  import { CliError } from "../shared/errors.js";
4
4
  import { loadCommandContext } from "./shared/task-backend.js";
@@ -89,3 +89,112 @@ export async function cmdSyncParsed(opts) {
89
89
  throw mapBackendError(err, { command: "sync", root: opts.rootOverride ?? null });
90
90
  }
91
91
  }
92
+ export async function cmdBackendMigrateCanonicalStateParsed(opts) {
93
+ try {
94
+ const ctx = opts.ctx ??
95
+ (await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
96
+ const backend = ctx.taskBackend;
97
+ const backendId = ctx.backendId;
98
+ const config = ctx.config;
99
+ if (opts.flags.backendId && backendId && opts.flags.backendId !== backendId) {
100
+ throw new CliError({
101
+ exitCode: 2,
102
+ code: "E_USAGE",
103
+ message: `Configured backend is "${backendId}", not "${opts.flags.backendId}"`,
104
+ context: {
105
+ command: "backend migrate-canonical-state",
106
+ reason_code: "sync_backend_mismatch",
107
+ },
108
+ });
109
+ }
110
+ if (!backend.migrateCanonicalState) {
111
+ throw new CliError({
112
+ exitCode: 2,
113
+ code: "E_USAGE",
114
+ message: backendNotSupportedMessage("migrateCanonicalState()"),
115
+ });
116
+ }
117
+ if (backendId !== "local") {
118
+ await ensureNetworkApproved({
119
+ config,
120
+ yes: opts.flags.yes,
121
+ reason: `backend migrate-canonical-state may access the network (backend: ${backendId})`,
122
+ });
123
+ }
124
+ const result = await backend.migrateCanonicalState();
125
+ if (!opts.flags.quiet) {
126
+ process.stdout.write(`${successMessage("backend migrate-canonical-state", undefined, `scanned=${result.scanned} migrated=${result.migrated.length} skipped-structured=${result.skippedStructured.length} skipped-no-doc=${result.skippedNoDoc.length} failed=${result.failed.length}`)}\n`);
127
+ }
128
+ if (result.failed.length > 0) {
129
+ for (const failure of result.failed.slice(0, 20)) {
130
+ process.stderr.write(`${warnMessage(`backend migrate-canonical-state failed for ${failure.taskId}: ${failure.reason}`)}\n`);
131
+ }
132
+ return 1;
133
+ }
134
+ return 0;
135
+ }
136
+ catch (err) {
137
+ if (err instanceof CliError)
138
+ throw err;
139
+ throw mapBackendError(err, {
140
+ command: "backend migrate-canonical-state",
141
+ root: opts.rootOverride ?? null,
142
+ });
143
+ }
144
+ }
145
+ export async function cmdBackendInspectParsed(opts) {
146
+ try {
147
+ const ctx = opts.ctx ??
148
+ (await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
149
+ const backend = ctx.taskBackend;
150
+ const backendId = ctx.backendId;
151
+ const config = ctx.config;
152
+ if (opts.flags.backendId && backendId && opts.flags.backendId !== backendId) {
153
+ throw new CliError({
154
+ exitCode: 2,
155
+ code: "E_USAGE",
156
+ message: `Configured backend is "${backendId}", not "${opts.flags.backendId}"`,
157
+ context: {
158
+ command: "backend inspect",
159
+ reason_code: "inspect_backend_mismatch",
160
+ },
161
+ });
162
+ }
163
+ if (!backend.inspectConfiguration) {
164
+ throw new CliError({
165
+ exitCode: 2,
166
+ code: "E_USAGE",
167
+ message: backendNotSupportedMessage("inspectConfiguration()"),
168
+ });
169
+ }
170
+ if (backendId !== "local") {
171
+ await ensureNetworkApproved({
172
+ config,
173
+ yes: opts.flags.yes,
174
+ reason: `backend inspect may access the network (backend: ${backendId})`,
175
+ });
176
+ }
177
+ const result = await backend.inspectConfiguration();
178
+ if (opts.flags.quiet)
179
+ return 0;
180
+ const canonicalStateSummary = result.canonicalState.configuredFieldId === null
181
+ ? result.canonicalState.visibleFieldId === null
182
+ ? "missing"
183
+ : `visible-unconfigured:${result.canonicalState.visibleFieldId}`
184
+ : `configured:${result.canonicalState.configuredFieldId}`;
185
+ process.stdout.write(`${successMessage("backend inspect", undefined, `visible-fields=${result.visibleCustomFields.length} canonical-state=${canonicalStateSummary} drift=${result.configuredFieldNameDrift.length}`)}\n`);
186
+ process.stdout.write(`canonical_state configured=${result.canonicalState.configuredFieldId ?? "unset"} visible=${result.canonicalState.visibleFieldId ?? "absent"}\n`);
187
+ for (const drift of result.configuredFieldNameDrift) {
188
+ process.stdout.write(`drift key=${drift.key} configured-id=${drift.configuredId} visible-name=${JSON.stringify(drift.visibleName)}\n`);
189
+ }
190
+ for (const field of result.visibleCustomFields) {
191
+ process.stdout.write(`field id=${field.id} name=${JSON.stringify(field.name)} non-empty=${field.nonEmptyCount}\n`);
192
+ }
193
+ return 0;
194
+ }
195
+ catch (err) {
196
+ if (err instanceof CliError)
197
+ throw err;
198
+ throw mapBackendError(err, { command: "backend inspect", root: opts.rootOverride ?? null });
199
+ }
200
+ }
@@ -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;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,CA+JhD,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,CAwLhD,CAAC"}
@@ -49,23 +49,38 @@ export const commitSpec = {
49
49
  kind: "boolean",
50
50
  name: "allow-tasks",
51
51
  default: false,
52
- description: "Allow the tasks export snapshot plus artifacts under the active task subtree.",
52
+ description: "Allow the tasks export snapshot plus artifacts under the active task subtree; standalone path scope.",
53
53
  },
54
54
  {
55
55
  kind: "boolean",
56
56
  name: "allow-base",
57
57
  default: false,
58
- description: "Allow base branch edits.",
58
+ description: "Allow base branch edits; branch override only, not a path allowlist.",
59
59
  },
60
60
  {
61
61
  kind: "boolean",
62
62
  name: "allow-policy",
63
63
  default: false,
64
- description: "Allow policy edits (e.g. AGENTS.md).",
64
+ description: "Allow policy edits (e.g. AGENTS.md); standalone path scope.",
65
+ },
66
+ {
67
+ kind: "boolean",
68
+ name: "allow-config",
69
+ default: false,
70
+ description: "Allow config edits; standalone path scope.",
71
+ },
72
+ {
73
+ kind: "boolean",
74
+ name: "allow-hooks",
75
+ default: false,
76
+ description: "Allow hooks edits; standalone path scope.",
77
+ },
78
+ {
79
+ kind: "boolean",
80
+ name: "allow-ci",
81
+ default: false,
82
+ description: "Allow CI workflow edits; standalone path scope.",
65
83
  },
66
- { kind: "boolean", name: "allow-config", default: false, description: "Allow config edits." },
67
- { kind: "boolean", name: "allow-hooks", default: false, description: "Allow hooks edits." },
68
- { kind: "boolean", name: "allow-ci", default: false, description: "Allow CI workflow edits." },
69
84
  {
70
85
  kind: "boolean",
71
86
  name: "require-clean",
@@ -79,11 +94,20 @@ export const commitSpec = {
79
94
  cmd: 'agentplane commit 202602030608-F1Q8AB -m "✨ F1Q8AB task: implement allowlist guard" --allow packages/agentplane',
80
95
  why: "Create a commit after validating allowlist and subject policy.",
81
96
  },
97
+ {
98
+ cmd: 'agentplane commit 202602030608-F1Q8AB -m "✨ F1Q8AB task: update publish workflow" --allow-ci',
99
+ why: "Commit CI-only changes without a redundant explicit workflow path prefix.",
100
+ },
82
101
  {
83
102
  cmd: "agentplane commit 202602030608-F1Q8AB --close",
84
103
  why: "Create a close commit for the task README using a deterministic message builder.",
85
104
  },
86
105
  ],
106
+ notes: [
107
+ "Protected path-scoped overrides can stand alone without a duplicate explicit prefix: `--allow-tasks`, `--allow-policy`, `--allow-config`, `--allow-hooks`, and `--allow-ci` each admit their own path family.",
108
+ "Top-level `agentplane commit` can auto-stage those protected path scopes when the git index starts empty.",
109
+ "`--allow-base` is different: it only overrides base-branch protection and never selects file paths by itself.",
110
+ ],
87
111
  validateRaw: (raw) => {
88
112
  const close = raw.opts.close === true;
89
113
  const msg = typeof raw.opts.message === "string" ? raw.opts.message.trim() : "";
@@ -1,5 +1,13 @@
1
1
  import { type CommandContext } from "../shared/task-backend.js";
2
+ type TaskDocSnapshot = {
3
+ id?: unknown;
4
+ status?: unknown;
5
+ doc_version?: unknown;
6
+ };
7
+ export declare function buildTaskReadmeMigrationFindings(tasks: TaskDocSnapshot[]): string[];
8
+ export declare function checkTaskReadmeMigrationState(repoRoot: string, ctx?: CommandContext): Promise<string[]>;
2
9
  export declare function checkWorkspace(repoRoot: string, opts?: {
3
10
  ctx?: CommandContext;
4
11
  }): Promise<string[]>;
12
+ export {};
5
13
  //# sourceMappingURL=workspace.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/workspace.ts"],"names":[],"mappings":"AAQA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AA6NpF,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,cAAc,CAAA;CAAE,GAC9B,OAAO,CAAC,MAAM,EAAE,CAAC,CAyDnB"}
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/workspace.ts"],"names":[],"mappings":"AAUA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEpF,KAAK,eAAe,GAAG;IACrB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAuFF,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,CAyDnF;AAED,wBAAsB,6BAA6B,CACjD,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,cAAc,GACnB,OAAO,CAAC,MAAM,EAAE,CAAC,CAOnB;AAuMD,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,cAAc,CAAA;CAAE,GAC9B,OAAO,CAAC,MAAM,EAAE,CAAC,CA2DnB"}
@@ -1,6 +1,7 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
+ import { parseTaskReadme, renderTaskDocFromSections } from "@agentplaneorg/core";
4
5
  import { renderDiagnosticFinding } from "../../shared/diagnostics.js";
5
6
  import { resolvePolicyGatewayForRepo } from "../../shared/policy-gateway.js";
6
7
  import { GitContext } from "../shared/git-context.js";
@@ -84,7 +85,7 @@ async function readTaskDocSnapshotsFromProjection(ctx) {
84
85
  return null;
85
86
  }
86
87
  }
87
- function buildTaskReadmeMigrationFindings(tasks) {
88
+ export function buildTaskReadmeMigrationFindings(tasks) {
88
89
  if (tasks.length === 0)
89
90
  return [];
90
91
  const legacy = tasks.filter((task) => task.doc_version !== 3);
@@ -138,7 +139,7 @@ function buildTaskReadmeMigrationFindings(tasks) {
138
139
  }),
139
140
  ];
140
141
  }
141
- async function checkTaskReadmeMigrationState(repoRoot, ctx) {
142
+ export async function checkTaskReadmeMigrationState(repoRoot, ctx) {
142
143
  const projectionTasks = await readTaskDocSnapshotsFromProjection(ctx);
143
144
  const tasks = projectionTasks && projectionTasks.length > 0
144
145
  ? projectionTasks
@@ -197,6 +198,129 @@ async function checkDoneTaskReadmeArchiveDrift(repoRoot, ctx) {
197
198
  }),
198
199
  ];
199
200
  }
201
+ function normalizeTaskBodyForComparison(text) {
202
+ return text.replaceAll("\r\n", "\n").trim();
203
+ }
204
+ function normalizeCanonicalSections(value) {
205
+ if (!value || typeof value !== "object" || Array.isArray(value))
206
+ return null;
207
+ const sections = {};
208
+ for (const [key, entry] of Object.entries(value)) {
209
+ const title = key.trim();
210
+ if (!title || typeof entry !== "string")
211
+ continue;
212
+ sections[title] = entry;
213
+ }
214
+ return Object.keys(sections).length > 0 ? sections : null;
215
+ }
216
+ async function checkTaskProjectionDrift(repoRoot, ctx) {
217
+ const workflowDir = path.join(repoRoot, ctx?.config.paths.workflow_dir ?? ".agentplane/tasks");
218
+ let entries;
219
+ try {
220
+ entries = await fs.readdir(workflowDir, { withFileTypes: true });
221
+ }
222
+ catch {
223
+ return [];
224
+ }
225
+ const drifted = [];
226
+ for (const entry of entries) {
227
+ if (!entry.isDirectory())
228
+ continue;
229
+ const readmePath = path.join(workflowDir, entry.name, "README.md");
230
+ let text = "";
231
+ try {
232
+ text = await fs.readFile(readmePath, "utf8");
233
+ }
234
+ catch {
235
+ continue;
236
+ }
237
+ let parsed;
238
+ try {
239
+ parsed = parseTaskReadme(text);
240
+ }
241
+ catch {
242
+ continue;
243
+ }
244
+ const sections = normalizeCanonicalSections(parsed.frontmatter.sections);
245
+ if (!sections)
246
+ continue;
247
+ const renderedBody = renderTaskDocFromSections(sections);
248
+ if (normalizeTaskBodyForComparison(parsed.body) === normalizeTaskBodyForComparison(renderedBody)) {
249
+ continue;
250
+ }
251
+ const taskId = typeof parsed.frontmatter.id === "string" && parsed.frontmatter.id.trim()
252
+ ? parsed.frontmatter.id.trim()
253
+ : entry.name;
254
+ const status = typeof parsed.frontmatter.status === "string" && parsed.frontmatter.status.trim()
255
+ ? parsed.frontmatter.status.trim().toUpperCase()
256
+ : "UNKNOWN";
257
+ drifted.push({ id: taskId, status });
258
+ }
259
+ if (drifted.length === 0)
260
+ return [];
261
+ const activeCount = drifted.filter((task) => task.status !== "DONE").length;
262
+ const examples = drifted
263
+ .slice(0, 5)
264
+ .map((task) => `${task.id}[${task.status}]`)
265
+ .join(", ");
266
+ return [
267
+ renderDiagnosticFinding({
268
+ severity: "WARN",
269
+ state: "task README projection drift detected",
270
+ likelyCause: "canonical frontmatter.sections no longer match the rendered task body on disk",
271
+ nextAction: {
272
+ command: "agentplane task normalize",
273
+ reason: "re-render task README bodies from canonical one-file task state",
274
+ },
275
+ details: [
276
+ `Drifted task READMEs: ${drifted.length}; active drifted tasks: ${activeCount}`,
277
+ examples ? `Examples: ${examples}` : "Examples unavailable.",
278
+ ],
279
+ }),
280
+ ];
281
+ }
282
+ function checkBackendReadiness(ctx) {
283
+ if (ctx?.backendId !== "redmine")
284
+ return [];
285
+ const { supports_task_revisions, supports_revision_guarded_writes } = ctx.taskBackend.capabilities;
286
+ if (supports_task_revisions === supports_revision_guarded_writes &&
287
+ supports_task_revisions === true) {
288
+ return [];
289
+ }
290
+ if (supports_task_revisions === false && supports_revision_guarded_writes === false) {
291
+ return [
292
+ renderDiagnosticFinding({
293
+ severity: "WARN",
294
+ state: "Redmine backend is running in partial compatibility mode without canonical_state support",
295
+ likelyCause: "AGENTPLANE_REDMINE_CUSTOM_FIELDS_CANONICAL_STATE is not configured, so Redmine cannot round-trip the full canonical task state or guard writes by remote revision",
296
+ nextAction: {
297
+ command: "agentplane backend inspect redmine --yes",
298
+ reason: "inspect visible Redmine custom fields first, then wire AGENTPLANE_REDMINE_CUSTOM_FIELDS_CANONICAL_STATE to the correct field id",
299
+ },
300
+ details: [
301
+ `Backend config: ${ctx.backendConfigPath}`,
302
+ "Current capability flags: supports_task_revisions=false; supports_revision_guarded_writes=false",
303
+ "Legacy doc field syncing can still work, but the backend remains partial-compatibility only.",
304
+ ],
305
+ }),
306
+ ];
307
+ }
308
+ return [
309
+ renderDiagnosticFinding({
310
+ severity: "WARN",
311
+ state: "Redmine backend capability contract is internally inconsistent",
312
+ likelyCause: "backend capability flags diverged, so doctor cannot rely on a single revision-guard readiness state",
313
+ nextAction: {
314
+ command: "inspect Redmine backend capability wiring and rerun agentplane doctor",
315
+ reason: "restore a coherent readiness contract before relying on guarded remote writes",
316
+ },
317
+ details: [
318
+ `Backend config: ${ctx.backendConfigPath}`,
319
+ `Current capability flags: supports_task_revisions=${String(supports_task_revisions)}; supports_revision_guarded_writes=${String(supports_revision_guarded_writes)}`,
320
+ ],
321
+ }),
322
+ ];
323
+ }
200
324
  export async function checkWorkspace(repoRoot, opts) {
201
325
  const problems = [];
202
326
  const requiredFiles = [path.join(repoRoot, ".agentplane", "config.json")];
@@ -243,6 +367,6 @@ export async function checkWorkspace(repoRoot, opts) {
243
367
  if (!hasJson) {
244
368
  problems.push("No agent profiles found in .agentplane/agents (*.json expected).");
245
369
  }
246
- problems.push(...(await checkTaskReadmeMigrationState(repoRoot, opts?.ctx)), ...(await checkDoneTaskReadmeArchiveDrift(repoRoot, opts?.ctx)));
370
+ problems.push(...checkBackendReadiness(opts?.ctx), ...(await checkTaskReadmeMigrationState(repoRoot, opts?.ctx)), ...(await checkDoneTaskReadmeArchiveDrift(repoRoot, opts?.ctx)), ...(await checkTaskProjectionDrift(repoRoot, opts?.ctx)));
247
371
  return problems;
248
372
  }
@@ -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;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
+ {"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,CAmI1D,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"}