@kortix/sdk 0.12.8 → 0.13.1
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/README.md +3 -6
- package/dist/browser/session-sync/session-sync-registry.d.ts +7 -2
- package/dist/browser/session-sync/session-sync-registry.d.ts.map +1 -1
- package/dist/browser/session-sync/session-sync-registry.js +33 -44
- package/dist/browser/session-sync/session-sync-registry.js.map +1 -1
- package/dist/browser/session-sync/session-transcript-cache.d.ts +9 -2
- package/dist/browser/session-sync/session-transcript-cache.d.ts.map +1 -1
- package/dist/browser/session-sync/session-transcript-cache.js +15 -5
- package/dist/browser/session-sync/session-transcript-cache.js.map +1 -1
- package/dist/browser/stores/opencode-compaction-store.d.ts +9 -3
- package/dist/browser/stores/opencode-compaction-store.d.ts.map +1 -1
- package/dist/browser/stores/opencode-compaction-store.js +5 -12
- package/dist/browser/stores/opencode-compaction-store.js.map +1 -1
- package/dist/browser/stores/sandbox-connection-store.d.ts +28 -17
- package/dist/browser/stores/sandbox-connection-store.d.ts.map +1 -1
- package/dist/browser/stores/sandbox-connection-store.js +32 -84
- package/dist/browser/stores/sandbox-connection-store.js.map +1 -1
- package/dist/browser/stores/session-working-store.d.ts +73 -0
- package/dist/browser/stores/session-working-store.d.ts.map +1 -0
- package/dist/browser/stores/session-working-store.js +86 -0
- package/dist/browser/stores/session-working-store.js.map +1 -0
- package/dist/browser/stores/sync-store/types.d.ts +14 -4
- package/dist/browser/stores/sync-store/types.d.ts.map +1 -1
- package/dist/browser/stores/sync-store.d.ts +179 -4
- package/dist/browser/stores/sync-store.d.ts.map +1 -1
- package/dist/browser/stores/sync-store.js +777 -65
- package/dist/browser/stores/sync-store.js.map +1 -1
- package/dist/core/client/kortix.d.ts +95 -0
- package/dist/core/client/kortix.d.ts.map +1 -1
- package/dist/core/client/kortix.js +78 -0
- package/dist/core/client/kortix.js.map +1 -1
- package/dist/core/files/client.d.ts +50 -2
- package/dist/core/files/client.d.ts.map +1 -1
- package/dist/core/files/client.js +253 -44
- package/dist/core/files/client.js.map +1 -1
- package/dist/core/files/types.d.ts +11 -0
- package/dist/core/files/types.d.ts.map +1 -1
- package/dist/core/http/abort-error.d.ts +89 -0
- package/dist/core/http/abort-error.d.ts.map +1 -0
- package/dist/core/http/abort-error.js +190 -0
- package/dist/core/http/abort-error.js.map +1 -0
- package/dist/core/http/api-client.d.ts.map +1 -1
- package/dist/core/http/api-client.js +18 -4
- package/dist/core/http/api-client.js.map +1 -1
- package/dist/core/http/opencode-errors.d.ts +7 -0
- package/dist/core/http/opencode-errors.d.ts.map +1 -1
- package/dist/core/http/opencode-errors.js +45 -13
- package/dist/core/http/opencode-errors.js.map +1 -1
- package/dist/core/rest/platform-client/github-app.d.ts +13 -0
- package/dist/core/rest/platform-client/github-app.d.ts.map +1 -1
- package/dist/core/rest/platform-client/github-app.js +2 -0
- package/dist/core/rest/platform-client/github-app.js.map +1 -1
- package/dist/core/rest/platform-client/members.d.ts +10 -64
- package/dist/core/rest/platform-client/members.d.ts.map +1 -1
- package/dist/core/rest/platform-client/members.js +10 -28
- package/dist/core/rest/platform-client/members.js.map +1 -1
- package/dist/core/rest/projects-client/accounts.d.ts +30 -5
- package/dist/core/rest/projects-client/accounts.d.ts.map +1 -1
- package/dist/core/rest/projects-client/accounts.js +1 -1
- package/dist/core/rest/projects-client/accounts.js.map +1 -1
- package/dist/core/rest/projects-client/apps.d.ts +13 -0
- package/dist/core/rest/projects-client/apps.d.ts.map +1 -1
- package/dist/core/rest/projects-client/apps.js.map +1 -1
- package/dist/core/rest/projects-client/assignments.d.ts +114 -0
- package/dist/core/rest/projects-client/assignments.d.ts.map +1 -0
- package/dist/core/rest/projects-client/assignments.js +91 -0
- package/dist/core/rest/projects-client/assignments.js.map +1 -0
- package/dist/core/rest/projects-client/billing.d.ts +10 -1
- package/dist/core/rest/projects-client/billing.d.ts.map +1 -1
- package/dist/core/rest/projects-client/billing.js +11 -2
- package/dist/core/rest/projects-client/billing.js.map +1 -1
- package/dist/core/rest/projects-client/connectors.d.ts +69 -1
- package/dist/core/rest/projects-client/connectors.d.ts.map +1 -1
- package/dist/core/rest/projects-client/connectors.js +17 -0
- package/dist/core/rest/projects-client/connectors.js.map +1 -1
- package/dist/core/rest/projects-client/files.js +2 -2
- package/dist/core/rest/projects-client/files.js.map +1 -1
- package/dist/core/rest/projects-client/gateway.d.ts +51 -0
- package/dist/core/rest/projects-client/gateway.d.ts.map +1 -1
- package/dist/core/rest/projects-client/gateway.js.map +1 -1
- package/dist/core/rest/projects-client/iam.d.ts +51 -3
- package/dist/core/rest/projects-client/iam.d.ts.map +1 -1
- package/dist/core/rest/projects-client/iam.js +18 -1
- package/dist/core/rest/projects-client/iam.js.map +1 -1
- package/dist/core/rest/projects-client/index.d.ts +1 -0
- package/dist/core/rest/projects-client/index.d.ts.map +1 -1
- package/dist/core/rest/projects-client/index.js +1 -0
- package/dist/core/rest/projects-client/index.js.map +1 -1
- package/dist/core/rest/projects-client/projects.d.ts +1 -1
- package/dist/core/rest/projects-client/projects.d.ts.map +1 -1
- package/dist/core/rest/projects-client/projects.js +2 -0
- package/dist/core/rest/projects-client/projects.js.map +1 -1
- package/dist/core/rest/projects-client/secrets.d.ts +19 -1
- package/dist/core/rest/projects-client/secrets.d.ts.map +1 -1
- package/dist/core/rest/projects-client/secrets.js +1 -1
- package/dist/core/rest/projects-client/secrets.js.map +1 -1
- package/dist/core/rest/projects-client/session-costs.d.ts +33 -0
- package/dist/core/rest/projects-client/session-costs.d.ts.map +1 -1
- package/dist/core/rest/projects-client/session-costs.js.map +1 -1
- package/dist/core/rest/projects-client/sessions.d.ts +261 -2
- package/dist/core/rest/projects-client/sessions.d.ts.map +1 -1
- package/dist/core/rest/projects-client/sessions.js +106 -4
- package/dist/core/rest/projects-client/sessions.js.map +1 -1
- package/dist/core/rest/projects-client/shared.d.ts +10 -1
- package/dist/core/rest/projects-client/shared.d.ts.map +1 -1
- package/dist/core/rest/projects-client/shared.js.map +1 -1
- package/dist/core/rest/projects-client/tokens.d.ts +13 -1
- package/dist/core/rest/projects-client/tokens.d.ts.map +1 -1
- package/dist/core/rest/projects-client/tokens.js +7 -2
- package/dist/core/rest/projects-client/tokens.js.map +1 -1
- package/dist/core/rest/projects-client/triggers.d.ts +69 -2
- package/dist/core/rest/projects-client/triggers.d.ts.map +1 -1
- package/dist/core/rest/projects-client/triggers.js +1 -1
- package/dist/core/rest/projects-client/triggers.js.map +1 -1
- package/dist/core/session/compaction.d.ts +98 -0
- package/dist/core/session/compaction.d.ts.map +1 -0
- package/dist/core/session/compaction.js +108 -0
- package/dist/core/session/compaction.js.map +1 -0
- package/dist/core/session/health.d.ts +22 -0
- package/dist/core/session/health.d.ts.map +1 -1
- package/dist/core/session/health.js +31 -5
- package/dist/core/session/health.js.map +1 -1
- package/dist/core/session/index.d.ts +2 -0
- package/dist/core/session/index.d.ts.map +1 -1
- package/dist/core/session/index.js +2 -0
- package/dist/core/session/index.js.map +1 -1
- package/dist/core/session/message-queue.d.ts +79 -15
- package/dist/core/session/message-queue.d.ts.map +1 -1
- package/dist/core/session/message-queue.js +73 -27
- package/dist/core/session/message-queue.js.map +1 -1
- package/dist/core/session/rewind.d.ts +76 -10
- package/dist/core/session/rewind.d.ts.map +1 -1
- package/dist/core/session/rewind.js +68 -11
- package/dist/core/session/rewind.js.map +1 -1
- package/dist/core/session/working.d.ts +241 -0
- package/dist/core/session/working.d.ts.map +1 -0
- package/dist/core/session/working.js +261 -0
- package/dist/core/session/working.js.map +1 -0
- package/dist/core/session-sync/session-sync-controller.d.ts +35 -20
- package/dist/core/session-sync/session-sync-controller.d.ts.map +1 -1
- package/dist/core/session-sync/session-sync-controller.js +48 -115
- package/dist/core/session-sync/session-sync-controller.js.map +1 -1
- package/dist/core/stream/event-stream.d.ts +22 -0
- package/dist/core/stream/event-stream.d.ts.map +1 -1
- package/dist/core/stream/event-stream.js +132 -36
- package/dist/core/stream/event-stream.js.map +1 -1
- package/dist/core/turns/grouping.d.ts +18 -2
- package/dist/core/turns/grouping.d.ts.map +1 -1
- package/dist/core/turns/grouping.js +45 -2
- package/dist/core/turns/grouping.js.map +1 -1
- package/dist/core/turns/index.d.ts +1 -0
- package/dist/core/turns/index.d.ts.map +1 -1
- package/dist/core/turns/index.js +1 -0
- package/dist/core/turns/index.js.map +1 -1
- package/dist/core/turns/open-turn.d.ts +81 -0
- package/dist/core/turns/open-turn.d.ts.map +1 -0
- package/dist/core/turns/open-turn.js +77 -0
- package/dist/core/turns/open-turn.js.map +1 -0
- package/dist/core/turns/state.js +26 -26
- package/dist/core/turns/state.js.map +1 -1
- package/dist/core/turns/types.d.ts +5 -0
- package/dist/core/turns/types.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/kortix.esm.min.js +25 -25
- package/dist/kortix.global.js +25 -25
- package/dist/node/server.d.ts.map +1 -1
- package/dist/node/server.js +14 -2
- package/dist/node/server.js.map +1 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +7 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/initial-session-pin.d.ts +17 -0
- package/dist/react/initial-session-pin.d.ts.map +1 -1
- package/dist/react/initial-session-pin.js +58 -0
- package/dist/react/initial-session-pin.js.map +1 -1
- package/dist/react/opencode.d.ts +6 -2
- package/dist/react/opencode.d.ts.map +1 -1
- package/dist/react/opencode.js +5 -1
- package/dist/react/opencode.js.map +1 -1
- package/dist/react/prefetch-session-start.d.ts +10 -4
- package/dist/react/prefetch-session-start.d.ts.map +1 -1
- package/dist/react/prefetch-session-start.js +10 -4
- package/dist/react/prefetch-session-start.js.map +1 -1
- package/dist/react/query-contracts.d.ts +2 -0
- package/dist/react/query-contracts.d.ts.map +1 -1
- package/dist/react/query-contracts.js +2 -0
- package/dist/react/query-contracts.js.map +1 -1
- package/dist/react/query-keys.d.ts +13 -2
- package/dist/react/query-keys.d.ts.map +1 -1
- package/dist/react/query-keys.js +13 -2
- package/dist/react/query-keys.js.map +1 -1
- package/dist/react/session-start-stash.d.ts +25 -0
- package/dist/react/session-start-stash.d.ts.map +1 -1
- package/dist/react/session-start-stash.js +34 -3
- package/dist/react/session-start-stash.js.map +1 -1
- package/dist/react/session-title-sync.d.ts +5 -1
- package/dist/react/session-title-sync.d.ts.map +1 -1
- package/dist/react/session-title-sync.js +16 -4
- package/dist/react/session-title-sync.js.map +1 -1
- package/dist/react/use-can.d.ts +105 -0
- package/dist/react/use-can.d.ts.map +1 -0
- package/dist/react/use-can.js +190 -0
- package/dist/react/use-can.js.map +1 -0
- package/dist/react/use-canonical-opencode-session.d.ts +6 -1
- package/dist/react/use-canonical-opencode-session.d.ts.map +1 -1
- package/dist/react/use-canonical-opencode-session.js +46 -3
- package/dist/react/use-canonical-opencode-session.js.map +1 -1
- package/dist/react/use-opencode-events/handle-event.d.ts +10 -0
- package/dist/react/use-opencode-events/handle-event.d.ts.map +1 -1
- package/dist/react/use-opencode-events/handle-event.js +76 -7
- package/dist/react/use-opencode-events/handle-event.js.map +1 -1
- package/dist/react/use-opencode-events/helpers.d.ts +21 -8
- package/dist/react/use-opencode-events/helpers.d.ts.map +1 -1
- package/dist/react/use-opencode-events/helpers.js +25 -26
- package/dist/react/use-opencode-events/helpers.js.map +1 -1
- package/dist/react/use-opencode-events/index.d.ts.map +1 -1
- package/dist/react/use-opencode-events/index.js +43 -26
- package/dist/react/use-opencode-events/index.js.map +1 -1
- package/dist/react/use-opencode-events/use-event-stream-refs.d.ts.map +1 -1
- package/dist/react/use-opencode-events/use-event-stream-refs.js +66 -3
- package/dist/react/use-opencode-events/use-event-stream-refs.js.map +1 -1
- package/dist/react/use-opencode-local.d.ts +17 -0
- package/dist/react/use-opencode-local.d.ts.map +1 -1
- package/dist/react/use-opencode-local.js +41 -7
- package/dist/react/use-opencode-local.js.map +1 -1
- package/dist/react/use-opencode-sessions/messages.d.ts +101 -1
- package/dist/react/use-opencode-sessions/messages.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/messages.js +481 -63
- package/dist/react/use-opencode-sessions/messages.js.map +1 -1
- package/dist/react/use-project-apps.d.ts +24 -1
- package/dist/react/use-project-apps.d.ts.map +1 -1
- package/dist/react/use-project-apps.js +5 -3
- package/dist/react/use-project-apps.js.map +1 -1
- package/dist/react/use-runtime-boot-stalled.d.ts +32 -0
- package/dist/react/use-runtime-boot-stalled.d.ts.map +1 -0
- package/dist/react/use-runtime-boot-stalled.js +48 -0
- package/dist/react/use-runtime-boot-stalled.js.map +1 -0
- package/dist/react/use-runtime-reconnect.d.ts +67 -1
- package/dist/react/use-runtime-reconnect.d.ts.map +1 -1
- package/dist/react/use-runtime-reconnect.js +116 -18
- package/dist/react/use-runtime-reconnect.js.map +1 -1
- package/dist/react/use-session-prompts.d.ts +113 -0
- package/dist/react/use-session-prompts.d.ts.map +1 -0
- package/dist/react/use-session-prompts.js +250 -0
- package/dist/react/use-session-prompts.js.map +1 -0
- package/dist/react/use-session-send.d.ts +169 -20
- package/dist/react/use-session-send.d.ts.map +1 -1
- package/dist/react/use-session-send.js +183 -30
- package/dist/react/use-session-send.js.map +1 -1
- package/dist/react/use-session-sync.d.ts +35 -2
- package/dist/react/use-session-sync.d.ts.map +1 -1
- package/dist/react/use-session-sync.js +49 -11
- package/dist/react/use-session-sync.js.map +1 -1
- package/dist/react/use-session-working.d.ts +57 -0
- package/dist/react/use-session-working.d.ts.map +1 -0
- package/dist/react/use-session-working.js +178 -0
- package/dist/react/use-session-working.js.map +1 -0
- package/dist/react/use-session.d.ts +131 -5
- package/dist/react/use-session.d.ts.map +1 -1
- package/dist/react/use-session.js +358 -69
- package/dist/react/use-session.js.map +1 -1
- package/package.json +2 -2
- package/dist/browser/stores/tab-store.d.ts +0 -91
- package/dist/browser/stores/tab-store.d.ts.map +0 -1
- package/dist/browser/stores/tab-store.js +0 -369
- package/dist/browser/stores/tab-store.js.map +0 -1
- package/dist/core/session/send-queue.d.ts +0 -70
- package/dist/core/session/send-queue.d.ts.map +0 -1
- package/dist/core/session/send-queue.js +0 -116
- package/dist/core/session/send-queue.js.map +0 -1
|
@@ -5,7 +5,6 @@ import { logger } from "../../core/http/logger.js";
|
|
|
5
5
|
// blocking overlay. By persisting it, users who were previously connected
|
|
6
6
|
// see the lightweight reconnect pill instead, making reconnection feel instant.
|
|
7
7
|
const STORAGE_KEY = "kortix-runtime-was-connected";
|
|
8
|
-
const PROVISION_VERIFIED_KEY = "kortix-runtime-provision-verified";
|
|
9
8
|
// Stronger than PROVISION_VERIFIED: POST /start already resolved stage='ready',
|
|
10
9
|
// which the backend only returns once it reached the daemon's /session (runtime
|
|
11
10
|
// proven healthy server-side). When this flag is set, the new instance starts
|
|
@@ -33,22 +32,6 @@ function saveWasConnected(value) {
|
|
|
33
32
|
/* SSR or storage unavailable */
|
|
34
33
|
}
|
|
35
34
|
}
|
|
36
|
-
function loadProvisionVerified() {
|
|
37
|
-
try {
|
|
38
|
-
return sessionStorage.getItem(PROVISION_VERIFIED_KEY) === "1";
|
|
39
|
-
}
|
|
40
|
-
catch {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
function clearProvisionVerified() {
|
|
45
|
-
try {
|
|
46
|
-
sessionStorage.removeItem(PROVISION_VERIFIED_KEY);
|
|
47
|
-
}
|
|
48
|
-
catch {
|
|
49
|
-
/* SSR or storage unavailable */
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
35
|
function loadRuntimeReadyVerified() {
|
|
53
36
|
try {
|
|
54
37
|
return sessionStorage.getItem(RUNTIME_READY_VERIFIED_KEY) === "1";
|
|
@@ -68,23 +51,24 @@ function clearRuntimeReadyVerified() {
|
|
|
68
51
|
export const useSandboxConnectionStore = create(() => ({
|
|
69
52
|
status: "connecting",
|
|
70
53
|
failCount: 0,
|
|
71
|
-
lastConnectedAt: null,
|
|
72
54
|
initialCheckDone: false,
|
|
73
55
|
wasConnected: loadWasConnected(),
|
|
74
56
|
reconnectAttempts: 0,
|
|
75
57
|
disconnectedAt: null,
|
|
76
|
-
sandboxVersion: null,
|
|
77
58
|
openCodeVersion: null,
|
|
78
59
|
healthy: null,
|
|
79
60
|
runtimeError: null,
|
|
80
|
-
recoveryPhase: "idle",
|
|
81
|
-
restartRequestedAt: null,
|
|
82
61
|
manualRetryNonce: 0,
|
|
62
|
+
lastRuntimeEvidenceAt: null,
|
|
63
|
+
bootingSinceAt: null,
|
|
83
64
|
}));
|
|
84
65
|
export function requestRuntimeReconnect() {
|
|
85
66
|
useSandboxConnectionStore.setState((state) => ({
|
|
86
67
|
status: "connecting", healthy: null, failCount: 0, runtimeError: null,
|
|
87
68
|
disconnectedAt: state.disconnectedAt ?? Date.now(), manualRetryNonce: state.manualRetryNonce + 1,
|
|
69
|
+
// A manual retry is the user's own reset — give the stall clock a fresh
|
|
70
|
+
// start too, instead of it re-firing on the very next tick.
|
|
71
|
+
bootingSinceAt: Date.now(),
|
|
88
72
|
}));
|
|
89
73
|
}
|
|
90
74
|
// ── Static actions (stable references, no re-render loops) ──
|
|
@@ -95,13 +79,10 @@ export function setSandboxStatus(next) {
|
|
|
95
79
|
return;
|
|
96
80
|
const updates = { status: next };
|
|
97
81
|
if (next === "connected") {
|
|
98
|
-
updates.lastConnectedAt = Date.now();
|
|
99
82
|
updates.failCount = 0;
|
|
100
83
|
updates.wasConnected = true;
|
|
101
84
|
updates.reconnectAttempts = 0;
|
|
102
85
|
updates.disconnectedAt = null;
|
|
103
|
-
updates.recoveryPhase = "idle";
|
|
104
|
-
updates.restartRequestedAt = null;
|
|
105
86
|
saveWasConnected(true);
|
|
106
87
|
if (state.status === "unreachable") {
|
|
107
88
|
logger.info("Sandbox connection restored", {
|
|
@@ -155,15 +136,13 @@ export function resetSandboxFail() {
|
|
|
155
136
|
* instance starts fresh. Without this, `wasConnected` from a previous instance
|
|
156
137
|
* leaks into the new one, causing wrong thresholds and stale UI.
|
|
157
138
|
*
|
|
158
|
-
* Exception: if
|
|
159
|
-
*
|
|
160
|
-
*
|
|
139
|
+
* Exception: if POST /start already proved the runtime ready
|
|
140
|
+
* (`markRuntimeReadyVerified`), we start connected+healthy so the chat
|
|
141
|
+
* subscribes at the switch instead of after one more client health RTT.
|
|
161
142
|
*/
|
|
162
143
|
export function resetForServerSwitch() {
|
|
163
144
|
const runtimeReady = loadRuntimeReadyVerified();
|
|
164
|
-
const fromProvisioning = loadProvisionVerified();
|
|
165
145
|
clearRuntimeReadyVerified();
|
|
166
|
-
clearProvisionVerified();
|
|
167
146
|
if (runtimeReady) {
|
|
168
147
|
// /start already resolved stage==='ready' (markRuntimeReadyVerified is set
|
|
169
148
|
// ONLY then — page.tsx), which the backend returns only after it reached the
|
|
@@ -185,34 +164,12 @@ export function resetForServerSwitch() {
|
|
|
185
164
|
wasConnected: true,
|
|
186
165
|
reconnectAttempts: 0,
|
|
187
166
|
disconnectedAt: null,
|
|
188
|
-
sandboxVersion: null,
|
|
189
167
|
openCodeVersion: null,
|
|
190
168
|
healthy: true,
|
|
191
169
|
runtimeError: null,
|
|
192
|
-
recoveryPhase: "idle",
|
|
193
|
-
restartRequestedAt: null,
|
|
194
|
-
manualRetryNonce: 0,
|
|
195
|
-
});
|
|
196
|
-
saveWasConnected(true);
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
if (fromProvisioning) {
|
|
200
|
-
// Provisioning already verified health — skip the blocking overlay.
|
|
201
|
-
// The health poller will still run and correct the status if needed.
|
|
202
|
-
useSandboxConnectionStore.setState({
|
|
203
|
-
status: "connecting",
|
|
204
|
-
failCount: 0,
|
|
205
|
-
initialCheckDone: false,
|
|
206
|
-
wasConnected: true, // lightweight reconnect pill instead of blocking overlay
|
|
207
|
-
reconnectAttempts: 0,
|
|
208
|
-
disconnectedAt: null,
|
|
209
|
-
sandboxVersion: null,
|
|
210
|
-
openCodeVersion: null,
|
|
211
|
-
healthy: null,
|
|
212
|
-
runtimeError: null,
|
|
213
|
-
recoveryPhase: "idle",
|
|
214
|
-
restartRequestedAt: null,
|
|
215
170
|
manualRetryNonce: 0,
|
|
171
|
+
lastRuntimeEvidenceAt: null,
|
|
172
|
+
bootingSinceAt: null,
|
|
216
173
|
});
|
|
217
174
|
saveWasConnected(true);
|
|
218
175
|
return;
|
|
@@ -224,40 +181,25 @@ export function resetForServerSwitch() {
|
|
|
224
181
|
wasConnected: false,
|
|
225
182
|
reconnectAttempts: 0,
|
|
226
183
|
disconnectedAt: null,
|
|
227
|
-
sandboxVersion: null,
|
|
228
184
|
openCodeVersion: null,
|
|
229
185
|
healthy: null,
|
|
230
186
|
runtimeError: null,
|
|
231
|
-
recoveryPhase: "idle",
|
|
232
|
-
restartRequestedAt: null,
|
|
233
187
|
manualRetryNonce: 0,
|
|
188
|
+
lastRuntimeEvidenceAt: null,
|
|
189
|
+
bootingSinceAt: Date.now(),
|
|
234
190
|
});
|
|
235
191
|
saveWasConnected(false);
|
|
236
192
|
}
|
|
237
|
-
export function markRecoveryRequested(phase) {
|
|
238
|
-
const now = Date.now();
|
|
239
|
-
useSandboxConnectionStore.setState((state) => ({
|
|
240
|
-
recoveryPhase: phase,
|
|
241
|
-
restartRequestedAt: now,
|
|
242
|
-
status: state.status === "connected" ? "connecting" : state.status,
|
|
243
|
-
disconnectedAt: state.disconnectedAt ?? now,
|
|
244
|
-
}));
|
|
245
|
-
}
|
|
246
|
-
export function markHostRestartRequested() {
|
|
247
|
-
markRecoveryRequested("restarting_host");
|
|
248
|
-
}
|
|
249
193
|
/**
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
194
|
+
* Record that a live SSE event from the active runtime just arrived. Cheap and
|
|
195
|
+
* called per event, so it only writes when the timestamp actually moves the
|
|
196
|
+
* freshness window (>= 1s granularity keeps store notifications rare).
|
|
253
197
|
*/
|
|
254
|
-
export function
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
/* SSR or storage unavailable */
|
|
260
|
-
}
|
|
198
|
+
export function noteRuntimeEvidence(at = Date.now()) {
|
|
199
|
+
const previous = useSandboxConnectionStore.getState().lastRuntimeEvidenceAt;
|
|
200
|
+
if (previous !== null && at - previous < 1_000)
|
|
201
|
+
return;
|
|
202
|
+
useSandboxConnectionStore.setState({ lastRuntimeEvidenceAt: at });
|
|
261
203
|
}
|
|
262
204
|
/**
|
|
263
205
|
* Called right before switching to a sandbox whose POST /start already returned
|
|
@@ -273,12 +215,6 @@ export function markRuntimeReadyVerified() {
|
|
|
273
215
|
/* SSR or storage unavailable */
|
|
274
216
|
}
|
|
275
217
|
}
|
|
276
|
-
export function setSandboxVersion(version) {
|
|
277
|
-
const current = useSandboxConnectionStore.getState().sandboxVersion;
|
|
278
|
-
if (current === version)
|
|
279
|
-
return;
|
|
280
|
-
useSandboxConnectionStore.setState({ sandboxVersion: version });
|
|
281
|
-
}
|
|
282
218
|
export function setOpenCodeHealth(healthy, version, runtimeError) {
|
|
283
219
|
const state = useSandboxConnectionStore.getState();
|
|
284
220
|
const updates = {};
|
|
@@ -293,6 +229,18 @@ export function setOpenCodeHealth(healthy, version, runtimeError) {
|
|
|
293
229
|
else if (healthy && state.runtimeError !== null) {
|
|
294
230
|
updates.runtimeError = null;
|
|
295
231
|
}
|
|
232
|
+
// Start (or keep) the stall clock while not healthy; clear it the instant
|
|
233
|
+
// we are. A "booting" 503 classification resets `failCount` on every tick
|
|
234
|
+
// (see `use-runtime-reconnect`'s `classifyProbeResult`), so it can repeat
|
|
235
|
+
// forever without ever crossing the unreachable threshold — this clock is
|
|
236
|
+
// the only thing that still bounds that case. See `bootingSinceAt`.
|
|
237
|
+
if (healthy) {
|
|
238
|
+
if (state.bootingSinceAt !== null)
|
|
239
|
+
updates.bootingSinceAt = null;
|
|
240
|
+
}
|
|
241
|
+
else if (state.bootingSinceAt === null) {
|
|
242
|
+
updates.bootingSinceAt = Date.now();
|
|
243
|
+
}
|
|
296
244
|
if (Object.keys(updates).length > 0) {
|
|
297
245
|
useSandboxConnectionStore.setState(updates);
|
|
298
246
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox-connection-store.js","sourceRoot":"","sources":["../../../src/browser/stores/sandbox-connection-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"sandbox-connection-store.js","sourceRoot":"","sources":["../../../src/browser/stores/sandbox-connection-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { AbortReceipt, SendReceipt, WorkingInboxInput } from '../../core/session/working.js';
|
|
2
|
+
/**
|
|
3
|
+
* The LOCAL-ISH inputs to `projectWorking`, one set per Kortix session.
|
|
4
|
+
*
|
|
5
|
+
* They live in a store rather than in each caller's `useState` because more
|
|
6
|
+
* than one place mounts `useSessionWorking` for the same session — `useSession`
|
|
7
|
+
* on the route, the composer, the session panel — and they all share one
|
|
8
|
+
* react-query cache entry for `GET .../turn`. When each held its own receipt,
|
|
9
|
+
* the observer WITHOUT one polled on its own timer, wrote an uninformed "no
|
|
10
|
+
* turns" read into that shared entry, and defeated the receipt the other one
|
|
11
|
+
* was standing on: the composer flipped Stop back to Send mid-send. One set of
|
|
12
|
+
* inputs per session is what makes "one answer" true for every mount point.
|
|
13
|
+
*
|
|
14
|
+
* Nothing here is authority. Every field is bounded by the projection
|
|
15
|
+
* (`OPTIMISTIC_RECEIPT_MAX_MS`, `OPTIMISTIC_ABORT_MAX_MS`,
|
|
16
|
+
* `INBOX_OBSERVATION_MAX_MS`), so a stale entry ages out rather than latching.
|
|
17
|
+
*/
|
|
18
|
+
interface SessionWorkingState {
|
|
19
|
+
/** Keyed by KORTIX session id — the id `GET .../turn` is addressed by, not
|
|
20
|
+
* the OpenCode wire id the sync store uses. */
|
|
21
|
+
receipts: Record<string, SendReceipt | null>;
|
|
22
|
+
aborts: Record<string, AbortReceipt>;
|
|
23
|
+
inbox: Record<string, WorkingInboxInput>;
|
|
24
|
+
/** Record that a prompt just left this tab. Replaces any previous receipt:
|
|
25
|
+
* the newest send is the one the UI is standing on. Also releases any
|
|
26
|
+
* pending stop — sending is the user saying they are not stopping. */
|
|
27
|
+
noteSendReceipt: (sessionId: string, receipt: {
|
|
28
|
+
messageId: string;
|
|
29
|
+
atMs: number;
|
|
30
|
+
}) => void;
|
|
31
|
+
/** The server durably accepted `messageId`. Ignored when a NEWER send has
|
|
32
|
+
* already replaced the receipt — otherwise the old response would release a
|
|
33
|
+
* receipt for a send it knows nothing about. */
|
|
34
|
+
acceptSendReceipt: (sessionId: string, messageId: string, atMs: number) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Nothing is coming: a refused send, Stop, or leaving the session.
|
|
37
|
+
*
|
|
38
|
+
* `messageId` names the send being dropped, and is required of every caller
|
|
39
|
+
* that HAS one, for the same reason `acceptSendReceipt` checks it: a
|
|
40
|
+
* `/compact` rejected at T+600ms used to delete the receipt of an ordinary
|
|
41
|
+
* prompt submitted at T+500ms whose POST was still on the wire, and an
|
|
42
|
+
* uninformed `/turn` read then flipped the composer back to Send mid-send.
|
|
43
|
+
* Omit it only where nothing is coming for ANY send — Stop, unmount.
|
|
44
|
+
*/
|
|
45
|
+
clearSendReceipt: (sessionId: string, messageId?: string) => void;
|
|
46
|
+
/**
|
|
47
|
+
* Record that this tab asked the running turn to end. Keeps the FIRST
|
|
48
|
+
* instant while a stop is still unsettled: two paths issue the same cancel
|
|
49
|
+
* (the SDK's `cancel()` and the host's `issueSessionCancel`) and restamping
|
|
50
|
+
* would extend the bar every time either one fired again.
|
|
51
|
+
*/
|
|
52
|
+
noteAbortReceipt: (sessionId: string, atMs: number) => void;
|
|
53
|
+
/** The server acknowledged the cancel. Stamped once — the first
|
|
54
|
+
* acknowledgement is the one a server read can be measured against. */
|
|
55
|
+
settleAbortReceipt: (sessionId: string, atMs: number) => void;
|
|
56
|
+
/** One reading of the durable prompt inbox, stamped at ISSUE time. */
|
|
57
|
+
noteInboxPending: (sessionId: string, pending: number, atMs: number) => void;
|
|
58
|
+
/** `POST .../prompts` returned: the row EXISTS, and the server said so. Raise
|
|
59
|
+
* the inbox floor to at least one pending row, covering the gap between that
|
|
60
|
+
* response and the list query refetching — a `/turn` poll landing in that gap
|
|
61
|
+
* answers "no turns" honestly and used to flip the composer back to Send with
|
|
62
|
+
* the user's prompt already queued. */
|
|
63
|
+
notePromptAccepted: (sessionId: string, atMs: number) => void;
|
|
64
|
+
/** Drop every input this session holds. Called by `useSessionWorking` when
|
|
65
|
+
* the LAST observer of the session unmounts — the maps otherwise accumulate
|
|
66
|
+
* one entry per session visited for the tab's lifetime. Correctness never
|
|
67
|
+
* depended on it (every field is bounded), this is leak hygiene. */
|
|
68
|
+
clearSession: (sessionId: string) => void;
|
|
69
|
+
reset: () => void;
|
|
70
|
+
}
|
|
71
|
+
export declare const useSessionWorkingStore: import("zustand").UseBoundStore<import("zustand").StoreApi<SessionWorkingState>>;
|
|
72
|
+
export {};
|
|
73
|
+
//# sourceMappingURL=session-working-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-working-store.d.ts","sourceRoot":"","sources":["../../../src/browser/stores/session-working-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAE/F;;;;;;;;;;;;;;;GAeG;AACH,UAAU,mBAAmB;IAC3B;oDACgD;IAChD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC,CAAC;IAC7C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAEzC;;2EAEuE;IACvE,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3F;;qDAEiD;IACjD,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChF;;;;;;;;;OASG;IACH,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAClE;;;;;OAKG;IACH,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5D;4EACwE;IACxE,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,sEAAsE;IACtE,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7E;;;;4CAIwC;IACxC,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D;;;yEAGqE;IACrE,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,eAAO,MAAM,sBAAsB,kFA0FhC,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { create } from 'zustand';
|
|
3
|
+
export const useSessionWorkingStore = create()((set) => ({
|
|
4
|
+
receipts: {},
|
|
5
|
+
aborts: {},
|
|
6
|
+
inbox: {},
|
|
7
|
+
noteSendReceipt: (sessionId, receipt) => set((state) => {
|
|
8
|
+
if (!sessionId)
|
|
9
|
+
return state;
|
|
10
|
+
const { [sessionId]: _stopped, ...aborts } = state.aborts;
|
|
11
|
+
return {
|
|
12
|
+
receipts: {
|
|
13
|
+
...state.receipts,
|
|
14
|
+
[sessionId]: { messageId: receipt.messageId, atMs: receipt.atMs, acceptedAtMs: null },
|
|
15
|
+
},
|
|
16
|
+
// A send releases the stop. Leaving it would bar `/turn` from reporting
|
|
17
|
+
// the turn this very send is about to start.
|
|
18
|
+
aborts,
|
|
19
|
+
};
|
|
20
|
+
}),
|
|
21
|
+
acceptSendReceipt: (sessionId, messageId, atMs) => set((state) => {
|
|
22
|
+
const current = state.receipts[sessionId];
|
|
23
|
+
if (!current || current.messageId !== messageId || current.acceptedAtMs != null) {
|
|
24
|
+
return state;
|
|
25
|
+
}
|
|
26
|
+
return { receipts: { ...state.receipts, [sessionId]: { ...current, acceptedAtMs: atMs } } };
|
|
27
|
+
}),
|
|
28
|
+
clearSendReceipt: (sessionId, messageId) => set((state) => {
|
|
29
|
+
const current = state.receipts[sessionId];
|
|
30
|
+
if (!(sessionId in state.receipts))
|
|
31
|
+
return state;
|
|
32
|
+
if (messageId !== undefined && current?.messageId !== messageId)
|
|
33
|
+
return state;
|
|
34
|
+
const { [sessionId]: _dropped, ...rest } = state.receipts;
|
|
35
|
+
return { receipts: rest };
|
|
36
|
+
}),
|
|
37
|
+
noteAbortReceipt: (sessionId, atMs) => set((state) => {
|
|
38
|
+
if (!sessionId)
|
|
39
|
+
return state;
|
|
40
|
+
const current = state.aborts[sessionId];
|
|
41
|
+
if (current && current.settledAtMs == null)
|
|
42
|
+
return state;
|
|
43
|
+
return { aborts: { ...state.aborts, [sessionId]: { atMs, settledAtMs: null } } };
|
|
44
|
+
}),
|
|
45
|
+
settleAbortReceipt: (sessionId, atMs) => set((state) => {
|
|
46
|
+
const current = state.aborts[sessionId];
|
|
47
|
+
if (!current || current.settledAtMs != null)
|
|
48
|
+
return state;
|
|
49
|
+
return { aborts: { ...state.aborts, [sessionId]: { ...current, settledAtMs: atMs } } };
|
|
50
|
+
}),
|
|
51
|
+
noteInboxPending: (sessionId, pending, atMs) => set((state) => {
|
|
52
|
+
if (!sessionId)
|
|
53
|
+
return state;
|
|
54
|
+
const current = state.inbox[sessionId];
|
|
55
|
+
// Readings settle in whatever order the network gives them; only the
|
|
56
|
+
// newest OBSERVATION may stand, or a late older one would walk the
|
|
57
|
+
// projection backwards.
|
|
58
|
+
if (current && current.atMs > atMs)
|
|
59
|
+
return state;
|
|
60
|
+
if (current && current.atMs === atMs && current.pending === pending)
|
|
61
|
+
return state;
|
|
62
|
+
return { inbox: { ...state.inbox, [sessionId]: { pending, atMs } } };
|
|
63
|
+
}),
|
|
64
|
+
notePromptAccepted: (sessionId, atMs) => set((state) => {
|
|
65
|
+
if (!sessionId)
|
|
66
|
+
return state;
|
|
67
|
+
const current = state.inbox[sessionId];
|
|
68
|
+
if (current && current.atMs > atMs)
|
|
69
|
+
return state;
|
|
70
|
+
const pending = Math.max(1, current?.pending ?? 0);
|
|
71
|
+
return { inbox: { ...state.inbox, [sessionId]: { pending, atMs } } };
|
|
72
|
+
}),
|
|
73
|
+
clearSession: (sessionId) => set((state) => {
|
|
74
|
+
if (!(sessionId in state.receipts) &&
|
|
75
|
+
!(sessionId in state.aborts) &&
|
|
76
|
+
!(sessionId in state.inbox)) {
|
|
77
|
+
return state;
|
|
78
|
+
}
|
|
79
|
+
const { [sessionId]: _r, ...receipts } = state.receipts;
|
|
80
|
+
const { [sessionId]: _a, ...aborts } = state.aborts;
|
|
81
|
+
const { [sessionId]: _i, ...inbox } = state.inbox;
|
|
82
|
+
return { receipts, aborts, inbox };
|
|
83
|
+
}),
|
|
84
|
+
reset: () => set({ receipts: {}, aborts: {}, inbox: {} }),
|
|
85
|
+
}));
|
|
86
|
+
//# sourceMappingURL=session-working-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-working-store.js","sourceRoot":"","sources":["../../../src/browser/stores/session-working-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { AssistantMessage, Message, Part, SnapshotFileDiff } from "@opencode-ai/sdk/v2/client";
|
|
2
|
+
import type { AbortReason } from "../../../core/http/abort-error.js";
|
|
3
|
+
export type { SessionRewindState } from "../../../core/session/rewind.js";
|
|
2
4
|
export type FileDiff = Omit<SnapshotFileDiff, "patch"> & {
|
|
3
5
|
patch?: string;
|
|
4
6
|
before?: string;
|
|
@@ -7,15 +9,23 @@ export type FileDiff = Omit<SnapshotFileDiff, "patch"> & {
|
|
|
7
9
|
/**
|
|
8
10
|
* A locally-synthesized "operation aborted" marker — distinct from (and not
|
|
9
11
|
* present in) the opencode SDK's `AssistantMessage['error']` union. The React
|
|
10
|
-
* layer fabricates this shape
|
|
11
|
-
* real SSE event for
|
|
12
|
-
* exactly like the real wire errors, so
|
|
13
|
-
* pattern, not the SDK's exact error
|
|
12
|
+
* layer fabricates this shape both for a real user Stop and when a runtime
|
|
13
|
+
* disposes mid-stream (there's no real SSE event for either case); consumers
|
|
14
|
+
* duck-type on `.name`/`.data.message` exactly like the real wire errors, so
|
|
15
|
+
* it only needs to match that access pattern, not the SDK's exact error
|
|
16
|
+
* union.
|
|
17
|
+
*
|
|
18
|
+
* `data.reason` is the machine-readable WHY — read via `abortErrorReason`
|
|
19
|
+
* (`core/http/abort-error.ts`), which is also where the closed `AbortReason`
|
|
20
|
+
* union and its "not yet emitted" members are documented. Optional because a
|
|
21
|
+
* real wire `MessageAbortedError` (which shares this duck-typed access
|
|
22
|
+
* pattern but is a different TS type) never carries one.
|
|
14
23
|
*/
|
|
15
24
|
export interface SyntheticAbortError {
|
|
16
25
|
name: "AbortError";
|
|
17
26
|
data: {
|
|
18
27
|
message: string;
|
|
28
|
+
reason?: AbortReason;
|
|
19
29
|
};
|
|
20
30
|
}
|
|
21
31
|
/** Every shape `AssistantMessage.error` (and `session.error`'s `error`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/browser/stores/sync-store/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,gBAAgB,EAChB,OAAO,EACP,IAAI,EACJ,gBAAgB,EAChB,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/browser/stores/sync-store/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,gBAAgB,EAChB,OAAO,EACP,IAAI,EACJ,gBAAgB,EAChB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAClE,YAAY,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAIvE,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,GAAG;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,CAAC;CAChD;AAED;;0BAE0B;AAC1B,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,GAAG,mBAAmB,CAAC;AAMxF,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,IAAI,EAAE,CAAC;CACd"}
|