dsh-tower 2.1.0-beta.1 → 2.3.0

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 (188) hide show
  1. package/CHANGELOG.md +154 -0
  2. package/COMPATIBILITY.md +6 -1
  3. package/CONTRIBUTING.md +71 -5
  4. package/PRINCIPLES.md +145 -0
  5. package/README.en.md +14 -5
  6. package/README.md +14 -5
  7. package/SECURITY.md +6 -0
  8. package/adapters/archive.js +279 -0
  9. package/adapters/caseSensitivity.js +66 -0
  10. package/adapters/default.js +51 -8
  11. package/{lib → adapters}/git.js +1 -1
  12. package/{lib → adapters}/leases.js +15 -6
  13. package/{lib → adapters}/legacy.js +20 -6
  14. package/adapters/persistence.js +543 -0
  15. package/adapters/stateFile.js +99 -0
  16. package/adapters/store-fs.js +28 -1
  17. package/adapters/store.js +204 -0
  18. package/{lib → adapters}/tests.js +15 -7
  19. package/adapters/vcs-git.js +15 -1
  20. package/{lib → adapters}/workspaceLock.js +1 -1
  21. package/{lib → adapters}/worktreeOwnership.js +18 -7
  22. package/app/archive.js +188 -0
  23. package/app/batch.js +9 -10
  24. package/app/board.js +4 -4
  25. package/app/checkCompletion.js +23 -11
  26. package/app/enrichedMissions.js +2 -4
  27. package/app/findings.js +6 -7
  28. package/app/gate.js +32 -15
  29. package/app/init.js +59 -22
  30. package/app/merge.js +64 -51
  31. package/app/messages.js +7 -8
  32. package/app/mission.js +7 -5
  33. package/app/plan.js +20 -9
  34. package/app/provision.js +12 -14
  35. package/app/read.js +65 -6
  36. package/app/rebase.js +14 -16
  37. package/app/recording.js +7 -8
  38. package/app/review.js +17 -8
  39. package/app/roster.js +14 -15
  40. package/{lib → app}/spawn-prechecks.js +4 -3
  41. package/app/spawn.js +12 -13
  42. package/app/teardown.js +28 -8
  43. package/app/tower.js +121 -39
  44. package/docs/README.md +6 -2
  45. package/docs/adr/0001-ports-adapters-as-data.md +49 -0
  46. package/docs/adr/0002-single-state-json.md +50 -0
  47. package/docs/adr/0003-allow-agent-control-default-true.md +48 -0
  48. package/docs/adr/0004-surface-budget.md +50 -0
  49. package/docs/adr/README.md +51 -0
  50. package/docs/agents/domain.md +38 -0
  51. package/docs/agents/issue-tracker.md +46 -0
  52. package/docs/agents/triage-labels.md +15 -0
  53. package/docs/agents/workflow.md +51 -0
  54. package/docs/architecture/overview.md +170 -37
  55. package/docs/guide/hot-reload.md +1 -1
  56. package/docs/guide/install-upgrade-migration.md +18 -1
  57. package/docs/guide/release.md +1 -1
  58. package/docs/operations/incident.md +82 -0
  59. package/docs/operations/runbook.md +12 -3
  60. package/docs/reference/blockers.md +3 -3
  61. package/docs/reference/config.generated.md +5 -0
  62. package/docs/reference/config.md +4 -0
  63. package/docs/reference/doctor.md +104 -8
  64. package/docs/reference/errors.generated.md +41 -35
  65. package/docs/reference/errors.md +54 -40
  66. package/docs/reference/events.md +38 -6
  67. package/docs/reference/surface-budget.md +128 -0
  68. package/docs/reference/tools.generated.md +9 -8
  69. package/docs/reference/tools.md +9 -8
  70. package/docs/zh/guide/hot-reload.md +1 -1
  71. package/docs/zh/guide/install-upgrade-migration.md +13 -1
  72. package/docs/zh/reference/blockers.md +3 -3
  73. package/docs/zh/reference/config.md +4 -0
  74. package/docs/zh/reference/doctor.md +63 -2
  75. package/docs/zh/reference/errors.md +4 -2
  76. package/docs/zh/reference/tools.md +6 -6
  77. package/domain/batch.js +2 -2
  78. package/domain/config/schema.js +51 -4
  79. package/domain/contracts/outputs.js +33 -3
  80. package/domain/contracts/tool-inputs/missions.js +2 -1
  81. package/domain/contracts/tool-inputs/ops.js +1 -0
  82. package/domain/errors.js +297 -40
  83. package/domain/events.js +207 -0
  84. package/domain/integration/gate.js +41 -12
  85. package/domain/integration/init.js +40 -4
  86. package/domain/integration/merge.js +35 -0
  87. package/domain/lockBudget.js +30 -0
  88. package/domain/mission.js +1 -1
  89. package/domain/missions/completion.js +72 -5
  90. package/domain/missions/lifecycle.js +11 -4
  91. package/domain/missions/plan.js +14 -0
  92. package/domain/missions/review.js +90 -7
  93. package/domain/planning.js +6 -3
  94. package/domain/read/views.js +17 -1
  95. package/domain/report.js +9 -1
  96. package/domain/scope.js +83 -11
  97. package/domain/state/archive.js +257 -0
  98. package/domain/state/migrations.js +145 -0
  99. package/domain/state/schema.js +6 -0
  100. package/domain/state.js +154 -4
  101. package/domain/summary.js +2 -0
  102. package/domain/surface.js +248 -0
  103. package/host/doctor.js +555 -0
  104. package/{lib → host}/modeStore.js +1 -1
  105. package/{lib → host}/tool-registry.js +106 -31
  106. package/host/tower.js +32 -0
  107. package/index.js +12 -9
  108. package/package.json +10 -3
  109. package/ports/archive.js +18 -0
  110. package/ports/caseSensitivity.js +15 -0
  111. package/ports/clock.js +10 -2
  112. package/ports/config.js +19 -0
  113. package/ports/contract.js +38 -0
  114. package/ports/events.js +24 -0
  115. package/ports/ids.js +10 -2
  116. package/ports/index.js +54 -2
  117. package/ports/ownership.js +17 -0
  118. package/ports/state.js +16 -0
  119. package/ports/store.js +52 -3
  120. package/ports/vcs.js +25 -4
  121. package/scripts/architecture-waivers.json +19 -0
  122. package/scripts/architecture.mjs +634 -23
  123. package/scripts/check-docs.mjs +8 -35
  124. package/scripts/check-pack.mjs +68 -39
  125. package/scripts/check-philosophy.mjs +266 -0
  126. package/scripts/domain-metrics.mjs +13 -4
  127. package/scripts/generate-config-reference.mjs +14 -1
  128. package/scripts/generate-error-reference.mjs +68 -14
  129. package/scripts/generate-events-reference.mjs +83 -0
  130. package/scripts/generate-tools-reference.mjs +11 -0
  131. package/scripts/issue-audit.mjs +2 -2
  132. package/scripts/lib/surface.mjs +87 -0
  133. package/scripts/pack-manifest.txt +64 -19
  134. package/scripts/regression-audit.mjs +164 -0
  135. package/scripts/release-check.mjs +1 -1
  136. package/scripts/surface-baseline.json +21 -0
  137. package/scripts/surface-baseline.mjs +120 -0
  138. package/tools/adopt.js +2 -3
  139. package/tools/batch.js +2 -3
  140. package/tools/complete.js +3 -4
  141. package/tools/diff.js +3 -3
  142. package/tools/doctor.js +7 -10
  143. package/tools/finding.js +2 -3
  144. package/tools/findings.js +3 -3
  145. package/tools/import-legacy.js +3 -5
  146. package/tools/inbox.js +3 -3
  147. package/tools/index.js +7 -7
  148. package/tools/init.js +4 -7
  149. package/tools/interrupt.js +2 -3
  150. package/tools/legacy-map.js +3 -5
  151. package/tools/merge.js +3 -3
  152. package/tools/mission.js +2 -3
  153. package/tools/plan.js +7 -6
  154. package/tools/preflight.js +3 -3
  155. package/tools/rebase.js +3 -3
  156. package/tools/recover.js +38 -13
  157. package/tools/reload.js +3 -6
  158. package/tools/resource.js +3 -5
  159. package/tools/review.js +3 -4
  160. package/tools/roster.js +2 -3
  161. package/tools/send.js +2 -2
  162. package/tools/spawn.js +8 -5
  163. package/tools/status.js +16 -8
  164. package/tools/teardown.js +3 -4
  165. package/tools/test.js +2 -2
  166. package/types/index.d.ts +35 -1
  167. package/ui-bundle/README.md +37 -3
  168. package/ui-bundle/client.cards.js +356 -0
  169. package/ui-bundle/client.denied.js +142 -0
  170. package/ui-bundle/client.dock.js +333 -0
  171. package/ui-bundle/client.helpers.js +271 -0
  172. package/ui-bundle/client.js +79 -1747
  173. package/ui-bundle/client.locales.js +247 -0
  174. package/ui-bundle/client.mode.js +206 -0
  175. package/ui-bundle/client.overlay.js +64 -0
  176. package/ui-bundle/client.styles.js +151 -0
  177. package/ui-bundle/client.toolview.js +82 -0
  178. package/ui-bundle/package.json +1 -0
  179. package/lib/doctor.js +0 -270
  180. package/lib/persistence.js +0 -349
  181. package/lib/store.js +0 -118
  182. /package/{lib → app}/briefing.js +0 -0
  183. /package/{lib → app}/spawn-support.js +0 -0
  184. /package/{lib → host}/compatibility.js +0 -0
  185. /package/{lib → host}/config.js +0 -0
  186. /package/{lib → host}/hmr.js +0 -0
  187. /package/{lib → host}/modeState.js +0 -0
  188. /package/{lib → host}/presets.js +0 -0
