@oh-my-pi/pi-coding-agent 15.7.2 → 15.7.3

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 (160) hide show
  1. package/CHANGELOG.md +75 -6
  2. package/dist/types/cli/args.d.ts +1 -1
  3. package/dist/types/cli/extension-flags.d.ts +36 -0
  4. package/dist/types/config/config-file.d.ts +4 -0
  5. package/dist/types/config/file-lock.d.ts +23 -0
  6. package/dist/types/config/keybindings.d.ts +2 -1
  7. package/dist/types/config/model-registry.d.ts +6 -0
  8. package/dist/types/config/settings-schema.d.ts +88 -65
  9. package/dist/types/edit/hashline/diff.d.ts +3 -3
  10. package/dist/types/eval/__tests__/agent-bridge.test.d.ts +1 -0
  11. package/dist/types/eval/__tests__/budget-bridge.test.d.ts +1 -0
  12. package/dist/types/eval/__tests__/idle-timeout.test.d.ts +1 -0
  13. package/dist/types/eval/agent-bridge.d.ts +25 -0
  14. package/dist/types/eval/backend.d.ts +17 -2
  15. package/dist/types/eval/budget-bridge.d.ts +29 -0
  16. package/dist/types/eval/idle-timeout.d.ts +28 -0
  17. package/dist/types/eval/js/executor.d.ts +8 -0
  18. package/dist/types/eval/js/tool-bridge.d.ts +2 -1
  19. package/dist/types/eval/py/executor.d.ts +13 -0
  20. package/dist/types/exec/bash-executor.d.ts +1 -0
  21. package/dist/types/extensibility/custom-tools/types.d.ts +2 -2
  22. package/dist/types/extensibility/extensions/runner.d.ts +7 -0
  23. package/dist/types/extensibility/plugins/git-url.d.ts +11 -1
  24. package/dist/types/extensibility/plugins/manager.d.ts +12 -1
  25. package/dist/types/extensibility/shared-events.d.ts +2 -2
  26. package/dist/types/memory-backend/index.d.ts +1 -1
  27. package/dist/types/memory-backend/resolve.d.ts +1 -1
  28. package/dist/types/memory-backend/types.d.ts +3 -3
  29. package/dist/types/mnemopi/backend.d.ts +4 -0
  30. package/dist/types/mnemopi/config.d.ts +29 -0
  31. package/dist/types/mnemopi/state.d.ts +72 -0
  32. package/dist/types/modes/components/custom-editor.d.ts +2 -2
  33. package/dist/types/modes/components/omfg-panel.d.ts +19 -0
  34. package/dist/types/modes/controllers/command-controller.d.ts +7 -0
  35. package/dist/types/modes/controllers/input-controller.d.ts +1 -3
  36. package/dist/types/modes/controllers/omfg-controller.d.ts +10 -0
  37. package/dist/types/modes/controllers/omfg-rule.d.ts +26 -0
  38. package/dist/types/modes/gradient-highlight.d.ts +5 -1
  39. package/dist/types/modes/interactive-mode.d.ts +7 -3
  40. package/dist/types/modes/magic-keywords.d.ts +14 -0
  41. package/dist/types/modes/markdown-prose.d.ts +27 -0
  42. package/dist/types/modes/orchestrate.d.ts +7 -2
  43. package/dist/types/modes/shared.d.ts +1 -1
  44. package/dist/types/modes/turn-budget.d.ts +18 -0
  45. package/dist/types/modes/types.d.ts +7 -3
  46. package/dist/types/modes/ultrathink.d.ts +7 -2
  47. package/dist/types/modes/workflow.d.ts +15 -0
  48. package/dist/types/sdk.d.ts +13 -3
  49. package/dist/types/session/agent-session.d.ts +40 -17
  50. package/dist/types/session/session-manager.d.ts +18 -0
  51. package/dist/types/session/session-storage.d.ts +6 -0
  52. package/dist/types/session/shake-types.d.ts +24 -0
  53. package/dist/types/task/executor.d.ts +2 -2
  54. package/dist/types/tiny/models.d.ts +15 -1
  55. package/dist/types/tiny/title-protocol.d.ts +4 -0
  56. package/dist/types/tools/index.d.ts +19 -3
  57. package/dist/types/tools/memory-edit.d.ts +1 -1
  58. package/examples/sdk/09-api-keys-and-oauth.ts +2 -2
  59. package/package.json +10 -10
  60. package/src/autoresearch/tools/run-experiment.ts +45 -113
  61. package/src/cli/args.ts +39 -16
  62. package/src/cli/extension-flags.ts +48 -0
  63. package/src/cli/plugin-cli.ts +11 -2
  64. package/src/config/config-file.ts +98 -13
  65. package/src/config/file-lock.ts +60 -17
  66. package/src/config/keybindings.ts +78 -27
  67. package/src/config/model-registry.ts +7 -1
  68. package/src/config/settings-schema.ts +94 -67
  69. package/src/config/settings.ts +12 -0
  70. package/src/edit/hashline/diff.ts +81 -24
  71. package/src/edit/renderer.ts +16 -12
  72. package/src/eval/__tests__/agent-bridge.test.ts +433 -0
  73. package/src/eval/__tests__/budget-bridge.test.ts +69 -0
  74. package/src/eval/__tests__/idle-timeout.test.ts +66 -0
  75. package/src/eval/__tests__/shared-executors.test.ts +21 -0
  76. package/src/eval/agent-bridge.ts +295 -0
  77. package/src/eval/backend.ts +17 -2
  78. package/src/eval/budget-bridge.ts +48 -0
  79. package/src/eval/idle-timeout.ts +80 -0
  80. package/src/eval/js/executor.ts +35 -7
  81. package/src/eval/js/index.ts +2 -1
  82. package/src/eval/js/shared/prelude.txt +85 -1
  83. package/src/eval/js/tool-bridge.ts +9 -0
  84. package/src/eval/py/executor.ts +41 -14
  85. package/src/eval/py/index.ts +2 -1
  86. package/src/eval/py/prelude.py +132 -1
  87. package/src/exec/bash-executor.ts +2 -3
  88. package/src/extensibility/custom-tools/types.ts +2 -2
  89. package/src/extensibility/extensions/runner.ts +12 -2
  90. package/src/extensibility/plugins/git-url.ts +90 -4
  91. package/src/extensibility/plugins/manager.ts +103 -7
  92. package/src/extensibility/shared-events.ts +2 -2
  93. package/src/internal-urls/docs-index.generated.ts +88 -88
  94. package/src/main.ts +44 -55
  95. package/src/memory-backend/index.ts +1 -1
  96. package/src/memory-backend/resolve.ts +3 -3
  97. package/src/memory-backend/types.ts +3 -3
  98. package/src/{mnemosyne → mnemopi}/backend.ts +70 -70
  99. package/src/{mnemosyne → mnemopi}/config.ts +36 -36
  100. package/src/{mnemosyne → mnemopi}/state.ts +67 -67
  101. package/src/modes/components/agent-dashboard.ts +6 -6
  102. package/src/modes/components/custom-editor.ts +4 -11
  103. package/src/modes/components/extensions/state-manager.ts +3 -4
  104. package/src/modes/components/footer.ts +8 -9
  105. package/src/modes/components/hook-selector.ts +86 -20
  106. package/src/modes/components/oauth-selector.ts +93 -21
  107. package/src/modes/components/omfg-panel.ts +141 -0
  108. package/src/modes/components/settings-defs.ts +2 -2
  109. package/src/modes/components/tips.txt +2 -1
  110. package/src/modes/components/tool-execution.ts +38 -19
  111. package/src/modes/components/tree-selector.ts +4 -3
  112. package/src/modes/components/user-message-selector.ts +94 -19
  113. package/src/modes/components/user-message.ts +8 -1
  114. package/src/modes/controllers/command-controller.ts +57 -0
  115. package/src/modes/controllers/event-controller.ts +60 -2
  116. package/src/modes/controllers/input-controller.ts +14 -11
  117. package/src/modes/controllers/omfg-controller.ts +283 -0
  118. package/src/modes/controllers/omfg-rule.ts +647 -0
  119. package/src/modes/controllers/selector-controller.ts +1 -0
  120. package/src/modes/gradient-highlight.ts +23 -6
  121. package/src/modes/interactive-mode.ts +41 -7
  122. package/src/modes/magic-keywords.ts +20 -0
  123. package/src/modes/markdown-prose.ts +247 -0
  124. package/src/modes/orchestrate.ts +17 -11
  125. package/src/modes/shared.ts +3 -11
  126. package/src/modes/turn-budget.ts +31 -0
  127. package/src/modes/types.ts +7 -1
  128. package/src/modes/ultrathink.ts +16 -10
  129. package/src/modes/utils/hotkeys-markdown.ts +1 -1
  130. package/src/modes/workflow.ts +42 -0
  131. package/src/prompts/system/omfg-user.md +51 -0
  132. package/src/prompts/system/system-prompt.md +1 -0
  133. package/src/prompts/system/workflow-notice.md +70 -0
  134. package/src/prompts/tools/eval.md +13 -1
  135. package/src/prompts/tools/memory-edit.md +1 -1
  136. package/src/sdk.ts +63 -33
  137. package/src/session/agent-session.ts +373 -56
  138. package/src/session/session-manager.ts +32 -0
  139. package/src/session/session-storage.ts +68 -8
  140. package/src/session/shake-types.ts +44 -0
  141. package/src/slash-commands/builtin-registry.ts +41 -16
  142. package/src/task/executor.ts +3 -3
  143. package/src/task/index.ts +6 -6
  144. package/src/tiny/models.ts +30 -2
  145. package/src/tiny/title-protocol.ts +11 -1
  146. package/src/tiny/worker.ts +19 -7
  147. package/src/tools/eval.ts +202 -26
  148. package/src/tools/grouped-file-output.ts +9 -2
  149. package/src/tools/index.ts +17 -5
  150. package/src/tools/memory-edit.ts +4 -4
  151. package/src/tools/memory-recall.ts +5 -5
  152. package/src/tools/memory-reflect.ts +5 -5
  153. package/src/tools/memory-retain.ts +4 -4
  154. package/src/tools/render-utils.ts +2 -1
  155. package/src/tools/search.ts +480 -76
  156. package/dist/types/mnemosyne/backend.d.ts +0 -4
  157. package/dist/types/mnemosyne/config.d.ts +0 -29
  158. package/dist/types/mnemosyne/state.d.ts +0 -72
  159. /package/dist/types/{mnemosyne → mnemopi}/index.d.ts +0 -0
  160. /package/src/{mnemosyne → mnemopi}/index.ts +0 -0
