@ours.network/fleet 1.0.5 → 1.1.0-nightly.10

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 (159) hide show
  1. package/README.md +122 -133
  2. package/dist/agent-recovery-gate.d.ts +17 -0
  3. package/dist/agent-recovery-gate.js +135 -0
  4. package/dist/application/capabilities.d.ts +0 -1
  5. package/dist/application/capabilities.js +3 -13
  6. package/dist/application/fleet-query-service.d.ts +0 -3
  7. package/dist/application/fleet-query-service.js +14 -25
  8. package/dist/application/role-creation-service.d.ts +5 -24
  9. package/dist/application/role-creation-service.js +27 -67
  10. package/dist/application/role-removal-service.js +6 -3
  11. package/dist/application/role-repository.d.ts +1 -2
  12. package/dist/application/role-repository.js +7 -7
  13. package/dist/application/session-control.d.ts +0 -12
  14. package/dist/application/session-control.js +0 -42
  15. package/dist/application/session-mutations.d.ts +5 -5
  16. package/dist/application/task-room-service.d.ts +1 -1
  17. package/dist/application/task-room-service.js +154 -16
  18. package/dist/application/types.d.ts +1 -8
  19. package/dist/briefing.js +12 -11
  20. package/dist/build-info.json +5 -5
  21. package/dist/cli.js +143 -63
  22. package/dist/config-yaml.d.ts +1 -1
  23. package/dist/config.d.ts +66 -6
  24. package/dist/config.js +398 -43
  25. package/dist/creation.d.ts +1 -1
  26. package/dist/creation.js +2 -2
  27. package/dist/daemon-recovery.d.ts +93 -0
  28. package/dist/daemon-recovery.js +328 -0
  29. package/dist/docs.d.ts +1 -1
  30. package/dist/docs.js +103 -127
  31. package/dist/doctor.js +18 -11
  32. package/dist/fleet-command-audit.d.ts +160 -0
  33. package/dist/fleet-command-audit.js +433 -0
  34. package/dist/fleet-proxy.d.ts +3 -1
  35. package/dist/fleet-proxy.js +30 -8
  36. package/dist/generated-agent-source.d.ts +9 -0
  37. package/dist/generated-agent-source.js +53 -0
  38. package/dist/harness/acp-session-transport.d.ts +8 -0
  39. package/dist/harness/acp-session-transport.js +3 -0
  40. package/dist/harness/agent-session.d.ts +51 -0
  41. package/dist/harness/agent-session.js +1 -0
  42. package/dist/harness/claude-code-session.d.ts +24 -0
  43. package/dist/harness/claude-code-session.js +36 -0
  44. package/dist/harness/claude-code.d.ts +2 -1
  45. package/dist/harness/claude-code.js +41 -81
  46. package/dist/harness/codex-session.d.ts +24 -0
  47. package/dist/harness/codex-session.js +36 -0
  48. package/dist/harness/codex.d.ts +2 -1
  49. package/dist/harness/codex.js +55 -45
  50. package/dist/harness/registry.js +4 -0
  51. package/dist/harness/types.d.ts +6 -38
  52. package/dist/index.d.ts +4 -6
  53. package/dist/index.js +2 -4
  54. package/dist/init-guidance.d.ts +1 -0
  55. package/dist/init-guidance.js +6 -0
  56. package/dist/isolation/resources.d.ts +3 -7
  57. package/dist/isolation/resources.js +3 -7
  58. package/dist/model-env.d.ts +4 -6
  59. package/dist/model-env.js +5 -8
  60. package/dist/monitor.d.ts +1 -24
  61. package/dist/monitor.js +5 -140
  62. package/dist/ops.js +4 -2
  63. package/dist/owner-channel/channel.d.ts +58 -2
  64. package/dist/owner-channel/channel.js +269 -29
  65. package/dist/owner-channel/commands.d.ts +2 -0
  66. package/dist/owner-channel/commands.js +31 -13
  67. package/dist/owner-channel/state.d.ts +2 -0
  68. package/dist/owner-channel/state.js +8 -2
  69. package/dist/preset-bootstrap.d.ts +10 -0
  70. package/dist/preset-bootstrap.js +85 -0
  71. package/dist/reports/artifact.d.ts +10 -0
  72. package/dist/reports/artifact.js +32 -0
  73. package/dist/reports/index.d.ts +5 -0
  74. package/dist/reports/index.js +5 -0
  75. package/dist/reports/render.d.ts +6 -0
  76. package/dist/reports/render.js +240 -0
  77. package/dist/reports/service.d.ts +42 -0
  78. package/dist/reports/service.js +57 -0
  79. package/dist/reports/tasks.d.ts +52 -0
  80. package/dist/reports/tasks.js +177 -0
  81. package/dist/reports/types.d.ts +315 -0
  82. package/dist/reports/types.js +6 -0
  83. package/dist/resolved-plan.d.ts +3 -2
  84. package/dist/resolved-plan.js +21 -5
  85. package/dist/rooms-tasks/cli.js +225 -40
  86. package/dist/rooms-tasks/config.js +24 -13
  87. package/dist/rooms-tasks/external-worker.d.ts +1 -0
  88. package/dist/rooms-tasks/external-worker.js +14 -9
  89. package/dist/rooms-tasks/provision.js +98 -36
  90. package/dist/rooms-tasks/templates.d.ts +0 -1
  91. package/dist/rooms-tasks/templates.js +9 -76
  92. package/dist/rooms-tasks/types.d.ts +10 -16
  93. package/dist/rooms-tasks/types.js +1 -4
  94. package/dist/runner.d.ts +13 -16
  95. package/dist/runner.js +110 -122
  96. package/dist/sensitive-config.d.ts +2 -0
  97. package/dist/sensitive-config.js +4 -0
  98. package/dist/session/acp.d.ts +7 -2
  99. package/dist/session/acp.js +29 -6
  100. package/dist/session/activity.d.ts +2 -3
  101. package/dist/session/activity.js +2 -3
  102. package/dist/session/arbiter.d.ts +4 -4
  103. package/dist/session/control.d.ts +17 -4
  104. package/dist/session/control.js +35 -0
  105. package/dist/session/types.d.ts +11 -5
  106. package/dist/spawn.d.ts +8 -33
  107. package/dist/spawn.js +53 -213
  108. package/dist/supervisor/none.d.ts +1 -1
  109. package/dist/supervisor/none.js +2 -2
  110. package/dist/temp-lifecycle.d.ts +1 -1
  111. package/dist/tmux.d.ts +1 -14
  112. package/dist/tmux.js +1 -51
  113. package/dist/watchdog/config.d.ts +10 -7
  114. package/dist/watchdog/config.js +30 -18
  115. package/dist/watchdog/run.js +12 -36
  116. package/dist/web/auth.d.ts +1 -1
  117. package/dist/web/fleet-config-service.d.ts +11 -8
  118. package/dist/web/fleet-config-service.js +384 -183
  119. package/dist/web/runtime.js +4 -15
  120. package/dist/web/server.d.ts +1 -3
  121. package/dist/web/server.js +3 -14
  122. package/dist/web/topology-promote.js +26 -19
  123. package/dist/web/topology.js +2 -2
  124. package/dist/web/yaml-document-edit.js +2 -0
  125. package/dist/web-app/assets/index-59GF-gsZ.css +1 -0
  126. package/dist/web-app/assets/index-BbTc5KtZ.js +10 -0
  127. package/dist/web-app/index.html +2 -2
  128. package/examples/fleet/agents/Alice.yaml +11 -0
  129. package/examples/fleet/agents/FleetCoordinator.yaml +7 -0
  130. package/examples/fleet/brains/claude-default.yaml +5 -0
  131. package/examples/fleet/roles/coordinator.yaml +5 -0
  132. package/examples/fleet/roles/developer.yaml +3 -0
  133. package/examples/fleet.yaml +74 -0
  134. package/package.json +5 -8
  135. package/presets/fleet/agents/Agent.yaml +3 -0
  136. package/presets/fleet/agents/Architect.yaml +3 -0
  137. package/presets/fleet/agents/Critic.yaml +3 -0
  138. package/presets/fleet/agents/Developer.yaml +3 -0
  139. package/presets/fleet/agents/Secretary.yaml +3 -0
  140. package/presets/fleet/agents/Tester.yaml +3 -0
  141. package/presets/fleet/brains/claude-default.yaml +5 -0
  142. package/presets/fleet/roles/Agent.yaml +6 -0
  143. package/presets/fleet/roles/Architect.yaml +6 -0
  144. package/presets/fleet/roles/Critic.yaml +6 -0
  145. package/presets/fleet/roles/Developer.yaml +6 -0
  146. package/presets/fleet/roles/Secretary.yaml +6 -0
  147. package/presets/fleet/roles/Tester.yaml +6 -0
  148. package/presets/fleet/room_templates/pair.yaml +11 -0
  149. package/presets/fleet/room_templates/single.yaml +8 -0
  150. package/presets/fleet/room_templates/team.yaml +12 -0
  151. package/presets/fleet.yaml +7 -0
  152. package/presets/manifest.json +5 -0
  153. package/dist/session/tmux.d.ts +0 -28
  154. package/dist/session/tmux.js +0 -80
  155. package/dist/web/terminal/bridge.d.ts +0 -27
  156. package/dist/web/terminal/bridge.js +0 -317
  157. package/dist/web-app/assets/TerminalView-C_G1ID2P.js +0 -9
  158. package/dist/web-app/assets/index-BCBK78hw.js +0 -10
  159. package/dist/web-app/assets/index-DuC-xnX4.css +0 -1
