@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.
Files changed (74) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +249 -0
  3. package/cordis.patch.yml +13 -0
  4. package/lib/client.js +225 -0
  5. package/lib/dsh-build.json +16 -0
  6. package/lib/envinit-bootstrap.js +334 -0
  7. package/lib/index.js +7021 -0
  8. package/lib/interface-version.json +4 -0
  9. package/lib/mission-core/capacity.d.ts +100 -0
  10. package/lib/mission-core/continuation.d.ts +106 -0
  11. package/lib/mission-core/dispatch.d.ts +165 -0
  12. package/lib/mission-core/engine.d.ts +331 -0
  13. package/lib/mission-core/index.d.ts +25 -0
  14. package/lib/mission-core/liveness.d.ts +99 -0
  15. package/lib/mission-core/prompt.d.ts +112 -0
  16. package/lib/mission-core/resources.d.ts +57 -0
  17. package/lib/mission-core/timing.d.ts +37 -0
  18. package/lib/mission-core/tree.d.ts +447 -0
  19. package/lib/mission-core/trouble.d.ts +40 -0
  20. package/lib/mission-core/types.d.ts +409 -0
  21. package/lib/mission-core/wellformed.d.ts +98 -0
  22. package/lib/types/claims.d.ts +3 -0
  23. package/lib/types/claims.d.ts.map +1 -0
  24. package/lib/types/client/MissionTreeView.d.ts +247 -0
  25. package/lib/types/client/MissionTreeView.d.ts.map +1 -0
  26. package/lib/types/client/api.d.ts +184 -0
  27. package/lib/types/client/api.d.ts.map +1 -0
  28. package/lib/types/client/contract.d.ts +209 -0
  29. package/lib/types/client/contract.d.ts.map +1 -0
  30. package/lib/types/client/index.d.ts +48 -0
  31. package/lib/types/client/index.d.ts.map +1 -0
  32. package/lib/types/client/seat.d.ts +26 -0
  33. package/lib/types/client/seat.d.ts.map +1 -0
  34. package/lib/types/client/styles.d.ts +6 -0
  35. package/lib/types/client/styles.d.ts.map +1 -0
  36. package/lib/types/coldResume.d.ts +123 -0
  37. package/lib/types/coldResume.d.ts.map +1 -0
  38. package/lib/types/domain.d.ts +93 -0
  39. package/lib/types/domain.d.ts.map +1 -0
  40. package/lib/types/envinit.d.ts +126 -0
  41. package/lib/types/envinit.d.ts.map +1 -0
  42. package/lib/types/executorSession.d.ts +129 -0
  43. package/lib/types/executorSession.d.ts.map +1 -0
  44. package/lib/types/faces.d.ts +30 -0
  45. package/lib/types/faces.d.ts.map +1 -0
  46. package/lib/types/host.d.ts +752 -0
  47. package/lib/types/host.d.ts.map +1 -0
  48. package/lib/types/index.d.ts +48 -0
  49. package/lib/types/index.d.ts.map +1 -0
  50. package/lib/types/interface_gate.d.ts +51 -0
  51. package/lib/types/interface_gate.d.ts.map +1 -0
  52. package/lib/types/log.d.ts +18 -0
  53. package/lib/types/log.d.ts.map +1 -0
  54. package/lib/types/projectionCache.d.ts +22 -0
  55. package/lib/types/projectionCache.d.ts.map +1 -0
  56. package/lib/types/prompt.d.ts +106 -0
  57. package/lib/types/prompt.d.ts.map +1 -0
  58. package/lib/types/source.d.ts +22 -0
  59. package/lib/types/source.d.ts.map +1 -0
  60. package/lib/types/store.d.ts +20 -0
  61. package/lib/types/store.d.ts.map +1 -0
  62. package/lib/types/timeFormat.d.ts +56 -0
  63. package/lib/types/timeFormat.d.ts.map +1 -0
  64. package/lib/types/tools.d.ts +34 -0
  65. package/lib/types/tools.d.ts.map +1 -0
  66. package/lib/types/wellformed.d.ts +43 -0
  67. package/lib/types/wellformed.d.ts.map +1 -0
  68. package/lib/types/wire.d.ts +178 -0
  69. package/lib/types/wire.d.ts.map +1 -0
  70. package/lib/types/workerEvents.d.ts +36 -0
  71. package/lib/types/workerEvents.d.ts.map +1 -0
  72. package/lib/types/workerSessions.d.ts +256 -0
  73. package/lib/types/workerSessions.d.ts.map +1 -0
  74. package/package.json +145 -0
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Hand-written Typert wire faces (host and client): the generator only runs inside the
3
+ * harness workspace, and both halves import this one module so the two faces cannot drift.
4
+ * @module @avantf/dsh-mission/wire
5
+ */
6
+ import * as z from 'zod';
7
+ import type { InvocationDescriptor } from '@deepseek-ai/dsh-typert-protocol';
8
+ export declare const PACKAGE = "@avantf/dsh-mission";
9
+ /** The Cordis service key that doubles as the Remote namespace. */
10
+ export declare const NAMESPACE = "avantfMission";
11
+ /**
12
+ * How many of a node's corrections the ROW projection carries. The texts themselves stay (a row marks
13
+ * a steered mission, and the tooltip explains a title that no longer matches its result), but a node
14
+ * whose owner corrected it many times must not make every frame carry all of them: past this many, the
15
+ * row keeps the NEWEST ones and {@link nodeSchema}'s `correctionCount` still reports the true number.
16
+ * The detail dialog is not affected — it reads every correction from `detailResultSchema`.
17
+ */
18
+ export declare const ROW_CORRECTIONS_MAX = 5;
19
+ /**
20
+ * The wire surface: `snapshot` the summary, `detail` one node's full record, `result` the FULL text
21
+ * behind a spilled one (on demand — a reader asks for it, the panel never prefetches it), `delete`
22
+ * one finished tree, `cleanFinished` every CLOSED tree this session owns (the panel's batch entry),
23
+ * `watch` a revision on every change (the engine pushing, not polling), and `resolveExecutorSession`
24
+ * the CLICK-TIME lookup of a historical node's executor session (W18 — it reads session logs, so it
25
+ * is deliberately NOT part of any render path).
26
+ * Every method carries a session id because a Remote invocation has no caller identity.
27
+ */
28
+ export declare const descriptors: readonly InvocationDescriptor[];
29
+ /**
30
+ * The `snapshot` result, mirrored by the client-side contract.
31
+ *
32
+ * THE VERSION FIELD. `snapshot` is the panel's ONE entry point (every other call is on demand behind a
33
+ * click), so the version marker lives here and nowhere else: one number that tells the browser half
34
+ * which host it is talking to, without adding a field to every method's arguments.
35
+ *
36
+ * `wire` is a plain optional number, NOT `z.literal(...)`: an unrecognized revision has to reach the
37
+ * client as a HINT (`client/api.ts` compares it against `SNAPSHOT_WIRE_VERSION`), and a literal would
38
+ * make `safeParse` fail and blank the whole panel — exactly the degradation the marker exists to
39
+ * avoid. Absent means "an older host that predates the marker": still readable, with a hint.
40
+ *
41
+ * WHY ADDING A REMOTE **MUST** BUMP THIS. The marker only pays for itself if it tracks the SET OF
42
+ * METHODS the host publishes, not the shape of one payload. The two halves of this plugin do not
43
+ * update together — the browser bundle is re-read on every page load, the host half only when `dsh
44
+ * web` starts — so a rebuilt client routinely talks to a host process loaded before the new method
45
+ * existed. The gateway answers a method that host never published with an HTTP 404, which reads
46
+ * exactly like "the mission or the file is gone" (measured: clicking the historical node `059f56ed`).
47
+ * A bumped revision is what lets the client refuse to make that call at all (`client/api.ts` gates
48
+ * the click-time lookup on {@link EXECUTOR_LOOKUP_WIRE_VERSION}). Bump on every added/removed
49
+ * `@Remote` method; do NOT bump for a new optional FIELD, which a `.default(...)`-carrying schema
50
+ * already absorbs across the gap.
51
+ *
52
+ * Revision history:
53
+ * - 1: `snapshot` / `detail` / `result` / `delete` / `watch`.
54
+ * - 2: `resolveExecutorSession` added (W18) — it shipped WITHOUT this bump, which is the defect the
55
+ * revision repairs.
56
+ * - 3: `cleanFinished` added — the panel's batch entry for a session's CLOSED task trees (the same
57
+ * semantics as `/clean missions all`).
58
+ */
59
+ export declare const SNAPSHOT_WIRE_VERSION = 3;
60
+ /**
61
+ * The wire revision that FIRST carried `resolveExecutorSession`. A host reporting less than this — or
62
+ * reporting no `wire` at all, i.e. one older than the marker — has never registered the method, so
63
+ * `fetchExecutorSession` refuses to SEND the call and says that restarting dsh fixes it. Kept here
64
+ * beside {@link SNAPSHOT_WIRE_VERSION} so the two revisions are read together; the current client
65
+ * advertises the newer one.
66
+ */
67
+ export declare const EXECUTOR_LOOKUP_WIRE_VERSION = 2;
68
+ /**
69
+ * The wire revision that FIRST carried `cleanFinished`. Same gate as the executor lookup, for the
70
+ * same reason: a rebuilt panel talking to a host process from before the method existed would get a
71
+ * gateway 404, which reads like "the mission is gone". The panel refuses to send the call and names
72
+ * the remedy instead.
73
+ */
74
+ export declare const CLEAN_FINISHED_WIRE_VERSION = 3;
75
+ export declare const snapshotResultSchema: z.ZodObject<{
76
+ wire: z.ZodOptional<z.ZodNumber>;
77
+ trees: z.ZodArray<z.ZodObject<{
78
+ rootId: z.ZodString;
79
+ nodes: z.ZodArray<z.ZodObject<{
80
+ id: z.ZodString;
81
+ parentId: z.ZodNullable<z.ZodString>;
82
+ children: z.ZodArray<z.ZodString>;
83
+ depth: z.ZodNumber;
84
+ title: z.ZodString;
85
+ context: z.ZodArray<z.ZodString>;
86
+ contextCount: z.ZodDefault<z.ZodNumber>;
87
+ corrections: z.ZodArray<z.ZodString>;
88
+ correctionCount: z.ZodDefault<z.ZodNumber>;
89
+ status: z.ZodString;
90
+ attempts: z.ZodNumber;
91
+ createdAt: z.ZodNumber;
92
+ dispatchedAt: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
93
+ endedAt: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
94
+ hasResult: z.ZodBoolean;
95
+ resultRef: z.ZodNullable<z.ZodString>;
96
+ workerSessionId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
97
+ workerLive: z.ZodDefault<z.ZodBoolean>;
98
+ weight: z.ZodDefault<z.ZodNumber>;
99
+ waitingFor: z.ZodDefault<z.ZodNullable<z.ZodObject<{
100
+ reason: z.ZodEnum<{
101
+ unit: "unit";
102
+ capacity: "capacity";
103
+ slot: "slot";
104
+ aging: "aging";
105
+ }>;
106
+ resource: z.ZodOptional<z.ZodEnum<{
107
+ cpu: "cpu";
108
+ memory: "memory";
109
+ }>>;
110
+ needed: z.ZodOptional<z.ZodNumber>;
111
+ available: z.ZodOptional<z.ZodNumber>;
112
+ unit: z.ZodOptional<z.ZodString>;
113
+ }, z.core.$strip>>>;
114
+ }, z.core.$strip>>;
115
+ closedAt: z.ZodNullable<z.ZodNumber>;
116
+ }, z.core.$strip>>;
117
+ }, z.core.$strip>;
118
+ /**
119
+ * What one batch cleanup did: the ROOT ids of the closed trees removed, and the root ids left
120
+ * standing. `skipped` is the session's own trees that are not closed out — never another session's
121
+ * tree, which this call does not even look at. Both halves are plain id lists so the panel can say
122
+ * "N removed / M skipped" without parsing prose.
123
+ */
124
+ export declare const cleanFinishedResultSchema: z.ZodObject<{
125
+ deleted: z.ZodArray<z.ZodString>;
126
+ skipped: z.ZodArray<z.ZodString>;
127
+ }, z.core.$strip>;
128
+ export declare const detailResultSchema: z.ZodObject<{
129
+ node: z.ZodOptional<z.ZodObject<{
130
+ id: z.ZodString;
131
+ rootId: z.ZodString;
132
+ title: z.ZodString;
133
+ description: z.ZodString;
134
+ context: z.ZodArray<z.ZodString>;
135
+ corrections: z.ZodArray<z.ZodString>;
136
+ analysisNotes: z.ZodArray<z.ZodString>;
137
+ analysisAttempt: z.ZodNumber;
138
+ status: z.ZodString;
139
+ attempts: z.ZodNumber;
140
+ depth: z.ZodNumber;
141
+ createdAt: z.ZodOptional<z.ZodNumber>;
142
+ dispatchedAt: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
143
+ endedAt: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
144
+ result: z.ZodNullable<z.ZodString>;
145
+ resultPointer: z.ZodNullable<z.ZodString>;
146
+ workerSessionId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
147
+ workerLive: z.ZodDefault<z.ZodBoolean>;
148
+ weight: z.ZodDefault<z.ZodNumber>;
149
+ waitingFor: z.ZodDefault<z.ZodNullable<z.ZodObject<{
150
+ reason: z.ZodEnum<{
151
+ unit: "unit";
152
+ capacity: "capacity";
153
+ slot: "slot";
154
+ aging: "aging";
155
+ }>;
156
+ resource: z.ZodOptional<z.ZodEnum<{
157
+ cpu: "cpu";
158
+ memory: "memory";
159
+ }>>;
160
+ needed: z.ZodOptional<z.ZodNumber>;
161
+ available: z.ZodOptional<z.ZodNumber>;
162
+ unit: z.ZodOptional<z.ZodString>;
163
+ }, z.core.$strip>>>;
164
+ }, z.core.$strip>>;
165
+ children: z.ZodArray<z.ZodObject<{
166
+ id: z.ZodString;
167
+ title: z.ZodString;
168
+ status: z.ZodString;
169
+ result: z.ZodNullable<z.ZodString>;
170
+ resultPointer: z.ZodNullable<z.ZodString>;
171
+ }, z.core.$strip>>;
172
+ error: z.ZodOptional<z.ZodString>;
173
+ }, z.core.$strip>;
174
+ /** The host face: schemas plus the service model, registered through `ctx.typert.register()`. */
175
+ export declare const hostContribution: never;
176
+ /** The client face: the same descriptors, mounted through `ctx.remote.$mount()`. */
177
+ export declare const clientContribution: never;
178
+ //# sourceMappingURL=wire.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../../src/wire.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAExB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAA;AAE5E,eAAO,MAAM,OAAO,wBAAwB,CAAA;AAE5C,mEAAmE;AACnE,eAAO,MAAM,SAAS,kBAAkB,CAAA;AAuFxC;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAA;AAsEpC;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,oBAAoB,EAQtD,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,qBAAqB,IAAI,CAAA;AAEtC;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,IAAI,CAAA;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,IAAI,CAAA;AAE5C,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAG/B,CAAA;AAqBF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB;;;iBAGpC,CAAA;AAuCF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAW7B,CAAA;AAoDF,iGAAiG;AACjG,eAAO,MAAM,gBAAgB,EAMxB,KAAK,CAAA;AAEV,oFAAoF;AACpF,eAAO,MAAM,kBAAkB,EAG1B,KAAK,CAAA"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Which durable session events count as a worker's OUTPUT, as opposed to a mere sign of life.
3
+ *
4
+ * The engine's stale check compares its window against `progressAt`, so the question this module
5
+ * answers is "does this event prove the MISSION moved?", not "is the session object alive?" — any
6
+ * event proves the latter, and the host records that separately (see `MissionTree.touchActivity`).
7
+ *
8
+ * The rule is an ALLOWLIST on purpose, not a denylist of "retry noise". The harness keeps growing
9
+ * `SessionEventMap` (plugins may merge their own types), and an unknown type is not evidence of
10
+ * work. Missing a genuinely productive type costs only that a long run is judged by the round cap
11
+ * instead of by its output — bounded, logged, budget-free; letting one more noise type through the
12
+ * other way is the W8 failure this exists to fix (2026-10-02: a node stayed `running` for 7.5 hours
13
+ * while transport retries refreshed its timestamp every minute).
14
+ *
15
+ * The three types allowed, and why each is production rather than plumbing:
16
+ *
17
+ * - `assistant/message` — the model's committed output for a step ("Assembled assistant message for
18
+ * one step, carrying the step's usage"). This is the mission's work arriving.
19
+ * - `tool/call` — the model asked for one tool with its argument JSON: a decision and an action.
20
+ * - `tool/result` — a completed tool call's result. Durable work product; the strongest evidence.
21
+ *
22
+ * Everything else is excluded deliberately. The ones that actually kept W8 alive are
23
+ * `assistant/attempt` — "one model attempt that committed no surface message", i.e. a failed,
24
+ * retried, cancelled or stream-errored attempt — and the log-only route snapshots `request/header`
25
+ * / `request/context`, which are appended per request, retries included. Boundary markers
26
+ * (`turn/*`, `step/*`), prompt plumbing (`system/message`, `developer/message`) and delivered input
27
+ * (`user/message`) are not output either: a worker that only receives messages and starts steps is
28
+ * exactly the "alive but producing nothing" state the `hung` cause reclaims.
29
+ *
30
+ * @module @avantf/dsh-mission/workerEvents
31
+ */
32
+ /** Whether one durable session event is output, rather than a retry that merely proves the session is alive. */
33
+ export declare function isOutputEvent(event: {
34
+ readonly type?: string;
35
+ }): boolean;
36
+ //# sourceMappingURL=workerEvents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workerEvents.d.ts","sourceRoot":"","sources":["../../src/workerEvents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAQH,gHAAgH;AAChH,wBAAgB,aAAa,CAAC,KAAK,EAAE;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAExE"}
@@ -0,0 +1,256 @@
1
+ import type { SessionId } from '@deepseek-ai/dsh-session';
2
+ /**
3
+ * The slice of the workspace registry these commands use, declared structurally: the
4
+ * registry is an optional service here (absent headless), and importing it would make a
5
+ * type the plugin only reads into a deployment requirement.
6
+ */
7
+ export interface ArchiveRegistry {
8
+ readonly archivedSessionIds?: readonly string[];
9
+ archiveSession(id: SessionId): Promise<void>;
10
+ /**
11
+ * Durable unarchive: idempotent on the host ("an id that is not archived resolves without
12
+ * writing"), which is what makes the reconcile pass safe to run on every mount. Optional here
13
+ * because a host older than the API must still mount; the pass reports itself unsupported then.
14
+ */
15
+ unarchiveSession?(id: SessionId): Promise<void>;
16
+ }
17
+ /** One stored session, as `sessionQuery.listSessions()` reports it. */
18
+ export interface StoredSession {
19
+ readonly header: {
20
+ readonly id: string;
21
+ readonly createdAt?: number;
22
+ readonly origin?: 'subagent';
23
+ readonly delegationDepth?: number;
24
+ readonly parentSession?: string;
25
+ };
26
+ /** Whether the id currently exists as a live agent. */
27
+ readonly live: boolean;
28
+ }
29
+ /** What the commands need from the host; explicit so tests can pass fakes. */
30
+ export interface WorkerSessionDeps {
31
+ /** Stored sessions, live ones included. */
32
+ list(): Promise<readonly StoredSession[]>;
33
+ /** Durable archive of one session. Absent in a deployment without a registry. */
34
+ archive?(id: string): Promise<void>;
35
+ /**
36
+ * Durable unarchive of one session — step 3 of the cleanup lifecycle. Absent without a registry,
37
+ * or on a host whose registry predates `unarchiveSession`; the pass then reports itself
38
+ * unsupported instead of pretending the marker was lifted.
39
+ */
40
+ unarchive?(id: string): Promise<void>;
41
+ isLive(id: string): boolean;
42
+ /** Root of the session store (`$DSH_HOME/sessions`, `~/.dsh/sessions` by default). */
43
+ sessionsRoot: string;
44
+ /**
45
+ * Root of the host's projection-cache record directory
46
+ * (`<dsh home>/storages/session_projcache/sessions` by default). The host keeps one record per
47
+ * session even after disposal and has no eviction API, so a released record leaves a residue this
48
+ * module removes. Absent/unreadable is not an error — it simply means there is nothing to clean.
49
+ */
50
+ projectionCacheRoot: string;
51
+ }
52
+ /** One of this plugin's workers, with what the commands need to report. */
53
+ export interface WorkerSession {
54
+ readonly id: string;
55
+ readonly createdAt: number;
56
+ readonly live: boolean;
57
+ /** Whether its log directory was found; a session can be listed without one. */
58
+ readonly bytes: number;
59
+ readonly dir: string | undefined;
60
+ }
61
+ /**
62
+ * A mission worker at all, whichever session owns it: `origin: subagent`, delegation depth 1, and a
63
+ * claim-id shape. The harness's own delegations use uuids, so they never match. Ownership is the
64
+ * separate half (`isOurWorker`), because a listing must be able to say "another session's worker"
65
+ * out loud without that statement being an authorization.
66
+ */
67
+ export declare function isMissionWorker(record: StoredSession): boolean;
68
+ export declare function isOurWorker(record: StoredSession, ownerId: string): boolean;
69
+ /**
70
+ * The directory a session id owns, scanned by name so no path encoding is replicated.
71
+ *
72
+ * One `readdir` per project directory, with `withFileTypes` so the check needs no `statSync` at all
73
+ * — the old shape asked `existsSync` AND `statSync` for every project on every call, and this runs
74
+ * once per candidate worker in a listing.
75
+ */
76
+ export declare function sessionDirFor(root: string, id: string): string | undefined;
77
+ /** This session's own workers, newest last. */
78
+ export declare function workerSessions(deps: WorkerSessionDeps, ownerId: string): Promise<readonly WorkerSession[]>;
79
+ /** Mission workers of OTHER sessions, as ids: shown so a skip is legible, never an authorization. */
80
+ export declare function foreignWorkerIds(deps: WorkerSessionDeps, ownerId: string): Promise<readonly string[]>;
81
+ /** One owner session's retention picture, computed from its own workers (never from the store). */
82
+ export interface WorkerRetention {
83
+ /** Settled workers (`!live`), newest first; ties broken by id so the order is deterministic. */
84
+ readonly settled: readonly WorkerSession[];
85
+ /** Live workers: excluded from the count entirely, and never a release candidate. */
86
+ readonly live: readonly WorkerSession[];
87
+ /** The newest `keep` settled workers the policy holds (all of them when the policy is off). */
88
+ readonly retained: readonly WorkerSession[];
89
+ /** Settled workers OLDER than the retained ones: what automatic retention would release. */
90
+ readonly releasable: readonly WorkerSession[];
91
+ /** `false` when `keep <= 0`: automatic retention is OFF, so nothing is releasable. */
92
+ readonly enabled: boolean;
93
+ }
94
+ /**
95
+ * Split one owner's workers into what the retention policy KEEPS and what it would release.
96
+ *
97
+ * The count is over SETTLED (`!live`) workers only. A live worker does not occupy a retention slot
98
+ * and is never a candidate, so "keep the newest N" means "keep the newest N FINISHED workers",
99
+ * however many are still running: 13 finished + 4 running with N=10 releases 3, and 3 finished +
100
+ * 8 running with N=10 releases nothing.
101
+ *
102
+ * Ordering is by `header.createdAt` descending — newest first — with the id as a deterministic
103
+ * tie-break, so a listing and a pass can never disagree about which worker sits on the boundary.
104
+ * `keep <= 0` disables the policy: everything is kept and nothing is releasable (the disabled
105
+ * spelling is "keep all", NOT "keep none").
106
+ */
107
+ export declare function workerRetention(workers: readonly WorkerSession[], keep: number): WorkerRetention;
108
+ export declare function bytes(n: number): string;
109
+ /** Archive every settled, not-yet-archived worker of this session. */
110
+ export declare function archiveWorkers(deps: WorkerSessionDeps, ownerId: string, archived: (id: string) => boolean): Promise<{
111
+ readonly archived: readonly string[];
112
+ readonly skipped: readonly string[];
113
+ readonly supported: boolean;
114
+ }>;
115
+ /** One worker a cleanup pass archived (when needed) and then removed. */
116
+ export interface CleanedWorker {
117
+ readonly id: string;
118
+ readonly freed: number;
119
+ /** `true` when THIS run wrote the archive marker; `false` when it was already archived. */
120
+ readonly archivedNow: boolean;
121
+ }
122
+ /** One settled worker whose archive FAILED: deliberately left in place, with the reason. */
123
+ export interface RefusedWorker {
124
+ readonly id: string;
125
+ readonly reason: string;
126
+ }
127
+ /** What one `/clean archive` pass did, and the three buckets of what it left alone. */
128
+ export interface WorkerCleanup {
129
+ readonly cleaned: readonly CleanedWorker[];
130
+ readonly refused: readonly RefusedWorker[];
131
+ /**
132
+ * Records that WERE removed, but whose archive marker could not be lifted (step 3 failed).
133
+ * The deletion stands — the files are gone, so keeping the marker only adds a ghost — and the
134
+ * failure is reported instead of rolled back.
135
+ */
136
+ readonly unarchiveFailures: readonly RefusedWorker[];
137
+ /**
138
+ * Projection-cache residue files removed for the records this pass released. The host keeps a
139
+ * disposed session's checkpoint with no eviction API, so this is the layer that would otherwise
140
+ * keep the worker listed forever.
141
+ */
142
+ readonly purged: readonly string[];
143
+ /** Residue files that could not be removed: reported, never fatal, never a rollback. */
144
+ readonly purgeFailures: readonly RefusedWorker[];
145
+ /** Ours, still running: never touched. */
146
+ readonly running: readonly string[];
147
+ /** Mission workers of other sessions: never touched. */
148
+ readonly foreign: readonly string[];
149
+ /** `false` when no registry is mounted: nothing can be archived, so nothing is removed. */
150
+ readonly supported: boolean;
151
+ }
152
+ /**
153
+ * Archive-then-remove in ONE pass, for this session's settled workers, finishing with the
154
+ * best-effort unarchive that keeps the registry free of ghost ids.
155
+ *
156
+ * Scope is exactly `isOurWorker(record, ownerId) && !live`: a live worker is never touched (no
157
+ * interrupt, no archive) and another session's worker is never touched. A settled worker that is not
158
+ * yet archived is archived FIRST, and removed only once that succeeded — a failed archive leaves the
159
+ * record in place and is reported, because "removed without an archive marker" is the one outcome the
160
+ * guardrails exist to prevent. After a successful removal the marker is lifted; if THAT fails the
161
+ * deletion still stands (the files are gone) and the failure is reported in `unarchiveFailures`.
162
+ * `only` narrows the pass to one named id, still looked up inside this session's own workers. Without
163
+ * a registry the pass is `supported: false` and removes nothing.
164
+ *
165
+ * `retain` is the AUTOMATIC retention half: it narrows the candidates to the settled workers OLDER
166
+ * than the newest `retain` (see {@link workerRetention}) and reuses this same archive → delete →
167
+ * unarchive → purge pipeline. Live workers are excluded from the count, so they never occupy a
168
+ * retention slot and are never released. `retain <= 0` means "policy off", which keeps everything.
169
+ * A named `only` pass is an explicit manual action and ignores `retain`.
170
+ *
171
+ * `all` is the corpus to work from — the automatic pass lists sessions ONCE and hands the same list
172
+ * to every owner (it used to call `listSessions` once per owner, on every sweep). `measureBytes`
173
+ * defaults to true for the manual commands, which report what each worker occupies; the automatic
174
+ * pass turns it off and measures only what it actually releases.
175
+ */
176
+ export declare function cleanWorkers(deps: WorkerSessionDeps, ownerId: string, archived: (id: string) => boolean, options?: {
177
+ readonly only?: string;
178
+ readonly retain?: number;
179
+ readonly all?: readonly StoredSession[];
180
+ readonly measureBytes?: boolean;
181
+ }): Promise<WorkerCleanup>;
182
+ export declare function removeWorker(worker: WorkerSession): number;
183
+ /**
184
+ * The live-preferred session corpus, as `sessionQuery.listSessions()` answers it.
185
+ *
186
+ * `readable: false` is the load-bearing half: with no session query at all, "no record" cannot be
187
+ * told apart from "cannot ask", and this module treats an unproven absence as presence.
188
+ */
189
+ export interface SessionCorpus {
190
+ readonly readable: boolean;
191
+ readonly known: ReadonlySet<string>;
192
+ }
193
+ /** What one ghost-reconciliation pass did, for the log line and the command's reply. */
194
+ export interface GhostReconcile {
195
+ /** Archive markers lifted this pass. */
196
+ readonly released: readonly string[];
197
+ /** Markers whose `unarchiveSession` call failed: reported, never fatal. */
198
+ readonly failed: readonly RefusedWorker[];
199
+ /** Projection-cache residue files removed this pass (records proven gone). */
200
+ readonly purged: readonly string[];
201
+ /** Residue files that could not be removed: reported, never fatal. */
202
+ readonly purgeFailures: readonly RefusedWorker[];
203
+ /** `false` when there is no unarchive API to call: nothing was attempted. */
204
+ readonly supported: boolean;
205
+ /** `false` when the corpus could not be read: absence is unproven, so nothing was attempted. */
206
+ readonly readable: boolean;
207
+ }
208
+ /** What one projection-cache purge pass did: what it removed, and what it could not. */
209
+ export interface ProjectionCachePurge {
210
+ readonly purged: readonly string[];
211
+ readonly failures: readonly RefusedWorker[];
212
+ }
213
+ /**
214
+ * Archived ids that are GHOSTS: mission-shaped, gone from the live-preferred corpus AND gone from
215
+ * the sessions root under every project directory.
216
+ *
217
+ * Written as one predicate used by both the listing and the reconcile pass, so what `/clean archive`
218
+ * shows and what it clears can never disagree. The narrowness is the whole safety argument: a
219
+ * non-mission id belongs to another subsystem or another session's archive set, and an id either
220
+ * source still knows is a record whose archive marker is still meaningful.
221
+ */
222
+ export declare function ghostArchiveIds(archived: ReadonlySet<string>, known: ReadonlySet<string>, sessionsRoot: string): readonly string[];
223
+ /**
224
+ * Projection-cache residue whose record is PROVEN gone: `mission-*`-shaped files under the cache
225
+ * root whose id is absent from BOTH the live-preferred corpus and the sessions root.
226
+ *
227
+ * The SAME absence predicate as `ghostArchiveIds`, for a different layer: that function reasons
228
+ * about archive markers, this one about the host's cached rows. Read-only: it answers what a purge
229
+ * would remove without removing anything.
230
+ *
231
+ * An unreadable corpus means absence is unproven, so the answer is `[]`. A record either source
232
+ * still knows is a session in use; its cache is never a candidate.
233
+ */
234
+ export declare function orphanProjectionCacheIds(deps: WorkerSessionDeps, corpus: SessionCorpus): readonly string[];
235
+ /**
236
+ * Remove the projection-cache residue of every record PROVEN gone.
237
+ *
238
+ * Registry-independent by design: proving a record gone needs the corpus and the sessions root, not
239
+ * an archive marker — and the archive set can legitimately be empty while residue persists, which
240
+ * is exactly why this enumerates the cache directory instead of taking archived ids as input. Every
241
+ * removal is best-effort; a failure is returned, never thrown.
242
+ */
243
+ export declare function purgeOrphanProjectionCache(deps: WorkerSessionDeps, corpus: SessionCorpus): ProjectionCachePurge;
244
+ /**
245
+ * Lift the archive markers older cleanups left behind, and clear the projection-cache residue of
246
+ * records that no longer exist, so the subagent list stops showing workers that are gone.
247
+ *
248
+ * Deliberately conservative, in three ways: only `mission-*`-shaped ids, only ids absent from BOTH
249
+ * the live-preferred corpus and the sessions root, and only when the corpus was readable at all (an
250
+ * unreadable corpus means absence is unproven). The residue purge runs FIRST and is
251
+ * registry-independent — the archive set no longer has to be non-empty for the pass to do its work.
252
+ * Each unarchive is best-effort — a failure is returned, never thrown — and the host's own unarchive
253
+ * is idempotent, so re-running this pass is safe.
254
+ */
255
+ export declare function reconcileArchivedGhosts(deps: WorkerSessionDeps, archived: ReadonlySet<string>, corpus: SessionCorpus): Promise<GhostReconcile>;
256
+ //# sourceMappingURL=workerSessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workerSessions.d.ts","sourceRoot":"","sources":["../../src/workerSessions.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,145 @@
1
+ {
2
+ "name": "@avantf/dsh-mission",
3
+ "version": "0.3.0",
4
+ "description": "DSH native Cordis plugin: a mission-tree engine (nodes attempted, decomposed by the blocked executor, converged by the engine)",
5
+ "type": "module",
6
+ "main": "lib/index.js",
7
+ "types": "lib/types/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./lib/types/index.d.ts",
11
+ "default": "./lib/index.js"
12
+ },
13
+ "./package.json": "./package.json",
14
+ "./client": {
15
+ "types": "./lib/types/client/index.d.ts",
16
+ "default": "./lib/client.js"
17
+ },
18
+ "./cordis.patch.yml": "./cordis.patch.yml"
19
+ },
20
+ "files": [
21
+ "lib/index.js",
22
+ "lib/client.js",
23
+ "lib/envinit-bootstrap.js",
24
+ "lib/dsh-build.json",
25
+ "lib/types",
26
+ "lib/mission-core",
27
+ "README.md",
28
+ "lib/interface-version.json",
29
+ "cordis.patch.yml"
30
+ ],
31
+ "engines": {
32
+ "node": ">=22.15.0 <23 || >=23.11.0"
33
+ },
34
+ "peerDependencies": {
35
+ "@avantf/dsh-plugin-base": ">=0.3.0 <1.0.0",
36
+ "@deepseek-ai/cordis": "^4.0.2",
37
+ "@deepseek-ai/cordis-plugin-timer": "^1.1.4",
38
+ "@deepseek-ai/dsh-agent": "^0.1.5-rc.2 || ^0.1.7-rc.2 || ^0.2.0-rc.2",
39
+ "@deepseek-ai/dsh-brand": "^0.1.5-rc.2 || ^0.1.7-rc.2 || ^0.2.0-rc.2",
40
+ "@deepseek-ai/dsh-commands": "^0.1.5-rc.2 || ^0.1.7-rc.2 || ^0.2.0-rc.2",
41
+ "@deepseek-ai/dsh-llm": "^0.1.5-rc.2 || ^0.1.7-rc.2 || ^0.2.0-rc.2",
42
+ "@deepseek-ai/dsh-session": "^0.1.5-rc.2 || ^0.1.7-rc.2 || ^0.2.0-rc.2",
43
+ "@deepseek-ai/dsh-session-query": "^0.1.5-rc.2 || ^0.1.7-rc.2 || ^0.2.0-rc.2",
44
+ "@deepseek-ai/dsh-spill": "^0.1.5-rc.2 || ^0.1.7-rc.2 || ^0.2.0-rc.2",
45
+ "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.2 || ^0.1.7-rc.2 || ^0.2.0-rc.2",
46
+ "@deepseek-ai/dsh-subagent": "^0.1.5-rc.2 || ^0.1.7-rc.2 || ^0.2.0-rc.2",
47
+ "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2 || ^0.1.7-rc.2 || ^0.2.0-rc.2",
48
+ "@deepseek-ai/dsh-tools": "^0.1.5-rc.2 || ^0.1.7-rc.2 || ^0.2.0-rc.2",
49
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2 || ^0.1.7-rc.2 || ^0.2.0-rc.2",
50
+ "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2 || ^0.1.7-rc.2 || ^0.2.0-rc.2",
51
+ "@deepseek-ai/schemastery": "^3.18.2",
52
+ "zod": ">=4.4.3 <5"
53
+ },
54
+ "peerDependenciesMeta": {
55
+ "@deepseek-ai/cordis": {
56
+ "optional": true
57
+ },
58
+ "@deepseek-ai/cordis-plugin-timer": {
59
+ "optional": true
60
+ },
61
+ "@deepseek-ai/dsh-agent": {
62
+ "optional": true
63
+ },
64
+ "@deepseek-ai/dsh-brand": {
65
+ "optional": true
66
+ },
67
+ "@deepseek-ai/dsh-commands": {
68
+ "optional": true
69
+ },
70
+ "@deepseek-ai/dsh-llm": {
71
+ "optional": true
72
+ },
73
+ "@deepseek-ai/dsh-session": {
74
+ "optional": true
75
+ },
76
+ "@deepseek-ai/dsh-session-query": {
77
+ "optional": true
78
+ },
79
+ "@deepseek-ai/dsh-spill": {
80
+ "optional": true
81
+ },
82
+ "@deepseek-ai/dsh-storage-domain": {
83
+ "optional": true
84
+ },
85
+ "@deepseek-ai/dsh-subagent": {
86
+ "optional": true
87
+ },
88
+ "@deepseek-ai/dsh-system-prompt": {
89
+ "optional": true
90
+ },
91
+ "@deepseek-ai/dsh-tools": {
92
+ "optional": true
93
+ },
94
+ "@deepseek-ai/dsh-typert-protocol": {
95
+ "optional": true
96
+ },
97
+ "@deepseek-ai/dsh-util-values": {
98
+ "optional": true
99
+ },
100
+ "@deepseek-ai/schemastery": {
101
+ "optional": true
102
+ }
103
+ },
104
+ "devDependencies": {
105
+ "@avantf/dsh-plugin-base": ">=0.3.0 <1.0.0",
106
+ "@avantf/mission-core": "0.3.0",
107
+ "@tanstack/react-virtual": "^3.14.13",
108
+ "@types/node": "^22.0.0",
109
+ "@types/react": "^18.3.12",
110
+ "@types/react-dom": "^18.3.1",
111
+ "esbuild": "0.25.0",
112
+ "react": "18.3.1",
113
+ "react-dom": "18.3.1",
114
+ "typescript": "^5.5.0",
115
+ "vitest": "^2.1.0",
116
+ "zod": "4.6.5"
117
+ },
118
+ "license": "MIT",
119
+ "publishConfig": {
120
+ "access": "public"
121
+ },
122
+ "repository": {
123
+ "type": "git",
124
+ "url": "git@gitee.com:ffeng86/dsh-plugins.git",
125
+ "directory": "mission/packages/plugin"
126
+ },
127
+ "author": "qunqi.ff",
128
+ "dsh": {
129
+ "bundle": {
130
+ "patch": "./cordis.patch.yml"
131
+ },
132
+ "client": {
133
+ "inject": [
134
+ "@deepseek-ai/dsh-client-ui-conversation",
135
+ "@deepseek-ai/dsh-api-remotes"
136
+ ],
137
+ "platform": "web"
138
+ }
139
+ },
140
+ "scripts": {
141
+ "build": "node ../../scripts/build.mjs",
142
+ "typecheck": "node ../../scripts/link-dsh.mjs --no-bake && tsc -p tsconfig.json --noEmit",
143
+ "test": "vitest run"
144
+ }
145
+ }