atris 3.34.0 → 3.36.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.
- package/AGENTS.md +35 -0
- package/FOR_AGENTS.md +5 -3
- package/README.md +5 -3
- package/atris/GETTING_STARTED.md +1 -1
- package/atris/atris.md +3 -0
- package/atris/policies/day-loop-voice.md +102 -0
- package/atris/policies/outbound-artifact-gate.md +2 -0
- package/atris/skills/design/SKILL.md +56 -32
- package/atris/skills/endgame/SKILL.md +12 -6
- package/atris/skills/engines/SKILL.md +35 -8
- package/atris/skills/fable-method/SKILL.md +66 -0
- package/atris/skills/improve/SKILL.md +65 -45
- package/atris/skills/render-cli/SKILL.md +88 -0
- package/atris/skills/youtube/SKILL.md +10 -1
- package/atris.md +6 -2
- package/ax +617 -31
- package/bin/atris.js +719 -266
- package/commands/activate.js +194 -88
- package/commands/aeo.js +52 -0
- package/commands/agents.js +166 -0
- package/commands/autoland.js +718 -72
- package/commands/autopilot-front.js +20 -2
- package/commands/autopilot.js +118 -2
- package/commands/avail.js +407 -0
- package/commands/bench.js +188 -0
- package/commands/brain.js +3 -0
- package/commands/brief.js +651 -0
- package/commands/business-sync.js +192 -6
- package/commands/business.js +91 -8
- package/commands/clean.js +50 -24
- package/commands/close.js +1083 -0
- package/commands/cloud.js +245 -0
- package/commands/codex-goal.js +26 -2
- package/commands/compile.js +292 -1
- package/commands/computer.js +150 -3
- package/commands/dream.js +365 -0
- package/commands/drill.js +371 -0
- package/commands/drive.js +187 -0
- package/commands/engine.js +1061 -29
- package/commands/experiments.js +28 -0
- package/commands/feed.js +202 -0
- package/commands/feedback.js +34 -12
- package/commands/fleet-report.js +206 -0
- package/commands/github.js +38 -0
- package/commands/gm.js +285 -3
- package/commands/goal.js +247 -0
- package/commands/improve.js +642 -26
- package/commands/init.js +83 -43
- package/commands/integrations.js +39 -11
- package/commands/interview.js +209 -0
- package/commands/land.js +253 -52
- package/commands/lesson.js +112 -1
- package/commands/lifecycle.js +39 -3
- package/commands/linear.js +38 -0
- package/commands/log.js +84 -1
- package/commands/loops.js +220 -16
- package/commands/meet.js +220 -0
- package/commands/member.js +899 -66
- package/commands/mission.js +3512 -332
- package/commands/next.js +137 -0
- package/commands/now.js +240 -21
- package/commands/one-lap.js +776 -0
- package/commands/orb.js +314 -0
- package/commands/pack-craft.js +179 -0
- package/commands/pack.js +823 -0
- package/commands/play.js +3 -2
- package/commands/probe.js +30 -3
- package/commands/pulse.js +241 -46
- package/commands/push.js +260 -82
- package/commands/radar.js +259 -14
- package/commands/rainmaker.js +49 -0
- package/commands/report.js +415 -0
- package/commands/scout.js +147 -0
- package/commands/search.js +363 -0
- package/commands/serve.js +54 -0
- package/commands/skill.js +47 -3
- package/commands/slop.js +50 -2
- package/commands/soul.js +1 -1
- package/commands/status.js +50 -5
- package/commands/stream.js +861 -0
- package/commands/stripe.js +38 -0
- package/commands/study.js +693 -0
- package/commands/supabase.js +39 -0
- package/commands/sync.js +67 -54
- package/commands/task.js +2275 -182
- package/commands/team.js +73 -0
- package/commands/truth.js +29 -3
- package/commands/unknowns.js +627 -0
- package/commands/update.js +44 -0
- package/commands/vercel.js +38 -0
- package/commands/verify.js +96 -0
- package/commands/watch.js +303 -0
- package/commands/wish.js +500 -0
- package/commands/workflow.js +11 -5
- package/commands/worktree.js +299 -20
- package/commands/write.js +399 -0
- package/commands/xp.js +29 -11
- package/lib/auto-accept-certified.js +391 -43
- package/lib/autoland.js +353 -52
- package/lib/ax-auto-lane.js +79 -0
- package/lib/bench/context.js +147 -0
- package/lib/bench/engines.js +141 -0
- package/lib/bench/report.js +140 -0
- package/lib/bench/runner.js +512 -0
- package/lib/brief-ledger.js +350 -0
- package/lib/cloud-mission.js +259 -0
- package/lib/codex-flight.js +154 -0
- package/lib/default-runner.js +45 -0
- package/lib/default-verifier.js +70 -0
- package/lib/engine-registry.js +232 -0
- package/lib/experiments/daily.js +640 -0
- package/lib/fleet.js +2431 -38
- package/lib/improve-vitals-html.js +171 -0
- package/lib/known-commands.js +58 -0
- package/lib/loop-doctor.js +416 -0
- package/lib/member-switches.js +144 -0
- package/lib/memory-view.js +14 -5
- package/lib/mission-room.js +1 -0
- package/lib/mission-root.js +52 -0
- package/lib/mission-runtime-loop.js +7 -0
- package/lib/next-moves.js +327 -10
- package/lib/official-cli-integration.js +174 -0
- package/lib/one-lap-validator.js +60 -0
- package/lib/orb-context.js +477 -0
- package/lib/orb-scorecard.js +224 -0
- package/lib/outbound-send-gate.js +165 -0
- package/lib/permission-grants.js +293 -0
- package/lib/policy-lessons.js +52 -1
- package/lib/pulse.js +277 -3
- package/lib/receipt-block.js +168 -0
- package/lib/receipt-evidence.js +65 -4
- package/lib/review-integrity.js +147 -0
- package/lib/router-brain.js +352 -0
- package/lib/runner-command.js +33 -0
- package/lib/self-drive.js +258 -0
- package/lib/short-name.js +103 -0
- package/lib/spawn-env.js +18 -0
- package/lib/state-detection.js +56 -1
- package/lib/sync-status.js +59 -0
- package/lib/task-db.js +319 -27
- package/lib/task-proof.js +43 -1
- package/lib/task-receipt.js +93 -0
- package/lib/team-presence.js +260 -0
- package/lib/tool-result-encode.js +7 -0
- package/lib/trust-tiers.js +90 -0
- package/lib/usage.js +107 -0
- package/lib/voice-gate.js +163 -0
- package/lib/wish-audit.js +1368 -0
- package/lib/wish-delegate.js +1840 -0
- package/lib/wish-design.js +110 -0
- package/lib/wish-stats.js +183 -0
- package/lib/wish-store.js +354 -0
- package/lib/zip.js +221 -0
- package/package.json +3 -1
- package/templates/loops/atris/loops/LOOPS.md +55 -0
- package/templates/loops/atris/loops/TICK.md +24 -0
- package/templates/loops/atris/loops/feedback.md +22 -0
- package/templates/loops/atris/loops/quality.md +22 -0
- package/templates/loops/atris/wiki/systems/loops.md +41 -0
- package/utils/api.js +5 -1
- package/utils/auth.js +57 -21
- package/utils/update-check.js +27 -6
- package/atris/learnings.jsonl +0 -1
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const SWITCHES_REL = path.join('.atris', 'state', 'member-switches.json');
|
|
7
|
+
|
|
8
|
+
function switchesPath(root = process.cwd()) {
|
|
9
|
+
return path.join(root, SWITCHES_REL);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function emptyState() {
|
|
13
|
+
return { members: {} };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function loadMemberSwitches(root = process.cwd()) {
|
|
17
|
+
const file = switchesPath(root);
|
|
18
|
+
try {
|
|
19
|
+
const raw = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
20
|
+
if (!raw || typeof raw !== 'object') return emptyState();
|
|
21
|
+
if (!raw.members || typeof raw.members !== 'object') return emptyState();
|
|
22
|
+
return { members: raw.members };
|
|
23
|
+
} catch {
|
|
24
|
+
return emptyState();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function writeAtomicJson(file, value) {
|
|
29
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
30
|
+
const tmp = `${file}.${process.pid}.${Date.now()}.tmp`;
|
|
31
|
+
fs.writeFileSync(tmp, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
|
|
32
|
+
fs.renameSync(tmp, file);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function saveMemberSwitches(state, root = process.cwd()) {
|
|
36
|
+
const next = state && typeof state === 'object' ? state : emptyState();
|
|
37
|
+
if (!next.members || typeof next.members !== 'object') next.members = {};
|
|
38
|
+
writeAtomicJson(switchesPath(root), next);
|
|
39
|
+
return next;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function isLocalMember(name, root = process.cwd()) {
|
|
43
|
+
const slug = String(name || '').trim();
|
|
44
|
+
if (!slug || slug.startsWith('-')) return false;
|
|
45
|
+
if (!/^[a-zA-Z0-9._-]+$/.test(slug)) return false;
|
|
46
|
+
return fs.existsSync(path.join(root, 'atris', 'team', slug, 'MEMBER.md'));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function normalizeMemberEntry(entry) {
|
|
50
|
+
const base = entry && typeof entry === 'object' ? entry : {};
|
|
51
|
+
const loops = base.loops && typeof base.loops === 'object' ? { ...base.loops } : {};
|
|
52
|
+
return {
|
|
53
|
+
awake: base.awake !== false,
|
|
54
|
+
loops,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function getMemberSwitch(name, root = process.cwd()) {
|
|
59
|
+
const state = loadMemberSwitches(root);
|
|
60
|
+
return normalizeMemberEntry(state.members[name]);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function isMemberAwake(name, root = process.cwd()) {
|
|
64
|
+
return getMemberSwitch(name, root).awake !== false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function isMemberLoopAwake(name, loopId, root = process.cwd()) {
|
|
68
|
+
const entry = getMemberSwitch(name, root);
|
|
69
|
+
if (entry.awake === false) return false;
|
|
70
|
+
const id = String(loopId || '').trim();
|
|
71
|
+
if (!id) return entry.awake !== false;
|
|
72
|
+
if (Object.prototype.hasOwnProperty.call(entry.loops, id)) {
|
|
73
|
+
return entry.loops[id] !== false;
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function ensureMemberEntry(state, name) {
|
|
79
|
+
if (!state.members[name] || typeof state.members[name] !== 'object') {
|
|
80
|
+
state.members[name] = { awake: true, loops: {} };
|
|
81
|
+
}
|
|
82
|
+
if (!state.members[name].loops || typeof state.members[name].loops !== 'object') {
|
|
83
|
+
state.members[name].loops = {};
|
|
84
|
+
}
|
|
85
|
+
if (typeof state.members[name].awake !== 'boolean') {
|
|
86
|
+
state.members[name].awake = state.members[name].awake !== false;
|
|
87
|
+
}
|
|
88
|
+
return state.members[name];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function setMemberAwake(name, awake, root = process.cwd()) {
|
|
92
|
+
const state = loadMemberSwitches(root);
|
|
93
|
+
const entry = ensureMemberEntry(state, name);
|
|
94
|
+
entry.awake = awake !== false;
|
|
95
|
+
saveMemberSwitches(state, root);
|
|
96
|
+
return normalizeMemberEntry(entry);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function setMemberLoopAwake(name, loopId, awake, root = process.cwd()) {
|
|
100
|
+
const id = String(loopId || '').trim();
|
|
101
|
+
if (!id) throw new Error('loop id required');
|
|
102
|
+
const state = loadMemberSwitches(root);
|
|
103
|
+
const entry = ensureMemberEntry(state, name);
|
|
104
|
+
entry.loops[id] = awake !== false;
|
|
105
|
+
saveMemberSwitches(state, root);
|
|
106
|
+
return normalizeMemberEntry(entry);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function readLoopFlag(argv = process.argv) {
|
|
110
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
111
|
+
const arg = argv[i];
|
|
112
|
+
if (arg === '--loop') {
|
|
113
|
+
const value = argv[i + 1];
|
|
114
|
+
if (value && !String(value).startsWith('-')) return String(value).trim();
|
|
115
|
+
return '';
|
|
116
|
+
}
|
|
117
|
+
if (String(arg).startsWith('--loop=')) {
|
|
118
|
+
return String(arg).slice('--loop='.length).trim();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return '';
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function memberArgFromArgv(argv = process.argv) {
|
|
125
|
+
// atris sleep|wake <name> [--loop <id>]
|
|
126
|
+
const raw = argv[3];
|
|
127
|
+
if (!raw || String(raw).startsWith('-')) return null;
|
|
128
|
+
return String(raw).trim();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
module.exports = {
|
|
132
|
+
SWITCHES_REL,
|
|
133
|
+
switchesPath,
|
|
134
|
+
loadMemberSwitches,
|
|
135
|
+
saveMemberSwitches,
|
|
136
|
+
isLocalMember,
|
|
137
|
+
getMemberSwitch,
|
|
138
|
+
isMemberAwake,
|
|
139
|
+
isMemberLoopAwake,
|
|
140
|
+
setMemberAwake,
|
|
141
|
+
setMemberLoopAwake,
|
|
142
|
+
readLoopFlag,
|
|
143
|
+
memberArgFromArgv,
|
|
144
|
+
};
|
package/lib/memory-view.js
CHANGED
|
@@ -9,13 +9,18 @@
|
|
|
9
9
|
const fs = require('fs');
|
|
10
10
|
const path = require('path');
|
|
11
11
|
|
|
12
|
-
// "- **[2026-06-18] some-id** — pass — text..." -> { date, id, status, text }
|
|
12
|
+
// "- **[2026-06-18] some-id** — pass — text..." -> { date, id, status, text, resolved }
|
|
13
|
+
// A leading "[resolved]" marker (written when a lesson's detector passes) is
|
|
14
|
+
// stripped from the text and surfaced as `resolved` so the view can retire it.
|
|
13
15
|
function parseLessons(text) {
|
|
14
16
|
const out = [];
|
|
15
17
|
for (const line of String(text || '').split('\n')) {
|
|
16
18
|
const m = line.match(/^-\s*\*\*\[([^\]]+)\]\s*([^*]+?)\*\*\s*[—:-]*\s*(pass|fail)?\s*[—:-]*\s*(.*)$/i);
|
|
17
19
|
if (!m) continue;
|
|
18
|
-
|
|
20
|
+
let body = m[4].trim();
|
|
21
|
+
const resolved = /\[resolved\]/i.test(body);
|
|
22
|
+
body = body.replace(/\[resolved\]\s*/i, '').trim();
|
|
23
|
+
out.push({ date: m[1].trim(), id: m[2].trim(), status: (m[3] || '').toLowerCase(), text: body, resolved });
|
|
19
24
|
}
|
|
20
25
|
return out; // append-only file: oldest first
|
|
21
26
|
}
|
|
@@ -55,15 +60,18 @@ function buildMemorySpec(root = process.cwd(), opts = {}) {
|
|
|
55
60
|
const theme = opts.theme || 'atris';
|
|
56
61
|
const brand = { name: opts.brand || 'Atris', accent: '.' };
|
|
57
62
|
const { lessons, learnings, tasks } = gatherMemory(root);
|
|
63
|
+
const openLessons = lessons.filter((l) => !l.resolved);
|
|
64
|
+
const resolvedCount = lessons.length - openLessons.length;
|
|
58
65
|
const recent = lessons.slice(-8).reverse(); // newest first
|
|
59
66
|
|
|
67
|
+
const retired = resolvedCount ? `, ${plural(resolvedCount, 'lesson')} auto-resolved` : '';
|
|
60
68
|
const slides = [];
|
|
61
69
|
slides.push({
|
|
62
70
|
type: 'title',
|
|
63
71
|
headline: 'What the workspace **learned**',
|
|
64
|
-
sub: `${plural(
|
|
72
|
+
sub: `${plural(openLessons.length, 'open lesson')}${retired} and ${plural(learnings.length, 'note')} compounded into memory${tasks ? `, ${plural(tasks.done, 'task')} done` : ''}.`,
|
|
65
73
|
});
|
|
66
|
-
slides.push({ type: 'bignumber', number: String(
|
|
74
|
+
slides.push({ type: 'bignumber', number: String(openLessons.length), label: `open lessons${resolvedCount ? ` (${resolvedCount} retired)` : ''}` });
|
|
67
75
|
|
|
68
76
|
if (recent.length) {
|
|
69
77
|
slides.push({
|
|
@@ -76,7 +84,8 @@ function buildMemorySpec(root = process.cwd(), opts = {}) {
|
|
|
76
84
|
header: { title: 'Recent updates', meta: `${recent.length} shown` },
|
|
77
85
|
rows: recent.map((l, i) => ({
|
|
78
86
|
title: titleize(l.id), sub: l.date,
|
|
79
|
-
value: l.
|
|
87
|
+
value: l.resolved ? 'resolved' : (l.status || 'note'),
|
|
88
|
+
sev: l.resolved ? 2 : (l.status === 'fail' ? 0 : (l.status === 'pass' ? 2 : 1)),
|
|
80
89
|
active: i === 0,
|
|
81
90
|
})),
|
|
82
91
|
},
|
package/lib/mission-room.js
CHANGED
|
@@ -799,6 +799,7 @@ function writeMissionRoomReceipt(room, options = {}) {
|
|
|
799
799
|
schema: 'atris.mission_room_receipt.v1',
|
|
800
800
|
at: at.toISOString(),
|
|
801
801
|
product_wedge: 'Chaos -> Mission Room',
|
|
802
|
+
...(roomWithMemory.wish_id ? { wish_id: roomWithMemory.wish_id } : {}),
|
|
802
803
|
room: roomWithMemory,
|
|
803
804
|
thinking_memory: thinkingMemory,
|
|
804
805
|
receipt_path: relativePath,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { spawnSync } = require('child_process');
|
|
5
|
+
|
|
6
|
+
// The mission store lives at <workspace>/.atris/state. Historically every
|
|
7
|
+
// mission entry point defaulted its root to process.cwd(), so running any
|
|
8
|
+
// `atris mission ...` verb from a subdirectory (e.g. atris/features/food-ordering)
|
|
9
|
+
// silently created a NESTED .atris there — a second, split-brain mission store
|
|
10
|
+
// the fleet never reads. Resolve to the workspace root so mission state always
|
|
11
|
+
// lands there, whichever subdir the caller happened to be in.
|
|
12
|
+
//
|
|
13
|
+
// This delegates to the SAME resolver the task/usage/goal store uses
|
|
14
|
+
// (lib/task-db findWorkspaceRoot): a bound customer sub-workspace spine
|
|
15
|
+
// (.atris/business.json | atris/atris.md) wins, else the git toplevel, else the
|
|
16
|
+
// caller's cwd. Sharing one resolver keeps mission state and task state in the
|
|
17
|
+
// same root — previously mission used only the git toplevel, so a mission
|
|
18
|
+
// started inside a bound sub-workspace split away from that workspace's task
|
|
19
|
+
// state. A git worktree reports its own toplevel (its .git marker), which is
|
|
20
|
+
// the correct per-worktree store, so --worktree missions are unaffected. If the
|
|
21
|
+
// shared resolver can't load, fall back to the git toplevel, then to cwd.
|
|
22
|
+
function resolveWorkspaceRoot(cwd = process.cwd()) {
|
|
23
|
+
try {
|
|
24
|
+
const { workspaceRoot } = require('./task-db');
|
|
25
|
+
const root = workspaceRoot(cwd);
|
|
26
|
+
if (root) return root;
|
|
27
|
+
} catch {}
|
|
28
|
+
try {
|
|
29
|
+
const top = spawnSync('git', ['rev-parse', '--show-toplevel'], { cwd, encoding: 'utf8' });
|
|
30
|
+
const root = String(top.stdout || '').trim();
|
|
31
|
+
if (top.status === 0 && root) return root;
|
|
32
|
+
} catch {}
|
|
33
|
+
return cwd;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Chdir to the workspace root before any mission state is written, so a caller
|
|
37
|
+
// standing in a subdirectory does not spawn a nested .atris store. Only
|
|
38
|
+
// redirects when cwd is strictly INSIDE the resolved root (a subdirectory);
|
|
39
|
+
// if cwd already IS the root, or somehow sits outside it, nothing moves.
|
|
40
|
+
// Returns { from, root } when it redirected so the caller can warn loudly,
|
|
41
|
+
// or null when it left cwd untouched.
|
|
42
|
+
function redirectToWorkspaceRoot(cwd = process.cwd()) {
|
|
43
|
+
const from = path.resolve(cwd);
|
|
44
|
+
const root = path.resolve(resolveWorkspaceRoot(from));
|
|
45
|
+
if (root === from) return null;
|
|
46
|
+
const rel = path.relative(root, from);
|
|
47
|
+
if (!rel || rel.startsWith('..') || path.isAbsolute(rel)) return null;
|
|
48
|
+
process.chdir(root);
|
|
49
|
+
return { from, root };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = { resolveWorkspaceRoot, redirectToWorkspaceRoot };
|
|
@@ -57,7 +57,10 @@ function missionRunIntentFromMessage(message) {
|
|
|
57
57
|
rest = cadenceFlag.text;
|
|
58
58
|
const noRun = hasBooleanFlag(rest, '--no-run') || hasBooleanFlag(rest, '--no-loop');
|
|
59
59
|
const noComplete = hasBooleanFlag(rest, '--no-complete');
|
|
60
|
+
const forceRoomPreflight = hasBooleanFlag(rest, '--preflight') || hasBooleanFlag(rest, '--room-preflight');
|
|
61
|
+
const skipRoomPreflight = hasBooleanFlag(rest, '--no-preflight') || hasBooleanFlag(rest, '--no-room-preflight') || !forceRoomPreflight;
|
|
60
62
|
rest = stripBooleanFlag(stripBooleanFlag(stripBooleanFlag(rest, '--no-run'), '--no-loop'), '--no-complete');
|
|
63
|
+
rest = stripBooleanFlag(stripBooleanFlag(stripBooleanFlag(stripBooleanFlag(rest, '--preflight'), '--room-preflight'), '--no-preflight'), '--no-room-preflight');
|
|
61
64
|
rest = rest.replace(/(^|\s)--json(?=\s|$)/g, ' ').replace(/\s+/g, ' ').trim();
|
|
62
65
|
|
|
63
66
|
const wantsLongRun = /\b(24\s*h|24\s*hours?|overnight|forever)\b/i.test(text);
|
|
@@ -69,6 +72,8 @@ function missionRunIntentFromMessage(message) {
|
|
|
69
72
|
cadence: cadenceFlag.value || (wantsLongRun ? '15m' : ''),
|
|
70
73
|
noRun,
|
|
71
74
|
noComplete,
|
|
75
|
+
roomPreflight: forceRoomPreflight,
|
|
76
|
+
noRoomPreflight: skipRoomPreflight,
|
|
72
77
|
};
|
|
73
78
|
}
|
|
74
79
|
|
|
@@ -245,6 +250,8 @@ async function runRuntimeMissionLoop(intent, options = {}) {
|
|
|
245
250
|
|
|
246
251
|
const startArgs = ['mission', 'run', intent.objective, '--runner', 'atris2', '--owner', intent.owner || 'mission-lead', '--json'];
|
|
247
252
|
if (intent.cadence) startArgs.push('--cadence', intent.cadence);
|
|
253
|
+
if (intent.roomPreflight) startArgs.push('--room-preflight');
|
|
254
|
+
else if (intent.noRoomPreflight) startArgs.push('--no-room-preflight');
|
|
248
255
|
const start = runCliJsonSync(cliPath, startArgs, { cwd, timeoutMs: 30000 });
|
|
249
256
|
const result = { ok: start.ok, status: start.status, start, noRun: intent.noRun === true, achieved: false };
|
|
250
257
|
if (!start.ok || !start.payload?.mission?.id) {
|