@@ -8,8 +8,8 @@
8
8
  <link rel="manifest" href="/manifest.webmanifest" />
9
9
  <link rel="icon" href="/icons/ours-fleet.svg" type="image/svg+xml" />
10
10
  <title>ours fleet console</title>
11
- <script type="module" crossorigin src="/assets/index-BCBK78hw.js"></script>
12
- <link rel="stylesheet" crossorigin href="/assets/index-DuC-xnX4.css">
11
+ <script type="module" crossorigin src="/assets/index-BbTc5KtZ.js"></script>
12
+ <link rel="stylesheet" crossorigin href="/assets/index-59GF-gsZ.css">
13
13
  </head>
14
14
  <body>
15
15
  <div id="root"></div>
@@ -0,0 +1,11 @@
1
+ role: { ref: developer }
2
+ brain: { ref: claude-default }
3
+ identity: Alice
4
+ coordinator: FleetCoordinator
5
+ cwd: ${work_root}/alice
6
+ permissions: { approval: ask, filesystem: workspace, unattended: deny }
7
+ env:
8
+ EXAMPLE_FLAG: "1"
9
+ monitor:
10
+ wake_sources: [message_received, file_received]
11
+ batch_ms: 2000
@@ -0,0 +1,7 @@
1
+ role: { ref: coordinator }
2
+ brain: { ref: claude-default }
3
+ identity: FleetCoordinator
4
+ cwd: ${work_root}
5
+ permissions: { approval: ask, filesystem: workspace, unattended: deny }
6
+ oversee:
7
+ - { agent: Alice, interval: 5m }
@@ -0,0 +1,5 @@
1
+ harness: claude-code
2
+ session: acp
3
+ model: null
4
+ effort: high
5
+ max_tokens: 500000
@@ -0,0 +1,5 @@
1
+ mission: "Coordinate the fleet: decompose goals, delegate work, review results, and report."
2
+ persona: |
3
+ You are the always-on hub. Keep ownership and status explicit and do not silently
4
+ take over work that should remain delegated.
5
+ bio: Fleet coordinator and owner-facing point of contact.
@@ -0,0 +1,3 @@
1
+ mission: Own the assigned repository end to end.
2
+ persona: Fix problems at the source, ship sound tests, and escalate cross-repository decisions.
3
+ bio: Repository developer; engage for implementation and maintenance.
@@ -0,0 +1,74 @@
1
+ # fleet.yaml — fleet-wide manifest; Agent/Role/Brain files live under ./fleet/.
2
+ #
3
+ # ours-fleet up create/start every role (idempotent)
4
+ # ours-fleet up Alice only the named role(s)
5
+ # ours-fleet restart re-sync + bounce, resuming context
6
+ # ours-fleet down stop everything
7
+ # ours-fleet config validate + print the merged plan
8
+ #
9
+ # Agent files are bare mappings in ./fleet/agents; reusable presets are in
10
+ # ./fleet/roles and ./fleet/brains. Kind comes from the directory and ID from filename.
11
+ #
12
+ # The v2 manifest contains fleet-wide operational policy and automation only.
13
+ # Brain and Role settings belong in bare documents under ./fleet/brains and
14
+ # ./fleet/roles; Agents compose them under ./fleet/agents. Legacy `roles:` and
15
+ # `fleet.d` are rejected. The web editor writes the manifest and direct Agent
16
+ # documents transactionally; Role/Brain presets remain read-only. Run
17
+ # `ours-fleet config` to validate the complete source set.
18
+
19
+ api_version: ours.network/fleet/v2
20
+
21
+ vars:
22
+ work_root: /home/me/work
23
+
24
+ # Space out agent LAUNCHES host-wide (ms) so a burst of boots doesn't hit the
25
+ # harness/API rate limit at once. Default 0 (no stagger). Enforced at the launch
26
+ # point, so it covers systemd host-boot too — not just `ours-fleet up`/restart.
27
+ # A lone start/restart waits zero; only concurrent boots are spread out.
28
+ # (Replaces the retired FLEET_START_STAGGER env var — see README "Start staggering".)
29
+ # start_stagger_ms: 4000
30
+
31
+ defaults:
32
+ permissions: # common intent translated to each harness/backend
33
+ approval: ask # ask | allow | deny
34
+ filesystem: workspace # read-only | workspace | unrestricted
35
+ unattended: deny # deny | wait when no ACP console is attached
36
+ monitor:
37
+ mode: fleet # fleet (default): ours-fleet supervisor; native: harness-owned monitor
38
+ interrupt: false # false: queue; true: cancel; after_tool: steer at an ACP tool boundary
39
+
40
+ # Harness, model, effort, session, token limits, session_options, and
41
+ # harness_options are Brain-owned. Define them in ./fleet/brains and select the
42
+ # Brain from each Agent document; see ./fleet/brains/claude-default.yaml.
43
+
44
+ # Rooms always use ours-cowork; configure its connection directly. The owner
45
+ # provider is a separate setting and defaults to messenger-server.
46
+ # rooms:
47
+ # cowork:
48
+ # config: /home/me/.ours-cowork/config.json
49
+ # owner:
50
+ # expected_cid: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
51
+ # public_invite_file: /home/me/.ours-fleet/owner-room-invite.txt
52
+ # defaults:
53
+ # template: team
54
+ # attach_owner: true
55
+ # close_when_task_done: true
56
+ #
57
+ # tasks:
58
+ # default_room_template: team
59
+ # create_mode: start
60
+ # close_room_on_done: true
61
+
62
+ # Scheduled internal turns are ACP-only, idle-only, and never build a backlog.
63
+ # The base file must be owned by you and not group/world writable when an enabled
64
+ # loop is present. A wildcard targets permanent roles only; temp roles do not inherit.
65
+ # loops:
66
+ # coordinator_pass:
67
+ # roles: [FleetCoordinator]
68
+ # interval: 10m
69
+ # initial_delay: 10m # omitted = one full interval; use 0s explicitly for immediate
70
+ # jitter: 30s
71
+ # enabled: true
72
+ # prompt: |
73
+ # Review current fleet state once and unstick only actionable work.
74
+ # If nothing material changed, complete silently without an owner report.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ours.network/fleet",
3
- "version": "1.0.5",
4
- "description": "Harness-agnostic fleet of persistent, identity-bound AI agents. Declarative fleet.yaml, tmux or ACP sessions, supervision, and ours.network messaging.",
3
+ "version": "1.1.0-nightly.10",
4
+ "description": "Harness-agnostic fleet of persistent, identity-bound AI agents. Declarative fleet.yaml, ACP sessions, supervision, and ours.network messaging.",
5
5
  "type": "module",
