atris 3.33.3 → 3.35.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.
Files changed (54) hide show
  1. package/AGENTS.md +0 -2
  2. package/FOR_AGENTS.md +5 -3
  3. package/atris/skills/engines/SKILL.md +16 -7
  4. package/atris/skills/render-cli/SKILL.md +88 -0
  5. package/atris.md +19 -0
  6. package/ax +475 -17
  7. package/bin/atris.js +206 -44
  8. package/commands/aeo.js +52 -0
  9. package/commands/autoland.js +313 -19
  10. package/commands/business.js +91 -8
  11. package/commands/codex-goal.js +26 -2
  12. package/commands/drive.js +187 -0
  13. package/commands/engine.js +73 -2
  14. package/commands/feed.js +202 -0
  15. package/commands/github.js +38 -0
  16. package/commands/gm.js +262 -3
  17. package/commands/init.js +13 -1
  18. package/commands/integrations.js +39 -11
  19. package/commands/interview.js +143 -0
  20. package/commands/land.js +114 -13
  21. package/commands/lesson.js +112 -1
  22. package/commands/linear.js +38 -0
  23. package/commands/loops.js +212 -0
  24. package/commands/member.js +398 -42
  25. package/commands/mission.js +598 -64
  26. package/commands/now.js +25 -1
  27. package/commands/radar.js +259 -14
  28. package/commands/serve.js +54 -0
  29. package/commands/status.js +50 -5
  30. package/commands/stripe.js +38 -0
  31. package/commands/supabase.js +39 -0
  32. package/commands/task.js +935 -71
  33. package/commands/truth.js +29 -3
  34. package/commands/unknowns.js +627 -0
  35. package/commands/update.js +44 -0
  36. package/commands/vercel.js +38 -0
  37. package/commands/worktree.js +68 -10
  38. package/commands/write.js +399 -0
  39. package/lib/auto-accept-certified.js +70 -19
  40. package/lib/autoland.js +39 -3
  41. package/lib/fleet.js +256 -13
  42. package/lib/memory-view.js +14 -5
  43. package/lib/mission-runtime-loop.js +7 -0
  44. package/lib/official-cli-integration.js +174 -0
  45. package/lib/outbound-send-gate.js +165 -0
  46. package/lib/permission-grants.js +293 -0
  47. package/lib/review-integrity.js +147 -0
  48. package/lib/runner-command.js +23 -0
  49. package/lib/task-db.js +220 -7
  50. package/lib/task-proof.js +20 -0
  51. package/lib/task-receipt.js +93 -0
  52. package/package.json +1 -1
  53. package/utils/update-check.js +27 -6
  54. package/atris/learnings.jsonl +0 -1
@@ -440,6 +440,170 @@ function memberRunOwnedActiveMissionId(name, missionMap) {
440
440
  return candidates[0]?.id || '';
441
441
  }
442
442
 
