@aexol/spectral 0.7.1 → 0.7.5

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 (219) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/agent/agents.js +1 -1
  3. package/dist/agent/index.js +199 -184
  4. package/dist/commands/serve.js +0 -3
  5. package/dist/designer/data/systems/renault/DESIGN.md +1 -1
  6. package/dist/designer/philosophies.js +668 -0
  7. package/dist/mcp/sampling-handler.js +1 -1
  8. package/dist/memory/commands/status.js +1 -1
  9. package/dist/memory/compaction.js +2 -2
  10. package/dist/memory/config.js +1 -1
  11. package/dist/memory/debug-log.js +1 -1
  12. package/dist/memory/hooks/compaction-hook.js +29 -0
  13. package/dist/memory/index.js +2 -0
  14. package/dist/memory/observer.js +2 -2
  15. package/dist/memory/project-observations-store.js +14 -0
  16. package/dist/memory/tokens.js +1 -1
  17. package/dist/memory/tools/read-project-observations.js +82 -0
  18. package/dist/memory/tools/recall-observation.js +2 -2
  19. package/dist/pi/agent-core/agent-loop.js +501 -0
  20. package/dist/pi/agent-core/agent.js +401 -0
  21. package/dist/pi/agent-core/harness/agent-harness.js +899 -0
  22. package/dist/pi/agent-core/harness/compaction/branch-summarization.js +173 -0
  23. package/dist/pi/agent-core/harness/compaction/compaction.js +532 -0
  24. package/dist/pi/agent-core/harness/compaction/utils.js +130 -0
  25. package/dist/pi/agent-core/harness/env/nodejs.js +485 -0
  26. package/dist/pi/agent-core/harness/messages.js +101 -0
  27. package/dist/pi/agent-core/harness/prompt-templates.js +229 -0
  28. package/dist/pi/agent-core/harness/session/jsonl-repo.js +100 -0
  29. package/dist/pi/agent-core/harness/session/jsonl-storage.js +230 -0
  30. package/dist/pi/agent-core/harness/session/memory-repo.js +41 -0
  31. package/dist/pi/agent-core/harness/session/memory-storage.js +113 -0
  32. package/dist/pi/agent-core/harness/session/repo-utils.js +38 -0
  33. package/dist/pi/agent-core/harness/session/session.js +196 -0
  34. package/dist/pi/agent-core/harness/session/uuid.js +49 -0
  35. package/dist/pi/agent-core/harness/skills.js +310 -0
  36. package/dist/pi/agent-core/harness/system-prompt.js +29 -0
  37. package/dist/pi/agent-core/harness/types.js +93 -0
  38. package/dist/pi/agent-core/harness/utils/shell-output.js +125 -0
  39. package/dist/pi/agent-core/harness/utils/truncate.js +289 -0
  40. package/dist/pi/agent-core/index.js +24 -0
  41. package/dist/pi/agent-core/node.js +2 -0
  42. package/dist/pi/agent-core/proxy.js +277 -0
  43. package/dist/pi/agent-core/types.js +1 -0
  44. package/dist/pi/ai/api-registry.js +43 -0
  45. package/dist/pi/ai/cli.js +120 -0
  46. package/dist/pi/ai/env-api-keys.js +169 -0
  47. package/dist/pi/ai/image-models.generated.js +441 -0
  48. package/dist/pi/ai/image-models.js +22 -0
  49. package/dist/pi/ai/images-api-registry.js +21 -0
  50. package/dist/pi/ai/images.js +13 -0
  51. package/dist/pi/ai/index.js +18 -0
  52. package/dist/pi/ai/models.generated.js +16220 -0
  53. package/dist/pi/ai/models.js +70 -0
  54. package/dist/pi/ai/oauth.js +1 -0
  55. package/dist/pi/ai/providers/anthropic.js +945 -0
  56. package/dist/pi/ai/providers/faux.js +367 -0
  57. package/dist/pi/ai/providers/github-copilot-headers.js +28 -0
  58. package/dist/pi/ai/providers/openai-completions.js +945 -0
  59. package/dist/pi/ai/providers/openai-prompt-cache.js +9 -0
  60. package/dist/pi/ai/providers/register-builtins.js +97 -0
  61. package/dist/pi/ai/providers/simple-options.js +40 -0
  62. package/dist/pi/ai/providers/transform-messages.js +183 -0
  63. package/dist/pi/ai/session-resources.js +21 -0
  64. package/dist/pi/ai/stream.js +26 -0
  65. package/dist/pi/ai/types.js +1 -0
  66. package/dist/pi/ai/utils/diagnostics.js +24 -0
  67. package/dist/pi/ai/utils/event-stream.js +80 -0
  68. package/dist/pi/ai/utils/hash.js +13 -0
  69. package/dist/pi/ai/utils/headers.js +7 -0
  70. package/dist/pi/ai/utils/json-parse.js +112 -0
  71. package/dist/pi/ai/utils/node-http-proxy.js +96 -0
  72. package/dist/pi/ai/utils/oauth/anthropic.js +334 -0
  73. package/dist/pi/ai/utils/oauth/device-code.js +54 -0
  74. package/dist/pi/ai/utils/oauth/github-copilot.js +270 -0
  75. package/dist/pi/ai/utils/oauth/index.js +121 -0
  76. package/dist/pi/ai/utils/oauth/oauth-page.js +104 -0
  77. package/dist/pi/ai/utils/oauth/openai-codex.js +384 -0
  78. package/dist/pi/ai/utils/oauth/pkce.js +30 -0
  79. package/dist/pi/ai/utils/oauth/types.js +1 -0
  80. package/dist/pi/ai/utils/overflow.js +150 -0
  81. package/dist/pi/ai/utils/sanitize-unicode.js +25 -0
  82. package/dist/pi/ai/utils/typebox-helpers.js +20 -0
  83. package/dist/pi/ai/utils/validation.js +280 -0
  84. package/dist/pi/coding-agent/bun/cli.js +7 -0
  85. package/dist/pi/coding-agent/bun/restore-sandbox-env.js +31 -0
  86. package/dist/pi/coding-agent/cli/args.js +340 -0
  87. package/dist/pi/coding-agent/cli/file-processor.js +82 -0
  88. package/dist/pi/coding-agent/cli/initial-message.js +21 -0
  89. package/dist/pi/coding-agent/cli.js +17 -0
  90. package/dist/pi/coding-agent/config.js +414 -0
  91. package/dist/pi/coding-agent/core/agent-session-runtime.js +299 -0
  92. package/dist/pi/coding-agent/core/agent-session-services.js +117 -0
  93. package/dist/pi/coding-agent/core/agent-session.js +2498 -0
  94. package/dist/pi/coding-agent/core/auth-guidance.js +20 -0
  95. package/dist/pi/coding-agent/core/auth-storage.js +441 -0
  96. package/dist/pi/coding-agent/core/bash-executor.js +110 -0
  97. package/dist/pi/coding-agent/core/compaction/branch-summarization.js +242 -0
  98. package/dist/pi/coding-agent/core/compaction/compaction.js +624 -0
  99. package/dist/pi/coding-agent/core/compaction/index.js +6 -0
  100. package/dist/pi/coding-agent/core/compaction/utils.js +152 -0
  101. package/dist/pi/coding-agent/core/defaults.js +1 -0
  102. package/dist/pi/coding-agent/core/diagnostics.js +1 -0
  103. package/dist/pi/coding-agent/core/event-bus.js +24 -0
  104. package/dist/pi/coding-agent/core/exec.js +74 -0
  105. package/dist/pi/coding-agent/core/export-html/ansi-to-html.js +248 -0
  106. package/dist/pi/coding-agent/core/export-html/index.js +225 -0
  107. package/dist/pi/coding-agent/core/export-html/tool-renderer.js +107 -0
  108. package/dist/pi/coding-agent/core/extensions/index.js +8 -0
  109. package/dist/pi/coding-agent/core/extensions/loader.js +485 -0
  110. package/dist/pi/coding-agent/core/extensions/runner.js +824 -0
  111. package/dist/pi/coding-agent/core/extensions/types.js +44 -0
  112. package/dist/pi/coding-agent/core/extensions/wrapper.js +21 -0
  113. package/dist/pi/coding-agent/core/footer-data-provider.js +309 -0
  114. package/dist/pi/coding-agent/core/http-dispatcher.js +47 -0
  115. package/dist/pi/coding-agent/core/index.js +11 -0
  116. package/dist/pi/coding-agent/core/keybindings.js +294 -0
  117. package/dist/pi/coding-agent/core/messages.js +122 -0
  118. package/dist/pi/coding-agent/core/model-registry.js +728 -0
  119. package/dist/pi/coding-agent/core/model-resolver.js +494 -0
  120. package/dist/pi/coding-agent/core/output-guard.js +58 -0
  121. package/dist/pi/coding-agent/core/package-manager.js +2020 -0
  122. package/dist/pi/coding-agent/core/prompt-templates.js +237 -0
  123. package/dist/pi/coding-agent/core/provider-display-names.js +32 -0
  124. package/dist/pi/coding-agent/core/resolve-config-value.js +125 -0
  125. package/dist/pi/coding-agent/core/resource-loader.js +733 -0
  126. package/dist/pi/coding-agent/core/sdk.js +282 -0
  127. package/dist/pi/coding-agent/core/session-cwd.js +37 -0
  128. package/dist/pi/coding-agent/core/session-manager.js +1146 -0
  129. package/dist/pi/coding-agent/core/settings-manager.js +794 -0
  130. package/dist/pi/coding-agent/core/skills.js +386 -0
  131. package/dist/pi/coding-agent/core/slash-commands.js +24 -0
  132. package/dist/pi/coding-agent/core/source-info.js +18 -0
  133. package/dist/pi/coding-agent/core/system-prompt.js +122 -0
  134. package/dist/pi/coding-agent/core/telemetry.js +8 -0
  135. package/dist/pi/coding-agent/core/timings.js +30 -0
  136. package/dist/pi/coding-agent/core/tools/bash.js +341 -0
  137. package/dist/pi/coding-agent/core/tools/edit-diff.js +344 -0
  138. package/dist/pi/coding-agent/core/tools/edit.js +324 -0
  139. package/dist/pi/coding-agent/core/tools/file-mutation-queue.js +36 -0
  140. package/dist/pi/coding-agent/core/tools/find.js +297 -0
  141. package/dist/pi/coding-agent/core/tools/grep.js +303 -0
  142. package/dist/pi/coding-agent/core/tools/index.js +111 -0
  143. package/dist/pi/coding-agent/core/tools/ls.js +168 -0
  144. package/dist/pi/coding-agent/core/tools/output-accumulator.js +183 -0
  145. package/dist/pi/coding-agent/core/tools/path-utils.js +61 -0
  146. package/dist/pi/coding-agent/core/tools/read.js +288 -0
  147. package/dist/pi/coding-agent/core/tools/render-utils.js +48 -0
  148. package/dist/pi/coding-agent/core/tools/tool-definition-wrapper.js +33 -0
  149. package/dist/pi/coding-agent/core/tools/truncate.js +214 -0
  150. package/dist/pi/coding-agent/core/tools/write.js +212 -0
  151. package/dist/pi/coding-agent/index.js +41 -0
  152. package/dist/pi/coding-agent/main.js +5 -0
  153. package/dist/pi/coding-agent/migrations.js +280 -0
  154. package/dist/pi/coding-agent/modes/index.js +7 -0
  155. package/dist/pi/coding-agent/modes/interactive/components/diff.js +132 -0
  156. package/dist/pi/coding-agent/modes/interactive/components/keybinding-hints.js +35 -0
  157. package/dist/pi/coding-agent/modes/interactive/components/visual-truncate.js +32 -0
  158. package/dist/pi/coding-agent/modes/interactive/interactive-mode.js +3 -0
  159. package/dist/pi/coding-agent/modes/interactive/theme/theme.js +1023 -0
  160. package/dist/pi/coding-agent/modes/print-mode.js +130 -0
  161. package/dist/pi/coding-agent/modes/rpc/jsonl.js +48 -0
  162. package/dist/pi/coding-agent/modes/rpc/rpc-client.js +409 -0
  163. package/dist/pi/coding-agent/modes/rpc/rpc-mode.js +600 -0
  164. package/dist/pi/coding-agent/modes/rpc/rpc-types.js +7 -0
  165. package/dist/pi/coding-agent/utils/ansi.js +51 -0
  166. package/dist/pi/coding-agent/utils/changelog.js +86 -0
  167. package/dist/pi/coding-agent/utils/child-process.js +87 -0
  168. package/dist/pi/coding-agent/utils/clipboard-image.js +244 -0
  169. package/dist/pi/coding-agent/utils/clipboard-native.js +13 -0
  170. package/dist/pi/coding-agent/utils/clipboard.js +116 -0
  171. package/dist/pi/coding-agent/utils/exif-orientation.js +157 -0
  172. package/dist/pi/coding-agent/utils/frontmatter.js +25 -0
  173. package/dist/pi/coding-agent/utils/fs-watch.js +24 -0
  174. package/dist/pi/coding-agent/utils/git.js +162 -0
  175. package/dist/pi/coding-agent/utils/html.js +39 -0
  176. package/dist/pi/coding-agent/utils/image-convert.js +38 -0
  177. package/dist/pi/coding-agent/utils/image-resize.js +136 -0
  178. package/dist/pi/coding-agent/utils/mime.js +68 -0
  179. package/dist/pi/coding-agent/utils/paths.js +91 -0
  180. package/dist/pi/coding-agent/utils/photon.js +120 -0
  181. package/dist/pi/coding-agent/utils/pi-user-agent.js +4 -0
  182. package/dist/pi/coding-agent/utils/shell.js +194 -0
  183. package/dist/pi/coding-agent/utils/sleep.js +16 -0
  184. package/dist/pi/coding-agent/utils/syntax-highlight.js +117 -0
  185. package/dist/pi/coding-agent/utils/tools-manager.js +327 -0
  186. package/dist/pi/coding-agent/utils/version-check.js +81 -0
  187. package/dist/pi/coding-agent/utils/windows-self-update.js +76 -0
  188. package/dist/pi/tui/autocomplete.js +631 -0
  189. package/dist/pi/tui/components/box.js +103 -0
  190. package/dist/pi/tui/components/cancellable-loader.js +34 -0
  191. package/dist/pi/tui/components/editor.js +1915 -0
  192. package/dist/pi/tui/components/image.js +88 -0
  193. package/dist/pi/tui/components/input.js +425 -0
  194. package/dist/pi/tui/components/loader.js +68 -0
  195. package/dist/pi/tui/components/markdown.js +633 -0
  196. package/dist/pi/tui/components/select-list.js +158 -0
  197. package/dist/pi/tui/components/settings-list.js +184 -0
  198. package/dist/pi/tui/components/spacer.js +22 -0
  199. package/dist/pi/tui/components/text.js +88 -0
  200. package/dist/pi/tui/components/truncated-text.js +50 -0
  201. package/dist/pi/tui/editor-component.js +1 -0
  202. package/dist/pi/tui/fuzzy.js +109 -0
  203. package/dist/pi/tui/index.js +31 -0
  204. package/dist/pi/tui/keybindings.js +173 -0
  205. package/dist/pi/tui/keys.js +1172 -0
  206. package/dist/pi/tui/kill-ring.js +43 -0
  207. package/dist/pi/tui/stdin-buffer.js +360 -0
  208. package/dist/pi/tui/terminal-image.js +335 -0
  209. package/dist/pi/tui/terminal.js +324 -0
  210. package/dist/pi/tui/tui.js +1076 -0
  211. package/dist/pi/tui/undo-stack.js +24 -0
  212. package/dist/pi/tui/utils.js +1016 -0
  213. package/dist/relay/dispatcher.js +30 -0
  214. package/dist/server/handlers/queue.js +52 -0
  215. package/dist/server/pi-bridge.js +9 -1
  216. package/dist/server/session-stream.js +76 -111
  217. package/dist/server/storage.js +154 -2
  218. package/dist/server/title-generator.js +14 -153
  219. package/package.json +24 -6
