@timurproko/a1 0.2.6-dev.717 → 0.2.6-dev.734
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/bin/cli.js +13 -2
- package/bin/ui.js +13 -0
- package/dist/app/session-shell/clipboard-services.d.ts +19 -0
- package/dist/app/session-shell/clipboard-services.js +7 -0
- package/dist/app/session-shell/exit-notice.d.ts +9 -5
- package/dist/app/session-shell/exit-notice.js +5 -5
- package/dist/app/session-shell/index.d.ts +3 -1
- package/dist/app/session-shell/index.js +1 -0
- package/dist/app/session-shell/paste-preparation-client.d.ts +3 -0
- package/dist/app/session-shell/paste-preparation-client.js +5 -2
- package/dist/app/session-shell/path-chip-presentation.d.ts +10 -3
- package/dist/app/session-shell/path-chip-presentation.js +48 -6
- package/dist/app/session-shell/prompt-chips.js +30 -4
- package/dist/app/session-shell/prompt-suggestion-controller.d.ts +5 -4
- package/dist/app/session-shell/prompt-suggestion-controller.js +148 -58
- package/dist/app/session-shell/quit-outro.d.ts +3 -1
- package/dist/app/session-shell/quit-outro.js +23 -8
- package/dist/app/session-shell/response-copy-transport.d.ts +6 -1
- package/dist/app/session-shell/response-copy-transport.js +8 -2
- package/dist/app/session-shell/session-shell-root.d.ts +22 -11
- package/dist/app/session-shell/session-shell-root.js +19 -12
- package/dist/app/session-shell/session-shell.d.ts +19 -21
- package/dist/app/session-shell/session-shell.js +678 -840
- package/dist/app/session-shell/session-viewport-controller.js +33 -21
- package/dist/cli/dispatch.js +5 -3
- package/dist/cli/session-context.d.ts +5 -1
- package/dist/cli/session-context.js +25 -8
- package/dist/composition/owned-ui.d.ts +23 -2
- package/dist/composition/owned-ui.js +124 -33
- package/dist/composition/session-info-reference.d.ts +2 -2
- package/dist/composition/session-info-reference.js +2 -2
- package/dist/composition/settings-route-host.js +2 -1
- package/dist/contracts/agent-engine/capability-ports.d.ts +1 -85
- package/dist/contracts/agent-engine/capability-ports.js +1 -35
- package/dist/contracts/agent-engine/index.d.ts +1 -7
- package/dist/contracts/agent-engine/index.js +0 -4
- package/dist/contracts/owned-ui/index.d.ts +9 -3
- package/dist/contracts/owned-ui/index.js +2 -1
- package/dist/contracts/owned-ui/model.d.ts +10 -0
- package/dist/contracts/owned-ui/session-backend.d.ts +119 -0
- package/dist/contracts/owned-ui/session-presenters.d.ts +55 -0
- package/dist/contracts/owned-ui/session-presenters.js +1 -0
- package/dist/contracts/owned-ui/session-workflows.d.ts +342 -0
- package/dist/contracts/owned-ui/session-workflows.js +30 -0
- package/dist/contracts/owned-ui/suggestion-diagnostics.d.ts +5 -1
- package/dist/contracts/owned-ui/suggestion-diagnostics.js +3 -1
- package/dist/contracts/owned-ui/validation.js +7 -0
- package/dist/features/launch/index.d.ts +1 -1
- package/dist/features/launch/session-context.d.ts +17 -2
- package/dist/features/launch/session-context.js +9 -5
- package/dist/features/owned-ui/settings-app.js +56 -54
- package/dist/features/prompt-suggestions/diagnostics.js +4 -1
- package/dist/foundation/lifecycle/index.d.ts +2 -2
- package/dist/foundation/lifecycle/index.js +1 -1
- package/dist/foundation/lifecycle/session-repository-context.d.ts +19 -2
- package/dist/foundation/lifecycle/session-repository-context.js +434 -66
- package/dist/foundation/process-containment/index.d.ts +1 -0
- package/dist/foundation/process-containment/index.js +1 -0
- package/dist/foundation/process-containment/native-process-inspector.d.ts +3 -0
- package/dist/foundation/process-containment/native-process-inspector.js +21 -0
- package/dist/foundation/release/bootstrap.js +1 -2
- package/dist/foundation/release/progress-palette.generated.d.ts +2 -2
- package/dist/foundation/release/progress-palette.generated.js +2 -2
- package/dist/foundation/release/release-gc.js +1 -1
- package/dist/foundation/release/update.js +0 -4
- package/dist/foundation/startup/startup-descriptor.js +2 -2
- package/dist/foundation/storage/control-store.js +0 -12
- package/dist/integrations/pi/components/components.js +2 -18
- package/dist/integrations/pi/components/index.d.ts +4 -4
- package/dist/integrations/pi/components/index.js +2 -2
- package/dist/integrations/pi/components/modal-frame.js +3 -4
- package/dist/integrations/pi/components/models-dialog.js +6 -35
- package/dist/integrations/pi/components/prompt-input-port.d.ts +1 -0
- package/dist/integrations/pi/components/resources/builtin-themes.d.ts +2 -2
- package/dist/integrations/pi/components/resources/builtin-themes.js +2 -2
- package/dist/integrations/pi/components/share-operation-dialog.js +3 -3
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +19 -16
- package/dist/integrations/pi/components/shell-extension-ui.d.ts +5 -3
- package/dist/integrations/pi/components/shell-extension-ui.js +26 -12
- package/dist/integrations/pi/components/shell-hotkey-sections.js +2 -2
- package/dist/integrations/pi/components/shell-presenters-info.js +10 -10
- package/dist/integrations/pi/components/shell-presenters-transcript.js +13 -13
- package/dist/integrations/pi/components/shell-selectors-dialogs.js +5 -6
- package/dist/integrations/pi/components/shell-shared-facade.d.ts +21 -1
- package/dist/integrations/pi/components/shell-shared-facade.js +19 -3
- package/dist/integrations/pi/components/skills-dialog.js +3 -3
- package/dist/integrations/pi/components/submitted-prompt-adapter.js +2 -3
- package/dist/integrations/pi/components/theme.d.ts +9 -0
- package/dist/integrations/pi/components/theme.js +30 -0
- package/dist/integrations/pi/components/tool-result-adapter.js +6 -1
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +1 -1
- package/dist/integrations/pi/components/upstream/assets/earendil-image.json +2 -2
- package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-editor.js +6 -6
- package/dist/integrations/pi/components/upstream/components/extension-input.js +4 -4
- package/dist/integrations/pi/components/upstream/components/extension-selector.js +4 -4
- package/dist/integrations/pi/components/upstream/components/mermaid.js +1 -1
- package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +5 -5
- package/dist/integrations/pi/components/upstream/components/owned-editor.js +8 -5
- package/dist/integrations/pi/components/upstream/components/pi-logo.js +1 -1
- package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/scoped-models-selector.js +3 -3
- package/dist/integrations/pi/components/upstream/components/session-footer.js +1 -1
- package/dist/integrations/pi/components/upstream/components/session-selector-search.js +1 -1
- package/dist/integrations/pi/components/upstream/components/session-selector.js +9 -9
- package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +3 -2
- package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +6 -3
- package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/status-indicator.js +1 -1
- package/dist/integrations/pi/components/upstream/components/themed-text.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/themed-text.js +1 -1
- package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/thinking-selector.js +2 -2
- package/dist/integrations/pi/components/upstream/components/tool-execution.d.ts +4 -0
- package/dist/integrations/pi/components/upstream/components/tool-execution.js +11 -1
- package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +2 -2
- package/dist/integrations/pi/components/upstream/components/tree-selector.js +27 -18
- package/dist/integrations/pi/components/upstream/components/trust-selector.js +1 -1
- package/dist/integrations/pi/components/upstream/external-editor.js +1 -1
- package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +4 -4
- package/dist/integrations/pi/components/upstream/history/editor-core.js +11 -7
- package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/kill-ring.js +1 -1
- package/dist/integrations/pi/components/upstream/history/printable-key.js +1 -1
- package/dist/integrations/pi/components/upstream/history/text-helpers.js +1 -1
- package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/undo-stack.js +1 -1
- package/dist/integrations/pi/components/upstream/history/word-navigation.js +1 -1
- package/dist/integrations/pi/components/upstream/model-search.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/program-status-reporter.d.ts +31 -0
- package/dist/integrations/pi/components/upstream/program-status-reporter.js +89 -0
- package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/theme/theme.d.ts +22 -1
- package/dist/integrations/pi/components/upstream/theme/theme.js +225 -10
- package/dist/integrations/pi/engine/adapter.d.ts +44 -24
- package/dist/integrations/pi/engine/adapter.js +130 -22
- package/dist/integrations/pi/engine/command-dispatch.d.ts +2 -5
- package/dist/integrations/pi/engine/extension-ui-binding.d.ts +2 -11
- package/dist/integrations/pi/engine/host-ports.d.ts +20 -0
- package/dist/integrations/pi/engine/host-ports.js +13 -0
- package/dist/integrations/pi/engine/host.d.ts +70 -0
- package/dist/integrations/pi/engine/host.js +147 -0
- package/dist/integrations/pi/engine/index.d.ts +8 -4
- package/dist/integrations/pi/engine/index.js +3 -1
- package/dist/integrations/pi/engine/pi-settings-metadata.json +1 -1
- package/dist/integrations/pi/engine/resource-catalog.d.ts +4 -23
- package/dist/integrations/pi/engine/resources/changelog.json +4 -4
- package/dist/integrations/pi/engine/runtime-integration.d.ts +8 -2
- package/dist/integrations/pi/engine/runtime-integration.js +12 -7
- package/dist/integrations/pi/engine/session-events.js +10 -2
- package/dist/integrations/pi/engine/session-integration.d.ts +3 -8
- package/dist/integrations/pi/engine/session-integration.js +0 -49
- package/dist/integrations/pi/engine/session-runtime.d.ts +18 -3
- package/dist/integrations/pi/engine/session-runtime.js +18 -7
- package/dist/integrations/pi/engine/settings-bridge.d.ts +2 -2
- package/dist/integrations/pi/engine/settings-bridge.js +0 -2
- package/dist/integrations/pi/engine/settings-port.d.ts +2 -0
- package/dist/integrations/pi/engine/settings-port.js +3 -5
- package/dist/integrations/pi/engine/transcript-projection.js +2 -1
- package/dist/integrations/pi/engine/workflows.d.ts +33 -260
- package/dist/integrations/pi/engine/workflows.js +6 -28
- package/dist/integrations/pi/session-presenters/index.d.ts +2 -0
- package/dist/integrations/pi/session-presenters/index.js +1 -0
- package/dist/integrations/pi/session-presenters/presenters.d.ts +16 -0
- package/dist/integrations/pi/session-presenters/presenters.js +341 -0
- package/dist/integrations/pi/startup-public.js +306 -290
- package/dist/integrations/pi/startup-public.manifest.json +289 -265
- package/dist/integrations/pi/tui-runtime/adapter.d.ts +2 -1
- package/dist/integrations/pi/tui-runtime/adapter.js +7 -2
- package/dist/integrations/pi/tui-runtime/contracts.d.ts +3 -1
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +8 -1
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +67 -2
- package/dist/integrations/pi/tui-runtime/index.d.ts +1 -1
- package/dist/integrations/pi/tui-runtime/index.js +1 -1
- package/dist/native/darwin-arm64/manifest.json +1 -1
- package/dist/native/linux-x64/manifest.json +1 -1
- package/dist/native/win32-x64/manifest.json +2 -2
- package/dist/native/win32-x64/process-guardian.exe +0 -0
- package/dist/product-identity.d.ts +2 -2
- package/dist/product-identity.js +2 -2
- package/dist/product-identity.json +3 -1
- package/dist/runtime-payload-inventory.json +3092 -2878
- package/dist/ui/components/prompt-input.d.ts +2 -0
- package/dist/ui/components/prompt-input.js +5 -1
- package/dist/ui/components/text-selection.d.ts +1 -1
- package/dist/ui/components/text-selection.js +3 -1
- package/dist/ui/components/theme.d.ts +2 -0
- package/dist/ui/components/transcript-viewport.d.ts +6 -4
- package/dist/ui/components/transcript-viewport.js +94 -16
- package/dist/ui/components/value-menu.d.ts +2 -0
- package/dist/ui/components/value-menu.js +13 -8
- package/dist/ui/settings/declarations.d.ts +38 -14
- package/dist/ui/settings/declarations.js +35 -11
- package/dist/ui/settings/migrations.js +23 -0
- package/docs/architecture/boundaries.md +9 -1
- package/docs/architecture/project-structure.md +7 -5
- package/docs/architecture/prompt-suggestions.md +14 -10
- package/docs/local-worktree-cleanup.md +11 -5
- package/docs/openspec-archive-automation.md +6 -5
- package/package.json +3 -3
- package/dist/contracts/agent-engine/model.d.ts +0 -78
- package/dist/contracts/agent-engine/model.js +0 -1
- package/dist/contracts/agent-engine/ports.d.ts +0 -18
- package/dist/contracts/agent-engine/serialization.d.ts +0 -7
- package/dist/contracts/agent-engine/serialization.js +0 -58
- package/dist/contracts/agent-engine/validation.d.ts +0 -5
- package/dist/contracts/agent-engine/validation.js +0 -128
- package/dist/integrations/pi/components/upstream/theme/system-theme.d.ts +0 -61
- package/dist/integrations/pi/components/upstream/theme/system-theme.js +0 -709
- /package/dist/contracts/{agent-engine/ports.js → owned-ui/session-backend.js} +0 -0
package/bin/cli.js
CHANGED
|
@@ -55,8 +55,19 @@ process.exitCode = await dispatchCli(process.argv.slice(2), {
|
|
|
55
55
|
return await runPackageCommand(request, { createPort: createPiPackagesPort });
|
|
56
56
|
},
|
|
57
57
|
sessionContext: async request => {
|
|
58
|
-
const { runSessionContextCommand } = await
|
|
59
|
-
|
|
58
|
+
const [{ runSessionContextCommand }, { createNativeProcessInspector }, { readLaunchContext }] = await Promise.all([
|
|
59
|
+
import("../dist/cli/session-context.js"),
|
|
60
|
+
import("../dist/foundation/process-containment/native-process-inspector.js"),
|
|
61
|
+
import("../dist/foundation/launch-context/index.js"),
|
|
62
|
+
]);
|
|
63
|
+
const launch = readLaunchContext(process.env);
|
|
64
|
+
let inspector;
|
|
65
|
+
return await runSessionContextCommand(request, {
|
|
66
|
+
inspectProcess: async pid => {
|
|
67
|
+
inspector ??= createNativeProcessInspector(process.env, process.platform, launch.releaseRoot);
|
|
68
|
+
return (await inspector).observe(pid);
|
|
69
|
+
},
|
|
70
|
+
});
|
|
60
71
|
},
|
|
61
72
|
}, {
|
|
62
73
|
stdout: message => process.stdout.write(message),
|
package/bin/ui.js
CHANGED
|
@@ -9,6 +9,13 @@ const { readLaunchContext } = await import("../dist/foundation/launch-context/in
|
|
|
9
9
|
const launchContext = readLaunchContext(process.env, "profile");
|
|
10
10
|
const profile = launchContext.launchProfile;
|
|
11
11
|
if (profile === undefined) throw new Error("A1 launch profile is missing");
|
|
12
|
+
if (profile === "a1") {
|
|
13
|
+
const [{ randomUUID }, { PRODUCT_IDENTITY }] = await Promise.all([
|
|
14
|
+
import("node:crypto"),
|
|
15
|
+
import("../dist/product-identity.js"),
|
|
16
|
+
]);
|
|
17
|
+
process.env[PRODUCT_IDENTITY.environment.sessionRuntimeId] = randomUUID();
|
|
18
|
+
}
|
|
12
19
|
const { installFatalExit } = await import("../dist/foundation/terminal-cleanup/fatal-exit.js");
|
|
13
20
|
const { resolveProductPaths } = await import("../dist/foundation/lifecycle/paths.js");
|
|
14
21
|
const { join } = await import("node:path");
|
|
@@ -49,10 +56,16 @@ Promise.resolve().then(() => {
|
|
|
49
56
|
if (sessionSelection && profile !== "a1") throw new Error("session selection requires the normal A1 profile");
|
|
50
57
|
return runSelectedInteractiveRuntime(profile, {
|
|
51
58
|
ownedUi: async (profileId, ownedSurfaces) => {
|
|
59
|
+
const processInspector = ownedSurfaces
|
|
60
|
+
? await import("../dist/foundation/process-containment/native-process-inspector.js")
|
|
61
|
+
.then(module => module.createNativeProcessInspector(process.env, process.platform, launchContext.releaseRoot))
|
|
62
|
+
.catch(() => null)
|
|
63
|
+
: null;
|
|
52
64
|
const { application, settings } = await composeOwnedUi({
|
|
53
65
|
cwd: process.cwd(),
|
|
54
66
|
profileId,
|
|
55
67
|
ownedSurfaces,
|
|
68
|
+
...(processInspector === null ? {} : { inspectProcess: pid => processInspector.observe(pid) }),
|
|
56
69
|
projectTrustPrompt: createConsoleProjectTrustPrompt({ presentation: profile === "a1" ? "bare" : "comparison" }),
|
|
57
70
|
sessionForkPrompt: createConsoleSessionForkPrompt(),
|
|
58
71
|
...(sessionSelection === undefined ? {} : { sessionSelection }),
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { HelperPool } from "./helper-pool.js";
|
|
2
|
+
/**
|
|
3
|
+
* Process-wide clipboard helper spares. Composition creates one and every session shell borrows it, so N
|
|
4
|
+
* sessions keep at most one spare paste helper and one spare copy helper instead of 2N. Shells warm the
|
|
5
|
+
* pools after their first frame; only the creator disposes them.
|
|
6
|
+
*/
|
|
7
|
+
export interface OwnedUiClipboardServices {
|
|
8
|
+
readonly paste: HelperPool;
|
|
9
|
+
readonly copy: HelperPool;
|
|
10
|
+
dispose(): void;
|
|
11
|
+
}
|
|
12
|
+
export interface OwnedUiClipboardServicesOptions {
|
|
13
|
+
/** Package/fault-test seams for the forked helpers' entries. */
|
|
14
|
+
readonly pasteHelper?: URL;
|
|
15
|
+
readonly copyHelper?: URL;
|
|
16
|
+
/** Idle bound for both spares; production keeps the default. */
|
|
17
|
+
readonly spareIdleMs?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare function createOwnedUiClipboardServices(options?: OwnedUiClipboardServicesOptions): OwnedUiClipboardServices;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createPasteHelperPool } from "./paste-executor.js";
|
|
2
|
+
import { createCopyHelperPool } from "./response-copy-transport.js";
|
|
3
|
+
export function createOwnedUiClipboardServices(options = {}) {
|
|
4
|
+
const paste = createPasteHelperPool(options.pasteHelper, options.spareIdleMs);
|
|
5
|
+
const copy = createCopyHelperPool(options.copyHelper, options.spareIdleMs);
|
|
6
|
+
return { paste, copy, dispose: () => { paste.dispose(); copy.dispose(); } };
|
|
7
|
+
}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { type SessionResumeCommandMetadata } from "./session-shell.js";
|
|
2
2
|
export interface ExitNoticeSource {
|
|
3
|
-
readonly
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
readonly identity: {
|
|
4
|
+
readonly sessionGeneration: number;
|
|
5
|
+
currentSessionResumeMetadata(): SessionResumeCommandMetadata | null;
|
|
6
|
+
};
|
|
7
|
+
readonly session: {
|
|
8
|
+
onEvent(listener: (event: {
|
|
9
|
+
readonly type: string;
|
|
10
|
+
}) => void): () => void;
|
|
11
|
+
};
|
|
8
12
|
}
|
|
9
13
|
export interface ArmedExitNotice {
|
|
10
14
|
clear(): void;
|
|
@@ -17,12 +17,12 @@ export function uncleanExitNoticeLines(resume) {
|
|
|
17
17
|
export function armExitNotice(source, path) {
|
|
18
18
|
let current = null;
|
|
19
19
|
let cleared = false;
|
|
20
|
-
let generation = source.sessionGeneration;
|
|
20
|
+
let generation = source.identity.sessionGeneration;
|
|
21
21
|
const write = () => {
|
|
22
22
|
if (cleared)
|
|
23
23
|
return;
|
|
24
24
|
// Protocol: plain text only; the guardian strips control characters, so styling would be lost.
|
|
25
|
-
const text = `${uncleanExitNoticeLines(source.currentSessionResumeMetadata()).join("\n")}\n`;
|
|
25
|
+
const text = `${uncleanExitNoticeLines(source.identity.currentSessionResumeMetadata()).join("\n")}\n`;
|
|
26
26
|
if (text === current)
|
|
27
27
|
return;
|
|
28
28
|
try {
|
|
@@ -35,13 +35,13 @@ export function armExitNotice(source, path) {
|
|
|
35
35
|
catch { }
|
|
36
36
|
};
|
|
37
37
|
write();
|
|
38
|
-
const unsubscribe = source.onEvent(event => {
|
|
38
|
+
const unsubscribe = source.session.onEvent(event => {
|
|
39
39
|
// Rationale: a session is persisted by its first response and replaced by /new or /resume;
|
|
40
40
|
// these events cover both without touching the per-chunk stream.
|
|
41
|
-
const replaced = source.sessionGeneration !== generation;
|
|
41
|
+
const replaced = source.identity.sessionGeneration !== generation;
|
|
42
42
|
if (!replaced && event.type !== "session-lifecycle" && event.type !== "assistant-message-completed")
|
|
43
43
|
return;
|
|
44
|
-
generation = source.sessionGeneration;
|
|
44
|
+
generation = source.identity.sessionGeneration;
|
|
45
45
|
write();
|
|
46
46
|
});
|
|
47
47
|
return {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { ClipboardDiagnosticCapture } from "./clipboard-diagnostics.js";
|
|
2
|
+
export { createOwnedUiClipboardServices } from "./clipboard-services.js";
|
|
3
|
+
export type { OwnedUiClipboardServices, OwnedUiClipboardServicesOptions } from "./clipboard-services.js";
|
|
2
4
|
export { ContextualPromptSuggestionController, samePromptSuggestionIdentity } from "./prompt-suggestion-controller.js";
|
|
3
5
|
export type { ContextualPromptSuggestionControllerOptions, ContextualPromptSuggestionSurface } from "./prompt-suggestion-controller.js";
|
|
4
6
|
export { OwnedUiSessionShell, OwnedUiSessionShellRoot, formatSessionResumeCommand, quoteCommandArgument } from "./session-shell.js";
|
|
5
|
-
export type { OwnedUiSessionShellOptions, OwnedUiShellDiagnosticOptions, OwnedUiShellEngineOptions, OwnedUiShellHistoryOptions, OwnedUiShellPresentationOptions, OwnedUiShellPromptImagesOptions, OwnedUiShellSkillsOptions, OwnedUiShellSuggestionOptions, SessionResumeCommandMetadata, } from "./session-shell.js";
|
|
7
|
+
export type { OwnedUiSessionShellOptions, OwnedUiShellDiagnosticOptions, OwnedUiShellEngineOptions, OwnedUiShellHistoryOptions, OwnedUiShellPresentationOptions, OwnedUiShellPromptImagesOptions, OwnedUiShellSharedServices, OwnedUiShellSkillsOptions, OwnedUiShellSuggestionOptions, SessionResumeCommandMetadata, } from "./session-shell.js";
|
|
6
8
|
export { STREAM_PRESENTATION_INTERVAL_MS, StreamPresentationCoalescer } from "./stream-presentation-coalescer.js";
|
|
7
9
|
export type { StreamPresentationScheduler } from "./stream-presentation-coalescer.js";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { ClipboardDiagnosticCapture } from "./clipboard-diagnostics.js";
|
|
2
|
+
export { createOwnedUiClipboardServices } from "./clipboard-services.js";
|
|
2
3
|
export { ContextualPromptSuggestionController, samePromptSuggestionIdentity } from "./prompt-suggestion-controller.js";
|
|
3
4
|
export { OwnedUiSessionShell, OwnedUiSessionShellRoot, formatSessionResumeCommand, quoteCommandArgument } from "./session-shell.js";
|
|
4
5
|
export { STREAM_PRESENTATION_INTERVAL_MS, StreamPresentationCoalescer } from "./stream-presentation-coalescer.js";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { startPasteExecutor } from "./paste-executor.js";
|
|
2
|
+
import type { HelperPool } from "./helper-pool.js";
|
|
2
3
|
import { type PasteEvent, type PasteSource, type PreparedPaste } from "./paste-protocol.js";
|
|
3
4
|
export interface PreparedPasteJob<T> {
|
|
4
5
|
readonly result: Promise<T>;
|
|
@@ -16,6 +17,8 @@ export interface PastePreparationClientOptions {
|
|
|
16
17
|
readonly helper?: URL;
|
|
17
18
|
/** Idle bound for the spare helper; production keeps the default. */
|
|
18
19
|
readonly spareIdleMs?: number;
|
|
20
|
+
/** Process-wide spare pool shared across sessions; the client warms it but never disposes it. */
|
|
21
|
+
readonly pool?: HelperPool;
|
|
19
22
|
}
|
|
20
23
|
/** Keeps eight distinct paste transactions alive through insertion; canceled executors retain capacity until fenced. */
|
|
21
24
|
export declare class PastePreparationClient {
|
|
@@ -8,13 +8,15 @@ export class PastePreparationClient {
|
|
|
8
8
|
#execute;
|
|
9
9
|
#helper;
|
|
10
10
|
#pool;
|
|
11
|
+
#ownsPool;
|
|
11
12
|
#sequence = 0;
|
|
12
13
|
#disposed = false;
|
|
13
14
|
constructor(options = {}) {
|
|
14
15
|
this.#onEvent = options.onEvent;
|
|
15
16
|
this.#execute = options.execute ?? startPasteExecutor;
|
|
16
17
|
this.#helper = options.helper;
|
|
17
|
-
this.#pool = options.execute === undefined ? createPasteHelperPool(options.helper, options.spareIdleMs) : undefined;
|
|
18
|
+
this.#pool = options.execute === undefined ? options.pool ?? createPasteHelperPool(options.helper, options.spareIdleMs) : undefined;
|
|
19
|
+
this.#ownsPool = options.pool === undefined;
|
|
18
20
|
}
|
|
19
21
|
/** Forks the spare helper now so the first paste takes a live child; later pastes rewarm it themselves. */
|
|
20
22
|
warm() { this.#pool?.warm(); }
|
|
@@ -160,7 +162,8 @@ export class PastePreparationClient {
|
|
|
160
162
|
async dispose() {
|
|
161
163
|
this.#disposed = true;
|
|
162
164
|
this.reset();
|
|
163
|
-
this.#
|
|
165
|
+
if (this.#ownsPool)
|
|
166
|
+
this.#pool?.dispose();
|
|
164
167
|
let timer;
|
|
165
168
|
await Promise.race([Promise.all([...this.#active].map(active => active.stopped)),
|
|
166
169
|
new Promise(resolve => { timer = setTimeout(resolve, PASTE_STOP_MS); timer.unref(); })]);
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import type { ClipboardPath, PreparedPasteText } from "./paste-types.js";
|
|
2
2
|
export declare const PATH_CHIP_PRESENTATION_UNITS = 4096;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/** Normalizes a path for host-filesystem identity comparisons. */
|
|
4
|
+
export declare function normalizedPathIdentity(fullPath: string): string;
|
|
5
|
+
/** Yields labels from the basename through the normalized rooted path, shortest first. */
|
|
6
|
+
export declare function pathChipLabelCandidates(fullPath: string): Iterable<string>;
|
|
7
|
+
/** Formats one path label with the established folder/file/image-file icon. */
|
|
8
|
+
export declare function pathChipTag(item: ClipboardPath, label?: string): string;
|
|
9
|
+
/** Yields complete deterministic tags lazily for path collision adoption. */
|
|
10
|
+
export declare function pathChipTagCandidates(item: ClipboardPath): Iterable<string>;
|
|
11
|
+
/** Returns the conservative UTF-16 presentation cost for one path occurrence. */
|
|
12
|
+
export declare function pathChipPresentationUnits(item: ClipboardPath): number;
|
|
6
13
|
/** Run in the isolated preparer: compact before path arrays become an oversized editor presentation. */
|
|
7
14
|
export declare function preparePathPresentation(paths: readonly ClipboardPath[]): PreparedPasteText;
|
|
@@ -1,19 +1,52 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
export const PATH_CHIP_PRESENTATION_UNITS = 4096;
|
|
3
|
-
// Invariant: a collision suffix containing any safe-integer index fits this per-occurrence reserve.
|
|
4
|
-
export const PATH_CHIP_SUFFIX_UNITS = 20;
|
|
5
3
|
const IMAGE_EXTENSION = /\.(?:jpe?g|png|webp|gif|bmp|tiff?)$/iu;
|
|
6
|
-
/**
|
|
7
|
-
export function
|
|
8
|
-
const
|
|
4
|
+
/** Normalizes a path for host-filesystem identity comparisons. */
|
|
5
|
+
export function normalizedPathIdentity(fullPath) {
|
|
6
|
+
const normalized = path.normalize(fullPath.trim());
|
|
7
|
+
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
8
|
+
}
|
|
9
|
+
/** Yields labels from the basename through the normalized rooted path, shortest first. */
|
|
10
|
+
export function* pathChipLabelCandidates(fullPath) {
|
|
11
|
+
const normalized = path.normalize(fullPath.trim());
|
|
12
|
+
const parsed = path.parse(normalized);
|
|
13
|
+
const relative = normalized.slice(parsed.root.length);
|
|
14
|
+
const segments = relative.split(path.sep).filter(segment => segment.length > 0);
|
|
15
|
+
let previous = "";
|
|
16
|
+
for (let depth = 1; depth <= segments.length; depth++) {
|
|
17
|
+
previous = segments.slice(-depth).join("/");
|
|
18
|
+
yield previous;
|
|
19
|
+
}
|
|
20
|
+
const rooted = displayPath(normalized);
|
|
21
|
+
if (segments.length === 0) {
|
|
22
|
+
const root = displayPath(parsed.root).replace(/\/$/u, "");
|
|
23
|
+
if (root.length > 0) {
|
|
24
|
+
previous = root;
|
|
25
|
+
yield root;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (rooted.length > 0 && rooted !== previous)
|
|
29
|
+
yield rooted;
|
|
30
|
+
}
|
|
31
|
+
/** Formats one path label with the established folder/file/image-file icon. */
|
|
32
|
+
export function pathChipTag(item, label = basePathLabel(item.fullPath)) {
|
|
9
33
|
const icon = item.kind === "folder" ? "📁" : IMAGE_EXTENSION.test(item.fullPath) ? "🖼 " : "📄";
|
|
10
34
|
return `[${icon} ${label}]`;
|
|
11
35
|
}
|
|
36
|
+
/** Yields complete deterministic tags lazily for path collision adoption. */
|
|
37
|
+
export function* pathChipTagCandidates(item) {
|
|
38
|
+
for (const label of pathChipLabelCandidates(item.fullPath))
|
|
39
|
+
yield pathChipTag(item, label);
|
|
40
|
+
}
|
|
41
|
+
/** Returns the conservative UTF-16 presentation cost for one path occurrence. */
|
|
42
|
+
export function pathChipPresentationUnits(item) {
|
|
43
|
+
return pathChipTag(item, displayPath(path.normalize(item.fullPath.trim()))).length;
|
|
44
|
+
}
|
|
12
45
|
/** Run in the isolated preparer: compact before path arrays become an oversized editor presentation. */
|
|
13
46
|
export function preparePathPresentation(paths) {
|
|
14
47
|
let units = 0;
|
|
15
48
|
for (const item of paths) {
|
|
16
|
-
units +=
|
|
49
|
+
units += pathChipPresentationUnits(item);
|
|
17
50
|
if (units > PATH_CHIP_PRESENTATION_UNITS) {
|
|
18
51
|
// Compatibility: individual adjacent chips expand without inserted separators or text re-normalization.
|
|
19
52
|
const text = paths.map(value => value.fullPath).join("");
|
|
@@ -22,3 +55,12 @@ export function preparePathPresentation(paths) {
|
|
|
22
55
|
}
|
|
23
56
|
return { kind: "paths", paths };
|
|
24
57
|
}
|
|
58
|
+
function basePathLabel(fullPath) {
|
|
59
|
+
const normalized = path.normalize(fullPath.trim());
|
|
60
|
+
return path.basename(normalized)
|
|
61
|
+
|| displayPath(path.parse(normalized).root).replace(/\/$/u, "")
|
|
62
|
+
|| displayPath(normalized);
|
|
63
|
+
}
|
|
64
|
+
function displayPath(value) {
|
|
65
|
+
return path.sep === "\\" ? value.replaceAll("\\", "/") : value;
|
|
66
|
+
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
|
-
import path from "node:path";
|
|
3
2
|
import { canonicalizeClipboardImage } from "./clipboard-image.js";
|
|
4
3
|
import { assertImageEncodedSize, assertPromptImages, canonicalPromptChipMatches, DEFAULT_PROMPT_IMAGE_LIMIT, ImageAttachmentError, replaceCanonicalPromptChips, } from "../../contracts/owned-ui/index.js";
|
|
5
4
|
import { ImagePreparationClient } from "./image-preparation-client.js";
|
|
6
5
|
import { preparePasteText } from "./paste-text-preparation.js";
|
|
7
|
-
import {
|
|
6
|
+
import { normalizedPathIdentity, pathChipTagCandidates } from "./path-chip-presentation.js";
|
|
8
7
|
import { PastePreparationClient } from "./paste-preparation-client.js";
|
|
9
8
|
const URL_SUBSTRING_PATTERN = /https?:\/\/[^\s\u0000-\u001f\u007f\]]+/giu;
|
|
10
9
|
const IMAGE_CHIP_IDENTIFIER_PATTERN = /^\[📷 screenshot-([a-f0-9]+)(?:-resized)?\]$/u;
|
|
@@ -23,6 +22,7 @@ function referencesPasteMarker(text, entry) {
|
|
|
23
22
|
/** Owns semantic chips and bounded pending paste references; cancels background work on reset or disposal. */
|
|
24
23
|
export class PromptChipStore {
|
|
25
24
|
#chips = new Map();
|
|
25
|
+
#pathTags = new Map();
|
|
26
26
|
// Invariant: clearing the editor never recycles a recoverable text chip's identity.
|
|
27
27
|
#textCounter = 0;
|
|
28
28
|
#pending = new Map();
|
|
@@ -199,6 +199,7 @@ export class PromptChipStore {
|
|
|
199
199
|
async dispose() {
|
|
200
200
|
await Promise.all([this.#preparation.dispose(), this.#isolated?.dispose(), ...this.#stopping]);
|
|
201
201
|
this.#chips.clear();
|
|
202
|
+
this.#pathTags.clear();
|
|
202
203
|
this.#pending.clear();
|
|
203
204
|
this.#countRejectedImages.clear();
|
|
204
205
|
this.#provisionalOwners.clear();
|
|
@@ -269,7 +270,26 @@ export class PromptChipStore {
|
|
|
269
270
|
this.#claimChip(tag, owner, true);
|
|
270
271
|
return tag;
|
|
271
272
|
}
|
|
272
|
-
return paste.paths.map(item => this.#
|
|
273
|
+
return paste.paths.map(item => this.#recordPath(item, owner)).join("");
|
|
274
|
+
}
|
|
275
|
+
#recordPath(item, owner) {
|
|
276
|
+
const key = pathChipKey(item);
|
|
277
|
+
const establishedTag = this.#pathTags.get(key);
|
|
278
|
+
if (establishedTag !== undefined && this.#chips.has(establishedTag)) {
|
|
279
|
+
this.#claimChip(establishedTag, owner, false);
|
|
280
|
+
return establishedTag;
|
|
281
|
+
}
|
|
282
|
+
for (const tag of pathChipTagCandidates(item)) {
|
|
283
|
+
const chip = { kind: item.kind, tag, path: item.fullPath };
|
|
284
|
+
const existing = this.#chips.get(tag);
|
|
285
|
+
if (existing !== undefined && !sameChipValue(existing, chip))
|
|
286
|
+
continue;
|
|
287
|
+
this.#chips.set(tag, chip);
|
|
288
|
+
this.#pathTags.set(key, tag);
|
|
289
|
+
this.#claimChip(tag, owner, existing === undefined);
|
|
290
|
+
return tag;
|
|
291
|
+
}
|
|
292
|
+
throw new Error("Path chip labels could not distinguish normalized paths");
|
|
273
293
|
}
|
|
274
294
|
/** Hide provisional clipboard identities until the read identifies an actual image. */
|
|
275
295
|
hiddenRanges(line) {
|
|
@@ -501,7 +521,10 @@ export class PromptChipStore {
|
|
|
501
521
|
owners.delete(owner);
|
|
502
522
|
if (owners.size === 0) {
|
|
503
523
|
this.#provisionalOwners.delete(tag);
|
|
524
|
+
const chip = this.#chips.get(tag);
|
|
504
525
|
this.#chips.delete(tag);
|
|
526
|
+
if (chip?.kind === "file" || chip?.kind === "folder")
|
|
527
|
+
this.#pathTags.delete(pathChipKey(chip));
|
|
505
528
|
}
|
|
506
529
|
}
|
|
507
530
|
}
|
|
@@ -522,13 +545,16 @@ export class PromptChipStore {
|
|
|
522
545
|
return uniqueTag;
|
|
523
546
|
}
|
|
524
547
|
}
|
|
548
|
+
function pathChipKey(item) {
|
|
549
|
+
return `${item.kind}\0${normalizedPathIdentity("fullPath" in item ? item.fullPath : item.path)}`;
|
|
550
|
+
}
|
|
525
551
|
function sameChipValue(left, right) {
|
|
526
552
|
if (left.kind !== right.kind)
|
|
527
553
|
return false;
|
|
528
554
|
if (left.kind === "url" && right.kind === "url")
|
|
529
555
|
return left.url === right.url;
|
|
530
556
|
if ((left.kind === "file" || left.kind === "folder") && (right.kind === "file" || right.kind === "folder")) {
|
|
531
|
-
return
|
|
557
|
+
return normalizedPathIdentity(left.path) === normalizedPathIdentity(right.path);
|
|
532
558
|
}
|
|
533
559
|
if (left.kind === "image" && right.kind === "image")
|
|
534
560
|
return left.image.data === right.image.data;
|
|
@@ -17,7 +17,7 @@ export interface ContextualPromptSuggestionControllerOptions {
|
|
|
17
17
|
type DecisionIdentity = Omit<OwnedUiPromptSuggestionIdentity, "model"> & {
|
|
18
18
|
readonly model: OwnedUiPromptSuggestionIdentity["model"] | null;
|
|
19
19
|
};
|
|
20
|
-
/** Prefetches one inert candidate
|
|
20
|
+
/** Prefetches one inert candidate and owns one bounded settlement/retry recovery lifecycle. */
|
|
21
21
|
export declare class ContextualPromptSuggestionController {
|
|
22
22
|
#private;
|
|
23
23
|
readonly options: ContextualPromptSuggestionControllerOptions;
|
|
@@ -26,12 +26,13 @@ export declare class ContextualPromptSuggestionController {
|
|
|
26
26
|
setEnabled(enabled: boolean): void;
|
|
27
27
|
skip(identity: DecisionIdentity, reason: SuggestionDecisionReason): void;
|
|
28
28
|
consider(identity: OwnedUiPromptSuggestionIdentity, decision: boolean | SuggestionDecision): void;
|
|
29
|
-
|
|
29
|
+
/** Settles an existing prefetch or starts the first request when that eligible prefetch was missed. */
|
|
30
|
+
settle(identity: OwnedUiPromptSuggestionIdentity, decision?: boolean | SuggestionDecision): void;
|
|
30
31
|
accept(): void;
|
|
31
32
|
invalidate(): void;
|
|
32
|
-
/** Retires
|
|
33
|
+
/** Retires generating or scheduled recovery; a prepared or available suggestion survives a draft edit. */
|
|
33
34
|
abortPending(): void;
|
|
34
|
-
/** Reasserts retained ghost text
|
|
35
|
+
/** Reasserts retained ghost text or retries a deferred presentation when the editor is eligible. */
|
|
35
36
|
restoreAvailable(): void;
|
|
36
37
|
dispose(): void;
|
|
37
38
|
}
|