@ours.network/fleet 1.1.0-nightly.1 → 1.1.0-nightly.11

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 (186) hide show
  1. package/README.md +133 -95
  2. package/dist/agent-recovery-gate.d.ts +17 -0
  3. package/dist/agent-recovery-gate.js +135 -0
  4. package/dist/application/fleet-query-service.js +15 -2
  5. package/dist/application/role-command-service.js +9 -0
  6. package/dist/application/role-creation-service.d.ts +2 -21
  7. package/dist/application/role-creation-service.js +26 -64
  8. package/dist/application/role-removal-service.js +6 -3
  9. package/dist/application/task-room-service.d.ts +7 -1
  10. package/dist/application/task-room-service.js +269 -69
  11. package/dist/application/types.d.ts +1 -1
  12. package/dist/briefing.js +11 -7
  13. package/dist/build-info.json +4 -4
  14. package/dist/canonical-json.d.ts +2 -0
  15. package/dist/canonical-json.js +10 -0
  16. package/dist/cli.js +178 -65
  17. package/dist/config-yaml.d.ts +1 -1
  18. package/dist/config.d.ts +87 -2
  19. package/dist/config.js +526 -28
  20. package/dist/creation.d.ts +1 -1
  21. package/dist/creation.js +2 -2
  22. package/dist/daemon-recovery.d.ts +93 -0
  23. package/dist/daemon-recovery.js +328 -0
  24. package/dist/docs.d.ts +1 -1
  25. package/dist/docs.js +94 -102
  26. package/dist/doctor.d.ts +2 -0
  27. package/dist/doctor.js +38 -5
  28. package/dist/fleet-command-audit.d.ts +160 -0
  29. package/dist/fleet-command-audit.js +437 -0
  30. package/dist/fleet-proxy.d.ts +2 -0
  31. package/dist/fleet-proxy.js +30 -8
  32. package/dist/generated-agent-source.d.ts +9 -0
  33. package/dist/generated-agent-source.js +53 -0
  34. package/dist/harness/agent-session.d.ts +18 -0
  35. package/dist/harness/claude-code-session.d.ts +6 -0
  36. package/dist/harness/claude-code-session.js +8 -0
  37. package/dist/harness/claude-code.js +12 -0
  38. package/dist/harness/codex-session.d.ts +6 -0
  39. package/dist/harness/codex-session.js +8 -0
  40. package/dist/harness/codex.js +20 -0
  41. package/dist/harness/registry.js +4 -0
  42. package/dist/index.d.ts +1 -1
  43. package/dist/index.js +1 -1
  44. package/dist/init-guidance.d.ts +1 -0
  45. package/dist/init-guidance.js +6 -0
  46. package/dist/model-env.d.ts +2 -3
  47. package/dist/model-env.js +3 -5
  48. package/dist/ops.js +6 -19
  49. package/dist/owner-channel/channel.d.ts +56 -0
  50. package/dist/owner-channel/channel.js +269 -29
  51. package/dist/owner-channel/commands.d.ts +2 -0
  52. package/dist/owner-channel/commands.js +31 -13
  53. package/dist/owner-channel/state.d.ts +2 -0
  54. package/dist/owner-channel/state.js +8 -2
  55. package/dist/preset-bootstrap.d.ts +10 -0
  56. package/dist/preset-bootstrap.js +85 -0
  57. package/dist/preset-migration.d.ts +27 -0
  58. package/dist/preset-migration.js +200 -0
  59. package/dist/reports/artifact.d.ts +10 -0
  60. package/dist/reports/artifact.js +32 -0
  61. package/dist/reports/index.d.ts +5 -0
  62. package/dist/reports/index.js +5 -0
  63. package/dist/reports/render.d.ts +6 -0
  64. package/dist/reports/render.js +240 -0
  65. package/dist/reports/service.d.ts +42 -0
  66. package/dist/reports/service.js +57 -0
  67. package/dist/reports/tasks.d.ts +52 -0
  68. package/dist/reports/tasks.js +177 -0
  69. package/dist/reports/types.d.ts +315 -0
  70. package/dist/reports/types.js +6 -0
  71. package/dist/resolved-plan.d.ts +3 -2
  72. package/dist/resolved-plan.js +25 -5
  73. package/dist/rooms-tasks/cli.d.ts +2 -0
  74. package/dist/rooms-tasks/cli.js +342 -65
  75. package/dist/rooms-tasks/config.js +12 -14
  76. package/dist/rooms-tasks/external-worker.d.ts +1 -0
  77. package/dist/rooms-tasks/external-worker.js +14 -9
  78. package/dist/rooms-tasks/launch-snapshot.d.ts +10 -0
  79. package/dist/rooms-tasks/launch-snapshot.js +159 -0
  80. package/dist/rooms-tasks/member-overrides.d.ts +27 -0
  81. package/dist/rooms-tasks/member-overrides.js +170 -0
  82. package/dist/rooms-tasks/provision.js +82 -37
  83. package/dist/rooms-tasks/room-state.js +4 -0
  84. package/dist/rooms-tasks/task-state.d.ts +2 -0
  85. package/dist/rooms-tasks/task-state.js +19 -1
  86. package/dist/rooms-tasks/templates.d.ts +4 -2
  87. package/dist/rooms-tasks/templates.js +42 -78
  88. package/dist/rooms-tasks/types.d.ts +36 -17
  89. package/dist/rooms-tasks/types.js +2 -4
  90. package/dist/runner.d.ts +9 -2
  91. package/dist/runner.js +84 -20
  92. package/dist/sensitive-config.d.ts +2 -0
  93. package/dist/sensitive-config.js +4 -0
  94. package/dist/session/acp.d.ts +5 -0
  95. package/dist/session/acp.js +27 -3
  96. package/dist/session/control.d.ts +14 -1
  97. package/dist/session/control.js +35 -0
  98. package/dist/spawn.d.ts +8 -33
  99. package/dist/spawn.js +64 -212
  100. package/dist/temp-lifecycle.d.ts +1 -1
  101. package/dist/watchdog/config.d.ts +10 -7
  102. package/dist/watchdog/config.js +29 -19
  103. package/dist/watchdog/run.js +4 -13
  104. package/dist/web/fleet-config-service.d.ts +12 -8
  105. package/dist/web/fleet-config-service.js +404 -185
  106. package/dist/web/topology-promote.js +25 -15
  107. package/dist/web/topology.js +2 -2
  108. package/dist/web/yaml-document-edit.js +2 -0
  109. package/dist/web-app/assets/index-C0h3ALvs.js +10 -0
  110. package/dist/web-app/index.html +1 -1
  111. package/examples/fleet/agents/Alice.yaml +11 -0
  112. package/examples/fleet/agents/FleetCoordinator.yaml +7 -0
  113. package/examples/fleet/brains/claude-default.yaml +5 -0
  114. package/examples/fleet/roles/coordinator.yaml +5 -0
  115. package/examples/fleet/roles/developer.yaml +3 -0
  116. package/examples/fleet.yaml +74 -0
  117. package/package.json +3 -1
  118. package/presets/brain-catalog.json +16 -0
  119. package/presets/fleet/agent_templates/Agent.yaml +3 -0
  120. package/presets/fleet/agent_templates/Architect.yaml +3 -0
  121. package/presets/fleet/agent_templates/Critic.yaml +3 -0
  122. package/presets/fleet/agent_templates/Developer.yaml +3 -0
  123. package/presets/fleet/agent_templates/Secretary.yaml +3 -0
  124. package/presets/fleet/agent_templates/Tester.yaml +3 -0
  125. package/presets/fleet/agents/FleetCoordinator.yaml +4 -0
  126. package/presets/fleet/brains/claude-default.yaml +5 -0
  127. package/presets/fleet/brains/claude-fable-5-high.yaml +5 -0
  128. package/presets/fleet/brains/claude-fable-5-low.yaml +5 -0
  129. package/presets/fleet/brains/claude-fable-5-max.yaml +5 -0
  130. package/presets/fleet/brains/claude-fable-5-medium.yaml +5 -0
  131. package/presets/fleet/brains/claude-fable-5-xhigh.yaml +5 -0
  132. package/presets/fleet/brains/claude-opus-5-high.yaml +5 -0
  133. package/presets/fleet/brains/claude-opus-5-low.yaml +5 -0
  134. package/presets/fleet/brains/claude-opus-5-max.yaml +5 -0
  135. package/presets/fleet/brains/claude-opus-5-medium.yaml +5 -0
  136. package/presets/fleet/brains/claude-opus-5-xhigh.yaml +5 -0
  137. package/presets/fleet/brains/claude-sonnet-5-high.yaml +5 -0
  138. package/presets/fleet/brains/claude-sonnet-5-low.yaml +5 -0
  139. package/presets/fleet/brains/claude-sonnet-5-max.yaml +5 -0
  140. package/presets/fleet/brains/claude-sonnet-5-medium.yaml +5 -0
  141. package/presets/fleet/brains/claude-sonnet-5-xhigh.yaml +5 -0
  142. package/presets/fleet/brains/codex-gpt-5-3-codex-spark-high.yaml +5 -0
  143. package/presets/fleet/brains/codex-gpt-5-3-codex-spark-low.yaml +5 -0
  144. package/presets/fleet/brains/codex-gpt-5-3-codex-spark-medium.yaml +5 -0
  145. package/presets/fleet/brains/codex-gpt-5-3-codex-spark-xhigh.yaml +5 -0
  146. package/presets/fleet/brains/codex-gpt-5-4-high.yaml +5 -0
  147. package/presets/fleet/brains/codex-gpt-5-4-low.yaml +5 -0
  148. package/presets/fleet/brains/codex-gpt-5-4-medium.yaml +5 -0
  149. package/presets/fleet/brains/codex-gpt-5-4-mini-high.yaml +5 -0
  150. package/presets/fleet/brains/codex-gpt-5-4-mini-low.yaml +5 -0
  151. package/presets/fleet/brains/codex-gpt-5-4-mini-medium.yaml +5 -0
  152. package/presets/fleet/brains/codex-gpt-5-4-mini-xhigh.yaml +5 -0
  153. package/presets/fleet/brains/codex-gpt-5-4-xhigh.yaml +5 -0
  154. package/presets/fleet/brains/codex-gpt-5-5-high.yaml +5 -0
  155. package/presets/fleet/brains/codex-gpt-5-5-low.yaml +5 -0
  156. package/presets/fleet/brains/codex-gpt-5-5-medium.yaml +5 -0
  157. package/presets/fleet/brains/codex-gpt-5-5-xhigh.yaml +5 -0
  158. package/presets/fleet/brains/codex-gpt-5-6-luna-high.yaml +5 -0
  159. package/presets/fleet/brains/codex-gpt-5-6-luna-low.yaml +5 -0
  160. package/presets/fleet/brains/codex-gpt-5-6-luna-max.yaml +5 -0
  161. package/presets/fleet/brains/codex-gpt-5-6-luna-medium.yaml +5 -0
  162. package/presets/fleet/brains/codex-gpt-5-6-luna-xhigh.yaml +5 -0
  163. package/presets/fleet/brains/codex-gpt-5-6-sol-high.yaml +5 -0
  164. package/presets/fleet/brains/codex-gpt-5-6-sol-low.yaml +5 -0
  165. package/presets/fleet/brains/codex-gpt-5-6-sol-max.yaml +5 -0
  166. package/presets/fleet/brains/codex-gpt-5-6-sol-medium.yaml +5 -0
  167. package/presets/fleet/brains/codex-gpt-5-6-sol-ultra.yaml +5 -0
  168. package/presets/fleet/brains/codex-gpt-5-6-sol-xhigh.yaml +5 -0
  169. package/presets/fleet/brains/codex-gpt-5-6-terra-high.yaml +5 -0
  170. package/presets/fleet/brains/codex-gpt-5-6-terra-low.yaml +5 -0
  171. package/presets/fleet/brains/codex-gpt-5-6-terra-max.yaml +5 -0
  172. package/presets/fleet/brains/codex-gpt-5-6-terra-medium.yaml +5 -0
  173. package/presets/fleet/brains/codex-gpt-5-6-terra-ultra.yaml +5 -0
  174. package/presets/fleet/brains/codex-gpt-5-6-terra-xhigh.yaml +5 -0
  175. package/presets/fleet/roles/Agent.yaml +6 -0
  176. package/presets/fleet/roles/Architect.yaml +6 -0
  177. package/presets/fleet/roles/Critic.yaml +6 -0
  178. package/presets/fleet/roles/Developer.yaml +6 -0
  179. package/presets/fleet/roles/Secretary.yaml +6 -0
  180. package/presets/fleet/roles/Tester.yaml +6 -0
  181. package/presets/fleet/room_templates/pair.yaml +11 -0
  182. package/presets/fleet/room_templates/single.yaml +8 -0
  183. package/presets/fleet/room_templates/team.yaml +12 -0
  184. package/presets/fleet.yaml +7 -0
  185. package/presets/manifest.json +6 -0
  186. package/dist/web-app/assets/index-DhMDVRU1.js +0 -10