@@ -1,4 +1,4 @@
1
- export * from "../mnemosyne";
1
+ export * from "../mnemopi";
2
2
  export * from "./local-backend";
3
3
  export * from "./off-backend";
4
4
  export * from "./resolve";
@@ -6,7 +6,7 @@ import type { MemoryBackend } from "./types";
6
6
  * Selection rules (single source of truth — every memory consumer routes
7
7
  * through this):
8
8
  * - `memory.backend === "hindsight"` → Hindsight remote memory
9
- * - `memory.backend === "mnemosyne"` → local Mnemosyne SQLite memory
9
+ * - `memory.backend === "mnemopi"` → local Mnemopi SQLite memory
10
10
  * - `memory.backend === "local"` → local rollout summary pipeline
11
11
  * - everything else → no-op
12
12
  *
@@ -9,9 +9,9 @@ import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
9
9
  import type { ModelRegistry } from "../config/model-registry";
10
10
  import type { Settings } from "../config/settings";
11
11
  import type { HindsightSessionState } from "../hindsight/state";
12
- import type { MnemosyneSessionState } from "../mnemosyne/state";
12
+ import type { MnemopiSessionState } from "../mnemopi/state";
13
13
  import type { AgentSession } from "../session/agent-session";
14
- export type MemoryBackendId = "off" | "local" | "hindsight" | "mnemosyne";
14
+ export type MemoryBackendId = "off" | "local" | "hindsight" | "mnemopi";
15
15
  export interface MemoryBackendStartOptions {
16
16
  session: AgentSession;
17
17
  settings: Settings;
@@ -19,7 +19,7 @@ export interface MemoryBackendStartOptions {
19
19
  agentDir: string;
20
20
  taskDepth: number;
21
21
  parentHindsightSessionState?: HindsightSessionState;
22
- parentMnemosyneSessionState?: MnemosyneSessionState;
22
+ parentMnemopiSessionState?: MnemopiSessionState;
23
23
  }
24
24
  export interface MemoryBackend {
25
25
  readonly id: MemoryBackendId;
@@ -0,0 +1,4 @@
1
+ import type { MemoryBackend } from "../memory-backend/types";
2
+ import type { AgentSession } from "../session/agent-session";
3
+ export declare const mnemopiBackend: MemoryBackend;
4
+ export declare function getMnemopiDbDirForTests(session: AgentSession): string | undefined;
@@ -0,0 +1,29 @@
1
+ import type { MnemopiOptions } from "@oh-my-pi/pi-mnemopi";
2
+ import type { Settings } from "../config/settings";
3
+ export type MnemopiLlmMode = "none" | "smol" | "remote";
4
+ export type MnemopiScoping = "global" | "per-project" | "per-project-tagged";
5
+ export type MnemopiProviderOptions = Pick<MnemopiOptions, "noEmbeddings" | "embeddingModel" | "embeddingApiUrl" | "embeddingApiKey" | "llm">;
6
+ export interface MnemopiBackendConfig {
7
+ dbPath: string;
8
+ baseBank?: string;
9
+ bank: string;
10
+ globalBank?: string;
11
+ retainBank?: string;
12
+ recallBanks?: readonly string[];
13
+ scoping?: MnemopiScoping;
14
+ autoRecall: boolean;
15
+ autoRetain: boolean;
16
+ retainEveryNTurns: number;
17
+ recallLimit: number;
18
+ recallContextTurns: number;
19
+ recallMaxQueryChars: number;
20
+ injectionTokenLimit: number;
21
+ debug: boolean;
22
+ providerOptions: MnemopiProviderOptions;
23
+ llmMode: MnemopiLlmMode;
24
+ llmBaseUrl?: string;
25
+ llmApiKey?: string;
26
+ llmModel?: string;
27
+ }
28
+ export declare function loadMnemopiConfig(settings: Settings, agentDir: string): MnemopiBackendConfig;
29
+ export declare function truncateApproxTokens(text: string, tokenLimit: number): string;
@@ -0,0 +1,72 @@
1
+ import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
2
+ import { Mnemopi, type RecallResult } from "@oh-my-pi/pi-mnemopi";
3
+ import type { AgentSession } from "../session/agent-session";
4
+ import type { MnemopiBackendConfig } from "./config";
5
+ interface MnemopiScopedMemory {
6
+ bank: string;
7
+ memory: Mnemopi;
8
+ }
9
+ type MnemopiRememberInput = Parameters<Mnemopi["remember"]>[0];
10
+ type MnemopiRememberOptions = Parameters<Mnemopi["remember"]>[1];
11
+ export type MnemopiMemoryEditOperation = "update" | "forget" | "invalidate";
12
+ export interface MnemopiMemoryEditOptions {
13
+ content?: string;
14
+ importance?: number;
15
+ replacementId?: string;
16
+ }
17
+ export interface MnemopiMemoryEditResult {
18
+ status: "updated" | "deleted" | "invalidated" | "not_found";
19
+ bank?: string;
20
+ store?: "working" | "episodic";
21
+ }
22
+ export declare function getMnemopiSessionState(session: AgentSession | undefined): MnemopiSessionState | undefined;
23
+ export declare function setMnemopiSessionState(session: AgentSession, state: MnemopiSessionState | undefined): MnemopiSessionState | undefined;
24
+ export interface MnemopiSessionStateOptions {
25
+ sessionId: string;
26
+ config: MnemopiBackendConfig;
27
+ session: AgentSession;
28
+ aliasOf?: MnemopiSessionState;
29
+ lastRetainedTurn?: number;
30
+ hasRecalledForFirstTurn?: boolean;
31
+ }
32
+ export declare class MnemopiSessionState {
33
+ sessionId: string;
34
+ readonly config: MnemopiBackendConfig;
35
+ readonly session: AgentSession;
36
+ readonly memory: Mnemopi;
37
+ readonly globalMemory?: Mnemopi;
38
+ readonly aliasOf?: MnemopiSessionState;
39
+ private readonly scoped;
40
+ lastRetainedTurn: number;
41
+ hasRecalledForFirstTurn: boolean;
42
+ lastRecallSnippet?: string;
43
+ unsubscribe?: () => void;
44
+ constructor(options: MnemopiSessionStateOptions);
45
+ setSessionId(sessionId: string): void;
46
+ resetConversationTracking(): void;
47
+ getScopedRecallTargets(): readonly MnemopiScopedMemory[];
48
+ getScopedRetainTarget(): MnemopiScopedMemory;
49
+ editScopedMemory(op: MnemopiMemoryEditOperation, id: string, options?: MnemopiMemoryEditOptions): MnemopiMemoryEditResult;
50
+ formatScopedRecallWithIds(results: readonly RecallResult[]): string;
51
+ collectScopedRecallResults(query: string): RecallResult[];
52
+ recallResultsScoped(query: string): RecallResult[];
53
+ formatScopedRecallContext(results: readonly RecallResult[], format?: "bullet" | "json"): string | undefined;
54
+ formatContextScoped(results: readonly RecallResult[], format?: "bullet" | "json"): string;
55
+ rememberInScope(memory: MnemopiRememberInput, options?: MnemopiRememberOptions): string | undefined;
56
+ rememberScoped(memory: MnemopiRememberInput, options?: MnemopiRememberOptions): string | undefined;
57
+ recallForContext(query: string): Promise<string | undefined>;
58
+ beforeAgentStartPrompt(promptText: string): Promise<string | undefined>;
59
+ recallForCompaction(messages: AgentMessage[]): Promise<string | undefined>;
60
+ maybeRetainOnAgentEnd(_messages: AgentMessage[]): Promise<void>;
61
+ forceRetainCurrentSession(): Promise<void>;
62
+ retainMessages(messages: Array<{
63
+ role: string;
64
+ content: string;
65
+ }>, sourceId: string): Promise<void>;
66
+ attachSessionListeners(): void;
67
+ maybeRecallOnAgentStart(): Promise<void>;
68
+ dispose(): void;
69
+ }
70
+ export declare function getMnemopiScopedDbPaths(config: MnemopiBackendConfig): readonly string[];
71
+ export declare function getMnemopiScopedBanks(config: MnemopiBackendConfig): readonly string[];
72
+ export {};
@@ -6,7 +6,8 @@ type ConfigurableEditorAction = Extract<AppKeybinding, "app.interrupt" | "app.cl
6
6
  */
7
7
  export declare class CustomEditor extends Editor {
8
8
  #private;
9
- /** Gradient-highlight the "ultrathink" / "orchestrate" keywords as the user types them. */
9
+ /** Gradient-highlight the "ultrathink" / "orchestrate" / "workflow" keywords as the user types
10
+ * them, skipping any occurrence inside code spans, fenced blocks, or XML sections. */
10
11
  decorateText: (text: string) => string;
11
12
  onEscape?: () => void;
12
13
  shouldBypassAutocompleteOnEscape?: () => boolean;
@@ -21,7 +22,6 @@ export declare class CustomEditor extends Editor {
21
22
  onExternalEditor?: () => void;
22
23
  onHistorySearch?: () => void;
23
24
  onSuspend?: () => void;
24
- onShowHotkeys?: () => void;
25
25
  onSelectModelTemporary?: () => void;
26
26
  /** Called when the configured copy-prompt shortcut is pressed. */
27
27
  onCopyPrompt?: () => void;
@@ -0,0 +1,19 @@
1
+ import { Container, type TUI } from "@oh-my-pi/pi-tui";
2
+ export type OmfgPanelState = "generating" | "validating" | "confirming" | "saving" | "saved" | "rejected" | "aborted" | "error";
3
+ interface OmfgPanelComponentOptions {
4
+ complaint: string;
5
+ tui: TUI;
6
+ }
7
+ export declare class OmfgPanelComponent extends Container {
8
+ #private;
9
+ constructor(options: OmfgPanelComponentOptions);
10
+ appendDraft(delta: string): void;
11
+ setRule(text: string): void;
12
+ setStatus(state: OmfgPanelState, status: string): void;
13
+ markSaved(path: string): void;
14
+ markRejected(): void;
15
+ markAborted(): void;
16
+ markError(message: string): void;
17
+ close(): void;
18
+ }
19
+ export {};
@@ -3,6 +3,7 @@ import { type ProviderDetails, type UsageReport } from "@oh-my-pi/pi-ai";
3
3
  import type { CompactOptions } from "../../extensibility/extensions/types";
4
4
  import { theme } from "../../modes/theme/theme";
5
5
  import type { InteractiveModeContext } from "../../modes/types";
6
+ import { type ShakeMode } from "../../session/shake-types";
6
7
  export declare class CommandController {
7
8
  #private;
8
9
  private readonly ctx;
@@ -29,6 +30,12 @@ export declare class CommandController {
29
30
  handleBashCommand(command: string, excludeFromContext?: boolean): Promise<void>;
30
31
  handlePythonCommand(code: string, excludeFromContext?: boolean): Promise<void>;
31
32
  handleCompactCommand(customInstructions?: string): Promise<CompactionOutcome>;
33
+ /**
34
+ * TUI handler for `/shake`. `elide`/`images` are instant structural drops;
35
+ * `summary` runs the local on-device compressor behind a cancelable loader
36
+ * (Esc aborts via `abortCompaction`). Rebuilds the chat and reports counts.
37
+ */
38
+ handleShakeCommand(mode: ShakeMode): Promise<void>;
32
39
  handleSkillCommand(skillPath: string, args: string): Promise<void>;
33
40
  executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean): Promise<CompactionOutcome>;
34
41
  handleHandoffCommand(customInstructions?: string): Promise<void>;
@@ -24,9 +24,7 @@ export declare class InputController {
24
24
  /** Copy current prompt text to system clipboard. */
25
25
  handleCopyPrompt(): void;
26
26
  cycleThinkingLevel(): void;
27
- cycleRoleModel(options?: {
28
- temporary?: boolean;
29
- }): Promise<void>;
27
+ cycleRoleModel(direction?: "forward" | "backward"): Promise<void>;
30
28
  toggleToolOutputExpansion(): void;
31
29
  setToolsExpanded(expanded: boolean): void;
32
30
  toggleThinkingBlockVisibility(): void;
@@ -0,0 +1,10 @@
1
+ import type { InteractiveModeContext } from "../types";
2
+ export declare class OmfgController {
3
+ #private;
4
+ private readonly ctx;
5
+ constructor(ctx: InteractiveModeContext);
6
+ hasActiveRequest(): boolean;
7
+ handleEscape(): boolean;
8
+ dispose(): void;
9
+ start(complaint: string): Promise<void>;
10
+ }
@@ -0,0 +1,26 @@
1
+ import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
2
+ import type { Rule } from "../../capability/rule";
3
+ export interface ParsedGeneratedRule {
4
+ rule: Rule;
5
+ fileContent: string;
6
+ }
7
+ export type GeneratedRuleParseResult = ParsedGeneratedRule | {
8
+ error: string;
9
+ };
10
+ export interface RuleHistoryValidation {
11
+ matched: boolean;
12
+ feedback?: string;
13
+ }
14
+ export interface ParsedRuleHistoryValidation {
15
+ candidate: ParsedGeneratedRule;
16
+ validation: RuleHistoryValidation;
17
+ repairedCondition: boolean;
18
+ }
19
+ export type OmfgRuleSourceLevel = "project" | "user";
20
+ export declare function extractGeneratedRuleJson(text: string): string | null;
21
+ export declare function sanitizeRuleName(rawName: string): string;
22
+ export declare function buildOmfgRuleForPath(ruleName: string, fileContent: string, filePath: string, level: OmfgRuleSourceLevel): Rule;
23
+ export declare function parseGeneratedRule(text: string): GeneratedRuleParseResult;
24
+ export declare function validateRuleAgainstAssistantHistory(rule: Rule, messages: readonly AgentMessage[]): RuleHistoryValidation;
25
+ export declare function validateParsedRuleAgainstAssistantHistory(candidate: ParsedGeneratedRule, messages: readonly AgentMessage[]): ParsedRuleHistoryValidation;
26
+ export declare function ruleMatchesAssistantHistory(rule: Rule, messages: readonly AgentMessage[]): boolean;
@@ -1,3 +1,7 @@
1
+ /** A gradient keyword highlighter. `resetTo` is the SGR foreground sequence
2
+ * re-emitted after each painted keyword so surrounding text keeps its color;
3
+ * it defaults to a plain foreground reset (editor / default-colored text). */
4
+ export type KeywordHighlighter = (text: string, resetTo?: string) => string;
1
5
  /** Declarative spec for {@link createGradientHighlighter}. */
2
6
  export interface GradientHighlightSpec {
3
7
  /** Cheap, stateless presence probe used to skip the boundary regex on most lines. Must be non-global. */
@@ -20,4 +24,4 @@ export interface GradientHighlightSpec {
20
24
  * untouched when `probe` does not match. The palette is compiled lazily and
21
25
  * memoized per active color mode.
22
26
  */
23
- export declare function createGradientHighlighter(spec: GradientHighlightSpec): (text: string) => string;
27
+ export declare function createGradientHighlighter(spec: GradientHighlightSpec): KeywordHighlighter;
@@ -11,6 +11,7 @@ import { type PlanApprovalDetails } from "../plan-mode/approved-plan";
11
11
  import type { AgentSession, AgentSessionEvent } from "../session/agent-session";
12
12
  import { HistoryStorage } from "../session/history-storage";
13
13
  import type { SessionContext, SessionManager } from "../session/session-manager";
14
+ import type { ShakeMode } from "../session/shake-types";
14
15
  import type { LspStartupServerInfo } from "../tools";
15
16
  import type { EventBus } from "../utils/event-bus";
16
17
  import type { AssistantMessageComponent } from "./components/assistant-message";
@@ -53,6 +54,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
53
54
  statusContainer: Container;
54
55
  todoContainer: Container;
55
56
  btwContainer: Container;
57
+ omfgContainer: Container;
56
58
  editor: CustomEditor;
57
59
  editorContainer: Container;
58
60
  hookWidgetContainerAbove: Container;
@@ -207,6 +209,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
207
209
  handleSSHCommand(text: string): Promise<void>;
208
210
  handleCompactCommand(customInstructions?: string): Promise<CompactionOutcome>;
209
211
  handleHandoffCommand(customInstructions?: string): Promise<void>;
212
+ handleShakeCommand(mode: ShakeMode): Promise<void>;
210
213
  executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean): Promise<CompactionOutcome>;
211
214
  openInBrowser(urlOrPath: string): void;
212
215
  showSettingsSelector(): void;
@@ -233,10 +236,11 @@ export declare class InteractiveMode implements InteractiveModeContext {
233
236
  handleBtwCommand(question: string): Promise<void>;
234
237
  hasActiveBtw(): boolean;
235
238
  handleBtwEscape(): boolean;
239
+ handleOmfgCommand(complaint: string): Promise<void>;
240
+ hasActiveOmfg(): boolean;
241
+ handleOmfgEscape(): boolean;
236
242
  cycleThinkingLevel(): void;
237
- cycleRoleModel(options?: {
238
- temporary?: boolean;
239
- }): Promise<void>;
243
+ cycleRoleModel(direction?: "forward" | "backward"): Promise<void>;
240
244
  toggleToolOutputExpansion(): void;
241
245
  setToolsExpanded(expanded: boolean): void;
242
246
  toggleThinkingBlockVisibility(): void;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Gradient-highlight every magic keyword ("ultrathink", "orchestrate",
3
+ * "workflow") that appears as standalone prose, skipping any occurrence inside a
4
+ * code block, inline code span, or XML/HTML section. Each highlighter paints its
5
+ * own keyword with its own gradient, so chaining is order-independent — the
6
+ * earlier passes only inject zero-width SGR escapes (no backticks or angle
7
+ * brackets), which never confuse the later passes' markdown masking.
8
+ *
9
+ * `resetTo` is the SGR foreground sequence restored after each painted keyword;
10
+ * pass the surrounding text color when decorating already-colored content (e.g.
11
+ * a themed message bubble) so the gradient does not bleed into the rest of the
12
+ * line. Defaults to a plain foreground reset for default-colored editor text.
13
+ */
14
+ export declare function highlightMagicKeywords(text: string, resetTo?: string): string;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Markdown structure awareness for the magic-keyword affordances
3
+ * ("ultrathink"/"orchestrate"/"workflow").
4
+ *
5
+ * Keyword detection and editor/transcript highlighting must fire only on prose
6
+ * the user is actually addressing to the model — never on a word that happens to
7
+ * live inside a fenced code block, an inline code span, or an HTML/XML section.
8
+ * {@link maskNonProse} returns a length-preserving copy of the text where every
9
+ * such region is blanked to spaces, so a word-bounded match run against the mask
10
+ * never lands inside code/markup while its indices still address the original
11
+ * text for painting.
12
+ */
13
+ /**
14
+ * Return a copy of `text` with identical length (indices map 1:1) where every
15
+ * character inside a non-prose region is replaced by a space. Non-prose regions
16
+ * are markdown fenced code blocks, inline code spans, and HTML/XML tags together
17
+ * with the content they enclose. Newlines are preserved. Text with no construct
18
+ * that could open such a region is returned unchanged.
19
+ */
20
+ export declare function maskNonProse(text: string): string;
21
+ /**
22
+ * Whether `text` contains a standalone keyword match (per the non-global,
23
+ * word-bounded `word` regex) that lives in prose rather than inside a code
24
+ * block, inline code span, or HTML/XML section. `word` MUST be non-global so
25
+ * `.test` stays stateless.
26
+ */
27
+ export declare function keywordInProse(text: string, word: RegExp): boolean;
@@ -1,10 +1,15 @@
1
+ import { type KeywordHighlighter } from "./gradient-highlight";
1
2
  /** Hidden system notice appended after a user message that mentions "orchestrate". */
2
3
  export declare const ORCHESTRATE_NOTICE: string;
3
- /** Whether `text` contains the standalone keyword "orchestrate" (any case). */
4
+ /**
5
+ * Whether `text` contains the standalone keyword "orchestrate" (lowercase,
6
+ * whitespace-delimited) in prose — never inside a code block, inline code span,
7
+ * or XML/HTML section.
8
+ */
4
9
  export declare function containsOrchestrate(text: string): boolean;
5
10
  /**
6
11
  * Highlight every standalone "orchestrate" in `text` for editor display with a
7
12
  * cool teal→violet gradient (hue 150..280), visually distinct from ultrathink's
8
13
  * full-spectrum rainbow.
9
14
  */
10
- export declare const highlightOrchestrate: (text: string) => string;
15
+ export declare const highlightOrchestrate: KeywordHighlighter;
@@ -1,5 +1,5 @@
1
1
  import type { TabBarTheme } from "@oh-my-pi/pi-tui";
2
- /** Sanitize text for display in a single-line status. Strips ANSI escape sequences, C0/C1 control characters, collapses whitespace, trims. */
2
+ /** Sanitize text for display in a single-line status. Strips ANSI/VT escape sequences, maps remaining C0/C1 control characters to spaces, collapses whitespace, trims. */
3
3
  export declare function sanitizeStatusText(text: string): string;
4
4
  /** Shared tab bar theme used by model-selector and settings-selector. */
5
5
  export declare function getTabBarTheme(): TabBarTheme;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * "+Nk" turn token-budget directive.
3
+ *
4
+ * A standalone `+<number>[k|m]` token in the user's message sets a per-turn
5
+ * output-token budget surfaced by the `eval` `budget` helper. By default it is
6
+ * ADVISORY — the model self-limits via `budget.remaining()`. Append `!`
7
+ * (`+500k!`) to make it a HARD ceiling: eval `agent()` refuses to spawn once the
8
+ * turn's spend reaches it. Matching is anchored to token boundaries so it does
9
+ * not fire on prices or version strings embedded in prose.
10
+ */
11
+ export interface TurnBudget {
12
+ /** Output-token ceiling for the turn. */
13
+ total: number;
14
+ /** Whether the ceiling is enforced (eval `agent()` throws past it) vs advisory. */
15
+ hard: boolean;
16
+ }
17
+ /** Parse a `+Nk`/`+N`/`+Nm`(`!`) turn-budget directive from `text`, or null when absent. */
18
+ export declare function parseTurnBudget(text: string): TurnBudget | null;
@@ -11,6 +11,7 @@ import type { PlanApprovalDetails } from "../plan-mode/approved-plan";
11
11
  import type { AgentSession, AgentSessionEvent } from "../session/agent-session";
12
12
  import type { HistoryStorage } from "../session/history-storage";
13
13
  import type { SessionContext, SessionManager } from "../session/session-manager";
14
+ import type { ShakeMode } from "../session/shake-types";
14
15
  import type { LspStartupServerInfo } from "../tools";
15
16
  import type { AssistantMessageComponent } from "./components/assistant-message";
16
17
  import type { BashExecutionComponent } from "./components/bash-execution";
@@ -57,6 +58,7 @@ export interface InteractiveModeContext {
57
58
  statusContainer: Container;
58
59
  todoContainer: Container;
59
60
  btwContainer: Container;
61
+ omfgContainer: Container;
60
62
  editor: CustomEditor;
61
63
  editorContainer: Container;
62
64
  hookWidgetContainerAbove: Container;
@@ -207,6 +209,7 @@ export interface InteractiveModeContext {
207
209
  handleSSHCommand(text: string): Promise<void>;
208
210
  handleCompactCommand(customInstructions?: string): Promise<CompactionOutcome>;
209
211
  handleHandoffCommand(customInstructions?: string): Promise<void>;
212
+ handleShakeCommand(mode: ShakeMode): Promise<void>;
210
213
  handleMoveCommand(targetPath: string): Promise<void>;
211
214
  handleRenameCommand(title: string): Promise<void>;
212
215
  handleMemoryCommand(text: string): Promise<void>;
@@ -241,10 +244,11 @@ export interface InteractiveModeContext {
241
244
  handleBtwCommand(question: string): Promise<void>;
242
245
  hasActiveBtw(): boolean;
243
246
  handleBtwEscape(): boolean;
247
+ handleOmfgCommand(complaint: string): Promise<void>;
248
+ hasActiveOmfg(): boolean;
249
+ handleOmfgEscape(): boolean;
244
250
  cycleThinkingLevel(): void;
245
- cycleRoleModel(options?: {
246
- temporary?: boolean;
247
- }): Promise<void>;
251
+ cycleRoleModel(direction?: "forward" | "backward"): Promise<void>;
248
252
  toggleToolOutputExpansion(): void;
249
253
  setToolsExpanded(expanded: boolean): void;
250
254
  toggleThinkingBlockVisibility(): void;
@@ -1,10 +1,15 @@
1
+ import { type KeywordHighlighter } from "./gradient-highlight";
1
2
  /** Hidden system notice appended after a user message that mentions "ultrathink". */
2
3
  export declare const ULTRATHINK_NOTICE: string;
3
- /** Whether `text` contains the standalone keyword "ultrathink" (any case). */
4
+ /**
5
+ * Whether `text` contains the standalone keyword "ultrathink" (lowercase,
6
+ * whitespace-delimited) in prose — never inside a code block, inline code span,
7
+ * or XML/HTML section.
8
+ */
4
9
  export declare function containsUltrathink(text: string): boolean;
5
10
  /**
6
11
  * Rainbow-highlight every standalone "ultrathink" in `text` for editor display.
7
12
  * Sweeps red→violet (hue 0..330), stopping short of the wrap back to red so the
8
13
  * gradient resolves smoothly regardless of casing or match length.
9
14
  */
10
- export declare const highlightUltrathink: (text: string) => string;
15
+ export declare const highlightUltrathink: KeywordHighlighter;
@@ -0,0 +1,15 @@
1
+ import { type KeywordHighlighter } from "./gradient-highlight";
2
+ /** Hidden system notice appended after a user message that mentions "workflow". */
3
+ export declare const WORKFLOW_NOTICE: string;
4
+ /**
5
+ * Whether `text` contains the standalone keyword "workflow"/"workflows"
6
+ * (lowercase, whitespace-delimited) in prose — never inside a code block, inline
7
+ * code span, or XML/HTML section.
8
+ */
9
+ export declare function containsWorkflow(text: string): boolean;
10
+ /**
11
+ * Highlight every standalone "workflow"/"workflows" in `text` for editor display
12
+ * with a warm amber→green gradient (hue 30..150), visually distinct from
13
+ * ultrathink's rainbow and orchestrate's teal→violet.
14
+ */
15
+ export declare const highlightWorkflow: KeywordHighlighter;
@@ -13,7 +13,7 @@ import { type FileSlashCommand } from "./extensibility/slash-commands";
13
13
  import type { HindsightSessionState } from "./hindsight/state";
14
14
  import { type LocalProtocolOptions } from "./internal-urls";
15
15
  import { MCPManager, type MCPToolsLoadResult } from "./mcp";
16
- import { type MnemosyneSessionState } from "./mnemosyne/state";
16
+ import { type MnemopiSessionState } from "./mnemopi/state";
17
17
  import { AgentRegistry } from "./registry/agent-registry";
18
18
  import { AgentSession } from "./session/agent-session";
19
19
  import { AuthStorage } from "./session/auth-storage";
@@ -99,8 +99,8 @@ export interface CreateAgentSessionOptions {
99
99
  taskDepth?: number;
100
100
  /** Parent Hindsight state to alias for subagent memory tools. */
101
101
  parentHindsightSessionState?: HindsightSessionState;
102
- /** Parent Mnemosyne state to alias for subagent memory tools. */
103
- parentMnemosyneSessionState?: MnemosyneSessionState;
102
+ /** Parent Mnemopi state to alias for subagent memory tools. */
103
+ parentMnemopiSessionState?: MnemopiSessionState;
104
104
  /** Pre-allocated agent identity for IRC routing. Default: "0-Main" for top-level, parentTaskPrefix-derived for sub. */
105
105
  agentId?: string;
106
106
  /** Display name for the agent in IRC. Default: "main" or "sub". */
@@ -176,6 +176,16 @@ export declare function discoverAuthStorage(agentDir?: string): Promise<AuthStor
176
176
  * Discover extensions from cwd.
177
177
  */
178
178
  export declare function discoverExtensions(cwd?: string): Promise<LoadExtensionsResult>;
179
+ /**
180
+ * Load the discovered/configured extensions for a session — everything {@link
181
+ * createAgentSession} would load except the inline factory extensions it appends
182
+ * itself. Extracted so the CLI can resolve extension-registered flags (and thus
183
+ * classify `@file` arguments extension-aware) *before* a session — and its
184
+ * terminal breadcrumb — is created, then hand the result back through
185
+ * {@link CreateAgentSessionOptions.preloadedExtensions} so the work is not
186
+ * repeated. Keep this the single source of the discovery branch logic.
187
+ */
188
+ export declare function loadSessionExtensions(options: Pick<CreateAgentSessionOptions, "disableExtensionDiscovery" | "additionalExtensionPaths">, cwd: string, settings: Settings, eventBus: EventBus): Promise<LoadExtensionsResult>;
179
189
  /**
180
190
  * Discover skills from cwd and agentDir.
181
191
  */