overlord-cli 0.2607171335.0 → 0.2607191710.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.
@@ -1 +1 @@
1
- 0.3.3
1
+ 0.3.4
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://antigravity.google/schemas/v1/plugin.json",
3
3
  "name": "overlord",
4
- "version": "0.3.3",
4
+ "version": "0.3.4",
5
5
  "description": "Chat-driven access to Overlord mission protocol workflows with hook-driven activity capture.",
6
6
  "author": {
7
7
  "name": "Cooperativ",
@@ -188,7 +188,7 @@ const tools = [
188
188
  name: 'overlord_deliver_session',
189
189
  title: 'Deliver mission session',
190
190
  description:
191
- 'Deliver an attached session with explicit summary and optional change rationales.',
191
+ 'Deliver an attached session with explicit summary, optional change rationales, and optional human-action/tradeoff evidence.',
192
192
  inputSchema: objectSchema(
193
193
  {
194
194
  missionId: stringProperty('Mission UUID or workspace display id.'),
@@ -201,7 +201,19 @@ const tools = [
201
201
  changeRationales: {
202
202
  type: 'array',
203
203
  description: 'Explicit change rationale objects, if files were changed.'
204
- }
204
+ },
205
+ humanActions: {
206
+ type: 'array',
207
+ description:
208
+ 'Concrete actions a human must perform; exclude Git operations and routine review/testing.'
209
+ },
210
+ tradeoffsMade: {
211
+ type: 'array',
212
+ description: 'Implementation decisions, alternatives considered, and rationale.'
213
+ },
214
+ knownRisks: { type: 'array', description: 'Residual risks or limitations.' },
215
+ deferredWork: { type: 'array', description: 'Intentionally deferred work.' },
216
+ assumptions: { type: 'array', description: 'Material implementation assumptions.' }
205
217
  },
206
218
  ['missionId', 'sessionKey', 'summary']
207
219
  )
@@ -294,6 +306,28 @@ function callOverlordTool(name, args) {
294
306
  ...(args.noFileChanges === true ? { 'no-file-changes': true } : {}),
295
307
  ...(Array.isArray(args.changeRationales)
296
308
  ? { 'change-rationales-json': args.changeRationales }
309
+ : {}),
310
+ ...(Array.isArray(args.humanActions) ||
311
+ Array.isArray(args.tradeoffsMade) ||
312
+ Array.isArray(args.knownRisks) ||
313
+ Array.isArray(args.deferredWork) ||
314
+ Array.isArray(args.assumptions)
315
+ ? {
316
+ payload: {
317
+ deliveryReport: {
318
+ schemaVersion: 1,
319
+ agentReport: {
320
+ ...(Array.isArray(args.humanActions) ? { humanActions: args.humanActions } : {}),
321
+ ...(Array.isArray(args.tradeoffsMade)
322
+ ? { tradeoffsMade: args.tradeoffsMade }
323
+ : {}),
324
+ ...(Array.isArray(args.knownRisks) ? { knownRisks: args.knownRisks } : {}),
325
+ ...(Array.isArray(args.deferredWork) ? { deferredWork: args.deferredWork } : {}),
326
+ ...(Array.isArray(args.assumptions) ? { assumptions: args.assumptions } : {})
327
+ }
328
+ }
329
+ }
330
+ }
297
331
  : {})
298
332
  });
299
333
  }
@@ -328,7 +362,7 @@ process.stdin.on('data', async chunk => {
328
362
  result: {
329
363
  protocolVersion: PROTOCOL_VERSION,
330
364
  capabilities: { tools: { listChanged: false } },
331
- serverInfo: { name: 'overlord-antigravity', version: '0.3.3' }
365
+ serverInfo: { name: 'overlord-antigravity', version: '0.3.4' }
332
366
  }
333
367
  });
334
368
  continue;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "overlord",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Overlord mission protocol workflow for Claude Code — attach/update/ask/deliver, slash commands, and hook-driven activity capture.",