@@ -1,16 +1,15 @@
1
1
  import { createHash, randomUUID } from 'node:crypto';
2
2
  import { mkdirSync, readFileSync, readdirSync, realpathSync, statSync } from 'node:fs';
3
3
  import { isAbsolute, relative } from 'node:path';
4
- import { loadConfig, NOTIFY_EVENT_TYPES, resolveMonitorConfig, resolveRoleModel, resolvePermissions, ROLE_NAME_RE, validateMonitorConfig, } from '../config.js';
4
+ import { loadConfig, NOTIFY_EVENT_TYPES, resolveMonitorConfig, resolvePermissions, ROLE_NAME_RE, validateMonitorConfig, } from '../config.js';
5
5
  import { daemonIdentityProvisioner, } from '../creation.js';
6
6
  import { replaceFileAtomically } from '../atomic-file.js';
7
7
  import { stateRoot } from '../paths.js';
8
- import { buildRoleConfig, spawnDryRun, spawnPermanent, spawnTemp, validateSpawnOpts, } from '../spawn.js';
8
+ import { spawnDryRun, spawnPermanent, spawnTemp, validateSpawnOpts, } from '../spawn.js';
9
9
  import { FleetError, normalizeError } from './errors.js';
10
10
  import { inheritCallerSpawnDefaults } from '../fleet-proxy.js';
