@herbertgao/pi-extensions 2026.9.6 → 2026.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/README.md +3 -8
  2. package/THIRD_PARTY_NOTICES.md +0 -4
  3. package/node_modules/@narumitw/pi-btw/README.md +2 -0
  4. package/node_modules/@narumitw/pi-btw/dist/index.ts +284 -365
  5. package/node_modules/@narumitw/pi-btw/dist/index.ts.map +3 -3
  6. package/node_modules/@narumitw/pi-btw/package.json +52 -53
  7. package/node_modules/@narumitw/pi-btw/src/bring-to-main.ts +494 -547
  8. package/node_modules/@narumitw/pi-btw/src/btw.ts +814 -856
  9. package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +673 -674
  10. package/node_modules/@narumitw/pi-btw/src/keybindings.ts +228 -270
  11. package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +309 -318
  12. package/node_modules/@narumitw/pi-btw/src/menu.ts +416 -454
  13. package/node_modules/@narumitw/pi-btw/src/settings.ts +203 -219
  14. package/node_modules/@narumitw/pi-btw/src/side-thread.ts +173 -201
  15. package/node_modules/@narumitw/pi-btw/src/text.ts +21 -23
  16. package/node_modules/@narumitw/pi-btw/src/transcript-markdown.ts +65 -0
  17. package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +611 -662
  18. package/node_modules/pi-lens/CHANGELOG.md +239 -0
  19. package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +3 -0
  20. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +30 -4
  21. package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +2 -0
  22. package/node_modules/pi-lens/dist/clients/bash-file-access.js +26 -0
  23. package/node_modules/pi-lens/dist/clients/biome-client.js +1 -1
  24. package/node_modules/pi-lens/dist/clients/blocker-freshness.js +403 -35
  25. package/node_modules/pi-lens/dist/clients/bootstrap.js +6 -1
  26. package/node_modules/pi-lens/dist/clients/cascade-format.js +200 -4
  27. package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +10 -2
  28. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +16 -1
  29. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +12 -1
  30. package/node_modules/pi-lens/dist/clients/dispatch/ast-grep-catalog.js +65 -0
  31. package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +28 -0
  32. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +9 -2
  33. package/node_modules/pi-lens/dist/clients/dispatch/finding-policy.js +222 -0
  34. package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +389 -13
  35. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +175 -25
  36. package/node_modules/pi-lens/dist/clients/dispatch/rule-ignores.js +62 -0
  37. package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +21 -41
  38. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +6 -1
  39. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +7 -7
  40. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -12
  41. package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +2 -21
  42. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +1 -1
  43. package/node_modules/pi-lens/dist/clients/dispatch/types.js +4 -1
  44. package/node_modules/pi-lens/dist/clients/disposition-publish.js +1 -0
  45. package/node_modules/pi-lens/dist/clients/effective-config.js +1 -1
  46. package/node_modules/pi-lens/dist/clients/file-kinds.js +26 -1
  47. package/node_modules/pi-lens/dist/clients/file-role.js +21 -21
  48. package/node_modules/pi-lens/dist/clients/file-utils.js +156 -10
  49. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +56 -9
  50. package/node_modules/pi-lens/dist/clients/format-service.js +39 -21
  51. package/node_modules/pi-lens/dist/clients/formatters.js +60 -13
  52. package/node_modules/pi-lens/dist/clients/generation-guard.js +2 -2
  53. package/node_modules/pi-lens/dist/clients/git-guard.js +11 -3
  54. package/node_modules/pi-lens/dist/clients/indent-retarget.js +78 -8
  55. package/node_modules/pi-lens/dist/clients/installer/index.js +333 -114
  56. package/node_modules/pi-lens/dist/clients/instance-reaper-state.js +7 -0
  57. package/node_modules/pi-lens/dist/clients/instance-reaper.js +20 -10
  58. package/node_modules/pi-lens/dist/clients/language-profile.js +23 -1
  59. package/node_modules/pi-lens/dist/clients/language-registry.js +5 -1
  60. package/node_modules/pi-lens/dist/clients/latency-logger.js +4 -1
  61. package/node_modules/pi-lens/dist/clients/lens-engine.js +12 -3
  62. package/node_modules/pi-lens/dist/clients/lens-events.js +2 -1
  63. package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +79 -0
  64. package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +2 -1
  65. package/node_modules/pi-lens/dist/clients/lsp/client.js +25 -21
  66. package/node_modules/pi-lens/dist/clients/lsp/config.js +2 -2
  67. package/node_modules/pi-lens/dist/clients/lsp/index.js +7 -0
  68. package/node_modules/pi-lens/dist/clients/lsp/launch.js +16 -4
  69. package/node_modules/pi-lens/dist/clients/lsp/server.js +19 -2
  70. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +2 -1
  71. package/node_modules/pi-lens/dist/clients/lsp-mutation.js +5 -3
  72. package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +12 -8
  73. package/node_modules/pi-lens/dist/clients/mcp/session.js +36 -4
  74. package/node_modules/pi-lens/dist/clients/ndjson-logger.js +24 -7
  75. package/node_modules/pi-lens/dist/clients/observed-mutation.js +40 -2
  76. package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +23 -3
  77. package/node_modules/pi-lens/dist/clients/opengrep-client.js +110 -15
  78. package/node_modules/pi-lens/dist/clients/path-utils.js +123 -3
  79. package/node_modules/pi-lens/dist/clients/performance-report.js +5 -1
  80. package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +1 -1
  81. package/node_modules/pi-lens/dist/clients/pipeline.js +74 -5
  82. package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +37 -5
  83. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +145 -18
  84. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/dead-code.js +4 -1
  85. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +59 -3
  86. package/node_modules/pi-lens/dist/clients/project-lens-config.js +45 -2
  87. package/node_modules/pi-lens/dist/clients/read-guard.js +70 -11
  88. package/node_modules/pi-lens/dist/clients/resource-sampler.js +147 -9
  89. package/node_modules/pi-lens/dist/clients/ruff-client.js +1 -1
  90. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +33 -5
  91. package/node_modules/pi-lens/dist/clients/runtime-context.js +6 -2
  92. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +77 -7
  93. package/node_modules/pi-lens/dist/clients/runtime-session.js +21 -2
  94. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +43 -12
  95. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +330 -85
  96. package/node_modules/pi-lens/dist/clients/runtime-turn.js +147 -17
  97. package/node_modules/pi-lens/dist/clients/safe-spawn.js +258 -5
  98. package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +6 -0
  99. package/node_modules/pi-lens/dist/clients/session-event-guard.js +50 -5
  100. package/node_modules/pi-lens/dist/clients/sg-runner.js +23 -11
  101. package/node_modules/pi-lens/dist/clients/sgconfig.js +79 -2
  102. package/node_modules/pi-lens/dist/clients/test-runner-client.js +6 -41
  103. package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +43 -0
  104. package/node_modules/pi-lens/dist/clients/tool-agreement.js +423 -0
  105. package/node_modules/pi-lens/dist/clients/tool-config.js +50 -0
  106. package/node_modules/pi-lens/dist/clients/tool-cwd.js +47 -76
  107. package/node_modules/pi-lens/dist/clients/tool-policy.js +163 -7
  108. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +120 -0
  109. package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +127 -189
  110. package/node_modules/pi-lens/dist/clients/widget-state.js +98 -0
  111. package/node_modules/pi-lens/dist/clients/word-index.js +5 -2
  112. package/node_modules/pi-lens/dist/clients/write-ordering-guard.js +7 -0
  113. package/node_modules/pi-lens/dist/index.js +27416 -24153
  114. package/node_modules/pi-lens/dist/mcp/server.js +5 -2
  115. package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +7 -1
  116. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +168 -53
  117. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +244 -72
  118. package/node_modules/pi-lens/docs/audit1.md +5 -5
  119. package/node_modules/pi-lens/docs/dependencies.md +11 -0
  120. package/node_modules/pi-lens/docs/dispositions.md +52 -0
  121. package/node_modules/pi-lens/docs/environment-variables.md +2 -2
  122. package/node_modules/pi-lens/docs/features.md +4 -4
  123. package/node_modules/pi-lens/docs/globalconfig.md +3 -1
  124. package/node_modules/pi-lens/docs/language-coverage.md +1 -0
  125. package/node_modules/pi-lens/docs/pi-lens-fixer.md +53 -94
  126. package/node_modules/pi-lens/docs/pi-lens-investigator.md +43 -38
  127. package/node_modules/pi-lens/docs/pi-lens-retro.md +97 -0
  128. package/node_modules/pi-lens/docs/pi-lens-reviewer.md +53 -66
  129. package/node_modules/pi-lens/docs/release-qa-baseline.md +22 -0
  130. package/node_modules/pi-lens/docs/settings.md +7 -4
  131. package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +1 -1
  132. package/node_modules/pi-lens/docs/usage.md +2 -0
  133. package/node_modules/pi-lens/package.json +1 -1
  134. package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/sql-injection.yml +24 -12
  135. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +40 -0
  136. package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +15 -0
  137. package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +7 -0
  138. package/package.json +5 -11
  139. package/node_modules/@luxusai/pi-hindsight/CHANGELOG.md +0 -376
  140. package/node_modules/@luxusai/pi-hindsight/README.md +0 -92
  141. package/node_modules/@luxusai/pi-hindsight/docs/adr/001-memory-lifecycle-and-scope.md +0 -56
  142. package/node_modules/@luxusai/pi-hindsight/docs/adr/002-explicit-routing-strategy-seam.md +0 -169
  143. package/node_modules/@luxusai/pi-hindsight/docs/adr/003-tui-memory-mode-vocabulary.md +0 -107
  144. package/node_modules/@luxusai/pi-hindsight/docs/adr/004-lifeos-dual-bank-design.md +0 -89
  145. package/node_modules/@luxusai/pi-hindsight/docs/adr/005-domain-banks-and-agent-first-surface.md +0 -189
  146. package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark.webp +0 -0
  147. package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark@2x.webp +0 -0
  148. package/node_modules/@luxusai/pi-hindsight/docs/coding-memory-evaluation.md +0 -54
  149. package/node_modules/@luxusai/pi-hindsight/docs/compatibility.md +0 -75
  150. package/node_modules/@luxusai/pi-hindsight/docs/hindsight-core-functions.md +0 -300
  151. package/node_modules/@luxusai/pi-hindsight/docs/mission-and-mental-model-quality.md +0 -158
  152. package/node_modules/@luxusai/pi-hindsight/docs/next-opt-out-design.md +0 -164
  153. package/node_modules/@luxusai/pi-hindsight/docs/risky-memory-modes.md +0 -139
  154. package/node_modules/@luxusai/pi-hindsight/docs/starter-mental-model-suggestions.md +0 -74
  155. package/node_modules/@luxusai/pi-hindsight/docs/surface-reference.md +0 -261
  156. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-operations.ts +0 -151
  157. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-selection.ts +0 -18
  158. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-settings-presenter.ts +0 -46
  159. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-templates.ts +0 -383
  160. package/node_modules/@luxusai/pi-hindsight/extensions/banks/banking.ts +0 -240
  161. package/node_modules/@luxusai/pi-hindsight/extensions/banks/knowledge-page-seed.ts +0 -176
  162. package/node_modules/@luxusai/pi-hindsight/extensions/banks/retain-strategies.ts +0 -178
  163. package/node_modules/@luxusai/pi-hindsight/extensions/client/client-retry.ts +0 -41
  164. package/node_modules/@luxusai/pi-hindsight/extensions/client/client.ts +0 -386
  165. package/node_modules/@luxusai/pi-hindsight/extensions/client/fetch-compat.ts +0 -39
  166. package/node_modules/@luxusai/pi-hindsight/extensions/client/timeout.ts +0 -34
  167. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-defaults.ts +0 -140
  168. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-model.ts +0 -61
  169. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-registry.ts +0 -925
  170. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-field-paths.ts +0 -247
  171. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-normalize.ts +0 -547
  172. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-writer.ts +0 -480
  173. package/node_modules/@luxusai/pi-hindsight/extensions/config/config.ts +0 -182
  174. package/node_modules/@luxusai/pi-hindsight/extensions/config/setup-gate.ts +0 -86
  175. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-execute.ts +0 -1010
  176. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-parse.ts +0 -175
  177. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-plan.ts +0 -425
  178. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-presentation.ts +0 -210
  179. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-sessions.ts +0 -817
  180. package/node_modules/@luxusai/pi-hindsight/extensions/index.ts +0 -25
  181. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/git-seed.ts +0 -319
  182. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-recall.ts +0 -196
  183. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-retain.ts +0 -189
  184. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-runtime.ts +0 -65
  185. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle.ts +0 -260
  186. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/mental-models.ts +0 -244
  187. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/observation-scopes.ts +0 -59
  188. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-cleanup.ts +0 -82
  189. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-visibility.ts +0 -45
  190. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall.ts +0 -331
  191. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-cursor.ts +0 -354
  192. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-job-builder.ts +0 -66
  193. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-receipts.ts +0 -132
  194. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain.ts +0 -228
  195. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-bank-template-operations.ts +0 -74
  196. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-config-operations.ts +0 -16
  197. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-control-operations.ts +0 -648
  198. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-diagnostics-operations.ts +0 -105
  199. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-identity.ts +0 -68
  200. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-service.ts +0 -71
  201. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-types.ts +0 -13
  202. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-recall-operations.ts +0 -162
  203. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-retain-operations.ts +0 -131
  204. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-scope.ts +0 -104
  205. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-session-operations.ts +0 -37
  206. package/node_modules/@luxusai/pi-hindsight/extensions/operations/operation-catalog.ts +0 -893
  207. package/node_modules/@luxusai/pi-hindsight/extensions/operations/reflect-presenter.ts +0 -35
  208. package/node_modules/@luxusai/pi-hindsight/extensions/operations/scope-migrate.ts +0 -177
  209. package/node_modules/@luxusai/pi-hindsight/extensions/operations/tools.ts +0 -7
  210. package/node_modules/@luxusai/pi-hindsight/extensions/queue/flush-presenter.ts +0 -21
  211. package/node_modules/@luxusai/pi-hindsight/extensions/queue/jsonl-queue-store.ts +0 -112
  212. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-delivery.ts +0 -111
  213. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-lock.ts +0 -214
  214. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-operations.ts +0 -70
  215. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue.ts +0 -392
  216. package/node_modules/@luxusai/pi-hindsight/extensions/tui/bank-template-presentation.ts +0 -45
  217. package/node_modules/@luxusai/pi-hindsight/extensions/tui/commands.ts +0 -9
  218. package/node_modules/@luxusai/pi-hindsight/extensions/tui/guided-setup.ts +0 -860
  219. package/node_modules/@luxusai/pi-hindsight/extensions/tui/prefill-input.ts +0 -105
  220. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-flow.ts +0 -189
  221. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-server-probe.ts +0 -299
  222. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-actions.ts +0 -201
  223. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-facts.ts +0 -47
  224. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-render.ts +0 -239
  225. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-types.ts +0 -50
  226. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui.ts +0 -259
  227. package/node_modules/@luxusai/pi-hindsight/extensions/tui/tool-presenters.ts +0 -77
  228. package/node_modules/@luxusai/pi-hindsight/extensions/types.ts +0 -534
  229. package/node_modules/@luxusai/pi-hindsight/extensions/utils/diagnostics.ts +0 -319
  230. package/node_modules/@luxusai/pi-hindsight/extensions/utils/messages.ts +0 -325
  231. package/node_modules/@luxusai/pi-hindsight/extensions/utils/sanitize.ts +0 -42
  232. package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-memory-meta.ts +0 -244
  233. package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-operations.ts +0 -56
  234. package/node_modules/@luxusai/pi-hindsight/extensions/utils/session.ts +0 -50
  235. package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-fields.ts +0 -167
  236. package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-health.ts +0 -207
  237. package/node_modules/@luxusai/pi-hindsight/extensions/utils/status.ts +0 -120
  238. package/node_modules/@luxusai/pi-hindsight/extensions/version.ts +0 -8
  239. package/node_modules/@luxusai/pi-hindsight/package.json +0 -118
  240. package/node_modules/@luxusai/pi-hindsight/skills/hindsight-memory-doctor/SKILL.md +0 -75
