@oh-my-pi/pi-coding-agent 15.10.11 → 15.11.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 +103 -2
- package/dist/cli.js +5790 -5731
- package/dist/types/async/index.d.ts +0 -1
- package/dist/types/cli/args.d.ts +1 -0
- package/dist/types/cli/gallery-fixtures/types.d.ts +5 -0
- package/dist/types/cli-commands.d.ts +12 -0
- package/dist/types/commands/launch.d.ts +4 -0
- package/dist/types/config/api-key-resolver.d.ts +3 -0
- package/dist/types/config/keybindings.d.ts +6 -1
- package/dist/types/config/model-registry.d.ts +1 -0
- package/dist/types/config/model-resolver.d.ts +18 -0
- package/dist/types/config/settings-schema.d.ts +85 -34
- package/dist/types/config/settings.d.ts +7 -0
- package/dist/types/edit/hashline/noop-loop-guard.d.ts +72 -0
- package/dist/types/eval/py/executor.d.ts +5 -0
- package/dist/types/eval/py/kernel.d.ts +6 -1
- package/dist/types/eval/py/runtime.d.ts +9 -0
- package/dist/types/exec/bash-executor.d.ts +2 -0
- package/dist/types/export/html/template.generated.d.ts +1 -1
- package/dist/types/extensibility/custom-tools/types.d.ts +2 -2
- package/dist/types/extensibility/extensions/runner.d.ts +3 -2
- package/dist/types/extensibility/extensions/types.d.ts +3 -0
- package/dist/types/extensibility/shared-events.d.ts +2 -2
- package/dist/types/internal-urls/history-protocol.d.ts +14 -0
- package/dist/types/internal-urls/index.d.ts +1 -0
- package/dist/types/internal-urls/types.d.ts +1 -1
- package/dist/types/irc/bus.d.ts +66 -0
- package/dist/types/memory-backend/index.d.ts +1 -0
- package/dist/types/memory-backend/runtime.d.ts +4 -0
- package/dist/types/memory-backend/types.d.ts +66 -1
- package/dist/types/modes/components/agent-hub.d.ts +30 -0
- package/dist/types/modes/components/compaction-summary-message.d.ts +10 -4
- package/dist/types/modes/components/custom-editor.d.ts +2 -0
- package/dist/types/modes/components/tool-execution.d.ts +8 -0
- package/dist/types/modes/components/ttsr-notification.d.ts +5 -1
- package/dist/types/modes/components/welcome.d.ts +3 -9
- package/dist/types/modes/controllers/selector-controller.d.ts +1 -1
- package/dist/types/modes/index.d.ts +3 -3
- package/dist/types/modes/interactive-mode.d.ts +10 -4
- package/dist/types/modes/oauth-manual-input.d.ts +7 -0
- package/dist/types/modes/rpc/rpc-client.d.ts +39 -2
- package/dist/types/modes/rpc/rpc-mode.d.ts +31 -2
- package/dist/types/modes/rpc/rpc-subagents.d.ts +24 -0
- package/dist/types/modes/rpc/rpc-types.d.ts +75 -1
- package/dist/types/modes/setup-wizard/index.d.ts +5 -1
- package/dist/types/modes/setup-wizard/lazy.d.ts +2 -0
- package/dist/types/modes/theme/theme.d.ts +2 -1
- package/dist/types/modes/types.d.ts +5 -2
- package/dist/types/modes/utils/ui-helpers.d.ts +1 -1
- package/dist/types/registry/agent-lifecycle.d.ts +51 -0
- package/dist/types/registry/agent-registry.d.ts +16 -5
- package/dist/types/secrets/index.d.ts +1 -1
- package/dist/types/secrets/obfuscator.d.ts +8 -2
- package/dist/types/session/agent-session.d.ts +49 -32
- package/dist/types/session/messages.d.ts +2 -4
- package/dist/types/session/session-history-format.d.ts +12 -0
- package/dist/types/session/session-manager.d.ts +21 -3
- package/dist/types/session/streaming-output.d.ts +46 -0
- package/dist/types/slash-commands/acp-builtins.d.ts +16 -0
- package/dist/types/slash-commands/builtin-registry.d.ts +1 -0
- package/dist/types/slash-commands/types.d.ts +1 -1
- package/dist/types/system-prompt.d.ts +2 -0
- package/dist/types/task/executor.d.ts +12 -2
- package/dist/types/task/index.d.ts +13 -6
- package/dist/types/task/output-manager.d.ts +0 -7
- package/dist/types/task/repair-args.d.ts +8 -7
- package/dist/types/task/types.d.ts +63 -51
- package/dist/types/thinking.d.ts +4 -0
- package/dist/types/tiny/title-client.d.ts +11 -0
- package/dist/types/tiny/title-protocol.d.ts +1 -0
- package/dist/types/tools/browser/tab-worker.d.ts +3 -1
- package/dist/types/tools/find.d.ts +0 -11
- package/dist/types/tools/grouped-file-output.d.ts +0 -49
- package/dist/types/tools/index.d.ts +7 -3
- package/dist/types/tools/irc.d.ts +76 -38
- package/dist/types/tools/job.d.ts +7 -1
- package/dist/types/utils/git.d.ts +15 -2
- package/dist/types/utils/title-generator.d.ts +3 -2
- package/examples/extensions/with-deps/package.json +1 -0
- package/package.json +11 -10
- package/scripts/bundle-dist.ts +28 -19
- package/src/async/index.ts +0 -1
- package/src/auto-thinking/classifier.ts +1 -0
- package/src/cli/args.ts +3 -0
- package/src/cli/gallery-cli.ts +1 -1
- package/src/cli/gallery-fixtures/agentic.ts +230 -115
- package/src/cli/gallery-fixtures/types.ts +5 -0
- package/src/cli-commands.ts +29 -0
- package/src/cli.ts +28 -15
- package/src/commands/launch.ts +4 -0
- package/src/commit/agentic/tools/analyze-file.ts +38 -19
- package/src/commit/model-selection.ts +3 -2
- package/src/config/api-key-resolver.ts +8 -6
- package/src/config/keybindings.ts +6 -1
- package/src/config/model-registry.ts +97 -30
- package/src/config/model-resolver.ts +60 -0
- package/src/config/settings-schema.ts +99 -55
- package/src/config/settings.ts +68 -3
- package/src/edit/hashline/execute.ts +39 -2
- package/src/edit/hashline/noop-loop-guard.ts +99 -0
- package/src/eval/__tests__/agent-bridge.test.ts +5 -3
- package/src/eval/agent-bridge.ts +3 -16
- package/src/eval/completion-bridge.ts +1 -0
- package/src/eval/js/shared/prelude.txt +1 -1
- package/src/eval/py/executor.ts +29 -7
- package/src/eval/py/index.ts +6 -1
- package/src/eval/py/kernel.ts +31 -11
- package/src/eval/py/prelude.py +5 -6
- package/src/eval/py/runtime.ts +37 -0
- package/src/exec/bash-executor.ts +82 -3
- package/src/export/html/template.generated.ts +1 -1
- package/src/export/html/template.js +38 -13
- package/src/extensibility/custom-tools/types.ts +2 -2
- package/src/extensibility/extensions/get-commands-handler.ts +2 -1
- package/src/extensibility/extensions/runner.ts +6 -1
- package/src/extensibility/extensions/types.ts +3 -0
- package/src/extensibility/shared-events.ts +2 -2
- package/src/hindsight/bank.ts +17 -2
- package/src/internal-urls/docs-index.generated.ts +11 -11
- package/src/internal-urls/history-protocol.ts +113 -0
- package/src/internal-urls/index.ts +1 -0
- package/src/internal-urls/router.ts +3 -1
- package/src/internal-urls/types.ts +1 -1
- package/src/irc/bus.ts +292 -0
- package/src/main.ts +26 -66
- package/src/memories/index.ts +2 -0
- package/src/memory-backend/index.ts +1 -0
- package/src/memory-backend/local-backend.ts +9 -0
- package/src/memory-backend/off-backend.ts +9 -0
- package/src/memory-backend/runtime.ts +66 -0
- package/src/memory-backend/types.ts +81 -1
- package/src/mnemopi/backend.ts +151 -4
- package/src/modes/acp/acp-agent.ts +119 -11
- package/src/modes/components/{session-observer-overlay.ts → agent-hub.ts} +586 -367
- package/src/modes/components/assistant-message.ts +19 -21
- package/src/modes/components/compaction-summary-message.ts +68 -32
- package/src/modes/components/custom-editor.ts +10 -0
- package/src/modes/components/footer.ts +3 -1
- package/src/modes/components/status-line/component.ts +118 -34
- package/src/modes/components/tool-execution.ts +31 -1
- package/src/modes/components/ttsr-notification.ts +72 -30
- package/src/modes/components/welcome.ts +9 -33
- package/src/modes/controllers/command-controller.ts +1 -1
- package/src/modes/controllers/event-controller.ts +65 -0
- package/src/modes/controllers/extension-ui-controller.ts +8 -8
- package/src/modes/controllers/input-controller.ts +19 -2
- package/src/modes/controllers/mcp-command-controller.ts +38 -3
- package/src/modes/controllers/selector-controller.ts +21 -17
- package/src/modes/index.ts +3 -21
- package/src/modes/interactive-mode.ts +47 -22
- package/src/modes/oauth-manual-input.ts +30 -3
- package/src/modes/rpc/rpc-client.ts +154 -3
- package/src/modes/rpc/rpc-mode.ts +97 -12
- package/src/modes/rpc/rpc-subagents.ts +265 -0
- package/src/modes/rpc/rpc-types.ts +81 -1
- package/src/modes/setup-wizard/index.ts +12 -2
- package/src/modes/setup-wizard/lazy.ts +16 -0
- package/src/modes/theme/theme.ts +18 -5
- package/src/modes/types.ts +5 -5
- package/src/modes/utils/hotkeys-markdown.ts +1 -0
- package/src/modes/utils/ui-helpers.ts +51 -49
- package/src/prompts/system/irc-incoming.md +3 -4
- package/src/prompts/system/orchestrate-notice.md +2 -2
- package/src/prompts/system/subagent-system-prompt.md +0 -5
- package/src/prompts/system/system-prompt.md +1 -0
- package/src/prompts/system/workflow-notice.md +2 -2
- package/src/prompts/tools/eval.md +3 -3
- package/src/prompts/tools/irc.md +29 -19
- package/src/prompts/tools/read.md +2 -2
- package/src/prompts/tools/task-summary.md +5 -16
- package/src/prompts/tools/task.md +38 -29
- package/src/registry/agent-lifecycle.ts +218 -0
- package/src/registry/agent-registry.ts +16 -5
- package/src/sdk.ts +37 -10
- package/src/secrets/index.ts +8 -1
- package/src/secrets/obfuscator.ts +39 -18
- package/src/session/agent-session.ts +422 -291
- package/src/session/messages.ts +11 -78
- package/src/session/session-history-format.ts +246 -0
- package/src/session/session-manager.ts +59 -5
- package/src/session/streaming-output.ts +226 -10
- package/src/slash-commands/acp-builtins.ts +24 -0
- package/src/slash-commands/builtin-registry.ts +20 -0
- package/src/slash-commands/types.ts +1 -1
- package/src/system-prompt.ts +14 -0
- package/src/task/executor.ts +851 -461
- package/src/task/index.ts +721 -796
- package/src/task/output-manager.ts +0 -11
- package/src/task/render.ts +148 -63
- package/src/task/repair-args.ts +21 -9
- package/src/task/types.ts +82 -66
- package/src/thinking.ts +7 -0
- package/src/tiny/title-client.ts +34 -5
- package/src/tiny/title-protocol.ts +1 -1
- package/src/tiny/worker.ts +6 -4
- package/src/tools/ask.ts +4 -2
- package/src/tools/bash.ts +61 -10
- package/src/tools/browser/tab-worker.ts +26 -7
- package/src/tools/browser.ts +28 -1
- package/src/tools/find.ts +2 -27
- package/src/tools/grouped-file-output.ts +1 -118
- package/src/tools/image-gen.ts +11 -4
- package/src/tools/index.ts +17 -13
- package/src/tools/inspect-image.ts +1 -0
- package/src/tools/irc.ts +596 -171
- package/src/tools/job.ts +41 -7
- package/src/tools/read.ts +57 -1
- package/src/tools/renderers.ts +2 -0
- package/src/tools/resolve.ts +4 -1
- package/src/utils/commit-message-generator.ts +1 -0
- package/src/utils/git.ts +267 -13
- package/src/utils/title-generator.ts +24 -5
- package/dist/types/async/support.d.ts +0 -2
- package/dist/types/modes/components/session-observer-overlay.d.ts +0 -11
- package/dist/types/task/simple-mode.d.ts +0 -8
- package/src/async/support.ts +0 -5
- package/src/task/simple-mode.ts +0 -27
|
@@ -1023,18 +1023,18 @@
|
|
|
1023
1023
|
}
|
|
1024
1024
|
|
|
1025
1025
|
function renderTask(name, args, result, ctx) {
|
|
1026
|
-
const
|
|
1027
|
-
|
|
1028
|
-
|
|
1026
|
+
const badges = [];
|
|
1027
|
+
if (args.resume) badges.push('resume=' + str(args.resume));
|
|
1028
|
+
else badges.push('agent=' + (str(args.agent) || '?'));
|
|
1029
|
+
if (args.id) badges.push('id=' + str(args.id));
|
|
1029
1030
|
if (args.isolated) badges.push('isolated');
|
|
1030
1031
|
let html = toolHead('task', '', badges);
|
|
1031
|
-
|
|
1032
|
+
const description = str(args.description);
|
|
1033
|
+
const assignment = str(args.assignment);
|
|
1034
|
+
if (description || assignment) {
|
|
1032
1035
|
html += '<div class="tool-args">';
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
const desc = t?.description ? escapeHtml(String(t.description)) : '';
|
|
1036
|
-
html += '<div class="tool-arg"><span class="tool-arg-key">' + id + '</span> ' + desc + '</div>';
|
|
1037
|
-
}
|
|
1036
|
+
if (description) html += '<div class="tool-arg"><span class="tool-arg-key">' + escapeHtml(description) + '</span></div>';
|
|
1037
|
+
if (assignment) html += '<div class="tool-arg">' + escapeHtml(assignment) + '</div>';
|
|
1038
1038
|
html += '</div>';
|
|
1039
1039
|
}
|
|
1040
1040
|
if (result) {
|
|
@@ -1479,13 +1479,38 @@
|
|
|
1479
1479
|
}
|
|
1480
1480
|
|
|
1481
1481
|
function renderIrc(name, args, result, ctx) {
|
|
1482
|
-
const
|
|
1482
|
+
const details = result && result.details ? result.details : null;
|
|
1483
|
+
const op = str(args.op) || (details && str(details.op)) || '?';
|
|
1483
1484
|
const badges = [op];
|
|
1484
|
-
if (args.to) badges.push('to=' + args.to);
|
|
1485
|
-
if (
|
|
1485
|
+
if (args.to) badges.push('to=' + str(args.to));
|
|
1486
|
+
if (op === 'wait' && args.from) badges.push('from=' + str(args.from));
|
|
1487
|
+
if (args.await) badges.push('await');
|
|
1488
|
+
if (args.peek) badges.push('peek');
|
|
1486
1489
|
let html = toolHead('irc', '', badges);
|
|
1487
1490
|
if (args.message) html += '<div class="tool-output"><div>' + escapeHtml(String(args.message)) + '</div></div>';
|
|
1488
|
-
|
|
1491
|
+
let renderedDetails = false;
|
|
1492
|
+
if (details && Array.isArray(details.receipts) && details.receipts.length) {
|
|
1493
|
+
html += '<div class="tool-args">';
|
|
1494
|
+
for (const receipt of details.receipts) {
|
|
1495
|
+
const outcome = escapeHtml(String(receipt.outcome)) + (receipt.error ? ' — ' + escapeHtml(String(receipt.error)) : '');
|
|
1496
|
+
html += '<div class="tool-arg"><span class="tool-arg-key">' + escapeHtml(String(receipt.to)) + '</span> ' + outcome + '</div>';
|
|
1497
|
+
}
|
|
1498
|
+
html += '</div>';
|
|
1499
|
+
renderedDetails = true;
|
|
1500
|
+
}
|
|
1501
|
+
if (details && details.waited) {
|
|
1502
|
+
html += '<div class="tool-output"><div>' + escapeHtml(String(details.waited.from)) + ': ' + escapeHtml(String(details.waited.body)) + '</div></div>';
|
|
1503
|
+
renderedDetails = true;
|
|
1504
|
+
}
|
|
1505
|
+
if (details && Array.isArray(details.inbox) && details.inbox.length) {
|
|
1506
|
+
html += '<div class="tool-args">';
|
|
1507
|
+
for (const msg of details.inbox) {
|
|
1508
|
+
html += '<div class="tool-arg"><span class="tool-arg-key">' + escapeHtml(String(msg.from)) + '</span> ' + escapeHtml(String(msg.body)) + '</div>';
|
|
1509
|
+
}
|
|
1510
|
+
html += '</div>';
|
|
1511
|
+
renderedDetails = true;
|
|
1512
|
+
}
|
|
1513
|
+
if (!renderedDetails && result) {
|
|
1489
1514
|
const output = ctx.getResultText();
|
|
1490
1515
|
if (output) html += formatExpandableOutput(output, 8);
|
|
1491
1516
|
}
|
|
@@ -103,11 +103,11 @@ export type CustomToolSessionEvent =
|
|
|
103
103
|
| {
|
|
104
104
|
reason: "auto_compaction_start";
|
|
105
105
|
trigger: "threshold" | "overflow" | "idle" | "incomplete";
|
|
106
|
-
action: "context-full" | "handoff" | "shake";
|
|
106
|
+
action: "context-full" | "handoff" | "shake" | "snapcompact";
|
|
107
107
|
}
|
|
108
108
|
| {
|
|
109
109
|
reason: "auto_compaction_end";
|
|
110
|
-
action: "context-full" | "handoff" | "shake";
|
|
110
|
+
action: "context-full" | "handoff" | "shake" | "snapcompact";
|
|
111
111
|
result: CompactionResult | undefined;
|
|
112
112
|
aborted: boolean;
|
|
113
113
|
willRetry: boolean;
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* themselves. Each frontend (interactive-mode, ACP) prepends its own builtins.
|
|
16
16
|
*/
|
|
17
17
|
import type { SkillsSettings } from "../../config/settings";
|
|
18
|
+
import { BUILTIN_SLASH_COMMAND_RESERVED_NAMES } from "../../slash-commands/builtin-registry";
|
|
18
19
|
import type { CustomCommandSource, LoadedCustomCommand } from "../custom-commands";
|
|
19
20
|
import { getSkillSlashCommandName, type Skill } from "../skills";
|
|
20
21
|
import type { SlashCommandInfo, SlashCommandLocation } from "../slash-commands";
|
|
@@ -32,7 +33,7 @@ export function getSessionSlashCommands(session: CommandsCapableSession): SlashC
|
|
|
32
33
|
|
|
33
34
|
const runner = session.extensionRunner;
|
|
34
35
|
if (runner) {
|
|
35
|
-
for (const cmd of runner.getRegisteredCommands()) {
|
|
36
|
+
for (const cmd of runner.getRegisteredCommands(BUILTIN_SLASH_COMMAND_RESERVED_NAMES)) {
|
|
36
37
|
out.push({
|
|
37
38
|
name: cmd.name,
|
|
38
39
|
description: cmd.description,
|
|
@@ -6,6 +6,7 @@ import type { CredentialDisabledEvent, ImageContent, Model, ProviderResponseMeta
|
|
|
6
6
|
import type { KeyId } from "@oh-my-pi/pi-tui";
|
|
7
7
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
8
8
|
import type { ModelRegistry } from "../../config/model-registry";
|
|
9
|
+
import type { MemoryRuntimeContext } from "../../memory-backend";
|
|
9
10
|
import { type Theme, theme } from "../../modes/theme/theme";
|
|
10
11
|
import type { SessionManager } from "../../session/session-manager";
|
|
11
12
|
import type {
|
|
@@ -187,6 +188,7 @@ export class ExtensionRunner {
|
|
|
187
188
|
#switchSessionHandler: SwitchSessionHandler = async () => ({ cancelled: false });
|
|
188
189
|
#reloadHandler: () => Promise<void> = async () => {};
|
|
189
190
|
#shutdownHandler: ShutdownHandler = () => {};
|
|
191
|
+
#getMemoryFn?: () => MemoryRuntimeContext | undefined;
|
|
190
192
|
#commandDiagnostics: Array<{ type: string; message: string; path: string }> = [];
|
|
191
193
|
#initialized = false;
|
|
192
194
|
/**
|
|
@@ -204,8 +206,10 @@ export class ExtensionRunner {
|
|
|
204
206
|
private readonly cwd: string,
|
|
205
207
|
private readonly sessionManager: SessionManager,
|
|
206
208
|
private readonly modelRegistry: ModelRegistry,
|
|
209
|
+
getMemory?: () => MemoryRuntimeContext | undefined,
|
|
207
210
|
) {
|
|
208
211
|
this.#uiContext = noOpUIContext;
|
|
212
|
+
this.#getMemoryFn = getMemory;
|
|
209
213
|
}
|
|
210
214
|
|
|
211
215
|
initialize(
|
|
@@ -427,7 +431,7 @@ export class ExtensionRunner {
|
|
|
427
431
|
return this.extensions.flatMap(ext => ext.assistantThinkingRenderers);
|
|
428
432
|
}
|
|
429
433
|
|
|
430
|
-
getRegisteredCommands(reserved?:
|
|
434
|
+
getRegisteredCommands(reserved?: ReadonlySet<string>): RegisteredCommand[] {
|
|
431
435
|
this.#commandDiagnostics = [];
|
|
432
436
|
|
|
433
437
|
const commands = new Map<string, RegisteredCommand>();
|
|
@@ -480,6 +484,7 @@ export class ExtensionRunner {
|
|
|
480
484
|
hasPendingMessages: () => this.#hasPendingMessagesFn(),
|
|
481
485
|
shutdown: () => this.#shutdownHandler(),
|
|
482
486
|
getSystemPrompt: () => this.#getSystemPromptFn(),
|
|
487
|
+
memory: this.#getMemoryFn?.(),
|
|
483
488
|
};
|
|
484
489
|
}
|
|
485
490
|
|
|
@@ -40,6 +40,7 @@ import type { EditToolDetails } from "../../edit";
|
|
|
40
40
|
import type { PythonResult } from "../../eval/py/executor";
|
|
41
41
|
import type { BashResult } from "../../exec/bash-executor";
|
|
42
42
|
import type { ExecOptions, ExecResult } from "../../exec/exec";
|
|
43
|
+
import type { MemoryRuntimeContext } from "../../memory-backend";
|
|
43
44
|
import type { CustomEditor } from "../../modes/components/custom-editor";
|
|
44
45
|
import type { Theme } from "../../modes/theme/theme";
|
|
45
46
|
import type { CustomMessage } from "../../session/messages";
|
|
@@ -319,6 +320,8 @@ export interface ExtensionContext {
|
|
|
319
320
|
shutdown(): void;
|
|
320
321
|
/** Get the current effective system prompt. */
|
|
321
322
|
getSystemPrompt(): string[];
|
|
323
|
+
/** Structured memory runtime for status/search/save across the configured backend. */
|
|
324
|
+
memory?: MemoryRuntimeContext;
|
|
322
325
|
}
|
|
323
326
|
|
|
324
327
|
/**
|
|
@@ -204,13 +204,13 @@ export interface TurnEndEvent {
|
|
|
204
204
|
export interface AutoCompactionStartEvent {
|
|
205
205
|
type: "auto_compaction_start";
|
|
206
206
|
reason: "threshold" | "overflow" | "idle" | "incomplete";
|
|
207
|
-
action: "context-full" | "handoff" | "shake";
|
|
207
|
+
action: "context-full" | "handoff" | "shake" | "snapcompact";
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
/** Fired when auto-compaction ends */
|
|
211
211
|
export interface AutoCompactionEndEvent {
|
|
212
212
|
type: "auto_compaction_end";
|
|
213
|
-
action: "context-full" | "handoff" | "shake";
|
|
213
|
+
action: "context-full" | "handoff" | "shake" | "snapcompact";
|
|
214
214
|
result: CompactionResult | undefined;
|
|
215
215
|
aborted: boolean;
|
|
216
216
|
willRetry: boolean;
|
package/src/hindsight/bank.ts
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
import * as path from "node:path";
|
|
24
24
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
25
|
+
import * as git from "../utils/git";
|
|
25
26
|
import type { HindsightApi } from "./client";
|
|
26
27
|
import type { HindsightConfig } from "./config";
|
|
27
28
|
|
|
@@ -53,10 +54,24 @@ function baseBankId(config: HindsightConfig): string {
|
|
|
53
54
|
return prefix ? `${prefix}-${base}` : base;
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* Best-effort project label from a working-directory path.
|
|
59
|
+
*
|
|
60
|
+
* When `directory` lives inside a git repository we resolve the primary
|
|
61
|
+
* checkout root (or the shared common dir for bare-repo worktrees) via
|
|
62
|
+
* {@link git.repo.primaryRootSync} and basename that, so every linked
|
|
63
|
+
* worktree of one repo shares the same `project:<name>` tag.
|
|
64
|
+
* Outside a repo (or when resolution fails), fall back to the cwd basename.
|
|
65
|
+
*
|
|
66
|
+
* Sync only: this runs on the hot path of `computeBankScope`, which is
|
|
67
|
+
* exposed as a sync API to callers like `backend.ts` and must stay sync.
|
|
68
|
+
* `git.repo.primaryRootSync` walks `.git`/`commondir` with sync file reads —
|
|
69
|
+
* no subprocess — so the cost is one or two `stat`s and a small `readFile`.
|
|
70
|
+
*/
|
|
57
71
|
function projectLabel(directory: string): string {
|
|
58
72
|
if (!directory) return UNKNOWN_PROJECT;
|
|
59
|
-
|
|
73
|
+
const primary = git.repo.primaryRootSync(directory);
|
|
74
|
+
return path.basename(primary ?? directory) || UNKNOWN_PROJECT;
|
|
60
75
|
}
|
|
61
76
|
|
|
62
77
|
/**
|