@avantf/dsh-mission 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +249 -0
- package/cordis.patch.yml +13 -0
- package/lib/client.js +225 -0
- package/lib/dsh-build.json +16 -0
- package/lib/envinit-bootstrap.js +334 -0
- package/lib/index.js +7021 -0
- package/lib/interface-version.json +4 -0
- package/lib/mission-core/capacity.d.ts +100 -0
- package/lib/mission-core/continuation.d.ts +106 -0
- package/lib/mission-core/dispatch.d.ts +165 -0
- package/lib/mission-core/engine.d.ts +331 -0
- package/lib/mission-core/index.d.ts +25 -0
- package/lib/mission-core/liveness.d.ts +99 -0
- package/lib/mission-core/prompt.d.ts +112 -0
- package/lib/mission-core/resources.d.ts +57 -0
- package/lib/mission-core/timing.d.ts +37 -0
- package/lib/mission-core/tree.d.ts +447 -0
- package/lib/mission-core/trouble.d.ts +40 -0
- package/lib/mission-core/types.d.ts +409 -0
- package/lib/mission-core/wellformed.d.ts +98 -0
- package/lib/types/claims.d.ts +3 -0
- package/lib/types/claims.d.ts.map +1 -0
- package/lib/types/client/MissionTreeView.d.ts +247 -0
- package/lib/types/client/MissionTreeView.d.ts.map +1 -0
- package/lib/types/client/api.d.ts +184 -0
- package/lib/types/client/api.d.ts.map +1 -0
- package/lib/types/client/contract.d.ts +209 -0
- package/lib/types/client/contract.d.ts.map +1 -0
- package/lib/types/client/index.d.ts +48 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/client/seat.d.ts +26 -0
- package/lib/types/client/seat.d.ts.map +1 -0
- package/lib/types/client/styles.d.ts +6 -0
- package/lib/types/client/styles.d.ts.map +1 -0
- package/lib/types/coldResume.d.ts +123 -0
- package/lib/types/coldResume.d.ts.map +1 -0
- package/lib/types/domain.d.ts +93 -0
- package/lib/types/domain.d.ts.map +1 -0
- package/lib/types/envinit.d.ts +126 -0
- package/lib/types/envinit.d.ts.map +1 -0
- package/lib/types/executorSession.d.ts +129 -0
- package/lib/types/executorSession.d.ts.map +1 -0
- package/lib/types/faces.d.ts +30 -0
- package/lib/types/faces.d.ts.map +1 -0
- package/lib/types/host.d.ts +752 -0
- package/lib/types/host.d.ts.map +1 -0
- package/lib/types/index.d.ts +48 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/interface_gate.d.ts +51 -0
- package/lib/types/interface_gate.d.ts.map +1 -0
- package/lib/types/log.d.ts +18 -0
- package/lib/types/log.d.ts.map +1 -0
- package/lib/types/projectionCache.d.ts +22 -0
- package/lib/types/projectionCache.d.ts.map +1 -0
- package/lib/types/prompt.d.ts +106 -0
- package/lib/types/prompt.d.ts.map +1 -0
- package/lib/types/source.d.ts +22 -0
- package/lib/types/source.d.ts.map +1 -0
- package/lib/types/store.d.ts +20 -0
- package/lib/types/store.d.ts.map +1 -0
- package/lib/types/timeFormat.d.ts +56 -0
- package/lib/types/timeFormat.d.ts.map +1 -0
- package/lib/types/tools.d.ts +34 -0
- package/lib/types/tools.d.ts.map +1 -0
- package/lib/types/wellformed.d.ts +43 -0
- package/lib/types/wellformed.d.ts.map +1 -0
- package/lib/types/wire.d.ts +178 -0
- package/lib/types/wire.d.ts.map +1 -0
- package/lib/types/workerEvents.d.ts +36 -0
- package/lib/types/workerEvents.d.ts.map +1 -0
- package/lib/types/workerSessions.d.ts +256 -0
- package/lib/types/workerSessions.d.ts.map +1 -0
- package/package.json +145 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The "任务" view: one session's mission trees, driven by the `useSnapshot` hook so the
|
|
3
|
+
* component knows nothing about the transport; one mission's detail is read on demand and
|
|
4
|
+
* shown in a modal panel (left: section nav, right: the section, scrolled), the same shape
|
|
5
|
+
* as the shell's 设置 dialog. There is no toolbar (the engine pushes changes), deletion is a
|
|
6
|
+
* TREE-level gesture in the tree header (removing a node from a live tree leaves one that
|
|
7
|
+
* cannot converge), and a row's CHILDREN are open by default while its mission is in play and
|
|
8
|
+
* folded once it has finished — that folding is the tree, not the detail.
|
|
9
|
+
* @module @avantf/dsh-mission/client/MissionTreeView
|
|
10
|
+
*/
|
|
11
|
+
import { type ReactNode } from 'react';
|
|
12
|
+
import type { ExecutorSessionLookup, MissionNodeDetail, MissionViewProps, WorkerSessionTarget } from './contract.js';
|
|
13
|
+
/**
|
|
14
|
+
* The one dialog's data, as this view tracks it (not part of the contract): which node it is
|
|
15
|
+
* for, and how far that read has got. One at a time, because the dialog is modal — the
|
|
16
|
+
* per-node cache the inline panel kept existed only to survive rows scrolling past.
|
|
17
|
+
*/
|
|
18
|
+
interface DialogState {
|
|
19
|
+
readonly nodeId: string;
|
|
20
|
+
readonly status: 'loading' | 'ready' | 'error';
|
|
21
|
+
readonly detail?: MissionNodeDetail;
|
|
22
|
+
readonly error?: string;
|
|
23
|
+
}
|
|
24
|
+
/** How one on-demand full-result read is going, or `undefined` before it has been asked for. */
|
|
25
|
+
export interface FullResultState {
|
|
26
|
+
readonly status: 'loading' | 'ready' | 'error';
|
|
27
|
+
readonly text?: string;
|
|
28
|
+
readonly error?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The result pane for ONE read state, rendered as a pure function so every rule that matters —
|
|
32
|
+
* expanded replaces the head, a failed read keeps the locator, no reader means no button — is
|
|
33
|
+
* testable without a DOM to click in.
|
|
34
|
+
*/
|
|
35
|
+
export declare function ResultPane({ text, pointer, full, canLoad, onToggle }: {
|
|
36
|
+
text: string | null;
|
|
37
|
+
pointer: string | null;
|
|
38
|
+
full: FullResultState | undefined;
|
|
39
|
+
/** Whether a full read is even possible (a `result` face on the host). */
|
|
40
|
+
canLoad: boolean;
|
|
41
|
+
onToggle: () => void;
|
|
42
|
+
}): ReactNode;
|
|
43
|
+
/** One section of the detail dialog: its nav cell and the pane the cell shows. */
|
|
44
|
+
export interface DetailTab {
|
|
45
|
+
readonly id: string;
|
|
46
|
+
readonly label: string;
|
|
47
|
+
/** How many entries the section holds; rendered after the label when present. */
|
|
48
|
+
readonly count?: number;
|
|
49
|
+
readonly body: ReactNode;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The detail's sections, derived from ONE detail read.
|
|
53
|
+
*
|
|
54
|
+
* Exported and pure so the mapping is testable without a DOM: the spec renders to static
|
|
55
|
+
* markup and cannot click a nav cell, so "what does the 纠偏 section hold" has to be
|
|
56
|
+
* askable of a function rather than of a rendered, clicked dialog.
|
|
57
|
+
*
|
|
58
|
+
* A section with nothing to show is ABSENT rather than empty: a 「纠偏」 tab reading
|
|
59
|
+
* 「(无)」 on a mission that was never steered is a section that exists only to say it does
|
|
60
|
+
* not. 内容 / 结果 always exist — every mission has a body to achieve, and "no result yet" is
|
|
61
|
+
* itself a fact about one.
|
|
62
|
+
*
|
|
63
|
+
* 标题 is NOT a section: it heads the dialog (see `MissionDetailDialog`), because it answers
|
|
64
|
+
* "which mission am I looking at" — a question asked before any section is chosen, and one a
|
|
65
|
+
* reader must be able to answer while reading every one of them. What used to share that tab
|
|
66
|
+
* (id / dispatch count / depth) rides the same header as its meta line.
|
|
67
|
+
*
|
|
68
|
+
* Order is the order a reader asks the questions: what it must achieve (内容) → why it exists
|
|
69
|
+
* (上下文) → how the executor reasoned about splitting it (拆解信息) → how the direction
|
|
70
|
+
* changed (纠偏) → what came out (结果) → what the parts reported (子任务).
|
|
71
|
+
*/
|
|
72
|
+
export declare function detailTabs(detail: MissionNodeDetail, options?: {
|
|
73
|
+
readonly loadResult?: (nodeId: string) => Promise<string>;
|
|
74
|
+
}): readonly DetailTab[];
|
|
75
|
+
/**
|
|
76
|
+
* Take everything that is NOT on the path from `overlay` up to `<body>` out of the tab order, and
|
|
77
|
+
* return the undo.
|
|
78
|
+
*
|
|
79
|
+
* `inert` is the platform's own "not tabbable, not clickable, hidden from assistive tech" flag, and
|
|
80
|
+
* the shell's overlays use it for the same reason. Only elements that were not ALREADY inert are
|
|
81
|
+
* touched, so an overlay opened over another one restores exactly what it changed. The walk goes all
|
|
82
|
+
* the way up, not just to the panel's own root: the composer and the sidebars are behind the mask
|
|
83
|
+
* too, and a dialog that lets Tab reach them is modal only in appearance.
|
|
84
|
+
*/
|
|
85
|
+
export declare function inertBackground(overlay: HTMLElement): () => void;
|
|
86
|
+
/**
|
|
87
|
+
* The address of one worker session, exactly as the host's `uiWorkspace.openSession` takes it: the
|
|
88
|
+
* durable parent/child address of a *continuable* subagent — what the main UI sends when a child is
|
|
89
|
+
* picked from the "N 个子智能" dropdown. The PARENT is the owner session this panel belongs to.
|
|
90
|
+
*
|
|
91
|
+
* Exported, with `workerSessionOpen`/`createWorkerSessionClick`/`NodeIdEntry`, because this suite
|
|
92
|
+
* has no DOM: a spec cannot press a rendered button, so it asks these functions (the very ones the
|
|
93
|
+
* entry is wired to) what a click sends. That keeps "点击发出的 target 形状" pinned without adding a
|
|
94
|
+
* browser environment.
|
|
95
|
+
*/
|
|
96
|
+
export declare function workerSessionTarget(parentSessionId: string, workerSessionId: string): WorkerSessionTarget;
|
|
97
|
+
/**
|
|
98
|
+
* What a node-id entry says, in BOTH cases — W18: the id is an entry whether or not the record
|
|
99
|
+
* already names an executor. The wording names the DESTINATION (the session that executed this
|
|
100
|
+
* mission) and its state, because the thing rendered is the MISSION's id and a reader must not
|
|
101
|
+
* mistake the click for "open the task".
|
|
102
|
+
*
|
|
103
|
+
* Without a handle the label stays honest rather than promising a session that may not exist: the
|
|
104
|
+
* click TRIES, and a miss is explained by {@link workerFailureText} instead of being a dead link.
|
|
105
|
+
* That is also why the two forms are not the same sentence — a reader can tell whether a lookup is
|
|
106
|
+
* about to happen.
|
|
107
|
+
*/
|
|
108
|
+
export declare function nodeIdLinkLabel(workerSessionId: string | null | undefined, workerLive: boolean | undefined): string;
|
|
109
|
+
/** Why one click could not open a session. Four kinds, four sentences (see {@link workerFailureText}). */
|
|
110
|
+
export type WorkerSessionFailureReason = 'never-dispatched' | 'not-found' | 'unsupported' | 'open';
|
|
111
|
+
/**
|
|
112
|
+
* The sentence a failed click leaves behind, per reason. Exported and pure so each of the four is
|
|
113
|
+
* pinned by a test (this suite has no DOM) and so no caller has to invent wording:
|
|
114
|
+
*
|
|
115
|
+
* - 「从未派发过」 is a FACT about the record, not a failure to find something;
|
|
116
|
+
* - 「找不到」 is the case the spec names: a node that WAS dispatched, whose session is gone;
|
|
117
|
+
* - 「无法打开」 is the host's own limitation — no `uiWorkspace` to navigate with, no session service
|
|
118
|
+
* to look one up in, or an older host whose Remote face predates the lookup — and the detail says
|
|
119
|
+
* which one, since the three have different remedies;
|
|
120
|
+
* - 「打开失败」 is the one case where a session WAS named and navigation refused it.
|
|
121
|
+
*/
|
|
122
|
+
export declare function workerFailureText(reason: WorkerSessionFailureReason, detail?: string): string;
|
|
123
|
+
/** What a busy button shows instead of the id — a separate export because there is no DOM here to
|
|
124
|
+
* re-render, so the affordance itself is what a test can pin. */
|
|
125
|
+
export declare function workerSessionBusyText(busy: boolean, nodeId: string): string;
|
|
126
|
+
/** What one click did, as data: a test pins the address that was opened, and the panel renders this
|
|
127
|
+
* failure instead of the click having "done nothing". */
|
|
128
|
+
export type WorkerSessionOpenOutcome = {
|
|
129
|
+
readonly opened: true;
|
|
130
|
+
readonly workerSessionId: string;
|
|
131
|
+
} | {
|
|
132
|
+
readonly opened: false;
|
|
133
|
+
readonly reason: WorkerSessionFailureReason;
|
|
134
|
+
readonly message: string;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* The panel's one click handler, W18: the node id is ALWAYS an entry, and the session is resolved
|
|
138
|
+
* lazily when the record does not already name one.
|
|
139
|
+
*
|
|
140
|
+
* Order: ① a handle on the record opens immediately (zero I/O); ② otherwise `resolveSession` asks the
|
|
141
|
+
* host, and ONLY a `resolved` answer is opened; ③ a miss becomes a sentence about WHY — never a throw,
|
|
142
|
+
* never a blank panel. `onLookupStart` fires before the first await, which is what lets the button
|
|
143
|
+
* say 查找中… instead of looking like it ignored the click.
|
|
144
|
+
*
|
|
145
|
+
* `open` may throw or answer with a rejected promise (the session really was cleaned up): both become
|
|
146
|
+
* the `open` failure. The panel must never blank — or lose its place — because a link went stale,
|
|
147
|
+
* which is the one failure a link invited by us can cause.
|
|
148
|
+
*/
|
|
149
|
+
export declare function workerSessionOpen(input: {
|
|
150
|
+
readonly nodeId: string;
|
|
151
|
+
readonly parentSessionId: string;
|
|
152
|
+
/** The handle already on the record, when there is one. */
|
|
153
|
+
readonly workerSessionId?: string | null;
|
|
154
|
+
readonly open?: (target: WorkerSessionTarget) => unknown;
|
|
155
|
+
readonly resolveSession?: (nodeId: string) => Promise<ExecutorSessionLookup>;
|
|
156
|
+
readonly onLookupStart?: () => void;
|
|
157
|
+
}): Promise<WorkerSessionOpenOutcome>;
|
|
158
|
+
/**
|
|
159
|
+
* The click handler the entry is wired to, as a function of the entry's own state setters.
|
|
160
|
+
*
|
|
161
|
+
* Split out for the same reason `workerSessionTarget` is: this suite has no DOM, so "what a click
|
|
162
|
+
* does" has to be askable of a function rather than of a rendered, clicked button. It is also where
|
|
163
|
+
* the 查找中… bookkeeping lives — `onLookupStart` fires only when a lookup is really needed, so a
|
|
164
|
+
* click that already has a handle does not flash a wait state it never had.
|
|
165
|
+
*/
|
|
166
|
+
export declare function createWorkerSessionClick(input: {
|
|
167
|
+
readonly nodeId: string;
|
|
168
|
+
readonly parentSessionId: string;
|
|
169
|
+
readonly workerSessionId?: string | null;
|
|
170
|
+
readonly open?: (target: WorkerSessionTarget) => unknown;
|
|
171
|
+
readonly resolveSession?: (nodeId: string) => Promise<ExecutorSessionLookup>;
|
|
172
|
+
/** Whether a click is already in flight; a second one is ignored rather than queued. */
|
|
173
|
+
readonly busy: boolean;
|
|
174
|
+
readonly setBusy: (busy: boolean) => void;
|
|
175
|
+
readonly setFailed: (failed: boolean) => void;
|
|
176
|
+
readonly onFailure: (message: string) => void;
|
|
177
|
+
}): () => Promise<void>;
|
|
178
|
+
/**
|
|
179
|
+
* One node id as an ENTRY. W18: the id is clickable on EVERY node — an existing handle opens its
|
|
180
|
+
* session directly, and a historical record without one is looked up at CLICK time (the lookup reads
|
|
181
|
+
* session logs, so it must never happen while rendering). Both places that show a node id (the tree
|
|
182
|
+
* header's root id and the detail dialog's heading) render this, so the same thing never becomes two
|
|
183
|
+
* links — W8 put a second, separate link on the worker session id, and that link is what this
|
|
184
|
+
* replaces.
|
|
185
|
+
*
|
|
186
|
+
* Two degradation paths, both deliberate:
|
|
187
|
+
* ① the host cannot complete the jump — no `uiWorkspace` service, no session service, or an older
|
|
188
|
+
* host whose Remote face predates the lookup → the click SAYS which
|
|
189
|
+
* ({@link workerFailureText}); the id stays an entry rather than a dead-looking one, so the
|
|
190
|
+
* explanation is one click away instead of a tooltip a reader has to go looking for;
|
|
191
|
+
* ② `open` throws or rejects (the session really was cleaned up) → `onFailure` turns it into the
|
|
192
|
+
* caller's message; the panel never blanks and never loses its place.
|
|
193
|
+
*/
|
|
194
|
+
export declare function NodeIdEntry({ nodeId, workerSessionId, workerLive, sessionId, open, onFailure, resolveSession, className, }: {
|
|
195
|
+
/** The MISSION's id — what is rendered; the session is only the destination. */
|
|
196
|
+
nodeId: string;
|
|
197
|
+
workerSessionId: string | null | undefined;
|
|
198
|
+
workerLive?: boolean;
|
|
199
|
+
/** The owner session the worker hangs under — the parent half of the address. */
|
|
200
|
+
sessionId: string;
|
|
201
|
+
open?: (target: WorkerSessionTarget) => void;
|
|
202
|
+
onFailure: (message: string) => void;
|
|
203
|
+
/** The click-time lookup; absent on a host whose Remote face predates it (see `MissionViewProps`). */
|
|
204
|
+
resolveSession?: (nodeId: string) => Promise<ExecutorSessionLookup>;
|
|
205
|
+
/** The caller's own monospace slot class, applied to both the link and the plain-text form. */
|
|
206
|
+
className: string;
|
|
207
|
+
}): ReactNode;
|
|
208
|
+
/**
|
|
209
|
+
* The inline message a failed open leaves behind. Split out as a pure component, like `ResultPane`,
|
|
210
|
+
* so its markup is testable without a DOM to click in; the dialog owns the state that shows it.
|
|
211
|
+
*/
|
|
212
|
+
export declare function WorkerSessionHint({ message }: {
|
|
213
|
+
message: string;
|
|
214
|
+
}): ReactNode;
|
|
215
|
+
/**
|
|
216
|
+
* One mission's detail as a MODAL panel: a section rail on the left, the chosen section in a
|
|
217
|
+
* scrollable column on the right — the shell's 设置 dialog, sized for reading (1040×880, capped
|
|
218
|
+
* by the viewport) rather than the settings' 800×800.
|
|
219
|
+
*
|
|
220
|
+
* The heading is the mission's own TITLE, not a 「标题」 section: "which mission is this" is asked
|
|
221
|
+
* before a section is chosen and must stay answerable while reading every one of them.
|
|
222
|
+
*
|
|
223
|
+
* Why a dialog instead of an expanding row: the detail exists to be READ and it runs long —
|
|
224
|
+
* a description, every correction, every child's conclusion. Inline, it pushed the tree down
|
|
225
|
+
* by however much the text happened to be, so comparing two missions meant scrolling one of
|
|
226
|
+
* them out of sight. A fixed panel with its own scroll keeps the tree where it was.
|
|
227
|
+
*/
|
|
228
|
+
export declare function MissionDetailDialog({ nodeId, state, onClose, loadResult, sessionId, openWorkerSession, resolveWorkerSession }: {
|
|
229
|
+
nodeId: string;
|
|
230
|
+
/** `undefined` until this node's first read lands; a loading state once it has been asked for. */
|
|
231
|
+
state: DialogState | undefined;
|
|
232
|
+
onClose: () => void;
|
|
233
|
+
/** Read a spilled result back in full. Absent in a host that has no `result` face, and then the
|
|
234
|
+
* pane shows the locator without offering a read it cannot perform. */
|
|
235
|
+
loadResult?: (nodeId: string) => Promise<string>;
|
|
236
|
+
/** The owner session the shown mission's worker hangs under — the parent half of the address. */
|
|
237
|
+
sessionId: string;
|
|
238
|
+
/** Open the executor's session; absent on a host with no `uiWorkspace` service, and then the id
|
|
239
|
+
* is rendered as plain text instead of a dead link (see `MissionViewProps.openWorkerSession`). */
|
|
240
|
+
openWorkerSession?: (target: WorkerSessionTarget) => void;
|
|
241
|
+
/** The click-time lookup for a record with no handle (see `MissionViewProps.resolveWorkerSession`). */
|
|
242
|
+
resolveWorkerSession?: (nodeId: string) => Promise<ExecutorSessionLookup>;
|
|
243
|
+
}): ReactNode;
|
|
244
|
+
/** Render the session's mission trees. */
|
|
245
|
+
export declare function MissionTreeView({ useSnapshot, onDeleteTree, onCleanFinished, loadDetail, loadResult, sessionId, openWorkerSession, resolveWorkerSession, }: MissionViewProps): ReactNode;
|
|
246
|
+
export {};
|
|
247
|
+
//# sourceMappingURL=MissionTreeView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MissionTreeView.d.ts","sourceRoot":"","sources":["../../../src/client/MissionTreeView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAsF,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAE1H,OAAO,KAAK,EACV,qBAAqB,EACrB,iBAAiB,EAGjB,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,eAAe,CAAA;AA0EtB;;;;GAIG;AACH,UAAU,WAAW;IACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,CAAA;IAC9C,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAA;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB;AA8BD,gGAAgG;AAChG,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,CAAA;IAC9C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;IACrE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,IAAI,EAAE,eAAe,GAAG,SAAS,CAAA;IACjC,0EAA0E;IAC1E,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,MAAM,IAAI,CAAA;CACrB,GAAG,SAAS,CAoCZ;AAuCD,kFAAkF;AAClF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,iFAAiF;IACjF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CACzB;AAkCD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE;IAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CAAO,GAC1E,SAAS,SAAS,EAAE,CAwFtB;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,IAAI,CAiBhE;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,mBAAmB,CAEzG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC1C,UAAU,EAAE,OAAO,GAAG,SAAS,GAC9B,MAAM,CAIR;AAED,0GAA0G;AAC1G,MAAM,MAAM,0BAA0B,GAAG,kBAAkB,GAAG,WAAW,GAAG,aAAa,GAAG,MAAM,CAAA;AAElG;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,0BAA0B,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAc7F;AAED;kEACkE;AAClE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED;0DAC0D;AAC1D,MAAM,MAAM,wBAAwB,GAChC;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,0BAA0B,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAErG;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,2DAA2D;IAC3D,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,OAAO,CAAA;IACxD,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAA;IAC5E,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,IAAI,CAAA;CACpC,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAmCpC;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,OAAO,CAAA;IACxD,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAA;IAC5E,wFAAwF;IACxF,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACzC,QAAQ,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;IAC7C,QAAQ,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9C,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAgBtB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EAAE,eAAe,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,GAC3F,EAAE;IACD,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IAC1C,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,iFAAiF;IACjF,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAA;IAC5C,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,sGAAsG;IACtG,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACnE,+FAA+F;IAC/F,SAAS,EAAE,MAAM,CAAA;CAClB,GAAG,SAAS,CAoCZ;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAE7E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,EAAE;IAC9H,MAAM,EAAE,MAAM,CAAA;IACd,kGAAkG;IAClG,KAAK,EAAE,WAAW,GAAG,SAAS,CAAA;IAC9B,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB;4EACwE;IACxE,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IAChD,iGAAiG;IACjG,SAAS,EAAE,MAAM,CAAA;IACjB;uGACmG;IACnG,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAA;IACzD,uGAAuG;IACvG,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAA;CAC1E,GAAG,SAAS,CAyHZ;AAuTD,0CAA0C;AAC1C,wBAAgB,eAAe,CAAC,EAC9B,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,iBAAiB,EAAE,oBAAoB,GACvH,EAAE,gBAAgB,GAAG,SAAS,CA2K9B"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import type { ExecutorSessionLookup, MissionNodeDetail, MissionSnapshot } from './contract.js';
|
|
2
|
+
/** Safety-net re-read interval; slow on purpose, since the session itself is the primary trigger. */
|
|
3
|
+
export declare const POLL_INTERVAL_MS = 5000;
|
|
4
|
+
/**
|
|
5
|
+
* Coalescing window: one turn's burst of session revisions becomes a single read.
|
|
6
|
+
*/
|
|
7
|
+
export declare const REFRESH_COALESCE_MS = 400;
|
|
8
|
+
/**
|
|
9
|
+
* How often the panel re-reads even while the engine's change stream is up. The stream is the update
|
|
10
|
+
* channel, but a stream that is silently dead (open, delivering nothing) is not detectable from this
|
|
11
|
+
* side, and the panel must not be able to go stale forever — this bounds the staleness. It is not a
|
|
12
|
+
* "poll": at 30 s it is a backstop, and a healthy stream still gives sub-second freshness.
|
|
13
|
+
*/
|
|
14
|
+
export declare const STREAM_KEEPALIVE_MS = 30000;
|
|
15
|
+
/**
|
|
16
|
+
* The cheap session-side value that changes when the mission tree may have. It deliberately does NOT
|
|
17
|
+
* include the chat node count: the mission tree is not a function of how many messages the
|
|
18
|
+
* conversation holds, and folding that in made every chat activity re-read and re-render the whole
|
|
19
|
+
* tree (the stream is what carries actual mission changes; `queued`/`running` are the session-side
|
|
20
|
+
* facts that matter).
|
|
21
|
+
*/
|
|
22
|
+
export declare function sessionRevision(input: {
|
|
23
|
+
readonly queued: number;
|
|
24
|
+
readonly running: boolean;
|
|
25
|
+
}): string;
|
|
26
|
+
/** The Remote namespace surface this plugin consumes. */
|
|
27
|
+
export interface MissionRemote {
|
|
28
|
+
snapshot: (args: {
|
|
29
|
+
sessionId: string;
|
|
30
|
+
}) => Promise<unknown>;
|
|
31
|
+
detail: (args: {
|
|
32
|
+
sessionId: string;
|
|
33
|
+
nodeId: string;
|
|
34
|
+
}) => Promise<unknown>;
|
|
35
|
+
delete: (args: {
|
|
36
|
+
sessionId: string;
|
|
37
|
+
rootId: string;
|
|
38
|
+
}) => Promise<unknown>;
|
|
39
|
+
/** Delete EVERY closed tree this session owns (the panel's "清理已完成"). Optional for the same
|
|
40
|
+
* reason as `result`: an older host has no such method, and the panel refuses to send the call
|
|
41
|
+
* rather than reading the gateway's 404 as "the missions are gone". */
|
|
42
|
+
cleanFinished?: (args: {
|
|
43
|
+
sessionId: string;
|
|
44
|
+
}) => Promise<unknown>;
|
|
45
|
+
/** The FULL text behind a spilled result. Optional for the same reason `watch` is: an older host
|
|
46
|
+
* simply does not have it, and the pane falls back to showing the locator. */
|
|
47
|
+
result?: (args: {
|
|
48
|
+
sessionId: string;
|
|
49
|
+
nodeId: string;
|
|
50
|
+
}) => Promise<unknown>;
|
|
51
|
+
/** The click-time executor lookup (W18). Optional for the same reason as `result`: an older host
|
|
52
|
+
* has no such method, and the panel says "the two halves are out of step" instead of guessing. */
|
|
53
|
+
resolveExecutorSession?: (args: {
|
|
54
|
+
sessionId: string;
|
|
55
|
+
nodeId: string;
|
|
56
|
+
}) => Promise<unknown>;
|
|
57
|
+
/** The engine's change stream, called with the transport's cancellation signal.
|
|
58
|
+
* Optional: an older host may not expose it, so the caller keeps its timer fallback. */
|
|
59
|
+
watch?: (args: {
|
|
60
|
+
sessionId: string;
|
|
61
|
+
}, signal: AbortSignal) => AsyncIterable<unknown>;
|
|
62
|
+
}
|
|
63
|
+
/** A timer as the client platform publishes it (`interval` returns its disposer). */
|
|
64
|
+
export interface IntervalTimer {
|
|
65
|
+
interval: (callback: () => void, delay: number) => () => void;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The human half of a failure. `Error#message` is NOT an own enumerable property, so a plain
|
|
69
|
+
* `JSON.stringify(error)` drops exactly the sentence a reader needs and leaves `{"code":…}` — the
|
|
70
|
+
* `RemoteError` this boundary carries is an `Error` subclass with `code`/`details` as the own ones.
|
|
71
|
+
* So: the message first, the JSON only when there is no message to show.
|
|
72
|
+
*/
|
|
73
|
+
export declare function errorText(error: unknown): string;
|
|
74
|
+
/**
|
|
75
|
+
* Collapse a burst of triggers into ONE call after `delayMs` of quiet.
|
|
76
|
+
*
|
|
77
|
+
* The mission tree has three refresh triggers (the session revision, the engine's change stream, and the
|
|
78
|
+
* stream's reopen) and the engine pushes a frame per state change, so without this a burst of changes
|
|
79
|
+
* costs one snapshot RPC per frame. `cancel` releases a pending call — the disposer of the effect that
|
|
80
|
+
* owns the coalescer, so leaving the tab cannot fire a read into an unmounted panel.
|
|
81
|
+
*/
|
|
82
|
+
export declare function coalesce(run: () => void, delayMs: number): {
|
|
83
|
+
request: () => void;
|
|
84
|
+
cancel: () => void;
|
|
85
|
+
};
|
|
86
|
+
/** Peel the transport envelope (`{ ok, value }` / `{ ok, error }`, or a bare value) so a
|
|
87
|
+
* wiring mistake surfaces as a message rather than an empty view. */
|
|
88
|
+
export declare function unwrap(response: unknown): {
|
|
89
|
+
value?: unknown;
|
|
90
|
+
error?: string;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* The version-skew note for one `snapshot` payload, or `undefined` when the two halves agree.
|
|
94
|
+
*
|
|
95
|
+
* WHY A NOTE AND NOT A THROW. The host half is loaded ONCE when `dsh web` starts; this bundle is
|
|
96
|
+
* re-read on every page load. So a rebuilt client routinely talks to an older host, and the ONE thing
|
|
97
|
+
* the marker must never do is blank the panel: `snapshot` is the entry point every other read hangs
|
|
98
|
+
* off, and an unrecognised revision usually still carries the fields the panel renders. So an absent
|
|
99
|
+
* marker ("host predates it") and an unknown one ("host is newer") both come back as a note beside the
|
|
100
|
+
* tree, never as a failed read.
|
|
101
|
+
*
|
|
102
|
+
* `wire` is read off the RAW payload rather than a validated field: the schema accepts any number, and
|
|
103
|
+
* a payload whose `wire` is missing must not be reported as a shape failure.
|
|
104
|
+
*/
|
|
105
|
+
export declare function snapshotSkew(value: unknown): string | undefined;
|
|
106
|
+
/** Read one session's trees; throws with the reason when the read cannot be trusted. */
|
|
107
|
+
export declare function fetchSnapshot(remote: MissionRemote, sessionId: string): Promise<MissionSnapshot>;
|
|
108
|
+
/**
|
|
109
|
+
* Delete one whole finished mission tree by root — the unit is the TREE; a refusal travels in
|
|
110
|
+
* the result envelope and becomes an exception here.
|
|
111
|
+
*/
|
|
112
|
+
export declare function deleteWork(remote: MissionRemote, sessionId: string, rootId: string): Promise<readonly string[]>;
|
|
113
|
+
/**
|
|
114
|
+
* Delete EVERY closed tree this session owns — the batch entry behind the panel's "清理已完成".
|
|
115
|
+
*
|
|
116
|
+
* The first half is the version-skew gate, exactly as {@link fetchExecutorSession}'s: against a host
|
|
117
|
+
* whose `wire` predates the method, sending the call can only produce a gateway 404 that reads like
|
|
118
|
+
* "the missions are gone". The call is not sent, and the sentence names the remedy (restart dsh).
|
|
119
|
+
*
|
|
120
|
+
* Returns the two id lists the host reported — the roots removed and the roots kept because they were
|
|
121
|
+
* never retired — so the caller can render "N removed / M skipped" without parsing prose.
|
|
122
|
+
*/
|
|
123
|
+
export declare function cleanFinishedWork(remote: MissionRemote, sessionId: string, hostWire?: number): Promise<{
|
|
124
|
+
deleted: readonly string[];
|
|
125
|
+
skipped: readonly string[];
|
|
126
|
+
}>;
|
|
127
|
+
export declare function asDetail(value: unknown): Partial<MissionNodeDetail> & {
|
|
128
|
+
error?: string;
|
|
129
|
+
};
|
|
130
|
+
/** Read one mission's full detail on demand — results run to 2 KB each, and the snapshot re-reads on change. */
|
|
131
|
+
export declare function fetchDetail(remote: MissionRemote, sessionId: string, nodeId: string): Promise<MissionNodeDetail>;
|
|
132
|
+
/**
|
|
133
|
+
* Name a transport failure that is really a VERSION SKEW.
|
|
134
|
+
*
|
|
135
|
+
* The two halves of this plugin do not update together: the browser bundle is re-read on every page
|
|
136
|
+
* load, the host half is loaded once when `dsh web` starts. So a rebuilt plugin routinely talks to an
|
|
137
|
+
* older host, and the gateway answers a method that host never published with an HTTP 404 — which
|
|
138
|
+
* reads exactly like "the mission or the file is gone", the two things it does NOT mean. The sentence
|
|
139
|
+
* therefore names the missing REGISTRATION (an older host, or one that was never restarted) rather
|
|
140
|
+
* than only repeating the transport text.
|
|
141
|
+
*/
|
|
142
|
+
export declare function transportHint(cause: unknown): string;
|
|
143
|
+
/**
|
|
144
|
+
* Read the FULL text behind a spilled result. On demand only: the pane offering it is answering a
|
|
145
|
+
* question ("show me all of it"), and the host reads a file to answer — so nothing prefetches it.
|
|
146
|
+
* A host that cannot resolve the locator answers with a reason instead, which the pane shows beside
|
|
147
|
+
* the locator rather than as a failed read.
|
|
148
|
+
*/
|
|
149
|
+
export declare function fetchFullResult(remote: MissionRemote, sessionId: string, nodeId: string): Promise<string>;
|
|
150
|
+
/**
|
|
151
|
+
* Ask the host to find the session that ran one node (W18). CALLED ONLY FROM A CLICK: the server
|
|
152
|
+
* side lists the session corpus and reads a few logs, which is exactly the cost the panel must not
|
|
153
|
+
* pay while rendering.
|
|
154
|
+
*
|
|
155
|
+
* Four failure shapes, kept apart on purpose:
|
|
156
|
+
* - the host reports a `wire` older than the method (an older host, or one never restarted) → the call
|
|
157
|
+
* is NOT SENT at all, and the sentence names the remedy (restart dsh);
|
|
158
|
+
* - the host has no such method despite a current `wire` → the same version-skew sentence;
|
|
159
|
+
* - the call itself failed (transport) → `transportHint`'s reading of it;
|
|
160
|
+
* - the host ANSWERED "never dispatched" / "not found" / "cannot look up" → returned as an answer,
|
|
161
|
+
* because those are outcomes a reader must be told about, not failures of the panel.
|
|
162
|
+
*
|
|
163
|
+
* `hostWire` is the revision the host reported on its last `snapshot` (carried on the snapshot the
|
|
164
|
+
* panel renders from). Checked FIRST and before the remote is even touched: against a host that never
|
|
165
|
+
* registered the method, sending the call can only produce a gateway 404 that reads like a deleted
|
|
166
|
+
* mission (see `transportHint`).
|
|
167
|
+
*/
|
|
168
|
+
export declare function fetchExecutorSession(remote: MissionRemote, sessionId: string, nodeId: string, hostWire?: number): Promise<ExecutorSessionLookup>;
|
|
169
|
+
/**
|
|
170
|
+
* Follow the engine's change stream, calling `onChange` per frame; the frame carries a
|
|
171
|
+
* revision and nothing else. The CALLER decides what a normal end means.
|
|
172
|
+
*/ export declare function watchChanges(remote: MissionRemote, sessionId: string, signal: AbortSignal, onChange: () => void): Promise<void>;
|
|
173
|
+
export declare const STREAM_REOPEN_MS = 1000;
|
|
174
|
+
/**
|
|
175
|
+
* Start re-reading on a timer — a poll, not a subscription, because the tree lives in a
|
|
176
|
+
* host-side KV domain with no event feed. Two rungs because the platform `timer` service is
|
|
177
|
+
* NOT reliably mounted: the service is preferred, the browser's own timers are the fallback.
|
|
178
|
+
*/
|
|
179
|
+
export declare function startPolling(refresh: () => void, intervalMs: number, service: Partial<IntervalTimer> | undefined, host?: HostTimers): () => void;
|
|
180
|
+
export interface HostTimers {
|
|
181
|
+
setInterval?: (callback: () => void, delay: number) => unknown;
|
|
182
|
+
clearInterval?: (handle: unknown) => void;
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/client/api.ts"],"names":[],"mappings":"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"}
|