5
5
  "author": {
6
6
  "name": "Cooperativ",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "overlord",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Chat-driven access to Overlord mission protocol workflows with hook-driven activity capture.",
5
5
  "author": {
6
6
  "name": "Cooperativ",
@@ -188,7 +188,7 @@ const tools = [
188
188
  name: 'overlord_deliver_session',
189
189
  title: 'Deliver mission session',
190
190
  description:
191
- 'Deliver an attached session with explicit summary and optional change rationales.',
191
+ 'Deliver an attached session with explicit summary, optional change rationales, and optional human-action/tradeoff evidence.',
192
192
  inputSchema: objectSchema(
193
193
  {
194
194
  missionId: stringProperty('Mission UUID or workspace display id.'),
@@ -201,7 +201,19 @@ const tools = [
201
201
  changeRationales: {
202
202
  type: 'array',
203
203
  description: 'Explicit change rationale objects, if files were changed.'
204
- }
204
+ },
205
+ humanActions: {
206
+ type: 'array',
207
+ description:
208
+ 'Concrete actions a human must perform; exclude Git operations and routine review/testing.'
209
+ },
210
+ tradeoffsMade: {
211
+ type: 'array',
212
+ description: 'Implementation decisions, alternatives considered, and rationale.'
213
+ },
214
+ knownRisks: { type: 'array', description: 'Residual risks or limitations.' },
215
+ deferredWork: { type: 'array', description: 'Intentionally deferred work.' },
216
+ assumptions: { type: 'array', description: 'Material implementation assumptions.' }
205
217
  },
206
218
  ['missionId', 'sessionKey', 'summary']
207
219
  )
@@ -294,6 +306,28 @@ function callOverlordTool(name, args) {
294
306
  ...(args.noFileChanges === true ? { 'no-file-changes': true } : {}),
295
307
  ...(Array.isArray(args.changeRationales)
296
308
  ? { 'change-rationales-json': args.changeRationales }
309
+ : {}),
310
+ ...(Array.isArray(args.humanActions) ||
311
+ Array.isArray(args.tradeoffsMade) ||
312
+ Array.isArray(args.knownRisks) ||
313
+ Array.isArray(args.deferredWork) ||
314
+ Array.isArray(args.assumptions)
315
+ ? {
316
+ payload: {
317
+ deliveryReport: {
318
+ schemaVersion: 1,
319
+ agentReport: {
320
+ ...(Array.isArray(args.humanActions) ? { humanActions: args.humanActions } : {}),
321
+ ...(Array.isArray(args.tradeoffsMade)
322
+ ? { tradeoffsMade: args.tradeoffsMade }
323
+ : {}),
324
+ ...(Array.isArray(args.knownRisks) ? { knownRisks: args.knownRisks } : {}),
325
+ ...(Array.isArray(args.deferredWork) ? { deferredWork: args.deferredWork } : {}),
326
+ ...(Array.isArray(args.assumptions) ? { assumptions: args.assumptions } : {})
327
+ }
328
+ }
329
+ }
330
+ }
297
331
  : {})
298
332
  });
299
333
  }
@@ -328,7 +362,7 @@ process.stdin.on('data', async chunk => {
328
362
  result: {
329
363
  protocolVersion: PROTOCOL_VERSION,
330
364
  capabilities: { tools: { listChanged: false } },
331
- serverInfo: { name: 'overlord-codex', version: '0.3.3' }
365
+ serverInfo: { name: 'overlord-codex', version: '0.3.4' }
332
366
  }
333
367
  });
334
368
  continue;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "overlord",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Overlord mission protocol workflow for Cursor — attach/update/ask/deliver, slash commands, MCP bridge, and follow-up capture.",
5
5
  "author": {
6
6
  "name": "Cooperativ",
@@ -188,7 +188,7 @@ const tools = [
188
188
  name: 'overlord_deliver_session',
189
189
  title: 'Deliver mission session',
190
190
  description:
191
- 'Deliver an attached session with explicit summary and optional change rationales.',
191
+ 'Deliver an attached session with explicit summary, optional change rationales, and optional human-action/tradeoff evidence.',
192
192
  inputSchema: objectSchema(
193
193
  {
194
194
  missionId: stringProperty('Mission UUID or workspace display id.'),
@@ -201,7 +201,19 @@ const tools = [
201
201
  changeRationales: {
202
202
  type: 'array',
203
203
  description: 'Explicit change rationale objects, if files were changed.'
204
- }
204
+ },
205
+ humanActions: {
206
+ type: 'array',
207
+ description:
208
+ 'Concrete actions a human must perform; exclude Git operations and routine review/testing.'
209
+ },
210
+ tradeoffsMade: {
211
+ type: 'array',
212
+ description: 'Implementation decisions, alternatives considered, and rationale.'
213
+ },
214
+ knownRisks: { type: 'array', description: 'Residual risks or limitations.' },
215
+ deferredWork: { type: 'array', description: 'Intentionally deferred work.' },
216
+ assumptions: { type: 'array', description: 'Material implementation assumptions.' }
205
217
  },
206
218
  ['missionId', 'sessionKey', 'summary']
207
219
  )
@@ -294,6 +306,28 @@ function callOverlordTool(name, args) {
294
306
  ...(args.noFileChanges === true ? { 'no-file-changes': true } : {}),
295
307
  ...(Array.isArray(args.changeRationales)
296
308
  ? { 'change-rationales-json': args.changeRationales }
309
+ : {}),
310
+ ...(Array.isArray(args.humanActions) ||
311
+ Array.isArray(args.tradeoffsMade) ||
312
+ Array.isArray(args.knownRisks) ||
313
+ Array.isArray(args.deferredWork) ||
314
+ Array.isArray(args.assumptions)
315
+ ? {
316
+ payload: {
317
+ deliveryReport: {
318
+ schemaVersion: 1,
319
+ agentReport: {
320
+ ...(Array.isArray(args.humanActions) ? { humanActions: args.humanActions } : {}),
321
+ ...(Array.isArray(args.tradeoffsMade)
322
+ ? { tradeoffsMade: args.tradeoffsMade }
323
+ : {}),
324
+ ...(Array.isArray(args.knownRisks) ? { knownRisks: args.knownRisks } : {}),
325
+ ...(Array.isArray(args.deferredWork) ? { deferredWork: args.deferredWork } : {}),
326
+ ...(Array.isArray(args.assumptions) ? { assumptions: args.assumptions } : {})
327
+ }
328
+ }
329
+ }
330
+ }
297
331
  : {})
298
332
  });
299
333
  }
@@ -328,7 +362,7 @@ process.stdin.on('data', async chunk => {
328
362
  result: {
329
363
  protocolVersion: PROTOCOL_VERSION,
330
364
  capabilities: { tools: { listChanged: false } },
331
- serverInfo: { name: 'overlord-cursor', version: '0.3.3' }
365
+ serverInfo: { name: 'overlord-cursor', version: '0.3.4' }
332
366
  }
333
367
  });
334
368
  continue;
@@ -22,6 +22,12 @@ Use this mode when the prompt already contains a mission ID or explicitly says t
22
22
  6. If blocked, call `ovld protocol ask --session-key <sessionKey> --mission-id <mission_id> --question "..."` and stop.
23
23
  7. Deliver last with `ovld protocol deliver --session-key <sessionKey> --mission-id <mission_id> --summary "..."`, including `changeRationales` only for meaningful behavioral file changes made as part of this mission.
24
24
 
25
+ At delivery, provide `deliveryReport.agentReport` through `--payload-json` / `--payload-file`: use
26
+ `humanActions`, `tradeoffsMade`, `knownRisks`, `deferredWork`, and `assumptions`, with empty arrays
27
+ when none apply. Human actions are concrete work a user must perform outside completed agent work;
28
+ never include Git operations or routine review/testing. Tradeoffs record the implementation decision,
29
+ alternatives considered, and rationale. These fields improve review visibility but never block delivery.
30
+
25
31
  For full command syntax, flags, phase values, and event types see **CLI Command Reference** below.
26
32
 
27
33
  ## Missions vs Objectives
@@ -164,6 +170,33 @@ EOF
164
170
 
165
171
  If `heartbeat` succeeds but `deliver` or `update` fails, the session is likely fine — retry with large JSON on stdin instead of inline `--*-json`.
166
172
 
173
+ ### Delivery Evidence
174
+
175
+ Send agent-authored facts in the delivery payload; Overlord stores an immediate deterministic
176
+ presentation, so do not wait for or invoke an AI provider.
177
+
178
+ ```json
179
+ {
180
+ "deliveryReport": {
181
+ "schemaVersion": 1,
182
+ "agentReport": {
183
+ "humanActions": [],
184
+ "tradeoffsMade": [],
185
+ "knownRisks": [],
186
+ "deferredWork": [],
187
+ "assumptions": []
188
+ }
189
+ }
190
+ }
191
+ ```
192
+
193
+ Only list a human action when a person must perform a concrete non-Git step outside the
194
+ agent's completed work (for example, add a secret, run a production migration, deploy, or
195
+ configure an external integration). Never list committing, pushing, opening a pull request,
196
+ reviewing code, or ordinary tests. A tradeoff must state the decision, alternatives considered,
197
+ and rationale. Missing evidence is normalized to empty arrays for compatibility, but agents
198
+ should report it when applicable.
199
+
167
200
  ### Preflight: check your changes before delivering