package/ports/store.js CHANGED
@@ -1,11 +1,60 @@
1
- // Store port (#56). Implementation: adapters/store-fs.js.
1
+ // Store port (#69). Implementation: adapters/store-fs.js.
2
+ //
3
+ // App use cases depend on this contract, not on adapters/store.js: they receive the
4
+ // implementation through the composition root and never import the adapter.
5
+ // The contract lists every method app/** and tools/** call, so an implementation
6
+ // that is missing one fails `assertPorts` at construction instead of mid-mission.
7
+ import { assertPort, definePort } from './contract.js'
8
+
2
9
  /**
3
10
  * @typedef {object} StorePort
11
+ * @property {(commonDir: string) => { dir: string, state: string, lock: string, gitLock: string, activity: string }} pathsFor
4
12
  * @property {(file: string) => Promise<boolean>} exists
5
13
  * @property {(dir: string) => Promise<void>} ensureDir
6
14
  * @property {(file: string) => Promise<any>} readJson
7
15
  * @property {(file: string, value: unknown) => Promise<void>} writeJsonAtomic
8
16
  * @property {(file: string, value: unknown) => Promise<void>} appendJsonl
9
- * @property {(paths: object, fn: () => Promise<any>, options?: object) => Promise<any>} withLock
17
+ * @property {(paths: object, fn: (paths: object) => Promise<any>, options?: object) => Promise<any>} withLock
18
+ * @property {(paths: object, fn: (paths: object) => Promise<any>, options?: object) => Promise<any>} withGitLock
19
+ * @property {(file: string, limit?: number) => Promise<any[]>} readActivityTail
20
+ * @property {(file: string) => Promise<string>} readText
21
+ * @property {(file: string, text: string, encoding?: string) => Promise<void>} writeText
22
+ * @property {(file: string, text: string, encoding?: string) => Promise<void>} appendText
23
+ * @property {(from: string, to: string) => Promise<void>} rename
24
+ * @property {(from: string, to: string) => Promise<void>} renameWithRetry
25
+ * @property {(file: string) => Promise<{ mtimeMs: number }>} stat
26
+ * @property {(file: string) => Promise<void>} unlink
27
+ * @property {(paths: object, options?: object) => Promise<{ record: any, raw: string | null }>} readGitLock
28
+ * @property {(lock: { record: any } | null, options?: object) => { held: boolean, pid?: number | null, phase?: string | null, heldMs?: number }} gitLockView
10
29
  */
