@oh-my-pi/pi-coding-agent 16.1.10 → 16.1.12

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 (63) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/dist/cli.js +2480 -2481
  3. package/dist/types/export/html/index.d.ts +31 -2
  4. package/dist/types/export/html/web-palette.d.ts +117 -0
  5. package/dist/types/export/share.d.ts +10 -5
  6. package/dist/types/hindsight/content.d.ts +7 -0
  7. package/dist/types/hindsight/transcript.d.ts +1 -1
  8. package/dist/types/modes/components/hook-editor.d.ts +2 -1
  9. package/dist/types/modes/interactive-mode.d.ts +5 -0
  10. package/dist/types/modes/types.d.ts +17 -0
  11. package/dist/types/modes/utils/keybinding-matchers.d.ts +13 -0
  12. package/dist/types/secrets/index.d.ts +1 -1
  13. package/dist/types/secrets/obfuscator.d.ts +43 -9
  14. package/dist/types/session/agent-session.d.ts +4 -0
  15. package/dist/types/session/session-context.d.ts +2 -0
  16. package/dist/types/session/session-entries.d.ts +6 -0
  17. package/dist/types/session/session-manager.d.ts +2 -1
  18. package/dist/types/tools/acp-bridge.d.ts +29 -0
  19. package/dist/types/tools/browser/cmux/cmux-tab.d.ts +7 -0
  20. package/dist/types/tools/browser/tab-worker.d.ts +20 -0
  21. package/dist/types/utils/jj.d.ts +25 -0
  22. package/dist/types/utils/title-generator.d.ts +0 -2
  23. package/package.json +12 -12
  24. package/scripts/generate-share-viewer.ts +4 -2
  25. package/src/autoresearch/git.ts +12 -0
  26. package/src/discovery/opencode.ts +47 -4
  27. package/src/edit/hashline/filesystem.ts +8 -0
  28. package/src/edit/modes/patch.ts +18 -2
  29. package/src/edit/modes/replace.ts +13 -10
  30. package/src/export/html/index.ts +50 -8
  31. package/src/export/html/web-palette.ts +142 -0
  32. package/src/export/share.ts +198 -8
  33. package/src/hindsight/backend.ts +4 -4
  34. package/src/hindsight/content.ts +17 -1
  35. package/src/hindsight/transcript.ts +2 -2
  36. package/src/internal-urls/docs-index.generated.txt +1 -1
  37. package/src/main.ts +8 -0
  38. package/src/modes/components/agent-dashboard.ts +8 -8
  39. package/src/modes/components/hook-editor.ts +13 -10
  40. package/src/modes/components/session-selector.ts +3 -0
  41. package/src/modes/controllers/event-controller.ts +9 -5
  42. package/src/modes/controllers/extension-ui-controller.ts +6 -2
  43. package/src/modes/interactive-mode.ts +69 -29
  44. package/src/modes/theme/dark.json +1 -1
  45. package/src/modes/types.ts +18 -0
  46. package/src/modes/utils/keybinding-matchers.ts +36 -1
  47. package/src/modes/utils/ui-helpers.ts +1 -0
  48. package/src/prompts/tools/browser.md +3 -2
  49. package/src/sdk.ts +14 -2
  50. package/src/secrets/index.ts +1 -1
  51. package/src/secrets/obfuscator.ts +220 -71
  52. package/src/session/agent-session.ts +57 -43
  53. package/src/session/session-context.ts +5 -0
  54. package/src/session/session-entries.ts +6 -0
  55. package/src/session/session-manager.ts +3 -1
  56. package/src/task/worktree.ts +12 -4
  57. package/src/thinking.ts +1 -1
  58. package/src/tools/acp-bridge.ts +66 -0
  59. package/src/tools/browser/cmux/cmux-tab.ts +37 -0
  60. package/src/tools/browser/tab-worker.ts +160 -37
  61. package/src/tools/write.ts +2 -25
  62. package/src/utils/jj.ts +47 -0
  63. package/src/utils/title-generator.ts +31 -99
@@ -15,7 +15,7 @@ import type { AgentSession } from "../session/agent-session";
15
15
  import { type BankScope, computeBankScope } from "./bank";
16
16
  import { createHindsightClient } from "./client";
17
17
  import { isHindsightConfigured, loadHindsightConfig } from "./config";