6
6
  "license": "FSL-1.1-Apache-2.0",
7
7
  "repository": {
@@ -15,6 +15,8 @@
15
15
  "files": [
16
16
  "dist",
17
17
  "contrib",
18
+ "examples",
19
+ "presets",
18
20
  "README.md",
19
21
  "LICENSE"
20
22
  ],
@@ -40,10 +42,6 @@
40
42
  "@fastify/websocket": "^11.2.0",
41
43
  "@ours.network/cli": "1.0.1",
42
44
  "@ours.network/sdk": "3.0.1",
43
- "@xterm/addon-fit": "0.10.0",
44
- "@xterm/addon-serialize": "0.13.0",
45
- "@xterm/headless": "5.5.0",
46
- "@xterm/xterm": "5.5.0",
47
45
  "commander": "^12.1.0",
48
46
  "fastify": "^5.4.0",
49
47
  "react": "^19.1.1",
@@ -54,8 +52,7 @@
54
52
  },
55
53
  "optionalDependencies": {
56
54
  "@agentclientprotocol/claude-agent-acp": "^0.63.0",
57
- "@agentclientprotocol/codex-acp": "1.1.7",
58
- "node-pty": "^1.1.0"
55
+ "@agentclientprotocol/codex-acp": "1.1.7"
59
56
  },