11
- export {}
30
+
31
+ // `rename` and `renameWithRetry` are both declared because they are not
32
+ // interchangeable: `renameWithRetry` has temp-file semantics and on a terminal
33
+ // failure it unlinks its source, which is right for a disposable temp file but
34
+ // would delete the bytes `tower_recover` must keep auditable. The audit rename
35
+ // therefore uses the plain `rename` primitive (see tools/recover.js).
36
+ export const STORE_PORT = definePort('StorePort', [
37
+ 'pathsFor',
38
+ 'exists',
39
+ 'ensureDir',
40
+ 'readJson',
41
+ 'writeJsonAtomic',
42
+ 'appendJsonl',
43
+ 'withLock',
44
+ 'withGitLock',
45
+ 'readActivityTail',
46
+ 'readText',
47
+ 'writeText',
48
+ 'appendText',
49
+ 'rename',
50
+ 'renameWithRetry',
51
+ 'stat',
52
+ 'unlink',
53
+ 'readGitLock',
54
+ 'gitLockView',
55
+ ])
56
+
57
+ /** @param {unknown} impl */
58
+ export function assertStorePort(impl) {
59
+ return /** @type {StorePort} */ (assertPort(impl, STORE_PORT, 'store'))
60
+ }
package/ports/vcs.js CHANGED
@@ -1,11 +1,32 @@
1
- // Vcs port (#56). Implementation: adapters/vcs-git.js.
1
+ // Vcs port (#69). Implementation: adapters/vcs-git.js.
2
+ import { assertPort, definePort } from './contract.js'
3
+
2
4
  /**
3
5
  * @typedef {object} VcsPort
4
6
  * @property {(cwd: string, args: string[], options?: object) => Promise<string>} git
5
7
  * @property {(cwd: string, args: string[], options?: object) => Promise<string|null>} tryGit
6
8
  * @property {(cwd: string, ref: string) => Promise<string>} revParse
7
9
  * @property {(cwd: string) => Promise<boolean>} isClean
8
- * @property {(cwd: string, a: string, b: string) => Promise<boolean>} isAncestor
9
- * @property {(repoRoot: string) => Promise<{root:string, commonDir:string, branch:string|null}>} resolveRepo
10
+ * @property {(cwd: string, ancestor: string, descendant: string) => Promise<boolean>} isAncestor
11
+ * @property {(repoRoot: string) => Promise<{ root: string, commonDir: string, branch: string|null }>} resolveRepo
12
+ * @property {(cwd: string) => Promise<string|null>} currentBranch
13
+ * @property {(cwd: string, fromRef: string) => Promise<number>} countCommits
14
+ * @property {(cwd: string) => Promise<Array<{ path: string, branch?: string, head?: string }>>} listWorktrees
10
15
  */
