@ours.network/fleet 1.2.0-nightly.2 → 1.2.0-nightly.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +18 -21
  2. package/dist/agent-ours/bridge.d.ts +3 -0
  3. package/dist/agent-ours/bridge.js +169 -0
  4. package/dist/agent-ours/controller.d.ts +14 -0
  5. package/dist/agent-ours/controller.js +60 -0
  6. package/dist/agent-ours/file-rpc.d.ts +23 -0
  7. package/dist/agent-ours/file-rpc.js +123 -0
  8. package/dist/agent-ours/harness.d.ts +14 -0
  9. package/dist/agent-ours/harness.js +64 -0
  10. package/dist/agent-ours/mcp-endpoint.d.ts +15 -0
  11. package/dist/agent-ours/mcp-endpoint.js +111 -0
  12. package/dist/agent-ours/runtime.d.ts +53 -0
  13. package/dist/agent-ours/runtime.js +247 -0
  14. package/dist/agent-ours/service.d.ts +23 -0
  15. package/dist/agent-ours/service.js +352 -0
  16. package/dist/agent-ours/state.d.ts +45 -0
  17. package/dist/agent-ours/state.js +95 -0
  18. package/dist/agent-ours/wire.d.ts +14 -0
  19. package/dist/agent-ours/wire.js +55 -0
  20. package/dist/agent-recovery-gate.js +1 -1
  21. package/dist/briefing.js +10 -59
  22. package/dist/build-info.json +4 -4
  23. package/dist/cli.js +15 -2
  24. package/dist/creation.d.ts +1 -1
  25. package/dist/creation.js +3 -14
  26. package/dist/docs.d.ts +1 -1
  27. package/dist/docs.js +15 -20
  28. package/dist/doctor.js +2 -2
  29. package/dist/fleet-command-audit.js +1 -1
  30. package/dist/harness/agent-session.d.ts +2 -0
  31. package/dist/harness/claude-code-session.js +4 -2
  32. package/dist/harness/codex-session.js +9 -2
  33. package/dist/harness/hermes-session.js +7 -1
  34. package/dist/rooms-tasks/provision.js +9 -2
  35. package/dist/runner.d.ts +4 -0
  36. package/dist/runner.js +522 -492
  37. package/dist/session/codex-app-server-transport.js +1 -1
  38. package/dist/spawn.js +12 -16
  39. package/dist/temp-supervisor-recovery.d.ts +3 -0
  40. package/dist/temp-supervisor-recovery.js +46 -0
  41. package/dist/watchdog/briefing.js +3 -16
  42. package/dist/watchdog/run.js +19 -5
  43. package/package.json +5 -3
@@ -1,3 +1,4 @@
1
+ import type { ManagedHarnessOurs } from '../agent-ours/harness.js';
1
2
  import type { CommonPermissions, FleetPermissionMode, ResolvedRole } from '../config.js';
2
3
  import type { AgentSession } from '../session/types.js';
3
4
  import type { Launch, SessionPrep } from './types.js';
@@ -22,6 +23,7 @@ export interface AgentSessionConfigSelection {
22
23
  value: string;
23
24
  }
