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 { canonicalizeJson } from "@agentplaneorg/core";
1
+ import { canonicalizeJson, taskDocToSectionMap } from "@agentplaneorg/core";
2
2
  import { isRecord } from "../../shared/guards.js";
3
3
  import { appendCommentNotes as appendCommentNotesImpl, normalizeComments as normalizeCommentsImpl, } from "./redmine/comments.js";
4
4
  import { requestJson as requestRedmineJson } from "./redmine/client.js";
@@ -6,6 +6,8 @@ import { appendCustomField as appendRedmineCustomField, customFieldValue as redm
6
6
  import { doneRatioForStatus, issueToTask as issueToTaskImpl, startDateFromTaskId, taskToIssuePayload as taskToIssuePayloadImpl, } from "./redmine/mapping.js";
7
7
  import { coerceDocVersion as coerceRedmineDocVersion, maybeParseJson as maybeParseRedmineJson, } from "./redmine/parse.js";
8
8
  import { findIssueByTaskId as findIssueByTaskIdImpl, listTasksRemote as listTasksRemoteImpl, } from "./redmine/remote.js";
9
+ import { detectConfiguredFieldNameDrift, inferVisibleCanonicalStateFieldId, inspectVisibleCustomFields, } from "./redmine/inspect.js";
10
+ import { buildRedmineCanonicalStateWithOptions, parseRedmineCanonicalState, } from "./redmine/state.js";
9
11
  import { readRedmineEnv } from "./redmine/env.js";
10
12
  import { BackendError, DEFAULT_DOC_UPDATED_BY, DOC_VERSION, RedmineUnavailable, ensureDocMetadata, firstNonEmptyString, generateTaskId, mapLimit, missingTaskIdMessage, normalizeDocVersion, nowIso, redmineConfigMissingEnvMessage, redmineIssueIdMissingMessage, sleep, toStringSafe, unknownTaskIdMessage, validateTaskId, writeTasksExportFromTasks, } from "./shared.js";
11
13
  export class RedmineBackend {
@@ -15,6 +17,8 @@ export class RedmineBackend {
15
17
  projection: "cache",
16
18
  reads_from_projection_by_default: true,
17
19
  writes_task_readmes: true,
20
+ supports_task_revisions: false,
21
+ supports_revision_guarded_writes: false,
18
22
  may_access_network_on_read: false,
19
23
  may_access_network_on_write: true,
20
24
  supports_projection_refresh: true,
@@ -72,6 +76,12 @@ export class RedmineBackend {
72
76
  if (!this.customFields?.task_id) {
73
77
  throw new BackendError(redmineConfigMissingEnvMessage("AGENTPLANE_REDMINE_CUSTOM_FIELDS_TASK_ID"), "E_BACKEND");
74
78
  }
79
+ const supportsStructuredRevisions = Boolean(this.customFields?.canonical_state);
80
+ this.capabilities = {
81
+ ...this.capabilities,
82
+ supports_task_revisions: supportsStructuredRevisions,
83
+ supports_revision_guarded_writes: supportsStructuredRevisions,
84
+ };
75
85
  for (const [key, value] of Object.entries(this.statusMap)) {
76
86
  if (typeof value === "number")
77
87
  this.reverseStatus.set(value, key);
@@ -134,6 +144,107 @@ export class RedmineBackend {
134
144
  return await this.cache.normalizeTasks();
135
145
  return { scanned: 0, changed: 0 };
136
146
  }
147
+ async migrateCanonicalState() {
148
+ if (!this.customFields.canonical_state) {
149
+ throw new BackendError(redmineConfigMissingEnvMessage("AGENTPLANE_REDMINE_CUSTOM_FIELDS_CANONICAL_STATE"), "E_BACKEND");
150
+ }
151
+ const tasks = await this.listTasksRemote();
152
+ const result = {
153
+ scanned: tasks.length,
154
+ migrated: [],
155
+ skippedStructured: [],
156
+ skippedNoDoc: [],
157
+ failed: [],
158
+ };
159
+ for (const [index, task] of tasks.entries()) {
160
+ const taskId = toStringSafe(task.id).trim();
161
+ if (!taskId)
162
+ continue;
163
+ const issue = this.issueCache.get(taskId);
164
+ if (!issue) {
165
+ result.failed.push({
166
+ taskId,
167
+ reason: "Redmine issue payload was not cached during remote list refresh",
168
+ });
169
+ continue;
170
+ }
171
+ const currentState = parseRedmineCanonicalState(this.customFieldValue(issue, this.customFields.canonical_state));
172
+ if (currentState) {
173
+ result.skippedStructured.push(taskId);
174
+ continue;
175
+ }
176
+ const sections = task.sections && Object.keys(task.sections).length > 0
177
+ ? task.sections
178
+ : task.doc
179
+ ? taskDocToSectionMap(task.doc)
180
+ : undefined;
181
+ if (!sections || Object.keys(sections).length === 0) {
182
+ result.skippedNoDoc.push(taskId);
183
+ continue;
184
+ }
185
+ const issueIdText = toStringSafe(issue.id);
186
+ if (!issueIdText) {
187
+ result.failed.push({ taskId, reason: redmineIssueIdMissingMessage() });
188
+ continue;
189
+ }
190
+ const currentRevision = 0;
191
+ const nextRevision = Math.max(task.revision ?? 0, currentRevision, 1);
192
+ const nextCanonicalState = buildRedmineCanonicalStateWithOptions({
193
+ ...task,
194
+ sections,
195
+ revision: nextRevision,
196
+ }, { base: currentState, revision: nextRevision });
197
+ if (!nextCanonicalState) {
198
+ result.skippedNoDoc.push(taskId);
199
+ continue;
200
+ }
201
+ const customFields = [];
202
+ this.appendCustomField(customFields, "canonical_state", nextCanonicalState);
203
+ try {
204
+ await this.requestJson("PUT", `issues/${issueIdText}.json`, {
205
+ issue: { custom_fields: customFields },
206
+ });
207
+ this.setIssueCustomFieldValue(issue, this.customFields.canonical_state, nextCanonicalState);
208
+ this.issueCache.set(taskId, issue);
209
+ await this.cacheTask({
210
+ ...task,
211
+ sections,
212
+ revision: nextRevision,
213
+ dirty: false,
214
+ }, false);
215
+ result.migrated.push(taskId);
216
+ }
217
+ catch (err) {
218
+ const reason = err instanceof Error ? err.message : "Unknown Redmine canonical_state migration failure";
219
+ result.failed.push({ taskId, reason });
220
+ }
221
+ if (this.batchPauseMs > 0 && this.batchSize > 0 && (index + 1) % this.batchSize === 0) {
222
+ await sleep(this.batchPauseMs);
223
+ }
224
+ }
225
+ return result;
226
+ }
227
+ async inspectConfiguration() {
228
+ const visibleCustomFields = await inspectVisibleCustomFields({
229
+ projectId: this.projectId,
230
+ requestJson: async (method, reqPath, payload, params) => await this.requestJson(method, reqPath, payload, params),
231
+ });
232
+ const visibleCanonicalStateFieldId = inferVisibleCanonicalStateFieldId(visibleCustomFields);
233
+ return {
234
+ backendId: this.id,
235
+ visibleCustomFields,
236
+ canonicalState: {
237
+ configuredFieldId: typeof this.customFields.canonical_state === "number"
238
+ ? this.customFields.canonical_state
239
+ : null,
240
+ visibleFieldId: visibleCanonicalStateFieldId,
241
+ },
242
+ configuredFieldNameDrift: detectConfiguredFieldNameDrift({
243
+ configuredFields: this.customFields,
244
+ visibleFields: visibleCustomFields,
245
+ }),
246
+ };
247
+ }
137
248
  async getTask(taskId) {
138
249
  if (!this.cache) {
139
250
  throw new BackendError("Redmine cache is disabled; projection reads are unavailable", "E_BACKEND");
@@ -150,7 +261,7 @@ export class RedmineBackend {
150
261
  throw new Error(unknownTaskIdMessage(taskId));
151
262
  return toStringSafe(task.doc);
152
263
  }
153
- async setTaskDoc(taskId, doc, updatedBy) {
264
+ async setTaskDoc(taskId, doc, updatedBy, opts) {
154
265
  if (!this.customFields.doc) {
155
266
  throw new BackendError(redmineConfigMissingEnvMessage("AGENTPLANE_REDMINE_CUSTOM_FIELDS_DOC"), "E_BACKEND");
156
267
  }
@@ -162,13 +273,38 @@ export class RedmineBackend {
162
273
  if (!issueIdText)
163
274
  throw new Error(redmineIssueIdMissingMessage());
164
275
  const cachedTask = this.issueToTask(issue, taskId);
276
+ const currentState = parseRedmineCanonicalState(this.customFieldValue(issue, this.customFields.canonical_state));
277
+ this.assertExpectedRevisionSupported(taskId, opts);
278
+ this.assertExpectedRevision(taskId, opts?.expectedRevision, currentState?.revision ?? 1);
165
279
  const taskDoc = {
166
280
  doc: String(doc ?? ""),
167
281
  doc_version: cachedTask?.doc_version,
168
282
  };
169
283
  ensureDocMetadata(taskDoc, updatedBy);
284
+ const nextSections = taskDocToSectionMap(String(taskDoc.doc ?? ""));
285
+ const nextRevision = Math.max(cachedTask?.revision ?? 0, currentState?.revision ?? 0, 0) + 1;
170
286
  const customFields = [];
171
287
  this.appendCustomField(customFields, "doc", taskDoc.doc);
288
+ const nextCanonicalState = buildRedmineCanonicalStateWithOptions({
289
+ id: taskId,
290
+ title: cachedTask?.title ?? "",
291
+ description: cachedTask?.description ?? "",
292
+ status: cachedTask?.status ?? "TODO",
293
+ priority: cachedTask?.priority ?? "med",
294
+ owner: cachedTask?.owner ?? this.ownerAgent,
295
+ depends_on: cachedTask?.depends_on ?? [],
296
+ tags: cachedTask?.tags ?? [],
297
+ verify: cachedTask?.verify ?? [],
298
+ doc: taskDoc.doc,
299
+ sections: nextSections,
300
+ revision: nextRevision,
301
+ plan_approval: cachedTask?.plan_approval,
302
+ verification: cachedTask?.verification,
303
+ events: cachedTask?.events,
304
+ }, { base: currentState, revision: nextRevision });
305
+ if (nextCanonicalState) {
306
+ this.appendCustomField(customFields, "canonical_state", nextCanonicalState);
307
+ }
172
308
  this.appendCustomField(customFields, "doc_version", taskDoc.doc_version);
173
309
  this.appendCustomField(customFields, "doc_updated_at", taskDoc.doc_updated_at);
174
310
  this.appendCustomField(customFields, "doc_updated_by", taskDoc.doc_updated_by);
@@ -177,6 +313,8 @@ export class RedmineBackend {
177
313
  });
178
314
  if (cachedTask) {
179
315
  cachedTask.doc = taskDoc.doc;
316
+ cachedTask.sections = nextSections;
317
+ cachedTask.revision = nextRevision;
180
318
  cachedTask.doc_version = taskDoc.doc_version;
181
319
  cachedTask.doc_updated_at = taskDoc.doc_updated_at;
182
320
  cachedTask.doc_updated_by = taskDoc.doc_updated_by;
@@ -190,16 +328,20 @@ export class RedmineBackend {
190
328
  const cached = await this.cache.getTask(taskId);
191
329
  if (!cached)
192
330
  throw new Error(unknownTaskIdMessage(taskId));
331
+ this.assertExpectedRevisionSupported(taskId, opts);
332
+ this.assertExpectedRevision(taskId, opts?.expectedRevision, cached.revision ?? 1);
193
333
  cached.doc = String(doc ?? "");
334
+ cached.sections = taskDocToSectionMap(cached.doc);
335
+ cached.revision = Math.max(cached.revision ?? 0, 0) + 1;
194
336
  ensureDocMetadata(cached, updatedBy);
195
337
  cached.dirty = true;
196
- await this.cache.writeTask(cached);
338
+ await this.cache.writeTask(cached, opts);
197
339
  return;
198
340
  }
199
341
  throw err;
200
342
  }
201
343
  }
202
- async touchTaskDocMetadata(taskId, updatedBy) {
344
+ async touchTaskDocMetadata(taskId, updatedBy, opts) {
203
345
  try {
204
346
  const issue = await this.findIssueByTaskId(taskId);
205
347
  if (!issue)
@@ -209,6 +351,9 @@ export class RedmineBackend {
209
351
  throw new Error(redmineIssueIdMissingMessage());
210
352
  const docValue = this.customFieldValue(issue, this.customFields.doc);
211
353
  const cachedTask = this.issueToTask(issue, taskId);
354
+ const currentState = parseRedmineCanonicalState(this.customFieldValue(issue, this.customFields.canonical_state));
355
+ this.assertExpectedRevisionSupported(taskId, opts);
356
+ this.assertExpectedRevision(taskId, opts?.expectedRevision, currentState?.revision ?? 1);
212
357
  const taskDoc = {
213
358
  doc: docValue ?? "",
214
359
  doc_version: cachedTask?.doc_version,
@@ -237,15 +382,17 @@ export class RedmineBackend {
237
382
  const cached = await this.cache.getTask(taskId);
238
383
  if (!cached)
239
384
  throw new Error(unknownTaskIdMessage(taskId));
385
+ this.assertExpectedRevisionSupported(taskId, opts);
386
+ this.assertExpectedRevision(taskId, opts?.expectedRevision, cached.revision ?? 1);
240
387
  ensureDocMetadata(cached, updatedBy);
241
388
  cached.dirty = true;
242
- await this.cache.writeTask(cached);
389
+ await this.cache.writeTask(cached, opts);
243
390
  return;
244
391
  }
245
392
  throw err;
246
393
  }
247
394
  }
248
- async writeTask(task) {
395
+ async writeTask(task, opts) {
249
396
  const taskId = toStringSafe(task.id).trim();
250
397
  if (!taskId)
251
398
  throw new Error(missingTaskIdMessage());
@@ -260,9 +407,26 @@ export class RedmineBackend {
260
407
  const payload = await this.requestJson("GET", `issues/${issueIdText}.json`);
261
408
  existingIssue = this.issueFromPayload(payload);
262
409
  }
263
- const payload = this.taskToIssuePayload(task, existingIssue ?? undefined);
410
+ const currentState = existingIssue && this.customFields.canonical_state
411
+ ? parseRedmineCanonicalState(this.customFieldValue(existingIssue, this.customFields.canonical_state))
412
+ : null;
413
+ this.assertExpectedRevisionSupported(taskId, opts);
414
+ this.assertExpectedRevision(taskId, opts?.expectedRevision, currentState?.revision ?? 0);
415
+ const nextRevision = issueIdText
416
+ ? Math.max(task.revision ?? 0, currentState?.revision ?? 0, 0) + 1
417
+ : Math.max(task.revision ?? 0, currentState?.revision ?? 0, 1);
418
+ const taskForWrite = {
419
+ ...task,
420
+ revision: nextRevision,
421
+ sections: task.sections && Object.keys(task.sections).length > 0
422
+ ? task.sections
423
+ : task.doc
424
+ ? taskDocToSectionMap(task.doc)
425
+ : undefined,
426
+ };
427
+ const payload = this.taskToIssuePayload(taskForWrite, existingIssue ?? undefined);
264
428
  if (payload.status_id === undefined) {
265
- const inferredStatusId = await this.inferStatusIdForTaskStatus(task.status);
429
+ const inferredStatusId = await this.inferStatusIdForTaskStatus(taskForWrite.status);
266
430
  if (inferredStatusId !== null)
267
431
  payload.status_id = inferredStatusId;
268
432
  }
@@ -287,27 +451,37 @@ export class RedmineBackend {
287
451
  const existingComments = existingIssue && this.customFields.comments
288
452
  ? this.normalizeComments(this.maybeParseJson(this.customFieldValue(existingIssue, this.customFields.comments)))
289
453
  : [];
290
- const desiredComments = this.normalizeComments(task.comments);
454
+ const desiredComments = this.normalizeComments(taskForWrite.comments);
291
455
  await this.appendCommentNotes(issueIdText, existingComments, desiredComments);
292
456
  }
293
- task.dirty = false;
294
- await this.cacheTask(task, false);
457
+ taskForWrite.dirty = false;
458
+ await this.cacheTask(taskForWrite, false);
295
459
  this.issueCache.clear();
296
460
  }
297
461
  catch (err) {
298
462
  if (err instanceof RedmineUnavailable) {
299
463
  if (!this.cache)
300
464
  throw err;
301
- task.dirty = true;
302
- await this.cacheTask(task, true);
465
+ this.assertExpectedRevisionSupported(taskId, opts);
466
+ const taskForCache = {
467
+ ...task,
468
+ revision: Math.max(task.revision ?? 0, 1),
469
+ sections: task.sections && Object.keys(task.sections).length > 0
470
+ ? task.sections
471
+ : task.doc
472
+ ? taskDocToSectionMap(task.doc)
473
+ : undefined,
474
+ dirty: true,
475
+ };
476
+ await this.cache.writeTask(taskForCache, opts);
303
477
  return;
304
478
  }
305
479
  throw err;
306
480
  }
307
481
  }
308
- async writeTasks(tasks) {
482
+ async writeTasks(tasks, opts) {
309
483
  for (const [index, task] of tasks.entries()) {
310
- await this.writeTask(task);
484
+ await this.writeTask(task, opts);
311
485
  if (this.batchPauseMs > 0 && this.batchSize > 0 && (index + 1) % this.batchSize === 0) {
312
486
  await sleep(this.batchPauseMs);
313
487
  }
@@ -430,6 +604,22 @@ export class RedmineBackend {
430
604
  const next = { ...task, dirty };
431
605
  await this.cache.writeTask(next);
432
606
  }
607
+ assertExpectedRevisionSupported(taskId, opts) {
608
+ if (opts?.expectedRevision === undefined)
609
+ return;
610
+ if (this.capabilities.supports_revision_guarded_writes)
611
+ return;
612
+ throw new BackendError(`Task revision guarding is unavailable for ${taskId} without AGENTPLANE_REDMINE_CUSTOM_FIELDS_CANONICAL_STATE`, "E_BACKEND");
613
+ }
614
+ assertExpectedRevision(taskId, expectedRevision, currentRevision) {
615
+ if (expectedRevision === undefined)
616
+ return;
617
+ const expected = Math.trunc(expectedRevision);
618
+ if (expected <= 0 || expected === currentRevision)
619
+ return;
620
+ throw new BackendError(`Task revision changed concurrently: ${taskId} ` +
621
+ `(expected revision ${expected}, current revision ${currentRevision})`, "E_BACKEND");
622
+ }
433
623
  taskIdFieldId() {
434
624
  const fieldId = this.customFields?.task_id;
435
625
  if (fieldId)
@@ -1,5 +1,5 @@
1
1
  export declare const TASK_ID_RE: RegExp;
2
2
  export declare const DEFAULT_DOC_UPDATED_BY = "agentplane";
3
- export declare const DOC_VERSION = 2;
3
+ export declare const DOC_VERSION = 3;
4
4
  export declare const SUPPORTED_DOC_VERSIONS: readonly [2, 3];
5
5
  //# sourceMappingURL=constants.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { TASK_ID_ALPHABET } from "@agentplaneorg/core";
2
2
  export const TASK_ID_RE = new RegExp(String.raw `^\d{12}-[${TASK_ID_ALPHABET}]{4,}$`);
3
3
  export const DEFAULT_DOC_UPDATED_BY = "agentplane";
4
- export const DOC_VERSION = 2;
4
+ export const DOC_VERSION = 3;
5
5
  export const SUPPORTED_DOC_VERSIONS = [2, 3];
@@ -1 +1 @@
1
- {"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../../../src/backends/task-backend/shared/record.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAYtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,CAwD7D"}
1
+ {"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../../../src/backends/task-backend/shared/record.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAYtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAkB3C,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,CA2D7D"}
@@ -3,6 +3,22 @@ import { extractTaskDoc } from "./doc.js";
3
3
  import { normalizeEvents } from "./events.js";
4
4
  import { normalizeDependsOn, normalizePlanApproval, normalizeVerificationResult, } from "./normalize.js";
5
5
  import { toStringArray } from "./strings.js";
6
+ import { renderTaskDocFromSections, taskDocToSectionMap } from "@agentplaneorg/core";
7
+ function normalizeRevision(value) {
8
+ return Number.isInteger(value) && Number(value) > 0 ? Number(value) : undefined;
9
+ }
10
+ function normalizeCanonicalSections(value) {
11
+ if (!isRecord(value))
12
+ return undefined;
13
+ const out = {};
14
+ for (const [title, text] of Object.entries(value)) {
15
+ const normalizedTitle = title.trim();
16
+ if (!normalizedTitle || typeof text !== "string")
17
+ continue;
18
+ out[normalizedTitle] = text.replaceAll("\r\n", "\n").trimEnd();
19
+ }
20
+ return Object.keys(out).length > 0 ? out : undefined;
21
+ }
6
22
  export function taskRecordToData(record) {
7
23
  const fm = record.frontmatter;
8
24
  const comments = Array.isArray(fm.comments)
@@ -19,6 +35,8 @@ export function taskRecordToData(record) {
19
35
  const events = normalizeEvents(fm.events);
20
36
  const planApproval = normalizePlanApproval(fm.plan_approval);
21
37
  const verification = normalizeVerificationResult(fm.verification);
38
+ const sections = normalizeCanonicalSections(fm.sections);
39
+ const doc = sections ? renderTaskDocFromSections(sections) : extractTaskDoc(record.body);
22
40
  const baseId = typeof fm.id === "string" ? fm.id : typeof record.id === "string" ? record.id : "";
23
41
  const task = {
24
42
  id: baseId.trim(),
@@ -32,6 +50,7 @@ export function taskRecordToData(record) {
32
50
  status: typeof fm.status === "string" ? fm.status : "TODO",
33
51
  priority: typeof fm.priority === "string" || typeof fm.priority === "number" ? fm.priority : "",
34
52
  owner: typeof fm.owner === "string" ? fm.owner : "",
53
+ revision: normalizeRevision(fm.revision) ?? 1,
35
54
  depends_on: normalizeDependsOn(fm.depends_on),
36
55
  tags: toStringArray(fm.tags),
37
56
  verify: toStringArray(fm.verify),
@@ -46,8 +65,8 @@ export function taskRecordToData(record) {
46
65
  dirty: typeof fm.dirty === "boolean" ? fm.dirty : undefined,
47
66
  id_source: typeof fm.id_source === "string" ? fm.id_source : undefined,
48
67
  };
49
- const doc = extractTaskDoc(record.body);
50
68
  if (doc)
51
69
  task.doc = doc;
70
+ task.sections = sections ?? (doc ? taskDocToSectionMap(doc) : undefined);
52
71
  return task;
53
72
  }
@@ -33,6 +33,7 @@ export type TaskData = {
33
33
  status: string;
34
34
  priority: string | number;
35
35
  owner: string;
36
+ revision?: number;
36
37
  depends_on: string[];
37
38
  tags: string[];
38
39
  verify: string[];
@@ -48,6 +49,7 @@ export type TaskData = {
48
49
  }[];
49
50
  events?: TaskEvent[];
50
51
  doc?: string;
52
+ sections?: Record<string, string>;
51
53
  doc_version?: number;
52
54
  doc_updated_at?: string;
53
55
  doc_updated_by?: string;
@@ -55,11 +57,16 @@ export type TaskData = {
55
57
  id_source?: string;
56
58
  };
57
59
  export type TaskDocMeta = Pick<TaskData, "doc" | "doc_version" | "doc_updated_at" | "doc_updated_by">;
60
+ export type TaskWriteOptions = {
61
+ expectedRevision?: number;
62
+ };
58
63
  export type TaskBackendCapabilities = {
59
64
  canonical_source: "local" | "remote";
60
65
  projection: "canonical" | "cache";
61
66
  reads_from_projection_by_default: boolean;
62
67
  writes_task_readmes?: boolean;
68
+ supports_task_revisions: boolean;
69
+ supports_revision_guarded_writes: boolean;
63
70
  may_access_network_on_read: boolean;
64
71
  may_access_network_on_write: boolean;
65
72
  supports_projection_refresh: boolean;
@@ -71,6 +78,35 @@ export type TaskProjectionRefreshOptions = {
71
78
  quiet?: boolean;
72
79
  conflict?: "diff" | "prefer-local" | "prefer-remote" | "fail";
73
80
  };
81
+ export type TaskCanonicalStateMigrationResult = {
82
+ scanned: number;
83
+ migrated: string[];
84
+ skippedStructured: string[];
85
+ skippedNoDoc: string[];
86
+ failed: {
87
+ taskId: string;
88
+ reason: string;
89
+ }[];
90
+ };
91
+ export type TaskBackendVisibleField = {
92
+ id: number;
93
+ name: string;
94
+ nonEmptyCount: number;
95
+ };
96
+ export type TaskBackendFieldNameDrift = {
97
+ key: string;
98
+ configuredId: number;
99
+ visibleName: string;
100
+ };
101
+ export type TaskBackendInspectionResult = {
102
+ backendId: string;
103
+ visibleCustomFields: TaskBackendVisibleField[];
104
+ canonicalState: {
105
+ configuredFieldId: number | null;
106
+ visibleFieldId: number | null;
107
+ };
108
+ configuredFieldNameDrift: TaskBackendFieldNameDrift[];
109
+ };
74
110
  export type TaskBackend = {
75
111
  id: string;
76
112
  capabilities: TaskBackendCapabilities;
@@ -79,18 +115,20 @@ export type TaskBackend = {
79
115
  getLastListWarnings?(): string[];
80
116
  getTask(taskId: string): Promise<TaskData | null>;
81
117
  getTasks?(taskIds: string[]): Promise<(TaskData | null)[]>;
82
- writeTask(task: TaskData): Promise<void>;
83
- writeTasks?(tasks: TaskData[]): Promise<void>;
118
+ writeTask(task: TaskData, opts?: TaskWriteOptions): Promise<void>;
119
+ writeTasks?(tasks: TaskData[], opts?: TaskWriteOptions): Promise<void>;
84
120
  normalizeTasks?(): Promise<{
85
121
  scanned: number;
86
122
  changed: number;
87
123
  }>;
88
124
  refreshProjection?(opts: TaskProjectionRefreshOptions): Promise<void>;
125
+ migrateCanonicalState?(): Promise<TaskCanonicalStateMigrationResult>;
126
+ inspectConfiguration?(): Promise<TaskBackendInspectionResult>;
89
127
  exportProjectionSnapshot?(outputPath: string): Promise<void>;
90
128
  exportTasksJson?(outputPath: string): Promise<void>;
91
129
  getTaskDoc?(taskId: string): Promise<string>;
92
- setTaskDoc?(taskId: string, doc: string, updatedBy?: string): Promise<void>;
93
- touchTaskDocMetadata?(taskId: string, updatedBy?: string): Promise<void>;
130
+ setTaskDoc?(taskId: string, doc: string, updatedBy?: string, opts?: TaskWriteOptions): Promise<void>;
131
+ touchTaskDocMetadata?(taskId: string, updatedBy?: string, opts?: TaskWriteOptions): Promise<void>;
94
132
  sync?(opts: {
95
133
  direction: "push" | "pull";
96
134
  conflict: "diff" | "prefer-local" | "prefer-remote" | "fail";
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/backends/task-backend/shared/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/backends/task-backend/shared/types.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  export { DEFAULT_DOC_UPDATED_BY, DOC_VERSION, TASK_ID_RE } from "./shared/constants.js";
2
- export type { PlanApproval, PlanApprovalState, TaskBackend, TaskBackendCapabilities, TaskData, TaskDocMeta, TaskEvent, TaskEventType, TaskProjectionRefreshOptions, VerificationResult, VerificationState, } from "./shared/types.js";
2
+ export type { PlanApproval, PlanApprovalState, TaskBackend, TaskBackendCapabilities, TaskBackendFieldNameDrift, TaskBackendInspectionResult, TaskBackendVisibleField, TaskCanonicalStateMigrationResult, TaskData, TaskDocMeta, TaskEvent, TaskEventType, TaskProjectionRefreshOptions, TaskWriteOptions, VerificationResult, VerificationState, } from "./shared/types.js";
3
3
  export * from "./shared/concurrency.js";
4
4
  export * from "./shared/doc.js";
5
5
  export * from "./shared/errors.js";
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/backends/task-backend/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExF,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,uBAAuB,EACvB,QAAQ,EACR,WAAW,EACX,SAAS,EACT,aAAa,EACb,4BAA4B,EAC5B,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/backends/task-backend/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExF,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,uBAAuB,EACvB,yBAAyB,EACzB,2BAA2B,EAC3B,uBAAuB,EACvB,iCAAiC,EACjC,QAAQ,EACR,WAAW,EACX,SAAS,EACT,aAAa,EACb,4BAA4B,EAC5B,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC"}
@@ -1,4 +1,4 @@
1
- export { BackendError, RedmineUnavailable, buildTasksExportSnapshotFromTasks, extractTaskDoc, mergeTaskDoc, taskRecordToData, writeTasksExportFromTasks, type PlanApproval, type PlanApprovalState, type TaskBackend, type TaskBackendCapabilities, type TaskData, type TaskEvent, type TaskEventType, type TaskProjectionRefreshOptions, type VerificationResult, type VerificationState, } from "./task-backend/shared.js";
1
+ export { BackendError, RedmineUnavailable, buildTasksExportSnapshotFromTasks, extractTaskDoc, mergeTaskDoc, taskRecordToData, writeTasksExportFromTasks, type PlanApproval, type PlanApprovalState, type TaskBackend, type TaskBackendCapabilities, type TaskBackendFieldNameDrift, type TaskBackendInspectionResult, type TaskBackendVisibleField, type TaskData, type TaskEvent, type TaskEventType, type TaskProjectionRefreshOptions, type TaskWriteOptions, type VerificationResult, type VerificationState, } from "./task-backend/shared.js";
2
2
  export { LocalBackend } from "./task-backend/local-backend.js";
3
3
  export { RedmineBackend } from "./task-backend/redmine-backend.js";
4
4
  export { loadTaskBackend } from "./task-backend/load.js";
@@ -1 +1 @@
1
- {"version":3,"file":"task-backend.d.ts","sourceRoot":"","sources":["../../src/backends/task-backend.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,iCAAiC,EACjC,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,yBAAyB,EACzB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,uBAAuB,EAC5B,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,4BAA4B,EACjC,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,GACvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/D,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAEnE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"task-backend.d.ts","sourceRoot":"","sources":["../../src/backends/task-backend.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,iCAAiC,EACjC,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,yBAAyB,EACzB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,EAChC,KAAK,uBAAuB,EAC5B,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,4BAA4B,EACjC,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,GACvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/D,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAEnE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function installTaskBackendTestHarness(): void;
2
+ export declare function makeTempDir(): Promise<string>;
3
+ export declare const makeIssue: (priorityName?: string) => Record<string, unknown>;
4
+ //# sourceMappingURL=task-backend.test-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-backend.test-helpers.d.ts","sourceRoot":"","sources":["../../src/backends/task-backend.test-helpers.ts"],"names":[],"mappings":"AAUA,wBAAgB,6BAA6B,IAAI,IAAI,CAWpD;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAEnD;AAED,eAAO,MAAM,SAAS,GAAI,eAAe,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAatE,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { mkdtemp } from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { afterEach, beforeEach } from "vitest";
5
+ import { silenceStdIO } from "../cli/run-cli.test-helpers.js";
6
+ const TMP_PREFIX = "agentplane-task-backend-";
7
+ export function installTaskBackendTestHarness() {
8
+ let restoreStdIO = null;
9
+ beforeEach(() => {
10
+ restoreStdIO = silenceStdIO();
11
+ });
12
+ afterEach(() => {
13
+ restoreStdIO?.();
14
+ restoreStdIO = null;
15
+ });
16
+ }
17
+ export async function makeTempDir() {
18
+ return await mkdtemp(path.join(os.tmpdir(), TMP_PREFIX));
19
+ }
20
+ export const makeIssue = (priorityName) => ({
21
+ id: 1,
22
+ subject: "Subject",
23
+ description: "Desc",
24
+ status: { id: 1 },
25
+ priority: priorityName ? { name: priorityName } : undefined,
26
+ custom_fields: [
27
+ { id: 2, value: '["echo ok"]' },
28
+ { id: 3, value: '{"hash":"h","message":"m"}' },
29
+ { id: 4, value: "note" },
30
+ { id: 5, value: "2" },
31
+ ],
32
+ updated_on: "2026-01-30T00:00:00Z",
33
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"task-index.d.ts","sourceRoot":"","sources":["../../src/backends/task-index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAI3C,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,cAAc,EAAE,CAAC,CAAC;IAClB,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,cAAc,EAAE,CAAC,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,eAAe,CAAC;AAE5C,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAU7D;AA8ED,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAWpF;AAED,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5F;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,QAAQ,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,cAAc,CAahB"}
1
+ {"version":3,"file":"task-index.d.ts","sourceRoot":"","sources":["../../src/backends/task-index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAI3C,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,cAAc,EAAE,CAAC,CAAC;IAClB,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,cAAc,EAAE,CAAC,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,eAAe,CAAC;AAE5C,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAU7D;AA8ED,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAWpF;AAED,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5F;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,QAAQ,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,cAAc,CAchB"}
@@ -127,6 +127,7 @@ export function buildTaskIndexEntry(task, readmePath, mtimeMs) {
127
127
  ...task,
128
128
  // Keep the index payload lean for list/search/next paths.
129
129
  doc: undefined,
130
+ sections: undefined,
130
131
  comments: undefined,
131
132
  events: undefined,
132
133
  };
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap-guide.d.ts","sourceRoot":"","sources":["../../src/cli/bootstrap-guide.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB,4CAA4C,CAAC;AAClF,eAAO,MAAM,+BAA+B,0BAA0B,CAAC;AAEvE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,4BAA4B,oKAM/B,CAAC;AAEX,eAAO,MAAM,4BAA4B,UAIxC,CAAC;AAEF,eAAO,MAAM,oCAAoC,oUAMvC,CAAC;AAEX,eAAO,MAAM,2BAA2B,sFAI9B,CAAC;AAEX,eAAO,MAAM,kBAAkB,EAAE,SAAS,gBAAgB,EAmChD,CAAC;AAEX,wBAAgB,4BAA4B,IAAI,MAAM,CAErD;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,GAAG,MAAM,EAAE,CAiB3F;AAMD,wBAAgB,kBAAkB,IAAI,MAAM,CA2B3C"}
1
+ {"version":3,"file":"bootstrap-guide.d.ts","sourceRoot":"","sources":["../../src/cli/bootstrap-guide.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB,4CAA4C,CAAC;AAClF,eAAO,MAAM,+BAA+B,0BAA0B,CAAC;AAEvE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,4BAA4B,oKAM/B,CAAC;AAEX,eAAO,MAAM,4BAA4B,UAIxC,CAAC;AAEF,eAAO,MAAM,oCAAoC,oUAMvC,CAAC;AAEX,eAAO,MAAM,2BAA2B,sFAI9B,CAAC;AAEX,eAAO,MAAM,kBAAkB,EAAE,SAAS,gBAAgB,EAoChD,CAAC;AAEX,wBAAgB,4BAA4B,IAAI,MAAM,CAErD;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,GAAG,MAAM,EAAE,CAiB3F;AAMD,wBAAgB,kBAAkB,IAAI,MAAM,CA2B3C"}
@@ -40,6 +40,7 @@ export const BOOTSTRAP_SECTIONS = [
40
40
  summary: "Use one short direct-mode route: create the task, approve it, start it, verify it, and finish it.",
41
41
  commands: BOOTSTRAP_DIRECT_HAPPY_PATH_COMMANDS,
42
42
  notes: [
43
+ "Use `agentplane role ORCHESTRATOR` during planning, then switch to `agentplane role <OWNER>` before owner-scoped execution.",
43
44
  "Use `task doc set` to fill required README sections before approval.",
44
45
  "For dependent tasks, wait until upstream tasks are DONE before `task start-ready`.",
45
46
  "`task plan approve` and `task start-ready` must run sequentially, never in parallel.",
@@ -1 +1 @@
1
- {"version":3,"file":"command-guide.d.ts","sourceRoot":"","sources":["../../src/cli/command-guide.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B,CAAC;AAkGF,wBAAgB,SAAS,IAAI,MAAM,EAAE,CAEpC;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAMvE;AAMD,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;CAAO,GAC/C,MAAM,GAAG,IAAI,CA6Bf;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAoCzC"}
1
+ {"version":3,"file":"command-guide.d.ts","sourceRoot":"","sources":["../../src/cli/command-guide.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B,CAAC;AAmGF,wBAAgB,SAAS,IAAI,MAAM,EAAE,CAEpC;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAMvE;AAMD,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;CAAO,GAC/C,MAAM,GAAG,IAAI,CA6Bf;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAoCzC"}