168
201
 
169
202
  Never hand-triage `git status` to figure out which dirty files are yours. Run the preflight first:
package/dist/index.js CHANGED
@@ -13538,6 +13538,87 @@ var init_discover_project_local = __esm({
13538
13538
  }
13539
13539
  });
13540
13540
 
13541
+ // src/pre-launch.ts
13542
+ function substitutePreLaunchVariables(commands, variables) {
13543
+ return commands.map(
13544
+ (command) => command.replace(PLACEHOLDER_PATTERN, (match, name) => {
13545
+ const value = variables[name];
13546
+ return value === void 0 ? match : value;
13547
+ })
13548
+ ).map((command) => command.trim()).filter((command) => command.length > 0);
13549
+ }
13550
+ function substituteLaunchEnvVars(envVars, variables) {
13551
+ const resolved = {};
13552
+ for (const [rawKey, rawValue] of Object.entries(envVars)) {
13553
+ const key = rawKey.trim();
13554
+ if (!key) continue;
13555
+ resolved[key] = rawValue.replace(PLACEHOLDER_PATTERN, (match, name) => {
13556
+ const value = variables[name];
13557
+ return value === void 0 ? match : value;
13558
+ });
13559
+ }
13560
+ return resolved;
13561
+ }
13562
+ function resourcePaths(projectResources) {
13563
+ if (!Array.isArray(projectResources)) return [];
13564
+ const paths = [];
13565
+ for (const entry of projectResources) {
13566
+ if (entry && typeof entry === "object") {
13567
+ const path27 = entry.path;
13568
+ if (typeof path27 === "string" && path27.trim()) paths.push(path27.trim());
13569
+ }
13570
+ }
13571
+ return paths;
13572
+ }
13573
+ function primaryResourcePath(projectResources) {
13574
+ if (!Array.isArray(projectResources)) return "";
13575
+ let currentPath = "";
13576
+ for (const entry of projectResources) {
13577
+ if (!entry || typeof entry !== "object") continue;
13578
+ const record = entry;
13579
+ const path27 = typeof record.path === "string" ? record.path.trim() : "";
13580
+ if (!path27) continue;
13581
+ if (record.isPrimary === true) return path27;
13582
+ if (record.isCurrent === true && !currentPath) currentPath = path27;
13583
+ }
13584
+ return currentPath;
13585
+ }
13586
+ function buildPreLaunchVariables({
13587
+ launchEnv = {},
13588
+ projectResources,
13589
+ workingDirectory,
13590
+ contextFile,
13591
+ tmpDir
13592
+ }) {
13593
+ const paths = resourcePaths(projectResources);
13594
+ const scratch = typeof tmpDir === "string" ? tmpDir.trim() : "";
13595
+ const cwd = typeof workingDirectory === "string" ? workingDirectory.trim() : "";
13596
+ const contextPath = typeof contextFile === "string" ? contextFile.trim() : "";
13597
+ return {
13598
+ // Optional Overlord env keys default to empty so documented placeholders
13599
+ // resolve rather than remaining as literal `{VAR}` tokens.
13600
+ OVERLORD_EXECUTION_REQUEST_ID: "",
13601
+ OVERLORD_PROJECT_RESOURCES: "",
13602
+ ...launchEnv,
13603
+ OVERLORD_PROJECT_RESOURCES_PATHS: paths.join(" "),
13604
+ OVERLORD_PROJECT_RESOURCES_PATHS_CSV: paths.join(","),
13605
+ OVERLORD_PRIMARY_RESOURCE_PATH: primaryResourcePath(projectResources),
13606
+ OVERLORD_WORKING_DIRECTORY: cwd,
13607
+ OVERLORD_CONTEXT_FILE: contextPath,
13608
+ OVERLORD_TMPDIR: scratch,
13609
+ TMPDIR: scratch,
13610
+ TMP: scratch,
13611
+ TEMP: scratch
13612
+ };
13613
+ }
13614
+ var PLACEHOLDER_PATTERN;
13615
+ var init_pre_launch = __esm({
13616
+ "src/pre-launch.ts"() {
13617
+ "use strict";
13618
+ PLACEHOLDER_PATTERN = /\{([A-Z0-9_]+)\}/g;
13619
+ }
13620
+ });
13621
+
13541
13622
  // src/terminal-launcher.ts
