@rzx/ohs 1.0.3 → 1.0.4
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/frontend/index.js +161 -154
- package/dist/frontend/index.js.map +2 -2
- package/dist/index.js +35139 -57428
- package/dist/index.js.map +17 -199
- package/package.json +8 -8
package/dist/frontend/index.js
CHANGED
|
@@ -14,8 +14,17 @@ var __export = (target, all) => {
|
|
|
14
14
|
set: __exportSetter.bind(all, name)
|
|
15
15
|
});
|
|
16
16
|
};
|
|
17
|
-
var __esm = (fn, res) => () =>
|
|
18
|
-
|
|
17
|
+
var __esm = (fn, res, err) => () => {
|
|
18
|
+
if (fn)
|
|
19
|
+
try {
|
|
20
|
+
res = fn(fn = 0);
|
|
21
|
+
} catch (e) {
|
|
22
|
+
err = [e];
|
|
23
|
+
}
|
|
24
|
+
if (err)
|
|
25
|
+
throw err[0];
|
|
26
|
+
return res;
|
|
27
|
+
};
|
|
19
28
|
|
|
20
29
|
// ../frontend/src/theme/builtinThemes.ts
|
|
21
30
|
function getTheme(name) {
|
|
@@ -692,8 +701,8 @@ function parseServerCapabilities(value) {
|
|
|
692
701
|
if (!isRecord2(value.features))
|
|
693
702
|
throw new Error("features must be an object");
|
|
694
703
|
const features = {};
|
|
695
|
-
for (const [name,
|
|
696
|
-
features[name] = positiveInteger2(
|
|
704
|
+
for (const [name, version] of Object.entries(value.features)) {
|
|
705
|
+
features[name] = positiveInteger2(version, `features.${name}`);
|
|
697
706
|
}
|
|
698
707
|
const attachments = parseAttachmentTransferCapabilities(value.attachments);
|
|
699
708
|
return {
|
|
@@ -815,12 +824,12 @@ class OpenHarnessClient {
|
|
|
815
824
|
auth: false,
|
|
816
825
|
signal: options.signal
|
|
817
826
|
});
|
|
818
|
-
const
|
|
819
|
-
const compatibility = checkProtocolCompatibility(
|
|
827
|
+
const capabilities = parseServerCapabilities(value);
|
|
828
|
+
const compatibility = checkProtocolCompatibility(capabilities, options.support ?? { version: 2 });
|
|
820
829
|
if (!compatibility.compatible) {
|
|
821
|
-
throw new IncompatibleProtocolError(
|
|
830
|
+
throw new IncompatibleProtocolError(capabilities, compatibility.reason ?? "Client and server protocol versions are incompatible");
|
|
822
831
|
}
|
|
823
|
-
return
|
|
832
|
+
return capabilities;
|
|
824
833
|
}
|
|
825
834
|
async uploadAttachment(input) {
|
|
826
835
|
const headers = this.headers();
|
|
@@ -1495,9 +1504,9 @@ async function* streamServerSentEvents(open, decode = (value) => value) {
|
|
|
1495
1504
|
const frames = buffer.split(/\r?\n\r?\n/);
|
|
1496
1505
|
buffer = frames.pop() ?? "";
|
|
1497
1506
|
for (const frame of frames) {
|
|
1498
|
-
const
|
|
1499
|
-
if (
|
|
1500
|
-
yield decode(
|
|
1507
|
+
const event = parseSseFrame(frame);
|
|
1508
|
+
if (event !== undefined)
|
|
1509
|
+
yield decode(event);
|
|
1501
1510
|
}
|
|
1502
1511
|
}
|
|
1503
1512
|
buffer += decoder.decode();
|
|
@@ -1535,9 +1544,9 @@ var init_http_client = __esm(() => {
|
|
|
1535
1544
|
};
|
|
1536
1545
|
IncompatibleProtocolError = class IncompatibleProtocolError extends Error {
|
|
1537
1546
|
capabilities;
|
|
1538
|
-
constructor(
|
|
1547
|
+
constructor(capabilities, message) {
|
|
1539
1548
|
super(message);
|
|
1540
|
-
this.capabilities =
|
|
1549
|
+
this.capabilities = capabilities;
|
|
1541
1550
|
this.name = "IncompatibleProtocolError";
|
|
1542
1551
|
}
|
|
1543
1552
|
};
|
|
@@ -1661,17 +1670,17 @@ function readPayloadRecord(event, key) {
|
|
|
1661
1670
|
const value = event.payload[key];
|
|
1662
1671
|
return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
1663
1672
|
}
|
|
1664
|
-
function upsertSession(state,
|
|
1665
|
-
if (!
|
|
1673
|
+
function upsertSession(state, session) {
|
|
1674
|
+
if (!session)
|
|
1666
1675
|
return state;
|
|
1667
|
-
const bucket = cloneBucket(state.buckets[
|
|
1668
|
-
bucket.session =
|
|
1669
|
-
const sessions = { ...state.sessions, [
|
|
1676
|
+
const bucket = cloneBucket(state.buckets[session.id]);
|
|
1677
|
+
bucket.session = session;
|
|
1678
|
+
const sessions = { ...state.sessions, [session.id]: session };
|
|
1670
1679
|
return {
|
|
1671
1680
|
...state,
|
|
1672
1681
|
sessions,
|
|
1673
1682
|
sessionOrder: sortSessionOrder(sessions),
|
|
1674
|
-
buckets: { ...state.buckets, [
|
|
1683
|
+
buckets: { ...state.buckets, [session.id]: bucket }
|
|
1675
1684
|
};
|
|
1676
1685
|
}
|
|
1677
1686
|
function archiveSession(state, event) {
|
|
@@ -1791,34 +1800,34 @@ function upsertRun(state, run) {
|
|
|
1791
1800
|
return state;
|
|
1792
1801
|
const bucket = cloneBucket(state.buckets[run.sessionId]);
|
|
1793
1802
|
bucket.runs = { ...bucket.runs, [run.id]: run };
|
|
1794
|
-
const
|
|
1795
|
-
bucket.session =
|
|
1796
|
-
const sessions =
|
|
1803
|
+
const session = refreshSessionStatusFromRuns(bucket.session, bucket.runs, run.updatedAt);
|
|
1804
|
+
bucket.session = session;
|
|
1805
|
+
const sessions = session ? { ...state.sessions, [run.sessionId]: session } : state.sessions;
|
|
1797
1806
|
return {
|
|
1798
1807
|
...state,
|
|
1799
1808
|
sessions,
|
|
1800
|
-
sessionOrder:
|
|
1809
|
+
sessionOrder: session ? sortSessionOrder(sessions) : state.sessionOrder,
|
|
1801
1810
|
buckets: { ...state.buckets, [run.sessionId]: bucket }
|
|
1802
1811
|
};
|
|
1803
1812
|
}
|
|
1804
1813
|
function upsertRunAttempt(state, attempt) {
|
|
1805
1814
|
if (!attempt)
|
|
1806
1815
|
return state;
|
|
1807
|
-
const run = Object.values(state.buckets).flatMap((
|
|
1816
|
+
const run = Object.values(state.buckets).flatMap((bucket) => Object.values(bucket.runs)).find((candidate) => candidate.id === attempt.runId);
|
|
1808
1817
|
if (!run)
|
|
1809
1818
|
return state;
|
|
1810
1819
|
const bucket = cloneBucket(state.buckets[run.sessionId]);
|
|
1811
1820
|
bucket.attempts = { ...bucket.attempts, [attempt.id]: attempt };
|
|
1812
1821
|
return { ...state, buckets: { ...state.buckets, [run.sessionId]: bucket } };
|
|
1813
1822
|
}
|
|
1814
|
-
function refreshSessionStatusFromRuns(
|
|
1815
|
-
if (!
|
|
1816
|
-
return
|
|
1823
|
+
function refreshSessionStatusFromRuns(session, runs, updatedAt) {
|
|
1824
|
+
if (!session || session.status === "archived" || session.status === "closing")
|
|
1825
|
+
return session;
|
|
1817
1826
|
const running = Object.values(runs).some((candidate) => candidate.status === "pending" || candidate.status === "running");
|
|
1818
1827
|
return {
|
|
1819
|
-
...
|
|
1828
|
+
...session,
|
|
1820
1829
|
status: running ? "running" : "idle",
|
|
1821
|
-
updatedAt: Math.max(
|
|
1830
|
+
updatedAt: Math.max(session.updatedAt, updatedAt)
|
|
1822
1831
|
};
|
|
1823
1832
|
}
|
|
1824
1833
|
function upsertPermission(state, request) {
|
|
@@ -1865,7 +1874,7 @@ function upsertSorted(rows, row, sortKey) {
|
|
|
1865
1874
|
return without.sort((a, b) => sortKey(a) - sortKey(b));
|
|
1866
1875
|
}
|
|
1867
1876
|
function sortSessionOrder(sessions) {
|
|
1868
|
-
return Object.values(sessions).sort((a, b) => b.updatedAt - a.updatedAt || a.id.localeCompare(b.id)).map((
|
|
1877
|
+
return Object.values(sessions).sort((a, b) => b.updatedAt - a.updatedAt || a.id.localeCompare(b.id)).map((session) => session.id);
|
|
1869
1878
|
}
|
|
1870
1879
|
var UnsupportedSessionEventSchemaVersionError;
|
|
1871
1880
|
var init_reducer = __esm(() => {
|
|
@@ -2124,7 +2133,7 @@ function shouldPresentSlashOutput(slash) {
|
|
|
2124
2133
|
}
|
|
2125
2134
|
function formatJobReadResult(result) {
|
|
2126
2135
|
const snapshot = result.snapshot;
|
|
2127
|
-
const
|
|
2136
|
+
const capabilities = [
|
|
2128
2137
|
`read=${snapshot.capabilities.read}`,
|
|
2129
2138
|
`wait=${snapshot.capabilities.wait}`,
|
|
2130
2139
|
`send=${snapshot.capabilities.send}`,
|
|
@@ -2141,7 +2150,7 @@ function formatJobReadResult(result) {
|
|
|
2141
2150
|
` Updated at: ${snapshot.updatedAt}`,
|
|
2142
2151
|
` Finished at: ${snapshot.finishedAt ?? "(n/a)"}`,
|
|
2143
2152
|
` Detail: ${snapshot.detail ?? "(none)"}`,
|
|
2144
|
-
` Capabilities: ${
|
|
2153
|
+
` Capabilities: ${capabilities}`,
|
|
2145
2154
|
` Metadata: ${snapshot.metadata ? JSON.stringify(snapshot.metadata) : "(none)"}`,
|
|
2146
2155
|
` Cursor: ${result.cursor}`,
|
|
2147
2156
|
` Truncated: ${result.truncated}`,
|
|
@@ -2321,7 +2330,7 @@ async function dispatchSessionCommand(slash, host) {
|
|
|
2321
2330
|
return [
|
|
2322
2331
|
`Jobs (${jobs.length}):`,
|
|
2323
2332
|
"",
|
|
2324
|
-
...jobs.map((
|
|
2333
|
+
...jobs.map((job) => ` ${job.id} [${job.status}] ${job.kind}: ${job.label}`)
|
|
2325
2334
|
].join(`
|
|
2326
2335
|
`);
|
|
2327
2336
|
});
|
|
@@ -2517,7 +2526,7 @@ No entries found.`;
|
|
|
2517
2526
|
emit([
|
|
2518
2527
|
`Agent Jobs (${agents.length}):`,
|
|
2519
2528
|
"",
|
|
2520
|
-
...agents.map((
|
|
2529
|
+
...agents.map((job) => ` ${job.id} [${job.status}] ${job.label}`)
|
|
2521
2530
|
].join(`
|
|
2522
2531
|
`));
|
|
2523
2532
|
return "handled";
|
|
@@ -2903,7 +2912,7 @@ function beginJobList(previous) {
|
|
|
2903
2912
|
return { status: "loading", jobs: [...previous.jobs] };
|
|
2904
2913
|
}
|
|
2905
2914
|
function resolveJobList(jobs, now, previous) {
|
|
2906
|
-
const cachedById = new Map(previous?.jobs.map((
|
|
2915
|
+
const cachedById = new Map(previous?.jobs.map((job) => [job.id, job]) ?? []);
|
|
2907
2916
|
return {
|
|
2908
2917
|
status: "ready",
|
|
2909
2918
|
jobs: jobs.map((snapshot) => preferMonotonicSnapshot(cachedById.get(snapshot.id), snapshot)),
|
|
@@ -2920,8 +2929,8 @@ function rejectJobList(previous, error) {
|
|
|
2920
2929
|
};
|
|
2921
2930
|
}
|
|
2922
2931
|
function mergeJobSnapshot(state, snapshot, now) {
|
|
2923
|
-
const found = state.jobs.some((
|
|
2924
|
-
const jobs = found ? state.jobs.map((
|
|
2932
|
+
const found = state.jobs.some((job) => job.id === snapshot.id);
|
|
2933
|
+
const jobs = found ? state.jobs.map((job) => job.id === snapshot.id ? preferMonotonicSnapshot(job, snapshot) : job) : [snapshot, ...state.jobs];
|
|
2925
2934
|
return { status: "ready", jobs, refreshedAt: now };
|
|
2926
2935
|
}
|
|
2927
2936
|
function preferMonotonicSnapshot(cached, incoming) {
|
|
@@ -2943,8 +2952,8 @@ function isJobSnapshot(value, ownerSession) {
|
|
|
2943
2952
|
if (!isRecord3(value)) {
|
|
2944
2953
|
return false;
|
|
2945
2954
|
}
|
|
2946
|
-
const
|
|
2947
|
-
return typeof value.id === "string" && value.id.trim().length > 0 && value.ownerSession === ownerSession && typeof value.label === "string" && typeof value.cwd === "string" && typeof value.kind === "string" && JOB_KINDS.includes(value.kind) && typeof value.status === "string" && JOB_STATUSES.includes(value.status) && Number.isFinite(value.startedAt) && Number.isFinite(value.updatedAt) && (value.finishedAt === undefined || Number.isFinite(value.finishedAt)) && (value.detail === undefined || typeof value.detail === "string") && (value.metadata === undefined || isRecord3(value.metadata)) && isRecord3(
|
|
2955
|
+
const capabilities = value.capabilities;
|
|
2956
|
+
return typeof value.id === "string" && value.id.trim().length > 0 && value.ownerSession === ownerSession && typeof value.label === "string" && typeof value.cwd === "string" && typeof value.kind === "string" && JOB_KINDS.includes(value.kind) && typeof value.status === "string" && JOB_STATUSES.includes(value.status) && Number.isFinite(value.startedAt) && Number.isFinite(value.updatedAt) && (value.finishedAt === undefined || Number.isFinite(value.finishedAt)) && (value.detail === undefined || typeof value.detail === "string") && (value.metadata === undefined || isRecord3(value.metadata)) && isRecord3(capabilities) && typeof capabilities.read === "boolean" && typeof capabilities.wait === "boolean" && typeof capabilities.send === "boolean" && typeof capabilities.cancel === "boolean";
|
|
2948
2957
|
}
|
|
2949
2958
|
function validateJobSnapshot(value, ownerSession, expectedJobId) {
|
|
2950
2959
|
if (!isRecord3(value)) {
|
|
@@ -3234,7 +3243,7 @@ function archiveClientSession(state, sessionId, archivedAt) {
|
|
|
3234
3243
|
};
|
|
3235
3244
|
}
|
|
3236
3245
|
function listTopLevelSessions(sessions, activeSessionId) {
|
|
3237
|
-
return [...sessions].filter((
|
|
3246
|
+
return [...sessions].filter((session) => !session.parentId && session.status !== "archived").sort((a, b) => {
|
|
3238
3247
|
if (a.id === activeSessionId)
|
|
3239
3248
|
return -1;
|
|
3240
3249
|
if (b.id === activeSessionId)
|
|
@@ -3243,14 +3252,14 @@ function listTopLevelSessions(sessions, activeSessionId) {
|
|
|
3243
3252
|
});
|
|
3244
3253
|
}
|
|
3245
3254
|
function sessionSelectOptions(sessions, activeSessionId) {
|
|
3246
|
-
return listTopLevelSessions(sessions, activeSessionId).map((
|
|
3247
|
-
value:
|
|
3248
|
-
label: `${
|
|
3249
|
-
description: `${
|
|
3255
|
+
return listTopLevelSessions(sessions, activeSessionId).map((session) => ({
|
|
3256
|
+
value: session.id,
|
|
3257
|
+
label: `${session.id === activeSessionId ? "* " : ""}${session.title || session.id}`,
|
|
3258
|
+
description: `${session.model} | ${session.status}`
|
|
3250
3259
|
}));
|
|
3251
3260
|
}
|
|
3252
|
-
function shouldAutoActivateSession(
|
|
3253
|
-
const runtime = readSessionRuntimeConfig(
|
|
3261
|
+
function shouldAutoActivateSession(session, defaultModel, pluginsEnabled) {
|
|
3262
|
+
const runtime = readSessionRuntimeConfig(session);
|
|
3254
3263
|
return runtime.model === defaultModel && (pluginsEnabled == null || (runtime.pluginsEnabled ?? true) === pluginsEnabled);
|
|
3255
3264
|
}
|
|
3256
3265
|
function recoverableInterruptedRuns(bucket) {
|
|
@@ -3602,17 +3611,17 @@ Refresh failed: ${message}` : `Failed to load ${request.title}: ${message}`;
|
|
|
3602
3611
|
}, LIVE_TEXT_DELTA_FLUSH_MS);
|
|
3603
3612
|
}, [clearPendingClientState]);
|
|
3604
3613
|
useEffect(() => clearPendingClientState, [clearPendingClientState]);
|
|
3605
|
-
const activateSession = useCallback((
|
|
3606
|
-
const runtime = readSessionRuntimeConfig(
|
|
3607
|
-
activeSessionIdRef.current =
|
|
3608
|
-
setActiveSessionId(
|
|
3614
|
+
const activateSession = useCallback((session) => {
|
|
3615
|
+
const runtime = readSessionRuntimeConfig(session, defaultRuntimeRef.current);
|
|
3616
|
+
activeSessionIdRef.current = session.id;
|
|
3617
|
+
setActiveSessionId(session.id);
|
|
3609
3618
|
clearAuxiliaryState();
|
|
3610
3619
|
setStatus((current) => ({
|
|
3611
3620
|
...current,
|
|
3612
3621
|
model: runtime.model,
|
|
3613
3622
|
...runtime.provider ? { provider: runtime.provider } : {},
|
|
3614
|
-
session_id:
|
|
3615
|
-
cwd:
|
|
3623
|
+
session_id: session.id,
|
|
3624
|
+
cwd: session.cwd,
|
|
3616
3625
|
permission_mode: typeof runtime.permissionMode === "string" ? runtime.permissionMode : current.permission_mode,
|
|
3617
3626
|
...typeof runtime.maxTurns === "number" ? { max_turns: runtime.maxTurns } : {},
|
|
3618
3627
|
session_mode: statusSessionMode(runtime.sessionMode)
|
|
@@ -3656,7 +3665,7 @@ Refresh failed: ${message}` : `Failed to load ${request.title}: ${message}`;
|
|
|
3656
3665
|
try {
|
|
3657
3666
|
await client.health();
|
|
3658
3667
|
const cwd = daemon.cwd ?? process.cwd();
|
|
3659
|
-
const [settings, sessions,
|
|
3668
|
+
const [settings, sessions, commands] = await Promise.all([client.getSettings().catch(() => ({})), client.listSessions({ cwd, limit: 20 }), client.listCommands({ cwd }).catch(() => [])]);
|
|
3660
3669
|
const model = daemon.model ?? stringSetting(settings.model) ?? "default";
|
|
3661
3670
|
const provider = stringSetting(settings.provider);
|
|
3662
3671
|
const baseUrl = stringSetting(settings.baseUrl);
|
|
@@ -3669,8 +3678,8 @@ Refresh failed: ${message}` : `Failed to load ${request.title}: ${message}`;
|
|
|
3669
3678
|
};
|
|
3670
3679
|
if (cancelled)
|
|
3671
3680
|
return;
|
|
3672
|
-
listedSessionsRef.current = Object.fromEntries(sessions.map((
|
|
3673
|
-
setCommandCatalog(
|
|
3681
|
+
listedSessionsRef.current = Object.fromEntries(sessions.map((session) => [session.id, session]));
|
|
3682
|
+
setCommandCatalog(commands);
|
|
3674
3683
|
setStatus((current) => ({
|
|
3675
3684
|
...current,
|
|
3676
3685
|
model,
|
|
@@ -3680,10 +3689,10 @@ Refresh failed: ${message}` : `Failed to load ${request.title}: ${message}`;
|
|
|
3680
3689
|
...typeof daemon?.maxTurns === "number" ? { max_turns: daemon.maxTurns } : {},
|
|
3681
3690
|
session_mode: statusSessionMode(daemon?.sessionMode)
|
|
3682
3691
|
}));
|
|
3683
|
-
const
|
|
3684
|
-
if (
|
|
3685
|
-
activateSession(
|
|
3686
|
-
client.getSession(
|
|
3692
|
+
const session = sessions[0];
|
|
3693
|
+
if (session && shouldAutoActivateSession(session, model, daemon?.pluginsEnabled)) {
|
|
3694
|
+
activateSession(session);
|
|
3695
|
+
client.getSession(session.id).catch(() => {});
|
|
3687
3696
|
}
|
|
3688
3697
|
setReady(true);
|
|
3689
3698
|
} catch (error) {
|
|
@@ -3817,18 +3826,18 @@ Refresh failed: ${message}` : `Failed to load ${request.title}: ${message}`;
|
|
|
3817
3826
|
sessionMode: nextSessionModeRef.current,
|
|
3818
3827
|
pluginsEnabled: daemon?.pluginsEnabled
|
|
3819
3828
|
});
|
|
3820
|
-
const
|
|
3829
|
+
const session = await client.createSession({
|
|
3821
3830
|
cwd,
|
|
3822
3831
|
model,
|
|
3823
3832
|
title: title?.trim() || "TUI",
|
|
3824
3833
|
metadata
|
|
3825
3834
|
});
|
|
3826
|
-
activateSession(
|
|
3835
|
+
activateSession(session);
|
|
3827
3836
|
setSelectRequest(null);
|
|
3828
3837
|
setLocalBusy(false);
|
|
3829
3838
|
setSubmittedRun(null);
|
|
3830
3839
|
pendingNewSessionTitleRef.current = undefined;
|
|
3831
|
-
return
|
|
3840
|
+
return session;
|
|
3832
3841
|
}, [activateSession, daemon?.cwd, daemon?.maxTurns, daemon?.model, daemon?.permissionMode, daemon?.pluginsEnabled, daemon?.sessionMode]);
|
|
3833
3842
|
useEffect(() => {
|
|
3834
3843
|
if (!ready || sentInitialPromptRef.current || !config.initial_prompt)
|
|
@@ -3839,17 +3848,17 @@ Refresh failed: ${message}` : `Failed to load ${request.title}: ${message}`;
|
|
|
3839
3848
|
return;
|
|
3840
3849
|
setLocalBusy(true);
|
|
3841
3850
|
(async () => {
|
|
3842
|
-
const
|
|
3843
|
-
if (!
|
|
3851
|
+
const session = activeSessionId ? clientState.sessions[activeSessionId] ?? await client.getSession(activeSessionId) : await createAndSwitchSession();
|
|
3852
|
+
if (!session) {
|
|
3844
3853
|
setLocalBusy(false);
|
|
3845
3854
|
return;
|
|
3846
3855
|
}
|
|
3847
|
-
const response = await client.admitPrompt(
|
|
3856
|
+
const response = await client.admitPrompt(session.id, {
|
|
3848
3857
|
id: createPromptRequestId(),
|
|
3849
3858
|
content: config.initial_prompt
|
|
3850
3859
|
});
|
|
3851
3860
|
setLocalBusy(false);
|
|
3852
|
-
setSubmittedRun(response.run ? { sessionId:
|
|
3861
|
+
setSubmittedRun(response.run ? { sessionId: session.id, runId: response.run.id } : null);
|
|
3853
3862
|
})().catch((error) => reportError(error instanceof Error ? error.message : String(error)));
|
|
3854
3863
|
}, [activeSessionId, clientState.sessions, config.initial_prompt, createAndSwitchSession, ready, reportError]);
|
|
3855
3864
|
const sendRequest = useCallback((action) => {
|
|
@@ -3867,13 +3876,13 @@ Refresh failed: ${message}` : `Failed to load ${request.title}: ${message}`;
|
|
|
3867
3876
|
if (!model)
|
|
3868
3877
|
return;
|
|
3869
3878
|
if (sessionId) {
|
|
3870
|
-
const
|
|
3879
|
+
const session = await client.updateSession(sessionId, {
|
|
3871
3880
|
metadata: patchSessionRuntimeMetadata({}, {
|
|
3872
3881
|
model,
|
|
3873
3882
|
...provider ? { provider } : {}
|
|
3874
3883
|
})
|
|
3875
3884
|
});
|
|
3876
|
-
activateSession(
|
|
3885
|
+
activateSession(session);
|
|
3877
3886
|
} else {
|
|
3878
3887
|
const settingsPatch = { model };
|
|
3879
3888
|
if (provider)
|
|
@@ -3915,8 +3924,8 @@ Refresh failed: ${message}` : `Failed to load ${request.title}: ${message}`;
|
|
|
3915
3924
|
activateSession(knownSession);
|
|
3916
3925
|
return;
|
|
3917
3926
|
}
|
|
3918
|
-
const
|
|
3919
|
-
activateSession(
|
|
3927
|
+
const session = await client.getSession(target);
|
|
3928
|
+
activateSession(session);
|
|
3920
3929
|
return;
|
|
3921
3930
|
}
|
|
3922
3931
|
if (slash?.name === "/resume") {
|
|
@@ -3948,9 +3957,9 @@ Refresh failed: ${message}` : `Failed to load ${request.title}: ${message}`;
|
|
|
3948
3957
|
return;
|
|
3949
3958
|
}
|
|
3950
3959
|
setLocalBusy(true);
|
|
3951
|
-
const
|
|
3960
|
+
const response = await client.resumeInterruptedRun(sessionId, runId, { id: createPromptRequestId() });
|
|
3952
3961
|
setLocalBusy(false);
|
|
3953
|
-
setSubmittedRun(
|
|
3962
|
+
setSubmittedRun(response.run ? { sessionId, runId: response.run.id } : null);
|
|
3954
3963
|
setSelectRequest(null);
|
|
3955
3964
|
return;
|
|
3956
3965
|
}
|
|
@@ -3991,7 +4000,7 @@ Refresh failed: ${message}` : `Failed to load ${request.title}: ${message}`;
|
|
|
3991
4000
|
return;
|
|
3992
4001
|
setLocalBusy(true);
|
|
3993
4002
|
const commandName = slash.name.replace(/^\//, "");
|
|
3994
|
-
const
|
|
4003
|
+
const response = await client.admitPrompt(sessionId, {
|
|
3995
4004
|
id: createPromptRequestId(),
|
|
3996
4005
|
content: slash.args,
|
|
3997
4006
|
metadata: {
|
|
@@ -4005,17 +4014,17 @@ Refresh failed: ${message}` : `Failed to load ${request.title}: ${message}`;
|
|
|
4005
4014
|
}
|
|
4006
4015
|
});
|
|
4007
4016
|
setLocalBusy(false);
|
|
4008
|
-
setSubmittedRun(
|
|
4017
|
+
setSubmittedRun(response.run ? { sessionId, runId: response.run.id } : null);
|
|
4009
4018
|
return;
|
|
4010
4019
|
}
|
|
4011
4020
|
pushSystem(`Unknown command: ${slash.name}`);
|
|
4012
4021
|
return;
|
|
4013
4022
|
}
|
|
4014
4023
|
if (!sessionId) {
|
|
4015
|
-
const
|
|
4016
|
-
if (!
|
|
4024
|
+
const session = await createAndSwitchSession(pendingNewSessionTitleRef.current);
|
|
4025
|
+
if (!session)
|
|
4017
4026
|
return;
|
|
4018
|
-
sessionId =
|
|
4027
|
+
sessionId = session.id;
|
|
4019
4028
|
}
|
|
4020
4029
|
setLocalBusy(true);
|
|
4021
4030
|
const response = await client.admitPrompt(sessionId, {
|
|
@@ -4056,8 +4065,8 @@ Refresh failed: ${message}` : `Failed to load ${request.title}: ${message}`;
|
|
|
4056
4065
|
includeArchived: false,
|
|
4057
4066
|
limit: 20
|
|
4058
4067
|
});
|
|
4059
|
-
listedSessionsRef.current = Object.fromEntries(sessions.map((
|
|
4060
|
-
const remoteNext = sessions.find((
|
|
4068
|
+
listedSessionsRef.current = Object.fromEntries(sessions.map((session) => [session.id, session]));
|
|
4069
|
+
const remoteNext = sessions.find((session) => session.id !== target);
|
|
4061
4070
|
if (remoteNext)
|
|
4062
4071
|
activateSession(remoteNext);
|
|
4063
4072
|
else
|
|
@@ -4107,7 +4116,7 @@ Refresh failed: ${message}` : `Failed to load ${request.title}: ${message}`;
|
|
|
4107
4116
|
includeArchived: false,
|
|
4108
4117
|
limit: 20
|
|
4109
4118
|
});
|
|
4110
|
-
listedSessionsRef.current = Object.fromEntries(sessions.map((
|
|
4119
|
+
listedSessionsRef.current = Object.fromEntries(sessions.map((session) => [session.id, session]));
|
|
4111
4120
|
setSelectRequest((current) => current?.submitPrefix === "/sessions open " ? {
|
|
4112
4121
|
title: "Sessions",
|
|
4113
4122
|
submitPrefix: "/sessions open ",
|
|
@@ -4889,9 +4898,9 @@ var init_QuestionDialog = __esm(() => {
|
|
|
4889
4898
|
// ../frontend/src/hooks/useModalWiring.tsx
|
|
4890
4899
|
import { useEffect as useEffect4, useRef as useRef5 } from "react";
|
|
4891
4900
|
import { jsxDEV as jsxDEV7 } from "@opentui/react/jsx-dev-runtime";
|
|
4892
|
-
function useModalWiring(
|
|
4901
|
+
function useModalWiring(session, dialog) {
|
|
4893
4902
|
useEffect4(() => {
|
|
4894
|
-
const modal =
|
|
4903
|
+
const modal = session.modal;
|
|
4895
4904
|
if (!modal)
|
|
4896
4905
|
return;
|
|
4897
4906
|
if (modal.kind === "permission") {
|
|
@@ -4903,25 +4912,25 @@ function useModalWiring(session2, dialog) {
|
|
|
4903
4912
|
if (respondedRef.current)
|
|
4904
4913
|
return;
|
|
4905
4914
|
respondedRef.current = true;
|
|
4906
|
-
|
|
4915
|
+
session.sendRequest({
|
|
4907
4916
|
type: "permission_response",
|
|
4908
4917
|
request_id: requestId,
|
|
4909
4918
|
allowed,
|
|
4910
4919
|
scope
|
|
4911
4920
|
});
|
|
4912
|
-
|
|
4921
|
+
session.setModal(null);
|
|
4913
4922
|
dialog.close();
|
|
4914
4923
|
};
|
|
4915
4924
|
const onClose = () => {
|
|
4916
4925
|
if (!respondedRef.current) {
|
|
4917
4926
|
respondedRef.current = true;
|
|
4918
|
-
|
|
4927
|
+
session.sendRequest({
|
|
4919
4928
|
type: "permission_response",
|
|
4920
4929
|
request_id: requestId,
|
|
4921
4930
|
allowed: false,
|
|
4922
4931
|
scope: "once"
|
|
4923
4932
|
});
|
|
4924
|
-
|
|
4933
|
+
session.setModal(null);
|
|
4925
4934
|
}
|
|
4926
4935
|
};
|
|
4927
4936
|
dialog.replace(/* @__PURE__ */ jsxDEV7(PermissionDialog, {
|
|
@@ -4939,12 +4948,12 @@ function useModalWiring(session2, dialog) {
|
|
|
4939
4948
|
if (respondedRef.current)
|
|
4940
4949
|
return;
|
|
4941
4950
|
respondedRef.current = true;
|
|
4942
|
-
|
|
4951
|
+
session.sendRequest({
|
|
4943
4952
|
type: "question_response",
|
|
4944
4953
|
request_id: requestId,
|
|
4945
4954
|
answer
|
|
4946
4955
|
});
|
|
4947
|
-
|
|
4956
|
+
session.setModal(null);
|
|
4948
4957
|
};
|
|
4949
4958
|
const onClose = () => {
|
|
4950
4959
|
sendAnswer("");
|
|
@@ -4957,19 +4966,19 @@ function useModalWiring(session2, dialog) {
|
|
|
4957
4966
|
}
|
|
4958
4967
|
}, undefined, false, undefined, this), onClose);
|
|
4959
4968
|
}
|
|
4960
|
-
}, [
|
|
4969
|
+
}, [session.modal]);
|
|
4961
4970
|
useEffect4(() => {
|
|
4962
|
-
const req =
|
|
4971
|
+
const req = session.displayRequest;
|
|
4963
4972
|
if (!req)
|
|
4964
4973
|
return;
|
|
4965
4974
|
dialog.replace(/* @__PURE__ */ jsxDEV7(DialogText, {
|
|
4966
4975
|
title: req.title,
|
|
4967
4976
|
content: req.content
|
|
4968
|
-
}, undefined, false, undefined, this), () =>
|
|
4969
|
-
}, [
|
|
4977
|
+
}, undefined, false, undefined, this), () => session.setDisplayRequest(null));
|
|
4978
|
+
}, [session.displayRequest]);
|
|
4970
4979
|
const selectOpenRef = useRef5(false);
|
|
4971
4980
|
useEffect4(() => {
|
|
4972
|
-
const req =
|
|
4981
|
+
const req = session.selectRequest;
|
|
4973
4982
|
if (!req) {
|
|
4974
4983
|
if (selectOpenRef.current) {
|
|
4975
4984
|
selectOpenRef.current = false;
|
|
@@ -4987,15 +4996,15 @@ function useModalWiring(session2, dialog) {
|
|
|
4987
4996
|
})),
|
|
4988
4997
|
onSelect: (value) => {
|
|
4989
4998
|
selectOpenRef.current = false;
|
|
4990
|
-
|
|
4999
|
+
session.sendRequest({
|
|
4991
5000
|
type: "submit_line",
|
|
4992
5001
|
line: `${req.submitPrefix}${value}`
|
|
4993
5002
|
});
|
|
4994
|
-
|
|
5003
|
+
session.setSelectRequest(null);
|
|
4995
5004
|
dialog.close();
|
|
4996
5005
|
},
|
|
4997
5006
|
onDelete: isSessions ? (value) => {
|
|
4998
|
-
|
|
5007
|
+
session.sendRequest({ type: "delete_session", session_id: value });
|
|
4999
5008
|
} : undefined
|
|
5000
5009
|
}, undefined, false, undefined, this);
|
|
5001
5010
|
if (selectOpenRef.current) {
|
|
@@ -5005,9 +5014,9 @@ function useModalWiring(session2, dialog) {
|
|
|
5005
5014
|
selectOpenRef.current = true;
|
|
5006
5015
|
dialog.replace(node, () => {
|
|
5007
5016
|
selectOpenRef.current = false;
|
|
5008
|
-
|
|
5017
|
+
session.setSelectRequest(null);
|
|
5009
5018
|
});
|
|
5010
|
-
}, [
|
|
5019
|
+
}, [session.selectRequest]);
|
|
5011
5020
|
}
|
|
5012
5021
|
var init_useModalWiring = __esm(() => {
|
|
5013
5022
|
init_DialogSelect();
|
|
@@ -7185,7 +7194,7 @@ function JobsPanel({ state, detailState, onRefresh, onSelect, onCancel }) {
|
|
|
7185
7194
|
const c = theme.colors;
|
|
7186
7195
|
const [kindFilter, setKindFilter] = useState12();
|
|
7187
7196
|
const [statusFilter, setStatusFilter] = useState12();
|
|
7188
|
-
const visibleJobs = useMemo6(() => state.jobs.filter((
|
|
7197
|
+
const visibleJobs = useMemo6(() => state.jobs.filter((job) => (!kindFilter || job.kind === kindFilter) && (!statusFilter || job.status === statusFilter)), [kindFilter, state.jobs, statusFilter]);
|
|
7189
7198
|
const { index, setIndex, moveUp, moveDown } = useListNavigation(visibleJobs.length);
|
|
7190
7199
|
const cursorIndex = Math.min(index, Math.max(0, visibleJobs.length - 1));
|
|
7191
7200
|
const selectedJob = visibleJobs[cursorIndex];
|
|
@@ -7247,12 +7256,12 @@ function JobsPanel({ state, detailState, onRefresh, onSelect, onCancel }) {
|
|
|
7247
7256
|
}, undefined, false, undefined, this),
|
|
7248
7257
|
visibleJobs.length > 0 ? /* @__PURE__ */ jsxDEV21("box", {
|
|
7249
7258
|
flexDirection: "column",
|
|
7250
|
-
children: jobWindow.map((
|
|
7259
|
+
children: jobWindow.map((job, visibleIndex) => {
|
|
7251
7260
|
const isCursor = windowStart + visibleIndex === cursorIndex;
|
|
7252
7261
|
return /* @__PURE__ */ jsxDEV21(JobRow, {
|
|
7253
|
-
job
|
|
7262
|
+
job,
|
|
7254
7263
|
selected: isCursor
|
|
7255
|
-
},
|
|
7264
|
+
}, job.id, false, undefined, this);
|
|
7256
7265
|
})
|
|
7257
7266
|
}, undefined, false, undefined, this) : state.status === "ready" || state.status === "idle" ? /* @__PURE__ */ jsxDEV21("text", {
|
|
7258
7267
|
fg: c.muted,
|
|
@@ -7289,22 +7298,22 @@ function ListRemoteState({ state }) {
|
|
|
7289
7298
|
}
|
|
7290
7299
|
return null;
|
|
7291
7300
|
}
|
|
7292
|
-
function JobRow({ job
|
|
7301
|
+
function JobRow({ job, selected }) {
|
|
7293
7302
|
const { theme } = useTheme();
|
|
7294
7303
|
const c = theme.colors;
|
|
7295
|
-
const marker = statusMarker(
|
|
7296
|
-
const foreground = selected ? c.background : statusColor2(
|
|
7304
|
+
const marker = statusMarker(job.status);
|
|
7305
|
+
const foreground = selected ? c.background : statusColor2(job.status, c);
|
|
7297
7306
|
return /* @__PURE__ */ jsxDEV21("box", {
|
|
7298
7307
|
flexDirection: "column",
|
|
7299
7308
|
backgroundColor: selected ? c.accent : undefined,
|
|
7300
7309
|
children: [
|
|
7301
7310
|
/* @__PURE__ */ jsxDEV21("text", {
|
|
7302
7311
|
fg: foreground,
|
|
7303
|
-
children: `${marker} ${
|
|
7312
|
+
children: `${marker} ${job.kind} ${job.status} ${truncate2(job.label, 50)}`
|
|
7304
7313
|
}, undefined, false, undefined, this),
|
|
7305
7314
|
/* @__PURE__ */ jsxDEV21("text", {
|
|
7306
7315
|
fg: selected ? c.background : c.muted,
|
|
7307
|
-
children: ` ${truncate2(
|
|
7316
|
+
children: ` ${truncate2(job.id, 24)} ${truncate2(job.cwd, 44)}`
|
|
7308
7317
|
}, undefined, false, undefined, this)
|
|
7309
7318
|
]
|
|
7310
7319
|
}, undefined, true, undefined, this);
|
|
@@ -7574,9 +7583,7 @@ var init_selection = () => {};
|
|
|
7574
7583
|
// ../frontend/src/App.tsx
|
|
7575
7584
|
var exports_App = {};
|
|
7576
7585
|
__export(exports_App, {
|
|
7577
|
-
App: () => App
|
|
7578
|
-
createJobsPanelCallbacks: () => createJobsPanelCallbacks,
|
|
7579
|
-
shouldOpenJobsPanel: () => shouldOpenJobsPanel
|
|
7586
|
+
App: () => App
|
|
7580
7587
|
});
|
|
7581
7588
|
import { useCallback as useCallback7, useEffect as useEffect10, useMemo as useMemo7, useRef as useRef9, useState as useState13 } from "react";
|
|
7582
7589
|
import { useKeyboard as useKeyboard8, useRenderer, useTerminalDimensions as useTerminalDimensions5 } from "@opentui/react";
|
|
@@ -7612,9 +7619,9 @@ function AppInner({ config }) {
|
|
|
7612
7619
|
renderer.destroy();
|
|
7613
7620
|
}, [renderer]);
|
|
7614
7621
|
const onSessionError = useCallback7((message) => toast(message, "error"), [toast]);
|
|
7615
|
-
const
|
|
7616
|
-
const jobsPanelCallbacks = useMemo7(() => createJobsPanelCallbacks(
|
|
7617
|
-
const activeSessionId = typeof
|
|
7622
|
+
const session = useServerSync(config, onSessionError);
|
|
7623
|
+
const jobsPanelCallbacks = useMemo7(() => createJobsPanelCallbacks(session.sendRequest), [session.sendRequest]);
|
|
7624
|
+
const activeSessionId = typeof session.status.session_id === "string" ? session.status.session_id : undefined;
|
|
7618
7625
|
const previousSessionIdRef = useRef9(undefined);
|
|
7619
7626
|
useEffect10(() => {
|
|
7620
7627
|
const previousSessionId = previousSessionIdRef.current;
|
|
@@ -7627,8 +7634,8 @@ function AppInner({ config }) {
|
|
|
7627
7634
|
}, [activeSessionId, dialog.closeAll]);
|
|
7628
7635
|
const [history, setHistory] = useState13([]);
|
|
7629
7636
|
const [draft, setDraft] = useState13("");
|
|
7630
|
-
const { escHint, handleEscape } = useEscToCancel(
|
|
7631
|
-
|
|
7637
|
+
const { escHint, handleEscape } = useEscToCancel(session.busy, () => {
|
|
7638
|
+
session.sendRequest({ type: "interrupt" });
|
|
7632
7639
|
});
|
|
7633
7640
|
const appendHistory = useCallback7((line) => {
|
|
7634
7641
|
setHistory((prev) => {
|
|
@@ -7637,22 +7644,22 @@ function AppInner({ config }) {
|
|
|
7637
7644
|
});
|
|
7638
7645
|
}, []);
|
|
7639
7646
|
const setPermissionMode = useCallback7((mode) => {
|
|
7640
|
-
|
|
7641
|
-
}, [
|
|
7647
|
+
session.sendRequest({ type: "set_permission_mode", permission_mode: mode });
|
|
7648
|
+
}, [session]);
|
|
7642
7649
|
const openModelPicker = useCallback7(() => {
|
|
7643
|
-
const currentModel = typeof
|
|
7650
|
+
const currentModel = typeof session.status.model === "string" ? session.status.model : config.daemon?.model ?? undefined;
|
|
7644
7651
|
dialog.replace(/* @__PURE__ */ jsxDEV22("box", {
|
|
7645
7652
|
flexDirection: "column",
|
|
7646
7653
|
children: /* @__PURE__ */ jsxDEV22("text", {
|
|
7647
7654
|
children: "Loading models..."
|
|
7648
7655
|
}, undefined, false, undefined, this)
|
|
7649
7656
|
}, undefined, false, undefined, this));
|
|
7650
|
-
|
|
7657
|
+
session.loadModels().then((providers) => {
|
|
7651
7658
|
dialog.replace(/* @__PURE__ */ jsxDEV22(ModelPickerDialog, {
|
|
7652
7659
|
providers,
|
|
7653
7660
|
currentModel,
|
|
7654
7661
|
onSelect: (model) => {
|
|
7655
|
-
|
|
7662
|
+
session.sendRequest({
|
|
7656
7663
|
type: "select_model",
|
|
7657
7664
|
model: model.id,
|
|
7658
7665
|
provider: model.providerName
|
|
@@ -7666,7 +7673,7 @@ function AppInner({ config }) {
|
|
|
7666
7673
|
dialog.close();
|
|
7667
7674
|
toast(`Models: ${message}`, "error");
|
|
7668
7675
|
});
|
|
7669
|
-
}, [config.daemon?.model, dialog,
|
|
7676
|
+
}, [config.daemon?.model, dialog, session, toast]);
|
|
7670
7677
|
const handleCommand = useCallback7((line) => {
|
|
7671
7678
|
const themeSetMatch = line.match(/^\/theme\s+set\s+(\S+)$/);
|
|
7672
7679
|
if (themeSetMatch?.[1]) {
|
|
@@ -7697,7 +7704,7 @@ function AppInner({ config }) {
|
|
|
7697
7704
|
return true;
|
|
7698
7705
|
}
|
|
7699
7706
|
if (line.trim() === "/permissions" || line.trim() === "/permissions show") {
|
|
7700
|
-
const currentMode = String(
|
|
7707
|
+
const currentMode = String(session.status.permission_mode ?? "default");
|
|
7701
7708
|
const currentIndex = PERMISSION_MODES.findIndex((m) => m.value === currentMode);
|
|
7702
7709
|
dialog.replace(/* @__PURE__ */ jsxDEV22(DialogSelect, {
|
|
7703
7710
|
title: "Permission Mode",
|
|
@@ -7717,9 +7724,9 @@ function AppInner({ config }) {
|
|
|
7717
7724
|
return true;
|
|
7718
7725
|
}
|
|
7719
7726
|
if (line.trim() === "/plan") {
|
|
7720
|
-
const currentMode = String(
|
|
7727
|
+
const currentMode = String(session.status.permission_mode ?? "default");
|
|
7721
7728
|
const isPlan = currentMode === "plan";
|
|
7722
|
-
|
|
7729
|
+
session.sendRequest({
|
|
7723
7730
|
type: "submit_line",
|
|
7724
7731
|
line: isPlan ? "/plan off" : "/plan on"
|
|
7725
7732
|
});
|
|
@@ -7727,7 +7734,7 @@ function AppInner({ config }) {
|
|
|
7727
7734
|
}
|
|
7728
7735
|
const coordinatorMatch = line.trim().match(/^\/coordinator(?:\s+(on|off|status))?$/);
|
|
7729
7736
|
if (coordinatorMatch) {
|
|
7730
|
-
const currentMode = String(
|
|
7737
|
+
const currentMode = String(session.status.session_mode ?? "direct");
|
|
7731
7738
|
const action = coordinatorMatch[1] ?? (currentMode === "coordinator" ? "off" : "on");
|
|
7732
7739
|
if (action === "status") {
|
|
7733
7740
|
toast(`Coordinator mode: ${currentMode === "coordinator" ? "on" : "off"}`);
|
|
@@ -7737,7 +7744,7 @@ function AppInner({ config }) {
|
|
|
7737
7744
|
toast("Use /new before changing coordinator mode", "error");
|
|
7738
7745
|
return true;
|
|
7739
7746
|
}
|
|
7740
|
-
|
|
7747
|
+
session.sendRequest({
|
|
7741
7748
|
type: "set_session_mode",
|
|
7742
7749
|
session_mode: action === "on" ? "coordinator" : "direct"
|
|
7743
7750
|
});
|
|
@@ -7745,22 +7752,22 @@ function AppInner({ config }) {
|
|
|
7745
7752
|
return true;
|
|
7746
7753
|
}
|
|
7747
7754
|
if (line.trim() === "/sessions") {
|
|
7748
|
-
|
|
7755
|
+
session.sendRequest({ type: "list_sessions" });
|
|
7749
7756
|
return true;
|
|
7750
7757
|
}
|
|
7751
7758
|
if (shouldOpenJobsPanel(line)) {
|
|
7752
7759
|
setJobsPanelOpen(true);
|
|
7753
|
-
|
|
7760
|
+
session.sendRequest({ type: "job_request", job_action: "open" });
|
|
7754
7761
|
return true;
|
|
7755
7762
|
}
|
|
7756
7763
|
return false;
|
|
7757
|
-
}, [activeSessionId, dialog, openModelPicker,
|
|
7764
|
+
}, [activeSessionId, dialog, openModelPicker, session, setThemeName, theme.name, toast]);
|
|
7758
7765
|
const registryRef = useRef9(null);
|
|
7759
7766
|
const openCommandPalette = useCallback7(() => {
|
|
7760
|
-
const
|
|
7761
|
-
if (!
|
|
7767
|
+
const registry = registryRef.current;
|
|
7768
|
+
if (!registry)
|
|
7762
7769
|
return;
|
|
7763
|
-
const allCmds =
|
|
7770
|
+
const allCmds = registry.all();
|
|
7764
7771
|
dialog.replace(/* @__PURE__ */ jsxDEV22(DialogSelect, {
|
|
7765
7772
|
title: "Commands",
|
|
7766
7773
|
items: allCmds.map((cmd) => ({
|
|
@@ -7771,7 +7778,7 @@ function AppInner({ config }) {
|
|
|
7771
7778
|
})),
|
|
7772
7779
|
onSelect: (id) => {
|
|
7773
7780
|
dialog.close();
|
|
7774
|
-
const cmd =
|
|
7781
|
+
const cmd = registry.get(id);
|
|
7775
7782
|
cmd?.run();
|
|
7776
7783
|
}
|
|
7777
7784
|
}, undefined, false, undefined, this));
|
|
@@ -7781,17 +7788,17 @@ function AppInner({ config }) {
|
|
|
7781
7788
|
appendHistory(line);
|
|
7782
7789
|
return;
|
|
7783
7790
|
}
|
|
7784
|
-
|
|
7791
|
+
session.sendRequest({ type: "submit_line", line });
|
|
7785
7792
|
appendHistory(line);
|
|
7786
|
-
}, [appendHistory, handleCommand,
|
|
7793
|
+
}, [appendHistory, handleCommand, session]);
|
|
7787
7794
|
const onCycleMode = useCallback7(() => {
|
|
7788
|
-
const currentMode = String(
|
|
7795
|
+
const currentMode = String(session.status.permission_mode ?? "default");
|
|
7789
7796
|
const idx = PERMISSION_MODE_ORDER.indexOf(currentMode);
|
|
7790
7797
|
const nextMode = PERMISSION_MODE_ORDER[(idx + 1) % PERMISSION_MODE_ORDER.length] ?? "default";
|
|
7791
7798
|
setPermissionMode(nextMode);
|
|
7792
|
-
}, [
|
|
7799
|
+
}, [session.status.permission_mode, setPermissionMode]);
|
|
7793
7800
|
const registry = useMemo7(() => buildRegistry({
|
|
7794
|
-
backendCommands: (
|
|
7801
|
+
backendCommands: (session.commandDetails.length > 0 ? [...session.commandDetails] : session.commands.map((name) => ({ name }))).sort((a, b) => a.name.localeCompare(b.name)),
|
|
7795
7802
|
local: [
|
|
7796
7803
|
{
|
|
7797
7804
|
id: "app.palette",
|
|
@@ -7834,7 +7841,7 @@ function AppInner({ config }) {
|
|
|
7834
7841
|
title: "Jobs",
|
|
7835
7842
|
run: () => {
|
|
7836
7843
|
setJobsPanelOpen(true);
|
|
7837
|
-
|
|
7844
|
+
session.sendRequest({ type: "job_request", job_action: "open" });
|
|
7838
7845
|
}
|
|
7839
7846
|
},
|
|
7840
7847
|
{
|
|
@@ -7860,11 +7867,11 @@ function AppInner({ config }) {
|
|
|
7860
7867
|
}
|
|
7861
7868
|
],
|
|
7862
7869
|
submitLine: (line) => {
|
|
7863
|
-
|
|
7870
|
+
session.sendRequest({ type: "submit_line", line });
|
|
7864
7871
|
}
|
|
7865
|
-
}), [handleCommand, onSessionExit, openCommandPalette,
|
|
7872
|
+
}), [handleCommand, onSessionExit, openCommandPalette, session]);
|
|
7866
7873
|
registryRef.current = registry;
|
|
7867
|
-
useModalWiring(
|
|
7874
|
+
useModalWiring(session, dialog);
|
|
7868
7875
|
useKeyboard8((key) => {
|
|
7869
7876
|
if (key.ctrl && key.name === "c") {
|
|
7870
7877
|
if (copySelectionToClipboard(renderer, toast)) {
|
|
@@ -7888,7 +7895,7 @@ function AppInner({ config }) {
|
|
|
7888
7895
|
if (key.ctrl && key.name === "b") {
|
|
7889
7896
|
setSidebarOpen((v) => !v);
|
|
7890
7897
|
}
|
|
7891
|
-
if (key.name === "escape" &&
|
|
7898
|
+
if (key.name === "escape" && session.busy && !dialog.isOpen) {
|
|
7892
7899
|
handleEscape();
|
|
7893
7900
|
}
|
|
7894
7901
|
});
|
|
@@ -7897,12 +7904,12 @@ function AppInner({ config }) {
|
|
|
7897
7904
|
return /* @__PURE__ */ jsxDEV22(Fragment3, {
|
|
7898
7905
|
children: [
|
|
7899
7906
|
/* @__PURE__ */ jsxDEV22(AppView, {
|
|
7900
|
-
transcript:
|
|
7901
|
-
assistantBuffer:
|
|
7902
|
-
ready:
|
|
7903
|
-
busy:
|
|
7904
|
-
status:
|
|
7905
|
-
mcpServers:
|
|
7907
|
+
transcript: session.transcript,
|
|
7908
|
+
assistantBuffer: session.assistantBuffer,
|
|
7909
|
+
ready: session.ready,
|
|
7910
|
+
busy: session.busy,
|
|
7911
|
+
status: session.status,
|
|
7912
|
+
mcpServers: session.mcpServers,
|
|
7906
7913
|
version: config.version ?? null,
|
|
7907
7914
|
history,
|
|
7908
7915
|
slashCommands: registry.slashCommands(),
|
|
@@ -7927,8 +7934,8 @@ function AppInner({ config }) {
|
|
|
7927
7934
|
padding: 1,
|
|
7928
7935
|
flexDirection: "column",
|
|
7929
7936
|
children: /* @__PURE__ */ jsxDEV22(JobsPanel, {
|
|
7930
|
-
state:
|
|
7931
|
-
detailState:
|
|
7937
|
+
state: session.jobState,
|
|
7938
|
+
detailState: session.jobDetailState,
|
|
7932
7939
|
...jobsPanelCallbacks
|
|
7933
7940
|
}, undefined, false, undefined, this)
|
|
7934
7941
|
}, undefined, false, undefined, this) : null
|
|
@@ -8012,7 +8019,7 @@ try {
|
|
|
8012
8019
|
}
|
|
8013
8020
|
try {
|
|
8014
8021
|
assertSupportedTuiRuntime();
|
|
8015
|
-
const [{ createCliRenderer }, { createElement, createRoot }, { App
|
|
8022
|
+
const [{ createCliRenderer }, { createElement, createRoot }, { App }] = await Promise.all([
|
|
8016
8023
|
import("@opentui/core"),
|
|
8017
8024
|
import("@opentui/react"),
|
|
8018
8025
|
Promise.resolve().then(() => (init_App(), exports_App))
|
|
@@ -8024,10 +8031,10 @@ try {
|
|
|
8024
8031
|
onDestroy: () => process.exit(process.exitCode ?? 0)
|
|
8025
8032
|
});
|
|
8026
8033
|
renderer.setTerminalTitle("OpenHarness");
|
|
8027
|
-
createRoot(renderer).render(createElement(
|
|
8034
|
+
createRoot(renderer).render(createElement(App, { config }));
|
|
8028
8035
|
} catch (err) {
|
|
8029
8036
|
console.error("[openharness] \u7EC8\u7AEF\u6E32\u67D3\u5668\u521D\u59CB\u5316\u5931\u8D25\uFF08\u9700\u8981 Bun + \u652F\u6301\u7684\u5E73\u53F0\uFF09\uFF1A", err);
|
|
8030
8037
|
process.exit(1);
|
|
8031
8038
|
}
|
|
8032
8039
|
|
|
8033
|
-
//# debugId=
|
|
8040
|
+
//# debugId=BAFB208A6EB2D30564756E2164756E21
|