agentera 3.0.0-dev.4 → 3.0.0-dev.46

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 (585) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +108 -22
  3. package/bundle/.agentera-npx-bundle.json +1 -1
  4. package/bundle/CHANGELOG.md +1351 -0
  5. package/bundle/DESIGN.md +229 -0
  6. package/bundle/LICENSE +201 -0
  7. package/bundle/README.md +143 -0
  8. package/bundle/UPGRADE.md +236 -0
  9. package/bundle/extract-corpus-parity.json +21 -0
  10. package/bundle/fixtures/routing/hybrid-corpus.yaml +154 -0
  11. package/bundle/references/adapters/package-publication.json +437 -0
  12. package/bundle/references/adapters/package-registry.yaml +434 -189
  13. package/bundle/references/adapters/package-surface-characterization.md +66 -35
  14. package/bundle/references/adapters/runtime-lifecycle-adapters.yaml +74 -0
  15. package/bundle/references/adapters/runtime-lifecycle-authority.yaml +62 -0
  16. package/bundle/references/adapters/runtime-lifecycle-operation-contract.yaml +84 -0
  17. package/bundle/references/adapters/runtime-retired-resources.yaml +333 -0
  18. package/bundle/references/analysis/evidence-tier-authority.yaml +518 -0
  19. package/bundle/references/analysis/verification-policy.yaml +191 -0
  20. package/bundle/references/artifacts/artifact-registry-interface-model.yaml +20 -10
  21. package/bundle/references/artifacts/glossary-entry-contract.yaml +1254 -0
  22. package/bundle/references/artifacts/state-storage-authority.yaml +2982 -0
  23. package/bundle/references/artifacts/verbosity-budget-authority.yaml +42 -0
  24. package/bundle/references/cli/app-lifecycle-vocabulary.yaml +7 -8
  25. package/bundle/references/cli/capability-instruction-contract.yaml +97 -59
  26. package/bundle/references/cli/hybrid-route-contract.yaml +438 -0
  27. package/bundle/references/cli/routing-model.md +155 -0
  28. package/bundle/references/cli/trigger-schema-enrichment.md +147 -0
  29. package/bundle/references/cli/update-channels.yaml +35 -2
  30. package/bundle/references/cli/vocabulary-index.yaml +23 -20
  31. package/bundle/references/cli/vocabulary.md +337 -366
  32. package/bundle/references/meta/retained-reference-authority.yaml +151 -0
  33. package/bundle/registry.json +14 -14
  34. package/bundle/skills/agentera/SKILL.md +218 -408
  35. package/bundle/skills/agentera/capabilities/audit/schemas/artifacts.yaml +84 -0
  36. package/bundle/skills/agentera/capabilities/{inspektera → audit}/schemas/exit.yaml +2 -2
  37. package/bundle/skills/agentera/capabilities/audit/schemas/triggers.yaml +25 -0
  38. package/bundle/skills/agentera/capabilities/{inspektera → audit}/schemas/validation.yaml +37 -18
  39. package/bundle/skills/agentera/capabilities/build/schemas/artifacts.yaml +102 -0
  40. package/bundle/skills/agentera/capabilities/{realisera → build}/schemas/exit.yaml +6 -5
  41. package/bundle/skills/agentera/capabilities/build/schemas/triggers.yaml +27 -0
  42. package/bundle/skills/agentera/capabilities/build/schemas/validation.yaml +176 -0
  43. package/bundle/skills/agentera/capabilities/{visualisera → design}/schemas/artifacts.yaml +12 -12
  44. package/bundle/skills/agentera/capabilities/{visualisera → design}/schemas/exit.yaml +5 -5
  45. package/bundle/skills/agentera/capabilities/design/schemas/triggers.yaml +16 -0
  46. package/bundle/skills/agentera/capabilities/{visualisera → design}/schemas/validation.yaml +7 -7
  47. package/bundle/skills/agentera/capabilities/discuss/schemas/artifacts.yaml +51 -0
  48. package/bundle/skills/agentera/capabilities/{resonera → discuss}/schemas/exit.yaml +2 -2
  49. package/bundle/skills/agentera/capabilities/discuss/schemas/triggers.yaml +20 -0
  50. package/bundle/skills/agentera/capabilities/discuss/schemas/validation.yaml +144 -0
  51. package/bundle/skills/agentera/capabilities/document/schemas/artifacts.yaml +80 -0
  52. package/bundle/skills/agentera/capabilities/document/schemas/triggers.yaml +16 -0
  53. package/bundle/skills/agentera/capabilities/{dokumentera → document}/schemas/validation.yaml +18 -18
  54. package/bundle/skills/agentera/capabilities/{optimera → optimize}/schemas/artifacts.yaml +18 -18
  55. package/bundle/skills/agentera/capabilities/{optimera → optimize}/schemas/exit.yaml +2 -2
  56. package/bundle/skills/agentera/capabilities/optimize/schemas/triggers.yaml +16 -0
  57. package/bundle/skills/agentera/capabilities/{optimera → optimize}/schemas/validation.yaml +9 -9
  58. package/bundle/skills/agentera/capabilities/orchestrate/schemas/artifacts.yaml +76 -0
  59. package/bundle/skills/agentera/capabilities/{orkestrera → orchestrate}/schemas/exit.yaml +9 -7
  60. package/bundle/skills/agentera/capabilities/orchestrate/schemas/triggers.yaml +23 -0
  61. package/bundle/skills/agentera/capabilities/orchestrate/schemas/validation.yaml +121 -0
  62. package/bundle/skills/agentera/capabilities/plan/schemas/artifacts.yaml +66 -0
  63. package/bundle/skills/agentera/capabilities/{planera → plan}/schemas/exit.yaml +2 -2
  64. package/bundle/skills/agentera/capabilities/plan/schemas/triggers.yaml +23 -0
  65. package/bundle/skills/agentera/capabilities/plan/schemas/validation.yaml +121 -0
  66. package/bundle/skills/agentera/capabilities/profile/schemas/artifacts.yaml +23 -0
  67. package/bundle/skills/agentera/capabilities/{profilera → profile}/schemas/exit.yaml +6 -5
  68. package/bundle/skills/agentera/capabilities/profile/schemas/triggers.yaml +20 -0
  69. package/bundle/skills/agentera/capabilities/profile/schemas/validation.yaml +115 -0
  70. package/bundle/skills/agentera/capabilities/research/schemas/artifacts.yaml +24 -0
  71. package/bundle/skills/agentera/capabilities/research/schemas/triggers.yaml +16 -0
  72. package/bundle/skills/agentera/capabilities/{inspirera → research}/schemas/validation.yaml +2 -2
  73. package/bundle/skills/agentera/capabilities/status/schemas/artifacts.yaml +73 -0
  74. package/bundle/skills/agentera/capabilities/status/schemas/triggers.yaml +22 -0
  75. package/bundle/skills/agentera/capabilities/{hej → status}/schemas/validation.yaml +5 -5
  76. package/bundle/skills/agentera/capabilities/{visionera → vision}/schemas/artifacts.yaml +16 -16
  77. package/bundle/skills/agentera/capabilities/{visionera → vision}/schemas/exit.yaml +7 -6
  78. package/bundle/skills/agentera/capabilities/vision/schemas/triggers.yaml +23 -0
  79. package/bundle/skills/agentera/capabilities/{visionera → vision}/schemas/validation.yaml +18 -20
  80. package/bundle/skills/agentera/capability_schema_contract.yaml +200 -37
  81. package/bundle/skills/agentera/protocol.yaml +31 -31
  82. package/bundle/skills/agentera/route-phrases.yaml +81 -0
  83. package/bundle/skills/agentera/schemas/artifacts/changelog.yaml +5 -4
  84. package/bundle/skills/agentera/schemas/artifacts/decisions.yaml +40 -22
  85. package/bundle/skills/agentera/schemas/artifacts/design.yaml +5 -4
  86. package/bundle/skills/agentera/schemas/artifacts/docs.yaml +15 -19
  87. package/bundle/skills/agentera/schemas/artifacts/experiments.yaml +145 -14
  88. package/bundle/skills/agentera/schemas/artifacts/glossary.yaml +82 -0
  89. package/bundle/skills/agentera/schemas/artifacts/health.yaml +58 -21
  90. package/bundle/skills/agentera/schemas/artifacts/objective.yaml +22 -8
  91. package/bundle/skills/agentera/schemas/artifacts/plan.yaml +421 -33
  92. package/bundle/skills/agentera/schemas/artifacts/progress.yaml +143 -53
  93. package/bundle/skills/agentera/schemas/artifacts/todo.yaml +345 -31
  94. package/bundle/skills/agentera/schemas/artifacts/vision.yaml +3 -3
  95. package/dist/analytics/extractCorpus/cli.js +190 -0
  96. package/dist/analytics/extractCorpus/copilotSessions.js +275 -0
  97. package/dist/analytics/extractCorpus/core.js +392 -0
  98. package/dist/analytics/extractCorpus/corpus.js +167 -0
  99. package/dist/analytics/extractCorpus/coverageAudit.js +260 -0
  100. package/dist/analytics/extractCorpus/cursorSessions.js +425 -0
  101. package/dist/analytics/extractCorpus/evidenceTiers.js +603 -0
  102. package/dist/analytics/extractCorpus/extractCorpusParity.js +105 -0
  103. package/dist/analytics/extractCorpus/filesystemSources.js +118 -0
  104. package/dist/analytics/extractCorpus/index.js +14 -0
  105. package/dist/analytics/extractCorpus/jsonlSessions.js +204 -0
  106. package/dist/analytics/extractCorpus/sqliteCaps.js +43 -0
  107. package/dist/analytics/extractCorpus/sqliteSessions.js +367 -0
  108. package/dist/analytics/extractCorpus/tierReader.js +108 -0
  109. package/dist/analytics/extractCorpus.js +2 -1791
  110. package/dist/analytics/glossaryAdviceResolution.js +166 -0
  111. package/dist/analytics/glossaryInputAcquisition.js +319 -0
  112. package/dist/analytics/personalGlossaryAdmission.js +133 -0
  113. package/dist/analytics/personalGlossaryProfile.js +219 -0
  114. package/dist/analytics/profileSignals.js +211 -0
  115. package/dist/analytics/usageStats.js +169 -42
  116. package/dist/audit/terminologyDrift.js +281 -0
  117. package/dist/bin/agentera.js +3 -2
  118. package/dist/capabilities/audit/instructions.js +16 -0
  119. package/dist/capabilities/build/instructions.js +56 -0
  120. package/dist/capabilities/design/instructions.js +4 -0
  121. package/dist/capabilities/discuss/instructions.js +29 -0
  122. package/dist/capabilities/document/instructions.js +11 -0
  123. package/dist/capabilities/index.js +40 -0
  124. package/dist/capabilities/optimize/instructions.js +14 -0
  125. package/dist/capabilities/orchestrate/instructions.js +40 -0
  126. package/dist/capabilities/plan/instructions.js +32 -0
  127. package/dist/capabilities/profile/instructions.js +70 -0
  128. package/dist/capabilities/research/instructions.js +5 -0
  129. package/dist/capabilities/status/instructions.js +11 -0
  130. package/dist/capabilities/status/startupInstructions.js +34 -0
  131. package/dist/capabilities/vision/instructions.js +4 -0
  132. package/dist/cli/appContext.js +30 -24
  133. package/dist/cli/argvalidate.js +0 -1
  134. package/dist/cli/capabilityContext/benchmark.js +565 -0
  135. package/dist/cli/capabilityContext/bespoke.js +44 -0
  136. package/dist/cli/capabilityContext/build.js +242 -0
  137. package/dist/cli/capabilityContext/closeout.js +233 -0
  138. package/dist/cli/capabilityContext/contract.js +179 -0
  139. package/dist/cli/capabilityContext/evidence.js +463 -0
  140. package/dist/cli/capabilityContext/index.js +3 -0
  141. package/dist/cli/capabilityContext/orchestration.js +131 -0
  142. package/dist/cli/capabilityContext/planState.js +260 -0
  143. package/dist/cli/capabilityContext/progress.js +142 -0
  144. package/dist/cli/capabilityContext/projectVerification.js +409 -0
  145. package/dist/cli/capabilityContext/shared.js +83 -0
  146. package/dist/cli/capabilityContext/slim.js +152 -0
  147. package/dist/cli/capabilityContext/startup.js +150 -0
  148. package/dist/cli/capabilityContext/startupAggregation.js +68 -0
  149. package/dist/cli/capabilityContext/types.js +56 -0
  150. package/dist/cli/capabilityContext.js +1 -2421
  151. package/dist/cli/commands/appHome.js +22 -0
  152. package/dist/cli/commands/capability.js +5 -12
  153. package/dist/cli/commands/compact.js +41 -13
  154. package/dist/cli/commands/doctor.js +127 -97
  155. package/dist/cli/commands/durability.js +81 -0
  156. package/dist/cli/commands/glossaryAdvice.js +138 -0
  157. package/dist/cli/commands/lint.js +26 -44
  158. package/dist/cli/commands/personalGlossary.js +176 -0
  159. package/dist/cli/commands/prime/briefOrientation.js +747 -0
  160. package/dist/cli/commands/prime/buildExecutionRequest.js +165 -0
  161. package/dist/cli/commands/prime/bundleStatus.js +190 -0
  162. package/dist/cli/commands/prime/collectEntityOrientation.js +311 -0
  163. package/dist/cli/commands/prime/collectOrientationState.js +212 -0
  164. package/dist/cli/commands/prime/orientationOutput.js +397 -0
  165. package/dist/cli/commands/prime/types.js +1 -0
  166. package/dist/cli/commands/prime/v1Migration.js +38 -0
  167. package/dist/cli/commands/prime.js +80 -558
  168. package/dist/cli/commands/profileGrounding.js +55 -0
  169. package/dist/cli/commands/query.js +78 -53
  170. package/dist/cli/commands/report.js +96 -25
  171. package/dist/cli/commands/route.js +142 -0
  172. package/dist/cli/commands/schema.js +266 -143
  173. package/dist/cli/commands/state/decisions.js +387 -0
  174. package/dist/cli/commands/state/docs.js +70 -0
  175. package/dist/cli/commands/state/experimentRecords.js +151 -0
  176. package/dist/cli/commands/state/experiments.js +14 -0
  177. package/dist/cli/commands/state/get.js +129 -0
  178. package/dist/cli/commands/state/health.js +14 -0
  179. package/dist/cli/commands/state/index.js +16 -0
  180. package/dist/cli/commands/state/list.js +194 -0
  181. package/dist/cli/commands/state/objective.js +25 -0
  182. package/dist/cli/commands/state/plan.js +14 -0
  183. package/dist/cli/commands/state/planTasks.js +154 -0
  184. package/dist/cli/commands/state/plans.js +154 -0
  185. package/dist/cli/commands/state/progress.js +13 -0
  186. package/dist/cli/commands/state/shared.js +14 -0
  187. package/dist/cli/commands/state/todo.js +42 -0
  188. package/dist/cli/commands/state/write.js +434 -0
  189. package/dist/cli/commands/upgrade.js +146 -5
  190. package/dist/cli/commands/upgradeVerify.js +118 -0
  191. package/dist/cli/commands/validate.js +272 -213
  192. package/dist/cli/commands/verify.js +24 -9
  193. package/dist/cli/contracts/bundleStatus.js +1 -0
  194. package/dist/cli/contracts/orientationState.js +1 -0
  195. package/dist/cli/dispatch/argvParser.js +32 -0
  196. package/dist/cli/dispatch/check.js +372 -0
  197. package/dist/cli/dispatch/commands.js +27 -0
  198. package/dist/cli/dispatch/index.js +207 -0
  199. package/dist/cli/dispatch/lifecycle.js +652 -0
  200. package/dist/cli/dispatch/prime.js +139 -0
  201. package/dist/cli/dispatch/projections.js +17 -0
  202. package/dist/cli/dispatch/shared.js +63 -0
  203. package/dist/cli/dispatch/state.js +140 -0
  204. package/dist/cli/dispatch.js +1 -996
  205. package/dist/cli/errors.js +52 -0
  206. package/dist/cli/help.js +390 -43
  207. package/dist/cli/migrationRequired.js +87 -0
  208. package/dist/cli/orientation/attention.js +59 -0
  209. package/dist/cli/orientation/corpusCoverage.js +102 -0
  210. package/dist/cli/orientation.js +444 -173
  211. package/dist/cli/planArtifacts.js +350 -0
  212. package/dist/cli/planEvidence.js +157 -0
  213. package/dist/cli/planLifecycleState.js +36 -0
  214. package/dist/cli/planTaskIndex.js +11 -0
  215. package/dist/cli/preCutoverCommand.js +32 -0
  216. package/dist/cli/prime-blob.js +71 -3
  217. package/dist/cli/profileAcquisition.js +167 -0
  218. package/dist/cli/startupCompletenessContract.js +59 -0
  219. package/dist/cli/stateQuery.js +63 -14
  220. package/dist/cli/structured.js +0 -1
  221. package/dist/cli/todoMarkdown.js +46 -0
  222. package/dist/cli/todoReadinessSelection.js +192 -0
  223. package/dist/cli/todoSeverity.js +18 -0
  224. package/dist/core/atomicWriter.js +20 -0
  225. package/dist/core/developmentChannel.js +1 -0
  226. package/dist/core/developmentInvocation.js +374 -0
  227. package/dist/core/difflib.js +0 -1
  228. package/dist/core/envPaths.js +20 -0
  229. package/dist/core/jsonValue.js +5 -0
  230. package/dist/core/paths.js +0 -1
  231. package/dist/core/pyjson.js +67 -3
  232. package/dist/core/shell.js +4 -0
  233. package/dist/core/skillIdentity.js +23 -0
  234. package/dist/core/sourceRoot.js +9 -12
  235. package/dist/core/text.js +10 -0
  236. package/dist/core/toml.js +0 -1
  237. package/dist/core/yaml.js +8 -1
  238. package/dist/eval/evalSkills.js +30 -26
  239. package/dist/eval/hybridRouteEvaluation.js +155 -0
  240. package/dist/eval/semanticEval.js +43 -20
  241. package/dist/eval/semanticFixtures.js +16 -5
  242. package/dist/hooks/common.js +11 -81
  243. package/dist/hooks/compaction/apply.js +446 -0
  244. package/dist/hooks/compaction/dryRun.js +184 -0
  245. package/dist/hooks/compaction/index.js +22 -0
  246. package/dist/hooks/compaction/parse.js +325 -0
  247. package/dist/hooks/compaction/retention.js +202 -0
  248. package/dist/hooks/compaction/status.js +360 -0
  249. package/dist/hooks/compaction/types.js +5 -0
  250. package/dist/hooks/validateArtifact/agentFacing.js +9 -0
  251. package/dist/hooks/validateArtifact/index.js +92 -0
  252. package/dist/hooks/validateArtifact/markdown.js +145 -0
  253. package/dist/hooks/validateArtifact/schema.js +546 -0
  254. package/dist/hooks/validateArtifact/traversal.js +107 -0
  255. package/dist/hooks/validateArtifact/violations.js +107 -0
  256. package/dist/migrate/v2HandoffManifest.js +452 -0
  257. package/dist/registries/activationContract.js +2 -0
  258. package/dist/registries/activationTuples.js +106 -0
  259. package/dist/registries/artifactProtocolIds.js +78 -0
  260. package/dist/registries/artifactRegistry.js +224 -63
  261. package/dist/registries/artifactSchemaProjection.js +45 -0
  262. package/dist/registries/capabilityContract.js +141 -13
  263. package/dist/registries/evaluatorHandoffContract.js +170 -0
  264. package/dist/registries/evidenceTierContract.js +371 -0
  265. package/dist/registries/glossaryAdviceContract.js +79 -0
  266. package/dist/registries/glossaryCaveatContract.js +67 -0
  267. package/dist/registries/glossaryConsumerContractValidation.js +787 -0
  268. package/dist/registries/glossaryEntryContract.js +757 -0
  269. package/dist/registries/glossaryTermIdentity.js +17 -0
  270. package/dist/registries/glossaryTermOccurrence.js +20 -0
  271. package/dist/registries/hybridRoute.js +274 -0
  272. package/dist/registries/hybridRouteReceipt.js +221 -0
  273. package/dist/registries/packagePublication.js +229 -0
  274. package/dist/registries/packageRegistry.js +187 -211
  275. package/dist/registries/todoReadinessContract.js +448 -0
  276. package/dist/registries/triggerLoader.js +174 -0
  277. package/dist/registries/verbosityBudgetContract.js +205 -0
  278. package/dist/release/releaseMetadata.js +385 -0
  279. package/dist/runtime/lifecycleAdapterContract.js +457 -0
  280. package/dist/runtime/lifecycleAdapters.js +777 -0
  281. package/dist/runtime/lifecycleAuthority.js +453 -0
  282. package/dist/runtime/lifecycleOperationContract.js +123 -0
  283. package/dist/runtime/lifecycleOperations.js +634 -0
  284. package/dist/runtime/lifecycleOwnershipJournal.js +622 -0
  285. package/dist/runtime/lifecyclePublication.js +415 -0
  286. package/dist/runtime/lifecycleSnapshot.js +438 -0
  287. package/dist/runtime/nativeResourceCleanup.js +502 -0
  288. package/dist/setup/opencode.js +20 -0
  289. package/dist/setup/opencodeConstants.js +1 -0
  290. package/dist/setup/sharedSkill.js +45 -0
  291. package/dist/setup/smokeChecks.js +21 -82
  292. package/dist/state/archiveDiscovery.js +580 -0
  293. package/dist/state/archivePublication.js +225 -0
  294. package/dist/state/archiveRecovery.js +237 -0
  295. package/dist/state/archiveReplay.js +53 -0
  296. package/dist/state/canonicalMigrationRecord.js +36 -0
  297. package/dist/state/changelog.js +221 -0
  298. package/dist/state/decisionEntities.js +367 -0
  299. package/dist/state/decisionLegacyValidation.js +215 -0
  300. package/dist/state/decisionMigrationProvenance.js +199 -0
  301. package/dist/state/decisionOverlay.js +254 -0
  302. package/dist/state/decisionRevision.js +256 -0
  303. package/dist/state/decisionRevisionMigration.js +89 -0
  304. package/dist/state/directRetrieval.js +323 -0
  305. package/dist/state/durability.js +324 -0
  306. package/dist/state/entityCutover.js +459 -0
  307. package/dist/state/entityCutoverGit.js +127 -0
  308. package/dist/state/entityGlossaryAuthority.js +13 -0
  309. package/dist/state/entityListProjection.js +187 -0
  310. package/dist/state/entityListRuntimeRegistry.js +85 -0
  311. package/dist/state/entityMigrationCausality.js +97 -0
  312. package/dist/state/entityMigrationIdentity.js +5 -0
  313. package/dist/state/entityMigrationPreview.js +846 -0
  314. package/dist/state/entityMigrationTodo.js +133 -0
  315. package/dist/state/entityPublicationContext.js +806 -0
  316. package/dist/state/entityRetrievalHelp.js +506 -0
  317. package/dist/state/entityStorage.js +896 -0
  318. package/dist/state/exactReplacementRecovery.js +18 -0
  319. package/dist/state/experimentArchive.js +63 -0
  320. package/dist/state/experimentIdentity.js +202 -0
  321. package/dist/state/healthEntities.js +262 -0
  322. package/dist/state/healthEntityValidation.js +18 -0
  323. package/dist/state/healthRepair.js +69 -0
  324. package/dist/state/installRoot.js +64 -25
  325. package/dist/state/legacyEntityCutoverEvidence.js +65 -0
  326. package/dist/state/legacyIdentity.js +47 -0
  327. package/dist/state/legacySummaryRecord.js +6 -0
  328. package/dist/state/listAccounting.js +54 -0
  329. package/dist/state/listClassification.js +17 -0
  330. package/dist/state/listCursor.js +42 -0
  331. package/dist/state/listRetrieval.js +781 -0
  332. package/dist/state/migrationSourceBinding.js +30 -0
  333. package/dist/state/objectiveExperimentEntities.js +322 -0
  334. package/dist/state/planEntities.js +530 -0
  335. package/dist/state/planIdentity.js +47 -0
  336. package/dist/state/planRetrieval.js +313 -0
  337. package/dist/state/planTaskRetrieval.js +294 -0
  338. package/dist/state/progressEntities.js +512 -0
  339. package/dist/state/progressGlossaryCaveat.js +168 -0
  340. package/dist/state/progressPublicationOrder.js +19 -0
  341. package/dist/state/projectRoot.js +62 -0
  342. package/dist/state/projectionPolicy.js +190 -0
  343. package/dist/state/retrievalAuthority.js +156 -0
  344. package/dist/state/safeProjectFile.js +155 -0
  345. package/dist/state/startupAnalysis/benchmark.js +432 -0
  346. package/dist/state/startupAnalysis/contract.js +160 -0
  347. package/dist/state/startupAnalysis/helpers.js +286 -0
  348. package/dist/state/startupAnalysis/index.js +6 -0
  349. package/dist/state/startupAnalysis/metrics.js +340 -0
  350. package/dist/state/startupAnalysis/records.js +198 -0
  351. package/dist/state/startupAnalysis/report.js +111 -0
  352. package/dist/state/startupAnalysis/threshold.js +512 -0
  353. package/dist/state/startupAnalysis.js +2 -1953
  354. package/dist/state/startupProjection.js +499 -0
  355. package/dist/state/stateMode.js +85 -0
  356. package/dist/state/stateStorageAuthority.js +47 -0
  357. package/dist/state/summaryEntityRead.js +25 -0
  358. package/dist/state/summaryMigrationProvenance.js +66 -0
  359. package/dist/state/summarySourceRowAuthority.js +36 -0
  360. package/dist/state/todoDocsEntities.js +1064 -0
  361. package/dist/state/todoDocsEntityValidation.js +158 -0
  362. package/dist/state/todoMarkdownProjection.js +51 -0
  363. package/dist/state/todoReconciliationActivation.js +132 -0
  364. package/dist/state/todoReconciliationInspection.js +173 -0
  365. package/dist/state/todoReconciliationRepair.js +170 -0
  366. package/dist/state/todoReconciliationTransaction.js +582 -0
  367. package/dist/state/write/assign.js +20 -0
  368. package/dist/state/write/candidateMutation.js +269 -0
  369. package/dist/state/write/errors.js +11 -0
  370. package/dist/state/write/experimentPublication.js +192 -0
  371. package/dist/state/write/explain.js +332 -0
  372. package/dist/state/write/fields.js +61 -0
  373. package/dist/state/write/glossaryPublication.js +263 -0
  374. package/dist/state/write/grammar.js +280 -0
  375. package/dist/state/write/helpers.js +29 -0
  376. package/dist/state/write/index.js +12 -0
  377. package/dist/state/write/input.js +367 -0
  378. package/dist/state/write/lock.js +837 -0
  379. package/dist/state/write/mutation.js +234 -0
  380. package/dist/state/write/operations.js +169 -0
  381. package/dist/state/write/planEvaluation.js +128 -0
  382. package/dist/state/write/planPublication.js +179 -0
  383. package/dist/state/write/runtimeOperations.js +142 -0
  384. package/dist/state/write/serialize.js +1 -0
  385. package/dist/state/write/transaction.js +52 -0
  386. package/dist/state/write/validate.js +7 -0
  387. package/dist/upgrade/appContentRefresh.js +383 -0
  388. package/dist/upgrade/appModel.js +8 -7
  389. package/dist/upgrade/atomicWriter.js +1 -0
  390. package/dist/upgrade/bundleEvidence.js +33 -0
  391. package/dist/upgrade/channels.js +12 -8
  392. package/dist/upgrade/compatibility.js +56 -21
  393. package/dist/upgrade/doctor.js +197 -192
  394. package/dist/upgrade/doctorClassifier.js +187 -0
  395. package/dist/upgrade/installedHooksRetirement.js +196 -0
  396. package/dist/upgrade/legacyAgentCleanup.js +282 -0
  397. package/dist/upgrade/lifecycleUpgrade.js +113 -0
  398. package/dist/upgrade/migrateArtifactsV2ToV3.js +367 -149
  399. package/dist/upgrade/migrationPublication.js +122 -0
  400. package/dist/upgrade/nextMajorDoctor.js +155 -0
  401. package/dist/upgrade/npxPlatformStatus.js +22 -0
  402. package/dist/upgrade/projectIntegration.js +145 -187
  403. package/dist/upgrade/projectIntegrationDecision.js +50 -0
  404. package/dist/upgrade/retiredResourceDiagnostics.js +117 -0
  405. package/dist/upgrade/runtimeMigration.js +278 -352
  406. package/dist/upgrade/upgradeCommands.js +14 -1
  407. package/dist/upgrade/upgradeLock.js +85 -0
  408. package/dist/upgrade/upgradeOrchestrator.js +263 -59
  409. package/dist/upgrade/v3CapabilitySurface.js +14 -0
  410. package/dist/upgrade/versionResolution.js +12 -5
  411. package/dist/validate/activationArtifactEvidence.js +844 -0
  412. package/dist/validate/activationConjunction.js +816 -0
  413. package/dist/validate/activationEvidenceManifest.js +515 -0
  414. package/dist/validate/activationPackageSemantics.js +29 -0
  415. package/dist/validate/appHomeContract.js +5 -11
  416. package/dist/validate/bootstrapAuthority.js +44 -0
  417. package/dist/validate/capability.js +144 -15
  418. package/dist/validate/crossCapability.js +15 -10
  419. package/dist/validate/retainedReferenceAuthority.js +879 -0
  420. package/dist/validate/selfAudit.js +73 -37
  421. package/dist/validate/v1LegacyCruft.js +131 -0
  422. package/dist/validate/vocabularyAuthority.js +303 -0
  423. package/package.json +53 -27
  424. package/bundle/references/adapters/cursor.md +0 -213
  425. package/bundle/references/adapters/opencode.md +0 -530
  426. package/bundle/references/adapters/package-manifest-interface-model.yaml +0 -337
  427. package/bundle/references/adapters/runtime-adapter-characterization.md +0 -79
  428. package/bundle/references/adapters/runtime-adapter-interface-model.yaml +0 -200
  429. package/bundle/references/adapters/runtime-adapter-registry.yaml +0 -548
  430. package/bundle/references/adapters/runtime-feature-parity.md +0 -189
  431. package/bundle/references/analysis/benchmark.md +0 -267
  432. package/bundle/references/analysis/startup-measurement-contract.yaml +0 -424
  433. package/bundle/references/cli/agent-ready-state-contract.yaml +0 -953
  434. package/bundle/references/cli/audience-namespace-cli-migration.yaml +0 -355
  435. package/bundle/references/cli/bundle-skill-vocabulary.yaml +0 -278
  436. package/bundle/references/cli/capability-tool-classification.yaml +0 -53
  437. package/bundle/references/cli/routing-execution-vocabulary.yaml +0 -281
  438. package/bundle/references/meta/documentation-inventory.md +0 -43
  439. package/bundle/references/v1-section-mapping.md +0 -47
  440. package/bundle/skills/agentera/.claude-plugin/plugin.json +0 -27
  441. package/bundle/skills/agentera/agents/dokumentera.toml +0 -6
  442. package/bundle/skills/agentera/agents/hej.toml +0 -6
  443. package/bundle/skills/agentera/agents/inspektera.toml +0 -6
  444. package/bundle/skills/agentera/agents/inspirera.toml +0 -6
  445. package/bundle/skills/agentera/agents/optimera.toml +0 -6
  446. package/bundle/skills/agentera/agents/orkestrera.toml +0 -6
  447. package/bundle/skills/agentera/agents/planera.toml +0 -6
  448. package/bundle/skills/agentera/agents/profilera.toml +0 -6
  449. package/bundle/skills/agentera/agents/realisera.toml +0 -6
  450. package/bundle/skills/agentera/agents/resonera.toml +0 -6
  451. package/bundle/skills/agentera/agents/visionera.toml +0 -6
  452. package/bundle/skills/agentera/agents/visualisera.toml +0 -6
  453. package/bundle/skills/agentera/capabilities/dokumentera/instructions.md +0 -428
  454. package/bundle/skills/agentera/capabilities/dokumentera/schemas/artifacts.yaml +0 -73
  455. package/bundle/skills/agentera/capabilities/dokumentera/schemas/triggers.yaml +0 -35
  456. package/bundle/skills/agentera/capabilities/hej/instructions.md +0 -331
  457. package/bundle/skills/agentera/capabilities/hej/schemas/artifacts.yaml +0 -69
  458. package/bundle/skills/agentera/capabilities/hej/schemas/triggers.yaml +0 -58
  459. package/bundle/skills/agentera/capabilities/inspektera/instructions.md +0 -514
  460. package/bundle/skills/agentera/capabilities/inspektera/schemas/artifacts.yaml +0 -76
  461. package/bundle/skills/agentera/capabilities/inspektera/schemas/triggers.yaml +0 -38
  462. package/bundle/skills/agentera/capabilities/inspirera/instructions.md +0 -280
  463. package/bundle/skills/agentera/capabilities/inspirera/schemas/artifacts.yaml +0 -24
  464. package/bundle/skills/agentera/capabilities/inspirera/schemas/triggers.yaml +0 -34
  465. package/bundle/skills/agentera/capabilities/optimera/instructions.md +0 -437
  466. package/bundle/skills/agentera/capabilities/optimera/schemas/triggers.yaml +0 -39
  467. package/bundle/skills/agentera/capabilities/orkestrera/instructions.md +0 -433
  468. package/bundle/skills/agentera/capabilities/orkestrera/schemas/artifacts.yaml +0 -64
  469. package/bundle/skills/agentera/capabilities/orkestrera/schemas/triggers.yaml +0 -42
  470. package/bundle/skills/agentera/capabilities/orkestrera/schemas/validation.yaml +0 -107
  471. package/bundle/skills/agentera/capabilities/planera/instructions.md +0 -368
  472. package/bundle/skills/agentera/capabilities/planera/schemas/artifacts.yaml +0 -62
  473. package/bundle/skills/agentera/capabilities/planera/schemas/triggers.yaml +0 -34
  474. package/bundle/skills/agentera/capabilities/planera/schemas/validation.yaml +0 -61
  475. package/bundle/skills/agentera/capabilities/profilera/instructions.md +0 -419
  476. package/bundle/skills/agentera/capabilities/profilera/schemas/artifacts.yaml +0 -18
  477. package/bundle/skills/agentera/capabilities/profilera/schemas/triggers.yaml +0 -45
  478. package/bundle/skills/agentera/capabilities/profilera/schemas/validation.yaml +0 -57
  479. package/bundle/skills/agentera/capabilities/realisera/instructions.md +0 -403
  480. package/bundle/skills/agentera/capabilities/realisera/schemas/artifacts.yaml +0 -80
  481. package/bundle/skills/agentera/capabilities/realisera/schemas/triggers.yaml +0 -39
  482. package/bundle/skills/agentera/capabilities/realisera/schemas/validation.yaml +0 -110
  483. package/bundle/skills/agentera/capabilities/resonera/instructions.md +0 -329
  484. package/bundle/skills/agentera/capabilities/resonera/schemas/artifacts.yaml +0 -47
  485. package/bundle/skills/agentera/capabilities/resonera/schemas/triggers.yaml +0 -46
  486. package/bundle/skills/agentera/capabilities/resonera/schemas/validation.yaml +0 -77
  487. package/bundle/skills/agentera/capabilities/visionera/instructions.md +0 -309
  488. package/bundle/skills/agentera/capabilities/visionera/schemas/triggers.yaml +0 -41
  489. package/bundle/skills/agentera/capabilities/visualisera/instructions.md +0 -400
  490. package/bundle/skills/agentera/capabilities/visualisera/schemas/triggers.yaml +0 -33
  491. package/bundle/skills/agentera/references/contract.md +0 -1039
  492. package/bundle/skills/hej/.claude-plugin/plugin.json +0 -6
  493. package/bundle/skills/hej/SKILL.md +0 -69
  494. package/bundle/skills/hej/agents/hej.toml +0 -11
  495. package/bundle/skills/hej/agents/openai.yaml +0 -8
  496. package/dist/analytics/extractCorpus.js.map +0 -1
  497. package/dist/analytics/usageStats.js.map +0 -1
  498. package/dist/bin/agentera.js.map +0 -1
  499. package/dist/cli/appContext.js.map +0 -1
  500. package/dist/cli/argvalidate.js.map +0 -1
  501. package/dist/cli/capabilityContext.js.map +0 -1
  502. package/dist/cli/commands/backfill.js +0 -84
  503. package/dist/cli/commands/backfill.js.map +0 -1
  504. package/dist/cli/commands/capability.js.map +0 -1
  505. package/dist/cli/commands/compact.js.map +0 -1
  506. package/dist/cli/commands/doctor.js.map +0 -1
  507. package/dist/cli/commands/lint.js.map +0 -1
  508. package/dist/cli/commands/prime.js.map +0 -1
  509. package/dist/cli/commands/query.js.map +0 -1
  510. package/dist/cli/commands/report.js.map +0 -1
  511. package/dist/cli/commands/schema.js.map +0 -1
  512. package/dist/cli/commands/state.js +0 -1012
  513. package/dist/cli/commands/state.js.map +0 -1
  514. package/dist/cli/commands/upgrade.js.map +0 -1
  515. package/dist/cli/commands/validate.js.map +0 -1
  516. package/dist/cli/commands/verify.js.map +0 -1
  517. package/dist/cli/dispatch.js.map +0 -1
  518. package/dist/cli/help.js.map +0 -1
  519. package/dist/cli/orientation.js.map +0 -1
  520. package/dist/cli/prime-blob.js.map +0 -1
  521. package/dist/cli/stateQuery.js.map +0 -1
  522. package/dist/cli/structured.js.map +0 -1
  523. package/dist/core/difflib.js.map +0 -1
  524. package/dist/core/git.js +0 -43
  525. package/dist/core/git.js.map +0 -1
  526. package/dist/core/paths.js.map +0 -1
  527. package/dist/core/pyjson.js.map +0 -1
  528. package/dist/core/sourceRoot.js.map +0 -1
  529. package/dist/core/toml.js.map +0 -1
  530. package/dist/core/yaml.js.map +0 -1
  531. package/dist/eval/evalSkills.js.map +0 -1
  532. package/dist/eval/semanticEval.js.map +0 -1
  533. package/dist/eval/semanticFixtures.js.map +0 -1
  534. package/dist/hooks/common.js.map +0 -1
  535. package/dist/hooks/compaction.js +0 -935
  536. package/dist/hooks/compaction.js.map +0 -1
  537. package/dist/hooks/cursorPreToolUse.js +0 -19
  538. package/dist/hooks/cursorPreToolUse.js.map +0 -1
  539. package/dist/hooks/cursorSessionStart.js +0 -71
  540. package/dist/hooks/cursorSessionStart.js.map +0 -1
  541. package/dist/hooks/sessionStart.js +0 -209
  542. package/dist/hooks/sessionStart.js.map +0 -1
  543. package/dist/hooks/sessionStop.js +0 -212
  544. package/dist/hooks/sessionStop.js.map +0 -1
  545. package/dist/hooks/validateArtifact.js +0 -933
  546. package/dist/hooks/validateArtifact.js.map +0 -1
  547. package/dist/registries/artifactRegistry.js.map +0 -1
  548. package/dist/registries/capabilityContract.js.map +0 -1
  549. package/dist/registries/packageRegistry.js.map +0 -1
  550. package/dist/registries/runtimeAdapterRegistry.js +0 -315
  551. package/dist/registries/runtimeAdapterRegistry.js.map +0 -1
  552. package/dist/setup/codex.js +0 -1056
  553. package/dist/setup/codex.js.map +0 -1
  554. package/dist/setup/copilot.js +0 -227
  555. package/dist/setup/copilot.js.map +0 -1
  556. package/dist/setup/cursor.js +0 -127
  557. package/dist/setup/cursor.js.map +0 -1
  558. package/dist/setup/doctor.js +0 -1297
  559. package/dist/setup/doctor.js.map +0 -1
  560. package/dist/setup/smokeChecks.js.map +0 -1
  561. package/dist/state/installRoot.js.map +0 -1
  562. package/dist/state/progressCommit.js +0 -289
  563. package/dist/state/progressCommit.js.map +0 -1
  564. package/dist/state/startupAnalysis.js.map +0 -1
  565. package/dist/upgrade/appModel.js.map +0 -1
  566. package/dist/upgrade/channels.js.map +0 -1
  567. package/dist/upgrade/compatibility.js.map +0 -1
  568. package/dist/upgrade/doctor.js.map +0 -1
  569. package/dist/upgrade/migrateArtifactsV1ToV2.js +0 -571
  570. package/dist/upgrade/migrateArtifactsV1ToV2.js.map +0 -1
  571. package/dist/upgrade/migrateArtifactsV2ToV3.js.map +0 -1
  572. package/dist/upgrade/projectIntegration.js.map +0 -1
  573. package/dist/upgrade/runtimeMigration.js.map +0 -1
  574. package/dist/upgrade/upgradeCommands.js.map +0 -1
  575. package/dist/upgrade/upgradeOrchestrator.js.map +0 -1
  576. package/dist/upgrade/versionResolution.js.map +0 -1
  577. package/dist/validate/appHomeContract.js.map +0 -1
  578. package/dist/validate/capability.js.map +0 -1
  579. package/dist/validate/crossCapability.js.map +0 -1
  580. package/dist/validate/lifecycleAdapters.js +0 -772
  581. package/dist/validate/lifecycleAdapters.js.map +0 -1
  582. package/dist/validate/selfAudit.js.map +0 -1
  583. /package/bundle/skills/agentera/capabilities/{dokumentera → document}/schemas/exit.yaml +0 -0
  584. /package/bundle/skills/agentera/capabilities/{inspirera → research}/schemas/exit.yaml +0 -0
  585. /package/bundle/skills/agentera/capabilities/{hej → status}/schemas/exit.yaml +0 -0