13542
13623
  function shellQuote2(value) {
13543
13624
  return `'${value.replace(/'/g, `'\\''`)}'`;
@@ -13583,24 +13664,31 @@ function agentShellCommand({
13583
13664
  const assignments = Object.entries(extraEnv).filter(([key, value]) => key.trim() && value.trim()).map(([key, value]) => `${key}=${shellQuote2(value)}`).join(" ");
13584
13665
  return assignments ? `env ${assignments} ${invocation}` : invocation;
13585
13666
  }
13667
+ function withPreLaunchCommands(agentCommand, preLaunchCommands) {
13668
+ const pre = (preLaunchCommands ?? []).map((command) => command.trim()).filter(Boolean);
13669
+ return pre.length > 0 ? `${pre.join("; ")}; ${agentCommand}` : agentCommand;
13670
+ }
13586
13671
  function terminalInnerCommand({
13587
13672
  workingDirectory,
13588
13673
  agentCommand,
13589
- extraEnv = {}
13674
+ extraEnv = {},
13675
+ preLaunchCommands
13590
13676
  }) {
13591
13677
  const exports = Object.entries({ ...tmpEnvFor(workingDirectory), ...extraEnv }).map(([key, value]) => `export ${key}=${shellQuote2(value)}`).join("; ");
13592
- return `cd ${shellQuote2(workingDirectory)} && ${exports}; ${agentCommand}`;
13678
+ const invocation = withPreLaunchCommands(agentCommand, preLaunchCommands);
13679
+ return `cd ${shellQuote2(workingDirectory)} && ${exports}; ${invocation}`;
13593
13680
  }
13594
13681
  function terminalLaunchScriptContent({
13595
13682
  command,
13596
13683
  args,
13597
13684
  workingDirectory,
13598
13685
  preCommand,
13599
- extraEnv = {}
13686
+ extraEnv = {},
13687
+ preLaunchCommands
13600
13688
  }) {
13601
13689
  const agentCommand = agentShellCommand({ command, args, preCommand });
13602
13690
  return `#!/usr/bin/env bash
13603
- ${terminalInnerCommand({ workingDirectory, agentCommand, extraEnv })}
13691
+ ${terminalInnerCommand({ workingDirectory, agentCommand, extraEnv, preLaunchCommands })}
13604
13692
  `;
13605
13693
  }
13606
13694
  function terminalScriptCommand(scriptPath) {
@@ -13761,7 +13849,8 @@ function resolveLaunchExecution({
13761
13849
  terminalLaunchChord,
13762
13850
  terminalScriptPath,
13763
13851
  terminalLaunchBackground = false,
13764
- extraEnv = {}
13852
+ extraEnv = {},
13853
+ preLaunchCommands
13765
13854
  }) {
13766
13855
  const agentCommand = agentShellCommand({ command, args, preCommand });
13767
13856
  const genericAgentCommand = agentShellCommand({
@@ -13771,13 +13860,23 @@ function resolveLaunchExecution({
13771
13860
  extraEnv,
13772
13861
  includeEnvPrefix: true
13773
13862
  });
13863
+ const hasPreLaunch = (preLaunchCommands ?? []).some((entry) => entry.trim().length > 0);
13774
13864
  const launcher = terminalLauncher?.trim();
13775
13865
  const placement = terminalLaunchPlacement ?? "window";
13776
13866
  const chordClause = resolveChordClause(terminalLaunchChord);
13777
13867
  if (!launcher) {
13778
- return preCommand?.trim() ? { command: agentCommand, args: [], useShell: true, terminal: null, display: agentCommand } : { command, args, useShell: false, terminal: null, display: agentCommand };
13868
+ if (!preCommand?.trim() && !hasPreLaunch) {
13869
+ return { command, args, useShell: false, terminal: null, display: agentCommand };
13870
+ }
13871
+ const inline = withPreLaunchCommands(agentCommand, preLaunchCommands);
13872
+ return { command: inline, args: [], useShell: true, terminal: null, display: inline };
13779
13873
  }
13780
- const inner = terminalInnerCommand({ workingDirectory, agentCommand, extraEnv });
13874
+ const inner = terminalInnerCommand({
13875
+ workingDirectory,
13876
+ agentCommand,
13877
+ extraEnv,
13878
+ preLaunchCommands
13879
+ });
13781
13880
  const terminalInner = terminalScriptPath?.trim() ? terminalScriptCommand(terminalScriptPath.trim()) : inner;
13782
13881
  const builtin = resolveBuiltinTerminal(launcher);
13783
13882
  if (builtin === "terminal") {
@@ -13811,7 +13910,7 @@ function resolveLaunchExecution({
13811
13910
  display: `iTerm2 (${placement}) \u203A ${terminalInner}`
13812
13911
  };
13813
13912
  }
13814
- const genericTerminalCommand = terminalScriptPath?.trim() ? terminalScriptCommand(terminalScriptPath.trim()) : genericAgentCommand;
13913
+ const genericTerminalCommand = terminalScriptPath?.trim() ? terminalScriptCommand(terminalScriptPath.trim()) : withPreLaunchCommands(genericAgentCommand, preLaunchCommands);
13815
13914
  const full = placement === "window" ? `${terminalLaunchBackground ? backgroundLauncher(launcher) : launcher} ${genericTerminalCommand}` : buildGenericPlacementShell({
13816
13915
  launcher,
13817
13916
  inner: genericTerminalCommand,
@@ -14000,6 +14099,16 @@ Execution request: ${options.executionRequestId}` : context.launchContext;
14000
14099
  executionRequestId: options.executionRequestId,
14001
14100
  projectResources
14002
14101
  });
