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.
- package/commands/mission.js +132 -14
- package/package.json +1 -1
package/commands/mission.js
CHANGED
|
@@ -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
|
-
|
|
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:
|
|
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(
|
|
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
|
|
2315
|
-
|
|
2316
|
-
|
|
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(
|
|
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 &&
|
|
2339
|
-
startMissionFromRunObjective(ref,
|
|
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
|
|
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 "..."]
|