atris 3.30.4 → 3.30.6

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 (2) hide show
  1. package/commands/mission.js +132 -14
  2. package/package.json +1 -1
@@ -10,6 +10,8 @@ const {
10
10
  resolveClaudeRunnerBin,
11
11
  } = require('../lib/runner-command');
12
12
  const {
13
+ FUNCTIONAL_MEMBER_TOPICS,
14
+ listWorkspaceMemberSlugs,
13
15
  normalizeOwnerSlug,
14
16
  resolveFunctionalOwner,
15
17
  } = require('../lib/functional-owner');
@@ -142,19 +144,48 @@ function printJsonOrText(payload, lines, asJson) {
142
144
  for (const line of lines) console.log(line);
143
145
  }
144
146
 
145
- function missionRunInputRequired(asJson = false) {
147
+ const MISSION_RUN_VALUE_FLAGS = [
148
+ '--max-ticks',
149
+ '--max-wall',
150
+ '--cadence',
151
+ '--owner',
152
+ '--runner',
153
+ '--lane',
154
+ '--verify',
155
+ '--stop',
156
+ '--model',
157
+ ];
158
+ const MISSION_RUN_BOOLEAN_FLAGS = [
159
+ '--json',
160
+ '--due',
161
+ '--no-claude',
162
+ '--no-verify',
163
+ '--complete-on-pass',
164
+ '--no-drain',
165
+ '--always-on',
166
+ '--xp-task',
167
+ '--agent-xp',
168
+ ];
169
+ const DEFAULT_MISSION_RUN_OWNER_SLUGS = new Set(
170
+ FUNCTIONAL_MEMBER_TOPICS.map(topic => normalizeOwnerSlug(topic.owner)),
171
+ );
172
+
173
+ function missionRunInputRequired(asJson = false, owner = '') {
174
+ const defaultOwner = normalizeOwnerSlug(owner || process.env.ATRIS_AGENT_ID || 'mission-lead') || 'mission-lead';
146
175
  const payload = {
147
176
  ok: false,
148
177
  action: 'mission_input_required',
149
178
  prompt: 'What mission should Atris run?',
179
+ owner: defaultOwner,
150
180
  owner_prompt: 'Which team member should own it?',
151
- example: 'atris mission run "make onboarding magical" --owner mission-lead',
181
+ example: `atris mission run "make onboarding magical" --owner ${defaultOwner}`,
152
182
  };
153
183
  if (asJson) {
154
184
  console.log(JSON.stringify(payload, null, 2));
155
185
  } else {
156
186
  console.error('What mission should Atris run?');
157
- console.error('Try: atris mission run "make onboarding magical" --owner mission-lead');
187
+ if (defaultOwner) console.error(`Team member: ${defaultOwner}`);
188
+ console.error(`Try: atris mission run "make onboarding magical" --owner ${defaultOwner}`);
158
189
  }
159
190
  process.exit(1);
160
191
  }
@@ -178,6 +209,38 @@ function removeValueFlag(args, name) {
178
209
  return out;
179
210
  }
180
211
 
212
+ function missionRunOwnerRef(ref, root = process.cwd()) {
213
+ const owner = normalizeOwnerSlug(ref);
214
+ if (!owner || /\s/.test(String(ref || ''))) return null;
215
+ if (listWorkspaceMemberSlugs(root).has(owner)) return owner;
216
+ if (DEFAULT_MISSION_RUN_OWNER_SLUGS.has(owner)) return owner;
217
+ return null;
218
+ }
219
+
220
+ function missionRunArgsWithOwner(args, owner) {
221
+ return [...removeValueFlag(args, '--owner'), '--owner', owner];
222
+ }
223
+
224
+ function missionRunInputFromArgs(args, root = process.cwd()) {
225
+ const positionals = stripKnownFlags(args, MISSION_RUN_VALUE_FLAGS, MISSION_RUN_BOOLEAN_FLAGS);
226
+ const explicitOwner = Boolean(readFlag(args, '--owner', ''));
227
+ if (!explicitOwner && positionals.length > 0) {
228
+ const owner = missionRunOwnerRef(positionals[0], root);
229
+ if (owner) {
230
+ return {
231
+ ref: positionals.slice(1).join(' ').trim(),
232
+ args: missionRunArgsWithOwner(args, owner),
233
+ owner,
234
+ };
235
+ }
236
+ }
237
+ return {
238
+ ref: positionals.join(' ').trim(),
239
+ args,
240
+ owner: readFlag(args, '--owner', ''),
241
+ };
242
+ }
243
+
181
244
  async function promptMissionRunInput(args) {
182
245
  const defaultOwner = readFlag(args, '--owner', process.env.ATRIS_AGENT_ID || 'mission-lead');
183
246
  const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
@@ -872,6 +935,61 @@ function findActiveContinuationMission(parent, root = process.cwd()) {
872
935
  )) || null;
873
936
  }