@@ -1,201 +0,0 @@
1
- import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
2
- import type { ResolvedConfig } from "../types.js";
3
- import {
4
- buildConfigEditingFields,
5
- inputDefaultForConfigEditingField,
6
- parseConfigEditingFieldInput,
7
- patchForConfigEditingField,
8
- readConfigLayers,
9
- type ConfigEditingField,
10
- type FieldId,
11
- } from "../config/config-editing-model.js";
12
- import {
13
- createMemoryOperations,
14
- type MemoryOperationsDeps,
15
- } from "../operations/memory-operation-service.js";
16
- import { type ConfigScope, type ProjectConfigPatchInput } from "../config/config-writer.js";
17
- import { inputWithPrefill } from "./prefill-input.js";
18
- import { CANCEL } from "./setup-tui-types.js";
19
-
20
- const LOCAL_EMBED_GUIDANCE = [
21
- "Local hindsight-embed guidance:",
22
- "uvx hindsight-embed@latest profile create pi --port 8888",
23
- "uvx hindsight-embed@latest -p pi bank create <bank-id>",
24
- "uvx hindsight-embed@latest -p pi ui start",
25
- ].join("\n");
26
-
27
- async function writeAndReload(
28
- ctx: ExtensionCommandContext,
29
- deps: MemoryOperationsDeps,
30
- patch: ProjectConfigPatchInput,
31
- scope: ConfigScope = "project",
32
- ): Promise<void> {
33
- const result = await createMemoryOperations(deps).configure(ctx.cwd, { ...patch, scope });
34
- ctx.ui.notify(`Saved ${scope} config to ${result.path}; setup view reloaded.`, "info");
35
- }
36
-
37
- async function resetField(
38
- ctx: ExtensionCommandContext,
39
- deps: MemoryOperationsDeps,
40
- field: ConfigEditingField,
41
- scope: ConfigScope = "project",
42
- ): Promise<void> {
43
- await writeAndReload(ctx, deps, { resetDefaults: [field.resetKey] }, scope);
44
- }
45
-
46
- function settingPrompt(field: ConfigEditingField): string {
47
- return [
48
- field.label,
49
- field.description,
50
- `Effective: ${field.value} (${field.source ?? "default"})`,
51
- `Environment: ${field.envValue ?? "not set"}`,
52
- `Project: ${field.projectValue ?? "not set"}`,
53
- `User: ${field.globalValue ?? "not set"}`,
54
- `Default: ${field.defaultValue}`,
55
- field.source === "env"
56
- ? "Environment currently wins; project/user edits save for when env override is removed."
57
- : "Changes save immediately.",
58
- ].join("\n");
59
- }
60
-
61
- function scopeLabel(scope: ConfigScope): string {
62
- return scope === "project" ? "Project" : "User";
63
- }
64
-
65
- function withScopedValues(field: ConfigEditingField, values: string[]): string[] {
66
- const scoped = (field.editableScopes ?? ["project"]).flatMap((scope) =>
67
- values.map((value) => `${scopeLabel(scope)}: ${value}`),
68
- );
69
- const resets = (field.editableScopes ?? ["project"]).flatMap((scope) => {
70
- if (scope === "project" && field.projectValue !== undefined) return ["Remove project override"];
71
- if (scope === "global" && field.globalValue !== undefined) return ["Remove user override"];
72
- return [];
73
- });
74
- return [...scoped, ...resets, CANCEL];
75
- }
76
-
77
- function parseScopedAction(action: string): { scope: ConfigScope; value: string } | undefined {
78
- if (action.startsWith("Project: "))
79
- return { scope: "project", value: action.slice("Project: ".length) };
80
- if (action.startsWith("User: ")) return { scope: "global", value: action.slice("User: ".length) };
81
- return undefined;
82
- }
83
-
84
- async function chooseScope(
85
- ctx: ExtensionCommandContext,
86
- field: ConfigEditingField,
87
- ): Promise<ConfigScope | undefined> {
88
- const scopes = field.editableScopes ?? ["project"];
89
- if (scopes.length === 1) return scopes[0];
90
- const value = await ctx.ui.select(settingPrompt(field), scopes.map(scopeLabel).concat(CANCEL));
91
- if (!value || value === CANCEL) return undefined;
92
- return value === "User" ? "global" : "project";
93
- }
94
-
95
- async function handleResetAction(
96
- action: string,
97
- ctx: ExtensionCommandContext,
98
- deps: MemoryOperationsDeps,
99
- field: ConfigEditingField,
100
- ): Promise<boolean> {
101
- if (action === "Remove project override") {
102
- await resetField(ctx, deps, field, "project");
103
- return true;
104
- }
105
- if (action === "Remove user override") {
106
- await resetField(ctx, deps, field, "global");
107
- return true;
108
- }
109
- return false;
110
- }
111
-
112
- async function promptScopedValue(
113
- ctx: ExtensionCommandContext,
114
- deps: MemoryOperationsDeps,
115
- field: ConfigEditingField,
116
- ): Promise<{ scope: ConfigScope; value: string } | undefined> {
117
- if (field.kind === "boolean" || field.kind === "select") {
118
- const values = field.kind === "boolean" ? ["Enable", "Disable"] : (field.choices ?? []);
119
- const action = await ctx.ui.select(settingPrompt(field), withScopedValues(field, values));
120
- if (!action || action === CANCEL) return undefined;
121
- if (await handleResetAction(action, ctx, deps, field)) return undefined;
122
- return parseScopedAction(action);
123
- }
124
-
125
- const scope = await chooseScope(ctx, field);
126
- if (!scope) return undefined;
127
- const value = await inputWithPrefill(
128
- ctx.ui,
129
- settingPrompt(field),
130
- inputDefaultForConfigEditingField(field.id, deps.getConfig(), deps.getProjectBankId()),
131
- );
132
- const parsed = parseConfigEditingFieldInput(field, value);
133
- if (parsed === undefined) return undefined;
134
- return { scope, value: parsed };
135
- }
136
-
137
- export async function handleResetFieldAction(args: {
138
- ctx: ExtensionCommandContext;
139
- deps: MemoryOperationsDeps;
140
- config: ResolvedConfig;
141
- projectBankId: string;
142
- fieldId: FieldId;
143
- }): Promise<void> {
144
- const field = buildConfigEditingFields(
145
- args.config,
146
- args.projectBankId,
147
- readConfigLayers(args.ctx.cwd),
148
- ).find((item) => item.id === args.fieldId);
149
- if (field) {
150
- await resetField(args.ctx, args.deps, field, field.source === "global" ? "global" : "project");
151
- }
152
- }
153
-
154
- export async function handleFieldEdit(args: {
155
- fieldId: FieldId;
156
- ctx: ExtensionCommandContext;
157
- deps: MemoryOperationsDeps;
158
- config: ResolvedConfig;
159
- projectBankId: string;
160
- }): Promise<void> {
161
- const layers = readConfigLayers(args.ctx.cwd);
162
- const field = buildConfigEditingFields(args.config, args.projectBankId, layers).find(
163
- (item) => item.id === args.fieldId,
164
- );
165
- if (!field) return;
166
-
167
- const scoped = await promptScopedValue(args.ctx, args.deps, field);
168
- if (!scoped) return;
169
- const patch = patchForConfigEditingField(field.id, scoped.value, args.config);
170
- if (patch) await writeAndReload(args.ctx, args.deps, patch, scoped.scope);
171
- }
172
-
173
- export async function handleDeployment(
174
- ctx: ExtensionCommandContext,
175
- deps: MemoryOperationsDeps,
176
- config: ResolvedConfig,
177
- ): Promise<void> {
178
- const value = await ctx.ui.select("Hindsight deployment", [
179
- "Hindsight Cloud",
180
- "Existing local/external API",
181
- "Local hindsight-embed guidance",
182
- CANCEL,
183
- ]);
184
- if (value === "Hindsight Cloud") {
185
- const baseUrl = await ctx.ui.input("Hindsight Cloud base URL", config.hindsight.baseUrl);
186
- if (baseUrl) await writeAndReload(ctx, deps, { baseUrl: baseUrl.trim() });
187
- const envName = await ctx.ui.input("API key env var name", "HINDSIGHT_API_TOKEN");
188
- if (envName) await writeAndReload(ctx, deps, { apiKeyEnvVar: envName.trim() });
189
- } else if (value === "Existing local/external API") {
190
- const baseUrl = await ctx.ui.input("Hindsight API base URL", config.hindsight.baseUrl);
191
- if (baseUrl) await writeAndReload(ctx, deps, { baseUrl: baseUrl.trim() });
192
- } else if (value === "Local hindsight-embed guidance") {
193
- ctx.ui.notify(LOCAL_EMBED_GUIDANCE, "info");
194
- const useDefault = await ctx.ui.select("Set API URL to http://localhost:8888?", [
195
- "Yes",
196
- "No",
197
- CANCEL,
198
- ]);
199
- if (useDefault === "Yes") await writeAndReload(ctx, deps, { baseUrl: "http://localhost:8888" });
200
- }
201
- }
@@ -1,47 +0,0 @@
1
- import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
2
- import type { ResolvedConfig } from "../types.js";
3
- import {
4
- buildConfigEditingTabs,
5
- readConfigLayers,
6
- type ConfigEditingTab,
7
- } from "../config/config-editing-model.js";
8
- import type { MemoryOperationsDeps } from "../operations/memory-operation-service.js";
9
- import { listRetainReceipts } from "../lifecycle/retain-receipts.js";
10
- import { collectStatusHealthFacts } from "../utils/status-health.js";
11
- import { buildRetainReceiptStatusFacts } from "./setup-tui-render.js";
12
- import { RECEIPT_FACT_LIMIT, type SetupUiState } from "./setup-tui-types.js";
13
-
14
- export async function buildSetupTabs(args: {
15
- ctx: ExtensionCommandContext;
16
- config: ResolvedConfig;
17
- projectBankId: string;
18
- deps: MemoryOperationsDeps;
19
- state: SetupUiState;
20
- }): Promise<ConfigEditingTab[]> {
21
- const statusFacts = await collectStatusHealthFacts({
22
- client: args.deps.getClient(),
23
- config: args.config,
24
- projectBankId: args.projectBankId,
25
- });
26
- const receiptFacts = buildRetainReceiptStatusFacts(
27
- await listRetainReceipts(args.ctx.cwd, RECEIPT_FACT_LIMIT),
28
- );
29
- return buildConfigEditingTabs(
30
- args.config,
31
- args.projectBankId,
32
- readConfigLayers(args.ctx.cwd),
33
- [...buildInitHealthFacts(args.deps.getInitHealth?.()), ...statusFacts, ...receiptFacts],
34
- { showAdvanced: Boolean(args.state.showAdvanced) },
35
- );
36
- }
37
-
38
- export function buildInitHealthFacts(
39
- initHealth: ReturnType<NonNullable<MemoryOperationsDeps["getInitHealth"]>>,
40
- ): Array<[string, string]> {
41
- if (!initHealth) return [];
42
- if (initHealth.failures.length === 0) return [["Startup", `ok (${initHealth.checkedAt})`]];
43
- return initHealth.failures.map((failure) => [
44
- `Startup ${failure.subsystem}`,
45
- `failed: ${failure.error}`,
46
- ]);
47
- }
@@ -1,239 +0,0 @@
1
- import { DynamicBorder } from "@earendil-works/pi-coding-agent";
2
- import { truncateToWidth, visibleWidth, type Component } from "@earendil-works/pi-tui";
3
- import type { ConfigEditingTab } from "../config/config-editing-model.js";
4
- import type { RetainReceipt } from "../lifecycle/retain-receipts.js";
5
- import { formatRetainOutcome } from "../queue/flush-presenter.js";
6
- import {
7
- applySetupIntent,
8
- currentSetupTab,
9
- normalizeSetupUiState,
10
- selectedSetupField,
11
- selectedSetupIndex,
12
- setupIntentFromInput,
13
- } from "./setup-flow.js";
14
- import {
15
- HUB_ACTION_HELP,
16
- RECEIPT_FACT_LIMIT,
17
- type SetupActionId,
18
- type SetupUiState,
19
- type ThemeLike,
20
- } from "./setup-tui-types.js";
21
-
22
- const MIN_BODY_LINES = 30;
23
- const DOCS_BASE_URL = "https://luxus.github.io/pi-hindsight";
24
-
25
- const TAB_DOCS: Record<string, string> = {
26
- Status: `${DOCS_BASE_URL}/guides/use-hindsight-status/`,
27
- Connection: `${DOCS_BASE_URL}/start/installation/`,
28
- Banks: `${DOCS_BASE_URL}/concepts/memory-banks/`,
29
- Recall: `${DOCS_BASE_URL}/concepts/retain-recall-reflect/`,
30
- Retain: `${DOCS_BASE_URL}/concepts/queue-durability/`,
31
- Import: `${DOCS_BASE_URL}/guides/importing-sessions/`,
32
- UI: `${DOCS_BASE_URL}/start/setup-tui/`,
33
- };
34
-
35
- function fitColumns(left: string, right: string, width: number): string {
36
- if (width <= 0) return "";
37
- if (width < 40) return truncateToWidth(`${left} ${right}`, width);
38
- const rightWidth = Math.min(Math.max(12, visibleWidth(right)), Math.floor(width * 0.38));
39
- const leftWidth = Math.max(1, width - rightWidth - 1);
40
- return `${truncateToWidth(left, leftWidth)} ${truncateToWidth(right, rightWidth)}`;
41
- }
42
-
43
- function borderLine(
44
- width: number,
45
- left: string,
46
- fill: string,
47
- right: string,
48
- theme: ThemeLike,
49
- ): string {
50
- return theme.fg("borderAccent", `${left}${fill.repeat(Math.max(0, width - 2))}${right}`);
51
- }
52
-
53
- function padVisibleRight(content: string, width: number): string {
54
- const truncated = truncateToWidth(content, width);
55
- return `${truncated}${" ".repeat(Math.max(0, width - visibleWidth(truncated)))}`;
56
- }
57
-
58
- function boxed(content: string, width: number, theme: ThemeLike): string {
59
- if (width < 2) return truncateToWidth(content, width);
60
- return `${theme.fg("borderAccent", "│")}${padVisibleRight(content, width - 2)}${theme.fg("borderAccent", "│")}`;
61
- }
62
-
63
- function shortDocumentId(documentId: string): string {
64
- const parts = documentId.split(":");
65
- if (parts[0] === "pi-explicit" && parts.length >= 3) return `${parts[0]}:${parts[2]}`;
66
- return documentId;
67
- }
68
-
69
- function wrapWords(text: string, width: number): string[] {
70
- if (width <= 0) return [""];
71
- const words = text.split(/\s+/).filter(Boolean);
72
- const lines: string[] = [];
73
- let current = "";
74
- for (const word of words) {
75
- if (!current) current = word;
76
- else if (`${current} ${word}`.length <= width) current = `${current} ${word}`;
77
- else {
78
- lines.push(current);
79
- current = word;
80
- }
81
- }
82
- if (current) lines.push(current);
83
- return lines.length ? lines : [""];
84
- }
85
-
86
- export function buildRetainReceiptStatusFacts(receipts: RetainReceipt[]): Array<[string, string]> {
87
- if (receipts.length === 0) return [["Retain receipts", "none"]];
88
- return receipts.slice(0, RECEIPT_FACT_LIMIT).map((receipt, index) => {
89
- const outcome = formatRetainOutcome(receipt.outcome);
90
- const value = `${receipt.bankId} ${shortDocumentId(receipt.documentId)}${
91
- outcome ? ` (${outcome})` : ""
92
- }`;
93
- return [index === 0 ? "Recent retain" : `Recent retain ${index + 1}`, value];
94
- });
95
- }
96
-
97
- export function createSetupComponent(
98
- tabs: ConfigEditingTab[],
99
- theme: ThemeLike,
100
- state: SetupUiState,
101
- done: (action: SetupActionId | null) => void,
102
- ): Component {
103
- Object.assign(state, normalizeSetupUiState(tabs, state));
104
-
105
- return {
106
- render(width: number): string[] {
107
- Object.assign(state, normalizeSetupUiState(tabs, state));
108
- const tab = currentSetupTab(tabs, state) ?? tabs[0]!;
109
- const lines: string[] = [];
110
- const innerWidth = Math.max(0, width - 2);
111
- const changedCount = tabs.reduce(
112
- (count, item) => count + item.fields.filter((field) => field.changed).length,
113
- 0,
114
- );
115
- const horizontal = new DynamicBorder((s: string) => theme.fg("borderAccent", s));
116
-
117
- lines.push(...horizontal.render(width));
118
- lines.push(borderLine(width, "╭", "─", "╮", theme));
119
- lines.push(
120
- boxed(
121
- ` ${theme.fg("accent", theme.bold("Hindsight setup"))} ${theme.fg("dim", "saved immediately after edit · changed values marked *")}`,
122
- width,
123
- theme,
124
- ),
125
- );
126
- lines.push(
127
- boxed(` ${theme.fg("dim", `${changedCount} changed from defaults`)}`, width, theme),
128
- );
129
- lines.push(boxed("", width, theme));
130
-
131
- const tabLine = tabs
132
- .map((item, index) => {
133
- const dirty = item.fields.some((field) => field.changed) ? "*" : "";
134
- const label = ` ${item.id}${dirty} `;
135
- return index === state.tabIndex
136
- ? theme.bg("selectedBg", theme.fg("accent", theme.bold(label)))
137
- : theme.fg("muted", label);
138
- })
139
- .join(" ");
140
- lines.push(boxed(tabLine, width, theme));
141
- lines.push(boxed("", width, theme));
142
-
143
- lines.push(
144
- boxed(
145
- theme.fg(
146
- "accent",
147
- theme.bold(tab.id === "Status" ? "Memory status" : `${tab.id} settings`),
148
- ),
149
- width,
150
- theme,
151
- ),
152
- );
153
- if (tab.facts) {
154
- for (const [label, value] of tab.facts) {
155
- lines.push(
156
- boxed(
157
- fitColumns(
158
- ` ${theme.fg("muted", `${label}:`)}`,
159
- theme.fg("text", value),
160
- innerWidth,
161
- ),
162
- width,
163
- theme,
164
- ),
165
- );
166
- }
167
- } else {
168
- lines.push(
169
- boxed(theme.fg("dim", fitColumns("Setting", "Value", innerWidth)), width, theme),
170
- );
171
- }
172
-
173
- for (const [index, field] of tab.fields.entries()) {
174
- const isSelected = index === selectedSetupIndex(tabs, state);
175
- const marker = isSelected ? theme.fg("accent", "→") : " ";
176
- const dirty = field.changed ? theme.fg("warning", "*") : " ";
177
- const label = isSelected
178
- ? theme.fg("accent", theme.bold(field.label))
179
- : theme.fg("text", field.label);
180
- const rawValue = `${field.value} [${field.source ?? "default"}]`;
181
- const value = field.changed ? theme.fg("warning", rawValue) : theme.fg("text", rawValue);
182
- lines.push(
183
- boxed(fitColumns(`${marker}${dirty} ${label}`, value, innerWidth), width, theme),
184
- );
185
- }
186
-
187
- const detailField = selectedSetupField(tabs, state);
188
- if (detailField) {
189
- lines.push(boxed("", width, theme));
190
- lines.push(boxed(theme.fg("accent", theme.bold("Details")), width, theme));
191
- const details = [
192
- `Docs: ${TAB_DOCS[detailField.tab] ?? `${DOCS_BASE_URL}/reference/configuration/`}`,
193
- detailField.description,
194
- `Default: ${detailField.defaultValue}`,
195
- ...(detailField.projectValue ? [`Project: ${detailField.projectValue}`] : []),
196
- ...(detailField.globalValue ? [`User: ${detailField.globalValue}`] : []),
197
- ...(detailField.envValue ? [`Env: ${detailField.envValue}`] : []),
198
- ];
199
- for (const detail of details) {
200
- for (const line of wrapWords(detail, innerWidth - 3)) {
201
- lines.push(boxed(` ${theme.fg("dim", line)}`, width, theme));
202
- }
203
- }
204
- } else if (tab.id === "Status") {
205
- lines.push(boxed("", width, theme));
206
- lines.push(boxed(theme.fg("accent", theme.bold("Docs")), width, theme));
207
- for (const line of wrapWords(`Status guide: ${TAB_DOCS.Status}`, innerWidth - 3)) {
208
- lines.push(boxed(` ${theme.fg("dim", line)}`, width, theme));
209
- }
210
- }
211
-
212
- while (lines.length < MIN_BODY_LINES) lines.push(boxed("", width, theme));
213
-
214
- lines.push(
215
- boxed(
216
- theme.fg(
217
- "dim",
218
- state.showAdvanced
219
- ? ` advanced · h/l tabs · j/k · enter edit · r reset ·${HUB_ACTION_HELP}`
220
- : ` hub ·${HUB_ACTION_HELP}`,
221
- ),
222
- width,
223
- theme,
224
- ),
225
- );
226
- lines.push(borderLine(width, "╰", "─", "╯", theme));
227
- lines.push(...horizontal.render(width));
228
- return lines.map((line) => truncateToWidth(line, width));
229
- },
230
- handleInput(data: string): void {
231
- const intent = setupIntentFromInput(data);
232
- if (!intent) return;
233
- const result = applySetupIntent(tabs, state, intent);
234
- Object.assign(state, result.state);
235
- if (result.kind === "action") done(result.action);
236
- },
237
- invalidate(): void {},
238
- };
239
- }
@@ -1,50 +0,0 @@
1
- import type { FieldId, TabId } from "../config/config-editing-model.js";
2
-
3
- /** Day-to-day hub actions reachable from the `/hindsight` TUI. */
4
- export type HubActionId =
5
- | "choose-deployment"
6
- | "guided-setup"
7
- | "flush-queue"
8
- | "set-mode"
9
- | "next-opt-out"
10
- | "apply-mental-models"
11
- | "import-sessions"
12
- | "run-doctor"
13
- | "init-config"
14
- | "toggle-advanced"
15
- | "done";
16
-
17
- export type SetupActionId = FieldId | `reset:${FieldId}` | HubActionId;
18
-
19
- export type SetupStep = "config" | "profile" | "banks" | "review" | "done";
20
-
21
- export type SetupProfileChoice =
22
- | "project-user"
23
- | "project-only"
24
- | "isolated-only"
25
- | "user-only"
26
- | "recall-only";
27
-
28
- export type SetupUiState = {
29
- step?: SetupStep;
30
- tabIndex: number;
31
- selectedByTab: Partial<Record<TabId, number>>;
32
- showAdvanced?: boolean;
33
- profileChoice?: SetupProfileChoice;
34
- };
35
-
36
- export type ThemeLike = {
37
- fg(
38
- color: "accent" | "muted" | "dim" | "success" | "error" | "warning" | "borderAccent" | "text",
39
- text: string,
40
- ): string;
41
- bg(color: "selectedBg", text: string): string;
42
- bold(text: string): string;
43
- };
44
-
45
- export const RECEIPT_FACT_LIMIT = 3;
46
- export const CANCEL = "Cancel";
47
-
48
- /** Hub footer: status/setup/emergency first; import/templates/advanced demoted (agent tools own day-to-day edits). */
49
- export const HUB_ACTION_HELP =
50
- " g guided · m mode · x next-opt-out · f flush · o doctor · n init · d deployment · i import · t templates · a advanced · q close ";