18
- import type { HindsightMessage } from "./content";
18
+ import { type HindsightMessage, hasSubstantiveContent } from "./content";
19
19
  import { HindsightSessionState } from "./state";
20
20
 
21
21
  const STATIC_INSTRUCTIONS = [
@@ -330,7 +330,7 @@ function flattenMessagesForRecall(messages: AgentMessage[]): HindsightMessage[]
330
330
  if (msg.role === "user") {
331
331
  const content = msg.content;
332
332
  if (typeof content === "string") {
333
- if (content.trim()) out.push({ role: "user", content });
333
+ if (hasSubstantiveContent(content)) out.push({ role: "user", content });
334
334
  continue;
335
335
  }
336
336
  if (Array.isArray(content)) {
@@ -338,7 +338,7 @@ function flattenMessagesForRecall(messages: AgentMessage[]): HindsightMessage[]
338
338
  .filter((b): b is { type: "text"; text: string } => !!b && (b as { type?: unknown }).type === "text")
339
339
  .map(b => b.text)
340
340
  .join("\n");
341
- if (text.trim()) out.push({ role: "user", content: text });
341
+ if (hasSubstantiveContent(text)) out.push({ role: "user", content: text });
342
342
  }
343
343
  continue;
344
344
  }
@@ -347,7 +347,7 @@ function flattenMessagesForRecall(messages: AgentMessage[]): HindsightMessage[]
347
347
  .filter((b): b is { type: "text"; text: string } => b.type === "text")
348
348
  .map(b => b.text)
349
349
  .join("\n");
350
- if (text.trim()) out.push({ role: "assistant", content: text });
350
+ if (hasSubstantiveContent(text)) out.push({ role: "assistant", content: text });
351
351
  }
352
352
  }
353
353
  return out;
@@ -43,6 +43,22 @@ export function stripMemoryTags(content: string): string {
43
43
  .replace(LEGACY_RELEVANT_MEMORIES_REGEX, "");
44
44
  }
45
45
 
46
+ // At least one letter or digit means the message carries a token a retriever
47
+ // can actually match on. Punctuation/whitespace-only strings (e.g. the lone
48
+ // `.` some providers emit for tool-call-only or thinking-only assistant turns)
49
+ // are dropped before retain/recall touches them — see issue #1806.
50
+ const SUBSTANTIVE_CHAR_RE = /[\p{L}\p{N}]/u;
51
+
52
+ /**
53
+ * True when `content` carries at least one letter or digit. Used by retain
54
+ * and recall paths to drop placeholder assistant turns ("." / "..." / pure
55
+ * whitespace) that would otherwise pollute the bank and waste tokens on
56
+ * embeddings with no semantic content.
57
+ */
58
+ export function hasSubstantiveContent(content: string): boolean {
59
+ return SUBSTANTIVE_CHAR_RE.test(content);
60
+ }
61
+
46
62
  /** Format recall results into a bullet list for context injection. */
47
63
  export function formatMemories(results: RecallResultLike[]): string {
48
64
  if (results.length === 0) return "";
@@ -197,7 +213,7 @@ export function prepareRetentionTranscript(
197
213
  const parts: string[] = [];
198
214
  for (const msg of targetMessages) {
199
215
  const content = stripMemoryTags(msg.content).trim();
200
- if (!content) continue;
216
+ if (!hasSubstantiveContent(content)) continue;
201
217
  parts.push(`[role: ${msg.role}]\n${content}\n[${msg.role}:end]`);
202
218
  }
203
219
 
@@ -9,7 +9,7 @@
9
9
 
10
10
  import type { AssistantMessage } from "@oh-my-pi/pi-ai";
11
11
  import type { SessionEntry } from "../session/session-entries";
12
- import type { HindsightMessage } from "./content";
12
+ import { type HindsightMessage, hasSubstantiveContent } from "./content";
13
13
 
14
14
  export interface ReadonlySessionManagerLike {
15
15
  getEntries(): SessionEntry[];
@@ -39,7 +39,7 @@ export function extractMessages(sessionManager: ReadonlySessionManagerLike): Hin
39
39
  if (role !== "user" && role !== "assistant") continue;
40
40
 
41
41
  const text = role === "user" ? extractUserText(msg) : extractAssistantText(msg as AssistantMessage);
42
- if (text.length === 0) continue;
42
+ if (!hasSubstantiveContent(text)) continue;
43
43
  messages.push({ role, content: text });
44
44
  }
45
45