874
937
 
938
+ function findActiveMissionRunContinuation(root = process.cwd(), excludeId = '') {
939
+ const excluded = String(excludeId || '');
940
+ const candidates = listMissions(root)
941
+ .filter((mission) => (
942
+ mission.id !== excluded
943
+ && mission.started_from === 'mission_run_continuation'
944
+ && mission.continuation_policy === 'choose_next_mission'
945
+ && !TERMINAL_STATUSES.has(mission.status)
946
+ ));
947
+ candidates.sort((a, b) => missionSortTime(b) - missionSortTime(a));
948
+ return candidates[0] || null;
949
+ }
950
+
951
+ function completeActiveContinuationForStartedMission(nextMission, root = process.cwd()) {
952
+ const continuation = findActiveMissionRunContinuation(root, nextMission?.id);
953
+ if (!continuation || !nextMission) return null;
954
+ if (continuation.objective === nextMission.objective) return null;
955
+
956
+ const proof = `Started next mission ${nextMission.id}: ${nextMission.objective}`;
957
+ const completionGate = { ok: true, source: 'mission_run_continuation', forced: false };
958
+ const baseNext = {
959
+ ...continuation,
960
+ status: 'complete',
961
+ completed_at: stampIso(),
962
+ proof,
963
+ completion_gate: completionGate,
964
+ continued_by_mission_id: nextMission.id,
965
+ continued_by_objective: nextMission.objective,
966
+ next_action: 'mission complete',
967
+ };
968
+ const completion = missionCompletionReceipt(baseNext, proof);
969
+ const { mission: saved } = saveMission({
970
+ ...baseNext,
971
+ landing: completion.landing,
972
+ result: completion.result,
973
+ }, root, 'mission_continuation_completed', {
974
+ proof,
975
+ continued_by_mission_id: nextMission.id,
976
+ continued_by_objective: nextMission.objective,
977
+ });
978
+ appendMemberLog(saved.owner, 'Mission continuation completed', {
979
+ mission: saved.objective,
980
+ continued_by: nextMission.id,
981
+ proof,
982
+ }, root);
983
+ return {
984
+ completed: true,
985
+ mission: saved,
986
+ continued_by: {
987
+ mission_id: nextMission.id,
988
+ objective: nextMission.objective,
989
+ },
990
+ };
991
+ }
992
+
875
993
  function seedMissionRunContinuation(parent, root = process.cwd(), proof = '') {
876
994
  if (!parent || parent.status !== 'complete') return null;
877
995
  if (parent.continue_on_complete !== true) return null;
@@ -1032,6 +1150,7 @@ function startMissionFromRunObjective(objective, args) {
1032
1150
  verifier: saved.verifier,
1033
1151
  });
1034
1152
  const worktreeBaseline = captureMissionWorktreeBaseline(saved, process.cwd());
1153
+ const completedContinuationGoal = completeActiveContinuationForStartedMission(saved, process.cwd());
1035
1154
  const codexGoalState = refreshCodexGoalController(process.cwd());
