@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,648 +0,0 @@
1
- import { resolveProjectIdentity } from "../banks/banking.js";
2
- import { resolveOperationBank } from "../banks/bank-selection.js";
3
- import { buildStatusFields } from "../utils/status-fields.js";
4
- import type { MemoryOperationsDeps } from "./memory-operation-types.js";
5
- import { isMemorySetupComplete, setupRequiredMessage } from "../config/setup-gate.js";
6
- import { configureMemory, type ProjectConfigPatchInput } from "../config/config-writer.js";
7
- import { seedKnowledgePages } from "../banks/knowledge-page-seed.js";
8
- import type { HindsightLikeClient, ResolvedConfig, TagsMatch } from "../types.js";
9
-
10
- /** Keys agents may read/patch via hindsight_config (no raw secrets). */
11
- export const AGENT_CONFIG_ALLOWLIST = [
12
- "setupComplete",
13
- "scopeMode",
14
- "projectId",
15
- "projectIdStrategy",
16
- "includeSharedObservations",
17
- "projectBankId",
18
- "enableGlobalBank",
19
- "globalBankId",
20
- "agentUse",
21
- "mentalModelsInject",
22
- "memoryProfile",
23
- "recallEnabled",
24
- "recallBudget",
25
- "recallMaxTokens",
26
- "retainEnabled",
27
- "baseUrl",
28
- "apiKeyEnvVar",
29
- "timeoutMs",
30
- ] as const;
31
-
32
- export type AgentConfigKey = (typeof AGENT_CONFIG_ALLOWLIST)[number];
33
-
34
- const ALLOWLIST_SET = new Set<string>(AGENT_CONFIG_ALLOWLIST);
35
-
36
- export function agentConfigView(config: ResolvedConfig): Record<AgentConfigKey, unknown> {
37
- let memoryProfile: string = "project-only";
38
- if (config.recall.enabled && !config.retain.enabled) memoryProfile = "recall-only";
39
- else if (!config.banks.project.enabled && config.banks.user.enabled)
40
- memoryProfile = "global-only";
41
- else if (config.banks.project.enabled && config.banks.user.enabled)
42
- memoryProfile = "project+global";
43
-
44
- return {
45
- setupComplete: config.setupComplete,
46
- scopeMode: config.scope.mode,
47
- projectId: config.scope.projectId,
48
- projectIdStrategy: config.scope.projectIdStrategy,
49
- includeSharedObservations: config.scope.includeSharedObservations,
50
- projectBankId: config.banks.project.bankId,
51
- enableGlobalBank: config.banks.user.enabled,
52
- globalBankId: config.banks.user.bankId,
53
- agentUse: config.agentUse,
54
- mentalModelsInject: config.mentalModels.inject,
55
- memoryProfile,
56
- recallEnabled: config.recall.enabled,
57
- recallBudget: config.recall.budget,
58
- recallMaxTokens: config.recall.maxTokens,
59
- retainEnabled: config.retain.enabled,
60
- baseUrl: config.hindsight.baseUrl,
61
- apiKeyEnvVar: config.hindsight.apiKeyRef?.startsWith("env:")
62
- ? config.hindsight.apiKeyRef.slice(4)
63
- : undefined,
64
- timeoutMs: config.hindsight.timeoutMs,
65
- };
66
- }
67
-
68
- const ENUM_STRINGS: Partial<Record<AgentConfigKey, readonly string[]>> = {
69
- scopeMode: ["domain-tagged", "isolated-bank"],
70
- projectIdStrategy: ["remote", "basename"],
71
- agentUse: ["coding", "conversation"],
72
- memoryProfile: ["project-only", "project+global", "global-only", "recall-only"],
73
- recallBudget: ["low", "mid", "high"],
74
- };
75
-
76
- const BOOLEAN_KEYS = new Set<AgentConfigKey>([
77
- "setupComplete",
78
- "includeSharedObservations",
79
- "enableGlobalBank",
80
- "mentalModelsInject",
81
- "recallEnabled",
82
- "retainEnabled",
83
- ]);
84
-
85
- const NUMBER_KEYS = new Set<AgentConfigKey>(["recallMaxTokens", "timeoutMs"]);
86
-
87
- function assertAgentConfigValue(key: AgentConfigKey, value: unknown): unknown {
88
- if (BOOLEAN_KEYS.has(key)) {
89
- if (typeof value !== "boolean") {
90
- throw new Error(`Config field ${key} must be a boolean`);
91
- }
92
- return value;
93
- }
94
- if (NUMBER_KEYS.has(key)) {
95
- if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
96
- throw new Error(`Config field ${key} must be a non-negative number`);
97
- }
98
- return value;
99
- }
100
- const allowed = ENUM_STRINGS[key];
101
- if (allowed) {
102
- if (typeof value !== "string" || !allowed.includes(value)) {
103
- throw new Error(`Config field ${key} must be one of: ${allowed.join(", ")}`);
104
- }
105
- return value;
106
- }
107
- if (typeof value !== "string" || !value.trim()) {
108
- throw new Error(`Config field ${key} must be a non-empty string`);
109
- }
110
- return value;
111
- }
112
-
113
- /** Keep only allowlisted keys from a tool patch object. Rejects unknown keys and bad types. */
114
- export function pickAgentConfigPatch(raw: Record<string, unknown>): ProjectConfigPatchInput {
115
- const unknown = Object.keys(raw).filter((k) => !ALLOWLIST_SET.has(k));
116
- if (unknown.length) {
117
- throw new Error(
118
- `Config keys not allowlisted for agent patch: ${unknown.join(", ")}. Allowed: ${AGENT_CONFIG_ALLOWLIST.join(", ")}`,
119
- );
120
- }
121
- const out: ProjectConfigPatchInput = {};
122
- for (const key of AGENT_CONFIG_ALLOWLIST) {
123
- if (raw[key] === undefined) continue;
124
- const value = assertAgentConfigValue(key, raw[key]);
125
- (out as Record<string, unknown>)[key] = value;
126
- }
127
- if (Object.keys(out).length === 0) {
128
- throw new Error("Provide at least one allowlisted config field to patch.");
129
- }
130
- return out;
131
- }
132
-
133
- /** Domain-tagged coding bank must not mark setup complete without an explicit bankId. */
134
- export function assertAgentConfigPatchSafe(
135
- patch: ProjectConfigPatchInput,
136
- current: ResolvedConfig,
137
- ): void {
138
- const mode = patch.scopeMode ?? current.scope.mode;
139
- const projectEnabled =
140
- patch.memoryProfile === "global-only" || patch.memoryProfile === "recall-only"
141
- ? false
142
- : patch.memoryProfile
143
- ? true
144
- : current.banks.project.enabled;
145
- const bankId =
146
- typeof patch.projectBankId === "string" && patch.projectBankId.trim()
147
- ? patch.projectBankId.trim()
148
- : current.banks.project.bankId?.trim();
149
- const wantsSetupComplete = patch.setupComplete === true;
150
- if (wantsSetupComplete && mode === "domain-tagged" && projectEnabled && !bankId) {
151
- throw new Error(
152
- "Cannot set setupComplete=true in domain-tagged mode without projectBankId. Set projectBankId to the shared coding bank first.",
153
- );
154
- }
155
- }
156
-
157
- function clientMethod<K extends keyof HindsightLikeClient>(
158
- deps: MemoryOperationsDeps,
159
- method: K,
160
- ): NonNullable<HindsightLikeClient[K]> {
161
- const client = deps.getClient();
162
- const fn = client[method];
163
- if (typeof fn !== "function") {
164
- throw new Error(`Hindsight client does not support ${String(method)}.`);
165
- }
166
- // Bind without typing bind's overload union (optional methods vary).
167
- return (fn as (...args: never[]) => unknown).bind(client) as NonNullable<HindsightLikeClient[K]>;
168
- }
169
-
170
- /** Agent-facing list fields only (no content / reflect_response / source facts). */
171
- export type MentalModelListItemMetadata = {
172
- id: string;
173
- name: string;
174
- tags?: string[];
175
- max_tokens?: number;
176
- last_refreshed_at?: string;
177
- };
178
-
179
- function mentalModelListRows(response: unknown): Array<Record<string, unknown>> {
180
- if (Array.isArray(response)) {
181
- return response.filter((entry): entry is Record<string, unknown> =>
182
- Boolean(entry && typeof entry === "object"),
183
- );
184
- }
185
- if (!response || typeof response !== "object") return [];
186
- const body = response as { items?: unknown; mental_models?: unknown };
187
- const rows = Array.isArray(body.items)
188
- ? body.items
189
- : Array.isArray(body.mental_models)
190
- ? body.mental_models
191
- : [];
192
- return rows.filter((entry): entry is Record<string, unknown> =>
193
- Boolean(entry && typeof entry === "object"),
194
- );
195
- }
196
-
197
- /**
198
- * Project a listMentalModels response to metadata-only items for agent tools.
199
- * Drops content, reflect_response, and other heavy fields even if the server returns them.
200
- */
201
- export function projectMentalModelListMetadata(response: unknown): {
202
- items: MentalModelListItemMetadata[];
203
- } {
204
- const items: MentalModelListItemMetadata[] = [];
205
- for (const row of mentalModelListRows(response)) {
206
- const id = typeof row.id === "string" ? row.id : undefined;
207
- const name = typeof row.name === "string" ? row.name : undefined;
208
- if (!id || !name) continue;
209
- const tags = Array.isArray(row.tags)
210
- ? row.tags.filter((tag): tag is string => typeof tag === "string")
211
- : undefined;
212
- const maxTokens =
213
- typeof row.max_tokens === "number"
214
- ? row.max_tokens
215
- : typeof row.maxTokens === "number"
216
- ? row.maxTokens
217
- : undefined;
218
- const lastRefreshedAt =
219
- typeof row.last_refreshed_at === "string"
220
- ? row.last_refreshed_at
221
- : typeof row.lastRefreshedAt === "string"
222
- ? row.lastRefreshedAt
223
- : undefined;
224
- const item: MentalModelListItemMetadata = { id, name };
225
- if (tags !== undefined) item.tags = tags;
226
- if (maxTokens !== undefined) item.max_tokens = maxTokens;
227
- if (lastRefreshedAt !== undefined) item.last_refreshed_at = lastRefreshedAt;
228
- items.push(item);
229
- }
230
- return { items };
231
- }
232
-
233
- export function createControlOperations(deps: MemoryOperationsDeps) {
234
- return {
235
- async status(cwd: string) {
236
- const config = deps.getConfig();
237
- const fields = buildStatusFields(config, {
238
- cwd,
239
- projectBankId: deps.getProjectBankId(),
240
- });
241
- const { buildSyncStatus } = await import("../lifecycle/git-seed.js");
242
- const sync = await buildSyncStatus({
243
- cwd,
244
- config,
245
- client: deps.getClient(),
246
- bankId: deps.getProjectBankId(),
247
- });
248
- return {
249
- setupComplete: isMemorySetupComplete(config, cwd),
250
- ...(isMemorySetupComplete(config, cwd) ? {} : { setupHint: setupRequiredMessage() }),
251
- project: resolveProjectIdentity(cwd, config),
252
- fields,
253
- sync,
254
- };
255
- },
256
-
257
- scopeInfo(cwd: string) {
258
- const config = deps.getConfig();
259
- const project = resolveProjectIdentity(cwd, config);
260
- return {
261
- scopeMode: config.scope.mode,
262
- projectId: project.projectId,
263
- basis: project.basis,
264
- source: project.source,
265
- projectTag: `project:${project.projectId}`,
266
- legacyRepoTag: `repo:${project.legacyRepoKey}`,
267
- codingBankId: deps.getProjectBankId(),
268
- lifeBankId: config.banks.user.enabled ? config.banks.user.bankId : undefined,
269
- dualTagWindow: true,
270
- };
271
- },
272
-
273
- async bankGet(args: { bank?: string }) {
274
- const config = deps.getConfig();
275
- const bankId = resolveOperationBank({
276
- requestedBank: args.bank,
277
- config,
278
- projectBankId: deps.getProjectBankId(),
279
- });
280
- const client = deps.getClient();
281
- const [profile, stats, bankConfig] = await Promise.all([
282
- client.getBankProfile?.(bankId),
283
- client.getBankStats?.(bankId),
284
- client.getBankConfig?.(bankId),
285
- ]);
286
- return { bankId, profile, stats, config: bankConfig };
287
- },
288
-
289
- async bankUpdateMission(args: {
290
- bank?: string;
291
- retainMission?: string;
292
- reflectMission?: string;
293
- observationsMission?: string;
294
- dryRun?: boolean;
295
- }) {
296
- const config = deps.getConfig();
297
- const bankId = resolveOperationBank({
298
- requestedBank: args.bank,
299
- config,
300
- projectBankId: deps.getProjectBankId(),
301
- });
302
- const patch = {
303
- ...(args.retainMission !== undefined ? { retainMission: args.retainMission } : {}),
304
- ...(args.reflectMission !== undefined ? { reflectMission: args.reflectMission } : {}),
305
- ...(args.observationsMission !== undefined
306
- ? { observationsMission: args.observationsMission }
307
- : {}),
308
- };
309
- if (Object.keys(patch).length === 0) {
310
- throw new Error(
311
- "Provide at least one of retainMission, reflectMission, observationsMission.",
312
- );
313
- }
314
- // Mutating ops default dry-run at the operation layer (not only the tool catalog).
315
- if (args.dryRun ?? true) {
316
- return { dryRun: true, bankId, wouldUpdate: patch };
317
- }
318
- const update = clientMethod(deps, "updateBankConfig");
319
- const result = await update(bankId, patch);
320
- return { bankId, updated: patch, result };
321
- },
322
-
323
- async mentalModel(args: {
324
- action: "list" | "get" | "create" | "update" | "refresh" | "delete";
325
- bank?: string;
326
- id?: string;
327
- name?: string;
328
- sourceQuery?: string;
329
- tags?: string[];
330
- maxTokens?: number;
331
- /** How model tags filter source memories on refresh (create/update trigger). */
332
- tagsMatch?: TagsMatch;
333
- dryRun?: boolean;
334
- cwd: string;
335
- }) {
336
- const config = deps.getConfig();
337
- const bankId = resolveOperationBank({
338
- requestedBank: args.bank,
339
- config,
340
- projectBankId: deps.getProjectBankId(),
341
- });
342
- const project = resolveProjectIdentity(args.cwd, config);
343
- const isUserBank =
344
- args.bank === "global" ||
345
- args.bank === "user" ||
346
- (config.banks.user.bankId !== undefined && args.bank === config.banks.user.bankId);
347
-
348
- switch (args.action) {
349
- case "list": {
350
- const list = clientMethod(deps, "listMentalModels");
351
- // Prefer server metadata detail; always project so agent context cannot carry content.
352
- const raw = await list(bankId, { detail: "metadata" });
353
- return { bankId, result: projectMentalModelListMetadata(raw) };
354
- }
355
- case "get": {
356
- if (!args.id) throw new Error("id is required for get");
357
- const get = clientMethod(deps, "getMentalModel");
358
- return { bankId, result: await get(bankId, args.id) };
359
- }
360
- case "create": {
361
- if (!args.name?.trim() || !args.sourceQuery?.trim()) {
362
- throw new Error("name and sourceQuery are required for create");
363
- }
364
- const tags =
365
- args.tags ??
366
- (isUserBank ? ["source:pi"] : ["source:pi", `project:${project.projectId}`]);
367
- const trigger = {
368
- refreshAfterConsolidation: true as const,
369
- ...(args.tagsMatch ? { tagsMatch: args.tagsMatch } : {}),
370
- };
371
- if (args.dryRun ?? true) {
372
- return {
373
- dryRun: true,
374
- bankId,
375
- wouldCreate: {
376
- name: args.name,
377
- sourceQuery: args.sourceQuery,
378
- tags,
379
- trigger,
380
- },
381
- };
382
- }
383
- const create = clientMethod(deps, "createMentalModel");
384
- const result = await create(bankId, args.name.trim(), args.sourceQuery.trim(), {
385
- ...(args.id ? { id: args.id } : {}),
386
- tags,
387
- ...(args.maxTokens !== undefined ? { maxTokens: args.maxTokens } : {}),
388
- trigger,
389
- });
390
- return { bankId, result };
391
- }
392
- case "update": {
393
- if (!args.id) throw new Error("id is required for update");
394
- const options = {
395
- ...(args.name !== undefined ? { name: args.name } : {}),
396
- ...(args.sourceQuery !== undefined ? { sourceQuery: args.sourceQuery } : {}),
397
- ...(args.tags !== undefined ? { tags: args.tags } : {}),
398
- ...(args.maxTokens !== undefined ? { maxTokens: args.maxTokens } : {}),
399
- ...(args.tagsMatch
400
- ? { trigger: { refreshAfterConsolidation: true, tagsMatch: args.tagsMatch } }
401
- : {}),
402
- };
403
- if (Object.keys(options).length === 0) {
404
- throw new Error(
405
- "Provide name, sourceQuery, tags, maxTokens, and/or tagsMatch for update",
406
- );
407
- }
408
- if (args.dryRun ?? true)
409
- return { dryRun: true, bankId, id: args.id, wouldUpdate: options };
410
- const update = clientMethod(deps, "updateMentalModel");
411
- return { bankId, result: await update(bankId, args.id, options) };
412
- }
413
- case "refresh": {
414
- if (!args.id) throw new Error("id is required for refresh");
415
- if (args.dryRun ?? true) return { dryRun: true, bankId, id: args.id, wouldRefresh: true };
416
- const refresh = clientMethod(deps, "refreshMentalModel");
417
- return { bankId, result: await refresh(bankId, args.id) };
418
- }
419
- case "delete": {
420
- if (!args.id) throw new Error("id is required for delete");
421
- const del = clientMethod(deps, "deleteMentalModel");
422
- return {
423
- bankId,
424
- result: await del(bankId, args.id, { dryRun: args.dryRun ?? true }),
425
- };
426
- }
427
- default:
428
- throw new Error(`Unknown mental model action: ${String(args.action)}`);
429
- }
430
- },
431
-
432
- /**
433
- * Knowledge pages control plane (tree/search/get + dry-run mutating folder/page ops).
434
- * Requires a Hindsight client/server that exposes knowledge-base methods.
435
- */
436
- async knowledge(args: {
437
- action:
438
- | "tree"
439
- | "search"
440
- | "get"
441
- | "export"
442
- | "seed_taxonomy"
443
- | "create_page"
444
- | "create_folder"
445
- | "update"
446
- | "delete";
447
- bank?: string;
448
- id?: string;
449
- query?: string;
450
- limit?: number;
451
- name?: string;
452
- sourceQuery?: string;
453
- parentId?: string | null;
454
- tags?: string[];
455
- maxTokens?: number;
456
- /** Page create only — when set, restates server page defaults + tagsMatch (trigger replace). */
457
- tagsMatch?: TagsMatch;
458
- dryRun?: boolean;
459
- cwd: string;
460
- }) {
461
- const config = deps.getConfig();
462
- const bankId = resolveOperationBank({
463
- requestedBank: args.bank,
464
- config,
465
- projectBankId: deps.getProjectBankId(),
466
- });
467
- const project = resolveProjectIdentity(args.cwd, config);
468
- const isUserBank =
469
- args.bank === "global" ||
470
- args.bank === "user" ||
471
- (config.banks.user.bankId !== undefined && args.bank === config.banks.user.bankId);
472
-
473
- switch (args.action) {
474
- case "tree": {
475
- const tree = clientMethod(deps, "getKnowledgeBaseTree");
476
- return { bankId, result: await tree(bankId) };
477
- }
478
- case "seed_taxonomy": {
479
- // Idempotent five-page coding taxonomy; degrades when pages are unavailable.
480
- const baseTags = isUserBank
481
- ? ["source:pi"]
482
- : ["source:pi", `project:${project.projectId}`];
483
- const seed = await seedKnowledgePages({
484
- client: deps.getClient(),
485
- bankId,
486
- baseTags,
487
- dryRun: args.dryRun ?? true,
488
- });
489
- return { bankId, seed };
490
- }
491
- case "search": {
492
- if (!args.query?.trim()) throw new Error("query is required for search");
493
- const search = clientMethod(deps, "searchKnowledgeBase");
494
- return {
495
- bankId,
496
- result: await search(
497
- bankId,
498
- args.query.trim(),
499
- args.limit !== undefined ? { limit: args.limit } : undefined,
500
- ),
501
- };
502
- }
503
- case "get": {
504
- if (!args.id) throw new Error("id is required for get");
505
- const get = clientMethod(deps, "getKnowledgePage");
506
- return { bankId, result: await get(bankId, args.id) };
507
- }
508
- case "export": {
509
- // Portable markdown bundle of the whole knowledge base (not for routine Q&A).
510
- const exp = clientMethod(deps, "exportKnowledgeBase");
511
- return { bankId, result: await exp(bankId) };
512
- }
513
- case "create_page": {
514
- if (!args.name?.trim() || !args.sourceQuery?.trim()) {
515
- throw new Error("name and sourceQuery are required for create_page");
516
- }
517
- const tags =
518
- args.tags ??
519
- (isUserBank ? ["source:pi"] : ["source:pi", `project:${project.projectId}`]);
520
- // Omit trigger to keep server page defaults; only restate them when tagsMatch is set
521
- // (a supplied trigger replaces defaults rather than merging).
522
- const trigger = args.tagsMatch
523
- ? {
524
- mode: "delta" as const,
525
- factTypes: ["observation" as const],
526
- excludeMentalModels: true,
527
- refreshAfterConsolidation: true,
528
- tagsMatch: args.tagsMatch,
529
- }
530
- : undefined;
531
- const wouldCreate = {
532
- name: args.name.trim(),
533
- sourceQuery: args.sourceQuery.trim(),
534
- tags,
535
- ...(args.parentId !== undefined ? { parentId: args.parentId } : {}),
536
- ...(args.maxTokens !== undefined ? { maxTokens: args.maxTokens } : {}),
537
- ...(trigger ? { trigger } : {}),
538
- };
539
- if (args.dryRun ?? true) return { dryRun: true, bankId, wouldCreate };
540
- const create = clientMethod(deps, "createKnowledgePage");
541
- const result = await create(bankId, wouldCreate.name, wouldCreate.sourceQuery, {
542
- tags,
543
- ...(args.parentId !== undefined ? { parentId: args.parentId } : {}),
544
- ...(args.maxTokens !== undefined ? { maxTokens: args.maxTokens } : {}),
545
- ...(trigger ? { trigger } : {}),
546
- });
547
- return { bankId, result };
548
- }
549
- case "create_folder": {
550
- if (!args.name?.trim()) throw new Error("name is required for create_folder");
551
- const wouldCreate = {
552
- name: args.name.trim(),
553
- ...(args.parentId !== undefined ? { parentId: args.parentId } : {}),
554
- };
555
- if (args.dryRun ?? true) return { dryRun: true, bankId, wouldCreate };
556
- const create = clientMethod(deps, "createKnowledgeFolder");
557
- const result = await create(
558
- bankId,
559
- wouldCreate.name,
560
- args.parentId !== undefined ? { parentId: args.parentId } : undefined,
561
- );
562
- return { bankId, result };
563
- }
564
- case "update": {
565
- if (!args.id) throw new Error("id is required for update");
566
- const options: {
567
- name?: string;
568
- parentId?: string | null;
569
- sourceQuery?: string;
570
- tags?: string[];
571
- maxTokens?: number;
572
- } = {
573
- ...(args.name !== undefined ? { name: args.name } : {}),
574
- ...("parentId" in args ? { parentId: args.parentId } : {}),
575
- ...(args.sourceQuery !== undefined ? { sourceQuery: args.sourceQuery } : {}),
576
- ...(args.tags !== undefined ? { tags: args.tags } : {}),
577
- ...(args.maxTokens !== undefined ? { maxTokens: args.maxTokens } : {}),
578
- };
579
- if (Object.keys(options).length === 0) {
580
- throw new Error(
581
- "Provide name, parentId, sourceQuery, tags, and/or maxTokens for update",
582
- );
583
- }
584
- if (args.dryRun ?? true)
585
- return { dryRun: true, bankId, id: args.id, wouldUpdate: options };
586
- const update = clientMethod(deps, "updateKnowledgeNode");
587
- return { bankId, result: await update(bankId, args.id, options) };
588
- }
589
- case "delete": {
590
- if (!args.id) throw new Error("id is required for delete");
591
- if (args.dryRun ?? true) return { dryRun: true, bankId, id: args.id, wouldDelete: true };
592
- const del = clientMethod(deps, "deleteKnowledgeNode");
593
- return { bankId, result: await del(bankId, args.id) };
594
- }
595
- default:
596
- throw new Error(`Unknown knowledge action: ${String(args.action)}`);
597
- }
598
- },
599
-
600
- /**
601
- * Agent allowlisted config get/patch. Writes project (or optional global) config files.
602
- * Never accepts direct API keys — use apiKeyEnvVar only.
603
- */
604
- async config(args: {
605
- action: "get" | "patch";
606
- cwd: string;
607
- patch?: Record<string, unknown>;
608
- scope?: "project" | "global";
609
- dryRun?: boolean;
610
- }) {
611
- const config = deps.getConfig();
612
- if (args.action === "get") {
613
- return {
614
- allowlist: [...AGENT_CONFIG_ALLOWLIST],
615
- scope: args.scope ?? "project",
616
- values: agentConfigView(config),
617
- note: "Secrets are never returned. Patch only allowlisted keys; dryRun defaults true for patch.",
618
- };
619
- }
620
- if (!args.patch || typeof args.patch !== "object") {
621
- throw new Error("patch object is required for action=patch");
622
- }
623
- const picked = pickAgentConfigPatch(args.patch);
624
- assertAgentConfigPatchSafe(picked, config);
625
- const input: ProjectConfigPatchInput = {
626
- ...picked,
627
- scope: args.scope ?? "project",
628
- };
629
- if (args.dryRun ?? true) {
630
- return {
631
- dryRun: true,
632
- scope: input.scope,
633
- wouldPatch: picked,
634
- allowlist: [...AGENT_CONFIG_ALLOWLIST],
635
- };
636
- }
637
- const result = await configureMemory(args.cwd, input, deps);
638
- return {
639
- dryRun: false,
640
- scope: input.scope,
641
- patched: picked,
642
- path: result.path,
643
- projectBankId: result.projectBankId,
644
- values: agentConfigView(deps.getConfig()),
645
- };
646
- },
647
- };
648
- }