@oh-my-pi/pi-coding-agent 15.12.4 → 15.13.0
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.
- package/CHANGELOG.md +304 -6
- package/dist/cli.js +1015 -881
- package/dist/types/async/job-manager.d.ts +15 -0
- package/dist/types/autolearn/controller.d.ts +25 -0
- package/dist/types/autolearn/managed-skills.d.ts +45 -0
- package/dist/types/autoresearch/state.d.ts +1 -1
- package/dist/types/autoresearch/types.d.ts +1 -1
- package/dist/types/cli/args.d.ts +19 -1
- package/dist/types/cli/session-picker.d.ts +1 -1
- package/dist/types/cli/setup-cli.d.ts +1 -1
- package/dist/types/cli/setup-model-picker.d.ts +14 -0
- package/dist/types/collab/protocol.d.ts +1 -1
- package/dist/types/commands/say.d.ts +24 -0
- package/dist/types/config/keybindings.d.ts +3 -3
- package/dist/types/config/model-registry.d.ts +10 -0
- package/dist/types/config/models-config-schema.d.ts +12 -0
- package/dist/types/config/models-config.d.ts +8 -2
- package/dist/types/config/settings-schema.d.ts +261 -58
- package/dist/types/export/html/index.d.ts +2 -1
- package/dist/types/extensibility/extensions/model-api.d.ts +17 -0
- package/dist/types/extensibility/extensions/runner.d.ts +3 -1
- package/dist/types/extensibility/extensions/types.d.ts +47 -1
- package/dist/types/extensibility/hooks/index.d.ts +2 -1
- package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +9 -0
- package/dist/types/extensibility/plugins/loader.d.ts +11 -0
- package/dist/types/extensibility/shared-events.d.ts +1 -1
- package/dist/types/extensibility/skills.d.ts +10 -0
- package/dist/types/goals/guided-setup.d.ts +18 -0
- package/dist/types/goals/state.d.ts +1 -1
- package/dist/types/hindsight/transcript.d.ts +1 -1
- package/dist/types/index.d.ts +5 -0
- package/dist/types/internal-urls/local-protocol.d.ts +4 -2
- package/dist/types/main.d.ts +4 -3
- package/dist/types/mcp/startup-events.d.ts +11 -0
- package/dist/types/memories/index.d.ts +7 -0
- package/dist/types/memory-backend/local-backend.d.ts +4 -3
- package/dist/types/mnemopi/config.d.ts +4 -4
- package/dist/types/modes/components/agent-hub.d.ts +6 -0
- package/dist/types/modes/components/assistant-message.d.ts +1 -2
- package/dist/types/modes/components/compaction-summary-message.d.ts +15 -1
- package/dist/types/modes/components/custom-editor.d.ts +39 -1
- package/dist/types/modes/components/custom-editor.test.d.ts +1 -0
- package/dist/types/modes/components/session-selector.d.ts +1 -1
- package/dist/types/modes/components/tool-execution.d.ts +26 -16
- package/dist/types/modes/components/transcript-container.d.ts +23 -2
- package/dist/types/modes/components/tree-selector.d.ts +1 -1
- package/dist/types/modes/components/usage-row.d.ts +3 -0
- package/dist/types/modes/controllers/command-controller.d.ts +2 -2
- package/dist/types/modes/controllers/input-controller.d.ts +14 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +3 -1
- package/dist/types/modes/gradient-highlight.d.ts +9 -4
- package/dist/types/modes/image-references.d.ts +6 -0
- package/dist/types/modes/interactive-mode.d.ts +27 -3
- package/dist/types/modes/magic-keywords.d.ts +13 -1
- package/dist/types/modes/rpc/rpc-mode.d.ts +35 -1
- package/dist/types/modes/rpc/rpc-types.d.ts +9 -1
- package/dist/types/modes/runtime-init.d.ts +4 -0
- package/dist/types/modes/theme/theme.d.ts +13 -2
- package/dist/types/modes/types.d.ts +8 -2
- package/dist/types/modes/utils/ui-helpers.d.ts +1 -1
- package/dist/types/registry/agent-registry.d.ts +17 -0
- package/dist/types/secrets/obfuscator.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +14 -2
- package/dist/types/session/indexed-session-storage.d.ts +3 -4
- package/dist/types/session/session-context.d.ts +39 -0
- package/dist/types/session/session-entries.d.ts +159 -0
- package/dist/types/session/session-listing.d.ts +69 -0
- package/dist/types/session/session-loader.d.ts +16 -0
- package/dist/types/session/session-manager.d.ts +82 -474
- package/dist/types/session/session-migrations.d.ts +12 -0
- package/dist/types/session/session-paths.d.ts +25 -0
- package/dist/types/session/session-persistence.d.ts +8 -0
- package/dist/types/session/session-storage.d.ts +11 -12
- package/dist/types/session/snapcompact-inline.d.ts +12 -1
- package/dist/types/session/snapcompact-savings-journal.d.ts +46 -0
- package/dist/types/session/tool-choice-queue.d.ts +6 -6
- package/dist/types/stt/asr-client.d.ts +90 -0
- package/dist/types/stt/asr-protocol.d.ts +97 -0
- package/dist/types/stt/asr-worker.d.ts +2 -0
- package/dist/types/stt/downloader.d.ts +38 -0
- package/dist/types/stt/endpointer.d.ts +59 -0
- package/dist/types/stt/index.d.ts +5 -1
- package/dist/types/stt/models.d.ts +120 -0
- package/dist/types/stt/recorder.d.ts +17 -0
- package/dist/types/stt/stt-controller.d.ts +6 -0
- package/dist/types/stt/transcriber.d.ts +5 -7
- package/dist/types/stt/wav.d.ts +29 -0
- package/dist/types/system-prompt.d.ts +4 -0
- package/dist/types/task/executor.d.ts +2 -0
- package/dist/types/task/index.d.ts +9 -1
- package/dist/types/task/types.d.ts +36 -0
- package/dist/types/tools/bash.d.ts +2 -2
- package/dist/types/tools/eval-render.d.ts +1 -1
- package/dist/types/tools/index.d.ts +11 -1
- package/dist/types/tools/irc.d.ts +1 -0
- package/dist/types/tools/learn.d.ts +51 -0
- package/dist/types/tools/manage-skill.d.ts +40 -0
- package/dist/types/tools/plan-mode-guard.d.ts +10 -0
- package/dist/types/tools/renderers.d.ts +7 -11
- package/dist/types/tools/ssh.d.ts +1 -1
- package/dist/types/tools/todo.d.ts +1 -1
- package/dist/types/tools/tts.d.ts +25 -0
- package/dist/types/tools/write.d.ts +1 -1
- package/dist/types/tts/downloader.d.ts +20 -0
- package/dist/types/tts/index.d.ts +8 -0
- package/dist/types/tts/models.d.ts +82 -0
- package/dist/types/tts/player.d.ts +32 -0
- package/dist/types/tts/runtime.d.ts +6 -0
- package/dist/types/tts/streaming-player.d.ts +41 -0
- package/dist/types/tts/tts-client.d.ts +93 -0
- package/dist/types/tts/tts-protocol.d.ts +95 -0
- package/dist/types/tts/tts-worker.d.ts +2 -0
- package/dist/types/tts/vocalizer.d.ts +41 -0
- package/dist/types/tts/wav.d.ts +8 -0
- package/dist/types/utils/tool-choice.d.ts +8 -0
- package/dist/types/utils/tools-manager.d.ts +2 -1
- package/dist/types/utils/tools-manager.test.d.ts +1 -0
- package/dist/types/web/scrapers/github.d.ts +1 -1
- package/package.json +15 -14
- package/src/async/job-manager.ts +49 -0
- package/src/autolearn/controller.ts +139 -0
- package/src/autolearn/managed-skills.ts +257 -0
- package/src/autoresearch/state.ts +1 -1
- package/src/autoresearch/types.ts +1 -1
- package/src/cli/args.ts +56 -2
- package/src/cli/session-picker.ts +2 -1
- package/src/cli/setup-cli.ts +148 -47
- package/src/cli/setup-model-picker.ts +43 -0
- package/src/cli-commands.ts +1 -0
- package/src/cli.ts +45 -13
- package/src/collab/host.ts +1 -1
- package/src/collab/protocol.ts +1 -1
- package/src/commands/say.ts +102 -0
- package/src/commands/setup.ts +1 -1
- package/src/commit/agentic/tools/analyze-file.ts +3 -0
- package/src/config/keybindings.ts +2 -2
- package/src/config/model-discovery.ts +11 -5
- package/src/config/model-registry.ts +64 -9
- package/src/config/models-config-schema.ts +4 -1
- package/src/config/models-config.ts +2 -1
- package/src/config/settings-schema.ts +248 -32
- package/src/config/settings.ts +10 -0
- package/src/discovery/builtin.ts +23 -1
- package/src/discovery/claude-plugins.ts +44 -5
- package/src/discovery/helpers.ts +41 -1
- package/src/eval/__tests__/budget-bridge.test.ts +1 -1
- package/src/eval/js/shared/prelude.txt +69 -17
- package/src/export/html/index.ts +3 -6
- package/src/extensibility/extensions/model-api.ts +41 -0
- package/src/extensibility/extensions/runner.ts +4 -0
- package/src/extensibility/extensions/types.ts +52 -1
- package/src/extensibility/extensions/wrapper.ts +41 -5
- package/src/extensibility/hooks/index.ts +2 -1
- package/src/extensibility/plugins/legacy-pi-compat.ts +43 -13
- package/src/extensibility/plugins/loader.ts +30 -19
- package/src/extensibility/plugins/manager.ts +221 -90
- package/src/extensibility/shared-events.ts +1 -1
- package/src/extensibility/skills.ts +96 -15
- package/src/goals/guided-setup.ts +133 -0
- package/src/goals/state.ts +1 -1
- package/src/hindsight/transcript.ts +1 -1
- package/src/index.ts +5 -0
- package/src/internal-urls/docs-index.generated.ts +10 -10
- package/src/internal-urls/history-protocol.ts +1 -1
- package/src/internal-urls/local-protocol.ts +29 -7
- package/src/main.ts +27 -7
- package/src/mcp/startup-events.ts +21 -0
- package/src/mcp/transports/stdio.ts +2 -1
- package/src/memories/index.ts +146 -11
- package/src/memory-backend/local-backend.ts +11 -5
- package/src/mnemopi/backend.ts +1 -0
- package/src/mnemopi/config.ts +26 -10
- package/src/modes/acp/acp-agent.ts +3 -5
- package/src/modes/components/agent-hub.ts +49 -4
- package/src/modes/components/assistant-message.ts +4 -37
- package/src/modes/components/compaction-summary-message.ts +125 -26
- package/src/modes/components/custom-editor.test.ts +96 -0
- package/src/modes/components/custom-editor.ts +164 -8
- package/src/modes/components/session-selector.ts +1 -1
- package/src/modes/components/settings-defs.ts +7 -0
- package/src/modes/components/tool-execution.ts +82 -43
- package/src/modes/components/transcript-container.ts +70 -1
- package/src/modes/components/tree-selector.ts +1 -1
- package/src/modes/components/usage-row.ts +18 -0
- package/src/modes/components/user-message.ts +4 -2
- package/src/modes/controllers/command-controller.ts +14 -4
- package/src/modes/controllers/event-controller.ts +78 -11
- package/src/modes/controllers/extension-ui-controller.ts +6 -0
- package/src/modes/controllers/input-controller.ts +258 -27
- package/src/modes/controllers/selector-controller.ts +12 -2
- package/src/modes/gradient-highlight.ts +21 -9
- package/src/modes/image-references.ts +20 -0
- package/src/modes/interactive-mode.ts +286 -40
- package/src/modes/magic-keywords.ts +27 -5
- package/src/modes/rpc/rpc-mode.ts +146 -14
- package/src/modes/rpc/rpc-subagents.ts +2 -2
- package/src/modes/rpc/rpc-types.ts +8 -2
- package/src/modes/runtime-init.ts +28 -3
- package/src/modes/theme/theme.ts +98 -50
- package/src/modes/types.ts +6 -2
- package/src/modes/utils/hotkeys-markdown.ts +1 -1
- package/src/modes/utils/ui-helpers.ts +34 -6
- package/src/priority.json +5 -1
- package/src/prompts/agents/task.md +1 -0
- package/src/prompts/goals/guided-goal-interview.md +8 -0
- package/src/prompts/goals/guided-goal-system.md +12 -0
- package/src/prompts/memories/read-path.md +6 -0
- package/src/prompts/system/autolearn-guidance-learn.md +1 -0
- package/src/prompts/system/autolearn-guidance.md +7 -0
- package/src/prompts/system/autolearn-nudge.md +3 -0
- package/src/prompts/system/eager-task.md +7 -0
- package/src/prompts/system/eager-todo.md +11 -6
- package/src/prompts/system/subagent-system-prompt.md +4 -0
- package/src/prompts/system/system-prompt.md +10 -5
- package/src/prompts/system/title-marker-instruction.md +1 -0
- package/src/prompts/system/title-system-marker.md +16 -0
- package/src/prompts/tools/job.md +1 -0
- package/src/prompts/tools/learn.md +7 -0
- package/src/prompts/tools/manage-skill.md +9 -0
- package/src/prompts/tools/task.md +3 -0
- package/src/registry/agent-registry.ts +30 -0
- package/src/sdk.ts +88 -24
- package/src/secrets/obfuscator.ts +1 -1
- package/src/session/agent-session.ts +209 -87
- package/src/session/history-storage.ts +2 -2
- package/src/session/indexed-session-storage.ts +7 -17
- package/src/session/session-context.ts +352 -0
- package/src/session/session-entries.ts +194 -0
- package/src/session/session-listing.ts +588 -0
- package/src/session/session-loader.ts +106 -0
- package/src/session/session-manager.ts +933 -3145
- package/src/session/session-migrations.ts +78 -0
- package/src/session/session-paths.ts +193 -0
- package/src/session/session-persistence.ts +131 -0
- package/src/session/session-storage.ts +91 -50
- package/src/session/snapcompact-inline.ts +21 -1
- package/src/session/snapcompact-savings-journal.ts +113 -0
- package/src/session/tool-choice-queue.ts +23 -11
- package/src/slash-commands/builtin-registry.ts +25 -3
- package/src/stt/asr-client.ts +520 -0
- package/src/stt/asr-protocol.ts +65 -0
- package/src/stt/asr-worker.ts +790 -0
- package/src/stt/downloader.ts +107 -47
- package/src/stt/endpointer.ts +259 -0
- package/src/stt/index.ts +5 -1
- package/src/stt/models.ts +150 -0
- package/src/stt/recorder.ts +247 -60
- package/src/stt/stt-controller.ts +201 -22
- package/src/stt/transcriber.ts +37 -68
- package/src/stt/wav.ts +173 -0
- package/src/system-prompt.ts +8 -0
- package/src/task/agents.ts +1 -2
- package/src/task/executor.ts +49 -15
- package/src/task/index.ts +60 -6
- package/src/task/render.ts +83 -8
- package/src/task/types.ts +53 -0
- package/src/tools/ask.ts +8 -0
- package/src/tools/bash.ts +4 -3
- package/src/tools/eval-render.ts +4 -3
- package/src/tools/index.ts +40 -4
- package/src/tools/irc.ts +10 -2
- package/src/tools/job.ts +14 -2
- package/src/tools/learn.ts +144 -0
- package/src/tools/manage-skill.ts +104 -0
- package/src/tools/plan-mode-guard.ts +53 -19
- package/src/tools/renderers.ts +7 -11
- package/src/tools/ssh.ts +4 -3
- package/src/tools/todo.ts +1 -1
- package/src/tools/tts.ts +203 -92
- package/src/tools/write.ts +18 -2
- package/src/tts/downloader.ts +64 -0
- package/src/tts/index.ts +8 -0
- package/src/tts/models.ts +137 -0
- package/src/tts/player.ts +137 -0
- package/src/tts/runtime.ts +21 -0
- package/src/tts/streaming-player.ts +266 -0
- package/src/tts/tts-client.ts +647 -0
- package/src/tts/tts-protocol.ts +60 -0
- package/src/tts/tts-worker.ts +497 -0
- package/src/tts/vocalizer.ts +162 -0
- package/src/tts/wav.ts +58 -0
- package/src/utils/title-generator.ts +48 -5
- package/src/utils/tool-choice.ts +16 -0
- package/src/utils/tools-manager.test.ts +25 -0
- package/src/utils/tools-manager.ts +19 -1
- package/src/web/scrapers/github.ts +96 -0
- package/src/web/search/index.ts +13 -0
- package/src/web/search/providers/searxng.ts +13 -1
- package/dist/types/stt/setup.d.ts +0 -18
- package/src/stt/setup.ts +0 -52
- package/src/stt/transcribe.py +0 -70
|
@@ -80,8 +80,12 @@ export type RpcSessionChangeResult =
|
|
|
80
80
|
export type RpcSessionChangeSession = Pick<AgentSession, "newSession" | "switchSession" | "branch">;
|
|
81
81
|
|
|
82
82
|
export type RpcSkillCommandSession = Pick<AgentSession, "promptCustomMessage" | "skills" | "skillsSettings">;
|
|
83
|
+
export type RpcSkillCommandResult = { agentInvoked: true };
|
|
83
84
|
|
|
84
|
-
export async function tryRunRpcSkillCommand(
|
|
85
|
+
export async function tryRunRpcSkillCommand(
|
|
86
|
+
session: RpcSkillCommandSession,
|
|
87
|
+
text: string,
|
|
88
|
+
): Promise<RpcSkillCommandResult | false> {
|
|
85
89
|
if (!text.startsWith("/skill:")) return false;
|
|
86
90
|
if (!session.skillsSettings?.enableSkillCommands) return false;
|
|
87
91
|
const spaceIndex = text.indexOf(" ");
|
|
@@ -98,8 +102,120 @@ export async function tryRunRpcSkillCommand(session: RpcSkillCommandSession, tex
|
|
|
98
102
|
details: built.details,
|
|
99
103
|
attribution: "user",
|
|
100
104
|
});
|
|
101
|
-
return true;
|
|
105
|
+
return { agentInvoked: true };
|
|
102
106
|
}
|
|
107
|
+
|
|
108
|
+
export function reportLocalOnlyPromptResult(input: {
|
|
109
|
+
id: string | undefined;
|
|
110
|
+
prompt: Promise<boolean>;
|
|
111
|
+
output: (obj: object) => void;
|
|
112
|
+
onError: (error: Error) => void;
|
|
113
|
+
hasExtensionAgentMessageTask?: () => boolean;
|
|
114
|
+
waitForExtensionAgentMessageTasks?: () => Promise<void>;
|
|
115
|
+
}): void {
|
|
116
|
+
void input.prompt
|
|
117
|
+
.then(async agentInvoked => {
|
|
118
|
+
if (agentInvoked) return;
|
|
119
|
+
await input.waitForExtensionAgentMessageTasks?.();
|
|
120
|
+
if (!input.hasExtensionAgentMessageTask?.()) {
|
|
121
|
+
input.output({ type: "prompt_result", id: input.id, agentInvoked: false });
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
.catch(error => {
|
|
125
|
+
input.onError(error instanceof Error ? error : new Error(String(error)));
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
type RpcExtensionUserMessageScope = {
|
|
130
|
+
hasAgentMessageTask: boolean;
|
|
131
|
+
pendingAgentMessageTasks: Set<Promise<void>>;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Tracks extension-originated messages while an RPC prompt is executing.
|
|
136
|
+
* A slash command can resolve the outer prompt as local-only while also
|
|
137
|
+
* scheduling agent work through pi.sendUserMessage() or pi.sendMessage()
|
|
138
|
+
* with triggerTurn; that prompt must not report agentInvoked:false to the host.
|
|
139
|
+
*/
|
|
140
|
+
export class RpcExtensionUserMessageTracker {
|
|
141
|
+
#activePromptScopes = new Set<RpcExtensionUserMessageScope>();
|
|
142
|
+
|
|
143
|
+
markAgentMessageTask(): void {
|
|
144
|
+
for (const scope of this.#activePromptScopes) {
|
|
145
|
+
scope.hasAgentMessageTask = true;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
trackAgentMessageTask(task: Promise<unknown>): void {
|
|
150
|
+
for (const scope of this.#activePromptScopes) {
|
|
151
|
+
this.#trackAgentMessageTaskForScope(scope, task);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
#trackAgentMessageTaskForScope(scope: RpcExtensionUserMessageScope, task: Promise<unknown>): void {
|
|
156
|
+
const scopedTask = task.then(
|
|
157
|
+
() => {
|
|
158
|
+
scope.hasAgentMessageTask = true;
|
|
159
|
+
},
|
|
160
|
+
() => {},
|
|
161
|
+
);
|
|
162
|
+
scope.pendingAgentMessageTasks.add(scopedTask);
|
|
163
|
+
void scopedTask.finally(() => {
|
|
164
|
+
scope.pendingAgentMessageTasks.delete(scopedTask);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async #waitForAgentMessageTasks(scope: RpcExtensionUserMessageScope): Promise<void> {
|
|
169
|
+
while (scope.pendingAgentMessageTasks.size > 0) {
|
|
170
|
+
await Promise.allSettled(Array.from(scope.pendingAgentMessageTasks));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
watchPrompt<T>(startPrompt: () => Promise<T>): {
|
|
175
|
+
prompt: Promise<T>;
|
|
176
|
+
hasAgentMessageTask: () => boolean;
|
|
177
|
+
waitForAgentMessageTasks: () => Promise<void>;
|
|
178
|
+
} {
|
|
179
|
+
const scope: RpcExtensionUserMessageScope = {
|
|
180
|
+
hasAgentMessageTask: false,
|
|
181
|
+
pendingAgentMessageTasks: new Set(),
|
|
182
|
+
};
|
|
183
|
+
this.#activePromptScopes.add(scope);
|
|
184
|
+
let prompt: Promise<T>;
|
|
185
|
+
try {
|
|
186
|
+
prompt = startPrompt();
|
|
187
|
+
} catch (error) {
|
|
188
|
+
this.#activePromptScopes.delete(scope);
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
prompt: prompt.finally(() => {
|
|
193
|
+
this.#activePromptScopes.delete(scope);
|
|
194
|
+
}),
|
|
195
|
+
hasAgentMessageTask: () => scope.hasAgentMessageTask,
|
|
196
|
+
waitForAgentMessageTasks: () => this.#waitForAgentMessageTasks(scope),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export function watchAndReportLocalOnlyPromptResult(input: {
|
|
202
|
+
id: string | undefined;
|
|
203
|
+
startPrompt: () => Promise<boolean>;
|
|
204
|
+
output: (obj: object) => void;
|
|
205
|
+
onError: (error: Error) => void;
|
|
206
|
+
extensionUserMessageTracker: RpcExtensionUserMessageTracker;
|
|
207
|
+
}): void {
|
|
208
|
+
const trackedPrompt = input.extensionUserMessageTracker.watchPrompt(input.startPrompt);
|
|
209
|
+
reportLocalOnlyPromptResult({
|
|
210
|
+
id: input.id,
|
|
211
|
+
prompt: trackedPrompt.prompt,
|
|
212
|
+
output: input.output,
|
|
213
|
+
onError: input.onError,
|
|
214
|
+
hasExtensionAgentMessageTask: trackedPrompt.hasAgentMessageTask,
|
|
215
|
+
waitForExtensionAgentMessageTasks: trackedPrompt.waitForAgentMessageTasks,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
103
219
|
export type RpcSubagentResetRegistry = Pick<RpcSubagentRegistry, "clear">;
|
|
104
220
|
|
|
105
221
|
export async function handleRpcSessionChange(
|
|
@@ -277,6 +393,8 @@ export async function runRpcMode(
|
|
|
277
393
|
return { id, type: "response", command, success: false, error: message };
|
|
278
394
|
};
|
|
279
395
|
|
|
396
|
+
const extensionUserMessageTracker = new RpcExtensionUserMessageTracker();
|
|
397
|
+
|
|
280
398
|
const pendingExtensionRequests = new Map<string, PendingExtensionRequest>();
|
|
281
399
|
const hostToolBridge = new RpcHostToolBridge(output);
|
|
282
400
|
const hostUriBridge = new RpcHostUriBridge(output);
|
|
@@ -533,6 +651,9 @@ export async function runRpcMode(
|
|
|
533
651
|
onShutdown: () => {
|
|
534
652
|
shutdownState.requested = true;
|
|
535
653
|
},
|
|
654
|
+
trackAgentInvokingMessage: task => {
|
|
655
|
+
extensionUserMessageTracker.trackAgentMessageTask(task);
|
|
656
|
+
},
|
|
536
657
|
uiContext: rpcUiContext,
|
|
537
658
|
});
|
|
538
659
|
|
|
@@ -569,8 +690,9 @@ export async function runRpcMode(
|
|
|
569
690
|
// =================================================================
|
|
570
691
|
|
|
571
692
|
case "prompt": {
|
|
572
|
-
|
|
573
|
-
|
|
693
|
+
const skillResult = await tryRunRpcSkillCommand(session, command.message);
|
|
694
|
+
if (skillResult) {
|
|
695
|
+
return success(id, "prompt", skillResult);
|
|
574
696
|
}
|
|
575
697
|
const builtinResult = await executeAcpBuiltinSlashCommand(command.message, {
|
|
576
698
|
session,
|
|
@@ -589,22 +711,32 @@ export async function runRpcMode(
|
|
|
589
711
|
});
|
|
590
712
|
if (builtinResult !== false) {
|
|
591
713
|
if ("prompt" in builtinResult) {
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
714
|
+
watchAndReportLocalOnlyPromptResult({
|
|
715
|
+
id,
|
|
716
|
+
startPrompt: () => session.prompt(builtinResult.prompt, { images: command.images }),
|
|
717
|
+
output,
|
|
718
|
+
onError: promptError => output(error(id, "prompt", promptError.message)),
|
|
719
|
+
extensionUserMessageTracker,
|
|
720
|
+
});
|
|
721
|
+
return success(id, "prompt");
|
|
595
722
|
}
|
|
596
|
-
return success(id, "prompt");
|
|
723
|
+
return success(id, "prompt", { agentInvoked: false });
|
|
597
724
|
}
|
|
598
725
|
|
|
599
726
|
// Don't await - events will stream
|
|
600
727
|
// Extension commands are executed immediately, file prompt templates are expanded
|
|
601
728
|
// If streaming and streamingBehavior specified, queues via steer/followUp
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
729
|
+
watchAndReportLocalOnlyPromptResult({
|
|
730
|
+
id,
|
|
731
|
+
startPrompt: () =>
|
|
732
|
+
session.prompt(command.message, {
|
|
733
|
+
images: command.images,
|
|
734
|
+
streamingBehavior: command.streamingBehavior,
|
|
735
|
+
}),
|
|
736
|
+
output,
|
|
737
|
+
onError: promptError => output(error(id, "prompt", promptError.message)),
|
|
738
|
+
extensionUserMessageTracker,
|
|
739
|
+
});
|
|
608
740
|
return success(id, "prompt");
|
|
609
741
|
}
|
|
610
742
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs/promises";
|
|
2
2
|
import { isEnoent } from "@oh-my-pi/pi-utils";
|
|
3
|
-
import type { FileEntry, SessionMessageEntry } from "../../session/session-
|
|
4
|
-
import { parseSessionEntries } from "../../session/session-
|
|
3
|
+
import type { FileEntry, SessionMessageEntry } from "../../session/session-entries";
|
|
4
|
+
import { parseSessionEntries } from "../../session/session-loader";
|
|
5
5
|
import {
|
|
6
6
|
type AgentProgress,
|
|
7
7
|
type SubagentEventPayload,
|
|
@@ -10,7 +10,7 @@ import type { Effort, ImageContent, Model } from "@oh-my-pi/pi-ai";
|
|
|
10
10
|
import type { BashResult } from "../../exec/bash-executor";
|
|
11
11
|
import type { ContextUsage } from "../../extensibility/extensions/types";
|
|
12
12
|
import type { AgentSessionEvent, SessionStats } from "../../session/agent-session";
|
|
13
|
-
import type { FileEntry } from "../../session/session-
|
|
13
|
+
import type { FileEntry } from "../../session/session-entries";
|
|
14
14
|
import type { AvailableSlashCommandSource } from "../../slash-commands/available-commands";
|
|
15
15
|
import type {
|
|
16
16
|
AgentProgress,
|
|
@@ -126,6 +126,12 @@ export interface RpcAvailableCommandsUpdateFrame {
|
|
|
126
126
|
commands: RpcAvailableSlashCommand[];
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
export interface RpcPromptResultFrame {
|
|
130
|
+
type: "prompt_result";
|
|
131
|
+
id?: string;
|
|
132
|
+
agentInvoked: boolean;
|
|
133
|
+
}
|
|
134
|
+
|
|
129
135
|
export interface RpcHandoffResult {
|
|
130
136
|
savedPath?: string;
|
|
131
137
|
}
|
|
@@ -163,7 +169,7 @@ export interface RpcSubagentMessagesResult {
|
|
|
163
169
|
// Success responses with data
|
|
164
170
|
export type RpcResponse =
|
|
165
171
|
// Prompting (async - events follow)
|
|
166
|
-
| { id?: string; type: "response"; command: "prompt"; success: true }
|
|
172
|
+
| { id?: string; type: "response"; command: "prompt"; success: true; data?: { agentInvoked: boolean } }
|
|
167
173
|
| { id?: string; type: "response"; command: "steer"; success: true }
|
|
168
174
|
| { id?: string; type: "response"; command: "follow_up"; success: true }
|
|
169
175
|
| { id?: string; type: "response"; command: "abort"; success: true }
|
|
@@ -23,6 +23,10 @@ export interface InitializeExtensionsOptions {
|
|
|
23
23
|
onShutdown?: () => void;
|
|
24
24
|
/** Optional UI context (rpc supplies one; print runs headless). */
|
|
25
25
|
uiContext?: ExtensionUIContext;
|
|
26
|
+
/** Optional lifecycle hook for extension-originated messages that can start an agent turn. */
|
|
27
|
+
markAgentInvokingMessage?: () => void;
|
|
28
|
+
/** Optional lifecycle hook for extension-originated sends whose success/failure determines turn ownership. */
|
|
29
|
+
trackAgentInvokingMessage?: (task: Promise<unknown>) => void;
|
|
26
30
|
}
|
|
27
31
|
|
|
28
32
|
/**
|
|
@@ -35,19 +39,40 @@ export async function initializeExtensions(session: AgentSession, options: Initi
|
|
|
35
39
|
const runner = session.extensionRunner;
|
|
36
40
|
if (!runner) return;
|
|
37
41
|
|
|
38
|
-
const {
|
|
42
|
+
const {
|
|
43
|
+
reportSendError,
|
|
44
|
+
reportRuntimeError,
|
|
45
|
+
onShutdown,
|
|
46
|
+
uiContext,
|
|
47
|
+
markAgentInvokingMessage,
|
|
48
|
+
trackAgentInvokingMessage,
|
|
49
|
+
} = options;
|
|
39
50
|
const shutdown = onShutdown ?? (() => {});
|
|
40
51
|
|
|
41
52
|
runner.initialize(
|
|
42
53
|
// ExtensionActions
|
|
43
54
|
{
|
|
44
55
|
sendMessage: (message, sendOptions) => {
|
|
45
|
-
session.sendCustomMessage(message, sendOptions)
|
|
56
|
+
const sendTask = session.sendCustomMessage(message, sendOptions);
|
|
57
|
+
if (sendOptions?.triggerTurn) {
|
|
58
|
+
if (trackAgentInvokingMessage) {
|
|
59
|
+
trackAgentInvokingMessage(sendTask);
|
|
60
|
+
} else {
|
|
61
|
+
markAgentInvokingMessage?.();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
sendTask.catch(e => {
|
|
46
65
|
reportSendError("extension_send", e instanceof Error ? e : new Error(String(e)));
|
|
47
66
|
});
|
|
48
67
|
},
|
|
49
68
|
sendUserMessage: (content, sendOptions) => {
|
|
50
|
-
session.sendUserMessage(content, sendOptions)
|
|
69
|
+
const sendTask = session.sendUserMessage(content, sendOptions);
|
|
70
|
+
if (trackAgentInvokingMessage) {
|
|
71
|
+
trackAgentInvokingMessage(sendTask);
|
|
72
|
+
} else {
|
|
73
|
+
markAgentInvokingMessage?.();
|
|
74
|
+
}
|
|
75
|
+
sendTask.catch(e => {
|
|
51
76
|
reportSendError("extension_send_user", e instanceof Error ? e : new Error(String(e)));
|
|
52
77
|
});
|
|
53
78
|
},
|
package/src/modes/theme/theme.ts
CHANGED
|
@@ -2098,6 +2098,11 @@ var currentThemeName: string | undefined;
|
|
|
2098
2098
|
export function getCurrentThemeName(): string | undefined {
|
|
2099
2099
|
return currentThemeName;
|
|
2100
2100
|
}
|
|
2101
|
+
|
|
2102
|
+
/** Returns unstyled `text` before `initTheme()` assigns the global theme; use only for early-render paths. */
|
|
2103
|
+
export function fgOrPlain(color: ThemeColor, text: string, styledText: string = text): string {
|
|
2104
|
+
return typeof theme === "undefined" ? text : theme.fg(color, styledText);
|
|
2105
|
+
}
|
|
2101
2106
|
var currentSymbolPresetOverride: SymbolPreset | undefined;
|
|
2102
2107
|
var currentColorBlindMode: boolean = false;
|
|
2103
2108
|
var themeWatcher: fs.FSWatcher | undefined;
|
|
@@ -2108,6 +2113,7 @@ var autoDarkTheme: string = "dark";
|
|
|
2108
2113
|
var autoLightTheme: string = "light";
|
|
2109
2114
|
var onThemeChangeCallback: (() => void) | undefined;
|
|
2110
2115
|
var themeLoadRequestId: number = 0;
|
|
2116
|
+
let themeEpoch = 0;
|
|
2111
2117
|
|
|
2112
2118
|
function getCurrentThemeOptions(): CreateThemeOptions {
|
|
2113
2119
|
return {
|
|
@@ -2160,9 +2166,7 @@ export async function setTheme(
|
|
|
2160
2166
|
if (enableWatcher) {
|
|
2161
2167
|
await startThemeWatcher();
|
|
2162
2168
|
}
|
|
2163
|
-
|
|
2164
|
-
onThemeChangeCallback();
|
|
2165
|
-
}
|
|
2169
|
+
notifyThemeChange();
|
|
2166
2170
|
return { success: true };
|
|
2167
2171
|
} catch (error) {
|
|
2168
2172
|
if (requestId !== themeLoadRequestId) {
|
|
@@ -2171,6 +2175,10 @@ export async function setTheme(
|
|
|
2171
2175
|
// Theme is invalid - fall back to dark theme
|
|
2172
2176
|
currentThemeName = "dark";
|
|
2173
2177
|
theme = await loadTheme("dark", getCurrentThemeOptions());
|
|
2178
|
+
// The active theme just changed to the fallback — bump the epoch so memoized
|
|
2179
|
+
// renderers (e.g. ToolExecutionComponent) re-shape with the fallback colors
|
|
2180
|
+
// instead of holding the failed theme's stale styling.
|
|
2181
|
+
notifyThemeChange();
|
|
2174
2182
|
// Don't start watcher for fallback theme
|
|
2175
2183
|
return {
|
|
2176
2184
|
success: false,
|
|
@@ -2187,9 +2195,7 @@ export async function previewTheme(name: string): Promise<{ success: boolean; er
|
|
|
2187
2195
|
return { success: false, error: "Theme preview superseded by a newer request" };
|
|
2188
2196
|
}
|
|
2189
2197
|
theme = loadedTheme;
|
|
2190
|
-
|
|
2191
|
-
onThemeChangeCallback();
|
|
2192
|
-
}
|
|
2198
|
+
notifyThemeChange();
|
|
2193
2199
|
return { success: true };
|
|
2194
2200
|
} catch (error) {
|
|
2195
2201
|
if (requestId !== themeLoadRequestId) {
|
|
@@ -2236,9 +2242,7 @@ export function setThemeInstance(themeInstance: Theme): void {
|
|
|
2236
2242
|
theme = themeInstance;
|
|
2237
2243
|
currentThemeName = "<in-memory>";
|
|
2238
2244
|
stopThemeWatcher();
|
|
2239
|
-
|
|
2240
|
-
onThemeChangeCallback();
|
|
2241
|
-
}
|
|
2245
|
+
notifyThemeChange();
|
|
2242
2246
|
}
|
|
2243
2247
|
|
|
2244
2248
|
/**
|
|
@@ -2259,7 +2263,7 @@ export async function setSymbolPreset(preset: SymbolPreset): Promise<void> {
|
|
|
2259
2263
|
theme = await loadTheme("dark", getCurrentThemeOptions());
|
|
2260
2264
|
if (requestId !== themeLoadRequestId) return;
|
|
2261
2265
|
}
|
|
2262
|
-
|
|
2266
|
+
notifyThemeChange();
|
|
2263
2267
|
}
|
|
2264
2268
|
|
|
2265
2269
|
/**
|
|
@@ -2288,7 +2292,7 @@ export async function setColorBlindMode(enabled: boolean): Promise<void> {
|
|
|
2288
2292
|
theme = await loadTheme("dark", getCurrentThemeOptions());
|
|
2289
2293
|
if (requestId !== themeLoadRequestId) return;
|
|
2290
2294
|
}
|
|
2291
|
-
|
|
2295
|
+
notifyThemeChange();
|
|
2292
2296
|
}
|
|
2293
2297
|
|
|
2294
2298
|
/**
|
|
@@ -2302,6 +2306,23 @@ export function onThemeChange(callback: () => void): void {
|
|
|
2302
2306
|
onThemeChangeCallback = callback;
|
|
2303
2307
|
}
|
|
2304
2308
|
|
|
2309
|
+
/**
|
|
2310
|
+
* Monotonic counter bumped on any theme-affecting change that should invalidate
|
|
2311
|
+
* cached renders: theme swaps and reloads (including the invalid-theme dark
|
|
2312
|
+
* fallback), theme previews, symbol-preset changes, and color-blind-mode
|
|
2313
|
+
* changes — everything that routes through {@link notifyThemeChange}. Consumers
|
|
2314
|
+
* key cached renders on it so the next render re-shapes their output.
|
|
2315
|
+
*/
|
|
2316
|
+
export function getThemeEpoch(): number {
|
|
2317
|
+
return themeEpoch;
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
/** Bump the theme epoch and notify the registered theme-change listener. */
|
|
2321
|
+
function notifyThemeChange(): void {
|
|
2322
|
+
themeEpoch++;
|
|
2323
|
+
onThemeChangeCallback?.();
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2305
2326
|
/**
|
|
2306
2327
|
* Get available symbol presets.
|
|
2307
2328
|
*/
|
|
@@ -2354,9 +2375,7 @@ async function startThemeWatcher(): Promise<void> {
|
|
|
2354
2375
|
loadTheme(watchedThemeName, getCurrentThemeOptions())
|
|
2355
2376
|
.then(loadedTheme => {
|
|
2356
2377
|
theme = loadedTheme;
|
|
2357
|
-
|
|
2358
|
-
onThemeChangeCallback();
|
|
2359
|
-
}
|
|
2378
|
+
notifyThemeChange();
|
|
2360
2379
|
})
|
|
2361
2380
|
.catch(() => {
|
|
2362
2381
|
// Ignore errors (file might be in invalid state while being edited)
|
|
@@ -2396,9 +2415,7 @@ function reevaluateAutoTheme(debugLabel: string): void {
|
|
|
2396
2415
|
loadTheme(resolved, getCurrentThemeOptions())
|
|
2397
2416
|
.then(loadedTheme => {
|
|
2398
2417
|
theme = loadedTheme;
|
|
2399
|
-
|
|
2400
|
-
onThemeChangeCallback();
|
|
2401
|
-
}
|
|
2418
|
+
notifyThemeChange();
|
|
2402
2419
|
})
|
|
2403
2420
|
.catch(err => {
|
|
2404
2421
|
logger.debug(`Theme switch on ${debugLabel} failed`, { error: String(err) });
|
|
@@ -2520,18 +2537,74 @@ function ansi256ToHex(index: number): string {
|
|
|
2520
2537
|
return `#${grayHex}${grayHex}${grayHex}`;
|
|
2521
2538
|
}
|
|
2522
2539
|
|
|
2540
|
+
/**
|
|
2541
|
+
* Classify a parsed theme JSON as light/dark by the perceived luminance of its
|
|
2542
|
+
* status-line background. Mirrors {@link Theme.isLight} so the synchronous
|
|
2543
|
+
* helpers below stay in lockstep with the runtime classifier — see the comment
|
|
2544
|
+
* on `Theme.statusLineLuminance` for why `statusLineBg` is the source of truth
|
|
2545
|
+
* (themes like `porcelain` style a dark chat bubble on an otherwise-light
|
|
2546
|
+
* theme, so `userMessageBg` is unreliable).
|
|
2547
|
+
*/
|
|
2548
|
+
function isLightThemeJson(themeJson: ThemeJson): boolean {
|
|
2549
|
+
try {
|
|
2550
|
+
const resolved = resolveVarRefs(themeJson.colors.statusLineBg, themeJson.vars ?? {});
|
|
2551
|
+
const luminance = colorLuma(resolved);
|
|
2552
|
+
return luminance !== undefined && luminance > 0.5;
|
|
2553
|
+
} catch {
|
|
2554
|
+
return false;
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
|
|
2558
|
+
function getHtmlDefaultTextForSurface(surface: string | number | undefined): string {
|
|
2559
|
+
const luminance = surface === undefined ? undefined : colorLuma(surface);
|
|
2560
|
+
return luminance !== undefined && luminance > 0.5 ? "#000000" : "#e5e5e7";
|
|
2561
|
+
}
|
|
2562
|
+
|
|
2563
|
+
function resolveThemeExportColors(themeJson: ThemeJson): {
|
|
2564
|
+
pageBg?: string;
|
|
2565
|
+
cardBg?: string;
|
|
2566
|
+
infoBg?: string;
|
|
2567
|
+
} {
|
|
2568
|
+
const exportSection = themeJson.export;
|
|
2569
|
+
if (!exportSection) return {};
|
|
2570
|
+
|
|
2571
|
+
const vars = themeJson.vars ?? {};
|
|
2572
|
+
const resolve = (value: string | number | undefined): string | undefined => {
|
|
2573
|
+
if (value === undefined) return undefined;
|
|
2574
|
+
if (typeof value === "number") return ansi256ToHex(value);
|
|
2575
|
+
if (value === "" || value.startsWith("#")) return value;
|
|
2576
|
+
const varName = value.startsWith("$") ? value.slice(1) : value;
|
|
2577
|
+
if (varName in vars) {
|
|
2578
|
+
const resolved = resolveVarRefs(varName, vars);
|
|
2579
|
+
return typeof resolved === "number" ? ansi256ToHex(resolved) : resolved;
|
|
2580
|
+
}
|
|
2581
|
+
return value;
|
|
2582
|
+
};
|
|
2583
|
+
|
|
2584
|
+
return {
|
|
2585
|
+
pageBg: resolve(exportSection.pageBg),
|
|
2586
|
+
cardBg: resolve(exportSection.cardBg),
|
|
2587
|
+
infoBg: resolve(exportSection.infoBg),
|
|
2588
|
+
};
|
|
2589
|
+
}
|
|
2590
|
+
|
|
2523
2591
|
/**
|
|
2524
2592
|
* Get resolved theme colors as CSS-compatible hex strings.
|
|
2525
2593
|
* Used by HTML export to generate CSS custom properties.
|
|
2526
2594
|
*/
|
|
2527
2595
|
export async function getResolvedThemeColors(themeName?: string): Promise<Record<string, string>> {
|
|
2528
2596
|
const name = themeName ?? getDefaultTheme();
|
|
2529
|
-
const isLight = name === "light";
|
|
2530
2597
|
const themeJson = await loadThemeJson(name);
|
|
2598
|
+
const exportColors = resolveThemeExportColors(themeJson);
|
|
2531
2599
|
const resolved = resolveThemeColors(themeJson.colors, themeJson.vars);
|
|
2532
2600
|
|
|
2533
|
-
//
|
|
2534
|
-
|
|
2601
|
+
// Empty foreground tokens use the terminal default color. In HTML export,
|
|
2602
|
+
// that default must contrast the export surface, not the TUI status line:
|
|
2603
|
+
// custom light themes can still export dark transcript cards when they omit
|
|
2604
|
+
// `export`, because generateThemeVars derives those cards from userMessageBg.
|
|
2605
|
+
const defaultText = getHtmlDefaultTextForSurface(
|
|
2606
|
+
exportColors.cardBg ?? exportColors.pageBg ?? resolved.userMessageBg,
|
|
2607
|
+
);
|
|
2535
2608
|
|
|
2536
2609
|
const cssColors: Record<string, string> = {};
|
|
2537
2610
|
for (const [key, value] of Object.entries(resolved)) {
|
|
@@ -2548,8 +2621,9 @@ export async function getResolvedThemeColors(themeName?: string): Promise<Record
|
|
|
2548
2621
|
}
|
|
2549
2622
|
|
|
2550
2623
|
/**
|
|
2551
|
-
* Check if a theme is a "light" theme by analyzing its background
|
|
2552
|
-
* Loads theme JSON synchronously (built-in or custom file
|
|
2624
|
+
* Check if a theme is a "light" theme by analyzing its status-line background
|
|
2625
|
+
* luminance. Loads theme JSON synchronously (built-in or custom file on disk)
|
|
2626
|
+
* for callers in synchronous flows (settings migration, setup wizard).
|
|
2553
2627
|
*/
|
|
2554
2628
|
export function isLightTheme(themeName?: string): boolean {
|
|
2555
2629
|
const name = themeName ?? "dark";
|
|
@@ -2566,13 +2640,7 @@ export function isLightTheme(themeName?: string): boolean {
|
|
|
2566
2640
|
return false;
|
|
2567
2641
|
}
|
|
2568
2642
|
}
|
|
2569
|
-
|
|
2570
|
-
const resolved = resolveVarRefs(themeJson.colors.userMessageBg, themeJson.vars ?? {});
|
|
2571
|
-
const luminance = colorLuma(resolved);
|
|
2572
|
-
return luminance !== undefined && luminance > 0.5;
|
|
2573
|
-
} catch {
|
|
2574
|
-
return false;
|
|
2575
|
-
}
|
|
2643
|
+
return isLightThemeJson(themeJson);
|
|
2576
2644
|
}
|
|
2577
2645
|
|
|
2578
2646
|
/**
|
|
@@ -2587,27 +2655,7 @@ export async function getThemeExportColors(themeName?: string): Promise<{
|
|
|
2587
2655
|
const name = themeName ?? getDefaultTheme();
|
|
2588
2656
|
try {
|
|
2589
2657
|
const themeJson = await loadThemeJson(name);
|
|
2590
|
-
|
|
2591
|
-
if (!exportSection) return {};
|
|
2592
|
-
|
|
2593
|
-
const vars = themeJson.vars ?? {};
|
|
2594
|
-
const resolve = (value: string | number | undefined): string | undefined => {
|
|
2595
|
-
if (value === undefined) return undefined;
|
|
2596
|
-
if (typeof value === "number") return ansi256ToHex(value);
|
|
2597
|
-
if (value === "" || value.startsWith("#")) return value;
|
|
2598
|
-
const varName = value.startsWith("$") ? value.slice(1) : value;
|
|
2599
|
-
if (varName in vars) {
|
|
2600
|
-
const resolved = resolveVarRefs(varName, vars);
|
|
2601
|
-
return typeof resolved === "number" ? ansi256ToHex(resolved) : resolved;
|
|
2602
|
-
}
|
|
2603
|
-
return value;
|
|
2604
|
-
};
|
|
2605
|
-
|
|
2606
|
-
return {
|
|
2607
|
-
pageBg: resolve(exportSection.pageBg),
|
|
2608
|
-
cardBg: resolve(exportSection.cardBg),
|
|
2609
|
-
infoBg: resolve(exportSection.infoBg),
|
|
2610
|
-
};
|
|
2658
|
+
return resolveThemeExportColors(themeJson);
|
|
2611
2659
|
} catch {
|
|
2612
2660
|
return {};
|
|
2613
2661
|
}
|
package/src/modes/types.ts
CHANGED
|
@@ -18,7 +18,8 @@ import type { MCPManager } from "../mcp";
|
|
|
18
18
|
import type { PlanApprovalDetails } from "../plan-mode/approved-plan";
|
|
19
19
|
import type { AgentSession } from "../session/agent-session";
|
|
20
20
|
import type { HistoryStorage } from "../session/history-storage";
|
|
21
|
-
import type { SessionContext
|
|
21
|
+
import type { SessionContext } from "../session/session-context";
|
|
22
|
+
import type { SessionManager } from "../session/session-manager";
|
|
22
23
|
import type { ShakeMode } from "../session/shake-types";
|
|
23
24
|
import type { LspStartupServerInfo } from "../tools";
|
|
24
25
|
import type { EventBus } from "../utils/event-bus";
|
|
@@ -89,6 +90,7 @@ export interface InteractiveModeContext {
|
|
|
89
90
|
btwContainer: Container;
|
|
90
91
|
omfgContainer: Container;
|
|
91
92
|
errorBannerContainer: Container;
|
|
93
|
+
modelCycleContainer: Container;
|
|
92
94
|
editor: CustomEditor;
|
|
93
95
|
editorContainer: Container;
|
|
94
96
|
hookWidgetContainerAbove: Container;
|
|
@@ -196,6 +198,7 @@ export interface InteractiveModeContext {
|
|
|
196
198
|
*/
|
|
197
199
|
resetTranscript(): void;
|
|
198
200
|
showStatus(message: string, options?: { dim?: boolean }): void;
|
|
201
|
+
showModelCycleTrack(track: string): void;
|
|
199
202
|
showError(message: string): void;
|
|
200
203
|
showPinnedError(message: string): void;
|
|
201
204
|
clearPinnedError(): void;
|
|
@@ -307,7 +310,7 @@ export interface InteractiveModeContext {
|
|
|
307
310
|
showProviderSetup(): Promise<void>;
|
|
308
311
|
showHookConfirm(title: string, message: string): Promise<boolean>;
|
|
309
312
|
showDebugSelector(): Promise<void>;
|
|
310
|
-
showAgentHub(): void;
|
|
313
|
+
showAgentHub(options?: { requireContent?: boolean }): void;
|
|
311
314
|
resetObserverRegistry(): void;
|
|
312
315
|
|
|
313
316
|
// Input handling
|
|
@@ -332,6 +335,7 @@ export interface InteractiveModeContext {
|
|
|
332
335
|
registerExtensionShortcuts(): void;
|
|
333
336
|
handlePlanModeCommand(initialPrompt?: string): Promise<void>;
|
|
334
337
|
handleGoalModeCommand(rest?: string): Promise<void>;
|
|
338
|
+
handleGuidedGoalCommand(rest?: string): Promise<void>;
|
|
335
339
|
handleLoopCommand(args?: string): Promise<void>;
|
|
336
340
|
disableLoopMode(): void;
|
|
337
341
|
pauseLoop(): void;
|
|
@@ -49,7 +49,7 @@ export function buildHotkeysMarkdown(bindings: HotkeysMarkdownBindings): string
|
|
|
49
49
|
`| \`${appKey(bindings, "app.thinking.toggle")}\` | Toggle thinking block visibility |`,
|
|
50
50
|
`| \`${appKey(bindings, "app.editor.external")}\` | Edit message in external editor |`,
|
|
51
51
|
`| \`${appKey(bindings, "app.clipboard.pasteImage")}\` | Paste image or text from clipboard |`,
|
|
52
|
-
|
|
52
|
+
"| Hold `Space` | Speech-to-text (push-to-talk): hold to record, release to transcribe |",
|
|
53
53
|
`| \`${appKey(bindings, "app.agents.hub")}\` / \`${appKey(bindings, "app.session.observe")}\` / double-tap \`←\` (empty editor) | Open the agent hub |`,
|
|
54
54
|
"| `#` | Open prompt actions |",
|
|
55
55
|
"| `/` | Slash commands |",
|