1036
1155
  printJsonOrText(
1037
1156
  {
@@ -1047,6 +1166,7 @@ function startMissionFromRunObjective(objective, args) {
1047
1166
  dirty_count: worktreeBaseline.dirty_count,
1048
1167
  dirty_hash: worktreeBaseline.dirty_hash,
1049
1168
  } : null,
1169
+ completed_continuation_goal: completedContinuationGoal,
1050
1170
  codex_goal_state: codexGoalState,
1051
1171
  next_command: codexGoalState.goal?.next_command || `atris mission tick ${saved.id} --verify`,
1052
1172
  },
@@ -2311,17 +2431,15 @@ async function runMission(args) {
2311
2431
  const maxTicks = Math.max(1, Number(maxTicksFlag) || MISSION_RUN_DEFAULTS.maxTicks);
2312
2432
  const maxWallSeconds = Math.max(60, Number(readFlag(args, '--max-wall', '')) || MISSION_RUN_DEFAULTS.maxWallSeconds);
2313
2433
  const cadenceOverride = readFlag(args, '--cadence', '');
2314
- const ref = stripKnownFlags(
2315
- args,
2316
- ['--max-ticks', '--max-wall', '--cadence', '--owner', '--runner', '--lane', '--verify', '--stop', '--model'],
2317
- ['--json', '--due', '--no-claude', '--no-verify', '--complete-on-pass', '--no-drain', '--always-on', '--xp-task', '--agent-xp'],
2318
- ).join(' ').trim();
2434
+ const input = missionRunInputFromArgs(args);
2435
+ const ref = input.ref;
2436
+ const runArgs = input.args;
2319
2437
 
2320
2438
  if (!dueMode && !ref) {
2321
2439
  if (asJson || !process.stdin.isTTY || !process.stderr.isTTY) {
2322
- missionRunInputRequired(asJson);
2440
+ missionRunInputRequired(asJson, input.owner);
2323
2441
  }
2324
- const prompted = await promptMissionRunInput(args);
2442
+ const prompted = await promptMissionRunInput(runArgs);
2325
2443
  startMissionFromRunObjective(prompted.objective, prompted.args);
2326
2444
  return;
2327
2445
  }
@@ -2335,8 +2453,8 @@ async function runMission(args) {
2335
2453
  );
2336
2454
  return;
2337
2455
  }
2338
- if (!mission && ref && /\s/.test(ref) && !String(ref).startsWith('mission-')) {
2339
- startMissionFromRunObjective(ref, args);
2456
+ if (!mission && ref && !String(ref).startsWith('mission-')) {
2457
+ startMissionFromRunObjective(ref, runArgs);
2340
2458
  return;
2341
2459
  }
2342
2460
  if (!mission) {
@@ -3159,9 +3277,9 @@ atris mission - durable goal + loop + owner + proof state
3159
3277
  atris mission goal [--heartbeat] [--json]
3160
3278
  atris mission goal-loop [--max-wall 28800] [--max-iterations 32] [--no-claude] [--json]
3161
3279
  atris mission tick <id> [--verify] [--complete-on-pass] [--summary "..."] [--json]
3162
- atris mission run ["objective"|id|--due] [--owner <member>] [--max-ticks 4] [--max-wall 3600] [--cadence "15m"]
3280
+ atris mission run ["objective"|<member> ["objective"]|id|--due] [--owner <member>] [--max-ticks 4] [--max-wall 3600] [--cadence "15m"]
3163
3281
  [--no-claude] [--no-verify] [--complete-on-pass] [--no-drain] [--json]
3164
- (bare run prompts for mission + owner; --due runs the saved queue)
3282
+ (bare/member-only run prompts; one-word fuzzy intent starts a new visible-goal mission; --due runs the saved queue)
3165
3283
  (mission-run completions seed the next visible goal: decide and start the next useful mission)
3166
3284
  atris mission complete <id> --proof "..."
3167
3285
  atris mission stop <id> [--pause] [--reason "..."]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atris",
3
- "version": "3.30.4",
3
+ "version": "3.30.6",
4
4
  "main": "bin/atris.js",
5
5
  "bin": {
6
6
  "atris": "bin/atris.js",