@ours.network/fleet 1.0.0 → 1.0.2
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/README.md +14 -7
- package/dist/briefing.d.ts +2 -1
- package/dist/briefing.js +47 -86
- package/dist/build-info.json +4 -4
- package/dist/config.d.ts +8 -6
- package/dist/docs.d.ts +1 -1
- package/dist/docs.js +18 -6
- package/dist/harness/claude-code.js +1 -1
- package/dist/harness/types.d.ts +3 -3
- package/dist/rooms-tasks/cli.js +8 -19
- package/dist/rooms-tasks/close.js +11 -0
- package/dist/rooms-tasks/cowork-adapter.d.ts +5 -0
- package/dist/rooms-tasks/cowork-adapter.js +7 -1
- package/dist/rooms-tasks/member-startup.d.ts +5 -38
- package/dist/rooms-tasks/member-startup.js +3 -119
- package/dist/rooms-tasks/provision.js +202 -362
- package/dist/rooms-tasks/room-state.d.ts +1 -2
- package/dist/rooms-tasks/room-state.js +0 -9
- package/dist/rooms-tasks/types.d.ts +4 -20
- package/dist/session/acp.d.ts +4 -11
- package/dist/session/acp.js +7 -12
- package/dist/spawn.d.ts +3 -3
- package/dist/spawn.js +6 -14
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RoomOrchestrationRecord, RoomOrchestrationState, SagaPhase, RoomMemberSeat, ProvisioningDetail, MemberRetirementPhase, RoomClosePhase, RoomRoleBriefingDefinition, RoomMemberLaunchState
|
|
1
|
+
import type { RoomOrchestrationRecord, RoomOrchestrationState, SagaPhase, RoomMemberSeat, ProvisioningDetail, MemberRetirementPhase, RoomClosePhase, RoomRoleBriefingDefinition, RoomMemberLaunchState } from './types.js';
|
|
2
2
|
export declare const roomsDir: () => string;
|
|
3
3
|
export declare class RoomStateError extends Error {
|
|
4
4
|
}
|
|
@@ -26,7 +26,6 @@ export declare function updateRoomRoleBriefing(id: string, role: string, definit
|
|
|
26
26
|
export declare function updateRoomHistoryCursor(id: string, cursor: number): RoomOrchestrationRecord;
|
|
27
27
|
export declare function updateMemberStartup(id: string, roleName: string, update: {
|
|
28
28
|
launch?: RoomMemberLaunchState;
|
|
29
|
-
briefing?: RoomMemberBriefingState;
|
|
30
29
|
}): RoomOrchestrationRecord;
|
|
31
30
|
export declare function activateRoom(id: string): RoomOrchestrationRecord;
|
|
32
31
|
export declare function closeRoom(id: string): RoomOrchestrationRecord;
|
|
@@ -122,9 +122,6 @@ export function updateRoomHistoryCursor(id, cursor) {
|
|
|
122
122
|
const LAUNCH_ORDER = [
|
|
123
123
|
'pending', 'intent', 'launched', 'stopped', 'failed',
|
|
124
124
|
];
|
|
125
|
-
const BRIEFING_ORDER = [
|
|
126
|
-
'pending', 'relay_queued', 'relay_failed', 'acknowledged',
|
|
127
|
-
];
|
|
128
125
|
export function updateMemberStartup(id, roleName, update) {
|
|
129
126
|
const r = readRoom(id);
|
|
130
127
|
const seat = r.member_seats.find(candidate => candidate.role_name === roleName);
|
|
@@ -136,14 +133,8 @@ export function updateMemberStartup(id, roleName, update) {
|
|
|
136
133
|
&& !(seat.launch.state === 'failed' && update.launch.state === 'intent')) {
|
|
137
134
|
throw new RoomStateError(`room ${id} member ${roleName} launch cannot move backward to ${update.launch.state}`);
|
|
138
135
|
}
|
|
139
|
-
if (update.briefing && seat.briefing
|
|
140
|
-
&& BRIEFING_ORDER.indexOf(update.briefing.state) < BRIEFING_ORDER.indexOf(seat.briefing.state)) {
|
|
141
|
-
throw new RoomStateError(`room ${id} member ${roleName} briefing cannot move backward to ${update.briefing.state}`);
|
|
142
|
-
}
|
|
143
136
|
if (update.launch)
|
|
144
137
|
seat.launch = update.launch;
|
|
145
|
-
if (update.briefing)
|
|
146
|
-
seat.briefing = update.briefing;
|
|
147
138
|
writeRoom(r);
|
|
148
139
|
return r;
|
|
149
140
|
}
|
|
@@ -65,14 +65,14 @@ export interface TaskRecord {
|
|
|
65
65
|
terminal_intent?: TaskTerminalIntent;
|
|
66
66
|
}
|
|
67
67
|
export type RoomOrchestrationState = 'provisioning' | 'active' | 'closing' | 'closed';
|
|
68
|
-
export type SagaPhase = 'persist_intent' | 'create_room' | 'attach_owner' | 'create_members' | '
|
|
68
|
+
export type SagaPhase = 'persist_intent' | 'create_room' | 'attach_owner' | 'create_members' | 'join_role_groups' | 'wait_seats' | 'launch_work' | 'activate' | 'completed' | 'failed';
|
|
69
69
|
export interface SagaCursor {
|
|
70
70
|
phase: SagaPhase;
|
|
71
71
|
step_index: number;
|
|
72
72
|
error?: string;
|
|
73
73
|
recovery_hint?: string;
|
|
74
74
|
}
|
|
75
|
-
export type ProvisioningDetail = 'waiting_cowork' | 'waiting_owner_invite' | 'owner_cid_mismatch' | 'member_failed' | 'waiting_seats' | '
|
|
75
|
+
export type ProvisioningDetail = 'waiting_cowork' | 'waiting_owner_invite' | 'owner_cid_mismatch' | 'member_failed' | 'waiting_seats' | 'uncertain';
|
|
76
76
|
export interface RoomRoleBriefingDefinition {
|
|
77
77
|
role: string;
|
|
78
78
|
text: string;
|
|
@@ -92,22 +92,6 @@ export interface RoomMemberLaunchState {
|
|
|
92
92
|
updated_at: string;
|
|
93
93
|
error?: string;
|
|
94
94
|
}
|
|
95
|
-
export interface RoomMemberBriefingState {
|
|
96
|
-
role: string;
|
|
97
|
-
state: 'pending' | 'relay_queued' | 'relay_failed' | 'acknowledged';
|
|
98
|
-
message_id?: string;
|
|
99
|
-
relay_intent_record_id?: string;
|
|
100
|
-
relay_result_record_id?: string;
|
|
101
|
-
relay_wire_id?: string;
|
|
102
|
-
checked_at?: string;
|
|
103
|
-
acknowledged_at?: string;
|
|
104
|
-
acknowledgement_message_id?: string;
|
|
105
|
-
acknowledgement_seq?: number;
|
|
106
|
-
rejected_ack_count: number;
|
|
107
|
-
last_rejected_ack_reason?: string;
|
|
108
|
-
last_rejected_ack_seq?: number;
|
|
109
|
-
last_processed_seq?: number;
|
|
110
|
-
}
|
|
111
95
|
export type RoomHistoryEvidence = {
|
|
112
96
|
kind: 'message';
|
|
113
97
|
seq: number;
|
|
@@ -161,12 +145,12 @@ export interface RoomCloseCursor {
|
|
|
161
145
|
}
|
|
162
146
|
export interface RoomMemberSeat {
|
|
163
147
|
role_name: string;
|
|
164
|
-
identity_cid
|
|
148
|
+
identity_cid?: string;
|
|
149
|
+
invite_id?: string;
|
|
165
150
|
slot: string;
|
|
166
151
|
cowork_role: string;
|
|
167
152
|
seat_state: 'pending' | 'active' | 'removed';
|
|
168
153
|
launch?: RoomMemberLaunchState;
|
|
169
|
-
briefing?: RoomMemberBriefingState;
|
|
170
154
|
retirement?: MemberRetirement;
|
|
171
155
|
}
|
|
172
156
|
export interface RoomOrchestrationRecord {
|
package/dist/session/acp.d.ts
CHANGED
|
@@ -39,9 +39,9 @@ export interface AcpSessionOptions {
|
|
|
39
39
|
/** Adapter-authenticated request-metadata vocabulary; never inferred from ACP `_meta`. */
|
|
40
40
|
permissionMetadataSource?: 'codex-acp';
|
|
41
41
|
/**
|
|
42
|
-
* MCP servers the ROLE declares, for every session/new, resume and load.
|
|
43
|
-
*
|
|
44
|
-
*
|
|
42
|
+
* MCP servers the ROLE declares, for every session/new, resume and load.
|
|
43
|
+
* Omitted preserves inherited configuration; an explicit empty array disables
|
|
44
|
+
* every inherited server.
|
|
45
45
|
*/
|
|
46
46
|
mcpServers?: AcpMcpServer[];
|
|
47
47
|
/**
|
|
@@ -258,14 +258,7 @@ export declare class AcpSession implements SessionHandle {
|
|
|
258
258
|
private settlePendingAutomatically;
|
|
259
259
|
exitResult(): ExitRecord | null;
|
|
260
260
|
close(): Promise<void>;
|
|
261
|
-
/**
|
|
262
|
-
* The role's declared MCP servers, or `[]`.
|
|
263
|
-
*
|
|
264
|
-
* Sent on resume and load as well as on new: the agent builds its server set
|
|
265
|
-
* once per session, so a resumed session that omitted them would come back
|
|
266
|
-
* without the tools the role's config declares — which is exactly the shape of
|
|
267
|
-
* silent drop this plumbing exists to end.
|
|
268
|
-
*/
|
|
261
|
+
/** Preserve inheritance on omission; carry even an explicit empty override. */
|
|
269
262
|
private declaredMcpServers;
|
|
270
263
|
private initialize;
|
|
271
264
|
private captureRuntimeMetadata;
|
package/dist/session/acp.js
CHANGED
|
@@ -991,16 +991,11 @@ export class AcpSession {
|
|
|
991
991
|
});
|
|
992
992
|
this.conversation.close();
|
|
993
993
|
}
|
|
994
|
-
/**
|
|
995
|
-
* The role's declared MCP servers, or `[]`.
|
|
996
|
-
*
|
|
997
|
-
* Sent on resume and load as well as on new: the agent builds its server set
|
|
998
|
-
* once per session, so a resumed session that omitted them would come back
|
|
999
|
-
* without the tools the role's config declares — which is exactly the shape of
|
|
1000
|
-
* silent drop this plumbing exists to end.
|
|
1001
|
-
*/
|
|
994
|
+
/** Preserve inheritance on omission; carry even an explicit empty override. */
|
|
1002
995
|
declaredMcpServers() {
|
|
1003
|
-
return this.options.mcpServers
|
|
996
|
+
return this.options.mcpServers === undefined
|
|
997
|
+
? {}
|
|
998
|
+
: { mcpServers: this.options.mcpServers };
|
|
1004
999
|
}
|
|
1005
1000
|
async initialize() {
|
|
1006
1001
|
const initialized = await this.connection.agent.request(acp.methods.agent.initialize, {
|
|
@@ -1021,7 +1016,7 @@ export class AcpSession {
|
|
|
1021
1016
|
const resumed = await this.connection.agent.request(acp.methods.agent.session.resume, {
|
|
1022
1017
|
sessionId: persisted,
|
|
1023
1018
|
cwd: this.options.cwd,
|
|
1024
|
-
|
|
1019
|
+
...this.declaredMcpServers(),
|
|
1025
1020
|
});
|
|
1026
1021
|
this.captureRuntimeMetadata(resumed.configOptions);
|
|
1027
1022
|
this.sessionId = persisted;
|
|
@@ -1034,7 +1029,7 @@ export class AcpSession {
|
|
|
1034
1029
|
const loaded = await this.connection.agent.request(acp.methods.agent.session.load, {
|
|
1035
1030
|
sessionId: persisted,
|
|
1036
1031
|
cwd: this.options.cwd,
|
|
1037
|
-
|
|
1032
|
+
...this.declaredMcpServers(),
|
|
1038
1033
|
});
|
|
1039
1034
|
this.captureRuntimeMetadata(loaded.configOptions);
|
|
1040
1035
|
}
|
|
@@ -1046,7 +1041,7 @@ export class AcpSession {
|
|
|
1046
1041
|
else {
|
|
1047
1042
|
const created = await this.connection.agent.request(acp.methods.agent.session.new, {
|
|
1048
1043
|
cwd: this.options.cwd,
|
|
1049
|
-
|
|
1044
|
+
...this.declaredMcpServers(),
|
|
1050
1045
|
...(this.options.sessionMeta ? { _meta: this.options.sessionMeta } : {}),
|
|
1051
1046
|
});
|
|
1052
1047
|
this.sessionId = created.sessionId;
|
package/dist/spawn.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IsolationConfig } from './isolation/types.js';
|
|
2
|
-
import { type ApprovalMode, type FilesystemMode, type ResolvedRole, type RoleConfig, type MonitorConfig, type SessionBackendId, type UnattendedMode, type
|
|
2
|
+
import { type ApprovalMode, type FilesystemMode, type ResolvedRole, type RoleConfig, type MonitorConfig, type SessionBackendId, type UnattendedMode, type RoomMemberStartup } from './config.js';
|
|
3
3
|
import { type OpsDeps } from './ops.js';
|
|
4
4
|
import { type CreationDeps, type CreationProvenance } from './creation.js';
|
|
5
5
|
import './harness/claude-code.js';
|
|
@@ -46,8 +46,8 @@ export interface SpawnOpts {
|
|
|
46
46
|
creationActionId?: string;
|
|
47
47
|
/** Set only by a live role supervisor after a role-scoped proxy request. */
|
|
48
48
|
callerRole?: string;
|
|
49
|
-
/** Trusted Fleet-internal
|
|
50
|
-
|
|
49
|
+
/** Trusted Fleet-internal first-boot payload for a Cowork room member. */
|
|
50
|
+
roomMemberStartup?: RoomMemberStartup;
|
|
51
51
|
/** Internal provenance labels for values filled by the caller's supervisor. */
|
|
52
52
|
inheritedFromCaller?: string[];
|
|
53
53
|
/**
|
package/dist/spawn.js
CHANGED
|
@@ -8,7 +8,7 @@ import { loadConfig, resolveAuthProxy, resolveModelChain, resolveMonitorConfig,
|
|
|
8
8
|
import { resolveRoleModelEnv } from './model-env.js';
|
|
9
9
|
import { applyRole, up } from './ops.js';
|
|
10
10
|
import { START_STAGGER_FILE } from './runner.js';
|
|
11
|
-
import { buildProvenance,
|
|
11
|
+
import { buildProvenance, daemonIdentityProvisioner, ensureIdentity, provenanceOf, withCreationTransaction, writeProvenance, writeRoleFile, } from './creation.js';
|
|
12
12
|
import { VERSION } from './version.js';
|
|
13
13
|
import './harness/claude-code.js';
|
|
14
14
|
import './harness/codex.js';
|
|
@@ -389,21 +389,13 @@ export async function spawnTemp(o, binPath, launch = independentSupervisor, crea
|
|
|
389
389
|
return withCreationTransaction({ role: o.name, identity: effectiveIdentity(o) }, async (tx) => {
|
|
390
390
|
creation.onStage?.('checking_identity');
|
|
391
391
|
assertNameFree(o);
|
|
392
|
-
const guarantee = await ensureIdentity(effectiveIdentity(o), profileValues(o), creation.identityProvisioner ?? daemonIdentityInventoryProvisioner(), creation.log);
|
|
393
392
|
creation.onStage?.('checking_identity', {
|
|
394
|
-
result:
|
|
393
|
+
result: 'unknown', guarantee: 'unverified',
|
|
395
394
|
});
|
|
396
|
-
|
|
397
|
-
tx.record({
|
|
398
|
-
stage: `ours identity ${effectiveIdentity(o)}`,
|
|
399
|
-
undo: async () => {
|
|
400
|
-
await creation.identityProvisioner?.remove?.(effectiveIdentity(o));
|
|
401
|
-
},
|
|
402
|
-
});
|
|
403
|
-
return spawnTempInner(o, binPath, launch, tx, guarantee, creation.onStage);
|
|
395
|
+
return spawnTempInner(o, binPath, launch, tx, creation.onStage);
|
|
404
396
|
}, creation);
|
|
405
397
|
}
|
|
406
|
-
async function spawnTempInner(o, binPath, launch, tx,
|
|
398
|
+
async function spawnTempInner(o, binPath, launch, tx, onStage) {
|
|
407
399
|
const cfg = loadConfig(o.configPath);
|
|
408
400
|
const defaultHarness = cfg.defaults.harness;
|
|
409
401
|
const fromOpts = buildRoleConfig(o, defaultHarness);
|
|
@@ -445,13 +437,13 @@ async function spawnTempInner(o, binPath, launch, tx, guarantee, onStage) {
|
|
|
445
437
|
worklog: resolveWorklogPolicy(cfg.defaults.worklog, fromOpts.worklog),
|
|
446
438
|
auth_proxy: tempAuthProxy,
|
|
447
439
|
sourceFile: '(temp)',
|
|
448
|
-
|
|
440
|
+
roomMemberStartup: o.roomMemberStartup,
|
|
449
441
|
};
|
|
450
442
|
role.env = modelEnv.env;
|
|
451
443
|
if (role.auth_proxy && role.harness !== 'claude-code')
|
|
452
444
|
throw new Error('auth_proxy is supported only by claude-code');
|
|
453
445
|
onStage?.('writing_role');
|
|
454
|
-
const dir = applyRole(role, { temp: true, identityGuarantee:
|
|
446
|
+
const dir = applyRole(role, { temp: true, identityGuarantee: 'unverified' });
|
|
455
447
|
const provenance = buildProvenance({
|
|
456
448
|
role: o.name, lifetime: 'temporary', fleetVersion: VERSION,
|
|
457
449
|
settings: provenanceSettings(o, cfg.defaults),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ours.network/fleet",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Harness-agnostic fleet of persistent, identity-bound AI agents. Declarative fleet.yaml, tmux or ACP sessions, supervision, and ours.network messaging.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "FSL-1.1-Apache-2.0",
|