24
25
  export interface AgentSessionStartOptions {
26
+ managedOurs?: ManagedHarnessOurs;
25
27
  role: ResolvedRole;
26
28
  prep: SessionPrep;
27
29
  launch: PreparedAgentSessionLaunch;
@@ -1,3 +1,4 @@
1
+ import { managedClaudeMeta } from '../agent-ours/harness.js';
1
2
  import { AcpSession } from '../session/acp.js';
2
3
  import { acpAdapterState, } from './acp-session-transport.js';
3
4
  /** Explicit Claude Code implementation of Fleet's shared agent-session factory. */
@@ -25,8 +26,9 @@ export class ClaudeCodeAgentSessionAdapter {
25
26
  argv: launch.argv, cwd: options.cwd, env: launch.env,
26
27
  stateDir: options.stateDir, mode: options.mode, permissions: options.permissions,
27
28
  modeId: this.strategy.permissionModeId(role),
28
- mcpServers: this.strategy.mcpServers(role),
29
- sessionMeta: this.strategy.sessionMeta(role, prep),
29
+ mcpServers: options.managedOurs ? [...(this.strategy.mcpServers(role) ?? []).filter(s => s.name !== 'ours'), options.managedOurs.server] : this.strategy.mcpServers(role),
30
+ inheritEnvironment: options.managedOurs ? false : undefined,
31
+ sessionMeta: options.managedOurs ? managedClaudeMeta(this.strategy.sessionMeta(role, prep)) : this.strategy.sessionMeta(role, prep),
30
32
  configSelections: this.strategy.sessionConfigSelections(role),
31
33
  permissionMode: options.permissionMode,
32
34
  permissionMetadataSource: acpAdapterState(launch.adapterState).permissionMetadataSource,
@@ -23,6 +23,12 @@ export class CodexAgentSessionAdapter {
23
23
  }
24
24
  start(options) {
25
25
  const { role, prep, launch } = options;
26
+ const original = this.strategy.nativeConfig(role) ?? {};
27
+ const managed = options.managedOurs?.native;
28
+ const config = managed ? { ...original, ...managed,
29
+ mcp_servers: { ...(original.mcp_servers ?? {}), ...(managed.mcp_servers ?? {}) },
30
+ plugins: { ...(original.plugins ?? {}), ...(managed.plugins ?? {}) },
31
+ } : original;
26
32
  if (role.session === 'codex-app-server')
27
33
  return this.nativeTransport({
28
34
  name: role.name, argv: launch.argv, cwd: options.cwd, env: launch.env,
@@ -31,7 +37,7 @@ export class CodexAgentSessionAdapter {
31
37
  model: role.model, effort: role.effort,
32
38
  approvalPolicy: this.strategy.approvalPolicy(role),
33
39
  sandbox: this.strategy.sandbox(role),
34
- config: this.strategy.nativeConfig(role),
40
+ config,
35
41
  addDirs: this.strategy.addDirs(role),
36
42
  log: options.log,
37
43
  });
@@ -40,7 +46,8 @@ export class CodexAgentSessionAdapter {
40
46
  argv: launch.argv, cwd: options.cwd, env: launch.env,
41
47
  stateDir: options.stateDir, mode: options.mode, permissions: options.permissions,
42
48
  modeId: this.strategy.permissionModeId(role),
43
- mcpServers: this.strategy.mcpServers(role),
49
+ mcpServers: options.managedOurs ? [...(this.strategy.mcpServers(role) ?? []).filter(s => s.name !== 'ours'), options.managedOurs.server] : this.strategy.mcpServers(role),
50
+ inheritEnvironment: options.managedOurs ? false : undefined,
44
51
  sessionMeta: this.strategy.sessionMeta(role, prep),
45
52
  configSelections: this.strategy.sessionConfigSelections(role),
46
53
  permissionMode: options.permissionMode,
@@ -53,6 +53,12 @@ export class HermesAgentSessionAdapter {
53
53
  // composition; no second ambient merge may reintroduce provider secrets.
54
54
  const env = hermesChildEnvironment(role, preparedHome(prep), launch.env, launch.env);
55
55
  delete env.OURS_AUTOSTART;
56
+ if (options.managedOurs) {
57
+ for (const key of Object.keys(env))
58
+ if (key.startsWith('OURS_') && !key.startsWith('OURS_FLEET_'))
59
+ delete env[key];
60
+ Object.assign(env, { FLEET_OURS_MANAGED: '1' });
61
+ }
56
62
  await this.checks.preflight?.(options, env);
57
63
  const nativeProvider = await this.checks.expectedProvider(role, prep);
58
64
  if (typeof nativeProvider !== 'string' || !nativeProvider.trim())
@@ -68,7 +74,7 @@ export class HermesAgentSessionAdapter {
68
74
  permissions: options.permissions, modeId, requireMode: true,
69
75
  permissionMode: { fleetMode: options.permissionMode.fleetMode, nativeMode: modeId },
70
76
  permissionTimeoutMs: 50_000,
71
- mcpServers: hermesMcpServers(role, env),
77
+ mcpServers: options.managedOurs ? [...hermesMcpServers(role, env).filter(s => s.name !== 'ours'), options.managedOurs.server] : hermesMcpServers(role, env),
72
78
  scrubObsoleteOursAutostart: true,
73
79
  validateStartupResponse: async (initialized, created) => {
74
80
  await this.checks.validateArtifact(initialized);
@@ -1,3 +1,4 @@
1
+ import { readRoomReadiness } from '../agent-ours/service.js';
1
2
  import { createHash, randomUUID } from 'node:crypto';
2
3
  import { existsSync, readFileSync, realpathSync } from 'node:fs';
3
4
  import { join } from 'node:path';
@@ -149,8 +150,7 @@ function launchMatches(dir, member, actionId, taskSha, roomId, roomIdentityCid,
149
150
  && (startup.anonymous ?? false) === anonymous
150
151
  && sha256Text(startup.task ?? '') === taskSha
151
152
  && (expectedInviteId === undefined || startup.invite_id === expectedInviteId)
152
- && typeof startup.invite === 'string'
153
- && startup.invite.length > 0;
153
+ && startup.invite === '';
154
154
  }
155
155
  catch {
156
156
  return false;
@@ -345,7 +345,14 @@ function reconcileMemberSeats(roomId, members, observed, ownerSeatCid) {
345
345
  && seat.seat_state === 'active');
346
346
  const seats = current.member_seats.map(seat => {
347
347
  const member = members.find(candidate => candidate.name === seat.role_name);
348
+ const readiness = readRoomReadiness(current.room_identity_cid, member.name);
349
+ if (!readiness || readiness.room !== roomId || readiness.invite !== seat.invite_id) {
350
+ complete = false;
351
+ return seat;
352
+ }
348
353
  const found = exactCoworkSeat(observed, member, seat.invite_id);
354
+ if (found && found.identity_cid !== readiness.cid)
355
+ throw new Error('Cowork seat CID does not match supervisor provisioned identity');
349
356
  if (!found || found.seat_state !== 'active') {
350
357
  complete = false;
351
358
  return seat;
package/dist/runner.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { prepareManagedAgent, releaseManagedAgent } from './agent-ours/service.js';
1
2
  import { type ResolvedRole } from './config.js';
2
3
  import { type MonitorHandle, type MonitorOpts, type FetchLike } from './monitor.js';
3
4
  import { type DaemonGenerationProbe } from './daemon-recovery.js';
@@ -9,6 +10,8 @@ import { type OwnerChannelHandle, type OwnerChannelOptions } from './owner-chann
9
10
  import { type OwnerBinderLease } from './owner-channel/binder.js';
10
11
  import { ScheduledLoopManager, type ScheduledLoopManagerHandle } from './loops/manager.js';
11
12
  export interface RunnerDeps {
13
+ prepareAgentOurs: typeof prepareManagedAgent;
14
+ releaseAgentOurs: typeof releaseManagedAgent;
12
15
  exec: Exec;
13
16
  cpuDelegated(): boolean;
14
17
  isAlive(pid: number): boolean;
@@ -168,6 +171,7 @@ export declare function runOnce(name: string, opts?: {
168
171
  temp?: boolean;
169
172
  configPath?: string;
170
173
  allowResumeRotation?: boolean;
174
+ identityLifetime?: 'permanent' | 'temporary';
171
175
  }, partialDeps?: Partial<RunnerDeps>): Promise<AttemptResult>;
172
176
  /**
173
177
  * The persistent supervisor for one permanent role: run child sessions in a