60
57
  "devDependencies": {
61
58
  "@playwright/test": "^1.54.1",
@@ -0,0 +1,3 @@
1
+ role: { ref: Agent }
2
+ brain: { ref: claude-default }
3
+ permissions: { approval: ask, filesystem: workspace, unattended: deny }
@@ -0,0 +1,3 @@
1
+ role: { ref: Architect }
2
+ brain: { ref: claude-default }
3
+ permissions: { approval: ask, filesystem: workspace, unattended: deny }
@@ -0,0 +1,3 @@
1
+ role: { ref: Critic }
2
+ brain: { ref: claude-default }
3
+ permissions: { approval: ask, filesystem: workspace, unattended: deny }
@@ -0,0 +1,3 @@
1
+ role: { ref: Developer }
2
+ brain: { ref: claude-default }
3
+ permissions: { approval: ask, filesystem: workspace, unattended: deny }
@@ -0,0 +1,3 @@
1
+ role: { ref: Secretary }
2
+ brain: { ref: claude-default }
3
+ permissions: { approval: ask, filesystem: workspace, unattended: deny }
@@ -0,0 +1,3 @@
1
+ role: { ref: Tester }
2
+ brain: { ref: claude-default }
3
+ permissions: { approval: ask, filesystem: workspace, unattended: deny }
@@ -0,0 +1,5 @@
1
+ harness: claude-code
2
+ session: acp
3
+ model: null
4
+ effort: high
5
+ max_tokens: 500000
@@ -0,0 +1,6 @@
1
+ mission: Complete the assigned task safely and report a verifiable result.
2
+ persona: |
3
+ Work autonomously within the stated scope. Inspect before changing, preserve unrelated
4
+ state, test material work, and ask the owner when authority or intent is ambiguous.
5
+ Do not expand scope, publish, deploy, or claim completion without evidence.
6
+ bio: General-purpose task agent; engage for one bounded task with owner oversight.
@@ -0,0 +1,6 @@
1
+ mission: Produce an implementable specification for the assigned goal.
2
+ persona: |
3
+ Map constraints, interfaces, risks, acceptance criteria, and migration behavior before
4
+ implementation. Resolve ambiguity with the owner and hand off a bounded design. Do not
5
+ implement or approve deployment unless the task explicitly expands your role.
6
+ bio: Solution architect; engage to turn a goal into a bounded, reviewable specification.
@@ -0,0 +1,6 @@
1
+ mission: Independently challenge the proposed solution and verify its evidence.
2
+ persona: |
3
+ Audit assumptions, safety boundaries, regressions, tests, and delivery claims. Explain
4
+ concrete objections and acceptance criteria; do not edit the implementation or block
5
+ on taste alone. Sign off only when material risks have evidence-backed resolution.
6
+ bio: Independent reviewer; engage to challenge design, implementation, and verification.
@@ -0,0 +1,6 @@
1
+ mission: Implement the approved specification with maintainable code and tests.
2
+ persona: |
3
+ Make the smallest coherent change that satisfies the specification. Preserve unrelated
4
+ work, validate behavior in proportion to risk, and report deviations immediately. Do
5
+ not redesign approved scope, waive failing tests, publish, or deploy without authority.
6
+ bio: Implementation specialist; engage after a specification is approved.
@@ -0,0 +1,6 @@
1
+ mission: Implement the agreed solution and maintain the task's shared record.
2
+ persona: |
3
+ Turn agreed decisions into focused code, documentation, and tests. Keep collaborators
4
+ informed with compact evidence and preserve unrelated state. Pause material work for
5
+ required review; do not merge, publish, or widen scope without owner authorization.
6
+ bio: Implementing partner and record keeper; engage to deliver reviewed changes.
@@ -0,0 +1,6 @@
1
+ mission: Verify that the implementation satisfies the approved specification.
2
+ persona: |
3
+ Test observable behavior, failure paths, compatibility, and regression risk independently.
4
+ Report reproducible evidence and distinguish defects from preferences. Do not repair the
5
+ implementation or sign off with unresolved material failures.
6
+ bio: Independent verifier; engage to assess conformance, safety, and regression coverage.
@@ -0,0 +1,11 @@
1
+ version: 1
2
+ description: "Deliberation pair: Secretary writes code, Critic reviews — every decision deliberated together"
3
+ room: { quiet_membership: false, anonymous: false }
4
+ contract: |
5
+ Secretary and Critic deliberate every decision together before acting.
6
+ Secretary writes code; Critic reviews and challenges.
7
+ No material change lands without both agreeing.
8
+ Completion requires joint sign-off.
9
+ members:
10
+ - { slot: secretary, role: Secretary, count: 1, agent: { ref: Secretary } }
11
+ - { slot: critic, role: Critic, count: 1, agent: { ref: Critic } }
@@ -0,0 +1,8 @@
1
+ version: 1
2
+ description: "Solo agent: one general-purpose agent works the task with owner oversight"
3
+ room: { quiet_membership: false, anonymous: false }
4
+ contract: |
5
+ Agent works the task autonomously, consulting the owner when blocked.
6
+ Owner reviews and approves completion.
7
+ members:
8
+ - { slot: agent, role: Agent, count: 1, agent: { ref: Agent } }
@@ -0,0 +1,12 @@
1
+ version: 1
2
+ description: "Phased task pipeline: Architect specifies, Developer implements, Tester verifies"
3
+ room: { quiet_membership: false, anonymous: false }
4
+ contract: |
5
+ Architect produces a spec and posts it to the room. Work pauses for owner approval.
6
+ Developer implements per approved spec.
7
+ Tester verifies spec conformance and test coverage.
8
+ Completion requires tester sign-off.
9
+ members:
10
+ - { slot: architect, role: Architect, count: 1, agent: { ref: Architect } }
11
+ - { slot: developer, role: Developer, count: 1, agent: { ref: Developer } }
12
+ - { slot: tester, role: Tester, count: 1, agent: { ref: Tester } }
@@ -0,0 +1,7 @@
1
+ api_version: ours.network/fleet/v2
2
+
3
+ defaults:
4
+ permissions: { approval: ask, filesystem: workspace, unattended: deny }
5
+
6
+ # Rooms require an authenticated owner CID/invite before they can be started.
7
+ # See `ours-fleet docs`, then add `rooms:` and `tasks:` here.
@@ -0,0 +1,5 @@
1
+ {
2
+ "schema_version": 1,
3
+ "preset_revision": 1,
4
+ "description": "ours-fleet standard configuration presets"
5
+ }
@@ -1,28 +0,0 @@
1
- import type { Tmux } from '../tmux.js';
2
- import type { ExitRecord, InterruptOutcome, QueuedPrompt, SessionEvent, SessionHandle, SessionSnapshot, SubmitPromptOptions, TurnResult } from './types.js';
3
- /** SessionHandle adapter for the existing tmux transport. */
4
- export declare class TmuxSession implements SessionHandle {
5
- private readonly name;
6
- readonly pid: number;
7
- private readonly tmux;
8
- private readonly processAlive;
9
- readonly backend: "tmux";
10
- constructor(name: string, pid: number, tmux: Tmux, processAlive: (pid: number) => boolean);
11
- isAlive(): boolean;
12
- snapshot(): SessionSnapshot;
13
- queuePrompt(text: string, options?: SubmitPromptOptions): Promise<QueuedPrompt>;
14
- submitPrompt(text: string, options?: SubmitPromptOptions): Promise<TurnResult>;
15
- /** A keystroke is delivered or it throws; tmux offers no forced-recovery path. */
16
- interrupt(): Promise<InterruptOutcome>;
17
- respondPermission(): boolean;
18
- eventsSince(): SessionEvent[];
19
- subscribe(): () => void;
20
- setControllerAttached(): void;
21
- /**
22
- * A tmux pane's exit is only visible through the record its shell wrapper
23
- * writes; the runner owns that file and classifies it. Nothing observable
24
- * from here, so say `null` rather than guess.
25
- */
26
- exitResult(): ExitRecord | null;
27
- close(): Promise<void>;
28
- }
@@ -1,80 +0,0 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { SessionControlError, turnResult } from './types.js';
3
- /** SessionHandle adapter for the existing tmux transport. */
4
- export class TmuxSession {
5
- name;
6
- pid;
7
- tmux;
8
- processAlive;
9
- backend = 'tmux';
10
- constructor(name, pid, tmux, processAlive) {
11
- this.name = name;
12
- this.pid = pid;
13
- this.tmux = tmux;
14
- this.processAlive = processAlive;
15
- }
16
- isAlive() {
17
- return this.processAlive(this.pid);
18
- }
19
- snapshot() {
20
- return {
21
- backend: 'tmux',
22
- alive: this.isAlive(),
23
- readiness: this.isAlive() ? 'idle' : 'failed',
24
- };
25
- }
26
- async queuePrompt(text, options = {}) {
27
- if (!this.isAlive())
28
- throw new SessionControlError('offline', `tmux pane for '${this.name}' is offline`);
29
- try {
30
- if (options.interrupt)
31
- await this.interrupt();
32
- await this.tmux.sendText(this.name, text);
33
- }
34
- catch (error) {
35
- throw new SessionControlError('backend', error?.message ?? String(error));
36
- }
37
- // Keystrokes carry no terminal result: tmux cannot tell us how the turn ended.
38
- return {
39
- promptId: randomUUID(),
40
- queuedBehind: 0,
41
- completion: Promise.resolve(turnResult(true, 'inconclusive')),
42
- };
43
- }
44
- async submitPrompt(text, options = {}) {
45
- try {
46
- return await (await this.queuePrompt(text, options)).completion;
47
- }
48
- catch (error) {
49
- if (error instanceof SessionControlError)
50
- return turnResult(false, 'failed', error.message);
51
- throw error;
52
- }
53
- }
54
- /** A keystroke is delivered or it throws; tmux offers no forced-recovery path. */
55
- async interrupt() {
56
- await this.tmux.sendKey(this.name, 'C-c');
57
- return { state: 'settled' };
58
- }
59
- respondPermission() {
60
- return false;
61
- }
62
- eventsSince() {
63
- return [];
64
- }
65
- subscribe() {
66
- return () => { };
67
- }
68
- setControllerAttached() { }
69
- /**
70
- * A tmux pane's exit is only visible through the record its shell wrapper
71
- * writes; the runner owns that file and classifies it. Nothing observable
72
- * from here, so say `null` rather than guess.
73
- */
74
- exitResult() {
75
- return null;
76
- }
77
- async close() {
78
- await this.tmux.kill(this.name);
79
- }
80
- }
@@ -1,27 +0,0 @@
1
- import type { WebSocket } from 'ws';
2
- import { Tmux } from '../../tmux.js';
3
- import type { RoleRepository } from '../../application/role-repository.js';
4
- import type { AuditSink } from '../audit.js';
5
- type Constructor<T> = new (...args: any[]) => T;
6
- /** Node exposes these CommonJS xterm packages under `default`; Vite may expose named exports. */
7
- export declare function resolveModuleConstructor<T>(module: unknown, name: string): Constructor<T>;
8
- export interface TerminalBridgeManagerOptions {
9
- repository: RoleRepository;
10
- audit: AuditSink;
11
- tmux?: Tmux;
12
- maxBridges?: number;
13
- graceMs?: number;
14
- loadPty?: () => Promise<typeof import('node-pty')>;
15
- }
16
- export declare class TerminalBridgeManager {
17
- private readonly options;
18
- private readonly bridges;
19
- private ptyModule?;
20
- private ptyError?;
21
- constructor(options: TerminalBridgeManagerOptions);
22
- available(): Promise<boolean>;
23
- diagnostic(): string | undefined;
24
- connect(socket: WebSocket, roleId: string, hello: Record<string, unknown>): Promise<void>;
25
- close(): Promise<void>;
26
- }
27
- export {};