agentplane 0.3.5 → 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 (256) hide show
  1. package/README.md +103 -75
  2. package/assets/AGENTS.md +4 -2
  3. package/bin/dist-guard.js +13 -3
  4. package/bin/runtime-watch.d.ts +1 -0
  5. package/bin/runtime-watch.js +22 -5
  6. package/bin/stale-dist-policy.js +9 -2
  7. package/dist/.build-manifest.json +251 -821
  8. package/dist/adapters/task-backend/task-backend-adapter.d.ts +2 -2
  9. package/dist/adapters/task-backend/task-backend-adapter.d.ts.map +1 -1
  10. package/dist/adapters/task-backend/task-backend-adapter.js +2 -2
  11. package/dist/backends/task-backend/local-backend.d.ts +7 -5
  12. package/dist/backends/task-backend/local-backend.d.ts.map +1 -1
  13. package/dist/backends/task-backend/local-backend.js +79 -7
  14. package/dist/backends/task-backend/redmine/env.d.ts +1 -1
  15. package/dist/backends/task-backend/redmine/env.d.ts.map +1 -1
  16. package/dist/backends/task-backend/redmine/env.js +3 -0
  17. package/dist/backends/task-backend/redmine/inspect.d.ts +11 -0
  18. package/dist/backends/task-backend/redmine/inspect.d.ts.map +1 -0
  19. package/dist/backends/task-backend/redmine/inspect.js +75 -0
  20. package/dist/backends/task-backend/redmine/mapping.d.ts.map +1 -1
  21. package/dist/backends/task-backend/redmine/mapping.js +21 -2
  22. package/dist/backends/task-backend/redmine/state.d.ts +17 -0
  23. package/dist/backends/task-backend/redmine/state.d.ts.map +1 -0
  24. package/dist/backends/task-backend/redmine/state.js +95 -0
  25. package/dist/backends/task-backend/redmine-backend.d.ts +10 -16
  26. package/dist/backends/task-backend/redmine-backend.d.ts.map +1 -1
  27. package/dist/backends/task-backend/redmine-backend.js +205 -15
  28. package/dist/backends/task-backend/shared/constants.d.ts +1 -1
  29. package/dist/backends/task-backend/shared/constants.js +1 -1
  30. package/dist/backends/task-backend/shared/record.d.ts.map +1 -1
  31. package/dist/backends/task-backend/shared/record.js +20 -1
  32. package/dist/backends/task-backend/shared/types.d.ts +42 -4
  33. package/dist/backends/task-backend/shared/types.d.ts.map +1 -1
  34. package/dist/backends/task-backend/shared.d.ts +1 -1
  35. package/dist/backends/task-backend/shared.d.ts.map +1 -1
  36. package/dist/backends/task-backend.d.ts +1 -1
  37. package/dist/backends/task-backend.d.ts.map +1 -1
  38. package/dist/backends/task-backend.test-helpers.d.ts +4 -0
  39. package/dist/backends/task-backend.test-helpers.d.ts.map +1 -0
  40. package/dist/backends/task-backend.test-helpers.js +33 -0
  41. package/dist/backends/task-index.d.ts.map +1 -1
  42. package/dist/backends/task-index.js +1 -0
  43. package/dist/cli/bootstrap-guide.d.ts.map +1 -1
  44. package/dist/cli/bootstrap-guide.js +1 -0
  45. package/dist/cli/command-guide.d.ts.map +1 -1
  46. package/dist/cli/command-guide.js +3 -2
  47. package/dist/cli/reason-codes.d.ts.map +1 -1
  48. package/dist/cli/reason-codes.js +30 -0
  49. package/dist/cli/run-cli/command-catalog/core.d.ts +3 -0
  50. package/dist/cli/run-cli/command-catalog/core.d.ts.map +1 -0
  51. package/dist/cli/run-cli/command-catalog/core.js +137 -0
  52. package/dist/cli/run-cli/command-catalog/lifecycle.d.ts +3 -0
  53. package/dist/cli/run-cli/command-catalog/lifecycle.d.ts.map +1 -0
  54. package/dist/cli/run-cli/command-catalog/lifecycle.js +52 -0
  55. package/dist/cli/run-cli/command-catalog/project.d.ts +3 -0
  56. package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -0
  57. package/dist/cli/run-cli/command-catalog/project.js +80 -0
  58. package/dist/cli/run-cli/command-catalog/shared.d.ts +19 -0
  59. package/dist/cli/run-cli/command-catalog/shared.d.ts.map +1 -0
  60. package/dist/cli/run-cli/command-catalog/shared.js +9 -0
  61. package/dist/cli/run-cli/command-catalog/task.d.ts +3 -0
  62. package/dist/cli/run-cli/command-catalog/task.d.ts.map +1 -0
  63. package/dist/cli/run-cli/command-catalog/task.js +85 -0
  64. package/dist/cli/run-cli/command-catalog.d.ts +3 -18
  65. package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
  66. package/dist/cli/run-cli/command-catalog.js +8 -337
  67. package/dist/cli/run-cli/commands/ide.d.ts.map +1 -1
  68. package/dist/cli/run-cli/commands/ide.js +64 -2
  69. package/dist/cli/run-cli/commands/init/ui.d.ts.map +1 -1
  70. package/dist/cli/run-cli/commands/init/ui.js +33 -13
  71. package/dist/cli/run-cli/commands/init/write-env.d.ts.map +1 -1
  72. package/dist/cli/run-cli/commands/init/write-env.js +12 -0
  73. package/dist/cli/run-cli.core.pr-flow.test-helpers.d.ts +3 -0
  74. package/dist/cli/run-cli.core.pr-flow.test-helpers.d.ts.map +1 -0
  75. package/dist/cli/run-cli.core.pr-flow.test-helpers.js +41 -0
  76. package/dist/cli/run-cli.core.tasks.test-helpers.d.ts +2 -0
  77. package/dist/cli/run-cli.core.tasks.test-helpers.d.ts.map +1 -0
  78. package/dist/cli/run-cli.core.tasks.test-helpers.js +6 -0
  79. package/dist/cli/run-cli.test-helpers.d.ts +3 -0
  80. package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
  81. package/dist/cli/run-cli.test-helpers.js +140 -6
  82. package/dist/commands/backend/sync.command.d.ts +5 -1
  83. package/dist/commands/backend/sync.command.d.ts.map +1 -1
  84. package/dist/commands/backend/sync.command.js +67 -3
  85. package/dist/commands/backend.d.ts +22 -0
  86. package/dist/commands/backend.d.ts.map +1 -1
  87. package/dist/commands/backend.js +110 -1
  88. package/dist/commands/commit.spec.d.ts.map +1 -1
  89. package/dist/commands/commit.spec.js +31 -7
  90. package/dist/commands/doctor/runtime.d.ts.map +1 -1
  91. package/dist/commands/doctor/runtime.js +3 -6
  92. package/dist/commands/doctor/workspace.d.ts +8 -0
  93. package/dist/commands/doctor/workspace.d.ts.map +1 -1
  94. package/dist/commands/doctor/workspace.js +127 -3
  95. package/dist/commands/guard/commit.command.d.ts.map +1 -1
  96. package/dist/commands/guard/commit.command.js +30 -6
  97. package/dist/commands/guard/impl/allow.d.ts +9 -0
  98. package/dist/commands/guard/impl/allow.d.ts.map +1 -1
  99. package/dist/commands/guard/impl/allow.js +26 -10
  100. package/dist/commands/guard/impl/commands.d.ts.map +1 -1
  101. package/dist/commands/guard/impl/commands.js +146 -18
  102. package/dist/commands/guard/impl/comment-commit.d.ts.map +1 -1
  103. package/dist/commands/guard/impl/comment-commit.js +2 -0
  104. package/dist/commands/hooks/index.d.ts.map +1 -1
  105. package/dist/commands/hooks/index.js +8 -35
  106. package/dist/commands/recipes/impl/apply.d.ts +4 -0
  107. package/dist/commands/recipes/impl/apply.d.ts.map +1 -1
  108. package/dist/commands/recipes/impl/apply.js +34 -0
  109. package/dist/commands/recipes/impl/commands/explain.d.ts.map +1 -1
  110. package/dist/commands/recipes/impl/commands/explain.js +70 -11
  111. package/dist/commands/recipes/impl/commands/info.d.ts.map +1 -1
  112. package/dist/commands/recipes/impl/commands/info.js +24 -12
  113. package/dist/commands/recipes/impl/commands/install.d.ts.map +1 -1
  114. package/dist/commands/recipes/impl/commands/install.js +32 -36
  115. package/dist/commands/recipes/impl/commands/list.d.ts.map +1 -1
  116. package/dist/commands/recipes/impl/commands/list.js +7 -4
  117. package/dist/commands/recipes/impl/commands/remove.d.ts.map +1 -1
  118. package/dist/commands/recipes/impl/commands/remove.js +9 -11
  119. package/dist/commands/recipes/impl/constants.d.ts +2 -0
  120. package/dist/commands/recipes/impl/constants.d.ts.map +1 -1
  121. package/dist/commands/recipes/impl/constants.js +2 -0
  122. package/dist/commands/recipes/impl/manifest.d.ts.map +1 -1
  123. package/dist/commands/recipes/impl/manifest.js +219 -23
  124. package/dist/commands/recipes/impl/normalize.d.ts +3 -0
  125. package/dist/commands/recipes/impl/normalize.d.ts.map +1 -1
  126. package/dist/commands/recipes/impl/normalize.js +28 -24
  127. package/dist/commands/recipes/impl/paths.d.ts +9 -0
  128. package/dist/commands/recipes/impl/paths.d.ts.map +1 -1
  129. package/dist/commands/recipes/impl/paths.js +10 -1
  130. package/dist/commands/recipes/impl/project-installed-recipes.d.ts +7 -0
  131. package/dist/commands/recipes/impl/project-installed-recipes.d.ts.map +1 -0
  132. package/dist/commands/recipes/impl/project-installed-recipes.js +102 -0
  133. package/dist/commands/recipes/impl/resolver.d.ts +20 -0
  134. package/dist/commands/recipes/impl/resolver.d.ts.map +1 -0
  135. package/dist/commands/recipes/impl/resolver.js +220 -0
  136. package/dist/commands/recipes/impl/scenario.d.ts.map +1 -1
  137. package/dist/commands/recipes/impl/scenario.js +40 -11
  138. package/dist/commands/recipes/impl/types.d.ts +145 -16
  139. package/dist/commands/recipes/impl/types.d.ts.map +1 -1
  140. package/dist/commands/recipes/install.spec.d.ts.map +1 -1
  141. package/dist/commands/recipes/install.spec.js +3 -2
  142. package/dist/commands/recipes.d.ts +6 -4
  143. package/dist/commands/recipes.d.ts.map +1 -1
  144. package/dist/commands/recipes.js +5 -3
  145. package/dist/commands/recipes.test-helpers.d.ts +185 -0
  146. package/dist/commands/recipes.test-helpers.d.ts.map +1 -0
  147. package/dist/commands/recipes.test-helpers.js +339 -0
  148. package/dist/commands/scenario/impl/commands.d.ts.map +1 -1
  149. package/dist/commands/scenario/impl/commands.js +192 -336
  150. package/dist/commands/scenario/info.command.d.ts.map +1 -1
  151. package/dist/commands/scenario/info.command.js +7 -2
  152. package/dist/commands/scenario/list.command.js +2 -2
  153. package/dist/commands/scenario/run.command.d.ts.map +1 -1
  154. package/dist/commands/scenario/run.command.js +7 -2
  155. package/dist/commands/shared/reconcile-check.d.ts.map +1 -1
  156. package/dist/commands/shared/reconcile-check.js +77 -2
  157. package/dist/commands/shared/task-backend.d.ts +1 -1
  158. package/dist/commands/shared/task-backend.d.ts.map +1 -1
  159. package/dist/commands/shared/task-backend.js +9 -0
  160. package/dist/commands/shared/task-store.d.ts +92 -2
  161. package/dist/commands/shared/task-store.d.ts.map +1 -1
  162. package/dist/commands/shared/task-store.js +405 -43
  163. package/dist/commands/task/block.d.ts.map +1 -1
  164. package/dist/commands/task/block.js +84 -46
  165. package/dist/commands/task/close-duplicate.d.ts.map +1 -1
  166. package/dist/commands/task/close-duplicate.js +12 -37
  167. package/dist/commands/task/close-noop.d.ts.map +1 -1
  168. package/dist/commands/task/close-noop.js +12 -30
  169. package/dist/commands/task/close-shared.d.ts +14 -0
  170. package/dist/commands/task/close-shared.d.ts.map +1 -0
  171. package/dist/commands/task/close-shared.js +73 -0
  172. package/dist/commands/task/comment.d.ts.map +1 -1
  173. package/dist/commands/task/comment.js +34 -21
  174. package/dist/commands/task/derive.command.d.ts +1 -0
  175. package/dist/commands/task/derive.command.d.ts.map +1 -1
  176. package/dist/commands/task/derive.command.js +15 -2
  177. package/dist/commands/task/derive.d.ts +1 -0
  178. package/dist/commands/task/derive.d.ts.map +1 -1
  179. package/dist/commands/task/derive.js +27 -4
  180. package/dist/commands/task/doc-set.command.d.ts +2 -1
  181. package/dist/commands/task/doc-set.command.d.ts.map +1 -1
  182. package/dist/commands/task/doc-set.command.js +36 -4
  183. package/dist/commands/task/doc-template.d.ts.map +1 -1
  184. package/dist/commands/task/doc-template.js +2 -7
  185. package/dist/commands/task/doc.command.js +1 -1
  186. package/dist/commands/task/doc.d.ts +2 -1
  187. package/dist/commands/task/doc.d.ts.map +1 -1
  188. package/dist/commands/task/doc.js +139 -76
  189. package/dist/commands/task/finish.d.ts.map +1 -1
  190. package/dist/commands/task/finish.js +142 -80
  191. package/dist/commands/task/migrate-doc.d.ts +15 -0
  192. package/dist/commands/task/migrate-doc.d.ts.map +1 -1
  193. package/dist/commands/task/migrate-doc.js +128 -43
  194. package/dist/commands/task/new.d.ts.map +1 -1
  195. package/dist/commands/task/new.js +3 -1
  196. package/dist/commands/task/plan-set.command.js +1 -1
  197. package/dist/commands/task/plan.command.d.ts +8 -0
  198. package/dist/commands/task/plan.command.d.ts.map +1 -0
  199. package/dist/commands/task/plan.command.js +37 -0
  200. package/dist/commands/task/plan.d.ts.map +1 -1
  201. package/dist/commands/task/plan.js +198 -101
  202. package/dist/commands/task/set-status.command.d.ts.map +1 -1
  203. package/dist/commands/task/set-status.command.js +1 -1
  204. package/dist/commands/task/set-status.d.ts.map +1 -1
  205. package/dist/commands/task/set-status.js +115 -35
  206. package/dist/commands/task/shared/dependencies.d.ts +1 -0
  207. package/dist/commands/task/shared/dependencies.d.ts.map +1 -1
  208. package/dist/commands/task/shared/dependencies.js +10 -0
  209. package/dist/commands/task/shared/docs.d.ts +1 -0
  210. package/dist/commands/task/shared/docs.d.ts.map +1 -1
  211. package/dist/commands/task/shared/docs.js +8 -1
  212. package/dist/commands/task/shared/transitions.d.ts +17 -2
  213. package/dist/commands/task/shared/transitions.d.ts.map +1 -1
  214. package/dist/commands/task/shared/transitions.js +20 -13
  215. package/dist/commands/task/shared.d.ts +3 -3
  216. package/dist/commands/task/shared.d.ts.map +1 -1
  217. package/dist/commands/task/shared.js +3 -3
  218. package/dist/commands/task/start.d.ts.map +1 -1
  219. package/dist/commands/task/start.js +101 -71
  220. package/dist/commands/task/task.command.d.ts +8 -0
  221. package/dist/commands/task/task.command.d.ts.map +1 -0
  222. package/dist/commands/task/task.command.js +71 -0
  223. package/dist/commands/task/verify-command-shared.d.ts +16 -0
  224. package/dist/commands/task/verify-command-shared.d.ts.map +1 -0
  225. package/dist/commands/task/verify-command-shared.js +53 -0
  226. package/dist/commands/task/verify-ok.command.d.ts +2 -6
  227. package/dist/commands/task/verify-ok.command.d.ts.map +1 -1
  228. package/dist/commands/task/verify-ok.command.js +8 -50
  229. package/dist/commands/task/verify-record.d.ts.map +1 -1
  230. package/dist/commands/task/verify-record.js +124 -145
  231. package/dist/commands/task/verify-rework.command.d.ts +2 -6
  232. package/dist/commands/task/verify-rework.command.d.ts.map +1 -1
  233. package/dist/commands/task/verify-rework.command.js +8 -50
  234. package/dist/commands/upgrade/apply.d.ts +2 -0
  235. package/dist/commands/upgrade/apply.d.ts.map +1 -1
  236. package/dist/commands/upgrade/apply.js +33 -1
  237. package/dist/commands/upgrade.command.d.ts.map +1 -1
  238. package/dist/commands/upgrade.command.js +25 -0
  239. package/dist/commands/upgrade.d.ts +1 -0
  240. package/dist/commands/upgrade.d.ts.map +1 -1
  241. package/dist/commands/upgrade.js +34 -0
  242. package/dist/commands/verify.spec.d.ts.map +1 -1
  243. package/dist/commands/verify.spec.js +3 -12
  244. package/dist/policy/rules/allowlist.d.ts.map +1 -1
  245. package/dist/policy/rules/allowlist.js +16 -4
  246. package/dist/policy/rules/protected-paths.d.ts.map +1 -1
  247. package/dist/policy/rules/protected-paths.js +6 -1
  248. package/dist/ports/task-backend-port.d.ts +2 -2
  249. package/dist/ports/task-backend-port.d.ts.map +1 -1
  250. package/dist/shared/agent-emoji.d.ts.map +1 -1
  251. package/dist/shared/protected-paths.d.ts +17 -0
  252. package/dist/shared/protected-paths.d.ts.map +1 -1
  253. package/dist/shared/protected-paths.js +59 -10
  254. package/dist/shared/repo-cli-version.d.ts.map +1 -1
  255. package/dist/shared/repo-cli-version.js +9 -3
  256. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- import type { TaskData } from "../../backends/task-backend.js";
