@timurproko/a1 0.2.7-dev.806 → 0.2.7-dev.809
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/dist/app/session-shell/dialog-coordinator.d.ts +42 -0
- package/dist/app/session-shell/dialog-coordinator.js +133 -0
- package/dist/app/session-shell/dock-chrome.d.ts +34 -0
- package/dist/app/session-shell/dock-chrome.js +109 -0
- package/dist/app/session-shell/exit-notice.d.ts +1 -1
- package/dist/app/session-shell/exit-notice.js +1 -1
- package/dist/app/session-shell/extension-surface.d.ts +30 -0
- package/dist/app/session-shell/extension-surface.js +105 -0
- package/dist/app/session-shell/input-surface-switch.d.ts +36 -0
- package/dist/app/session-shell/input-surface-switch.js +85 -0
- package/dist/app/session-shell/login-interaction.d.ts +27 -0
- package/dist/app/session-shell/login-interaction.js +91 -0
- package/dist/app/session-shell/prompt-submission.d.ts +48 -0
- package/dist/app/session-shell/prompt-submission.js +276 -0
- package/dist/app/session-shell/resident-tab-coordinator.d.ts +41 -0
- package/dist/app/session-shell/resident-tab-coordinator.js +120 -0
- package/dist/app/session-shell/session-concern.d.ts +22 -0
- package/dist/app/session-shell/session-concern.js +29 -0
- package/dist/app/session-shell/session-lifecycle.d.ts +29 -0
- package/dist/app/session-shell/session-lifecycle.js +49 -0
- package/dist/app/session-shell/session-shell-root.d.ts +1 -1
- package/dist/app/session-shell/session-shell-root.js +182 -931
- package/dist/app/session-shell/session-shell.d.ts +2 -8
- package/dist/app/session-shell/session-shell.js +209 -897
- package/dist/app/session-shell/settings-bindings.d.ts +17 -0
- package/dist/app/session-shell/settings-bindings.js +91 -0
- package/dist/app/session-shell/shell-editor-factory.d.ts +27 -0
- package/dist/app/session-shell/shell-editor-factory.js +102 -0
- package/dist/app/session-shell/shell-host.d.ts +6 -0
- package/dist/app/session-shell/shell-host.js +26 -4
- package/dist/app/session-shell/shell-layout.d.ts +64 -0
- package/dist/app/session-shell/shell-layout.js +18 -0
- package/dist/app/session-shell/suggestion-surface.d.ts +25 -0
- package/dist/app/session-shell/suggestion-surface.js +63 -0
- package/dist/app/session-shell/transcript-document.d.ts +78 -0
- package/dist/app/session-shell/transcript-document.js +365 -0
- package/dist/app/session-shell/viewport-layout.d.ts +31 -0
- package/dist/app/session-shell/viewport-layout.js +160 -0
- package/dist/app/session-shell/workflow-output.d.ts +33 -0
- package/dist/app/session-shell/workflow-output.js +174 -0
- package/dist/app/session-shell/workflow-router.d.ts +25 -0
- package/dist/app/session-shell/workflow-router.js +39 -0
- package/dist/composition/owned-ui.d.ts +6 -25
- package/dist/composition/owned-ui.js +48 -242
- package/dist/composition/resident-tab-bridge.d.ts +16 -0
- package/dist/composition/resident-tab-bridge.js +159 -0
- package/dist/composition/session-backend.d.ts +19 -0
- package/dist/composition/session-backend.js +1 -0
- package/dist/composition/session-runtime-registry.d.ts +20 -0
- package/dist/composition/session-runtime-registry.js +85 -0
- package/dist/composition/settings-route-host.d.ts +6 -1
- package/dist/composition/settings-route-host.js +7 -6
- package/dist/composition/startup-route.d.ts +32 -0
- package/dist/composition/startup-route.js +72 -0
- package/dist/features/owned-ui/settings-app.d.ts +4 -1
- package/dist/features/owned-ui/settings-app.js +9 -3
- package/dist/features/resident-tab/shortcut-declarations.js +1 -1
- package/dist/features/resident-tab/status-deriver.d.ts +4 -3
- package/dist/features/resident-tab/status-deriver.js +2 -5
- package/dist/foundation/release/bootstrap.js +2 -2
- package/dist/foundation/resident-tabs/bridge-client.d.ts +1 -1
- package/dist/foundation/resident-tabs/bridge-client.js +2 -1
- package/dist/foundation/resident-tabs/fixture-control.d.ts +7 -0
- package/dist/foundation/resident-tabs/fixture-control.js +35 -0
- package/dist/foundation/resident-tabs/progress-observation.d.ts +7 -0
- package/dist/foundation/resident-tabs/progress-observation.js +119 -0
- package/dist/foundation/terminal-cleanup/index.d.ts +1 -1
- package/dist/foundation/terminal-cleanup/index.js +1 -1
- package/dist/foundation/terminal-cleanup/terminal-reset.d.ts +5 -0
- package/dist/foundation/terminal-cleanup/terminal-reset.js +5 -0
- package/dist/integrations/pi/engine/adapter.d.ts +4 -77
- package/dist/integrations/pi/engine/adapter.js +85 -393
- package/dist/integrations/pi/engine/command-dispatch.d.ts +13 -0
- package/dist/integrations/pi/engine/command-dispatch.js +57 -0
- package/dist/integrations/pi/engine/host.js +2 -2
- package/dist/integrations/pi/engine/ports.d.ts +56 -0
- package/dist/integrations/pi/engine/ports.js +89 -0
- package/dist/integrations/pi/engine/session-runtime.js +5 -2
- package/dist/integrations/pi/engine/view-state.d.ts +42 -0
- package/dist/integrations/pi/engine/view-state.js +126 -0
- package/dist/integrations/pi/tui-runtime/adapter.d.ts +6 -0
- package/dist/integrations/pi/tui-runtime/adapter.js +28 -1
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +11 -0
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +30 -1
- package/dist/native/darwin-arm64/manifest.json +1 -1
- package/dist/native/darwin-arm64/terminal-host.manifest.json +3 -3
- package/dist/native/darwin-arm64/terminal-host.node +0 -0
- package/dist/native/darwin-x64/manifest.json +1 -1
- package/dist/native/darwin-x64/terminal-host.manifest.json +3 -3
- package/dist/native/darwin-x64/terminal-host.node +0 -0
- package/dist/native/linux-x64/manifest.json +1 -1
- package/dist/native/linux-x64/terminal-host.manifest.json +3 -3
- package/dist/native/linux-x64/terminal-host.node +0 -0
- package/dist/native/win32-x64/manifest.json +2 -2
- package/dist/native/win32-x64/process-guardian.node +0 -0
- package/dist/native/win32-x64/terminal-host.manifest.json +3 -3
- package/dist/native/win32-x64/terminal-host.node +0 -0
- package/dist/product-identity.d.ts +2 -2
- package/dist/product-identity.js +2 -2
- package/dist/product-identity.json +6 -0
- package/dist/ui/settings/manager.d.ts +6 -0
- package/dist/ui/settings/manager.js +25 -0
- package/docs/architecture/boundaries.md +14 -0
- package/docs/architecture/resident-tabs.md +23 -18
- package/package.json +2 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type OwnedUiCommand, type OwnedUiCommandResult, type OwnedUiDiagnostics } from "../../../contracts/owned-ui/index.js";
|
|
2
2
|
import type { PiEmittedEvent } from "./event-delivery.js";
|
|
3
|
+
import type { PiEngineRuntime } from "./session-runtime.js";
|
|
4
|
+
import type { EngineViewState } from "./view-state.js";
|
|
3
5
|
export type AdapterCommandResult = OwnedUiCommandResult;
|
|
4
6
|
export interface PiCommandDispatchPorts {
|
|
5
7
|
sessionId(): string;
|
|
@@ -36,3 +38,14 @@ export declare class PiCommandDispatch {
|
|
|
36
38
|
reset(): void;
|
|
37
39
|
execute(command: OwnedUiCommand): Promise<AdapterCommandResult>;
|
|
38
40
|
}
|
|
41
|
+
/** What carrying out a command reaches: the running engine, the view state it updates, and disposal. */
|
|
42
|
+
export interface EngineCommandContext {
|
|
43
|
+
readonly engine: Pick<PiEngineRuntime, "runtime" | "session" | "generation" | "sessionCommands">;
|
|
44
|
+
readonly state: Pick<EngineViewState, "activeModel" | "thinkingLevel" | "setTerminal" | "terminal">;
|
|
45
|
+
/** False while delivery is overloaded or admission is stopped; a late model change then stays unpublished. */
|
|
46
|
+
admissionOpen(): boolean;
|
|
47
|
+
emit(value: PiEmittedEvent): void;
|
|
48
|
+
dispose(): Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
/** Carries out one admitted command against the running engine; throws when no session runs or the command fails. */
|
|
51
|
+
export declare function performEngineCommand(command: OwnedUiCommand, context: EngineCommandContext): Promise<void>;
|
|
@@ -123,3 +123,60 @@ export class PiCommandDispatch {
|
|
|
123
123
|
return { outcome, diagnostic };
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
|
+
// Invariant: prompt input and session controls run through the engine's own session commands, which own queuing and images.
|
|
127
|
+
async function runSessionCommand(request, context) {
|
|
128
|
+
const result = await context.engine.sessionCommands?.execute(request);
|
|
129
|
+
if (!result || result.outcome === "rejected" || result.outcome === "failed") {
|
|
130
|
+
throw new Error(request.type === "retry" ? "no previous prompt is available to retry" : `Pi session command failed: ${request.type}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function runPromptCommand(command, context) {
|
|
134
|
+
return runSessionCommand({
|
|
135
|
+
type: command.type,
|
|
136
|
+
text: command.text,
|
|
137
|
+
...(command.images === undefined ? {} : { images: [...command.images] }),
|
|
138
|
+
}, context);
|
|
139
|
+
}
|
|
140
|
+
const ownedUiStateCommand = () => {
|
|
141
|
+
throw new Error("owned UI state commands belong to the owned UI layer, not the Pi engine adapter");
|
|
142
|
+
};
|
|
143
|
+
// Invariant: one handler per command type; the table is exhaustive, so a new command type cannot be silently ignored.
|
|
144
|
+
const ENGINE_COMMANDS = {
|
|
145
|
+
"prompt": (command, context) => runPromptCommand(command, context),
|
|
146
|
+
"steer": (command, context) => runPromptCommand(command, context),
|
|
147
|
+
"follow-up": (command, context) => runPromptCommand(command, context),
|
|
148
|
+
"abort": (_command, context) => runSessionCommand({ type: "abort" }, context),
|
|
149
|
+
"retry": (_command, context) => runSessionCommand({ type: "retry" }, context),
|
|
150
|
+
"compact": (_command, context) => runSessionCommand({ type: "compact" }, context),
|
|
151
|
+
"set-model": async (command, context, { runtime, session, generation }) => {
|
|
152
|
+
const model = runtime.services.modelRuntime.getModel(command.model.providerId, command.model.modelId);
|
|
153
|
+
if (!model)
|
|
154
|
+
throw new Error(`model is unavailable: ${command.model.providerId}/${command.model.modelId}`);
|
|
155
|
+
await session.setModel(model);
|
|
156
|
+
if (generation === context.engine.generation && context.admissionOpen())
|
|
157
|
+
context.state.activeModel = { ...command.model };
|
|
158
|
+
},
|
|
159
|
+
"set-thinking-level": (command, context, { session }) => {
|
|
160
|
+
session.setThinkingLevel(command.thinkingLevel);
|
|
161
|
+
context.state.thinkingLevel = command.thinkingLevel;
|
|
162
|
+
},
|
|
163
|
+
"new-session": async (_command, _context, { runtime }) => { await runtime.newSession(); },
|
|
164
|
+
"resume-session": async (command, _context, { runtime }) => { await runtime.switchSession(command.sessionPath); },
|
|
165
|
+
"resize-surface": (command, context) => {
|
|
166
|
+
context.state.setTerminal(command.surface);
|
|
167
|
+
context.emit({ type: "terminal-surface", surface: context.state.terminal });
|
|
168
|
+
},
|
|
169
|
+
"shutdown": (_command, context) => context.dispose(),
|
|
170
|
+
"set-setting": ownedUiStateCommand,
|
|
171
|
+
"apply-customization": ownedUiStateCommand,
|
|
172
|
+
"remove-customization": ownedUiStateCommand,
|
|
173
|
+
};
|
|
174
|
+
/** Carries out one admitted command against the running engine; throws when no session runs or the command fails. */
|
|
175
|
+
export async function performEngineCommand(command, context) {
|
|
176
|
+
const { runtime, session, generation } = context.engine;
|
|
177
|
+
if (!runtime || !session)
|
|
178
|
+
throw new Error("engine session is unavailable");
|
|
179
|
+
// Invariant: the table maps each type to the handler for exactly that command, so the command fits its own handler.
|
|
180
|
+
const handler = ENGINE_COMMANDS[command.type];
|
|
181
|
+
await handler(command, context, { runtime, session, generation });
|
|
182
|
+
}
|
|
@@ -86,7 +86,7 @@ class ProcessPiEngineHost {
|
|
|
86
86
|
return;
|
|
87
87
|
this.#disposed = true;
|
|
88
88
|
this.#abort.abort();
|
|
89
|
-
const live = [...this.#sessions.values()].filter(session => !session.disposed);
|
|
89
|
+
const live = [...this.#sessions.values()].filter(session => !session.identity.disposed);
|
|
90
90
|
this.#sessions.clear();
|
|
91
91
|
await Promise.all(live.map(session => session.dispose()));
|
|
92
92
|
}
|
|
@@ -107,7 +107,7 @@ class ProcessPiEngineHost {
|
|
|
107
107
|
}
|
|
108
108
|
#forgetDisposedSessions() {
|
|
109
109
|
for (const [sessionId, session] of this.#sessions)
|
|
110
|
-
if (session.disposed)
|
|
110
|
+
if (session.identity.disposed)
|
|
111
111
|
this.#sessions.delete(sessionId);
|
|
112
112
|
}
|
|
113
113
|
// Rationale: the profile's timeout is installed once, by whichever session loads it first; a written
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { AgentSession } from "../startup-public.js";
|
|
2
|
+
import type { OwnedUiExtensionPort, OwnedUiImageAttachment, OwnedUiReleaseUpdate, OwnedUiSessionCatalogPort, OwnedUiSessionIdentityPort, OwnedUiSessionPort, OwnedUiSessionSettingsPort, OwnedUiWorkflowPort } from "../../../contracts/owned-ui/index.js";
|
|
3
|
+
import type { PiPinnedSettingsCallback, PiPinnedSettingsSnapshot, PiSessionSelectorContext, PiTreeSelectorContext, PiWorkflowInteractionHost, PiWorkflowRequest, PiWorkflowResult } from "./workflows.js";
|
|
4
|
+
import type { PiExtensionUiBinding } from "./extension-ui-binding.js";
|
|
5
|
+
import type { PiResourceCatalog } from "./resource-catalog.js";
|
|
6
|
+
import type { PiEngineRuntime } from "./session-runtime.js";
|
|
7
|
+
import type { PiEngineSettings } from "./settings-port.js";
|
|
8
|
+
import type { PiWorkflowContexts } from "./workflow-contexts.js";
|
|
9
|
+
import type { PiWorkflowRunner } from "./workflow-runner.js";
|
|
10
|
+
/**
|
|
11
|
+
* The Pi objects pinned selectors and transcript renderers are built from. They are not part of the
|
|
12
|
+
* session backend contract; only the session presenters owner reads them.
|
|
13
|
+
*/
|
|
14
|
+
export interface PiSessionPresentationSource {
|
|
15
|
+
pinnedModelSelectorContext(): ReturnType<PiWorkflowContexts["pinnedModelSelectorContext"]>;
|
|
16
|
+
pinnedSessionSelectorContext(): PiSessionSelectorContext;
|
|
17
|
+
pinnedTreeSelectorContext(): PiTreeSelectorContext;
|
|
18
|
+
pinnedMessageRenderer(customType: string): unknown;
|
|
19
|
+
pinnedToolRenderers(toolName: string): unknown;
|
|
20
|
+
pinnedShortcutDescriptions(bindings: Parameters<AgentSession["extensionRunner"]["getShortcuts"]>[0]): readonly {
|
|
21
|
+
readonly key: string;
|
|
22
|
+
readonly description: string;
|
|
23
|
+
}[];
|
|
24
|
+
pinnedSettingsModels(): Pick<PiPinnedSettingsSnapshot, "currentModel" | "availableDefaultModels">;
|
|
25
|
+
applyPinnedSettingValue(callback: PiPinnedSettingsCallback, value: unknown): Promise<PiWorkflowResult>;
|
|
26
|
+
}
|
|
27
|
+
export interface PiEngineAdapterPorts {
|
|
28
|
+
readonly identity: OwnedUiSessionIdentityPort;
|
|
29
|
+
readonly session: OwnedUiSessionPort;
|
|
30
|
+
readonly workflows: OwnedUiWorkflowPort;
|
|
31
|
+
readonly settings: OwnedUiSessionSettingsPort;
|
|
32
|
+
readonly catalog: OwnedUiSessionCatalogPort;
|
|
33
|
+
readonly extensions: OwnedUiExtensionPort;
|
|
34
|
+
readonly presentation: PiSessionPresentationSource;
|
|
35
|
+
}
|
|
36
|
+
/** The adapter's collaborators and its own session operations, which every port member reaches at call time. */
|
|
37
|
+
export interface EnginePortParts {
|
|
38
|
+
readonly sessionId: string;
|
|
39
|
+
readonly agentDir: string;
|
|
40
|
+
readonly engine: Pick<PiEngineRuntime, "cwd" | "generation" | "bindingGeneration" | "currentSessionResumeMetadata" | "currentSessionFile">;
|
|
41
|
+
readonly contexts: PiWorkflowContexts;
|
|
42
|
+
readonly workflows: PiWorkflowRunner;
|
|
43
|
+
readonly settings: PiEngineSettings;
|
|
44
|
+
readonly resources: PiResourceCatalog;
|
|
45
|
+
readonly extensions: PiExtensionUiBinding;
|
|
46
|
+
readonly session: OwnedUiSessionPort;
|
|
47
|
+
disposed(): boolean;
|
|
48
|
+
executeWorkflow(request: PiWorkflowRequest): Promise<PiWorkflowResult>;
|
|
49
|
+
clearQueuedWorkflows(): readonly string[];
|
|
50
|
+
setWorkflowInteractionHost(interaction: PiWorkflowInteractionHost): void;
|
|
51
|
+
announceReleaseUpdate(release: OwnedUiReleaseUpdate): void;
|
|
52
|
+
resolveTranscriptImage(assetId: string): OwnedUiImageAttachment | null;
|
|
53
|
+
/** The running session's extension runner; throws when no session runs. */
|
|
54
|
+
extensionRunner(): AgentSession["extensionRunner"] | undefined;
|
|
55
|
+
}
|
|
56
|
+
export declare function createEnginePorts(parts: EnginePortParts): PiEngineAdapterPorts;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// Invariant: every port member delegates at call time, so ports built once follow session replacement.
|
|
2
|
+
export function createEnginePorts(parts) {
|
|
3
|
+
const { engine, contexts, workflows, settings, resources, extensions } = parts;
|
|
4
|
+
return {
|
|
5
|
+
identity: {
|
|
6
|
+
sessionId: parts.sessionId,
|
|
7
|
+
agentDir: parts.agentDir,
|
|
8
|
+
get cwd() { return engine.cwd; },
|
|
9
|
+
get sessionGeneration() { return engine.generation; },
|
|
10
|
+
get sessionBindingGeneration() { return engine.bindingGeneration; },
|
|
11
|
+
get disposed() { return parts.disposed(); },
|
|
12
|
+
currentSessionResumeMetadata: () => engine.currentSessionResumeMetadata(),
|
|
13
|
+
currentSessionFile: () => engine.currentSessionFile(),
|
|
14
|
+
},
|
|
15
|
+
session: parts.session,
|
|
16
|
+
workflows: {
|
|
17
|
+
executeWorkflow: request => parts.executeWorkflow(request),
|
|
18
|
+
executeBashWorkflow: (command, excludeFromContext) => workflows.executeBashWorkflow(command, excludeFromContext),
|
|
19
|
+
cycleModelWorkflow: direction => workflows.cycleModelWorkflow(direction),
|
|
20
|
+
workflowAutocompleteCommands: () => resources.workflowAutocompleteCommands(),
|
|
21
|
+
clearQueuedWorkflows: () => parts.clearQueuedWorkflows(),
|
|
22
|
+
reloadBlockedResult: () => workflows.reloadBlockedResult(),
|
|
23
|
+
copyWorkflowText: text => workflows.copyWorkflowText(text),
|
|
24
|
+
setWorkflowInteractionHost: interaction => { parts.setWorkflowInteractionHost(interaction); },
|
|
25
|
+
},
|
|
26
|
+
settings: {
|
|
27
|
+
get productMode() { return settings.productMode; },
|
|
28
|
+
snapshot: () => {
|
|
29
|
+
// Invariant: the selector-only model values travel on the presentation source, not in the neutral snapshot.
|
|
30
|
+
const { currentModel: _currentModel, availableDefaultModels: _availableDefaultModels, ...snapshot } = settings.pinnedSettingsSnapshot();
|
|
31
|
+
return snapshot;
|
|
32
|
+
},
|
|
33
|
+
bindOwner: (owner, handlers) => settings.bindSettingsOwner(owner, handlers),
|
|
34
|
+
setDefaultThinkingLevel: level => { settings.setDefaultThinkingLevel(level); },
|
|
35
|
+
configuredTheme: () => settings.configuredTheme(),
|
|
36
|
+
},
|
|
37
|
+
catalog: {
|
|
38
|
+
modelsContext: () => contexts.modelsContext(),
|
|
39
|
+
setSessionModelScope: scopeIds => { contexts.setSessionModelScope(scopeIds); },
|
|
40
|
+
persistModelScope: scopeIds => { contexts.persistModelScope(scopeIds); },
|
|
41
|
+
refreshModels: signal => contexts.refreshModels(signal),
|
|
42
|
+
pinnedScopedModelsContext: () => contexts.pinnedScopedModelsContext(),
|
|
43
|
+
updateScopedModels: enabledModelIds => { contexts.updateScopedModels(enabledModelIds); },
|
|
44
|
+
persistScopedModels: enabledModelIds => { contexts.persistScopedModels(enabledModelIds); },
|
|
45
|
+
refreshScopedModels: signal => contexts.refreshScopedModels(signal),
|
|
46
|
+
pinnedProjectTrustContext: () => contexts.pinnedProjectTrustContext(),
|
|
47
|
+
persistProjectTrust: updates => { contexts.persistProjectTrust(updates); },
|
|
48
|
+
pinnedLoginOptions: authType => contexts.loginOptions(authType),
|
|
49
|
+
pinnedLoginMethodOptions: providerReference => contexts.pinnedLoginMethodOptions(providerReference),
|
|
50
|
+
pinnedAmbientAuthentication: selection => contexts.pinnedAmbientAuthentication(selection),
|
|
51
|
+
pinnedLogoutOptions: () => contexts.logoutOptions(),
|
|
52
|
+
pinnedForkOptions: () => contexts.pinnedForkOptions(),
|
|
53
|
+
},
|
|
54
|
+
extensions: {
|
|
55
|
+
nonVisualResources: () => resources.nonVisualResources(),
|
|
56
|
+
extensionResources: () => resources.extensionResources(),
|
|
57
|
+
resolveTranscriptImage: assetId => parts.resolveTranscriptImage(assetId),
|
|
58
|
+
visualExtensionSupport: () => extensions.support(),
|
|
59
|
+
bindExtensionUi: (ui, shutdown) => extensions.bind(ui, shutdown),
|
|
60
|
+
unbindExtensionUi: () => extensions.unbind(),
|
|
61
|
+
bindClipboardWriter: writer => workflows.bindClipboardWriter(writer),
|
|
62
|
+
announceReleaseUpdate: release => { parts.announceReleaseUpdate(release); },
|
|
63
|
+
},
|
|
64
|
+
presentation: {
|
|
65
|
+
pinnedModelSelectorContext: () => contexts.pinnedModelSelectorContext(),
|
|
66
|
+
pinnedSessionSelectorContext: () => contexts.pinnedSessionSelectorContext(),
|
|
67
|
+
pinnedTreeSelectorContext: () => contexts.pinnedTreeSelectorContext(),
|
|
68
|
+
pinnedMessageRenderer: customType => parts.extensionRunner()?.getMessageRenderer?.(customType),
|
|
69
|
+
pinnedToolRenderers: toolName => {
|
|
70
|
+
const runner = parts.extensionRunner();
|
|
71
|
+
if (runner === undefined)
|
|
72
|
+
return undefined;
|
|
73
|
+
if (typeof runner.resolveToolRenderers === "function") {
|
|
74
|
+
return runner.resolveToolRenderers(toolName, () => runner.getToolDefinition?.(toolName));
|
|
75
|
+
}
|
|
76
|
+
return runner.getToolDefinition?.(toolName);
|
|
77
|
+
},
|
|
78
|
+
pinnedShortcutDescriptions: bindings => {
|
|
79
|
+
const shortcuts = parts.extensionRunner()?.getShortcuts?.(bindings);
|
|
80
|
+
return shortcuts === undefined ? [] : [...shortcuts].map(([key, shortcut]) => ({ key, description: shortcut.description ?? shortcut.extensionPath }));
|
|
81
|
+
},
|
|
82
|
+
pinnedSettingsModels: () => {
|
|
83
|
+
const { currentModel, availableDefaultModels } = settings.pinnedSettingsSnapshot();
|
|
84
|
+
return { ...(currentModel === undefined ? {} : { currentModel }), availableDefaultModels };
|
|
85
|
+
},
|
|
86
|
+
applyPinnedSettingValue: (callback, value) => settings.applyPinnedSettingValue(callback, value),
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
@@ -2,6 +2,7 @@ import { execFile } from "node:child_process";
|
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import { promisify } from "node:util";
|
|
4
4
|
import { PRODUCT_IDENTITY } from "../../../product-identity.js";
|
|
5
|
+
import { residentProgressObserver } from "../../../foundation/resident-tabs/progress-observation.js";
|
|
5
6
|
import { observeCompactionProgress } from "./compaction-progress.js";
|
|
6
7
|
import { createPiRuntimeIntegration } from "./runtime-integration.js";
|
|
7
8
|
import { PiSessionCommandIntegration } from "./session-integration.js";
|
|
@@ -369,8 +370,10 @@ export class PiEngineRuntime {
|
|
|
369
370
|
return;
|
|
370
371
|
const generation = this.#sessionGeneration;
|
|
371
372
|
this.#unsubscribe = session.subscribe(event => {
|
|
372
|
-
if (generation
|
|
373
|
-
|
|
373
|
+
if (generation !== this.#sessionGeneration || this.#ports.disposed())
|
|
374
|
+
return;
|
|
375
|
+
residentProgressObserver()?.engineDelivery(event);
|
|
376
|
+
this.#ports.event(event);
|
|
374
377
|
});
|
|
375
378
|
}
|
|
376
379
|
/**
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { OwnedUiDiagnostics, OwnedUiEditorState, OwnedUiModelInfo, OwnedUiSessionViewModel, OwnedUiStatusView, OwnedUiTerminalSurface, OwnedUiThinkingLevel, OwnedUiUsageView } from "../../../contracts/owned-ui/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* The engine adapter's own view-model state: lifecycle, editor, status, terminal surface, active
|
|
4
|
+
* model, thinking level, the usage cache, diagnostics, and the view revision. Every change that
|
|
5
|
+
* touches more than one field is one named mutator, so the adapter and its collaborators never
|
|
6
|
+
* rebuild these objects inline.
|
|
7
|
+
*/
|
|
8
|
+
export declare class EngineViewState {
|
|
9
|
+
#private;
|
|
10
|
+
lifecycle: OwnedUiSessionViewModel["lifecycle"];
|
|
11
|
+
activeModel: OwnedUiModelInfo | null;
|
|
12
|
+
thinkingLevel: OwnedUiThinkingLevel;
|
|
13
|
+
get revision(): number;
|
|
14
|
+
get editor(): OwnedUiEditorState;
|
|
15
|
+
get status(): OwnedUiStatusView;
|
|
16
|
+
get terminal(): OwnedUiTerminalSurface;
|
|
17
|
+
get diagnostics(): readonly OwnedUiDiagnostics[];
|
|
18
|
+
/** Any emitted event advances the revision. */
|
|
19
|
+
advance(): void;
|
|
20
|
+
/** A full view is about to be published: usage is recomputed and the revision advances. */
|
|
21
|
+
invalidate(): void;
|
|
22
|
+
invalidateUsage(): void;
|
|
23
|
+
/** The cached usage view, computed once per published view. */
|
|
24
|
+
usage(read: () => OwnedUiUsageView): OwnedUiUsageView;
|
|
25
|
+
/** The engine started: the session is ready and accepts submissions. */
|
|
26
|
+
markReady(): void;
|
|
27
|
+
/** A run started with `message` as its working status; true when the session was already busy. */
|
|
28
|
+
enterWork(message: string): boolean;
|
|
29
|
+
leaveWork(): void;
|
|
30
|
+
/** Records compaction or retry progress; false when it did not change. */
|
|
31
|
+
setWorkProgress(percent: Exclude<OwnedUiStatusView["workingProgress"], undefined>): boolean;
|
|
32
|
+
setQueuedSubmissions(queuedSubmissions: readonly string[]): void;
|
|
33
|
+
/** Fills an empty editor with `text`, as tree navigation does for the selected branch's prompt. */
|
|
34
|
+
offerEditorText(text: string): void;
|
|
35
|
+
setHardwareCursor(hardwareCursor: boolean): void;
|
|
36
|
+
setTerminal(surface: OwnedUiTerminalSurface): void;
|
|
37
|
+
/** A replaced session starts with an empty editor that accepts submissions and no working status. */
|
|
38
|
+
replaceSession(): void;
|
|
39
|
+
/** Delivery overload ended the run: ready when it can resume, stopped once disposed, otherwise failed. */
|
|
40
|
+
settleOverload(canResume: boolean, disposed: boolean): void;
|
|
41
|
+
recordDiagnostic(severity: OwnedUiDiagnostics["severity"], code: string, message: string, recoverable: boolean): OwnedUiDiagnostics;
|
|
42
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
const DEFAULT_SURFACE = {
|
|
2
|
+
columns: 100,
|
|
3
|
+
rows: 32,
|
|
4
|
+
focusedRegion: "editor",
|
|
5
|
+
hardwareCursor: false,
|
|
6
|
+
};
|
|
7
|
+
const MAX_DIAGNOSTICS = 100;
|
|
8
|
+
const MAX_STATUS_DIAGNOSTICS = 8;
|
|
9
|
+
/**
|
|
10
|
+
* The engine adapter's own view-model state: lifecycle, editor, status, terminal surface, active
|
|
11
|
+
* model, thinking level, the usage cache, diagnostics, and the view revision. Every change that
|
|
12
|
+
* touches more than one field is one named mutator, so the adapter and its collaborators never
|
|
13
|
+
* rebuild these objects inline.
|
|
14
|
+
*/
|
|
15
|
+
export class EngineViewState {
|
|
16
|
+
#revision = 0;
|
|
17
|
+
#editor = {
|
|
18
|
+
text: "",
|
|
19
|
+
queuedSubmissions: [],
|
|
20
|
+
selection: null,
|
|
21
|
+
cursorOffset: 0,
|
|
22
|
+
historyRevision: 0,
|
|
23
|
+
submitEnabled: false,
|
|
24
|
+
};
|
|
25
|
+
#status = {
|
|
26
|
+
title: "Pi",
|
|
27
|
+
workingMessage: null,
|
|
28
|
+
diagnostics: [],
|
|
29
|
+
badges: [],
|
|
30
|
+
};
|
|
31
|
+
#terminal = DEFAULT_SURFACE;
|
|
32
|
+
lifecycle = "starting";
|
|
33
|
+
activeModel = null;
|
|
34
|
+
thinkingLevel = "medium";
|
|
35
|
+
#usage;
|
|
36
|
+
#diagnostics = [];
|
|
37
|
+
get revision() { return this.#revision; }
|
|
38
|
+
get editor() { return this.#editor; }
|
|
39
|
+
get status() { return this.#status; }
|
|
40
|
+
get terminal() { return this.#terminal; }
|
|
41
|
+
get diagnostics() { return this.#diagnostics; }
|
|
42
|
+
/** Any emitted event advances the revision. */
|
|
43
|
+
advance() {
|
|
44
|
+
this.#revision += 1;
|
|
45
|
+
}
|
|
46
|
+
/** A full view is about to be published: usage is recomputed and the revision advances. */
|
|
47
|
+
invalidate() {
|
|
48
|
+
this.#usage = undefined;
|
|
49
|
+
this.#revision += 1;
|
|
50
|
+
}
|
|
51
|
+
invalidateUsage() {
|
|
52
|
+
this.#usage = undefined;
|
|
53
|
+
}
|
|
54
|
+
/** The cached usage view, computed once per published view. */
|
|
55
|
+
usage(read) {
|
|
56
|
+
return this.#usage ??= read();
|
|
57
|
+
}
|
|
58
|
+
/** The engine started: the session is ready and accepts submissions. */
|
|
59
|
+
markReady() {
|
|
60
|
+
this.lifecycle = "ready";
|
|
61
|
+
this.#editor = { ...this.#editor, submitEnabled: true };
|
|
62
|
+
}
|
|
63
|
+
/** A run started with `message` as its working status; true when the session was already busy. */
|
|
64
|
+
enterWork(message) {
|
|
65
|
+
const wasBusy = this.lifecycle === "busy";
|
|
66
|
+
this.lifecycle = "busy";
|
|
67
|
+
this.#status = { ...this.#status, workingMessage: message, workingProgress: null };
|
|
68
|
+
return wasBusy;
|
|
69
|
+
}
|
|
70
|
+
leaveWork() {
|
|
71
|
+
this.lifecycle = "ready";
|
|
72
|
+
this.#status = { ...this.#status, workingMessage: null, workingProgress: null };
|
|
73
|
+
}
|
|
74
|
+
/** Records compaction or retry progress; false when it did not change. */
|
|
75
|
+
setWorkProgress(percent) {
|
|
76
|
+
if (this.#status.workingProgress === percent)
|
|
77
|
+
return false;
|
|
78
|
+
this.#status = { ...this.#status, workingProgress: percent };
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
setQueuedSubmissions(queuedSubmissions) {
|
|
82
|
+
this.#editor = { ...this.#editor, queuedSubmissions: [...queuedSubmissions], historyRevision: this.#editor.historyRevision + 1 };
|
|
83
|
+
}
|
|
84
|
+
/** Fills an empty editor with `text`, as tree navigation does for the selected branch's prompt. */
|
|
85
|
+
offerEditorText(text) {
|
|
86
|
+
if (!this.#editor.text.trim()) {
|
|
87
|
+
this.#editor = { ...this.#editor, text, selection: null, cursorOffset: text.length };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
setHardwareCursor(hardwareCursor) {
|
|
91
|
+
this.#terminal = { ...this.#terminal, hardwareCursor };
|
|
92
|
+
}
|
|
93
|
+
setTerminal(surface) {
|
|
94
|
+
this.#terminal = { ...surface };
|
|
95
|
+
}
|
|
96
|
+
/** A replaced session starts with an empty editor that accepts submissions and no working status. */
|
|
97
|
+
replaceSession() {
|
|
98
|
+
this.#editor = {
|
|
99
|
+
text: "",
|
|
100
|
+
queuedSubmissions: [],
|
|
101
|
+
selection: null,
|
|
102
|
+
cursorOffset: 0,
|
|
103
|
+
historyRevision: this.#editor.historyRevision + 1,
|
|
104
|
+
submitEnabled: true,
|
|
105
|
+
};
|
|
106
|
+
this.#status = { ...this.#status, workingMessage: null, workingProgress: null, badges: [] };
|
|
107
|
+
}
|
|
108
|
+
/** Delivery overload ended the run: ready when it can resume, stopped once disposed, otherwise failed. */
|
|
109
|
+
settleOverload(canResume, disposed) {
|
|
110
|
+
this.#status = { ...this.#status, workingMessage: null, workingProgress: null };
|
|
111
|
+
this.lifecycle = disposed ? "stopped" : canResume ? "ready" : "failed";
|
|
112
|
+
this.#editor = { ...this.#editor, submitEnabled: canResume && !disposed };
|
|
113
|
+
this.#revision += 1;
|
|
114
|
+
}
|
|
115
|
+
recordDiagnostic(severity, code, message, recoverable) {
|
|
116
|
+
const diagnostic = { sequence: this.#diagnostics.length, code, severity, message, recoverable };
|
|
117
|
+
this.#diagnostics.push(diagnostic);
|
|
118
|
+
if (this.#diagnostics.length > MAX_DIAGNOSTICS)
|
|
119
|
+
this.#diagnostics.shift();
|
|
120
|
+
this.#status = {
|
|
121
|
+
...this.#status,
|
|
122
|
+
diagnostics: [...this.#status.diagnostics, message].slice(-MAX_STATUS_DIAGNOSTICS),
|
|
123
|
+
};
|
|
124
|
+
return diagnostic;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { type ProgramStatus, type WheelScrollLines } from "@earendil-works/pi-tui";
|
|
2
2
|
import type { PiTuiComponentPort, PiTuiInputListener, PiTuiOverlayHandle, PiTuiOverlayOptions, PiTuiPreInputListener, PiTuiRuntimeAdapterOptions, PiTuiRuntimeState, PiTuiScrollState, PiTuiStopOptions, PiTuiViewport } from "./contracts.js";
|
|
3
|
+
/**
|
|
4
|
+
* Re-encodes one key report decoded by pi-tui in the legacy form, so a kitty-keyboard child
|
|
5
|
+
* (resident tabs) and a legacy terminal produce the same owned-screen action. Releases decode
|
|
6
|
+
* to nothing; mouse reports, paste, and unknown sequences pass through unchanged.
|
|
7
|
+
*/
|
|
8
|
+
export declare function legacyKeyInput(data: string): string;
|
|
3
9
|
export type PiTuiRuntimeErrorStage = "construction" | "start" | "input-drain" | "restoration";
|
|
4
10
|
/** Identifies the Pi TUI lifecycle stage that failed while preserving the original cause. */
|
|
5
11
|
export declare class PiTuiRuntimeError extends Error {
|
|
@@ -1,8 +1,35 @@
|
|
|
1
|
-
import { HStack, ProcessTerminal, ScrollView, TuiAltScreen, TuiMainScreen, VStack, visibleWidth, } from "@earendil-works/pi-tui";
|
|
1
|
+
import { HStack, ProcessTerminal, ScrollView, TuiAltScreen, TuiMainScreen, VStack, decodeKittyPrintable, isKeyRelease, parseKey, visibleWidth, } from "@earendil-works/pi-tui";
|
|
2
2
|
import { MouseReportInput, stripSgrMouseReports } from "./mouse-report-input.js";
|
|
3
3
|
import { GeometryObservedAltScreen, OverlayGeometryTracker } from "./overlay-geometry.js";
|
|
4
4
|
import { boundedCleanup, EMERGENCY_TERMINAL_RESET } from "../../../foundation/terminal-cleanup/terminal-reset.js";
|
|
5
5
|
import { InputPresentationCoordinator, } from "./input-presentation-coordinator.js";
|
|
6
|
+
// Protocol: the legacy bytes owned screens and their key tables compare against.
|
|
7
|
+
const LEGACY_KEY_BYTES = {
|
|
8
|
+
escape: "\u001b", up: "\u001b[A", down: "\u001b[B", right: "\u001b[C", left: "\u001b[D",
|
|
9
|
+
"shift+up": "\u001b[1;2A", "shift+down": "\u001b[1;2B", pageUp: "\u001b[5~", pageDown: "\u001b[6~",
|
|
10
|
+
home: "\u001b[H", end: "\u001b[F", "ctrl+home": "\u001b[1;5H", "ctrl+end": "\u001b[1;5F",
|
|
11
|
+
enter: "\r", tab: "\t", "shift+tab": "\u001b[Z", backspace: "\u007f", delete: "\u001b[3~",
|
|
12
|
+
space: " ", "ctrl+c": "\u0003", "ctrl+z": "\u001a",
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Re-encodes one key report decoded by pi-tui in the legacy form, so a kitty-keyboard child
|
|
16
|
+
* (resident tabs) and a legacy terminal produce the same owned-screen action. Releases decode
|
|
17
|
+
* to nothing; mouse reports, paste, and unknown sequences pass through unchanged.
|
|
18
|
+
*/
|
|
19
|
+
export function legacyKeyInput(data) {
|
|
20
|
+
if (data.length <= 1 || !data.startsWith("\u001b"))
|
|
21
|
+
return data;
|
|
22
|
+
const key = parseKey(data);
|
|
23
|
+
if (key === undefined)
|
|
24
|
+
return data;
|
|
25
|
+
if (isKeyRelease(data))
|
|
26
|
+
return "";
|
|
27
|
+
const legacy = LEGACY_KEY_BYTES[key];
|
|
28
|
+
if (legacy !== undefined)
|
|
29
|
+
return legacy;
|
|
30
|
+
const printable = decodeKittyPrintable(data);
|
|
31
|
+
return printable !== undefined && printable >= " " && printable !== "\u007f" ? printable : data;
|
|
32
|
+
}
|
|
6
33
|
/** Identifies the Pi TUI lifecycle stage that failed while preserving the original cause. */
|
|
7
34
|
export class PiTuiRuntimeError extends Error {
|
|
8
35
|
stage;
|
|
@@ -52,6 +52,17 @@ export interface DamageAwareTerminalOptions {
|
|
|
52
52
|
};
|
|
53
53
|
readonly onResize?: () => void;
|
|
54
54
|
readonly onHyperlinkCleanupRequired?: () => void;
|
|
55
|
+
/** Exact-artifact fault controls evaluated before physical writes; absent in ordinary sessions. */
|
|
56
|
+
readonly allowWrite?: () => boolean;
|
|
57
|
+
readonly writeChunks?: (data: string) => readonly string[];
|
|
58
|
+
/** Optional payload-free observation after a terminal write returns. */
|
|
59
|
+
readonly onWrite?: (metadata: {
|
|
60
|
+
readonly bytes: number;
|
|
61
|
+
readonly fragments: number;
|
|
62
|
+
readonly transaction: "synchronized-output" | "ordinary";
|
|
63
|
+
readonly frameId?: number;
|
|
64
|
+
readonly cause?: string;
|
|
65
|
+
}) => void;
|
|
55
66
|
}
|
|
56
67
|
/**
|
|
57
68
|
* A fail-closed adapter for one pinned Pi fullscreen write grammar. Semantic
|
|
@@ -166,7 +166,36 @@ export class DamageAwareTerminalAdapter {
|
|
|
166
166
|
const forwarded = this.#canvasBackgroundAnsi === null
|
|
167
167
|
? output
|
|
168
168
|
: paintTerminalCanvasFrame(output, this.#canvasBackgroundAnsi);
|
|
169
|
-
|
|
169
|
+
let writeAllowed = true;
|
|
170
|
+
try {
|
|
171
|
+
writeAllowed = this.options.allowWrite?.() ?? true;
|
|
172
|
+
}
|
|
173
|
+
catch { /* Invariant: fixture controls fail open. */ }
|
|
174
|
+
if (!writeAllowed)
|
|
175
|
+
return;
|
|
176
|
+
let chunks = [forwarded];
|
|
177
|
+
try {
|
|
178
|
+
const controlled = this.options.writeChunks?.(forwarded);
|
|
179
|
+
if (controlled !== undefined && controlled.length > 0 && controlled.length <= 4_096
|
|
180
|
+
&& controlled.join("") === forwarded)
|
|
181
|
+
chunks = controlled;
|
|
182
|
+
}
|
|
183
|
+
catch { /* Invariant: fixture controls fail open without corrupting the renderer write. */ }
|
|
184
|
+
for (const chunk of chunks)
|
|
185
|
+
this.inner.write(chunk);
|
|
186
|
+
try {
|
|
187
|
+
this.options.onWrite?.({
|
|
188
|
+
bytes: Buffer.byteLength(forwarded),
|
|
189
|
+
fragments: chunks.length,
|
|
190
|
+
transaction: forwarded.startsWith(BEGIN_SYNCHRONIZED_OUTPUT) && forwarded.endsWith(END_SYNCHRONIZED_OUTPUT)
|
|
191
|
+
? "synchronized-output" : "ordinary",
|
|
192
|
+
...(armed === undefined ? {} : {
|
|
193
|
+
frameId: armed.descriptor.frameId,
|
|
194
|
+
cause: armed.descriptor.cause,
|
|
195
|
+
}),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
catch { /* Invariant: observation never changes rendering or write completion. */ }
|
|
170
199
|
if (epoch !== this.#epoch
|
|
171
200
|
|| (armed !== undefined && this.#lastConsumedFrameId !== armed.descriptor.frameId))
|
|
172
201
|
return;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"platform": "darwin",
|
|
8
8
|
"architecture": "arm64",
|
|
9
9
|
"capability": "supported",
|
|
10
|
-
"builtAt": "2026-10-
|
|
10
|
+
"builtAt": "2026-10-20T08:53:57.218Z",
|
|
11
11
|
"artifact": {
|
|
12
12
|
"filename": "process-guardian.node",
|
|
13
13
|
"sha256": "a87eaaffcd986b624c8b044b756446cc1bdaf4334a1775b97820542fe34f9fb7",
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
"architecture": "arm64",
|
|
10
10
|
"target": "aarch64-apple-darwin",
|
|
11
11
|
"capability": "supported",
|
|
12
|
-
"builtAt": "2026-10-
|
|
12
|
+
"builtAt": "2026-10-20T08:57:24.837Z",
|
|
13
13
|
"artifact": {
|
|
14
14
|
"filename": "terminal-host.node",
|
|
15
|
-
"sha256": "
|
|
16
|
-
"size":
|
|
15
|
+
"sha256": "1885cc705611eb1b5a06148d77cb3e85dc99321124b7fec4be382630292555c6",
|
|
16
|
+
"size": 5747616
|
|
17
17
|
},
|
|
18
18
|
"entry": {
|
|
19
19
|
"filename": "dist/foundation/resident-tabs/host-entry.js",
|
|
Binary file
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"platform": "darwin",
|
|
8
8
|
"architecture": "x64",
|
|
9
9
|
"capability": "supported",
|
|
10
|
-
"builtAt": "2026-10-
|
|
10
|
+
"builtAt": "2026-10-20T08:54:05.958Z",
|
|
11
11
|
"artifact": {
|
|
12
12
|
"filename": "process-guardian.node",
|
|
13
13
|
"sha256": "783a65f0de287a1c02cd5429dbe97bc8633f4cc8a7b92e3e961180b9bdcff814",
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
"architecture": "x64",
|
|
10
10
|
"target": "x86_64-apple-darwin",
|
|
11
11
|
"capability": "supported",
|
|
12
|
-
"builtAt": "2026-10-
|
|
12
|
+
"builtAt": "2026-10-20T09:00:09.786Z",
|
|
13
13
|
"artifact": {
|
|
14
14
|
"filename": "terminal-host.node",
|
|
15
|
-
"sha256": "
|
|
16
|
-
"size":
|
|
15
|
+
"sha256": "a34271e9cc5ec28a638dd4bcaff97a7fb33ac0856f4cd5b18814400d540e8da7",
|
|
16
|
+
"size": 6263000
|
|
17
17
|
},
|
|
18
18
|
"entry": {
|
|
19
19
|
"filename": "dist/foundation/resident-tabs/host-entry.js",
|
|
Binary file
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"platform": "linux",
|
|
8
8
|
"architecture": "x64",
|
|
9
9
|
"capability": "supported",
|
|
10
|
-
"builtAt": "2026-10-
|
|
10
|
+
"builtAt": "2026-10-20T08:53:35.318Z",
|
|
11
11
|
"artifact": {
|
|
12
12
|
"filename": "process-guardian.node",
|
|
13
13
|
"sha256": "118e5954e3864672bd8482ab7edf419cb27dcdf2533720316979b7f5cc5a53a5",
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
"architecture": "x64",
|
|
10
10
|
"target": "x86_64-unknown-linux-gnu",
|
|
11
11
|
"capability": "supported",
|
|
12
|
-
"builtAt": "2026-10-
|
|
12
|
+
"builtAt": "2026-10-20T08:55:32.085Z",
|
|
13
13
|
"artifact": {
|
|
14
14
|
"filename": "terminal-host.node",
|
|
15
|
-
"sha256": "
|
|
16
|
-
"size":
|
|
15
|
+
"sha256": "5c7b589cd36b901a4a02d172f84d70111f7f4cec5ad796a6ea13524109fa4b50",
|
|
16
|
+
"size": 6988960
|
|
17
17
|
},
|
|
18
18
|
"entry": {
|
|
19
19
|
"filename": "dist/foundation/resident-tabs/host-entry.js",
|
|
Binary file
|