443
+ const MEMBER_LIVE_MISSION_STATUSES = new Set(['running', 'planning']);
444
+ const MEMBER_ACTIVE_ACTIVITY_MS = 24 * 60 * 60 * 1000;
445
+ const MEMBER_RECENT_ACTIVITY_MS = 72 * 60 * 60 * 1000;
446
+
447
+ function memberSlugFromRecord(member) {
448
+ if (member?.format === 'directory' && member.dir) return path.basename(member.dir);
449
+ if (member?.format === 'flat' && member.path) return path.basename(member.path, '.md');
450
+ return lowerCompact(member?.name || '');
451
+ }
452
+
453
+ function isFleetMember(member) {
454
+ if (!member || member.format !== 'directory') return false;
455
+ const slug = memberSlugFromRecord(member);
456
+ return Boolean(slug) && !new Set(['_archive', '_archived', '_template']).has(slug);
457
+ }
458
+
459
+ function missionTimeMs(mission) {
460
+ return Date.parse(mission?.last_tick_at || mission?.updated_at || mission?.created_at || '') || 0;
461
+ }
462
+
463
+ function memberOwnedMissions(name, missionMap = memberRunMissionMap()) {
464
+ const owner = lowerCompact(name);
465
+ return Array.from(missionMap.values())
466
+ .filter((mission) => lowerCompact(mission?.owner) === owner)
467
+ .sort((a, b) => missionTimeMs(b) - missionTimeMs(a));
468
+ }
469
+
470
+ function memberLatestMission(name, missionMap = memberRunMissionMap()) {
471
+ return memberOwnedMissions(name, missionMap)[0] || null;
472
+ }
473
+
474
+ function memberLiveMission(name, missionMap = memberRunMissionMap()) {
475
+ return memberOwnedMissions(name, missionMap)
476
+ .find((mission) => MEMBER_LIVE_MISSION_STATUSES.has(String(mission?.status || '').toLowerCase())) || null;
477
+ }
478
+
479
+ function missionShortName(mission, max = 36) {
480
+ return compactSentence(mission?.slug || mission?.title || mission?.objective || mission?.id || '', max) || '-';
481
+ }
482
+
483
+ function ageLabelFromMs(ms, nowMs = Date.now()) {
484
+ if (!ms) return '-';
485
+ const seconds = Math.max(0, Math.floor((nowMs - ms) / 1000));
486
+ if (seconds < 60) return 'now';
487
+ const minutes = Math.floor(seconds / 60);
488
+ if (minutes < 60) return `${minutes}m`;
489
+ const hours = Math.floor(minutes / 60);
490
+ if (hours < 48) return `${hours}h`;
491
+ return `${Math.floor(hours / 24)}d`;
492
+ }
493
+
494
+ function timestampMs(value) {
495
+ const ms = Date.parse(value || '');
496
+ return Number.isFinite(ms) ? ms : 0;
497
+ }
498
+
499
+ function newestMtimeRecursive(root) {
500
+ if (!fs.existsSync(root)) return 0;
501
+ let newest = 0;
502
+ const stack = [root];
503
+ while (stack.length) {
504
+ const current = stack.pop();
505
+ let stat = null;
506
+ try {
507
+ stat = fs.statSync(current);
508
+ } catch {
509
+ continue;
510
+ }
511
+ newest = Math.max(newest, stat.mtimeMs || 0);
512
+ if (!stat.isDirectory()) continue;
513
+ let entries = [];
514
+ try {
515
+ entries = fs.readdirSync(current);
516
+ } catch {
517
+ continue;
518
+ }
519
+ for (const entry of entries) stack.push(path.join(current, entry));
520
+ }
521
+ return newest;
522
+ }
523
+
524
+ function newestRunActivityMtime(name, root = process.cwd()) {
525
+ const runsDir = path.join(root, 'atris', 'runs');
526
+ if (!fs.existsSync(runsDir)) return 0;
527
+ const needle = lowerCompact(name);
528
+ let newest = 0;
529
+ for (const entry of fs.readdirSync(runsDir)) {
530
+ if (!lowerCompact(entry).includes(needle)) continue;
531
+ try {
532
+ newest = Math.max(newest, fs.statSync(path.join(runsDir, entry)).mtimeMs || 0);
533
+ } catch { /* ignore unreadable activity entries */ }
534
+ }
535
+ return newest;
536
+ }
537
+
538
+ function memberLastActivity(name, paths = memberPaths(name), root = process.cwd()) {
539
+ const logsMs = newestMtimeRecursive(path.join(paths.memberDir, 'logs'));
540
+ const runsMs = newestRunActivityMtime(name, root);
541
+ const ms = Math.max(logsMs, runsMs);
542
+ return {
543
+ at_ms: ms,
544
+ age: ageLabelFromMs(ms),
545
+ };
546
+ }
547
+
548
+ function memberMissionSummary(name, missionMap = memberRunMissionMap()) {
549
+ const latest = memberLatestMission(name, missionMap);
550
+ const live = memberLiveMission(name, missionMap);
551
+ const lastTickMs = timestampMs(latest?.last_tick_at);
552
+ return {
553
+ latest,
554
+ live,
555
+ name: missionShortName(latest),
556
+ state: latest?.status || '-',
557
+ last_tick_at: latest?.last_tick_at || null,
558
+ last_tick_age: ageLabelFromMs(lastTickMs),
559
+ live_mission: Boolean(live),
560
+ };
561
+ }
562
+
563
+ function memberVerdict({ mission, activity }, nowMs = Date.now()) {
564
+ const activityAge = activity?.at_ms ? nowMs - activity.at_ms : Number.POSITIVE_INFINITY;
565
+ if (mission?.live_mission || activityAge < MEMBER_ACTIVE_ACTIVITY_MS) return 'ACTIVE';
566
+ if (activityAge < MEMBER_RECENT_ACTIVITY_MS) return 'RECENT';
567
+ return 'IDLE';
568
+ }
569
+
570
+ function memberGoalPlaneStatus(name, paths = requireMemberDir(name)) {
571
+ const state = loadMemberGoals(name, paths);
572
+ const goal = activeGoal(state);
573
+ const current = memberOpenExperiment(state);
574
+ const lastReviewed = memberLastReviewedExperiment(state);
575
+ const value = memberValueSummary(state);
576
+ const logs = recentLogLines(paths.memberDir);
577
+ const needsUser = current?.status === 'blocked';
578
+ const stateLabel = !goal
579
+ ? 'no_goal'
580
+ : needsUser
581
+ ? 'needs_user'
582
+ : current
583
+ ? current.status
584
+ : 'ready';
585
+ const ask = needsUser ? (current.block?.ask || 'Needs operator input.') : null;
586
+ const nextCommand = !goal
587
+ ? `atris member goal ${name} "..."`
588
+ : needsUser
589
+ ? `atris member review ${name} ${current.id} --discard --proof "..."`
590
+ : current
591
+ ? `atris member review ${name} ${current.id} --accept --proof "..." --value 4`
592
+ : `atris member tick ${name}`;
593
+ return {
594
+ state,
595
+ goal,
596
+ current,
597
+ lastReviewed,
598
+ value,
599
+ logs,
600
+ needsUser,
601
+ stateLabel,
602
+ ask,
603
+ nextCommand,
604
+ };
605
+ }
606
+
443
607
  function resolveMemberRunMissionId(name, args = []) {
444
608
  const override = readFlag(args, '--mission', '') || readFlag(args, '--mission-id', '');
445
609
  if (override) return override;
@@ -3540,8 +3704,8 @@ function findAllMembers(teamDir) {
3540
3704
  const entries = fs.readdirSync(teamDir);
3541
3705
 
3542
3706
  for (const entry of entries) {
3543
- // Skip template directory and hidden files
3544
- if (entry === '_template' || entry.startsWith('.')) continue;
3707
+ // Skip template/archive directories and hidden files
3708
+ if (entry === '_template' || entry === '_archive' || entry === '_archived' || entry.startsWith('.')) continue;
3545
3709
 
3546
3710
  const fullPath = path.join(teamDir, entry);
3547
3711
  const stat = fs.statSync(fullPath);
@@ -6876,6 +7040,7 @@ function readMemberScope(name, paths) {
6876
7040
  function isAutoGeneratedArtifact(filePath, name) {
6877
7041
  const memberLogs = `atris/team/${name}/logs/`;
6878
7042
  if (filePath.startsWith(memberLogs)) return true;
7043
+ if (filePath === `atris/team/${name}/goals.json`) return true;
6879
7044
  if (filePath === `atris/team/${name}/now.md`) return true;
6880
7045
  return false;
6881
7046
  }
@@ -7431,11 +7596,105 @@ async function memberWake(name, ...args) {
7431
7596
  }
7432
7597
 
7433
7598
  function memberAlive(name, ...args) {
7599
+ if (name === '--all' || name === 'all') return memberAliveAll(...args);
7434
7600
  const nextArgs = args.includes('--alive') ? args : [...args, '--alive'];
7435
7601
  return memberLoop(name, ...nextArgs);
7436
7602
  }
7437
7603
 
7604
+ function collectFleetActivationRows(root = process.cwd()) {
7605
+ const teamDir = path.join(root, 'atris', 'team');
7606
+ const missionMap = memberRunMissionMap();
7607
+ return findAllMembers(teamDir)
7608
+ .filter(isFleetMember)
7609
+ .map((member) => {
7610
+ const slug = memberSlugFromRecord(member);
7611
+ const paths = memberPaths(slug);
7612
+ const goalPlane = memberGoalPlaneStatus(slug, paths);
7613
+ const activeMission = memberLiveMission(slug, missionMap);
7614
+ const latestMission = memberLatestMission(slug, missionMap);
7615
+ const skipped = !goalPlane.goal && !activeMission;
7616
+ return {
7617
+ member: slug,
7618
+ goal: goalPlane.goal || null,
7619
+ active_mission: activeMission || null,
7620
+ latest_mission: latestMission || null,
7621
+ skipped,
7622
+ skip_reason: skipped ? 'no_goal_and_no_active_mission' : null,
7623
+ };
7624
+ })
7625
+ .sort((a, b) => a.member.localeCompare(b.member));
7626
+ }
7627
+
7628
+ async function callMemberLoopForFleet(kind, member, args, captureOutput) {
7629
+ if (!captureOutput) {
7630
+ if (kind === 'alive') return memberAlive(member, ...args);
7631
+ return memberLoop(member, ...args);
7632
+ }
7633
+ const captured = [];
7634
+ const originalLog = console.log;
7635
+ console.log = (...parts) => captured.push(parts.join(' '));
7636
+ try {
7637
+ const result = kind === 'alive'
7638
+ ? await memberAlive(member, ...args)
7639
+ : await memberLoop(member, ...args);
7640
+ return { result, output: captured };
7641
+ } finally {
7642
+ console.log = originalLog;
7643
+ }
7644
+ }
7645
+
7646
+ async function memberLoopAll(kind, ...args) {
7647
+ const asJson = hasFlag(args, '--json');
7648
+ const rows = collectFleetActivationRows();
7649
+ const activated = [];
7650
+ const skipped = [];
7651
+ if (!asJson) console.log(`Member fleet ${kind}`);
7652
+ for (const row of rows) {
7653
+ if (row.skipped) {
7654
+ skipped.push(row);
7655
+ if (!asJson) console.log(`Skip ${row.member}: no goal and no active mission.`);
7656
+ continue;
7657
+ }
7658
+ if (!asJson) console.log(`Activate ${row.member}: ${row.goal ? 'goal' : `mission ${row.active_mission?.id || 'active'}`}`);
7659
+ const result = await callMemberLoopForFleet(kind, row.member, args, asJson);
7660
+ activated.push({
7661
+ member: row.member,
7662
+ reason: row.goal ? 'has_goal' : 'has_active_mission',
7663
+ mission_id: row.active_mission?.id || null,
7664
+ result: asJson ? result?.result || null : null,
7665
+ output: asJson ? result?.output || [] : undefined,
7666
+ });
7667
+ }
7668
+ const reasonCounts = skipped.reduce((acc, row) => {
7669
+ acc[row.skip_reason] = (acc[row.skip_reason] || 0) + 1;
7670
+ return acc;
7671
+ }, {});
7672
+ const payload = {
7673
+ ok: true,
7674
+ action: `${kind}_all`,
7675
+ activated: activated.length,
7676
+ skipped: skipped.length,
7677
+ skipped_reasons: reasonCounts,
7678
+ activated_members: activated,
7679
+ skipped_members: skipped.map((row) => ({
7680
+ member: row.member,
7681
+ reason: row.skip_reason,
7682
+ latest_mission_id: row.latest_mission?.id || null,
7683
+ latest_mission_status: row.latest_mission?.status || null,
7684
+ })),
7685
+ };
7686
+ printJsonOrText(payload, [
7687
+ `Summary: ${activated.length} activated, ${skipped.length} skipped (${Object.entries(reasonCounts).map(([reason, count]) => `${reason} x${count}`).join(', ') || 'none'}).`,
7688
+ ], asJson);
7689
+ return payload;
7690
+ }
7691
+
7692
+ function memberAliveAll(...args) {
7693
+ return memberLoopAll('alive', ...args);
7694
+ }
7695
+
7438
7696
  async function memberLoop(name, ...args) {
7697
+ if (name === '--all' || name === 'all') return memberLoopAll('loop', ...args);
7439
7698
  requireMemberDir(name);
7440
7699
  const asJson = hasFlag(args, '--json');
7441
7700
  const aliveMode = hasFlag(args, '--alive');
@@ -7962,44 +8221,136 @@ function memberBlock(name, experimentId, ...args) {
7962
8221
  );
7963
8222
  }
7964
8223
 
8224
+ function collectFleetMemberStatus(root = process.cwd()) {
8225
+ const teamDir = path.join(root, 'atris', 'team');
8226
+ const missionMap = memberRunMissionMap();
8227
+ return findAllMembers(teamDir)
8228
+ .filter(isFleetMember)
8229
+ .map((member) => {
8230
+ const slug = memberSlugFromRecord(member);
8231
+ const paths = memberPaths(slug);
8232
+ const goalPlane = memberGoalPlaneStatus(slug, paths);
8233
+ const mission = memberMissionSummary(slug, missionMap);
8234
+ const activity = memberLastActivity(slug, paths, root);
8235
+ const verdict = memberVerdict({ mission, activity });
8236
+ return {
8237
+ member: slug,
8238
+ role: member.role,
8239
+ goal_state: goalPlane.stateLabel,
8240
+ goal_title: goalPlane.goal?.title || null,
8241
+ mission: mission.latest ? {
8242
+ id: mission.latest.id || null,
8243
+ name: mission.name,
8244
+ state: mission.state,
8245
+ last_tick_at: mission.last_tick_at,
8246
+ last_tick_age: mission.last_tick_age,
8247
+ live: mission.live_mission,
8248
+ } : null,
8249
+ last_activity: activity,
8250
+ verdict,
8251
+ };
8252
+ })
8253
+ .sort((a, b) => a.member.localeCompare(b.member));
8254
+ }
8255
+
8256
+ function clipCell(value, width) {
8257
+ const clean = String(value || '-').replace(/\s+/g, ' ').trim() || '-';
8258
+ if (clean.length <= width) return clean.padEnd(width);
8259
+ if (width <= 3) return clean.slice(0, width);
8260
+ return `${clean.slice(0, width - 3)}...`;
8261
+ }
8262
+
8263
+ function renderMemberFleetStatusTable(rows) {
8264
+ if (!rows.length) return ['No active team members found in atris/team/.'];
8265
+ const widths = {
8266
+ member: 18,
8267
+ goal: 11,
8268
+ mission: 34,
8269
+ state: 10,
8270
+ tick: 8,
8271
+ activity: 8,
8272
+ verdict: 8,
8273
+ };
8274
+ const header = [
8275
+ clipCell('Member', widths.member),
8276
+ clipCell('Goal', widths.goal),
8277
+ clipCell('Mission', widths.mission),
8278
+ clipCell('State', widths.state),
8279
+ clipCell('Tick', widths.tick),
8280
+ clipCell('Activity', widths.activity),
8281
+ clipCell('Verdict', widths.verdict),
8282
+ ].join(' ');
8283
+ const rule = [
8284
+ '-'.repeat(widths.member),
8285
+ '-'.repeat(widths.goal),
8286
+ '-'.repeat(widths.mission),
8287
+ '-'.repeat(widths.state),
8288
+ '-'.repeat(widths.tick),
8289
+ '-'.repeat(widths.activity),
8290
+ '-'.repeat(widths.verdict),
8291
+ ].join(' ');
8292
+ return [
8293
+ 'Member fleet status',
8294
+ header,
8295
+ rule,
8296
+ ...rows.map((row) => [
8297
+ clipCell(row.member, widths.member),
8298
+ clipCell(row.goal_state, widths.goal),
8299
+ clipCell(row.mission?.name || '-', widths.mission),
8300
+ clipCell(row.mission?.state || '-', widths.state),
8301
+ clipCell(row.mission?.last_tick_age || '-', widths.tick),
8302
+ clipCell(row.last_activity?.age || '-', widths.activity),
8303
+ clipCell(row.verdict, widths.verdict),
8304
+ ].join(' ')),
8305
+ ];
8306
+ }
8307
+
8308
+ function memberStatusAll(...args) {
8309
+ const asJson = hasFlag(args, '--json');
8310
+ const rows = collectFleetMemberStatus();
8311
+ printJsonOrText(
8312
+ {
8313
+ ok: true,
8314
+ action: 'status_all',
8315
+ members: rows,
8316
+ },
8317
+ renderMemberFleetStatusTable(rows),
8318
+ asJson,
8319
+ );
8320
+ }
8321
+
7965
8322
  function memberStatus(name, ...args) {
8323
+ if (name === '--all' || name === 'all') return memberStatusAll(...args);
7966
8324
  const paths = requireMemberDir(name);
7967
8325
  const asJson = hasFlag(args, '--json');
7968
- const state = loadMemberGoals(name, paths);
7969
- const goal = activeGoal(state);
7970
- const current = memberOpenExperiment(state);
7971
- const lastReviewed = memberLastReviewedExperiment(state);
7972
- const value = memberValueSummary(state);
7973
- const logs = recentLogLines(paths.memberDir);
7974
- const needsUser = current?.status === 'blocked';
7975
- const stateLabel = !goal
7976
- ? 'no_goal'
7977
- : needsUser
7978
- ? 'needs_user'
7979
- : current
7980
- ? current.status
7981
- : 'ready';
7982
- const ask = needsUser ? (current.block?.ask || 'Needs operator input.') : null;
7983
- const nextCommand = !goal
7984
- ? `atris member goal ${name} "..."`
7985
- : needsUser
7986
- ? `atris member review ${name} ${current.id} --discard --proof "..."`
7987
- : current
7988
- ? `atris member review ${name} ${current.id} --accept --proof "..." --value 4`
7989
- : `atris member tick ${name}`;
8326
+ const goalPlane = memberGoalPlaneStatus(name, paths);
8327
+ const owner = paths.storageName || name;
8328
+ const mission = memberMissionSummary(owner, memberRunMissionMap());
8329
+ const activity = memberLastActivity(owner, paths);
8330
+ const verdict = memberVerdict({ mission, activity });
7990
8331
  const payload = {
7991
8332
  ok: true,
7992
8333
  action: 'status',
7993
8334
  member: name,
7994
- state: stateLabel,
7995
- needs_user: needsUser,
7996
- ask,
7997
- active_goal: goal || null,
7998
- current_experiment: current || null,
7999
- last_reviewed: lastReviewed || null,
8000
- value,
8001
- next_command: nextCommand,
8002
- recent_log: logs,
8335
+ state: goalPlane.stateLabel,
8336
+ needs_user: goalPlane.needsUser,
8337
+ ask: goalPlane.ask,
8338
+ active_goal: goalPlane.goal || null,
8339
+ current_experiment: goalPlane.current || null,
8340
+ last_reviewed: goalPlane.lastReviewed || null,
8341
+ value: goalPlane.value,
8342
+ mission: mission.latest ? {
8343
+ id: mission.latest.id || null,
8344
+ name: mission.name,
8345
+ state: mission.state,
8346
+ last_tick_at: mission.last_tick_at,
8347
+ last_tick_age: mission.last_tick_age,
8348
+ live: mission.live_mission,
8349
+ } : null,
8350
+ last_activity: activity,
8351
+ verdict,
8352
+ next_command: goalPlane.nextCommand,
8353
+ recent_log: goalPlane.logs,
8003
8354
  goals_path: paths.goalsJson,
8004
8355
  goals_md_path: paths.goalsMd,
8005
8356
  };
@@ -8007,13 +8358,16 @@ function memberStatus(name, ...args) {
8007
8358
  payload,
8008
8359
  [
8009
8360
  `Member: ${name}`,
8010
- `State: ${stateLabel}`,
8011
- `Goal: ${goal?.title || 'No goal yet'}`,
8012
- `Current: ${current ? `${current.status} - ${current.title}` : 'No open experiment'}`,
8013
- ...(ask ? [`Ask: ${ask}`] : []),
8014
- `Value: ${value.line}`,
8015
- `Next: ${nextCommand}`,
8016
- ...(logs.length ? ['Recent log:', ...logs.map((line) => ` ${line}`)] : []),
8361
+ `State: ${goalPlane.stateLabel}`,
8362
+ `Goal: ${goalPlane.goal?.title || 'No goal yet'}`,
8363
+ `Current: ${goalPlane.current ? `${goalPlane.current.status} - ${goalPlane.current.title}` : 'No open experiment'}`,
8364
+ ...(goalPlane.ask ? [`Ask: ${goalPlane.ask}`] : []),
8365
+ `Value: ${goalPlane.value.line}`,
8366
+ `Mission: ${mission.latest ? `${mission.name} (${mission.state}, last tick ${mission.last_tick_age})` : 'No owned mission'}`,
8367
+ `Activity: ${activity.age}`,
8368
+ `Verdict: ${verdict}`,
8369
+ `Next: ${goalPlane.nextCommand}`,
8370
+ ...(goalPlane.logs.length ? ['Recent log:', ...goalPlane.logs.map((line) => ` ${line}`)] : []),
8017
8371
  ],
8018
8372
  asJson,
8019
8373
  );
@@ -8186,11 +8540,11 @@ async function memberCommand(subcommand, ...args) {
8186
8540
  console.log(' goal-from-score <name> Create/reuse an active goal from Team score evidence');
8187
8541
  console.log(' wake <name> Read Mission state and decide tick/wait/ask/stop');
8188
8542
  console.log(' run <name> ["..."] Start a budgeted member mission, or run its active Mission Runtime');
8189
- console.log(' loop <name> Repeat wake on a bounded cadence with a no-overlap lease');
8543
+ console.log(' loop <name|--all> Repeat wake on a bounded cadence with a no-overlap lease');
8190
8544
  console.log(' tick <name> Propose the next bounded experiment');
8191
8545
  console.log(' review <name> <id> Accept/discard an experiment with proof');
8192
8546
  console.log(' block <name> <id> Mark an experiment blocked with a human/orchestrator ask');
8193
- console.log(' status <name> Show goal, open experiment, value, ask, and recent log');
8547
+ console.log(' status <name|--all> Show goal, mission, activity, value, ask, and recent log');
8194
8548
  console.log(' history <name> Show git history of member identity files (MEMBER.md, SOUL.md)');
8195
8549
  console.log(' supervisor recommendations Show advisory supervisor recommendations');
8196
8550
  console.log(' objective-generator proposals Show autonomous objective proposal');
@@ -8225,10 +8579,12 @@ async function memberCommand(subcommand, ...args) {
8225
8579
  console.log(' atris member loop growth --minutes 10 --interval 60 --json');
8226
8580
  console.log(' atris member alive growth --hourly --forever --execute --confirm-autonomy-policy --json');
8227
8581
  console.log(' atris member alive growth --install --hourly --forever --execute --confirm-autonomy-policy --json');
8582
+ console.log(' atris member alive --all --install --hourly --forever --dry-run');
8228
8583
  console.log(' atris member alive growth --minutes 480 --interval 900 --execute --confirm-autonomy-policy --json');
8229
8584
  console.log(' atris member loop growth --ticks 2 --interval 0 --json');
8230
8585
  console.log(' atris member tick growth --json');
8231
8586
  console.log(' atris member status growth');
8587
+ console.log(' atris member status --all');
8232
8588
  console.log(' atris member review growth exp_123 --accept --proof "validated" --value 4');
8233
8589
  console.log(' atris member archive old-member');
8234
8590
  console.log(' atris member purge-archived --days=60 --confirm "delete archived members"');