1
+ import type { TaskData, TaskWriteOptions } from "../../backends/task-backend.js";
2
2
  import type { TaskBackendPort } from "../../ports/task-backend-port.js";
3
3
  import type { CommandContext } from "../../commands/shared/task-backend.js";
4
4
  export declare class TaskBackendAdapter implements TaskBackendPort {
@@ -6,7 +6,7 @@ export declare class TaskBackendAdapter implements TaskBackendPort {
6
6
  constructor(ctx: CommandContext);
7
7
  listTasks(): Promise<TaskData[]>;
8
8
  getTask(id: string): Promise<TaskData | null>;
9
- writeTask(task: TaskData): Promise<void>;
9
+ writeTask(task: TaskData, opts?: TaskWriteOptions): Promise<void>;
10
10
  exportProjectionSnapshot(path: string): Promise<void>;
11
11
  }
12
12
  //# sourceMappingURL=task-backend-adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"task-backend-adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/task-backend/task-backend-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E,qBAAa,kBAAmB,YAAW,eAAe;IACxD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAiB;gBAEzB,GAAG,EAAE,cAAc;IAI/B,SAAS,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAIhC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAI7C,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAUtD"}
1
+ {"version":3,"file":"task-backend-adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/task-backend/task-backend-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACjF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E,qBAAa,kBAAmB,YAAW,eAAe;IACxD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAiB;gBAEzB,GAAG,EAAE,cAAc;IAI/B,SAAS,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAIhC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAI7C,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjE,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAUtD"}
@@ -9,8 +9,8 @@ export class TaskBackendAdapter {
9
9
  getTask(id) {
10
10
  return this.ctx.taskBackend.getTask(id);
11
11
  }
12
- writeTask(task) {
13
- return this.ctx.taskBackend.writeTask(task);
12
+ writeTask(task, opts) {
13
+ return this.ctx.taskBackend.writeTask(task, opts);
14
14
  }
15
15
  exportProjectionSnapshot(path) {
16
16
  const backend = this.ctx.taskBackend;
@@ -1,4 +1,4 @@
1
- import { type TaskBackend, type TaskData } from "./shared.js";
1
+ import { type TaskBackend, type TaskData, type TaskWriteOptions } from "./shared.js";
2
2
  export declare class LocalBackend implements TaskBackend {
3
3
  id: string;
4
4
  capabilities: {
@@ -6,6 +6,8 @@ export declare class LocalBackend implements TaskBackend {
6
6
  readonly projection: "canonical";
7
7
  readonly reads_from_projection_by_default: true;
8
8
  readonly writes_task_readmes: true;
9
+ readonly supports_task_revisions: true;
10
+ readonly supports_revision_guarded_writes: true;
9
11
  readonly may_access_network_on_read: false;
10
12
  readonly may_access_network_on_write: false;
11
13
  readonly supports_projection_refresh: false;
@@ -29,10 +31,10 @@ export declare class LocalBackend implements TaskBackend {
29
31
  getTask(taskId: string): Promise<TaskData | null>;
30
32
  getTasks(taskIds: string[]): Promise<(TaskData | null)[]>;
31
33
  getTaskDoc(taskId: string): Promise<string>;
32
- writeTask(task: TaskData): Promise<void>;
33
- setTaskDoc(taskId: string, doc: string, updatedBy?: string): Promise<void>;
34
- touchTaskDocMetadata(taskId: string, updatedBy?: string): Promise<void>;
35
- writeTasks(tasks: TaskData[]): Promise<void>;
34
+ writeTask(task: TaskData, opts?: TaskWriteOptions): Promise<void>;
35
+ setTaskDoc(taskId: string, doc: string, updatedBy?: string, opts?: TaskWriteOptions): Promise<void>;
36
+ touchTaskDocMetadata(taskId: string, updatedBy?: string, opts?: TaskWriteOptions): Promise<void>;
37
+ writeTasks(tasks: TaskData[], opts?: TaskWriteOptions): Promise<void>;
36
38
  normalizeTasks(): Promise<{
37
39
  scanned: number;
38
40
  changed: number;
@@ -1 +1 @@
1
- {"version":3,"file":"local-backend.d.ts","sourceRoot":"","sources":["../../../src/backends/task-backend/local-backend.ts"],"names":[],"mappings":"AAqBA,OAAO,EAiBL,KAAK,WAAW,EAChB,KAAK,QAAQ,EACd,MAAM,aAAa,CAAC;AAErB,qBAAa,YAAa,YAAW,WAAW;IAC9C,EAAE,SAAW;IACb,YAAY;;;;;;;;;;MAUD;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,gBAAgB,CAAgB;gBAE5B,QAAQ,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;IAKrD,cAAc,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAqB3E,SAAS,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAwHhC,mBAAmB,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAIhD,mBAAmB,IAAI,MAAM,EAAE;IAIzB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAoBjD,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC;IAKzD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAO3C,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAyExC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB1E,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBvE,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAO5C,cAAc,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAuF/D,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlD,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGlE"}
1
+ {"version":3,"file":"local-backend.d.ts","sourceRoot":"","sources":["../../../src/backends/task-backend/local-backend.ts"],"names":[],"mappings":"AAsBA,OAAO,EAkBL,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACtB,MAAM,aAAa,CAAC;AA4BrB,qBAAa,YAAa,YAAW,WAAW;IAC9C,EAAE,SAAW;IACb,YAAY;;;;;;;;;;;;MAYD;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,gBAAgB,CAAgB;gBAE5B,QAAQ,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;IAKrD,cAAc,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAqB3E,SAAS,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAwHhC,mBAAmB,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAIhD,mBAAmB,IAAI,MAAM,EAAE;IAIzB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAoBjD,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC;IAKzD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAO3C,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA0GjE,UAAU,CACd,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,gBAAgB,GACtB,OAAO,CAAC,IAAI,CAAC;IA4BV,oBAAoB,CACxB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,gBAAgB,GACtB,OAAO,CAAC,IAAI,CAAC;IAyBV,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAOrE,cAAc,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAoG/D,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlD,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGlE"}
@@ -1,10 +1,26 @@
1
1
  import { mkdir, readdir, readFile, stat } from "node:fs/promises";
2
2
  import path from "node:path";
3
- import { docChanged, parseTaskReadme, renderTaskReadme, taskReadmePath, } from "@agentplaneorg/core";
3
+ import { docChanged, parseTaskReadme, renderTaskReadme, taskDocToSectionMap, taskReadmePath, } from "@agentplaneorg/core";
4
4
  import { isRecord } from "../../shared/guards.js";
5
5
  import { writeTextIfChanged } from "../../shared/write-if-changed.js";
6
6
  import { buildTaskIndexEntry, loadTaskIndex, resolveTaskIndexPath, saveTaskIndex, } from "../task-index.js";
7
- import { DEFAULT_DOC_UPDATED_BY, defaultPlanApproval, defaultVerificationResult, extractTaskDoc, generateTaskId, invalidLengthMessage, mapLimit, mergeTaskDoc, missingTaskIdMessage, normalizeDocVersion, nowIso, resolveDocUpdatedByFromFrontmatter, resolveDocUpdatedByFromTask, taskRecordToData, validateTaskId, writeTasksExportFromTasks, } from "./shared.js";
7
+ import { DEFAULT_DOC_UPDATED_BY, defaultPlanApproval, defaultVerificationResult, extractTaskDoc, generateTaskId, invalidLengthMessage, mapLimit, mergeTaskDoc, missingTaskIdMessage, normalizeDocVersion, nowIso, resolveDocUpdatedByFromFrontmatter, resolveDocUpdatedByFromTask, taskRecordToData, validateTaskId, writeTasksExportFromTasks, BackendError, } from "./shared.js";
8
+ function storedRevisionFromFrontmatter(frontmatter, fallback) {
9
+ return Number.isInteger(frontmatter.revision) &&
10
+ typeof frontmatter.revision === "number" &&
11
+ frontmatter.revision > 0
12
+ ? frontmatter.revision
13
+ : fallback;
14
+ }
15
+ function assertExpectedRevision(opts) {
16
+ if (opts.expectedRevision === undefined)
17
+ return;
18
+ const expected = Math.trunc(opts.expectedRevision);
19
+ if (expected <= 0 || expected === opts.currentRevision)
20
+ return;
21
+ throw new BackendError(`Task revision changed concurrently: ${opts.taskId} ` +
22
+ `(expected revision ${expected}, current revision ${opts.currentRevision})`, "E_BACKEND");
23
+ }
8
24
  export class LocalBackend {
9
25
  id = "local";
10
26
  capabilities = {
@@ -12,6 +28,8 @@ export class LocalBackend {
12
28
  projection: "canonical",
13
29
  reads_from_projection_by_default: true,
14
30
  writes_task_readmes: true,
31
+ supports_task_revisions: true,
32
+ supports_revision_guarded_writes: true,
15
33
  may_access_network_on_read: false,
16
34
  may_access_network_on_write: false,
17
35
  supports_projection_refresh: false,
@@ -199,7 +217,7 @@ export class LocalBackend {
199
217
  const parsed = parseTaskReadme(text);
200
218
  return extractTaskDoc(parsed.body);
201
219
  }
202
- async writeTask(task) {
220
+ async writeTask(task, opts) {
203
221
  const taskId = task.id.trim();
204
222
  if (!taskId)
205
223
  throw new Error(missingTaskIdMessage());
@@ -220,8 +238,25 @@ export class LocalBackend {
220
238
  if (code !== "ENOENT")
221
239
  throw err;
222
240
  }
241
+ assertExpectedRevision({
242
+ taskId,
243
+ expectedRevision: opts?.expectedRevision,
244
+ currentRevision: Object.keys(existingFrontmatter).length > 0
245
+ ? storedRevisionFromFrontmatter(existingFrontmatter, 1)
246
+ : 0,
247
+ });
223
248
  const payload = { ...task };
224
249
  delete payload.doc;
250
+ if (!Number.isInteger(payload.revision) ||
251
+ typeof payload.revision !== "number" ||
252
+ payload.revision <= 0) {
253
+ payload.revision =
254
+ Number.isInteger(existingFrontmatter.revision) &&
255
+ typeof existingFrontmatter.revision === "number" &&
256
+ existingFrontmatter.revision > 0
257
+ ? existingFrontmatter.revision
258
+ : 1;
259
+ }
225
260
  for (const [key, value] of Object.entries(payload)) {
226
261
  if (value === undefined)
227
262
  delete payload[key];
@@ -244,6 +279,17 @@ export class LocalBackend {
244
279
  payload.verification = defaultVerificationResult();
245
280
  }
246
281
  const existingDocVersion = normalizeDocVersion(existingFrontmatter.doc_version);
282
+ const effectiveDoc = task.doc === undefined ? null : String(task.doc ?? "");
283
+ const nextSections = effectiveDoc === null
284
+ ? task.sections && Object.keys(task.sections).length > 0
285
+ ? task.sections
286
+ : existingDoc
287
+ ? taskDocToSectionMap(existingDoc)
288
+ : undefined
289
+ : taskDocToSectionMap(effectiveDoc);
290
+ if (nextSections && Object.keys(nextSections).length > 0) {
291
+ payload.sections = nextSections;
292
+ }
247
293
  if (task.doc !== undefined) {
248
294
  const docText = String(task.doc ?? "");
249
295
  body = mergeTaskDoc(body, docText);
@@ -264,10 +310,15 @@ export class LocalBackend {
264
310
  const text = renderTaskReadme(payload, body || "");
265
311
  await writeTextIfChanged(readme, text.endsWith("\n") ? text : `${text}\n`);
266
312
  }
267
- async setTaskDoc(taskId, doc, updatedBy) {
313
+ async setTaskDoc(taskId, doc, updatedBy, opts) {
268
314
  const readme = taskReadmePath(this.root, taskId);
269
315
  const text = await readFile(readme, "utf8");
270
316
  const parsed = parseTaskReadme(text);
317
+ assertExpectedRevision({
318
+ taskId,
319
+ expectedRevision: opts?.expectedRevision,
320
+ currentRevision: storedRevisionFromFrontmatter(parsed.frontmatter, 1),
321
+ });
271
322
  const docText = String(doc ?? "");
272
323
  const body = mergeTaskDoc(parsed.body, docText);
273
324
  const frontmatter = { ...parsed.frontmatter };
@@ -277,24 +328,34 @@ export class LocalBackend {
277
328
  frontmatter.doc_updated_at = nowIso();
278
329
  frontmatter.doc_updated_by = resolveDocUpdatedByFromFrontmatter(frontmatter, updatedBy, this.updatedBy);
279
330
  }
331
+ frontmatter.sections = taskDocToSectionMap(docText);
280
332
  frontmatter.doc_version = normalizeDocVersion(frontmatter.doc_version, currentDocVersion);
281
333
  const next = renderTaskReadme(frontmatter, body);
282
334
  await writeTextIfChanged(readme, next.endsWith("\n") ? next : `${next}\n`);
283
335
  }
284
- async touchTaskDocMetadata(taskId, updatedBy) {
336
+ async touchTaskDocMetadata(taskId, updatedBy, opts) {
285
337
  const readme = taskReadmePath(this.root, taskId);
286
338
  const text = await readFile(readme, "utf8");
287
339
  const parsed = parseTaskReadme(text);
340
+ assertExpectedRevision({
341
+ taskId,
342
+ expectedRevision: opts?.expectedRevision,
343
+ currentRevision: storedRevisionFromFrontmatter(parsed.frontmatter, 1),
344
+ });
288
345
  const frontmatter = { ...parsed.frontmatter };
289
346
  frontmatter.doc_version = normalizeDocVersion(frontmatter.doc_version);
290
347
  frontmatter.doc_updated_at = nowIso();
291
348
  frontmatter.doc_updated_by = resolveDocUpdatedByFromFrontmatter(frontmatter, updatedBy, this.updatedBy);
349
+ frontmatter.sections =
350
+ isRecord(frontmatter.sections) && Object.keys(frontmatter.sections).length > 0
351
+ ? frontmatter.sections
352
+ : taskDocToSectionMap(extractTaskDoc(parsed.body));
292
353
  const next = renderTaskReadme(frontmatter, parsed.body || "");
293
354
  await writeTextIfChanged(readme, next.endsWith("\n") ? next : `${next}\n`);
294
355
  }
295
- async writeTasks(tasks) {
356
+ async writeTasks(tasks, opts) {
296
357
  await mapLimit(tasks, 4, async (task) => {
297
- await this.writeTask(task);
358
+ await this.writeTask(task, opts);
298
359
  return null;
299
360
  });
300
361
  }
@@ -334,6 +395,14 @@ export class LocalBackend {
334
395
  // rendered output is identical (prevents mtime churn and diff-noise).
335
396
  const payload = { ...task };
336
397
  delete payload.doc;
398
+ if (!Number.isInteger(payload.revision) ||
399
+ typeof payload.revision !== "number" ||
400
+ payload.revision <= 0) {
401
+ payload.revision =
402
+ Number.isInteger(fm.revision) && typeof fm.revision === "number" && fm.revision > 0
403
+ ? fm.revision
404
+ : 1;
405
+ }
337
406
  for (const [key, value] of Object.entries(payload)) {
338
407
  if (value === undefined)
339
408
  delete payload[key];
@@ -359,6 +428,9 @@ export class LocalBackend {
359
428
  if (payload.doc_updated_by === undefined || payload.doc_updated_by === "") {
360
429
  payload.doc_updated_by = resolveDocUpdatedByFromTask(task, this.updatedBy);
361
430
  }
431
+ if (!payload.sections && task.doc) {
432
+ payload.sections = taskDocToSectionMap(task.doc);
433
+ }
362
434
  const next = renderTaskReadme(payload, parsed.body || "");
363
435
  const didWrite = await writeTextIfChanged(readme, next.endsWith("\n") ? next : `${next}\n`);
364
436
  return { taskId, scanned: true, changed: didWrite };
@@ -10,7 +10,7 @@ export type RedmineEnvConfig = {
10
10
  pauseMs?: number;
11
11
  };
12
12
  };
13
- type RedmineCustomFieldKey = "task_id" | "doc" | "doc_version" | "doc_updated_at" | "doc_updated_by" | "tags" | "priority" | "owner";
13
+ type RedmineCustomFieldKey = "task_id" | "canonical_state" | "doc" | "doc_version" | "doc_updated_at" | "doc_updated_by" | "tags" | "priority" | "owner";
14
14
  export declare function readRedmineEnv(): RedmineEnvConfig;
15
15
  export {};
16
16
  //# sourceMappingURL=env.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../../src/backends/task-backend/redmine/env.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7D,KAAK,EAAE;QACL,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,KAAK,qBAAqB,GACtB,SAAS,GACT,KAAK,GACL,aAAa,GACb,gBAAgB,GAChB,gBAAgB,GAChB,MAAM,GACN,UAAU,GACV,OAAO,CAAC;AA6BZ,wBAAgB,cAAc,IAAI,gBAAgB,CAiCjD"}
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../../src/backends/task-backend/redmine/env.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7D,KAAK,EAAE;QACL,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,KAAK,qBAAqB,GACtB,SAAS,GACT,iBAAiB,GACjB,KAAK,GACL,aAAa,GACb,gBAAgB,GAChB,gBAAgB,GAChB,MAAM,GACN,UAAU,GACV,OAAO,CAAC;AA6BZ,wBAAgB,cAAc,IAAI,gBAAgB,CAmCjD"}
@@ -25,6 +25,9 @@ export function readRedmineEnv() {
25
25
  const taskId = parsePositiveIntEnv("AGENTPLANE_REDMINE_CUSTOM_FIELDS_TASK_ID");
26
26
  if (taskId !== undefined)
27
27
  customFields.task_id = taskId;
28
+ const canonicalState = parsePositiveIntEnv("AGENTPLANE_REDMINE_CUSTOM_FIELDS_CANONICAL_STATE");
29
+ if (canonicalState !== undefined)
30
+ customFields.canonical_state = canonicalState;
28
31
  const doc = parsePositiveIntEnv("AGENTPLANE_REDMINE_CUSTOM_FIELDS_DOC");
29
32
  if (doc !== undefined)
30
33
  customFields.doc = doc;
@@ -0,0 +1,11 @@
1
+ import { type TaskBackendFieldNameDrift, type TaskBackendVisibleField } from "../shared.js";
2
+ export declare function inspectVisibleCustomFields(opts: {
3
+ projectId: string;
4
+ requestJson: (method: string, reqPath: string, payload?: Record<string, unknown>, params?: Record<string, unknown>) => Promise<Record<string, unknown>>;
5
+ }): Promise<TaskBackendVisibleField[]>;
6
+ export declare function inferVisibleCanonicalStateFieldId(visibleFields: TaskBackendVisibleField[]): number | null;
7
+ export declare function detectConfiguredFieldNameDrift(opts: {
8
+ configuredFields: Record<string, unknown>;
9
+ visibleFields: TaskBackendVisibleField[];
10
+ }): TaskBackendFieldNameDrift[];
11
+ //# sourceMappingURL=inspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../../../src/backends/task-backend/redmine/inspect.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC7B,MAAM,cAAc,CAAC;AAYtB,wBAAsB,0BAA0B,CAAC,IAAI,EAAE;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,CACX,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvC,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CA6CrC;AAED,wBAAgB,iCAAiC,CAC/C,aAAa,EAAE,uBAAuB,EAAE,GACvC,MAAM,GAAG,IAAI,CAGf;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE;IACnD,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,aAAa,EAAE,uBAAuB,EAAE,CAAC;CAC1C,GAAG,yBAAyB,EAAE,CAkB9B"}
@@ -0,0 +1,75 @@
1
+ import { isRecord } from "../../../shared/guards.js";
2
+ import { toStringSafe, } from "../shared.js";
3
+ function expectedFieldNameForKey(key) {
4
+ return key;
5
+ }
6
+ export async function inspectVisibleCustomFields(opts) {
7
+ const fields = new Map();
8
+ let offset = 0;
9
+ const limit = 100;
10
+ while (true) {
11
+ const payload = await opts.requestJson("GET", "issues.json", undefined, {
12
+ project_id: opts.projectId,
13
+ limit,
14
+ offset,
15
+ status_id: "*",
16
+ });
17
+ const issues = Array.isArray(payload.issues) ? payload.issues : [];
18
+ const pageIssues = issues.filter((issue) => isRecord(issue));
19
+ for (const issue of pageIssues) {
20
+ const customFields = Array.isArray(issue.custom_fields) ? issue.custom_fields : [];
21
+ for (const field of customFields) {
22
+ if (!isRecord(field) || typeof field.id !== "number")
23
+ continue;
24
+ const name = toStringSafe(field.name).trim();
25
+ if (!name)
26
+ continue;
27
+ const current = fields.get(field.id) ?? {
28
+ id: field.id,
29
+ name,
30
+ nonEmptyCount: 0,
31
+ };
32
+ const value = field.value;
33
+ if (value !== undefined && value !== null && toStringSafe(value).trim().length > 0) {
34
+ current.nonEmptyCount += 1;
35
+ }
36
+ fields.set(field.id, current);
37
+ }
38
+ }
39
+ const total = Number(payload.total_count ?? 0);
40
+ if (total === 0 || offset + limit >= total)
41
+ break;
42
+ offset += limit;
43
+ }
44
+ return [...fields.values()]
45
+ .toSorted((a, b) => a.id - b.id)
46
+ .map((field) => ({
47
+ id: field.id,
48
+ name: field.name,
49
+ nonEmptyCount: field.nonEmptyCount,
50
+ }));
51
+ }
52
+ export function inferVisibleCanonicalStateFieldId(visibleFields) {
53
+ const field = visibleFields.find((entry) => entry.name.trim() === "canonical_state");
54
+ return field?.id ?? null;
55
+ }
56
+ export function detectConfiguredFieldNameDrift(opts) {
57
+ const byId = new Map(opts.visibleFields.map((field) => [field.id, field]));
58
+ const drift = [];
59
+ for (const [key, rawId] of Object.entries(opts.configuredFields)) {
60
+ if (typeof rawId !== "number")
61
+ continue;
62
+ const visible = byId.get(rawId);
63
+ if (!visible)
64
+ continue;
65
+ const expectedName = expectedFieldNameForKey(key);
66
+ if (visible.name.trim() === expectedName)
67
+ continue;
68
+ drift.push({
69
+ key,
70
+ configuredId: rawId,
71
+ visibleName: visible.name,
72
+ });
73
+ }
74
+ return drift.toSorted((a, b) => a.configuredId - b.configuredId || a.key.localeCompare(b.key));
75
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"mapping.d.ts","sourceRoot":"","sources":["../../../../src/backends/task-backend/redmine/mapping.ts"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,QAAQ,EACd,MAAM,cAAc,CAAC;AAMtB,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASjE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIhE;AA2BD,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,GAAG,QAAQ,GAAG,IAAI,CAwElB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,IAAI,EAAE,QAAQ,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC7F,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAyC1B"}
1
+ {"version":3,"file":"mapping.d.ts","sourceRoot":"","sources":["../../../../src/backends/task-backend/redmine/mapping.ts"],"names":[],"mappings":"AAIA,OAAO,EAKL,KAAK,QAAQ,EACd,MAAM,cAAc,CAAC;AAOtB,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASjE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIhE;AA2BD,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,GAAG,QAAQ,GAAG,IAAI,CAqFlB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,IAAI,EAAE,QAAQ,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC7F,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA6C1B"}
@@ -1,8 +1,10 @@
1
+ import { renderTaskDocFromSections, taskDocToSectionMap } from "@agentplaneorg/core";
1
2
  import { isRecord } from "../../../shared/guards.js";
2
3
  import { ensureDocMetadata, normalizePriority, nowIso, toStringSafe, } from "../shared.js";
3
4
  import { customFieldValue } from "./fields.js";
4
5
  import { coerceDocVersion, maybeParseJson } from "./parse.js";
5
6
  import { normalizeComments } from "./comments.js";
7
+ import { buildRedmineCanonicalState, parseRedmineCanonicalState } from "./state.js";
6
8
  export function startDateFromTaskId(taskId) {
7
9
  if (!taskId.includes("-"))
8
10
  return null;
@@ -67,11 +69,13 @@ export function issueToTask(opts) {
67
69
  const docVersionVal = customFieldValue(opts.issue, opts.customFields.doc_version);
68
70
  const docUpdatedAtVal = customFieldValue(opts.issue, opts.customFields.doc_updated_at);
69
71
  const docUpdatedByVal = customFieldValue(opts.issue, opts.customFields.doc_updated_by);
72
+ const canonicalStateVal = customFieldValue(opts.issue, opts.customFields.canonical_state);
70
73
  const updatedOn = typeof opts.issue.updated_on === "string"
71
74
  ? opts.issue.updated_on
72
75
  : typeof opts.issue.created_on === "string"
73
76
  ? opts.issue.created_on
74
77
  : null;
78
+ const canonicalState = parseRedmineCanonicalState(canonicalStateVal);
75
79
  const priorityVal = isRecord(opts.issue.priority) ? opts.issue.priority : null;
76
80
  const priorityName = normalizePriority(priorityVal?.name ?? priorityFieldVal);
77
81
  const tags = [];
@@ -104,15 +108,26 @@ export function issueToTask(opts) {
104
108
  status: status ?? "TODO",
105
109
  priority: priorityName,
106
110
  owner: toStringSafe(ownerFieldVal ?? opts.ownerAgent),
111
+ revision: canonicalState?.revision ?? 1,
107
112
  tags: mergedTags,
108
113
  depends_on: [],
109
114
  verify: maybeParseJson(verifyVal),
110
115
  commit: maybeParseJson(commitVal),
111
116
  comments: normalizeComments(maybeParseJson(commentsVal)),
117
+ plan_approval: canonicalState?.plan_approval,
118
+ verification: canonicalState?.verification,
119
+ events: canonicalState?.events,
112
120
  id_source: "custom",
113
121
  };
114
- if (docVal)
115
- task.doc = toStringSafe(docVal);
122
+ const canonicalSections = canonicalState?.sections;
123
+ const derivedDoc = canonicalSections
124
+ ? renderTaskDocFromSections(canonicalSections)
125
+ : docVal
126
+ ? toStringSafe(docVal)
127
+ : "";
128
+ if (derivedDoc)
129
+ task.doc = derivedDoc;
130
+ task.sections = canonicalSections ?? (derivedDoc ? taskDocToSectionMap(derivedDoc) : undefined);
116
131
  const docVersion = coerceDocVersion(docVersionVal);
117
132
  task.doc_version = docVersion ?? opts.defaultDocVersion;
118
133
  task.doc_updated_at = docUpdatedAtVal ? toStringSafe(docUpdatedAtVal) : (updatedOn ?? nowIso());
@@ -145,6 +160,10 @@ export function taskToIssuePayload(opts) {
145
160
  const customFields = [];
146
161
  ensureDocMetadata(opts.task);
147
162
  opts.appendCustomField(customFields, "task_id", opts.task.id);
163
+ const canonicalState = buildRedmineCanonicalState(opts.task);
164
+ if (canonicalState) {
165
+ opts.appendCustomField(customFields, "canonical_state", canonicalState);
166
+ }
148
167
  opts.appendCustomField(customFields, "verify", opts.task.verify);
149
168
  opts.appendCustomField(customFields, "commit", opts.task.commit);
150
169
  opts.appendCustomField(customFields, "comments", opts.task.comments);
@@ -0,0 +1,17 @@
1
+ import type { TaskData } from "../shared/types.js";
2
+ export type RedmineCanonicalState = {
3
+ revision?: number;
4
+ sections?: Record<string, string>;
5
+ plan_approval?: TaskData["plan_approval"];
6
+ verification?: TaskData["verification"];
7
+ events?: TaskData["events"];
8
+ };
9
+ type BuildRedmineCanonicalStateOptions = {
10
+ base?: RedmineCanonicalState | null;
11
+ revision?: number | null;
12
+ };
13
+ export declare function parseRedmineCanonicalState(value: unknown): RedmineCanonicalState | null;
14
+ export declare function buildRedmineCanonicalState(task: TaskData): RedmineCanonicalState | null;
15
+ export declare function buildRedmineCanonicalStateWithOptions(task: TaskData, opts?: BuildRedmineCanonicalStateOptions): RedmineCanonicalState | null;
16
+ export {};
17
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../src/backends/task-backend/redmine/state.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnD,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,aAAa,CAAC,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IAC1C,YAAY,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IACxC,MAAM,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;CAC7B,CAAC;AAEF,KAAK,iCAAiC,GAAG;IACvC,IAAI,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AA6BF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,qBAAqB,GAAG,IAAI,CA2BvF;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,QAAQ,GAAG,qBAAqB,GAAG,IAAI,CAEvF;AAED,wBAAgB,qCAAqC,CACnD,IAAI,EAAE,QAAQ,EACd,IAAI,CAAC,EAAE,iCAAiC,GACvC,qBAAqB,GAAG,IAAI,CAwC9B"}
@@ -0,0 +1,95 @@
1
+ import { taskDocToSectionMap } from "@agentplaneorg/core";
2
+ import { isRecord } from "../../../shared/guards.js";
3
+ import { normalizeEvents } from "../shared/events.js";
4
+ import { normalizePlanApproval, normalizeVerificationResult } from "../shared/normalize.js";
5
+ import { toStringSafe } from "../shared/strings.js";
6
+ function normalizeRevision(value) {
7
+ return Number.isInteger(value) && Number(value) > 0 ? Number(value) : undefined;
8
+ }
9
+ function normalizeCanonicalSections(value) {
10
+ if (!isRecord(value))
11
+ return undefined;
12
+ const out = {};
13
+ for (const [title, text] of Object.entries(value)) {
14
+ const normalizedTitle = title.trim();
15
+ if (!normalizedTitle || typeof text !== "string")
16
+ continue;
17
+ out[normalizedTitle] = text.replaceAll("\r\n", "\n").trimEnd();
18
+ }
19
+ return Object.keys(out).length > 0 ? out : undefined;
20
+ }
21
+ function maybeParseJsonString(value) {
22
+ if (value === null || value === undefined)
23
+ return null;
24
+ const raw = toStringSafe(value).trim();
25
+ if (!raw)
26
+ return null;
27
+ if (!raw.startsWith("{"))
28
+ return raw;
29
+ try {
30
+ return JSON.parse(raw);
31
+ }
32
+ catch {
33
+ return raw;
34
+ }
35
+ }
36
+ export function parseRedmineCanonicalState(value) {
37
+ const parsed = maybeParseJsonString(value);
38
+ if (!isRecord(parsed))
39
+ return null;
40
+ const revision = normalizeRevision(parsed.revision);
41
+ const sections = normalizeCanonicalSections(parsed.sections);
42
+ const planApproval = normalizePlanApproval(parsed.plan_approval) ?? undefined;
43
+ const verification = normalizeVerificationResult(parsed.verification) ?? undefined;
44
+ const events = normalizeEvents(parsed.events);
45
+ if (revision === undefined &&
46
+ sections === undefined &&
47
+ planApproval === undefined &&
48
+ verification === undefined &&
49
+ events.length === 0) {
50
+ return null;
51
+ }
52
+ return {
53
+ ...(revision === undefined ? {} : { revision }),
54
+ ...(sections ? { sections } : {}),
55
+ ...(planApproval ? { plan_approval: planApproval } : {}),
56
+ ...(verification ? { verification } : {}),
57
+ ...(events.length > 0 ? { events } : {}),
58
+ };
59
+ }
60
+ export function buildRedmineCanonicalState(task) {
61
+ return buildRedmineCanonicalStateWithOptions(task);
62
+ }
63
+ export function buildRedmineCanonicalStateWithOptions(task, opts) {
64
+ const base = opts?.base ?? null;
65
+ const revision = normalizeRevision(opts?.revision) ??
66
+ normalizeRevision(task.revision) ??
67
+ normalizeRevision(base?.revision);
68
+ const sections = normalizeCanonicalSections(task.sections) ??
69
+ (typeof task.doc === "string" && task.doc.trim().length > 0
70
+ ? taskDocToSectionMap(task.doc)
71
+ : undefined) ??
72
+ normalizeCanonicalSections(base?.sections);
73
+ const planApproval = normalizePlanApproval(task.plan_approval) ??
74
+ normalizePlanApproval(base?.plan_approval) ??
75
+ undefined;
76
+ const verification = normalizeVerificationResult(task.verification) ??
77
+ normalizeVerificationResult(base?.verification) ??
78
+ undefined;
79
+ const events = normalizeEvents(task.events);
80
+ const fallbackEvents = events.length > 0 ? events : normalizeEvents(base?.events);
81
+ if (revision === undefined &&
82
+ sections === undefined &&
83
+ planApproval === undefined &&
84
+ verification === undefined &&
85
+ fallbackEvents.length === 0) {
86
+ return null;
87
+ }
88
+ return {
89
+ ...(revision === undefined ? {} : { revision }),
90
+ ...(sections ? { sections } : {}),
91
+ ...(planApproval ? { plan_approval: planApproval } : {}),
92
+ ...(verification ? { verification } : {}),
93
+ ...(fallbackEvents.length > 0 ? { events: fallbackEvents } : {}),
94
+ };
95
+ }
@@ -1,5 +1,5 @@
1
1
  import type { LocalBackend } from "./local-backend.js";
2
- import { type TaskBackend, type TaskData } from "./shared.js";
2
+ import { type TaskCanonicalStateMigrationResult, type TaskBackend, type TaskBackendInspectionResult, type TaskData, type TaskWriteOptions } from "./shared.js";
3
3
  export type RedmineSettings = {
4
4
  url?: string;
5
5
  api_key?: string;
@@ -13,17 +13,7 @@ export type RedmineSettings = {
13
13
  };
14
14
  export declare class RedmineBackend implements TaskBackend {
15
15
  id: string;
16
- capabilities: {
17
- readonly canonical_source: "remote";
18
- readonly projection: "cache";
19
- readonly reads_from_projection_by_default: true;
20
- readonly writes_task_readmes: true;
21
- readonly may_access_network_on_read: false;
22
- readonly may_access_network_on_write: true;
23
- readonly supports_projection_refresh: true;
24
- readonly supports_push_sync: true;
25
- readonly supports_snapshot_export: true;
26
- };
16
+ capabilities: TaskBackend["capabilities"];
27
17
  baseUrl: string;
28
18
  apiKey: string;
29
19
  projectId: string;
@@ -57,13 +47,15 @@ export declare class RedmineBackend implements TaskBackend {
57
47
  scanned: number;
58
48
  changed: number;
59
49
  }>;
50
+ migrateCanonicalState(): Promise<TaskCanonicalStateMigrationResult>;
51
+ inspectConfiguration(): Promise<TaskBackendInspectionResult>;
60
52
  getTask(taskId: string): Promise<TaskData | null>;
61
53
  getTasks(taskIds: string[]): Promise<(TaskData | null)[]>;
62
54
  getTaskDoc(taskId: string): Promise<string>;
63
- setTaskDoc(taskId: string, doc: string, updatedBy?: string): Promise<void>;
64
- touchTaskDocMetadata(taskId: string, updatedBy?: string): Promise<void>;
65
- writeTask(task: TaskData): Promise<void>;
66
- writeTasks(tasks: TaskData[]): Promise<void>;
55
+ setTaskDoc(taskId: string, doc: string, updatedBy?: string, opts?: TaskWriteOptions): Promise<void>;
56
+ touchTaskDocMetadata(taskId: string, updatedBy?: string, opts?: TaskWriteOptions): Promise<void>;
57
+ writeTask(task: TaskData, opts?: TaskWriteOptions): Promise<void>;
58
+ writeTasks(tasks: TaskData[], opts?: TaskWriteOptions): Promise<void>;
67
59
  sync(opts: {
68
60
  direction: "push" | "pull";
69
61
  conflict: "diff" | "prefer-local" | "prefer-remote" | "fail";
@@ -77,6 +69,8 @@ export declare class RedmineBackend implements TaskBackend {
77
69
  private diffTasks;
78
70
  private tasksDiffer;
79
71
  private cacheTask;
72
+ private assertExpectedRevisionSupported;
73
+ private assertExpectedRevision;
80
74
  private taskIdFieldId;
81
75
  private setIssueCustomFieldValue;
82
76
  private listTasksRemote;
@@ -1 +1 @@
1
- {"version":3,"file":"redmine-backend.d.ts","sourceRoot":"","sources":["../../../src/backends/task-backend/redmine-backend.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"redmine-backend.d.ts","sourceRoot":"","sources":["../../../src/backends/task-backend/redmine-backend.ts"],"names":[],"mappings":"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"}