@wastedcode/claudemux 0.2.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/CHANGELOG.md +257 -0
- package/LICENSE +21 -0
- package/README.md +493 -0
- package/bin/claudemux +6 -0
- package/dist/agents/claude.d.ts +3 -0
- package/dist/agents/claude.d.ts.map +1 -0
- package/dist/agents/claude.js +585 -0
- package/dist/agents/claude.js.map +1 -0
- package/dist/agents/index.d.ts +2 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +2 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/types.d.ts +252 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +2 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/backends/tmux/capture.d.ts +25 -0
- package/dist/backends/tmux/capture.d.ts.map +1 -0
- package/dist/backends/tmux/capture.js +35 -0
- package/dist/backends/tmux/capture.js.map +1 -0
- package/dist/backends/tmux/exec.d.ts +105 -0
- package/dist/backends/tmux/exec.d.ts.map +1 -0
- package/dist/backends/tmux/exec.js +226 -0
- package/dist/backends/tmux/exec.js.map +1 -0
- package/dist/backends/tmux/index.d.ts +22 -0
- package/dist/backends/tmux/index.d.ts.map +1 -0
- package/dist/backends/tmux/index.js +108 -0
- package/dist/backends/tmux/index.js.map +1 -0
- package/dist/backends/tmux/keys.d.ts +38 -0
- package/dist/backends/tmux/keys.d.ts.map +1 -0
- package/dist/backends/tmux/keys.js +63 -0
- package/dist/backends/tmux/keys.js.map +1 -0
- package/dist/backends/tmux/options.d.ts +24 -0
- package/dist/backends/tmux/options.d.ts.map +1 -0
- package/dist/backends/tmux/options.js +84 -0
- package/dist/backends/tmux/options.js.map +1 -0
- package/dist/backends/tmux/sessions.d.ts +70 -0
- package/dist/backends/tmux/sessions.d.ts.map +1 -0
- package/dist/backends/tmux/sessions.js +156 -0
- package/dist/backends/tmux/sessions.js.map +1 -0
- package/dist/backends/tmux/socket.d.ts +26 -0
- package/dist/backends/tmux/socket.d.ts.map +1 -0
- package/dist/backends/tmux/socket.js +31 -0
- package/dist/backends/tmux/socket.js.map +1 -0
- package/dist/backends/types.d.ts +110 -0
- package/dist/backends/types.d.ts.map +1 -0
- package/dist/backends/types.js +24 -0
- package/dist/backends/types.js.map +1 -0
- package/dist/cli/ask.d.ts +11 -0
- package/dist/cli/ask.d.ts.map +1 -0
- package/dist/cli/ask.js +17 -0
- package/dist/cli/ask.js.map +1 -0
- package/dist/cli/capture.d.ts +8 -0
- package/dist/cli/capture.d.ts.map +1 -0
- package/dist/cli/capture.js +15 -0
- package/dist/cli/capture.js.map +1 -0
- package/dist/cli/context.d.ts +71 -0
- package/dist/cli/context.d.ts.map +1 -0
- package/dist/cli/context.js +82 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/exists.d.ts +7 -0
- package/dist/cli/exists.d.ts.map +1 -0
- package/dist/cli/exists.js +16 -0
- package/dist/cli/exists.js.map +1 -0
- package/dist/cli/interrupt.d.ts +10 -0
- package/dist/cli/interrupt.d.ts.map +1 -0
- package/dist/cli/interrupt.js +13 -0
- package/dist/cli/interrupt.js.map +1 -0
- package/dist/cli/kill.d.ts +7 -0
- package/dist/cli/kill.d.ts.map +1 -0
- package/dist/cli/kill.js +14 -0
- package/dist/cli/kill.js.map +1 -0
- package/dist/cli/list.d.ts +10 -0
- package/dist/cli/list.d.ts.map +1 -0
- package/dist/cli/list.js +19 -0
- package/dist/cli/list.js.map +1 -0
- package/dist/cli/main.d.ts +13 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +143 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/messages.d.ts +9 -0
- package/dist/cli/messages.d.ts.map +1 -0
- package/dist/cli/messages.js +13 -0
- package/dist/cli/messages.js.map +1 -0
- package/dist/cli/respond.d.ts +10 -0
- package/dist/cli/respond.d.ts.map +1 -0
- package/dist/cli/respond.js +23 -0
- package/dist/cli/respond.js.map +1 -0
- package/dist/cli/resume.d.ts +12 -0
- package/dist/cli/resume.d.ts.map +1 -0
- package/dist/cli/resume.js +21 -0
- package/dist/cli/resume.js.map +1 -0
- package/dist/cli/send.d.ts +9 -0
- package/dist/cli/send.d.ts.map +1 -0
- package/dist/cli/send.js +16 -0
- package/dist/cli/send.js.map +1 -0
- package/dist/cli/spawn.d.ts +14 -0
- package/dist/cli/spawn.d.ts.map +1 -0
- package/dist/cli/spawn.js +21 -0
- package/dist/cli/spawn.js.map +1 -0
- package/dist/cli/state.d.ts +7 -0
- package/dist/cli/state.d.ts.map +1 -0
- package/dist/cli/state.js +11 -0
- package/dist/cli/state.js.map +1 -0
- package/dist/cli/turn-complete.d.ts +8 -0
- package/dist/cli/turn-complete.d.ts.map +1 -0
- package/dist/cli/turn-complete.js +14 -0
- package/dist/cli/turn-complete.js.map +1 -0
- package/dist/cli/wait.d.ts +13 -0
- package/dist/cli/wait.d.ts.map +1 -0
- package/dist/cli/wait.js +17 -0
- package/dist/cli/wait.js.map +1 -0
- package/dist/compose.d.ts +81 -0
- package/dist/compose.d.ts.map +1 -0
- package/dist/compose.js +64 -0
- package/dist/compose.js.map +1 -0
- package/dist/errors.d.ts +250 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +300 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/io/baseline.d.ts +53 -0
- package/dist/io/baseline.d.ts.map +1 -0
- package/dist/io/baseline.js +97 -0
- package/dist/io/baseline.js.map +1 -0
- package/dist/io/capture.d.ts +15 -0
- package/dist/io/capture.d.ts.map +1 -0
- package/dist/io/capture.js +13 -0
- package/dist/io/capture.js.map +1 -0
- package/dist/io/interrupt.d.ts +46 -0
- package/dist/io/interrupt.d.ts.map +1 -0
- package/dist/io/interrupt.js +60 -0
- package/dist/io/interrupt.js.map +1 -0
- package/dist/io/respond.d.ts +28 -0
- package/dist/io/respond.d.ts.map +1 -0
- package/dist/io/respond.js +33 -0
- package/dist/io/respond.js.map +1 -0
- package/dist/io/send.d.ts +44 -0
- package/dist/io/send.d.ts.map +1 -0
- package/dist/io/send.js +66 -0
- package/dist/io/send.js.map +1 -0
- package/dist/io/stabilize.d.ts +28 -0
- package/dist/io/stabilize.d.ts.map +1 -0
- package/dist/io/stabilize.js +20 -0
- package/dist/io/stabilize.js.map +1 -0
- package/dist/io/wait.d.ts +47 -0
- package/dist/io/wait.d.ts.map +1 -0
- package/dist/io/wait.js +117 -0
- package/dist/io/wait.js.map +1 -0
- package/dist/observe/incremental.d.ts +28 -0
- package/dist/observe/incremental.d.ts.map +1 -0
- package/dist/observe/incremental.js +57 -0
- package/dist/observe/incremental.js.map +1 -0
- package/dist/observe/observer.d.ts +86 -0
- package/dist/observe/observer.d.ts.map +1 -0
- package/dist/observe/observer.js +167 -0
- package/dist/observe/observer.js.map +1 -0
- package/dist/observe/session-observer.d.ts +49 -0
- package/dist/observe/session-observer.d.ts.map +1 -0
- package/dist/observe/session-observer.js +123 -0
- package/dist/observe/session-observer.js.map +1 -0
- package/dist/session/adopt.d.ts +52 -0
- package/dist/session/adopt.d.ts.map +1 -0
- package/dist/session/adopt.js +57 -0
- package/dist/session/adopt.js.map +1 -0
- package/dist/session/boot.d.ts +66 -0
- package/dist/session/boot.d.ts.map +1 -0
- package/dist/session/boot.js +216 -0
- package/dist/session/boot.js.map +1 -0
- package/dist/session/constants.d.ts +57 -0
- package/dist/session/constants.d.ts.map +1 -0
- package/dist/session/constants.js +54 -0
- package/dist/session/constants.js.map +1 -0
- package/dist/session/create.d.ts +88 -0
- package/dist/session/create.d.ts.map +1 -0
- package/dist/session/create.js +66 -0
- package/dist/session/create.js.map +1 -0
- package/dist/session/default-backend.d.ts +27 -0
- package/dist/session/default-backend.d.ts.map +1 -0
- package/dist/session/default-backend.js +58 -0
- package/dist/session/default-backend.js.map +1 -0
- package/dist/session/handle.d.ts +63 -0
- package/dist/session/handle.d.ts.map +1 -0
- package/dist/session/handle.js +284 -0
- package/dist/session/handle.js.map +1 -0
- package/dist/session/hooks.d.ts +37 -0
- package/dist/session/hooks.d.ts.map +1 -0
- package/dist/session/hooks.js +42 -0
- package/dist/session/hooks.js.map +1 -0
- package/dist/session/mutex.d.ts +15 -0
- package/dist/session/mutex.d.ts.map +1 -0
- package/dist/session/mutex.js +29 -0
- package/dist/session/mutex.js.map +1 -0
- package/dist/session/recover.d.ts +43 -0
- package/dist/session/recover.d.ts.map +1 -0
- package/dist/session/recover.js +45 -0
- package/dist/session/recover.js.map +1 -0
- package/dist/session/ref.d.ts +2 -0
- package/dist/session/ref.d.ts.map +1 -0
- package/dist/session/ref.js +5 -0
- package/dist/session/ref.js.map +1 -0
- package/dist/session/registry.d.ts +31 -0
- package/dist/session/registry.d.ts.map +1 -0
- package/dist/session/registry.js +32 -0
- package/dist/session/registry.js.map +1 -0
- package/dist/session/resolve.d.ts +30 -0
- package/dist/session/resolve.d.ts.map +1 -0
- package/dist/session/resolve.js +24 -0
- package/dist/session/resolve.js.map +1 -0
- package/dist/session/resume.d.ts +68 -0
- package/dist/session/resume.d.ts.map +1 -0
- package/dist/session/resume.js +54 -0
- package/dist/session/resume.js.map +1 -0
- package/dist/session/spawn-boot.d.ts +44 -0
- package/dist/session/spawn-boot.d.ts.map +1 -0
- package/dist/session/spawn-boot.js +87 -0
- package/dist/session/spawn-boot.js.map +1 -0
- package/dist/session/validate.d.ts +10 -0
- package/dist/session/validate.d.ts.map +1 -0
- package/dist/session/validate.js +0 -0
- package/dist/session/validate.js.map +1 -0
- package/dist/state/classifier.d.ts +29 -0
- package/dist/state/classifier.d.ts.map +1 -0
- package/dist/state/classifier.js +37 -0
- package/dist/state/classifier.js.map +1 -0
- package/dist/state/types.d.ts +32 -0
- package/dist/state/types.d.ts.map +1 -0
- package/dist/state/types.js +2 -0
- package/dist/state/types.js.map +1 -0
- package/dist/types.d.ts +401 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/util/ansi.d.ts +14 -0
- package/dist/util/ansi.d.ts.map +1 -0
- package/dist/util/ansi.js +18 -0
- package/dist/util/ansi.js.map +1 -0
- package/dist/util/emitter.d.ts +17 -0
- package/dist/util/emitter.d.ts.map +1 -0
- package/dist/util/emitter.js +33 -0
- package/dist/util/emitter.js.map +1 -0
- package/dist/util/sleep.d.ts +8 -0
- package/dist/util/sleep.d.ts.map +1 -0
- package/dist/util/sleep.js +10 -0
- package/dist/util/sleep.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Backend } from "../backends/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Bare `{ namespace, name }` operations for the public surface. Each
|
|
4
|
+
* accepts an optional `backend` override; when omitted, the process-wide
|
|
5
|
+
* default backend is used.
|
|
6
|
+
*/
|
|
7
|
+
/** Is the named session currently alive? */
|
|
8
|
+
export declare function exists(o: {
|
|
9
|
+
name: string;
|
|
10
|
+
namespace?: string;
|
|
11
|
+
backend?: Backend;
|
|
12
|
+
}): Promise<boolean>;
|
|
13
|
+
/**
|
|
14
|
+
* Kill the named session. Idempotent — "kill of a missing session" is
|
|
15
|
+
* success, not an error.
|
|
16
|
+
*/
|
|
17
|
+
export declare function kill(o: {
|
|
18
|
+
name: string;
|
|
19
|
+
namespace?: string;
|
|
20
|
+
backend?: Backend;
|
|
21
|
+
}): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* List short session names owned by `namespace`. Result is sorted for
|
|
24
|
+
* stable test/UX behavior; the backend's order is not part of the
|
|
25
|
+
* contract.
|
|
26
|
+
*/
|
|
27
|
+
export declare function list(o?: {
|
|
28
|
+
namespace?: string;
|
|
29
|
+
backend?: Backend;
|
|
30
|
+
}): Promise<string[]>;
|
|
31
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/session/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAIpD;;;;GAIG;AAEH,4CAA4C;AAC5C,wBAAgB,MAAM,CAAC,CAAC,EAAE;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,OAAO,CAAC,OAAO,CAAC,CAGnB;AAED;;;GAGG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAGhB;AAED;;;;GAIG;AACH,wBAAsB,IAAI,CAAC,CAAC,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAK/F"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DEFAULT_NAMESPACE } from "./constants.js";
|
|
2
|
+
import { sharedDefaultBackend } from "./default-backend.js";
|
|
3
|
+
/**
|
|
4
|
+
* Bare `{ namespace, name }` operations for the public surface. Each
|
|
5
|
+
* accepts an optional `backend` override; when omitted, the process-wide
|
|
6
|
+
* default backend is used.
|
|
7
|
+
*/
|
|
8
|
+
/** Is the named session currently alive? */
|
|
9
|
+
export function exists(o) {
|
|
10
|
+
const backend = o.backend ?? sharedDefaultBackend();
|
|
11
|
+
return backend.exists({ namespace: o.namespace ?? DEFAULT_NAMESPACE, name: o.name });
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Kill the named session. Idempotent — "kill of a missing session" is
|
|
15
|
+
* success, not an error.
|
|
16
|
+
*/
|
|
17
|
+
export function kill(o) {
|
|
18
|
+
const backend = o.backend ?? sharedDefaultBackend();
|
|
19
|
+
return backend.kill({ namespace: o.namespace ?? DEFAULT_NAMESPACE, name: o.name });
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* List short session names owned by `namespace`. Result is sorted for
|
|
23
|
+
* stable test/UX behavior; the backend's order is not part of the
|
|
24
|
+
* contract.
|
|
25
|
+
*/
|
|
26
|
+
export async function list(o = {}) {
|
|
27
|
+
const backend = o.backend ?? sharedDefaultBackend();
|
|
28
|
+
const namespace = o.namespace ?? DEFAULT_NAMESPACE;
|
|
29
|
+
const shortNames = await backend.list(namespace);
|
|
30
|
+
return [...shortNames].sort();
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/session/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D;;;;GAIG;AAEH,4CAA4C;AAC5C,MAAM,UAAU,MAAM,CAAC,CAItB;IACC,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,oBAAoB,EAAE,CAAC;IACpD,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AACvF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,IAAI,CAAC,CAIpB;IACC,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,oBAAoB,EAAE,CAAC;IACpD,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AACrF,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAA+C,EAAE;IAC1E,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,oBAAoB,EAAE,CAAC;IACpD,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS,IAAI,iBAAiB,CAAC;IACnD,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { AgentDef } from "../agents/types.js";
|
|
2
|
+
import type { Backend, SessionRef } from "../backends/types.js";
|
|
3
|
+
/** The options every lifecycle entry (`create`/`resume`/`adopt`) shares. */
|
|
4
|
+
export interface SessionContextOptions {
|
|
5
|
+
/** Session name within the namespace. */
|
|
6
|
+
name: string;
|
|
7
|
+
/** Namespace prefix (default: `"claudemux"`). */
|
|
8
|
+
namespace?: string;
|
|
9
|
+
/** Agent definition (default: claude). */
|
|
10
|
+
agent?: AgentDef;
|
|
11
|
+
/** Backend instance (default: the process-wide shared default). */
|
|
12
|
+
backend?: Backend;
|
|
13
|
+
}
|
|
14
|
+
/** The resolved front-matter every lifecycle entry derives before its own work. */
|
|
15
|
+
export interface SessionContext {
|
|
16
|
+
readonly ref: SessionRef;
|
|
17
|
+
readonly agent: AgentDef;
|
|
18
|
+
readonly backend: Backend;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Resolve the shared front-matter of every lifecycle entry point: default the
|
|
22
|
+
* namespace, validate name + namespace, default the agent and backend, and build
|
|
23
|
+
* the validated {@link SessionRef}. `create`/`resume`/`adopt` each open with THIS,
|
|
24
|
+
* then own their one distinct next step — the exists-check polarity (present is a
|
|
25
|
+
* collision for create/resume, absence for adopt) and spawn-vs-attach. Extracted
|
|
26
|
+
* because the four-line preamble was byte-identical across all three and drifted
|
|
27
|
+
* as a class (one place to fix a default or a validation rule, not three).
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveSessionContext(opts: SessionContextOptions): SessionContext;
|
|
30
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/session/resolve.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAKhE,4EAA4E;AAC5E,MAAM,WAAW,qBAAqB;IACpC,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,mFAAmF;AACnF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,qBAAqB,GAAG,cAAc,CASjF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { claude as defaultAgent } from "../agents/claude.js";
|
|
2
|
+
import { DEFAULT_NAMESPACE } from "./constants.js";
|
|
3
|
+
import { sharedDefaultBackend } from "./default-backend.js";
|
|
4
|
+
import { validateNamePart } from "./validate.js";
|
|
5
|
+
/**
|
|
6
|
+
* Resolve the shared front-matter of every lifecycle entry point: default the
|
|
7
|
+
* namespace, validate name + namespace, default the agent and backend, and build
|
|
8
|
+
* the validated {@link SessionRef}. `create`/`resume`/`adopt` each open with THIS,
|
|
9
|
+
* then own their one distinct next step — the exists-check polarity (present is a
|
|
10
|
+
* collision for create/resume, absence for adopt) and spawn-vs-attach. Extracted
|
|
11
|
+
* because the four-line preamble was byte-identical across all three and drifted
|
|
12
|
+
* as a class (one place to fix a default or a validation rule, not three).
|
|
13
|
+
*/
|
|
14
|
+
export function resolveSessionContext(opts) {
|
|
15
|
+
const namespace = opts.namespace ?? DEFAULT_NAMESPACE;
|
|
16
|
+
validateNamePart("namespace", namespace);
|
|
17
|
+
validateNamePart("name", opts.name);
|
|
18
|
+
return {
|
|
19
|
+
ref: { namespace, name: opts.name },
|
|
20
|
+
agent: opts.agent ?? defaultAgent,
|
|
21
|
+
backend: opts.backend ?? sharedDefaultBackend(),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/session/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAG7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAqBjD;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAA2B;IAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,iBAAiB,CAAC;IACtD,gBAAgB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACzC,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,OAAO;QACL,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;QACnC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,YAAY;QACjC,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,oBAAoB,EAAE;KAChD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { AgentDef } from "../agents/types.js";
|
|
2
|
+
import type { Backend } from "../backends/types.js";
|
|
3
|
+
import type { SessionHandle } from "../types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Options for {@link resume}. The peer of {@link CreateOptions} — same lifecycle
|
|
6
|
+
* shape, except the conversation id is **given** (the one to continue), not
|
|
7
|
+
* minted.
|
|
8
|
+
*/
|
|
9
|
+
export interface ResumeOptions {
|
|
10
|
+
/** Session name within the namespace (a fresh pane is spawned under it). */
|
|
11
|
+
name: string;
|
|
12
|
+
/** Working directory the agent runs in. */
|
|
13
|
+
cwd: string;
|
|
14
|
+
/**
|
|
15
|
+
* The conversation to continue — an `agentSessionId` previously surfaced by
|
|
16
|
+
* {@link create}/{@link adopt}. Validated as a v4 UUID before spawn. The agent
|
|
17
|
+
* maps it to its own resume mechanism (claude: `--resume <id>`); the vendor
|
|
18
|
+
* flag never appears in consumer code.
|
|
19
|
+
*/
|
|
20
|
+
agentSessionId: string;
|
|
21
|
+
/** Namespace prefix (default: `"claudemux"`). */
|
|
22
|
+
namespace?: string;
|
|
23
|
+
/** Agent definition (default: claude). */
|
|
24
|
+
agent?: AgentDef;
|
|
25
|
+
/** Backend instance (default: tmux on a fresh shared socket per process). */
|
|
26
|
+
backend?: Backend;
|
|
27
|
+
/** Extra args passed to the agent's argv. */
|
|
28
|
+
extraArgs?: string[];
|
|
29
|
+
/** Override env passed to the agent process. */
|
|
30
|
+
env?: Record<string, string>;
|
|
31
|
+
/** Boot timeout in ms (default 60_000). */
|
|
32
|
+
bootTimeoutMs?: number;
|
|
33
|
+
/** Opt in to auto-dismissing the workspace-trust dialog (default false). */
|
|
34
|
+
trustWorkspace?: boolean;
|
|
35
|
+
/** Inject the agent's observe hooks at spawn (default true). */
|
|
36
|
+
hooks?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resume an existing conversation in a **fresh pane** — the lifecycle peer of
|
|
40
|
+
* {@link create} (start fresh) and {@link adopt} (re-attach to a *running*
|
|
41
|
+
* pane). Use it after a crash, or to fork the conversation onto a new session:
|
|
42
|
+
* pass the `agentSessionId` you persisted from a prior {@link create}/
|
|
43
|
+
* {@link adopt}; the agent replays its history and you get a live handle.
|
|
44
|
+
*
|
|
45
|
+
* Composes the same spawn→boot→handle core as `create`; only identity differs
|
|
46
|
+
* (an existing id → the agent's resume flag, vs a fresh mint → `--session-id`).
|
|
47
|
+
*
|
|
48
|
+
* @throws `InvalidAgentSessionId` if `agentSessionId` is not a v4 UUID
|
|
49
|
+
* (before spawn).
|
|
50
|
+
* @throws `SessionExists` if a session with `{ namespace, name }` already exists
|
|
51
|
+
* — resume spawns a NEW pane and never silently adopts; pick an unused name,
|
|
52
|
+
* or {@link adopt} the running one.
|
|
53
|
+
* @throws the same boot failures as {@link create}
|
|
54
|
+
* (`LoginRequired`/`WorkspaceUntrusted`/`DialogStuck`/`AgentExitedDuringBoot`/
|
|
55
|
+
* `ReplTimeout`). An `AgentExitedDuringBoot` here most often means the id is
|
|
56
|
+
* already live in another pane (claude refuses to resume an in-use id).
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* import { create, resume } from "claudemux";
|
|
61
|
+
* const s = await create({ name: "job", cwd });
|
|
62
|
+
* const id = s.agentSessionId!; // persist this
|
|
63
|
+
* // …process restarts / crashes…
|
|
64
|
+
* const r = await resume({ name: "job-2", cwd, agentSessionId: id });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare function resume(opts: ResumeOptions): Promise<SessionHandle>;
|
|
68
|
+
//# sourceMappingURL=resume.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume.d.ts","sourceRoot":"","sources":["../../src/session/resume.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMjD;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gEAAgE;IAChE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAoBxE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { SessionExists } from "../errors.js";
|
|
2
|
+
import { formatSessionLabel } from "./ref.js";
|
|
3
|
+
import { resolveSessionContext } from "./resolve.js";
|
|
4
|
+
import { spawnBootHandle } from "./spawn-boot.js";
|
|
5
|
+
import { validateAgentSessionId } from "./validate.js";
|
|
6
|
+
/**
|
|
7
|
+
* Resume an existing conversation in a **fresh pane** — the lifecycle peer of
|
|
8
|
+
* {@link create} (start fresh) and {@link adopt} (re-attach to a *running*
|
|
9
|
+
* pane). Use it after a crash, or to fork the conversation onto a new session:
|
|
10
|
+
* pass the `agentSessionId` you persisted from a prior {@link create}/
|
|
11
|
+
* {@link adopt}; the agent replays its history and you get a live handle.
|
|
12
|
+
*
|
|
13
|
+
* Composes the same spawn→boot→handle core as `create`; only identity differs
|
|
14
|
+
* (an existing id → the agent's resume flag, vs a fresh mint → `--session-id`).
|
|
15
|
+
*
|
|
16
|
+
* @throws `InvalidAgentSessionId` if `agentSessionId` is not a v4 UUID
|
|
17
|
+
* (before spawn).
|
|
18
|
+
* @throws `SessionExists` if a session with `{ namespace, name }` already exists
|
|
19
|
+
* — resume spawns a NEW pane and never silently adopts; pick an unused name,
|
|
20
|
+
* or {@link adopt} the running one.
|
|
21
|
+
* @throws the same boot failures as {@link create}
|
|
22
|
+
* (`LoginRequired`/`WorkspaceUntrusted`/`DialogStuck`/`AgentExitedDuringBoot`/
|
|
23
|
+
* `ReplTimeout`). An `AgentExitedDuringBoot` here most often means the id is
|
|
24
|
+
* already live in another pane (claude refuses to resume an in-use id).
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { create, resume } from "claudemux";
|
|
29
|
+
* const s = await create({ name: "job", cwd });
|
|
30
|
+
* const id = s.agentSessionId!; // persist this
|
|
31
|
+
* // …process restarts / crashes…
|
|
32
|
+
* const r = await resume({ name: "job-2", cwd, agentSessionId: id });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export async function resume(opts) {
|
|
36
|
+
validateAgentSessionId(opts.agentSessionId);
|
|
37
|
+
const { ref, agent, backend } = resolveSessionContext(opts);
|
|
38
|
+
if (await backend.exists(ref)) {
|
|
39
|
+
throw new SessionExists(formatSessionLabel(ref));
|
|
40
|
+
}
|
|
41
|
+
return spawnBootHandle({
|
|
42
|
+
agent,
|
|
43
|
+
backend,
|
|
44
|
+
ref,
|
|
45
|
+
cwd: opts.cwd,
|
|
46
|
+
identity: { mode: "resume", agentSessionId: opts.agentSessionId },
|
|
47
|
+
hooks: opts.hooks !== false,
|
|
48
|
+
...(opts.extraArgs === undefined ? {} : { extraArgs: opts.extraArgs }),
|
|
49
|
+
...(opts.env === undefined ? {} : { env: opts.env }),
|
|
50
|
+
...(opts.bootTimeoutMs === undefined ? {} : { bootTimeoutMs: opts.bootTimeoutMs }),
|
|
51
|
+
...(opts.trustWorkspace === undefined ? {} : { trustWorkspace: opts.trustWorkspace }),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=resume.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume.js","sourceRoot":"","sources":["../../src/session/resume.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAqCvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAmB;IAC9C,sBAAsB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC5C,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IAE5D,IAAI,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,aAAa,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,eAAe,CAAC;QACrB,KAAK;QACL,OAAO;QACP,GAAG;QACH,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE;QACjE,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,KAAK;QAC3B,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;QACtE,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;QACpD,GAAG,CAAC,IAAI,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC;QAClF,GAAG,CAAC,IAAI,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC;KACtF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { AgentDef } from "../agents/types.js";
|
|
2
|
+
import type { Backend, SessionRef } from "../backends/types.js";
|
|
3
|
+
import type { SessionHandle } from "../types.js";
|
|
4
|
+
/**
|
|
5
|
+
* How the conversation id is decided for a spawn — the ONLY thing that differs
|
|
6
|
+
* between the lifecycle peers:
|
|
7
|
+
* - `fresh` (`create`): a minted or caller-chosen `sessionId` → `--session-id`.
|
|
8
|
+
* - `resume`: an existing `agentSessionId` → the agent's resume flag.
|
|
9
|
+
*/
|
|
10
|
+
type SpawnIdentity = {
|
|
11
|
+
readonly mode: "fresh";
|
|
12
|
+
readonly sessionId: string;
|
|
13
|
+
readonly explicit: boolean;
|
|
14
|
+
} | {
|
|
15
|
+
readonly mode: "resume";
|
|
16
|
+
readonly agentSessionId: string;
|
|
17
|
+
};
|
|
18
|
+
/** The shared spawn→boot→handle input. `identity` carries the fresh/resume split. */
|
|
19
|
+
export interface SpawnBootInput {
|
|
20
|
+
agent: AgentDef;
|
|
21
|
+
backend: Backend;
|
|
22
|
+
ref: SessionRef;
|
|
23
|
+
cwd: string;
|
|
24
|
+
identity: SpawnIdentity;
|
|
25
|
+
/** Inject the agent's observe hooks at spawn. */
|
|
26
|
+
hooks: boolean;
|
|
27
|
+
extraArgs?: string[];
|
|
28
|
+
env?: Record<string, string>;
|
|
29
|
+
bootTimeoutMs?: number;
|
|
30
|
+
trustWorkspace?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The shared lifecycle core for `create` (fresh) and `resume`: inject hooks,
|
|
34
|
+
* build the argv (mapping the {@link SpawnIdentity}), spawn the pane, boot it,
|
|
35
|
+
* cache the recoverable id, and return the handle. Both lifecycle faces compose
|
|
36
|
+
* this ONE owner so the spawn/boot/handle decision lives in a single place;
|
|
37
|
+
* they differ only in how identity is resolved before calling in.
|
|
38
|
+
*
|
|
39
|
+
* @throws the boot failures documented on {@link bootSession}; on any boot
|
|
40
|
+
* failure the just-spawned pane is killed (best-effort) before rethrowing.
|
|
41
|
+
*/
|
|
42
|
+
export declare function spawnBootHandle(o: SpawnBootInput): Promise<SessionHandle>;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=spawn-boot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn-boot.d.ts","sourceRoot":"","sources":["../../src/session/spawn-boot.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAOjD;;;;;GAKG;AACH,KAAK,aAAa,GACd;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAClF;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjE,qFAAqF;AACrF,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,UAAU,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,aAAa,CAAC;IACxB,iDAAiD;IACjD,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAwE/E"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { mkdirSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { bootSession } from "./boot.js";
|
|
4
|
+
import { AGENT_SESSION_ID_META_KEY } from "./constants.js";
|
|
5
|
+
import { makeHandle } from "./handle.js";
|
|
6
|
+
import { buildHookInjection } from "./hooks.js";
|
|
7
|
+
import { formatSessionLabel } from "./ref.js";
|
|
8
|
+
/**
|
|
9
|
+
* The shared lifecycle core for `create` (fresh) and `resume`: inject hooks,
|
|
10
|
+
* build the argv (mapping the {@link SpawnIdentity}), spawn the pane, boot it,
|
|
11
|
+
* cache the recoverable id, and return the handle. Both lifecycle faces compose
|
|
12
|
+
* this ONE owner so the spawn/boot/handle decision lives in a single place;
|
|
13
|
+
* they differ only in how identity is resolved before calling in.
|
|
14
|
+
*
|
|
15
|
+
* @throws the boot failures documented on {@link bootSession}; on any boot
|
|
16
|
+
* failure the just-spawned pane is killed (best-effort) before rethrowing.
|
|
17
|
+
*/
|
|
18
|
+
export async function spawnBootHandle(o) {
|
|
19
|
+
// The id the hook rendezvous is keyed on (the conversation we'll run under).
|
|
20
|
+
const idForHooks = o.identity.mode === "fresh" ? o.identity.sessionId : o.identity.agentSessionId;
|
|
21
|
+
const injection = buildHookInjection({
|
|
22
|
+
agent: o.agent,
|
|
23
|
+
sessionId: idForHooks,
|
|
24
|
+
enabled: o.hooks,
|
|
25
|
+
userExtraArgs: o.extraArgs ?? [],
|
|
26
|
+
});
|
|
27
|
+
if (injection.rendezvousPath !== undefined) {
|
|
28
|
+
mkdirSync(dirname(injection.rendezvousPath), { recursive: true });
|
|
29
|
+
}
|
|
30
|
+
const extraArgs = [...injection.args, ...(o.extraArgs ?? [])];
|
|
31
|
+
const argvBuild = o.agent.buildArgv({
|
|
32
|
+
cwd: o.cwd,
|
|
33
|
+
sessionName: formatSessionLabel(o.ref),
|
|
34
|
+
...(o.identity.mode === "fresh"
|
|
35
|
+
? { sessionId: o.identity.sessionId, sessionIdExplicit: o.identity.explicit }
|
|
36
|
+
: { resumeFrom: o.identity.agentSessionId }),
|
|
37
|
+
...(extraArgs.length > 0 ? { extraArgs } : {}),
|
|
38
|
+
});
|
|
39
|
+
const agentSessionId = argvBuild.agentSessionId;
|
|
40
|
+
const mergedEnv = { ...(argvBuild.env ?? {}), ...(o.env ?? {}) };
|
|
41
|
+
await o.backend.spawn({
|
|
42
|
+
namespace: o.ref.namespace,
|
|
43
|
+
name: o.ref.name,
|
|
44
|
+
cwd: o.cwd,
|
|
45
|
+
env: mergedEnv,
|
|
46
|
+
cmd: argvBuild.cmd,
|
|
47
|
+
argv: argvBuild.argv,
|
|
48
|
+
});
|
|
49
|
+
// The caller-known id to attribute a boot-death to: the resume id, or an
|
|
50
|
+
// explicitly-chosen fresh id (a minted v4 never collides, so omit it then).
|
|
51
|
+
const knownId = o.identity.mode === "resume"
|
|
52
|
+
? o.identity.agentSessionId
|
|
53
|
+
: o.identity.explicit
|
|
54
|
+
? o.identity.sessionId
|
|
55
|
+
: undefined;
|
|
56
|
+
try {
|
|
57
|
+
await bootSession(o.backend, o.agent, o.ref, {
|
|
58
|
+
cwd: o.cwd,
|
|
59
|
+
...(knownId === undefined ? {} : { agentSessionId: knownId }),
|
|
60
|
+
...(o.bootTimeoutMs === undefined ? {} : { timeoutMs: o.bootTimeoutMs }),
|
|
61
|
+
...(o.trustWorkspace === undefined ? {} : { trustWorkspace: o.trustWorkspace }),
|
|
62
|
+
...(injection.rendezvousPath === undefined
|
|
63
|
+
? {}
|
|
64
|
+
: { rendezvousPath: injection.rendezvousPath }),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
await o.backend.kill(o.ref).catch(() => undefined);
|
|
69
|
+
throw err;
|
|
70
|
+
}
|
|
71
|
+
// Best-effort: cache the id so adopt() can recover it after the process dies.
|
|
72
|
+
// Never load-bearing (the id is already on the handle); a failure is ignored.
|
|
73
|
+
if (agentSessionId !== undefined) {
|
|
74
|
+
await o.backend
|
|
75
|
+
.setSessionMeta(o.ref, AGENT_SESSION_ID_META_KEY, agentSessionId)
|
|
76
|
+
.catch(() => undefined);
|
|
77
|
+
}
|
|
78
|
+
return makeHandle({
|
|
79
|
+
backend: o.backend,
|
|
80
|
+
agent: o.agent,
|
|
81
|
+
namespace: o.ref.namespace,
|
|
82
|
+
name: o.ref.name,
|
|
83
|
+
...(agentSessionId === undefined ? {} : { agentSessionId }),
|
|
84
|
+
...(injection.rendezvousPath === undefined ? {} : { rendezvousPath: injection.rendezvousPath }),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=spawn-boot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn-boot.js","sourceRoot":"","sources":["../../src/session/spawn-boot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Validate a `name` or `namespace` field. Throws {@link InvalidSessionName}. */
|
|
2
|
+
export declare function validateNamePart(field: "name" | "namespace", value: string): void;
|
|
3
|
+
/**
|
|
4
|
+
* Validate a caller-supplied `agentSessionId`. Throws
|
|
5
|
+
* {@link InvalidAgentSessionId} if it is not a well-formed v4 UUID. This is a
|
|
6
|
+
* security boundary (the id reaches the agent argv and the backend's command
|
|
7
|
+
* grammar), not merely correctness — see the error's TSDoc.
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateAgentSessionId(value: string): void;
|
|
10
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/session/validate.ts"],"names":[],"mappings":"AA6BA,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAyBjF;AAWD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAI1D"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/session/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;AAE9E,8DAA8D;AAC9D,iGAAiG;AACjG,MAAM,YAAY,GAAG,OAAO,CAAC;AAE7B,iFAAiF;AACjF,MAAM,UAAU,gBAAgB,CAAC,KAA2B,EAAE,KAAa;IACzE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,mBAAmB,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,yDAAyD;QACzD,MAAM,IAAI,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,yBAAyB,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,kBAAkB,CAC1B,KAAK,EACL,KAAK,EACL,6EAA6E,CAC9E,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,EAAE,IAAI,cAAc,EAAE,CAAC;QAChC,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACnF,MAAM,IAAI,kBAAkB,CAC1B,KAAK,EACL,KAAK,EACL,oBAAoB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,gDAAgD,CAC1F,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,GAAG,wEAAwE,CAAC;AAEzF;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAa;IAClD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,qBAAqB,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { State } from "../types.js";
|
|
2
|
+
import type { ClassifierRules } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Map pane text → {@link State} via the agent's rules.
|
|
5
|
+
*
|
|
6
|
+
* **The dispatch order is load-bearing** and enforced by the function's
|
|
7
|
+
* structure, not by reviewer vigilance:
|
|
8
|
+
*
|
|
9
|
+
* `dialog → permission-prompt → working → idle → unknown`
|
|
10
|
+
*
|
|
11
|
+
* Dialog is checked before everything else so a boot dialog with a stray
|
|
12
|
+
* idle-shaped substring cannot mis-classify as idle. Permission-prompt is
|
|
13
|
+
* checked before working/idle so a permission shape mid-stream cannot
|
|
14
|
+
* mis-classify as working. `unknown` is the contractual "no predicate
|
|
15
|
+
* fired" return — consumers must not treat it as idle.
|
|
16
|
+
*
|
|
17
|
+
* @param text - The pane text to classify. Callers must pre-slice to the
|
|
18
|
+
* bottom-N lines (the "scrollback trap" — see
|
|
19
|
+
* `engineer/wiki/tmux-capture-pane-the-bottom-n-trap`).
|
|
20
|
+
* @param rules - The agent's predicate set.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { classify } from "./classifier.js";
|
|
25
|
+
* const state = classify(bottomLines, claude.rules);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function classify(text: string, rules: ClassifierRules): State;
|
|
29
|
+
//# sourceMappingURL=classifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classifier.d.ts","sourceRoot":"","sources":["../../src/state/classifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,KAAK,CAMpE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map pane text → {@link State} via the agent's rules.
|
|
3
|
+
*
|
|
4
|
+
* **The dispatch order is load-bearing** and enforced by the function's
|
|
5
|
+
* structure, not by reviewer vigilance:
|
|
6
|
+
*
|
|
7
|
+
* `dialog → permission-prompt → working → idle → unknown`
|
|
8
|
+
*
|
|
9
|
+
* Dialog is checked before everything else so a boot dialog with a stray
|
|
10
|
+
* idle-shaped substring cannot mis-classify as idle. Permission-prompt is
|
|
11
|
+
* checked before working/idle so a permission shape mid-stream cannot
|
|
12
|
+
* mis-classify as working. `unknown` is the contractual "no predicate
|
|
13
|
+
* fired" return — consumers must not treat it as idle.
|
|
14
|
+
*
|
|
15
|
+
* @param text - The pane text to classify. Callers must pre-slice to the
|
|
16
|
+
* bottom-N lines (the "scrollback trap" — see
|
|
17
|
+
* `engineer/wiki/tmux-capture-pane-the-bottom-n-trap`).
|
|
18
|
+
* @param rules - The agent's predicate set.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { classify } from "./classifier.js";
|
|
23
|
+
* const state = classify(bottomLines, claude.rules);
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function classify(text, rules) {
|
|
27
|
+
if (rules.dialog(text))
|
|
28
|
+
return "dialog";
|
|
29
|
+
if (rules.permissionPrompt(text))
|
|
30
|
+
return "permission-prompt";
|
|
31
|
+
if (rules.working(text))
|
|
32
|
+
return "working";
|
|
33
|
+
if (rules.idle(text))
|
|
34
|
+
return "idle";
|
|
35
|
+
return "unknown";
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=classifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classifier.js","sourceRoot":"","sources":["../../src/state/classifier.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,KAAsB;IAC3D,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IACxC,IAAI,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC;QAAE,OAAO,mBAAmB,CAAC;IAC7D,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1C,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC;IACpC,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Predicates the classifier dispatches over. Each agent (`src/agents/*.ts`)
|
|
3
|
+
* supplies its own rules; the classifier itself is agent-agnostic.
|
|
4
|
+
*/
|
|
5
|
+
export interface ClassifierRules {
|
|
6
|
+
/** True when the pane is showing a boot/system dialog. */
|
|
7
|
+
dialog(text: string): boolean;
|
|
8
|
+
/** True when the pane is showing a permission prompt awaiting user input. */
|
|
9
|
+
permissionPrompt(text: string): boolean;
|
|
10
|
+
/** True when the agent is actively producing output (spinner, streaming). */
|
|
11
|
+
working(text: string): boolean;
|
|
12
|
+
/** True when the REPL is idle and ready for input. */
|
|
13
|
+
idle(text: string): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* True when the pane shows a turn that was **interrupted** (ESC) rather than
|
|
16
|
+
* completed — a state only the pane sees (interrupt fires no `stop` hook).
|
|
17
|
+
* Optional: agents that can't distinguish it simply omit it. The Observer
|
|
18
|
+
* maps it to a `TurnOutcome` of `aborted`.
|
|
19
|
+
*/
|
|
20
|
+
interrupted?(text: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* True when the pane shows that input sent mid-turn was **queued** (the agent
|
|
23
|
+
* was busy, so it accepted the message to run after the current turn) rather
|
|
24
|
+
* than started immediately. Like {@link interrupted}, this is an orthogonal
|
|
25
|
+
* pane fact, NOT a dispatched {@link import('../types.js').State} (the agent is
|
|
26
|
+
* still `working`); it is read separately — by the send path, to tell a queued
|
|
27
|
+
* delivery ("accepted, will run") apart from a lost one ("re-send"). Optional:
|
|
28
|
+
* agents with no queue affordance omit it.
|
|
29
|
+
*/
|
|
30
|
+
queued?(text: string): boolean;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/state/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,0DAA0D;IAC1D,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,6EAA6E;IAC7E,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,6EAA6E;IAC7E,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,sDAAsD;IACtD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B;;;;;OAKG;IACH,WAAW,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACpC;;;;;;;;OAQG;IACH,MAAM,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CAChC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/state/types.ts"],"names":[],"mappings":""}
|