supipowers 1.5.3 → 2.0.1

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 (340) hide show
  1. package/README.md +14 -8
  2. package/bin/install.mjs +20 -5
  3. package/bin/install.ts +95 -0
  4. package/package.json +8 -4
  5. package/skills/context-mode/SKILL.md +17 -10
  6. package/skills/harness/SKILL.md +94 -0
  7. package/skills/ui-design/SKILL.md +63 -0
  8. package/skills/ui-design/sub-agent-templates/component-builder.md +29 -0
  9. package/skills/ui-design/sub-agent-templates/design-critic.md +46 -0
  10. package/skills/ui-design/sub-agent-templates/pencil/component-builder.md +29 -0
  11. package/skills/ui-design/sub-agent-templates/pencil/design-critic.md +42 -0
  12. package/skills/ui-design/sub-agent-templates/pencil/section-assembler.md +27 -0
  13. package/skills/ui-design/sub-agent-templates/section-assembler.md +27 -0
  14. package/skills/ultraplan-discover/SKILL.md +96 -0
  15. package/skills/ultraplan-intake/SKILL.md +89 -0
  16. package/skills/ultraplan-research/SKILL.md +129 -0
  17. package/skills/ultraplan-review/SKILL.md +86 -0
  18. package/skills/ultraplan-review-scope/SKILL.md +111 -0
  19. package/skills/ultraplan-review-structure/SKILL.md +120 -0
  20. package/skills/ultraplan-review-tdd/SKILL.md +142 -0
  21. package/skills/ultraplan-scout/SKILL.md +110 -0
  22. package/skills/ultraplan-synthesize/SKILL.md +124 -0
  23. package/src/{quality/ai-session.ts → ai/final-message.ts} +27 -0
  24. package/src/ai/schema-text.ts +129 -0
  25. package/src/ai/structured-output.ts +274 -0
  26. package/src/ai/template.ts +27 -0
  27. package/src/bootstrap.ts +63 -28
  28. package/src/commands/agents.ts +131 -42
  29. package/src/commands/ai-review.ts +251 -30
  30. package/src/commands/clear.ts +434 -0
  31. package/src/commands/commit.ts +1 -0
  32. package/src/commands/config.ts +242 -44
  33. package/src/commands/context.ts +55 -28
  34. package/src/commands/doctor.ts +234 -6
  35. package/src/commands/fix-pr.ts +306 -131
  36. package/src/commands/generate.ts +111 -21
  37. package/src/commands/memory.ts +192 -0
  38. package/src/commands/model-picker.ts +28 -21
  39. package/src/commands/model.ts +18 -8
  40. package/src/commands/optimize-context.ts +408 -29
  41. package/src/commands/plan.ts +2 -0
  42. package/src/commands/qa.ts +312 -137
  43. package/src/commands/release.ts +259 -76
  44. package/src/commands/review.ts +293 -59
  45. package/src/commands/status.ts +200 -13
  46. package/src/commands/supi.ts +3 -35
  47. package/src/commands/ui-design.ts +394 -0
  48. package/src/commands/ultraplan.ts +1518 -0
  49. package/src/commands/update.ts +86 -0
  50. package/src/config/defaults.ts +62 -0
  51. package/src/config/loader.ts +448 -60
  52. package/src/config/schema.ts +108 -2
  53. package/src/context/optimizer.ts +25 -33
  54. package/src/context/rule-renderer.ts +223 -0
  55. package/src/context/savings.ts +258 -0
  56. package/src/context/startup-check.ts +380 -0
  57. package/src/context/startup-optimizer.ts +355 -0
  58. package/src/context/tokenignore.ts +146 -0
  59. package/src/context-mode/cache-handle.ts +49 -0
  60. package/src/context-mode/cache-preview.ts +71 -0
  61. package/src/context-mode/cache-store.ts +738 -0
  62. package/src/context-mode/compressor.ts +131 -26
  63. package/src/context-mode/dedup.ts +108 -0
  64. package/src/context-mode/detector.ts +35 -4
  65. package/src/context-mode/event-extractor.ts +14 -12
  66. package/src/context-mode/event-store.ts +91 -36
  67. package/src/context-mode/hooks.ts +798 -56
  68. package/src/context-mode/knowledge/store.ts +255 -11
  69. package/src/context-mode/memory-store.ts +325 -0
  70. package/src/context-mode/metrics-recorder.ts +158 -0
  71. package/src/context-mode/metrics-store.ts +765 -0
  72. package/src/context-mode/model.ts +24 -0
  73. package/src/context-mode/processor-keys.ts +29 -0
  74. package/src/context-mode/processors/build.ts +66 -0
  75. package/src/context-mode/processors/docker.ts +57 -0
  76. package/src/context-mode/processors/git.ts +111 -0
  77. package/src/context-mode/processors/json.ts +112 -0
  78. package/src/context-mode/processors/k8s.ts +67 -0
  79. package/src/context-mode/processors/lint.ts +67 -0
  80. package/src/context-mode/processors/log.ts +86 -0
  81. package/src/context-mode/processors/registry.ts +116 -0
  82. package/src/context-mode/processors/test-runner.ts +102 -0
  83. package/src/context-mode/processors/types.ts +20 -0
  84. package/src/context-mode/repomap.ts +400 -0
  85. package/src/context-mode/routing.ts +97 -24
  86. package/src/context-mode/sandbox/runners.ts +5 -1
  87. package/src/context-mode/snapshot-builder.ts +106 -11
  88. package/src/context-mode/source-hash.ts +173 -0
  89. package/src/context-mode/tool-name.ts +11 -0
  90. package/src/context-mode/tools.ts +654 -22
  91. package/src/context-mode/web/fetcher.ts +31 -12
  92. package/src/debug/logger.ts +2 -1
  93. package/src/deps/registry.ts +1 -1
  94. package/src/discipline/failure-summarizer.ts +170 -0
  95. package/src/discipline/failure-taxonomy.ts +131 -0
  96. package/src/discipline/workflow-invariants.ts +125 -0
  97. package/src/discovery/index.ts +31 -0
  98. package/src/discovery/lsp.ts +87 -0
  99. package/src/discovery/rank.ts +144 -0
  100. package/src/discovery/sources.ts +89 -0
  101. package/src/discovery/workflow.ts +87 -0
  102. package/src/docs/contracts.ts +39 -0
  103. package/src/docs/drift.ts +117 -87
  104. package/src/fix-pr/assessment.ts +200 -0
  105. package/src/fix-pr/contracts.ts +47 -0
  106. package/src/fix-pr/fetch-comments.ts +80 -0
  107. package/src/fix-pr/prompt-builder.ts +58 -40
  108. package/src/fix-pr/scripts/exec.ts +34 -0
  109. package/src/fix-pr/scripts/trigger-review.ts +106 -0
  110. package/src/fix-pr/scripts/wait-and-check.ts +108 -0
  111. package/src/fix-pr/types.ts +4 -0
  112. package/src/git/branch-finish.ts +5 -0
  113. package/src/git/commit-contract.ts +83 -0
  114. package/src/git/commit.ts +121 -184
  115. package/src/git/status.ts +62 -8
  116. package/src/harness/anti_slop/architecture-parser.ts +210 -0
  117. package/src/harness/anti_slop/backend-factory.ts +30 -0
  118. package/src/harness/anti_slop/backend.ts +140 -0
  119. package/src/harness/anti_slop/desloppify-adapter.ts +319 -0
  120. package/src/harness/anti_slop/fallow-adapter.ts +305 -0
  121. package/src/harness/anti_slop/installer.ts +227 -0
  122. package/src/harness/anti_slop/queue.ts +216 -0
  123. package/src/harness/anti_slop/recommend.ts +84 -0
  124. package/src/harness/anti_slop/score.ts +180 -0
  125. package/src/harness/anti_slop/synthetic-edit-test.ts +128 -0
  126. package/src/harness/artifacts/agents-md.ts +88 -0
  127. package/src/harness/artifacts/checks-wiring.ts +57 -0
  128. package/src/harness/artifacts/docs-tree.ts +79 -0
  129. package/src/harness/artifacts/lint-configs.ts +136 -0
  130. package/src/harness/artifacts/review-agents.ts +67 -0
  131. package/src/harness/bare-entry.ts +108 -0
  132. package/src/harness/command.ts +1010 -0
  133. package/src/harness/default-agents/design.md +23 -0
  134. package/src/harness/default-agents/discover.md +18 -0
  135. package/src/harness/default-agents/implement.md +24 -0
  136. package/src/harness/default-agents/plan.md +19 -0
  137. package/src/harness/default-agents/research.md +21 -0
  138. package/src/harness/default-agents/validate.md +22 -0
  139. package/src/harness/gc/reporter.ts +28 -0
  140. package/src/harness/gc/runner.ts +136 -0
  141. package/src/harness/hooks/layer-context-inject.ts +155 -0
  142. package/src/harness/hooks/post-session-sweep.ts +130 -0
  143. package/src/harness/hooks/pre-edit-dupe-probe.ts +224 -0
  144. package/src/harness/hooks/register.ts +118 -0
  145. package/src/harness/model.ts +117 -0
  146. package/src/harness/pipeline.ts +348 -0
  147. package/src/harness/project-paths.ts +235 -0
  148. package/src/harness/stage-runner.ts +107 -0
  149. package/src/harness/stages/design.ts +386 -0
  150. package/src/harness/stages/discover.ts +454 -0
  151. package/src/harness/stages/implement.ts +162 -0
  152. package/src/harness/stages/plan.ts +335 -0
  153. package/src/harness/stages/research.ts +263 -0
  154. package/src/harness/stages/validate.ts +684 -0
  155. package/src/harness/storage.ts +467 -0
  156. package/src/harness/tools.ts +426 -0
  157. package/src/lsp/bridge.ts +56 -95
  158. package/src/lsp/capabilities.ts +108 -0
  159. package/src/lsp/contracts.ts +35 -0
  160. package/src/lsp/detector.ts +8 -12
  161. package/src/markdown-frontmatter.ts +68 -0
  162. package/src/mempalace/bridge.ts +135 -0
  163. package/src/mempalace/config.ts +75 -0
  164. package/src/mempalace/format.ts +163 -0
  165. package/src/mempalace/hooks.ts +370 -0
  166. package/src/mempalace/installer-helper.ts +194 -0
  167. package/src/mempalace/python/mempalace_bridge.py +440 -0
  168. package/src/mempalace/runtime.ts +565 -0
  169. package/src/mempalace/schema.ts +268 -0
  170. package/src/mempalace/session-summary.ts +198 -0
  171. package/src/mempalace/tool.ts +186 -0
  172. package/src/mempalace/uv.ts +256 -0
  173. package/src/migrate/runner.ts +354 -0
  174. package/src/planning/approval-flow.ts +206 -9
  175. package/src/planning/plan-writer-prompt.ts +4 -3
  176. package/src/planning/planning-ask-tool.ts +39 -0
  177. package/src/planning/render-markdown.ts +74 -0
  178. package/src/planning/spec.ts +42 -0
  179. package/src/planning/system-prompt.ts +11 -8
  180. package/src/planning/validate.ts +84 -0
  181. package/src/platform/omp.ts +15 -2
  182. package/src/platform/system-prompt.ts +37 -0
  183. package/src/platform/test-utils.ts +3 -0
  184. package/src/platform/types.ts +6 -1
  185. package/src/qa/config.ts +12 -6
  186. package/src/qa/detect-app-type.ts +13 -6
  187. package/src/qa/matrix.ts +12 -6
  188. package/src/qa/prompt-builder.ts +28 -30
  189. package/src/qa/scripts/dev-server-utils.ts +72 -0
  190. package/src/qa/scripts/run-e2e-tests.ts +226 -0
  191. package/src/qa/scripts/start-dev-server.ts +138 -0
  192. package/src/qa/scripts/stop-dev-server.ts +77 -0
  193. package/src/qa/session.ts +13 -7
  194. package/src/quality/ai-setup.ts +27 -25
  195. package/src/quality/contracts.ts +34 -0
  196. package/src/quality/gates/ai-review.ts +20 -58
  197. package/src/quality/gates/command.ts +249 -46
  198. package/src/quality/review-gates.ts +18 -2
  199. package/src/quality/runner.ts +63 -22
  200. package/src/quality/schemas.ts +37 -2
  201. package/src/quality/setup.ts +96 -16
  202. package/src/release/changelog.ts +1 -1
  203. package/src/release/channels/custom.ts +13 -3
  204. package/src/release/channels/types.ts +5 -0
  205. package/src/release/contracts.ts +90 -0
  206. package/src/release/executor.ts +122 -45
  207. package/src/release/prompt.ts +18 -2
  208. package/src/release/targets.ts +86 -0
  209. package/src/release/version.ts +96 -71
  210. package/src/review/agent-loader.ts +221 -109
  211. package/src/review/fixer.ts +10 -6
  212. package/src/review/multi-agent-runner.ts +114 -13
  213. package/src/review/output.ts +12 -139
  214. package/src/review/runner.ts +12 -6
  215. package/src/review/scope.ts +144 -24
  216. package/src/review/types.ts +1 -20
  217. package/src/review/validator.ts +12 -6
  218. package/src/storage/fix-pr-sessions.ts +21 -14
  219. package/src/storage/plans.ts +14 -5
  220. package/src/storage/qa-sessions.ts +25 -19
  221. package/src/storage/reliability-metrics.ts +180 -0
  222. package/src/storage/reports.ts +8 -7
  223. package/src/storage/review-sessions.ts +55 -20
  224. package/src/tool-catalog/active-tool-controller.ts +164 -0
  225. package/src/tool-catalog/active-tool-planner.ts +212 -0
  226. package/src/tool-catalog/tool-groups.ts +102 -0
  227. package/src/types.ts +1399 -5
  228. package/src/ui-design/backend-adapter.ts +78 -0
  229. package/src/ui-design/backends/local-html.ts +82 -0
  230. package/src/ui-design/backends/pencil-mcp.ts +111 -0
  231. package/src/ui-design/components-scanner.ts +124 -0
  232. package/src/ui-design/config.ts +55 -0
  233. package/src/ui-design/pen-scanner.ts +95 -0
  234. package/src/ui-design/pen-selector.ts +72 -0
  235. package/src/ui-design/prompt-builder.ts +73 -0
  236. package/src/ui-design/scanner.ts +136 -0
  237. package/src/ui-design/session.ts +974 -0
  238. package/src/ui-design/system-prompt.ts +312 -0
  239. package/src/ui-design/tokens-scanner.ts +181 -0
  240. package/src/ui-design/types.ts +96 -0
  241. package/src/ultraplan/agent-catalog.ts +522 -0
  242. package/src/ultraplan/authoring/agent-catalog.ts +310 -0
  243. package/src/ultraplan/authoring/authoring-tools.ts +552 -0
  244. package/src/ultraplan/authoring/command-handlers.ts +339 -0
  245. package/src/ultraplan/authoring/markdown.ts +510 -0
  246. package/src/ultraplan/authoring/model.ts +162 -0
  247. package/src/ultraplan/authoring/pipeline.ts +319 -0
  248. package/src/ultraplan/authoring/stage-runner.ts +141 -0
  249. package/src/ultraplan/authoring/stages/approve.ts +249 -0
  250. package/src/ultraplan/authoring/stages/discover.ts +289 -0
  251. package/src/ultraplan/authoring/stages/intake.ts +203 -0
  252. package/src/ultraplan/authoring/stages/research.ts +399 -0
  253. package/src/ultraplan/authoring/stages/review.ts +333 -0
  254. package/src/ultraplan/authoring/stages/scout.ts +188 -0
  255. package/src/ultraplan/authoring/stages/synthesize.ts +348 -0
  256. package/src/ultraplan/authoring/storage.ts +594 -0
  257. package/src/ultraplan/authoring/synth-gate.ts +165 -0
  258. package/src/ultraplan/authoring-draft.ts +653 -0
  259. package/src/ultraplan/authoring-persist.ts +180 -0
  260. package/src/ultraplan/authoring-tool.ts +608 -0
  261. package/src/ultraplan/authoring-wizard.ts +587 -0
  262. package/src/ultraplan/batch/merge.ts +98 -0
  263. package/src/ultraplan/batch/planner.ts +150 -0
  264. package/src/ultraplan/batch/presenter.ts +97 -0
  265. package/src/ultraplan/batch/storage.ts +420 -0
  266. package/src/ultraplan/batch/supervisor.ts +317 -0
  267. package/src/ultraplan/batch/worker.ts +26 -0
  268. package/src/ultraplan/batch/worktree.ts +110 -0
  269. package/src/ultraplan/contracts.ts +1593 -0
  270. package/src/ultraplan/default-agents/authoring/discoverer.md +12 -0
  271. package/src/ultraplan/default-agents/authoring/intake.md +12 -0
  272. package/src/ultraplan/default-agents/authoring/planner.md +12 -0
  273. package/src/ultraplan/default-agents/authoring/researcher.md +12 -0
  274. package/src/ultraplan/default-agents/authoring/scope-checker.md +12 -0
  275. package/src/ultraplan/default-agents/authoring/scout.md +12 -0
  276. package/src/ultraplan/default-agents/authoring/structure-checker.md +12 -0
  277. package/src/ultraplan/default-agents/authoring/tdd-checker.md +12 -0
  278. package/src/ultraplan/default-agents/backend-domain-reviewer.md +10 -0
  279. package/src/ultraplan/default-agents/backend-executor.md +10 -0
  280. package/src/ultraplan/default-agents/backend-stack-reviewer.md +10 -0
  281. package/src/ultraplan/default-agents/backend-tester.md +10 -0
  282. package/src/ultraplan/default-agents/frontend-domain-reviewer.md +10 -0
  283. package/src/ultraplan/default-agents/frontend-executor.md +10 -0
  284. package/src/ultraplan/default-agents/frontend-stack-reviewer.md +10 -0
  285. package/src/ultraplan/default-agents/frontend-tester.md +10 -0
  286. package/src/ultraplan/default-agents/infrastructure-domain-reviewer.md +10 -0
  287. package/src/ultraplan/default-agents/infrastructure-executor.md +10 -0
  288. package/src/ultraplan/default-agents/infrastructure-stack-reviewer.md +10 -0
  289. package/src/ultraplan/default-agents/infrastructure-tester.md +10 -0
  290. package/src/ultraplan/execution/contract.ts +71 -0
  291. package/src/ultraplan/execution/policy.ts +217 -0
  292. package/src/ultraplan/execution/runtime-tools.ts +107 -0
  293. package/src/ultraplan/execution/session-runner.ts +281 -0
  294. package/src/ultraplan/next-router.ts +85 -0
  295. package/src/ultraplan/presenter.ts +359 -0
  296. package/src/ultraplan/project-paths.ts +342 -0
  297. package/src/ultraplan/runtime/active-execution.ts +72 -0
  298. package/src/ultraplan/runtime/apply-mutation.ts +416 -0
  299. package/src/ultraplan/runtime/blockers.ts +243 -0
  300. package/src/ultraplan/runtime/hook-bridge.ts +486 -0
  301. package/src/ultraplan/runtime/launch-context.ts +207 -0
  302. package/src/ultraplan/runtime/migration.ts +524 -0
  303. package/src/ultraplan/runtime/normalize.ts +281 -0
  304. package/src/ultraplan/runtime/proof.ts +260 -0
  305. package/src/ultraplan/runtime/reducer.ts +416 -0
  306. package/src/ultraplan/runtime/repair.ts +251 -0
  307. package/src/ultraplan/runtime/tracker-storage.ts +368 -0
  308. package/src/ultraplan/session-selection.ts +291 -0
  309. package/src/ultraplan/storage.ts +374 -0
  310. package/src/utils/editor.ts +38 -0
  311. package/src/utils/executable.ts +80 -0
  312. package/src/utils/paths.ts +1 -20
  313. package/src/utils/shell.ts +31 -0
  314. package/src/visual/companion.ts +2 -1
  315. package/src/visual/scripts/frame-template.html +60 -0
  316. package/src/visual/scripts/index.js +59 -13
  317. package/src/visual/scripts/package.json +3 -0
  318. package/src/visual/start-server.ts +2 -1
  319. package/src/workspace/git-scope.ts +64 -0
  320. package/src/workspace/locks.ts +23 -0
  321. package/src/workspace/package-manager.ts +117 -0
  322. package/src/workspace/path-mapping.ts +75 -0
  323. package/src/workspace/project-slug.ts +92 -0
  324. package/src/workspace/repo-root.ts +137 -0
  325. package/src/workspace/selector.ts +115 -0
  326. package/src/workspace/state-paths.ts +118 -0
  327. package/src/workspace/targets.ts +313 -0
  328. package/src/fix-pr/scripts/diff-comments.sh +0 -33
  329. package/src/fix-pr/scripts/fetch-pr-comments.sh +0 -25
  330. package/src/fix-pr/scripts/trigger-review.sh +0 -36
  331. package/src/fix-pr/scripts/wait-and-check.sh +0 -37
  332. package/src/qa/scripts/detect-app-type.sh +0 -68
  333. package/src/qa/scripts/discover-routes.sh +0 -143
  334. package/src/qa/scripts/run-e2e-tests.sh +0 -131
  335. package/src/qa/scripts/start-dev-server.sh +0 -46
  336. package/src/qa/scripts/stop-dev-server.sh +0 -36
  337. package/src/review/prompts/fix-output-schema.md +0 -18
  338. package/src/review/prompts/review-output-schema.md +0 -38
  339. package/src/review/template.ts +0 -15
  340. /package/src/{review → ai}/prompts/invalid-output-retry.md +0 -0