14102
+ const launchVariables = buildPreLaunchVariables({
14103
+ launchEnv,
14104
+ projectResources,
14105
+ workingDirectory: options.workingDirectory,
14106
+ contextFile,
14107
+ tmpDir
14108
+ });
14109
+ const preLaunchCommands = options.preLaunchCommands && options.preLaunchCommands.length > 0 ? substitutePreLaunchVariables(options.preLaunchCommands, launchVariables) : [];
14110
+ const resolvedEnvVars = options.launchEnvVars && Object.keys(options.launchEnvVars).length > 0 ? substituteLaunchEnvVars(options.launchEnvVars, launchVariables) : {};
14111
+ const exportedEnv = { ...launchEnv, ...resolvedEnvVars };
14003
14112
  const prompt = launchContext.length > 4e3 ? `Read the Overlord context file at ${contextFile}, attach to mission ${context.displayId}, then immediately execute its current objective. Do not wait for more instructions.` : launchContext;
14004
14113
  const command = buildAgentCommand({
14005
14114
  agent: options.agent,
@@ -14023,7 +14132,8 @@ Execution request: ${options.executionRequestId}` : context.launchContext;
14023
14132
  args: command.args,
14024
14133
  workingDirectory: options.workingDirectory,
14025
14134
  preCommand: options.preCommand,
14026
- extraEnv: launchEnv
14135
+ extraEnv: exportedEnv,
14136
+ preLaunchCommands
14027
14137
  })
14028
14138
  );
14029
14139
  chmodSync3(terminalScriptPath, 448);
@@ -14038,7 +14148,8 @@ Execution request: ${options.executionRequestId}` : context.launchContext;
14038
14148
  terminalLaunchChord: options.terminalLaunchChord,
14039
14149
  terminalLaunchBackground: options.terminalLaunchBackground,
14040
14150
  terminalScriptPath,
14041
- extraEnv: launchEnv
14151
+ extraEnv: exportedEnv,
14152
+ preLaunchCommands
14042
14153
  });