@@ -1,4 +1,4 @@
1
- import { SettingsManager } from "@mariozechner/pi-coding-agent";
1
+ import { SettingsManager } from "../../pi/coding-agent/index.js";
2
2
  import { getMemoryState, rawTokensSinceLastBound, rawTokensSinceLastCompaction, } from "../branch.js";
3
3
  import { observationPoolTokens as estimateObservationPoolTokens } from "../compaction.js";
4
4
  import { countByRelevance, formatRelevanceHistogram } from "../relevance.js";
@@ -1,5 +1,5 @@
1
- import { agentLoop } from "@mariozechner/pi-agent-core";
2
- import { Type } from "@mariozechner/pi-ai";
1
+ import { agentLoop } from "../pi/agent-core/index.js";
2
+ import { Type } from "../pi/ai/index.js";
3
3
  import { debugLog, isDebugLogEnabled } from "./debug-log.js";
4
4
  import { hashId } from "./ids.js";
5
5
  import { AGENT_LOOP_MAX_TOKENS, boundedMaxTokens } from "./model-budget.js";
@@ -1,6 +1,6 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import { getAgentDir } from "@mariozechner/pi-coding-agent";
3
+ import { getAgentDir } from "../pi/coding-agent/index.js";
4
4
  export const DEFAULTS = {
5
5
  observationThresholdTokens: 1_000,
6
6
  compactionThresholdTokens: 50_000,
@@ -1,7 +1,7 @@
1
1
  import { AsyncLocalStorage } from "node:async_hooks";
2
2
  import { existsSync, mkdirSync, renameSync, statSync, unlinkSync, appendFileSync } from "node:fs";
3
3
  import { dirname, join } from "node:path";
4
- import { getAgentDir } from "@mariozechner/pi-coding-agent";
4
+ import { getAgentDir } from "../pi/coding-agent/index.js";
5
5
  export const DEBUG_LOG_MAX_BYTES = 10 * 1024 * 1024;
6
6
  export const DEBUG_LOG_RELATIVE_PATH = join("observational-memory", "debug.ndjson");
7
7
  const storage = new AsyncLocalStorage();
@@ -1,5 +1,6 @@
1
1
  import { debugLog, withDebugLogContext } from "../debug-log.js";
2
2
  import { resolveTurnLimits } from "../config.js";
3
+ import { getProjectObsStore } from "../project-observations-store.js";
3
4
  import { collectObservationsByCoverage, findLastCompactionIndex, gapRawEntries, getMemoryState, } from "../branch.js";
4
5
  import { coverageTagCounts, migrateLegacyReflections, observationPoolTokens, renderSummary, runPruner, runReflector, } from "../compaction.js";
5
6
  import { observationsToPromptLines, runObserver } from "../observer.js";
@@ -188,6 +189,8 @@ export function registerCompactionHook(pi, runtime) {
188
189
  };
189
190
  if (hasUI)
190
191
  ui?.notify(`Observational memory: no new observations — carrying forward ${memoryState.committedObs.length} observation${memoryState.committedObs.length === 1 ? "" : "s"}, ${workingReflections.length} reflection${workingReflections.length === 1 ? "" : "s"}`, "info");
192
+ // Promote reflections as project observations (cross-session durable memory).
193
+ persistProjectObservations(ctx, workingReflections);
191
194
  return {
192
195
  compaction: {
193
196
  summary,
@@ -274,6 +277,8 @@ export function registerCompactionHook(pi, runtime) {
274
277
  });
275
278
  if (hasUI)
276
279
  ui?.notify(`Observational memory: compaction assembled — ${finalObservations.length} observation${finalObservations.length === 1 ? "" : "s"}, ${finalReflections.length} reflection${finalReflections.length === 1 ? "" : "s"}`, "info");
280
+ // Promote reflections as project observations (cross-session durable memory).
281
+ persistProjectObservations(ctx, finalReflections);
277
282
  return {
278
283
  compaction: {
279
284
  summary,
@@ -288,4 +293,28 @@ export function registerCompactionHook(pi, runtime) {
288
293
  runtime.compactHookInFlight = false;
289
294
  }
290
295
  });
296
+ function persistProjectObservations(ctx, reflections) {
297
+ const store = getProjectObsStore();
298
+ if (!store)
299
+ return; // Not available in standalone pi mode.
300
+ const projectId = store.getProjectByCwd(ctx.cwd);
301
+ if (!projectId)
302
+ return; // No project registered for this cwd.
303
+ const sessionId = ctx.sessionManager.getSessionId?.();
304
+ if (!sessionId)
305
+ return;
306
+ if (reflections.length === 0)
307
+ return;
308
+ const projectObs = reflections.map((r) => ({
309
+ id: typeof r === "string" ? r : r.id ?? r.content.slice(0, 64),
310
+ content: typeof r === "string" ? r : r.content,
311
+ relevance: "high",
312
+ }));
313
+ store.insertProjectObservations(projectId, sessionId, projectObs, Date.now());
314
+ debugLog("compaction.project_obs", {
315
+ count: projectObs.length,
316
+ projectId,
317
+ sessionId,
318
+ });
319
+ }
291
320
  }
@@ -5,6 +5,7 @@ import { registerCompactionTrigger } from "./hooks/compaction-trigger.js";
5
5
  import { registerObserverTrigger } from "./hooks/observer-trigger.js";
6
6
  import { Runtime } from "./runtime.js";
7
7
  import { registerRecallTool } from "./tools/recall-observation.js";
8
+ import { registerReadProjectObservationsTool } from "./tools/read-project-observations.js";
8
9
  export default function observationalMemory(pi) {
9
10
  const runtime = new Runtime();
10
11
  // Log extension load so we can confirm it's running in serve mode.
@@ -15,4 +16,5 @@ export default function observationalMemory(pi) {
15
16
  registerStatusCommand(pi, runtime);
16
17
  registerViewCommand(pi, runtime);
17
18
  registerRecallTool(pi);
19
+ registerReadProjectObservationsTool(pi);
18
20
  }
@@ -1,5 +1,5 @@
1
- import { agentLoop } from "@mariozechner/pi-agent-core";
2
- import { Type } from "@mariozechner/pi-ai";
1
+ import { agentLoop } from "../pi/agent-core/index.js";
2
+ import { Type } from "../pi/ai/index.js";
3
3
  import { hashId } from "./ids.js";
4
4
  import { AGENT_LOOP_MAX_TOKENS, boundedMaxTokens } from "./model-budget.js";
5
5
  import { OBSERVER_SYSTEM } from "./prompts.js";
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Module-level singleton that bridges the server's SessionStore into the
3
+ * memory extension so the `read_project_observations` tool can query
4
+ * cross-session observations.
5
+ *
6
+ * Set once by the SessionStreamManager at startup. Read by tools at runtime.
7
+ */
8
+ let _store = null;
9
+ export function setProjectObsStore(store) {
10
+ _store = store;
11
+ }
12
+ export function getProjectObsStore() {
13
+ return _store;
14
+ }
@@ -1,4 +1,4 @@
1
- import { estimateTokens as estimateMessageTokens } from "@mariozechner/pi-coding-agent";
1
+ import { estimateTokens as estimateMessageTokens } from "../pi/coding-agent/index.js";
2
2
  export function estimateStringTokens(text) {
3
3
  return Math.ceil(text.length / 4);
4
4
  }
@@ -0,0 +1,82 @@
1
+ import { Type } from "../../pi/ai/index.js";
2
+ import { defineTool } from "../../pi/coding-agent/index.js";
3
+ import { getProjectObsStore } from "../project-observations-store.js";
4
+ export const READ_PROJECT_OBSERVATIONS_TOOL_NAME = "read_project_observations";
5
+ export const readProjectObservationsTool = defineTool({
6
+ name: READ_PROJECT_OBSERVATIONS_TOOL_NAME,
7
+ label: "Search project observations",
8
+ description: "Search all past observations across ALL sessions in this project. " +
9
+ "Use this when you need to recall project conventions, past decisions, " +
10
+ "file locations, or user preferences before editing or creating files. " +
11
+ "Uses simple substring matching — be specific with your query terms. " +
12
+ "Returns up to 20 most recent matching observations with relevance tags.",
13
+ promptSnippet: "Use read_project_observations(<query>) to search past observations across ALL sessions in this project.",
14
+ promptGuidelines: [
15
+ "Use read_project_observations before creating new files to find conventions for that file kind.",
16
+ "Use read_project_observations before editing a file to find past context about that file or its directory.",
17
+ "Be specific: search for file paths, technology names, or pattern keywords.",
18
+ "Do not use for broad topic searches — keep queries narrow for relevant results.",
19
+ "Results include relevance tags (critical/high/medium/low) to help you prioritize.",
20
+ ],
21
+ parameters: Type.Object({
22
+ query: Type.String({
23
+ minLength: 1,
24
+ description: "Substring to search for in past observation content. " +
25
+ "Use file paths (e.g. 'src/auth/middleware'), technology names, " +
26
+ "or pattern keywords (e.g. 'convention', 'api route').",
27
+ }),
28
+ }),
29
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
30
+ const query = params.query.trim();
31
+ if (!query) {
32
+ const message = "Query must be a non-empty string.";
33
+ return {
34
+ content: [{ type: "text", text: message }],
35
+ details: { status: "empty_query", results: [], count: 0 },
36
+ };
37
+ }
38
+ const store = getProjectObsStore();
39
+ if (!store) {
40
+ const message = "Project observations store is not available — " +
41
+ "this tool requires the spectral server (spectral serve).";
42
+ return {
43
+ content: [{ type: "text", text: message }],
44
+ details: { status: "store_unavailable", results: [], count: 0 },
45
+ };
46
+ }
47
+ const projectId = store.getProjectByCwd(ctx.cwd);
48
+ if (!projectId) {
49
+ const message = `No project found for current working directory: ${ctx.cwd}`;
50
+ return {
51
+ content: [{ type: "text", text: message }],
52
+ details: { status: "no_project", results: [], count: 0 },
53
+ };
54
+ }
55
+ const results = store.searchProjectObservations(projectId, query);
56
+ if (results.length === 0) {
57
+ const message = `No past observations found matching "${query}" in this project.`;
58
+ return {
59
+ content: [{ type: "text", text: message }],
60
+ details: { status: "no_results", query, results: [], count: 0 },
61
+ };
62
+ }
63
+ const lines = results.map((r) => `[${r.relevance}] ${r.content}`);
64
+ const text = `Found ${results.length} past observation(s) matching "${query}" in this project:\n\n${lines.join("\n")}`;
65
+ return {
66
+ content: [{ type: "text", text }],
67
+ details: {
68
+ status: "ok",
69
+ query,
70
+ results: results.map((r) => ({
71
+ content: r.content,
72
+ relevance: r.relevance,
73
+ sessionId: r.sessionId,
74
+ })),
75
+ count: results.length,
76
+ },
77
+ };
78
+ },
79
+ });
80
+ export function registerReadProjectObservationsTool(pi) {
81
+ pi.registerTool(readProjectObservationsTool);
82
+ }
@@ -1,5 +1,5 @@
1
- import { Type } from "@mariozechner/pi-ai";
2
- import { defineTool } from "@mariozechner/pi-coding-agent";
1
+ import { Type } from "../../pi/ai/index.js";
2
+ import { defineTool } from "../../pi/coding-agent/index.js";
3
3
  import { recallMemorySources, } from "../branch.js";
4
4
  import { renderRecallSourceEntries, renderRecallSourceEntry } from "../serialize.js";
5
5
  import { estimateEntryTokens } from "../tokens.js";