@@ -0,0 +1,434 @@
1
+ // src/commands/clear.ts
2
+ //
3
+ // `/supi:clear` — destructive cleanup for metrics, cache, current-session
4
+ // knowledge, and memory. Events are intentionally out of scope.
5
+ //
6
+ // UX rules (from L1 design spec §6.4 + plan Tasks 39\u201347):
7
+ // - Pre-deletion summary is rendered before any prompt.
8
+ // - The exact scope sentence is included verbatim so the user has full
9
+ // clarity on what is and is not being touched.
10
+ // - Confirmation falls back to `ctx.ui.select` when `ctx.ui.confirm` is
11
+ // absent (mirrors `optimize-context.ts` pattern).
12
+ // - Headless invocations (`!ctx.hasUI`) return silently; programmatic
13
+ // non-TUI variants are explicitly out of scope.
14
+
15
+ import type { Platform, PlatformContext } from "../platform/types.js";
16
+ import { basename } from "node:path";
17
+ import { getCacheStore, getKnowledgeStore, getMetricsStore, getSessionId } from "../context-mode/hooks.js";
18
+ import { getMemoryStore } from "../context-mode/memory-store.js";
19
+ import { getProjectStateDir } from "../workspace/state-paths.js";
20
+ import { formatSize } from "../context/analyzer.js";
21
+
22
+ const SESSION_SCOPE_SENTENCE =
23
+ "Scope: metrics, cache, current-session knowledge, and current-session memory. Project memory created before this clear is suppressed for this session. Events are not touched.";
24
+ const PROJECT_SCOPE_SENTENCE =
25
+ "Scope: metrics, cache, all indexed knowledge, and all memory for this project. Events are not touched.";
26
+
27
+ function formatRelativeTime(startedAtMs: number | null, now = Date.now()): string {
28
+ if (startedAtMs === null) return "unknown";
29
+ const delta = Math.max(0, now - startedAtMs);
30
+ const seconds = Math.floor(delta / 1000);
31
+ if (seconds < 60) return `${seconds}s ago`;
32
+ const minutes = Math.floor(seconds / 60);
33
+ if (minutes < 60) return `${minutes}m ago`;
34
+ const hours = Math.floor(minutes / 60);
35
+ if (hours < 24) return `${hours}h ago`;
36
+ const days = Math.floor(hours / 24);
37
+ return `${days}d ago`;
38
+ }
39
+
40
+ /** Confirmation helper that prefers `ctx.ui.confirm` when available, falling
41
+ * back to `ctx.ui.select(title, ["Confirm", "Cancel"], { helpText: summary })`.
42
+ * Mirrors the pattern in `optimize-context.ts:109`. */
43
+ async function confirmDestructive(
44
+ ctx: PlatformContext,
45
+ title: string,
46
+ summary: string,
47
+ ): Promise<boolean> {
48
+ const confirm = (ctx.ui as any).confirm;
49
+ if (typeof confirm === "function") {
50
+ return Boolean(await confirm.call(ctx.ui, title, summary));
51
+ }
52
+ const choice = await ctx.ui.select(title, ["Confirm", "Cancel"], {
53
+ helpText: summary,
54
+ });
55
+ return choice === "Confirm";
56
+ }
57
+
58
+ function recordCacheClearMetric(
59
+ store: ReturnType<typeof getMetricsStore>,
60
+ sessionId: string,
61
+ beforeBytes: number,
62
+ afterBytes = 0,
63
+ now = Date.now(),
64
+ ): void {
65
+ if (!store) return;
66
+ try {
67
+ store.record({
68
+ session_id: "(system)",
69
+ ts: now,
70
+ layer: "L3",
71
+ tool: "(system)",
72
+ processor: "cache-clear",
73
+ before_bytes: Math.max(0, Math.floor(beforeBytes)),
74
+ after_bytes: Math.max(0, Math.floor(afterBytes)),
75
+ cache_hit: 0,
76
+ unique_source_hash: null,
77
+ context_tokens: null,
78
+ context_window: null,
79
+ context_percent: null,
80
+ });
81
+ } catch {
82
+ // Clearing must not depend on metrics health.
83
+ }
84
+ }
85
+
86
+ /** Build the active-session deletion summary text. */
87
+ function buildActiveSessionSummary(
88
+ store: ReturnType<typeof getMetricsStore>,
89
+ cacheStore: ReturnType<typeof getCacheStore>,
90
+ knowledgeStore: ReturnType<typeof getKnowledgeStore>,
91
+ memoryStore: ReturnType<typeof getMemoryStore>,
92
+ sessionId: string,
93
+ ): string {
94
+ const lines: string[] = [];
95
+ if (store) {
96
+ const totals = store.getSessionTotals(sessionId);
97
+ const meta = store.getSessionMeta(sessionId);
98
+ const rels = formatRelativeTime(meta?.started_at ?? null);
99
+ const onDisk = formatSize(totals.afterBytes);
100
+ lines.push(
101
+ `${totals.rowCount} metrics rows in this session.`,
102
+ `Approx on-disk: ${onDisk}.`,
103
+ `Started: ${rels}.`,
104
+ `Metrics DB: ${store.dbPath}`,
105
+ );
106
+ } else {
107
+ lines.push("No metrics store available.");
108
+ }
109
+
110
+ if (cacheStore) {
111
+ const cache = cacheStore.getSessionStats(sessionId);
112
+ lines.push(
113
+ `${cache.refCount} cache refs in this session.`,
114
+ `Cache payload bytes reclaimable: ${cache.reclaimablePayloadBytes} bytes (${formatSize(cache.reclaimablePayloadBytes)}).`,
115
+ `Cache payload bytes retained: ${cache.retainedPayloadBytes} bytes (${formatSize(cache.retainedPayloadBytes)}).`,
116
+ `Cache DB: ${cacheStore.dbPath}`,
117
+ `Cache payloads: ${cacheStore.payloadRoot}`,
118
+ );
119
+ } else {
120
+ lines.push("No cache store available.");
121
+ }
122
+
123
+ if (knowledgeStore) {
124
+ lines.push(
125
+ `Knowledge DB: ${knowledgeStore.path}`,
126
+ "Current-session indexed knowledge will be cleared.",
127
+ );
128
+ } else {
129
+ lines.push("No knowledge store available.");
130
+ }
131
+
132
+ if (memoryStore) {
133
+ const sessionRows = memoryStore.countSessionRows(sessionId);
134
+ lines.push(
135
+ `Memory DB: ${memoryStore.dbPath}`,
136
+ `${sessionRows} session-owned memory rows for this session will be cleared; project memory remains.`,
137
+ );
138
+ } else {
139
+ lines.push("No memory store available.");
140
+ }
141
+
142
+ lines.push(SESSION_SCOPE_SENTENCE);
143
+ return lines.join("\n");
144
+ }
145
+
146
+ /** Build the project-wide deletion summary listing every session id. */
147
+ function buildProjectSummary(
148
+ store: ReturnType<typeof getMetricsStore>,
149
+ cacheStore: ReturnType<typeof getCacheStore>,
150
+ knowledgeStore: ReturnType<typeof getKnowledgeStore>,
151
+ memoryStore: ReturnType<typeof getMemoryStore>,
152
+ projectSlug: string,
153
+ ): { summary: string; sessionLines: string[] } {
154
+ const lines: string[] = [];
155
+ const metricsSessionRows = store ? store.listSessions(projectSlug) : [];
156
+ const cacheSessionRows = cacheStore ? cacheStore.listSessions() : [];
157
+ const knowledgeSessionRows = knowledgeStore ? knowledgeStore.listSessions() : [];
158
+ const memorySessionRows = memoryStore ? memoryStore.listSessions() : [];
159
+
160
+ // Merge metrics + cache + knowledge + memory sessions so the second
161
+ // destructive confirmation lists every session with data that will disappear.
162
+ const sessionMap = new Map<string, {
163
+ session_id: string;
164
+ metricsRows?: number;
165
+ startedAt?: number;
166
+ cacheRefs?: number;
167
+ knowledgeChunks?: number;
168
+ knowledgeUrlCache?: number;
169
+ memoryRows?: number;
170
+ }>();
171
+ const ensureSession = (sessionId: string) => {
172
+ let row = sessionMap.get(sessionId);
173
+ if (!row) {
174
+ row = { session_id: sessionId };
175
+ sessionMap.set(sessionId, row);
176
+ }
177
+ return row;
178
+ };
179
+
180
+ for (const s of metricsSessionRows) {
181
+ const row = ensureSession(s.session_id);
182
+ row.metricsRows = s.row_count;
183
+ row.startedAt = s.started_at;
184
+ }
185
+ for (const c of cacheSessionRows) {
186
+ ensureSession(c.session_id).cacheRefs = c.ref_count;
187
+ }
188
+ for (const k of knowledgeSessionRows) {
189
+ const row = ensureSession(k.session_id);
190
+ row.knowledgeChunks = k.chunk_count;
191
+ row.knowledgeUrlCache = k.url_cache_count;
192
+ }
193
+ for (const m of memorySessionRows) {
194
+ ensureSession(m.session_id).memoryRows = m.row_count;
195
+ }
196
+
197
+ const sessionLines = [...sessionMap.values()]
198
+ .sort((a, b) => a.session_id.localeCompare(b.session_id))
199
+ .map((s) => {
200
+ const parts: string[] = [];
201
+ if (s.metricsRows !== undefined) {
202
+ parts.push(`${s.metricsRows} metrics rows`);
203
+ if (s.startedAt !== undefined) parts.push(`started ${formatRelativeTime(s.startedAt)}`);
204
+ }
205
+ if (s.cacheRefs !== undefined) parts.push(`${s.cacheRefs} cache refs`);
206
+ if (s.knowledgeChunks !== undefined || s.knowledgeUrlCache !== undefined) {
207
+ parts.push(`${s.knowledgeChunks ?? 0} knowledge chunks`);
208
+ if ((s.knowledgeUrlCache ?? 0) > 0) parts.push(`${s.knowledgeUrlCache} URL cache rows`);
209
+ }
210
+ if (s.memoryRows !== undefined) parts.push(`${s.memoryRows} memory rows`);
211
+ return `${s.session_id} — ${parts.join(", ")}`;
212
+ });
213
+
214
+ if (store) {
215
+ lines.push(
216
+ `Project-wide clear: ${metricsSessionRows.length} session${metricsSessionRows.length === 1 ? "" : "s"} with metrics rows.`,
217
+ `Metrics DB: ${store.dbPath}`,
218
+ );
219
+ } else {
220
+ lines.push("No metrics store available.");
221
+ }
222
+
223
+ if (cacheStore) {
224
+ const cache = cacheStore.getStats();
225
+ lines.push(
226
+ `${cache.refCount} cache refs project-wide across ${cacheSessionRows.length} session${cacheSessionRows.length === 1 ? "" : "s"}.`,
227
+ `${cache.entryCount} cache entries project-wide.`,
228
+ `Cache payload bytes: ${cache.payloadBytes} bytes (${formatSize(cache.payloadBytes)}).`,
229
+ `Cache DB: ${cacheStore.dbPath}`,
230
+ `Cache payloads: ${cacheStore.payloadRoot}`,
231
+ );
232
+ } else {
233
+ lines.push("No cache store available.");
234
+ }
235
+
236
+ if (knowledgeStore) {
237
+ const knowledgeStats = knowledgeStore.getStats();
238
+ lines.push(
239
+ `${knowledgeStats.totalChunks} indexed knowledge chunks project-wide.`,
240
+ "All indexed knowledge scopes, including legacy rows, will be cleared.",
241
+ );
242
+ } else {
243
+ lines.push("No knowledge store available.");
244
+ }
245
+
246
+ if (memoryStore) {
247
+ const stats = memoryStore.getStats();
248
+ lines.push(
249
+ `Memory DB: ${memoryStore.dbPath}`,
250
+ `${stats.totalRows} memory rows project-wide will be cleared (session: ${stats.sessionRows}, project: ${stats.projectRows}).`,
251
+ );
252
+ } else {
253
+ lines.push("No memory store available.");
254
+ }
255
+
256
+ lines.push(PROJECT_SCOPE_SENTENCE);
257
+ return { summary: lines.join("\n"), sessionLines };
258
+ }
259
+
260
+ interface ParsedArgs {
261
+ scope: "session" | "project";
262
+ dryRun: boolean;
263
+ }
264
+
265
+ function parseArgs(args: string | undefined): ParsedArgs {
266
+ const tokens = (args ?? "").trim().split(/\s+/).filter(Boolean);
267
+ const dryRun = tokens.includes("--dry-run");
268
+ const scope = tokens.includes("all") ? "project" : "session";
269
+ return { scope, dryRun };
270
+ }
271
+
272
+ export function handleClear(
273
+ platform: Platform,
274
+ ctx: PlatformContext,
275
+ args?: string,
276
+ ): void {
277
+ if (!ctx.hasUI) return;
278
+
279
+ void (async () => {
280
+ const { scope, dryRun } = parseArgs(args);
281
+ const store = getMetricsStore();
282
+ const sessionId = getSessionId();
283
+ const cacheStore = getCacheStore();
284
+ const knowledgeStore = getKnowledgeStore();
285
+ const memoryStore = getMemoryStore();
286
+ const projectSlug = basename(getProjectStateDir(platform.paths, ctx.cwd));
287
+
288
+ if (scope === "session") {
289
+ const summary = buildActiveSessionSummary(store, cacheStore, knowledgeStore, memoryStore, sessionId);
290
+ ctx.ui.notify(summary, "info");
291
+
292
+ if (dryRun) {
293
+ ctx.ui.notify("Dry-run: nothing was deleted.", "info");
294
+ return;
295
+ }
296
+
297
+ const accepted = await confirmDestructive(
298
+ ctx,
299
+ "Clear metrics for this session?",
300
+ summary,
301
+ );
302
+ if (!accepted) {
303
+ ctx.ui.notify("Clear cancelled.", "info");
304
+ return;
305
+ }
306
+
307
+ if (!store && !cacheStore && !knowledgeStore && !memoryStore) {
308
+ ctx.ui.notify(
309
+ "Nothing to clear: metrics, cache, knowledge, and memory stores are not initialized.",
310
+ "info",
311
+ );
312
+ return;
313
+ }
314
+
315
+ try {
316
+ if (store) {
317
+ store.clearSession(sessionId);
318
+ }
319
+ if (knowledgeStore) {
320
+ knowledgeStore.clearSession(sessionId);
321
+ }
322
+ if (memoryStore) {
323
+ memoryStore.clearSession(sessionId);
324
+ }
325
+ if (cacheStore) {
326
+ const cacheResult = cacheStore.clearSession(sessionId);
327
+ // Record an L3 cache-clear metric reflecting what actually happened:
328
+ // before = total payload bytes referenced by this session;
329
+ // after = bytes retained because other sessions still reference them.
330
+ recordCacheClearMetric(
331
+ store,
332
+ sessionId,
333
+ cacheResult.deletedPayloadBytes + cacheResult.retainedPayloadBytes,
334
+ cacheResult.retainedPayloadBytes,
335
+ );
336
+ if (cacheResult.retainedPayloadBytes > 0) {
337
+ ctx.ui.notify(
338
+ `Metrics, cache, and current-session knowledge cleared for this session. ${formatSize(cacheResult.retainedPayloadBytes)} retained for other sessions.`,
339
+ "info",
340
+ );
341
+ } else {
342
+ ctx.ui.notify("Metrics, cache, and current-session knowledge cleared for this session.", "info");
343
+ }
344
+ } else {
345
+ ctx.ui.notify("Metrics and current-session knowledge cleared for this session. (No cache store active.)", "info");
346
+ }
347
+ } catch (e) {
348
+ ctx.ui.notify(
349
+ `Clear failed: ${(e as Error).message}. See /supi:doctor.`,
350
+ "error",
351
+ );
352
+ }
353
+ return;
354
+ }
355
+
356
+ // scope === "project"
357
+ const { summary, sessionLines } = buildProjectSummary(store, cacheStore, knowledgeStore, memoryStore, projectSlug);
358
+ ctx.ui.notify(summary, "info");
359
+
360
+ if (dryRun) {
361
+ ctx.ui.notify("Dry-run: nothing was deleted.", "info");
362
+ return;
363
+ }
364
+
365
+ const firstAccept = await confirmDestructive(
366
+ ctx,
367
+ "Clear metrics for the entire project?",
368
+ summary,
369
+ );
370
+ if (!firstAccept) {
371
+ ctx.ui.notify("Clear cancelled.", "info");
372
+ return;
373
+ }
374
+
375
+ // Second confirm: list every session so the user sees exactly what
376
+ // disappears.
377
+ const finalChoice = await ctx.ui.select(
378
+ "Confirm project-wide clear",
379
+ ["Confirm", "Cancel"],
380
+ {
381
+ helpText:
382
+ sessionLines.length > 0
383
+ ? `The following sessions will be cleared:\n${sessionLines.join("\n")}`
384
+ : "(no sessions tracked)",
385
+ },
386
+ );
387
+ if (finalChoice !== "Confirm") {
388
+ ctx.ui.notify("Clear cancelled.", "info");
389
+ return;
390
+ }
391
+
392
+ if (!store && !cacheStore && !knowledgeStore && !memoryStore) {
393
+ ctx.ui.notify(
394
+ "Nothing to clear: metrics, cache, knowledge, and memory stores are not initialized.",
395
+ "info",
396
+ );
397
+ return;
398
+ }
399
+
400
+ try {
401
+ if (store) {
402
+ store.clearProject(projectSlug);
403
+ }
404
+ if (cacheStore) {
405
+ const cacheResult = cacheStore.clearProject();
406
+ // Project-wide clear deletes every cache ref, so retained bytes are always 0.
407
+ recordCacheClearMetric(store, sessionId, cacheResult.deletedPayloadBytes, 0);
408
+ }
409
+ if (knowledgeStore) {
410
+ knowledgeStore.clearProject();
411
+ }
412
+ if (memoryStore) {
413
+ memoryStore.clearProject();
414
+ }
415
+ ctx.ui.notify("Metrics, cache, indexed knowledge, and memory cleared project-wide.", "info");
416
+ } catch (e) {
417
+ ctx.ui.notify(
418
+ `Clear failed: ${(e as Error).message}. See /supi:doctor.`,
419
+ "error",
420
+ );
421
+ }
422
+ })().catch((err) => {
423
+ ctx.ui.notify(`Clear error: ${(err as Error).message}`, "error");
424
+ });
425
+ }
426
+
427
+ export function registerClearCommand(platform: Platform): void {
428
+ platform.registerCommand("supi:clear", {
429
+ description: "Clear metrics, cache, current-session knowledge, and memory for the active session (or `all` for the project)",
430
+ async handler(args: string | undefined, ctx: any) {
431
+ handleClear(platform, ctx, args);
432
+ },
433
+ });
434
+ }
@@ -15,6 +15,7 @@ modelRegistry.register({
15
15
  harnessRoleHint: "default",
16
16
  });
17
17
 
18
+
18
19
  /**
19
20
  * Register the command for autocomplete and /help listing.
20
21
  * Actual execution goes through handleCommit via the TUI dispatch.