14043
14154
  return {
14044
14155
  ...command,
@@ -14046,7 +14157,7 @@ Execution request: ${options.executionRequestId}` : context.launchContext;
14046
14157
  contextFile,
14047
14158
  workingDirectory: options.workingDirectory,
14048
14159
  execution,
14049
- env: launchEnv
14160
+ env: exportedEnv
14050
14161
  };
14051
14162
  }
14052
14163
  async function launchAgent({
@@ -14080,6 +14191,7 @@ var init_launch = __esm({
14080
14191
  "src/launch.ts"() {
14081
14192
  "use strict";
14082
14193
  init_agent_binaries();
14194
+ init_pre_launch();
14083
14195
  init_project_tmp();
14084
14196
  init_terminal_launcher();
14085
14197
  AGENT_HISTORY_EXCLUDED_EVENT_TYPES = /* @__PURE__ */ new Set([
@@ -14561,6 +14673,9 @@ deliver:
14561
14673
  --mission-id <id>
14562
14674
  --summary or --summary-file <path|->
14563
14675
  or: --payload-json / --payload-file <path|-> with { summary, artifacts, changeRationales }
14676
+ The payload may also include deliveryReport: { schemaVersion: 1, agentReport: {
14677
+ humanActions, tradeoffsMade, knownRisks, deferredWork, assumptions } }. Use empty arrays
14678
+ when none apply. Human actions exclude Git operations and routine review/testing.
14564
14679
  Optional:
14565
14680
  --artifacts-json / --artifacts-file <path|->
14566
14681
  --change-rationales-json / --change-rationales-file <path|->
@@ -16422,6 +16537,17 @@ async function resolveTerminalLaunchSettings({
16422
16537
  function asRecord2(value) {
16423
16538
  return value && typeof value === "object" ? value : {};
16424
16539
  }
16540
+ function parsePreLaunchCommandsValue(value) {
16541
+ return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
16542
+ }
16543
+ function parseLaunchEnvVarsValue(value) {
16544
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
16545
+ const vars = {};
16546
+ for (const [key, raw] of Object.entries(value)) {
16547
+ if (key.trim() && typeof raw === "string") vars[key] = raw;
16548
+ }
16549
+ return vars;
16550
+ }
16425
16551
  async function readWorktreeBranchAutomationEnabled(runtime) {
16426
16552
  try {
16427
16553
  const settings = await runtime.backend.get("/api/launch-settings");
@@ -16933,6 +17059,16 @@ async function runManagementCommand({
16933
17059
  const executionTargetId = await resolvePreferredExecutionTargetId({
16934
17060
  backend: scopedRuntime.backend
16935
17061
  });
17062
+ const missionProjectId = asRecord2(mission).projectId;
17063
+ const projectLaunchSettings = typeof missionProjectId === "string" ? await scopedRuntime.backend.get(`/api/projects/${encodeURIComponent(missionProjectId)}`).then((project) => ({
17064
+ preLaunchCommands: parsePreLaunchCommandsValue(asRecord2(project).preLaunchCommands),
17065
+ launchEnvVars: parseLaunchEnvVarsValue(asRecord2(project).launchEnvVars)
17066
+ })).catch(() => ({
17067
+ preLaunchCommands: [],
17068
+ launchEnvVars: {}
17069
+ })) : { preLaunchCommands: [], launchEnvVars: {} };
17070
+ const preLaunchCommands = projectLaunchSettings.preLaunchCommands;
17071
+ const launchEnvVars = projectLaunchSettings.launchEnvVars;
16936
17072
  const prepared = await prepareMissionBranch({
16937
17073
  runtime: scopedRuntime,
16938
17074
  options: {
@@ -16960,6 +17096,8 @@ async function runManagementCommand({
16960
17096
  thinking: flagValue(parsed.flags, "--thinking"),
16961
17097
  flags: repeatedFlagValues(rest, "--flag"),
16962
17098
  preCommand: flagValue(parsed.flags, "--pre-command"),
17099
+ preLaunchCommands: preLaunchCommands.length > 0 ? preLaunchCommands : void 0,
17100
+ launchEnvVars: Object.keys(launchEnvVars).length > 0 ? launchEnvVars : void 0,
16963
17101
  executionTargetId: executionTargetId ?? void 0,
16964
17102
  ...terminal,
16965
17103
  dryRun
@@ -17036,7 +17174,7 @@ async function runManagementCommand({
17036
17174
  events: `/api/missions/${encodeURIComponent(missionId)}/events`,
17037
17175
  artifacts: `/api/missions/${encodeURIComponent(missionId)}/artifacts`,
17038
17176
  rationales: `/api/missions/${encodeURIComponent(missionId)}/file-changes`,
17039
- deliveries: `/api/missions/${encodeURIComponent(missionId)}/events`
17177
+ deliveries: `/api/missions/${encodeURIComponent(missionId)}/deliveries`
17040
17178
  };
17041
17179
  const path27 = sub ? pathBySub[sub] : void 0;
17042
17180
  if (!path27) {
@@ -17182,6 +17320,10 @@ async function runRunnerCommand({
17182
17320
  thinking: typeof requestRecord.requestedReasoningEffort === "string" ? requestRecord.requestedReasoningEffort : void 0,
17183
17321
  flags: Array.isArray(launchConfig.flags) ? launchConfig.flags.filter((value) => typeof value === "string") : [],
17184
17322
  preCommand: typeof launchConfig.preCommand === "string" ? launchConfig.preCommand : void 0,
17323
+ preLaunchCommands: Array.isArray(requestRecord.preLaunchCommands) ? requestRecord.preLaunchCommands.filter(
17324
+ (value) => typeof value === "string"
17325
+ ) : void 0,
17326
+ launchEnvVars: parseLaunchEnvVarsValue(requestRecord.launchEnvVars),
17185
17327
  executionRequestId: requestId,
17186
17328
  executionTargetId: executionTargetId || void 0,
17187
17329
  ...terminal,