11
- export {}
16
+
17
+ export const VCS_PORT = definePort('VcsPort', [
18
+ 'git',
19
+ 'tryGit',
20
+ 'revParse',
21
+ 'isClean',
22
+ 'isAncestor',
23
+ 'resolveRepo',
24
+ 'currentBranch',
25
+ 'countCommits',
26
+ 'listWorktrees',
27
+ ])
28
+
29
+ /** @param {unknown} impl */
30
+ export function assertVcsPort(impl) {
31
+ return /** @type {VcsPort} */ (assertPort(impl, VCS_PORT, 'vcs'))
32
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "$comment": "Justified architecture-gate exemptions (#80). Every entry needs rule, path, reason, and owner or ref. Scripts/architecture.mjs fails with waiver-contract when an entry is not justified. domain-pure, host-scope and no-lib-from-core cannot be waived at all, and domain/** accepts no waiver. Since #70 the retired lib/ layer has no waivers: host/** owns ambient state by rule, and only the two I/O adapters below are exempt.",
3
+ "waivers": [
4
+ {
5
+ "rule": "child-process-surface",
6
+ "path": "adapters/vcs-git.js",
7
+ "reason": "The git adapter is the single process-spawning boundary; no other module implements VcsPort with a child process.",
8
+ "owner": "louifinn",
9
+ "ref": "#50"
10
+ },
11
+ {
12
+ "rule": "fs-surface",
13
+ "path": "adapters/store-fs.js",
14
+ "reason": "The filesystem adapter is the single node:fs boundary; the store port needs atomic writes, lock files, and raw store reads.",
15
+ "owner": "louifinn",
16
+ "ref": "#50"
17
+ }
18
+ ]
19
+ }