11
11
  import { effectivePermissionMode } from '../permissions.js';
12
12
  import { effectiveRoleModel } from '../model-env.js';
13
- import { claudeModelCatalog, codexModelCatalog, } from './model-catalog.js';
14
13
  const canonical = (value) => {
15
14
  if (Array.isArray(value))
16
15
  return `[${value.map(canonical).join(',')}]`;
@@ -62,6 +61,16 @@ export class RoleCreationService {
62
61
  const creationActionId = randomUUID();
63
62
  plan.options.creationActionId = creationActionId;
64
63
  const statePath = await this.launchSync(plan.options);
64
+ const selectionSummary = (kind) => {
65
+ const value = plan.options[kind];
66
+ const provenance = plan.inherited.includes(kind) ? 'inherited' : 'explicit';
67
+ if (!value)
68
+ return `unresolved (${provenance})`;
69
+ if ('ref' in value)
70
+ return `ref:${value.ref} (${provenance})`;
71
+ const fingerprint = hash(value.inline).slice(0, 16);
72
+ return `inline:sha256:${fingerprint} (${provenance})`;
73
+ };
65
74
  return {
66
75
  caller: plan.caller, role: plan.options.name,
67
76
  lifetime: plan.options.temp ? 'temporary' : 'permanent', statePath,
@@ -70,6 +79,7 @@ export class RoleCreationService {
70
79
  monitor: { mode: plan.preview.resolvedRole.monitor.mode, interrupt: plan.preview.resolvedRole.monitor.interrupt },
71
80
  permissionMode: effectivePermissionMode(plan.preview.resolvedRole), inherited: plan.inherited,
72
81
  creationActionId,
82
+ brainSummary: selectionSummary('brain'), roleSummary: selectionSummary('role'),
73
83
  };
74
84
  }
75
85
  launchSync(options, creation) {
@@ -80,47 +90,16 @@ export class RoleCreationService {
80
90
  async capabilities() {
81
91
  const reasons = [];
82
92
  let defaults = {};
83
- let roles = [];
84
93
  try {
85
94
  const config = loadConfig(this.options.configPath);
86
95
  defaults = config.defaults;
87
- roles = config.roles;
88
96
  }
89
97
  catch (error) {
90
98
  reasons.push(`configuration is invalid: ${error.message}`);
91
99
  }
92
- const modelsFor = (harness, catalog) => {
93
- const configured = roles.filter(role => role.harness === harness)
94
- .flatMap(role => [role.model, ...(role.model_chain ?? [])])
95
- .filter((model) => Boolean(model));
96
- const inherited = resolveRoleModel(undefined, harness, defaults);
97
- const configuredOptions = [...new Set([...(inherited ? [inherited] : []), ...configured])]
98
- .filter(id => !catalog.models.some(model => model.id === id))
99
- .map(id => ({ id, label: `${id} (configured)`, reasoningEfforts: [], source: 'fleet-config' }));
100
- const modelOptions = [...configuredOptions, ...catalog.models];
101
- return { modelOptions, models: modelOptions.map(model => model.id) };
102
- };
103
- const codexCatalog = this.options.modelCatalogs?.codex?.() ?? codexModelCatalog();
104
- const claudeCatalog = this.options.modelCatalogs?.['claude-code']?.() ?? claudeModelCatalog();
105
- const codexModels = modelsFor('codex', codexCatalog);
106
- const claudeModels = modelsFor('claude-code', claudeCatalog);
107
100
  return {
108
101
  available: reasons.length === 0,
109
102
  reasons,
110
- harnesses: [
111
- {
112
- id: 'codex', available: true, sessions: ['acp'],
113
- defaultModel: resolveRoleModel(undefined, 'codex', defaults),
114
- ...codexModels, catalogSource: 'codex-runtime-catalog', customModelAllowed: true,
115
- warnings: codexCatalog.warnings,
116
- },
117
- {
118
- id: 'claude-code', available: true, sessions: ['acp'],
119
- defaultModel: resolveRoleModel(undefined, 'claude-code', defaults),
120
- ...claudeModels, catalogSource: 'claude-adapter-2.1', customModelAllowed: true,
121
- warnings: claudeCatalog.warnings,
122
- },
123
- ],
124
103
  lifetimes: ['permanent', 'temporary'],
125
104
  identityBootstrap: {
126
105
  mode: 'current-fleet-first-boot',
@@ -144,14 +123,12 @@ export class RoleCreationService {
144
123
  const defaults = cfg.defaults;
145
124
  const opts = this.spawnOptions(request);
146
125
  validateSpawnOpts(opts);
147
- buildRoleConfig(opts, defaults.harness);
126
+ const resolved = spawnDryRun(opts).resolvedRole;
148
127
  const cwd = request.cwd ? this.resolveCwd(request.cwd) : undefined;
149
128
  const effective = {
150
129
  name: request.name, identity: request.name,
151
- harness: request.harness ?? defaults.harness ?? 'claude-code',
152
- session: request.session ?? defaults.session ?? 'acp',
153
- model: resolveRoleModel(request.model, request.harness, defaults),
154
- reasoningEffort: request.reasoningEffort ?? undefined,
130
+ harness: resolved.harness, session: resolved.session, model: resolved.model,
131
+ reasoningEffort: resolved.effort,
155
132
  cwd, lifetime: request.lifetime,
156
133
  permissions: resolvePermissions(defaults.permissions, request.permissions),
157
134
  monitor: resolveMonitorConfig(defaults.monitor, request.monitor),
@@ -183,9 +160,7 @@ export class RoleCreationService {
183
160
  if (existingIdentity === 'unknown' && !request.unverifiedIdentityAcknowledged)
184
161
  prerequisites.push('confirm creation with an unverified identity preflight');
185
162
  const provenance = {
186
- harness: 'request', session: 'request', identity: 'built-in',
187
- model: request.model !== undefined ? 'request'
188
- : resolveRoleModel(undefined, request.harness, defaults) ? 'fleet-default' : 'built-in',
163
+ brain: 'request', role: 'request', identity: 'built-in',
189
164
  cwd: request.cwd ? 'request' : 'built-in', permissions: 'request',
190
165
  monitor: request.monitor ? 'request' : defaults.monitor ? 'fleet-default' : 'built-in',
191
166
  };
@@ -296,8 +271,8 @@ export class RoleCreationService {
296
271
  }
297
272
  validate(input) {
298
273
  const allowed = new Set([
299
- 'name', 'harness', 'model', 'reasoningEffort', 'session', 'cwd', 'lifetime', 'mission',
300
- 'coordinator', 'permissions', 'bio', 'persona', 'monitor', 'openAfterCreate',
274
+ 'name', 'brain', 'role', 'cwd', 'lifetime',
275
+ 'coordinator', 'permissions', 'monitor', 'openAfterCreate',
301
276
  'highRiskAcknowledged', 'reuseExistingIdentityAcknowledged',
302
277
  'unverifiedIdentityAcknowledged',
303
278
  ]);
@@ -307,20 +282,11 @@ export class RoleCreationService {
307
282
  throw new FleetError('invalid_request', `unsupported web creation field: ${unsupported[0]}`);
308
283
  if (!ROLE_NAME_RE.test(input.name))
309
284
  throw new FleetError('invalid_request', 'invalid role name');
310
- if (!['codex', 'claude-code'].includes(input.harness))
311
- throw new FleetError('invalid_request', 'unsupported harness');
312
- if (input.session !== 'acp')
313
- throw new FleetError('invalid_request', 'unsupported session backend');
285
+ if (!input.brain || !input.role)
286
+ throw new FleetError('invalid_request', 'brain and role selections are required');
314
287
  if (!['permanent', 'temporary'].includes(input.lifetime))
315
288
  throw new FleetError('invalid_request', 'unsupported lifetime');
316
- bounded(input.model ?? undefined, 'model', 128);
317
- bounded(input.reasoningEffort ?? undefined, 'reasoning effort', 16);
318
- if (input.reasoningEffort != null && !['low', 'medium', 'high', 'xhigh', 'max', 'ultra'].includes(input.reasoningEffort))
319
- throw new FleetError('invalid_request', 'unsupported reasoning effort');
320
- bounded(input.mission, 'mission', 4_096);
321
289
  bounded(input.coordinator, 'coordinator', 128);
322
- bounded(input.bio, 'bio', 8_192);
323
- bounded(input.persona, 'persona', 16_384);
324
290
  resolvePermissions(undefined, input.permissions);
325
291
  if (input.monitor) {
326
292
  const problems = validateMonitorConfig(input.monitor);
@@ -330,10 +296,8 @@ export class RoleCreationService {
330
296
  throw new FleetError('invalid_request', 'web creation supports monitor.inject=notification only');
331
297
  }
332
298
  return {
333
- ...input, model: input.model === null ? null : input.model?.trim() || undefined,
334
- reasoningEffort: input.reasoningEffort === null ? null : input.reasoningEffort?.trim() || undefined,
335
- mission: input.mission?.trim() || undefined, coordinator: input.coordinator?.trim() || undefined,
336
- bio: input.bio?.trim() || undefined, persona: input.persona?.trim() || undefined,
299
+ ...input, brain: structuredClone(input.brain), role: structuredClone(input.role),
300
+ coordinator: input.coordinator?.trim() || undefined,
337
301
  monitor: input.monitor ? structuredClone(input.monitor) : undefined,
338
302
  };
339
303
  }
@@ -360,12 +324,10 @@ export class RoleCreationService {
360
324
  spawnOptions(request, creationActionId) {
361
325
  return {
362
326
  name: request.name, temp: request.lifetime === 'temporary',
363
- identity: request.name, harness: request.harness,
364
- model: request.model, session: request.session, cwd: request.cwd,
365
- reasoningEffort: request.reasoningEffort,
366
- mission: request.mission, coordinator: request.coordinator,
327
+ identity: request.name, brain: request.brain, role: request.role, cwd: request.cwd,
328
+ coordinator: request.coordinator,
367
329
  approval: request.permissions.approval, filesystem: request.permissions.filesystem,
368
- unattended: request.permissions.unattended, bio: request.bio, persona: request.persona,
330
+ unattended: request.permissions.unattended,
369
331
  monitorConfig: request.monitor,
370
332
  configPath: this.options.configPath,
371
333
  surface: creationActionId ? 'web' : undefined, creationActionId,
@@ -4,6 +4,7 @@ import { loadConfig, ROLE_NAME_RE } from '../config.js';
4
4
  import { agentDir, stateRoot } from '../paths.js';
5
5
  import { rmRole } from '../ops.js';
6
6
  import { FleetError } from './errors.js';
7
+ import { provesGeneratedAgentSource } from '../generated-agent-source.js';
7
8
  export class RoleRemovalService {
8
9
  options;
9
10
  constructor(options) {
@@ -45,8 +46,9 @@ export class RoleRemovalService {
45
46
  `Stop and uninstall the exact backend registration for '${requested}'.`,
46
47
  `Archive then remove ${lifetime === 'temporary' ? temporaryState : permanentState}.`,
47
48
  ];
48
- if (role?.sourceFile.includes('/fleet.d/'))
49
- effects.push(`Remove spawned configuration ${role.sourceFile}.`);
49
+ const generatedSource = role && provesGeneratedAgentSource(agentDir(requested), cfg.files[0], role.sourceFile);
50
+ if (generatedSource)
51
+ effects.push(`Remove generated Agent configuration ${role.sourceFile}.`);
50
52
  else if (role)
51
53
  effects.push(`Keep hand-written configuration ${role.sourceFile}; the role can be recreated from it.`);
52
54
  else
@@ -76,7 +78,8 @@ export class RoleRemovalService {
76
78
  mkdirSync(recoveryPath, { recursive: true, mode: 0o700 });
77
79
  if (existsSync(sourceState))
78
80
  cpSync(sourceState, join(recoveryPath, 'state'), { recursive: true });
79
- if (role?.sourceFile.includes('/fleet.d/') && existsSync(role.sourceFile))
81
+ if (role && provesGeneratedAgentSource(agentDir(preview.role), cfg.files[0], role.sourceFile)
82
+ && existsSync(role.sourceFile))
80
83
  cpSync(role.sourceFile, join(recoveryPath, basename(role.sourceFile)));
81
84
  if (role || preview.lifetime === 'temporary')
82
85
  await rmRole(cfg, preview.role, this.options.ops);
@@ -2,6 +2,7 @@ import { type FleetConfig } from '../config.js';
2
2
  import { type CoworkAdapter } from '../rooms-tasks/cowork-adapter.js';
3
3
  import { provisionMembers } from '../rooms-tasks/provision.js';
4
4
  import { moveTaskToList } from '../rooms-tasks/task-state.js';
5
+ import { type MemberOverrides } from '../rooms-tasks/member-overrides.js';
5
6
  import type { RoomOrchestrationRecord, TaskListRecord, TaskOrigin, TaskOutcome, TaskRecord, TaskState } from '../rooms-tasks/types.js';
6
7
  export type TaskRoomActor = {
7
8
  kind: 'local_control';
@@ -57,6 +58,7 @@ export interface CreateTaskRequest {
57
58
  idempotencyKey?: string;
58
59
  origin: TaskOrigin;
59
60
  list?: string;
61
+ members?: MemberOverrides;
60
62
  }
61
63
  export interface CreateRoomRequest {
62
64
  actor: TaskRoomActor;
@@ -65,6 +67,7 @@ export interface CreateRoomRequest {
65
67
  goal?: string;
66
68
  brief?: string;
67
69
  briefFile?: string;
70
+ members?: MemberOverrides;
68
71
  }
69
72
  export interface TaskRoomServiceDeps {
70
73
  loadConfiguration?(path?: string): FleetConfig;
@@ -84,6 +87,8 @@ export declare class TaskRoomApplicationService {
84
87
  startTask(input: {
85
88
  actor: TaskRoomActor;
86
89
  taskId: string;
90
+ template?: string;
91
+ members?: MemberOverrides;
87
92
  }): Promise<TaskRecord>;
88
93
  listTasks(filter?: {
89
94
  state?: TaskState | TaskState[];
@@ -179,7 +184,7 @@ export declare class TaskRoomApplicationService {
179
184
  name: string;
180
185
  version: number;
181
186
  description: string;
182
- builtin?: boolean;
187
+ sourceFile?: string;
183
188
  room?: import("../rooms-tasks/types.js").TemplateRoomConfig;
184
189
  contract?: string;
185
190
  members: import("../rooms-tasks/types.js").TemplateMemberSlot[];
@@ -252,6 +257,7 @@ export declare class TaskRoomApplicationService {
252
257
  actor: TaskRoomActor;
253
258
  taskId: string;
254
259
  template?: string;
260
+ members?: MemberOverrides;
255
261
  }): Promise<{
256
262
  task: TaskRecord;
257
263
  status: 'ready' | 'already_active';