@@ -0,0 +1,582 @@
1
+ import { createHash } from "node:crypto";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { loadYamlMapping } from "../core/yaml.js";
5
+ import { canonicalRecordJson } from "./archiveDiscovery.js";
6
+ import { entityExactGetMaxBytes } from "./entityStorage.js";
7
+ import { FILE_REPLACEMENT_METADATA_NAME, FILE_REPLACEMENT_RECOVERY_VERSION, validateEntityRecoveryDirectory, } from "./entityPublicationContext.js";
8
+ import { ExactReplacementConflictError, FileReplacementError } from "./exactReplacementRecovery.js";
9
+ import { TODO_RECONCILIATION_ACTIVATION_PATH } from "./todoReconciliationActivation.js";
10
+ import { reject } from "./write/errors.js";
11
+ const VERSION = "agentera.todoReconciliationTransaction.v1";
12
+ const DIRECTORY = ".agentera/.todo-reconciliation";
13
+ const MAX_JOURNAL_BYTES = 4 * 1024 * 1024;
14
+ const MAX_TARGET_BYTES = 1024 * 1024;
15
+ const MAX_TARGETS = Math.floor(MAX_JOURNAL_BYTES / 32);
16
+ const ENTITY_MODE_MARKER = ".agentera/state-mode.yaml";
17
+ export class InjectedTodoReconciliationInterruption extends Error {
18
+ publishedTargets;
19
+ constructor(publishedTargets) {
20
+ super(`injected TODO reconciliation interruption after ${publishedTargets} target publications`);
21
+ this.publishedTargets = publishedTargets;
22
+ this.name = "InjectedTodoReconciliationInterruption";
23
+ }
24
+ }
25
+ function encode(bytes) {
26
+ return Buffer.from(bytes).toString("base64");
27
+ }
28
+ function decode(bytes) {
29
+ return Buffer.from(bytes, "base64");
30
+ }
31
+ function exactBase64(value) {
32
+ if (typeof value !== "string")
33
+ return false;
34
+ try {
35
+ return encode(decode(value)) === value;
36
+ }
37
+ catch {
38
+ return false;
39
+ }
40
+ }
41
+ export function todoCreateRequestSha256(record) {
42
+ return createHash("sha256")
43
+ .update("agentera.todoCreateRequest.v1\0")
44
+ .update(canonicalRecordJson(record))
45
+ .digest("hex");
46
+ }
47
+ function bytesAt(root, relative) {
48
+ const target = path.join(root, relative);
49
+ return fs.existsSync(target) ? fs.readFileSync(target) : null;
50
+ }
51
+ function same(left, right) {
52
+ return left === null ? right === null : right !== null && left.equals(right);
53
+ }
54
+ function validTarget(relative, publicPath) {
55
+ return relative === publicPath
56
+ || relative === TODO_RECONCILIATION_ACTIVATION_PATH
57
+ || relative === ENTITY_MODE_MARKER
58
+ || /^\.agentera\/entities\/[a-z][a-z0-9_]*\/[a-z][a-z0-9_]*\/[a-z]{10}\.yaml$/.test(relative);
59
+ }
60
+ function createReceiptFromTargets(targets) {
61
+ const created = targets.filter((target) => target.before === null && /^\.agentera\/entities\/todo\/todo_item\/[a-z]{10}\.yaml$/.test(target.path));
62
+ if (!created.length)
63
+ return undefined;
64
+ if (created.length !== 1)
65
+ invalidJournal("TODO reconciliation journal has multiple immutable TODO entity targets");
66
+ const target = created[0];
67
+ const createdId = path.posix.basename(target.path, ".yaml");
68
+ let envelope;
69
+ try {
70
+ envelope = loadYamlMapping(decode(target.after).toString("utf8"));
71
+ }
72
+ catch {
73
+ invalidJournal("TODO reconciliation journal has an invalid created entity envelope");
74
+ }
75
+ if (envelope.id !== createdId || envelope.artifact !== "todo" || !envelope.record || typeof envelope.record !== "object" || Array.isArray(envelope.record)) {
76
+ invalidJournal("TODO reconciliation journal create target does not match its canonical entity envelope");
77
+ }
78
+ const request = structuredClone(envelope.record);
79
+ delete request.reconciliation;
80
+ return { created_id: createdId, request_sha256: todoCreateRequestSha256(request) };
81
+ }
82
+ function invalidJournal(message) {
83
+ reject({
84
+ class: "conflict",
85
+ message,
86
+ recovery: `Preserve '${DIRECTORY}', restore its last valid committed journal bytes, and retry the exact non-dry-run TODO mutation; no target bytes were changed.`,
87
+ });
88
+ }
89
+ function parseJournal(bytes, fileName) {
90
+ if (bytes.length > MAX_JOURNAL_BYTES)
91
+ invalidJournal("TODO reconciliation journal exceeds its byte bound");
92
+ let parsed;
93
+ try {
94
+ parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
95
+ }
96
+ catch {
97
+ invalidJournal("TODO reconciliation journal is not valid bounded UTF-8 JSON");
98
+ }
99
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
100
+ invalidJournal("TODO reconciliation journal is not a mapping");
101
+ const value = parsed;
102
+ const expectedKeys = ["schema_version", "id", "public_path", "mapping_sha256", "targets", ...(value.create === undefined ? [] : ["create"]), ...(value.activation_effect_sha256 === undefined ? [] : ["activation_effect_sha256"])].sort().join(",");
103
+ if (Object.keys(value).sort().join(",") !== expectedKeys
104
+ || value.schema_version !== VERSION
105
+ || typeof value.id !== "string"
106
+ || !/^[a-f0-9]{24}$/.test(value.id)
107
+ || typeof value.public_path !== "string"
108
+ || typeof value.mapping_sha256 !== "string"
109
+ || !/^[a-f0-9]{64}$/.test(value.mapping_sha256)
110
+ || !Array.isArray(value.targets)
111
+ || value.targets.length < 1
112
+ || value.targets.length > MAX_TARGETS)
113
+ invalidJournal("TODO reconciliation journal is malformed");
114
+ if (value.activation_effect_sha256 !== undefined && !/^[a-f0-9]{64}$/.test(value.activation_effect_sha256))
115
+ invalidJournal("TODO reconciliation journal has an invalid activation effect authorization");
116
+ if (value.create !== undefined && (!value.create
117
+ || typeof value.create !== "object"
118
+ || Array.isArray(value.create)
119
+ || Object.keys(value.create).sort().join(",") !== "created_id,request_sha256"
120
+ || typeof value.create.created_id !== "string"
121
+ || !/^[a-z]{10}$/.test(value.create.created_id)
122
+ || typeof value.create.request_sha256 !== "string"
123
+ || !/^[a-f0-9]{64}$/.test(value.create.request_sha256)))
124
+ invalidJournal("TODO reconciliation journal has an invalid create receipt");
125
+ const paths = new Set();
126
+ for (const target of value.targets) {
127
+ if (!target
128
+ || typeof target !== "object"
129
+ || Array.isArray(target)
130
+ || Object.keys(target).sort().join(",") !== "after,before,path"
131
+ || typeof target.path !== "string"
132
+ || !validTarget(target.path, value.public_path)
133
+ || paths.has(target.path)
134
+ || (target.before !== null && !exactBase64(target.before))
135
+ || !exactBase64(target.after)
136
+ || decode(target.after).length > MAX_TARGET_BYTES
137
+ || (target.before !== null && decode(target.before).length > MAX_TARGET_BYTES))
138
+ invalidJournal("TODO reconciliation journal has an invalid target");
139
+ paths.add(target.path);
140
+ }
141
+ const body = value.targets;
142
+ const activates = body.some((target) => target.path === TODO_RECONCILIATION_ACTIVATION_PATH);
143
+ if (!activates && value.activation_effect_sha256 !== undefined)
144
+ invalidJournal("TODO reconciliation journal effect authorization has no activation target");
145
+ const inferredCreate = createReceiptFromTargets(body);
146
+ if (value.create && (!inferredCreate
147
+ || value.create.created_id !== inferredCreate.created_id
148
+ || value.create.request_sha256 !== inferredCreate.request_sha256))
149
+ invalidJournal("TODO reconciliation create receipt does not match its canonical entity target");
150
+ const identity = value.create || value.activation_effect_sha256
151
+ ? { ...(value.create ? { create: value.create } : {}), ...(value.activation_effect_sha256 ? { activation_effect_sha256: value.activation_effect_sha256 } : {}), targets: body }
152
+ : body;
153
+ const expectedId = createHash("sha256").update(canonicalRecordJson(identity)).digest("hex").slice(0, 24);
154
+ if (value.id !== expectedId || (fileName !== undefined && fileName !== `${value.id}.json`)) {
155
+ invalidJournal("TODO reconciliation journal identity does not match its canonical targets");
156
+ }
157
+ const create = value.create ?? inferredCreate;
158
+ return { ...value, ...(create ? { create } : {}) };
159
+ }
160
+ function targetLimit(target, sourceRoot) {
161
+ return target.path.startsWith(".agentera/entities/") ? entityExactGetMaxBytes(sourceRoot) : MAX_TARGET_BYTES;
162
+ }
163
+ function assertBinding(journal, binding) {
164
+ if (journal.public_path !== binding.publicPath || journal.mapping_sha256 !== binding.mappingSha256)
165
+ reject({
166
+ class: "conflict",
167
+ message: "TODO reconciliation mapping changed while a transaction is pending",
168
+ recovery: `Restore the docs mapping that resolves TODO.md to '${journal.public_path}', then retry the exact non-dry-run mutation once; no state was changed.`,
169
+ });
170
+ }
171
+ function fsyncDirectory(directory) {
172
+ if (process.platform === "win32")
173
+ return;
174
+ const fd = fs.openSync(directory, "r");
175
+ try {
176
+ fs.fsyncSync(fd);
177
+ }
178
+ finally {
179
+ fs.closeSync(fd);
180
+ }
181
+ }
182
+ function removeExactRole(file, expected) {
183
+ if (!fs.readFileSync(file).equals(expected))
184
+ throw new Error(`exact replacement recovery role '${file}' changed`);
185
+ fs.unlinkSync(file);
186
+ }
187
+ function parseFileRecoveryMetadata(file) {
188
+ let parsed;
189
+ try {
190
+ const bytes = fs.readFileSync(file);
191
+ if (bytes.length > 1024)
192
+ throw new Error("over bound");
193
+ parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
194
+ }
195
+ catch {
196
+ invalidJournal(`file replacement recovery metadata '${file}' is invalid`);
197
+ }
198
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
199
+ invalidJournal(`file replacement recovery metadata '${file}' is not a mapping`);
200
+ }
201
+ const value = parsed;
202
+ if (Object.keys(value).sort().join(",") !== "after_sha256,before_sha256,schema_version,target_path"
203
+ || value.schema_version !== FILE_REPLACEMENT_RECOVERY_VERSION
204
+ || typeof value.target_path !== "string"
205
+ || typeof value.before_sha256 !== "string"
206
+ || typeof value.after_sha256 !== "string"
207
+ || !/^[a-f0-9]{64}$/.test(value.before_sha256)
208
+ || !/^[a-f0-9]{64}$/.test(value.after_sha256))
209
+ invalidJournal(`file replacement recovery metadata '${file}' has an invalid canonical record`);
210
+ return value;
211
+ }
212
+ function recoveryConflict(target, paths, detail) {
213
+ const boundedPaths = paths.slice(0, 4).map((file) => path.relative(process.cwd(), file).split(path.sep).join("/"));
214
+ reject({
215
+ class: "conflict",
216
+ message: `TODO reconciliation target '${target.path}' conflicts with retained recovery roles: ${detail}`,
217
+ violations: boundedPaths.length ? boundedPaths.map((file) => `preserved recovery role: ${file}`) : undefined,
218
+ recovery: `Preserve the pending journal, canonical competitor, and every listed recovery role. Choose the intended canonical bytes, restore '${target.path}' to the journal's recorded before or after bytes without deleting the competitor copy, then retry the exact non-dry-run mutation once; this rejection changed no bytes.`,
219
+ });
220
+ }
221
+ function recoverImmutablePublicationStage(root, target) {
222
+ if (target.before !== null)
223
+ return;
224
+ const absolute = path.join(root, target.path);
225
+ const directory = path.dirname(absolute);
226
+ if (!fs.existsSync(directory))
227
+ return;
228
+ const name = path.basename(absolute);
229
+ const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
230
+ const pattern = new RegExp(`^\\.${escaped}\\.\\d+\\.[a-f0-9-]+\\.tmp$`);
231
+ const names = fs.readdirSync(directory).filter((candidate) => pattern.test(candidate));
232
+ if (!names.length)
233
+ return;
234
+ if (names.length > 1)
235
+ recoveryConflict(target, names.map((candidate) => path.join(directory, candidate)), "multiple immutable publication stages claim the same target");
236
+ const stage = path.join(directory, names[0]);
237
+ const stat = fs.lstatSync(stage);
238
+ const after = decode(target.after);
239
+ if (!stat.isFile() || stat.isSymbolicLink() || !fs.readFileSync(stage).equals(after)) {
240
+ recoveryConflict(target, [stage], "an immutable publication stage changed");
241
+ }
242
+ const current = bytesAt(root, target.path);
243
+ if (current !== null && !current.equals(after)) {
244
+ recoveryConflict(target, [stage], "the canonical target contains concurrent bytes");
245
+ }
246
+ removeExactRole(stage, after);
247
+ fsyncDirectory(directory);
248
+ }
249
+ function recoverFileReplacementRoles(context, target, entries, recoveryRoot, recoveryRootIdentity, targetDirectory) {
250
+ const before = target.before === null ? null : decode(target.before);
251
+ if (before === null)
252
+ return false;
253
+ const after = decode(target.after);
254
+ const matches = [];
255
+ for (const entry of entries) {
256
+ if (entry.name === ".gitignore")
257
+ continue;
258
+ const directory = path.join(recoveryRoot, entry.name);
259
+ const attemptIdentity = validateEntityRecoveryDirectory(context.validatedRoot, directory, targetDirectory, `private entity recovery attempt '${path.relative(context.pinnedPath(), directory).split(path.sep).join("/")}'`);
260
+ const metadata = path.join(directory, FILE_REPLACEMENT_METADATA_NAME);
261
+ if (!fs.existsSync(metadata))
262
+ continue;
263
+ const value = parseFileRecoveryMetadata(metadata);
264
+ if (value.target_path !== target.path)
265
+ continue;
266
+ if (value.before_sha256 !== createHash("sha256").update(before).digest("hex")
267
+ || value.after_sha256 !== createHash("sha256").update(after).digest("hex"))
268
+ recoveryConflict(target, [metadata], "the role digest does not match the pending journal");
269
+ const roleNames = fs.readdirSync(directory).sort();
270
+ if (roleNames.some((name) => !["original.previous", "replacement.tmp", FILE_REPLACEMENT_METADATA_NAME].includes(name))) {
271
+ recoveryConflict(target, roleNames.map((name) => path.join(directory, name)), "the recovery attempt contains an unknown role");
272
+ }
273
+ const previous = path.join(directory, "original.previous");
274
+ const stage = path.join(directory, "replacement.tmp");
275
+ if (fs.existsSync(previous)) {
276
+ const stat = fs.lstatSync(previous);
277
+ if (!stat.isFile() || stat.isSymbolicLink() || !fs.readFileSync(previous).equals(before)) {
278
+ recoveryConflict(target, [metadata, previous], "the retained baseline role changed");
279
+ }
280
+ }
281
+ if (fs.existsSync(stage)) {
282
+ const stat = fs.lstatSync(stage);
283
+ if (!stat.isFile() || stat.isSymbolicLink() || !fs.readFileSync(stage).equals(after)) {
284
+ recoveryConflict(target, [metadata, stage], "the replacement stage changed");
285
+ }
286
+ }
287
+ matches.push({
288
+ directory,
289
+ identity: attemptIdentity,
290
+ metadata,
291
+ ...(fs.existsSync(previous) ? { previous } : {}),
292
+ ...(fs.existsSync(stage) ? { stage } : {}),
293
+ });
294
+ }
295
+ if (matches.length > 1)
296
+ recoveryConflict(target, matches.map(({ metadata }) => metadata), "multiple recovery attempts claim the same target");
297
+ const match = matches[0];
298
+ if (!match)
299
+ return false;
300
+ const current = bytesAt(context.pinnedPath(), target.path);
301
+ if (!same(current, before) && !same(current, after)) {
302
+ recoveryConflict(target, [match.metadata, ...(match.previous ? [match.previous] : []), ...(match.stage ? [match.stage] : [])], current === null ? "the canonical target is absent" : "the canonical target contains concurrent bytes");
303
+ }
304
+ validateEntityRecoveryDirectory(context.validatedRoot, recoveryRoot, targetDirectory, "private entity recovery root '.agentera/.entity-recovery'", recoveryRootIdentity);
305
+ validateEntityRecoveryDirectory(context.validatedRoot, match.directory, targetDirectory, `private entity recovery attempt '${path.relative(context.pinnedPath(), match.directory).split(path.sep).join("/")}'`, match.identity);
306
+ if (match.stage)
307
+ removeExactRole(match.stage, after);
308
+ if (match.previous)
309
+ removeExactRole(match.previous, before);
310
+ removeExactRole(match.metadata, fs.readFileSync(match.metadata));
311
+ fs.rmdirSync(match.directory);
312
+ fsyncDirectory(recoveryRoot);
313
+ return true;
314
+ }
315
+ function recoverFileReplacement(context, target) {
316
+ if (target.before === null)
317
+ return;
318
+ const recoveryRoot = path.join(context.pinnedPath(), ".agentera/.entity-recovery");
319
+ if (!fs.existsSync(recoveryRoot))
320
+ return;
321
+ const targetDirectory = path.dirname(context.pinnedPath(target.path));
322
+ const recoveryRootIdentity = validateEntityRecoveryDirectory(context.validatedRoot, recoveryRoot, targetDirectory, "private entity recovery root '.agentera/.entity-recovery'");
323
+ const entries = fs.readdirSync(recoveryRoot, { withFileTypes: true });
324
+ if (entries.length > 128)
325
+ invalidJournal("file replacement recovery root exceeds its bounded entry count");
326
+ recoverFileReplacementRoles(context, target, entries, recoveryRoot, recoveryRootIdentity, targetDirectory);
327
+ }
328
+ function applyTarget(context, root, target, sourceRoot, publicPath) {
329
+ const before = target.before === null ? null : decode(target.before);
330
+ const after = decode(target.after);
331
+ recoverImmutablePublicationStage(root, target);
332
+ recoverFileReplacement(context, target);
333
+ const current = bytesAt(root, target.path);
334
+ if (same(current, after))
335
+ return null;
336
+ if (!same(current, before))
337
+ reject({
338
+ class: "conflict",
339
+ message: `TODO reconciliation target '${target.path}' changed after transaction preparation`,
340
+ recovery: "Preserve the pending journal and both repository changes, restore every target to either the recorded before or after bytes, then retry once; no additional state was changed.",
341
+ });
342
+ if (before === null) {
343
+ const identity = context.publishImmutable(target.path, after.toString("utf8"));
344
+ if (!identity)
345
+ reject({
346
+ class: "conflict",
347
+ message: `TODO reconciliation target '${target.path}' appeared during publication`,
348
+ recovery: `Preserve the competing target and retry the exact TODO mutation after reconciling it with the pending transaction; no competing bytes were overwritten.`,
349
+ });
350
+ return identity;
351
+ }
352
+ const replacement = target.path === publicPath
353
+ ? context.replaceVisible(target.path, before, after.toString("utf8"), targetLimit(target, sourceRoot))
354
+ : context.replaceExisting(target.path, before, after.toString("utf8"), targetLimit(target, sourceRoot));
355
+ return replacement.publishedIdentity;
356
+ }
357
+ function rollback(context, applied, sourceRoot, publicPath) {
358
+ const issues = [];
359
+ for (const { target, identity } of [...applied].reverse()) {
360
+ try {
361
+ if (target.before === null) {
362
+ const result = context.removeExact(target.path, identity, false);
363
+ if (result !== "removed")
364
+ throw new Error(`exact removal returned ${result}`);
365
+ }
366
+ else {
367
+ if (target.path === publicPath) {
368
+ context.restoreVisible(target.path, identity, decode(target.before).toString("utf8"), targetLimit(target, sourceRoot));
369
+ }
370
+ else {
371
+ context.restoreExact(target.path, identity, decode(target.before).toString("utf8"), targetLimit(target, sourceRoot));
372
+ }
373
+ }
374
+ }
375
+ catch (error) {
376
+ issues.push({
377
+ path: target.path,
378
+ message: (error instanceof Error ? error.message : String(error)).slice(0, 512),
379
+ retainedPaths: error instanceof ExactReplacementConflictError
380
+ ? error.retainedPaths.slice(0, 8).map((retainedPath) => retainedPath.slice(0, 512))
381
+ : [],
382
+ });
383
+ }
384
+ }
385
+ return issues;
386
+ }
387
+ function rejectIncompleteRollback(primary, issues) {
388
+ const primaryMessage = (primary instanceof Error ? primary.message : String(primary)).slice(0, 512);
389
+ const violations = issues.slice(0, 8).map(({ path: targetPath, message }) => `rollback target '${targetPath}': ${message}`);
390
+ const retained = [...new Set(issues.flatMap(({ retainedPaths }) => retainedPaths))].slice(0, 8);
391
+ violations.push(...retained.map((role) => `preserved recovery role: ${role}`));
392
+ reject({
393
+ class: "conflict",
394
+ message: `TODO reconciliation attempted rollback for every published target after '${primaryMessage}', but ${issues.length} target${issues.length === 1 ? "" : "s"} could not be restored`,
395
+ violations,
396
+ recovery: "Preserve the pending journal, each listed canonical target, and every listed recovery role. Targets not listed were restored. Reconcile each listed target to the journal's recorded before or after bytes without deleting concurrent bytes, then retry the exact non-dry-run mutation once.",
397
+ });
398
+ }
399
+ function rejectPublicationFailure(error, pendingJournal) {
400
+ reject({
401
+ class: "unsupported_target",
402
+ message: `recoverable complete-file replacement is unavailable for this target${error.code ? ` (${error.code})` : ""}`,
403
+ violations: [error.message.slice(0, 512)],
404
+ recovery: `${pendingJournal ? "Preserve the pending journal. " : ""}Use an owner-controlled regular file on the project-state filesystem with standard rename support, correct the reported capability or permission, then retry the exact non-dry-run mutation; all attempted target bytes were restored.`,
405
+ });
406
+ }
407
+ function rejectReplacementConflict(error) {
408
+ reject({
409
+ class: "conflict",
410
+ message: `TODO reconciliation retained a concurrent target without overwriting it: ${error.message.slice(0, 1024)}`,
411
+ violations: error.retainedPaths.slice(0, 4).map((role) => `preserved recovery role: ${role.slice(0, 512)}`),
412
+ recovery: "Preserve the pending journal, canonical competitor, and listed recovery roles. Choose the intended canonical bytes, restore the conflicted target to the journal's recorded before or after bytes without deleting the competitor copy, then retry the exact non-dry-run mutation once; no competitor bytes were overwritten.",
413
+ });
414
+ }
415
+ function journalPath(id) {
416
+ return `${DIRECTORY}/${id}.json`;
417
+ }
418
+ function finishJournal(context, relative, identity) {
419
+ if (context.removeExact(relative, identity) !== "removed")
420
+ throw new Error(`TODO reconciliation journal '${relative}' changed before cleanup`);
421
+ }
422
+ export function inspectTodoReconciliation(root, binding) {
423
+ const directory = path.join(root, DIRECTORY);
424
+ if (!fs.existsSync(directory))
425
+ return [];
426
+ const names = fs.readdirSync(directory).filter((name) => name.endsWith(".json")).sort();
427
+ if (names.length > 1)
428
+ reject({ class: "conflict", message: "multiple pending TODO reconciliation journals exist", recovery: "Preserve the journals and reconcile them to one transaction before retrying; no state was changed." });
429
+ return names.map((name) => { const journal = parseJournal(fs.readFileSync(path.join(directory, name)), name); assertBinding(journal, binding); return journal.id; });
430
+ }
431
+ export function recoverTodoReconciliation(context, sourceRoot, binding, options = {}) {
432
+ const root = context.pinnedPath();
433
+ const directory = path.join(root, DIRECTORY);
434
+ if (!fs.existsSync(directory))
435
+ return [];
436
+ const names = fs.readdirSync(directory).filter((name) => name.endsWith(".json")).sort();
437
+ if (names.length > 1)
438
+ reject({ class: "conflict", message: "multiple pending TODO reconciliation journals exist", recovery: "Preserve the journals and reconcile them to one transaction before retrying; no state was changed." });
439
+ const recovered = [];
440
+ for (const name of names) {
441
+ const relative = `${DIRECTORY}/${name}`;
442
+ const journalBytes = fs.readFileSync(path.join(root, relative));
443
+ const journal = parseJournal(journalBytes, name);
444
+ assertBinding(journal, binding);
445
+ if (journal.create && options.createRequestSha256 !== journal.create.request_sha256)
446
+ reject({
447
+ class: "conflict",
448
+ message: `pending TODO create for '${journal.create.created_id}' does not match this request`,
449
+ recovery: `Retry the exact original TODO create input to recover '${journal.create.created_id}'; no transaction target bytes were changed.`,
450
+ });
451
+ if (journal.activation_effect_sha256 && options.activationEffectSha256 !== journal.activation_effect_sha256)
452
+ reject({
453
+ class: "conflict",
454
+ message: "pending TODO activation does not match the authorized preview effect",
455
+ recovery: "Retry the exact activation apply command returned by the original preview; no transaction target bytes were changed.",
456
+ });
457
+ options.beforeRecovery?.(journal.targets.map((target) => ({
458
+ path: target.path,
459
+ before: target.before === null ? null : decode(target.before),
460
+ after: decode(target.after),
461
+ })));
462
+ const applied = [];
463
+ try {
464
+ for (const target of journal.targets) {
465
+ if (target.path === ENTITY_MODE_MARKER)
466
+ options.beforeActivation?.();
467
+ const identity = applyTarget(context, root, target, sourceRoot, journal.public_path);
468
+ if (identity)
469
+ applied.push({ target, identity });
470
+ }
471
+ options.beforeCommit?.();
472
+ context.assertValid();
473
+ const journalIdentity = context.replaceExisting(relative, journalBytes, journalBytes.toString("utf8"), MAX_JOURNAL_BYTES).publishedIdentity;
474
+ finishJournal(context, relative, journalIdentity);
475
+ recovered.push({
476
+ transaction_id: journal.id,
477
+ target_count: journal.targets.length,
478
+ ...(journal.create ? { create: journal.create } : {}),
479
+ });
480
+ }
481
+ catch (error) {
482
+ const rollbackIssues = applied.length ? rollback(context, applied, sourceRoot, journal.public_path) : [];
483
+ if (rollbackIssues.length)
484
+ rejectIncompleteRollback(error, rollbackIssues);
485
+ if (error instanceof ExactReplacementConflictError)
486
+ rejectReplacementConflict(error);
487
+ if (error instanceof FileReplacementError)
488
+ rejectPublicationFailure(error, true);
489
+ throw error;
490
+ }
491
+ }
492
+ return recovered;
493
+ }
494
+ export function publishTodoReconciliation(context, sourceRoot, binding, targets, options = {}) {
495
+ const normalized = targets
496
+ .filter((target) => options.retainUnchangedTargets || !same(target.before, Buffer.from(target.after)))
497
+ .sort((left, right) => Number(left.path === ENTITY_MODE_MARKER) - Number(right.path === ENTITY_MODE_MARKER)
498
+ || Number(left.path === binding.publicPath) - Number(right.path === binding.publicPath)
499
+ || left.path.localeCompare(right.path));
500
+ const body = normalized.map((target) => ({ path: target.path, before: target.before === null ? null : encode(target.before), after: encode(target.after) }));
501
+ if (options.activationEffectSha256 && !normalized.some((target) => target.path === TODO_RECONCILIATION_ACTIVATION_PATH))
502
+ reject({ class: "schema_violation", message: "TODO activation authorization requires its activation target", recovery: "Recompute the complete activation target set from a fresh dry-run; no state was changed." });
503
+ const identity = options.create || options.activationEffectSha256
504
+ ? { ...(options.create ? { create: options.create } : {}), ...(options.activationEffectSha256 ? { activation_effect_sha256: options.activationEffectSha256 } : {}), targets: body }
505
+ : body;
506
+ const id = createHash("sha256").update(canonicalRecordJson(identity)).digest("hex").slice(0, 24);
507
+ if (!normalized.length)
508
+ return { id, targetCount: 0 };
509
+ if (body.length > MAX_TARGETS
510
+ || new Set(body.map(({ path: targetPath }) => targetPath)).size !== body.length
511
+ || body.some((target) => !validTarget(target.path, binding.publicPath)))
512
+ reject({
513
+ class: "schema_violation",
514
+ message: "TODO reconciliation transaction has invalid or duplicate bounded targets",
515
+ recovery: "Reduce the managed TODO working set or cutover entity inventory below the declared journal bounds and retry; no state was changed.",
516
+ });
517
+ const publicTarget = normalized.find((target) => target.path === binding.publicPath && target.before !== null);
518
+ if (publicTarget) {
519
+ const root = context.pinnedPath();
520
+ const publicDevice = fs.statSync(path.dirname(path.join(root, binding.publicPath)), { bigint: true }).dev;
521
+ const recoveryDevice = fs.statSync(path.join(root, ".agentera"), { bigint: true }).dev;
522
+ if (publicDevice !== recoveryDevice)
523
+ reject({
524
+ class: "unsupported_target",
525
+ message: `mapped TODO target '${binding.publicPath}' is on a different filesystem from its private recovery root`,
526
+ recovery: "Map TODO.md to a regular file on the project-state filesystem, then retry the exact mutation; no journal or target bytes were changed.",
527
+ });
528
+ }
529
+ const journal = {
530
+ schema_version: VERSION,
531
+ id,
532
+ public_path: binding.publicPath,
533
+ mapping_sha256: binding.mappingSha256,
534
+ ...(options.create ? { create: options.create } : {}),
535
+ ...(options.activationEffectSha256 ? { activation_effect_sha256: options.activationEffectSha256 } : {}),
536
+ targets: body,
537
+ };
538
+ const bytes = `${JSON.stringify(journal)}\n`;
539
+ if (Buffer.byteLength(bytes) > MAX_JOURNAL_BYTES)
540
+ reject({ class: "schema_violation", message: "TODO reconciliation transaction exceeds its byte bound", recovery: "Reduce the managed TODO working set below the declared transaction bound and retry; no state was changed." });
541
+ const relativeJournal = journalPath(id);
542
+ const journalIdentity = context.publishImmutable(relativeJournal, bytes);
543
+ if (!journalIdentity)
544
+ reject({
545
+ class: "conflict",
546
+ message: `TODO reconciliation journal '${id}' already exists`,
547
+ recovery: "Retry the exact non-dry-run TODO mutation once so the existing journal is inspected and recovered before another transaction is prepared; no target bytes were changed.",
548
+ });
549
+ if (options.interruptAfterTarget === 0)
550
+ throw new InjectedTodoReconciliationInterruption(0);
551
+ const applied = [];
552
+ try {
553
+ for (const target of journal.targets) {
554
+ if (target.path === ENTITY_MODE_MARKER)
555
+ options.beforeActivation?.();
556
+ const identity = applyTarget(context, context.pinnedPath(), target, sourceRoot, journal.public_path);
557
+ if (identity)
558
+ applied.push({ target, identity });
559
+ if (options.interruptAfterTarget === applied.length)
560
+ throw new InjectedTodoReconciliationInterruption(applied.length);
561
+ }
562
+ options.beforeCommit?.();
563
+ context.assertValid();
564
+ finishJournal(context, relativeJournal, journalIdentity);
565
+ return { id, targetCount: normalized.length };
566
+ }
567
+ catch (error) {
568
+ if (error instanceof InjectedTodoReconciliationInterruption)
569
+ throw error;
570
+ const rollbackIssues = rollback(context, applied, sourceRoot, journal.public_path);
571
+ if (rollbackIssues.length)
572
+ rejectIncompleteRollback(error, rollbackIssues);
573
+ if (error instanceof ExactReplacementConflictError)
574
+ rejectReplacementConflict(error);
575
+ if (error instanceof FileReplacementError) {
576
+ finishJournal(context, relativeJournal, journalIdentity);
577
+ rejectPublicationFailure(error, false);
578
+ }
579
+ finishJournal(context, relativeJournal, journalIdentity);
580
+ throw error;
581
+ }
582
+ }
@@ -0,0 +1,20 @@
1
+ import { yamlEntryNumber } from "../../hooks/compaction/index.js";
2
+ function list(doc, key) {
3
+ return Array.isArray(doc[key]) ? doc[key] : [];
4
+ }
5
+ export function nextEntryNumber(doc, activeKey) {
6
+ const numbers = [...list(doc, activeKey), ...list(doc, "archive")].map(yamlEntryNumber);
7
+ return Math.max(0, ...numbers) + 1;
8
+ }
9
+ export function nextTaskNumber(doc) {
10
+ return Math.max(0, ...list(doc, "tasks").map(yamlEntryNumber)) + 1;
11
+ }
12
+ export function localDate(now = new Date()) {
13
+ const y = now.getFullYear();
14
+ const m = String(now.getMonth() + 1).padStart(2, "0");
15
+ const d = String(now.getDate()).padStart(2, "0");
16
+ return `${y}-${m}-${d}`;
17
+ }
18
+ export function localTimestamp(now = new Date()) {
19
+ return `${localDate(now)} ${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`;
20
+ }