atris 3.15.14 → 3.15.22
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 +84 -8
- package/README.md +5 -1
- package/atris/AGENTS.md +46 -1
- package/atris/CLAUDE.md +36 -1
- package/atris/GEMINI.md +14 -1
- package/atris/atris.md +12 -1
- package/atris/atrisDev.md +3 -2
- package/atris/context/README.md +11 -0
- package/atris/features/company-brain-sync/validate.md +5 -5
- package/atris/learnings.jsonl +1 -0
- package/atris/policies/atris-design.md +2 -0
- package/atris/skills/aeo/SKILL.md +2 -2
- package/atris/skills/atris/SKILL.md +15 -62
- package/atris/skills/design/SKILL.md +2 -0
- package/atris/skills/imessage/SKILL.md +19 -2
- package/atris/skills/loop/SKILL.md +6 -5
- package/atris/skills/magic-inbox/SKILL.md +1 -1
- package/atris/team/_template/MEMBER.md +23 -1
- package/atris/team/brainstormer/START_HERE.md +6 -0
- package/atris/team/executor/MEMBER.md +13 -0
- package/atris/team/executor/START_HERE.md +6 -0
- package/atris/team/launcher/START_HERE.md +6 -0
- package/atris/team/mission-lead/MEMBER.md +39 -0
- package/atris/team/mission-lead/MISSION.md +33 -0
- package/atris/team/mission-lead/START_HERE.md +6 -0
- package/atris/team/navigator/MEMBER.md +11 -0
- package/atris/team/navigator/START_HERE.md +6 -0
- package/atris/team/opus-overnight/MEMBER.md +39 -0
- package/atris/team/opus-overnight/MISSION.md +61 -0
- package/atris/team/opus-overnight/START_HERE.md +6 -0
- package/atris/team/opus-overnight/STEERING.md +35 -0
- package/atris/team/researcher/START_HERE.md +6 -0
- package/atris/team/validator/MEMBER.md +26 -6
- package/atris/team/validator/START_HERE.md +6 -0
- package/atris/wiki/concepts/agent-activation-contract.md +79 -0
- package/atris/wiki/concepts/workspace-initialization-contract.md +73 -0
- package/atris/wiki/index.md +27 -0
- package/atris/wiki/sources/atris-labs-2026-05-10.txt +17 -0
- package/atris/wiki/sources/atris-labs-goals-2026-05-10.txt +15 -0
- package/atris/wiki/sources/atrisos-generative-ui-product-surface-2026-05-10.txt +10 -0
- package/atris/wiki/sources/jack-dorsey-2026-05-10.txt +12 -0
- package/atris.md +49 -13
- package/bin/atris.js +660 -22
- package/commands/activate.js +12 -3
- package/commands/aeo.js +1 -1
- package/commands/align.js +10 -10
- package/commands/analytics.js +9 -4
- package/commands/app.js +2 -0
- package/commands/apps.js +276 -0
- package/commands/auth.js +1 -1
- package/commands/autopilot.js +74 -5
- package/commands/brain.js +536 -61
- package/commands/brainstorm.js +12 -12
- package/commands/business-sync.js +142 -24
- package/commands/clean.js +9 -6
- package/commands/codex-goal.js +311 -0
- package/commands/errors.js +11 -1
- package/commands/feedback.js +55 -17
- package/commands/fork.js +2 -2
- package/commands/gm.js +376 -0
- package/commands/init.js +80 -3
- package/commands/integrations.js +524 -0
- package/commands/learn.js +25 -16
- package/commands/lesson.js +41 -0
- package/commands/lifecycle.js +2 -2
- package/commands/member.js +2416 -9
- package/commands/mission.js +1776 -0
- package/commands/now.js +48 -7
- package/commands/play.js +425 -0
- package/commands/publish.js +2 -1
- package/commands/pull.js +72 -29
- package/commands/push.js +163 -18
- package/commands/review.js +51 -13
- package/commands/skill.js +2 -2
- package/commands/soul.js +19 -13
- package/commands/status.js +6 -1
- package/commands/sync.js +5 -4
- package/commands/task.js +1041 -147
- package/commands/terminal.js +5 -5
- package/commands/verify.js +7 -5
- package/commands/visualize.js +7 -0
- package/commands/wiki.js +53 -16
- package/commands/workflow.js +298 -54
- package/commands/workspace-clean.js +1 -1
- package/commands/worktree.js +468 -0
- package/commands/xp.js +1608 -0
- package/lib/manifest.js +34 -4
- package/lib/scorecard.js +3 -2
- package/lib/task-db.js +408 -27
- package/lib/todo-fallback.js +28 -2
- package/lib/todo.js +5 -3
- package/package.json +23 -2
- package/utils/update-check.js +51 -1
package/bin/atris.js
CHANGED
|
@@ -26,7 +26,13 @@ try {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
// Update check utility
|
|
29
|
-
const {
|
|
29
|
+
const {
|
|
30
|
+
checkForUpdates,
|
|
31
|
+
showUpdateNotification,
|
|
32
|
+
autoUpdate,
|
|
33
|
+
inspectInstallGitState,
|
|
34
|
+
formatInstallGitWarning,
|
|
35
|
+
} = require('../utils/update-check');
|
|
30
36
|
|
|
31
37
|
// State detection for smart default
|
|
32
38
|
const { detectWorkspaceState, loadContext } = require('../lib/state-detection');
|
|
@@ -62,10 +68,18 @@ const fetchMyAgents = (token) => _fetchMyAgents(token, apiRequestJson);
|
|
|
62
68
|
const displayAccountSummary = () => _displayAccountSummary(apiRequestJson);
|
|
63
69
|
|
|
64
70
|
// Run update check in background (non-blocking)
|
|
65
|
-
// Skip for 'version'
|
|
71
|
+
// Skip for 'version', 'update', and help commands to avoid redundant messages or help side effects.
|
|
66
72
|
let updateCheckPromise = null;
|
|
67
|
-
const
|
|
68
|
-
|
|
73
|
+
const updateCommand = process.argv[2];
|
|
74
|
+
const updateArgs = process.argv.slice(3);
|
|
75
|
+
const helpRequested = updateCommand === 'help'
|
|
76
|
+
|| updateCommand === '--help'
|
|
77
|
+
|| updateCommand === '-h'
|
|
78
|
+
|| updateArgs.includes('--help')
|
|
79
|
+
|| updateArgs.includes('-h')
|
|
80
|
+
|| updateArgs[0] === 'help';
|
|
81
|
+
const skipUpdateCheck = Boolean(process.env.ATRIS_SKIP_UPDATE_CHECK || process.env.NO_UPDATE_NOTIFIER || helpRequested);
|
|
82
|
+
if (!skipUpdateCheck && (!updateCommand || (updateCommand && !['version', 'update'].includes(updateCommand)))) {
|
|
69
83
|
updateCheckPromise = checkForUpdates()
|
|
70
84
|
.then((updateInfo) => {
|
|
71
85
|
// Show notification if update available (after command completes)
|
|
@@ -103,6 +117,15 @@ const isBusinessSyncSafetyCommand = command === 'sync'
|
|
|
103
117
|
|| firstCommandArg === 'resolve'
|
|
104
118
|
);
|
|
105
119
|
|
|
120
|
+
// Keep APP.md app-pack operations independent from the heavier workspace boot
|
|
121
|
+
// path so `atris apps --json` stays machine-readable for agents.
|
|
122
|
+
if (command === 'apps') {
|
|
123
|
+
const subcommand = process.argv[3];
|
|
124
|
+
const args = process.argv.slice(4);
|
|
125
|
+
require('../commands/apps').appsCommand(subcommand, ...args);
|
|
126
|
+
process.exit(0);
|
|
127
|
+
}
|
|
128
|
+
|
|
106
129
|
// Auto-sync skills only for commands that modify workspace state
|
|
107
130
|
if (['init', 'update', 'upgrade'].includes(command) || (command === 'sync' && !isBusinessSyncSafetyCommand)) {
|
|
108
131
|
try {
|
|
@@ -116,10 +139,68 @@ if (['init', 'update', 'upgrade'].includes(command) || (command === 'sync' && !i
|
|
|
116
139
|
}
|
|
117
140
|
}
|
|
118
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Load active missions from .atris/state/missions.jsonl (append-only event log).
|
|
144
|
+
* Walks lines in reverse, deduping by mission id, returns missions whose latest
|
|
145
|
+
* record has status in {ready, running, planning} sorted newest-first.
|
|
146
|
+
*
|
|
147
|
+
* Each mission: { id, owner, objective, status, verifier, verifier_passed, next_action, lane }.
|
|
148
|
+
*
|
|
149
|
+
* Returns [] if file missing or malformed — never throws.
|
|
150
|
+
*/
|
|
151
|
+
function loadActiveMissions(workspaceDir) {
|
|
152
|
+
try {
|
|
153
|
+
const file = path.join(workspaceDir, '.atris', 'state', 'missions.jsonl');
|
|
154
|
+
if (!fs.existsSync(file)) return [];
|
|
155
|
+
const lines = fs.readFileSync(file, 'utf8').split('\n').filter(Boolean);
|
|
156
|
+
const seen = new Map(); // id -> mission record
|
|
157
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
158
|
+
let rec;
|
|
159
|
+
try { rec = JSON.parse(lines[i]); } catch { continue; }
|
|
160
|
+
const id = rec.id || rec.mission_id;
|
|
161
|
+
if (!id || seen.has(id)) continue;
|
|
162
|
+
seen.set(id, rec);
|
|
163
|
+
}
|
|
164
|
+
const live = [];
|
|
165
|
+
for (const m of seen.values()) {
|
|
166
|
+
const status = m.status;
|
|
167
|
+
if (!['ready', 'running', 'planning'].includes(status)) continue;
|
|
168
|
+
live.push({
|
|
169
|
+
id: m.id || m.mission_id,
|
|
170
|
+
owner: m.owner || '?',
|
|
171
|
+
objective: m.objective || '',
|
|
172
|
+
status,
|
|
173
|
+
verifier: m.verifier || null,
|
|
174
|
+
verifier_passed: (m.verifier_result && m.verifier_result.passed) === true,
|
|
175
|
+
next_action: m.next_action || '',
|
|
176
|
+
lane: m.lane || null,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
// Most recently started first (rough — relies on insertion order from reversed walk)
|
|
180
|
+
return live;
|
|
181
|
+
} catch {
|
|
182
|
+
return [];
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function showSearchHelp() {
|
|
187
|
+
console.log('Usage: atris search <keyword>');
|
|
188
|
+
console.log('Example: atris search auth');
|
|
189
|
+
}
|
|
190
|
+
|
|
119
191
|
function searchJournal(keyword) {
|
|
120
192
|
if (!keyword) {
|
|
121
|
-
|
|
122
|
-
|
|
193
|
+
showSearchHelp();
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (keyword === '--help' || keyword === '-h') {
|
|
198
|
+
showSearchHelp();
|
|
199
|
+
process.exit(0);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (process.argv.slice(4).includes('--help') || process.argv.slice(4).includes('-h')) {
|
|
203
|
+
showSearchHelp();
|
|
123
204
|
process.exit(1);
|
|
124
205
|
}
|
|
125
206
|
|
|
@@ -253,14 +334,17 @@ function showHelp() {
|
|
|
253
334
|
console.log(' now - Show atris/now.md, the current operating truth');
|
|
254
335
|
console.log(' activate - Load Atris context');
|
|
255
336
|
console.log(' status - See local work and completions (`atris status <business>` for remote)');
|
|
337
|
+
console.log(' xp - Show Career XP and contribution graph');
|
|
256
338
|
console.log(' analytics - Show recent productivity from journals');
|
|
257
339
|
console.log(' search - Search journal history (atris search <keyword>)');
|
|
258
340
|
console.log(' clean - Housekeeping (stale tasks, archive journals, broken refs)');
|
|
259
341
|
console.log(' verify - Validate work is done (tests, MAP.md, changes)');
|
|
260
342
|
console.log(' task - Local agent task plane (atomic claims, TODO import)');
|
|
343
|
+
console.log(' mission - Goal + loop + member owner + verifier + receipt');
|
|
261
344
|
console.log(' release - Tag release, bump version, create GitHub release, draft /launch');
|
|
262
345
|
console.log(' learn - Project learnings (patterns, pitfalls, preferences)');
|
|
263
346
|
console.log(' brain - Compile MAP/TODO/wiki/state into a loadable agent brain');
|
|
347
|
+
console.log(' lesson - Append a one-line lesson to atris/lessons.md');
|
|
264
348
|
console.log(' ingest - Local-first wiki ingest into atris/wiki/');
|
|
265
349
|
console.log(' query - Local-first wiki query against atris/wiki/');
|
|
266
350
|
console.log(' lint - Local-first wiki lint for atris/wiki/');
|
|
@@ -269,6 +353,7 @@ function showHelp() {
|
|
|
269
353
|
console.log('Optional helpers:');
|
|
270
354
|
console.log(' brainstorm - Explore ideas conversationally before planning');
|
|
271
355
|
console.log(' autopilot - Guided loop that can clarify TODOs and run plan → do → review');
|
|
356
|
+
console.log(' worktree - Isolated Git worktrees plus guarded ship/merge for parallel agents');
|
|
272
357
|
console.log(' visualize - Generate a Slack/deck-ready visual from a prompt');
|
|
273
358
|
console.log('');
|
|
274
359
|
console.log('Experiments:');
|
|
@@ -319,7 +404,7 @@ function showHelp() {
|
|
|
319
404
|
console.log(' console - Start/attach always-on coding console (tmux daemon)');
|
|
320
405
|
console.log(' soul - Show, snapshot, or fork workspace identity');
|
|
321
406
|
console.log(' fleet - Inspect local fleet status');
|
|
322
|
-
console.log(' agent - Select
|
|
407
|
+
console.log(' agent - Select cloud agent, or run `agent doctor` for local CLI wiring');
|
|
323
408
|
console.log(' chat - Chat with the selected Atris agent');
|
|
324
409
|
console.log(' login - Sign in or add another account');
|
|
325
410
|
console.log(' logout - Sign out of current account');
|
|
@@ -333,7 +418,7 @@ function showHelp() {
|
|
|
333
418
|
console.log(' calendar - Calendar commands (today, week)');
|
|
334
419
|
console.log(' twitter - Twitter commands (post)');
|
|
335
420
|
console.log(' slack - Slack commands (channels)');
|
|
336
|
-
console.log(' imessage - Local Mac iMessage commands (doctor, recent)');
|
|
421
|
+
console.log(' imessage - Local Mac iMessage commands (doctor, lookup, recent, send)');
|
|
337
422
|
console.log(' integrations - Show integration status');
|
|
338
423
|
console.log('');
|
|
339
424
|
console.log('Skills:');
|
|
@@ -418,6 +503,216 @@ function showReviewHelp() {
|
|
|
418
503
|
console.log('');
|
|
419
504
|
}
|
|
420
505
|
|
|
506
|
+
function showStatusHelp() {
|
|
507
|
+
console.log('');
|
|
508
|
+
console.log('Usage: atris status [--quick] [--json] [--verbose]');
|
|
509
|
+
console.log('');
|
|
510
|
+
console.log('Description:');
|
|
511
|
+
console.log(' Show the local Atris workspace task, inbox, completion, lesson, and team status.');
|
|
512
|
+
console.log('');
|
|
513
|
+
console.log('Options:');
|
|
514
|
+
console.log(' --quick, -q Print one compact status line.');
|
|
515
|
+
console.log(' --json Print machine-readable workspace status.');
|
|
516
|
+
console.log(' --verbose, -v Print the legacy visual task board.');
|
|
517
|
+
console.log(' --help, -h Show this help.');
|
|
518
|
+
console.log('');
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
function showAnalyticsHelp() {
|
|
522
|
+
console.log('');
|
|
523
|
+
console.log('Usage: atris analytics');
|
|
524
|
+
console.log('');
|
|
525
|
+
console.log('Description:');
|
|
526
|
+
console.log(' Summarize local journal completions, inbox trend, and activity patterns.');
|
|
527
|
+
console.log('');
|
|
528
|
+
console.log('Options:');
|
|
529
|
+
console.log(' --help, -h Show this help.');
|
|
530
|
+
console.log('');
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
function showActivateHelp() {
|
|
534
|
+
console.log('');
|
|
535
|
+
console.log('Usage: atris activate');
|
|
536
|
+
console.log('');
|
|
537
|
+
console.log('Description:');
|
|
538
|
+
console.log(' Load workspace context, recent completions, TODO, MAP, journal, and wiki status.');
|
|
539
|
+
console.log('');
|
|
540
|
+
console.log('Options:');
|
|
541
|
+
console.log(' --help, -h Show this help.');
|
|
542
|
+
console.log('');
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
function showNextHelp(commandName = 'next') {
|
|
546
|
+
console.log('');
|
|
547
|
+
console.log(`Usage: atris ${commandName} [request]`);
|
|
548
|
+
console.log('');
|
|
549
|
+
console.log('Description:');
|
|
550
|
+
console.log(' Auto-advance to the next workflow step, or route a request through the Atris entry.');
|
|
551
|
+
console.log('');
|
|
552
|
+
console.log('Options:');
|
|
553
|
+
console.log(' --help, -h Show this help.');
|
|
554
|
+
console.log('');
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
function showVerifyHelp() {
|
|
558
|
+
console.log('');
|
|
559
|
+
console.log('Usage: atris verify [task]');
|
|
560
|
+
console.log('Usage: atris verify <feature-slug> --section <name>');
|
|
561
|
+
console.log('');
|
|
562
|
+
console.log('Description:');
|
|
563
|
+
console.log(' Validate workspace health, a specific task, or a feature rubric section.');
|
|
564
|
+
console.log('');
|
|
565
|
+
console.log('Options:');
|
|
566
|
+
console.log(' --section <name> Run a fenced bash check from atris/features/<slug>/validate.md.');
|
|
567
|
+
console.log(' --help, -h Show this help.');
|
|
568
|
+
console.log('');
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
function showUpdateHelp(commandName = 'update') {
|
|
572
|
+
console.log('');
|
|
573
|
+
console.log(`Usage: atris ${commandName} [--all] [--dry-run] [--force]`);
|
|
574
|
+
console.log('');
|
|
575
|
+
console.log('Description:');
|
|
576
|
+
console.log(' Sync Atris workspace files from the installed CLI templates.');
|
|
577
|
+
console.log('');
|
|
578
|
+
console.log('Options:');
|
|
579
|
+
console.log(' --all Update Atris files across projects under the current tree.');
|
|
580
|
+
console.log(' --dry-run Preview update work without writing files.');
|
|
581
|
+
console.log(' --force Overwrite existing template files where supported.');
|
|
582
|
+
console.log(' --help, -h Show this help.');
|
|
583
|
+
console.log('');
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
function showUpgradeHelp() {
|
|
587
|
+
console.log('');
|
|
588
|
+
console.log('Usage: atris upgrade');
|
|
589
|
+
console.log('');
|
|
590
|
+
console.log('Description:');
|
|
591
|
+
console.log(' Check npm for the latest Atris CLI and install it globally if newer.');
|
|
592
|
+
console.log('');
|
|
593
|
+
console.log('Options:');
|
|
594
|
+
console.log(' --help, -h Show this help.');
|
|
595
|
+
console.log('');
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
function showReleaseHelp() {
|
|
599
|
+
console.log('');
|
|
600
|
+
console.log('Usage: atris release [--dry-run]');
|
|
601
|
+
console.log('');
|
|
602
|
+
console.log('Description:');
|
|
603
|
+
console.log(' Draft or publish a release from local git history.');
|
|
604
|
+
console.log('');
|
|
605
|
+
console.log('Options:');
|
|
606
|
+
console.log(' --dry-run Print the planned release without committing, tagging, or pushing.');
|
|
607
|
+
console.log(' --help, -h Show this help.');
|
|
608
|
+
console.log('');
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
function showAuthHelp(commandName) {
|
|
612
|
+
const usage = {
|
|
613
|
+
login: 'Usage: atris login [--token <token>] [--force]',
|
|
614
|
+
logout: 'Usage: atris logout',
|
|
615
|
+
whoami: 'Usage: atris whoami',
|
|
616
|
+
switch: 'Usage: atris switch [account] [--global]',
|
|
617
|
+
use: 'Usage: atris use [account]',
|
|
618
|
+
accounts: 'Usage: atris accounts [add|remove <account>|remove --all]',
|
|
619
|
+
}[commandName] || 'Usage: atris login|logout|whoami';
|
|
620
|
+
console.log('');
|
|
621
|
+
console.log(usage);
|
|
622
|
+
console.log('');
|
|
623
|
+
console.log('Description:');
|
|
624
|
+
if (commandName === 'login') {
|
|
625
|
+
console.log(' Sign in with browser OAuth or a pasted API token.');
|
|
626
|
+
} else if (commandName === 'logout') {
|
|
627
|
+
console.log(' Sign out of the current Atris account.');
|
|
628
|
+
} else if (commandName === 'whoami') {
|
|
629
|
+
console.log(' Show the active Atris account.');
|
|
630
|
+
} else if (commandName === 'switch') {
|
|
631
|
+
console.log(' Switch the active account globally or for this terminal session.');
|
|
632
|
+
} else if (commandName === 'use') {
|
|
633
|
+
console.log(' Print an ATRIS_PROFILE export for per-terminal account use.');
|
|
634
|
+
} else if (commandName === 'accounts') {
|
|
635
|
+
console.log(' List, add, or remove saved Atris accounts.');
|
|
636
|
+
}
|
|
637
|
+
console.log('');
|
|
638
|
+
console.log('Options:');
|
|
639
|
+
if (commandName === 'login') {
|
|
640
|
+
console.log(' --token <token> Save an API token without prompting.');
|
|
641
|
+
console.log(' --force, -f Re-run login even if credentials already exist.');
|
|
642
|
+
} else if (commandName === 'switch') {
|
|
643
|
+
console.log(' --global, -g Switch the account for all terminals.');
|
|
644
|
+
}
|
|
645
|
+
console.log(' --help, -h Show this help.');
|
|
646
|
+
console.log('');
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
function showIntegrationsHelp() {
|
|
650
|
+
console.log('');
|
|
651
|
+
console.log('Usage: atris integrations');
|
|
652
|
+
console.log('');
|
|
653
|
+
console.log('Description:');
|
|
654
|
+
console.log(' Show connection status for Gmail, Calendar, Slack, Twitter, GitHub, and iMessage.');
|
|
655
|
+
console.log('');
|
|
656
|
+
console.log('Options:');
|
|
657
|
+
console.log(' --help, -h Show this help.');
|
|
658
|
+
console.log('');
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
function showSetupHelp() {
|
|
662
|
+
console.log('');
|
|
663
|
+
console.log('Usage: atris setup');
|
|
664
|
+
console.log('');
|
|
665
|
+
console.log('Description:');
|
|
666
|
+
console.log(' Guided first-time setup: checks Node.js, login, businesses, and pull.');
|
|
667
|
+
console.log('');
|
|
668
|
+
console.log('Options:');
|
|
669
|
+
console.log(' --help, -h Show this help.');
|
|
670
|
+
console.log('');
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
function showServeHelp() {
|
|
674
|
+
console.log('');
|
|
675
|
+
console.log('Usage: atris serve [--agent <agent_id>] [--allow-bash]');
|
|
676
|
+
console.log('');
|
|
677
|
+
console.log('Description:');
|
|
678
|
+
console.log(' Start the local AI Computer bridge for the current directory.');
|
|
679
|
+
console.log('');
|
|
680
|
+
console.log('Options:');
|
|
681
|
+
console.log(' --agent <agent_id> Bind the session to a specific cloud agent.');
|
|
682
|
+
console.log(' --allow-bash Allow remote bash operations in this directory.');
|
|
683
|
+
console.log(' --help, -h Show this help.');
|
|
684
|
+
console.log('');
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
function showLoopHelp() {
|
|
688
|
+
console.log('');
|
|
689
|
+
console.log('Usage: atris loop [--dry-run] [--json] [--limit=N]');
|
|
690
|
+
console.log('');
|
|
691
|
+
console.log('Description:');
|
|
692
|
+
console.log(' Inspect wiki upkeep state and optionally refresh wiki status/log files.');
|
|
693
|
+
console.log('');
|
|
694
|
+
console.log('Options:');
|
|
695
|
+
console.log(' --dry-run Preview wiki loop state without writing files.');
|
|
696
|
+
console.log(' --json Print the loop report as JSON.');
|
|
697
|
+
console.log(' --limit=N Limit suggested source count.');
|
|
698
|
+
console.log(' --help, -h Show this help.');
|
|
699
|
+
console.log('');
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
function showCleanHelp() {
|
|
703
|
+
console.log('');
|
|
704
|
+
console.log('Usage: atris clean [--dry-run]');
|
|
705
|
+
console.log('');
|
|
706
|
+
console.log('Description:');
|
|
707
|
+
console.log(' Check workspace housekeeping: stale tasks, MAP.md refs, old journals,');
|
|
708
|
+
console.log(' empty TODO sections, and stale wiki pages.');
|
|
709
|
+
console.log('');
|
|
710
|
+
console.log('Options:');
|
|
711
|
+
console.log(' --dry-run, -n Preview cleanup without changing files.');
|
|
712
|
+
console.log(' --help, -h Show this help.');
|
|
713
|
+
console.log('');
|
|
714
|
+
}
|
|
715
|
+
|
|
421
716
|
function showAutopilotHelp() {
|
|
422
717
|
console.log('');
|
|
423
718
|
console.log('Usage: atris autopilot [description] [options]');
|
|
@@ -457,11 +752,22 @@ const { planAtris: planCmd, doAtris: doCmd, reviewAtris: reviewCmd } = require('
|
|
|
457
752
|
|
|
458
753
|
// All other commands are lazy-loaded inline (require() only when invoked)
|
|
459
754
|
|
|
755
|
+
if (command === '2' && ['fast', 'pro'].includes(String(firstCommandArg || '').toLowerCase())) {
|
|
756
|
+
const userInput = process.argv.slice(2).join(' ');
|
|
757
|
+
planCmd(userInput)
|
|
758
|
+
.then(() => process.exit(0))
|
|
759
|
+
.catch((error) => {
|
|
760
|
+
console.error(`✗ Atris 2 failed: ${error.message || error}`);
|
|
761
|
+
process.exit(1);
|
|
762
|
+
});
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
|
|
460
766
|
// Check if this is a known command or natural language input
|
|
461
767
|
const knownCommands = ['init', 'log', 'now', 'status', 'analytics', 'visualize', 'brain', 'brainstorm', 'autopilot', 'run', 'plan', 'do', 'review', 'release',
|
|
462
|
-
'activate', '_activate', 'agent', 'chat', 'console', 'login', 'logout', 'whoami', 'switch', 'use', 'accounts', '_resolve', '_profile-email', '_switch-session', 'shell-init', 'update', 'upgrade', 'version', 'help', 'next', 'atris',
|
|
463
|
-
'clean', 'verify', 'search', 'skill', 'member', 'app', 'learn', 'plugin', 'experiments', 'receipt', 'proof', 'openclaw', 'pull', 'push', 'live', 'align', 'terminal', 'computer', 'diff', 'business', 'sync',
|
|
464
|
-
'ingest', 'query', 'lint', 'loop', 'task', 'aeo',
|
|
768
|
+
'activate', '_activate', 'agent', 'chat', 'console', 'serve', 'login', 'logout', 'whoami', 'switch', 'use', 'accounts', '_resolve', '_profile-email', '_switch-session', 'shell-init', 'update', 'upgrade', 'version', 'help', 'next', 'atris',
|
|
769
|
+
'clean', 'verify', 'search', 'skill', 'member', 'codex-goal', 'app', 'apps', 'learn', 'lesson', 'plugin', 'experiments', 'receipt', 'proof', 'openclaw', 'pull', 'push', 'live', 'align', 'terminal', 'computer', 'diff', 'business', 'sync',
|
|
770
|
+
'ingest', 'query', 'lint', 'loop', 'task', 'mission', 'worktree', 'aeo', 'xp', 'play', 'gm', 'x',
|
|
465
771
|
'gmail', 'calendar', 'twitter', 'slack', 'imessage', 'integrations', 'setup', 'clean-workspace', 'cw',
|
|
466
772
|
'fork', 'browse', 'publish', 'sleep', 'wake', 'feedback', 'errors', 'wiki', 'code-review', 'cr', 'soul', 'fleet'];
|
|
467
773
|
|
|
@@ -524,6 +830,17 @@ if (!command || !knownCommands.includes(command)) {
|
|
|
524
830
|
if (!command || !knownCommands.includes(command)) {
|
|
525
831
|
const userInput = process.argv.slice(2).join(' ');
|
|
526
832
|
|
|
833
|
+
if (process.argv.includes('--json')) {
|
|
834
|
+
console.log(JSON.stringify({
|
|
835
|
+
ok: false,
|
|
836
|
+
error: command ? `unknown command: ${command}` : 'unknown command',
|
|
837
|
+
command: command || null,
|
|
838
|
+
input: userInput,
|
|
839
|
+
usage: 'atris help',
|
|
840
|
+
}, null, 2));
|
|
841
|
+
process.exit(2);
|
|
842
|
+
}
|
|
843
|
+
|
|
527
844
|
// Warn if this looks like a mistyped single-word command (no spaces)
|
|
528
845
|
if (command && !userInput.includes(' ')) {
|
|
529
846
|
console.log(`⚠ Unknown command: "${command}". Run "atris help" for available commands.`);
|
|
@@ -570,12 +887,27 @@ async function interactiveEntry(userInput) {
|
|
|
570
887
|
? context.inProgressFeaturesCount
|
|
571
888
|
: (context.inProgressFeatures || []).length;
|
|
572
889
|
|
|
890
|
+
// Pull active missions (durable goals) — these outrank dev-pipeline state
|
|
891
|
+
// because a mission with an unverified verifier is a Keshav-attributable
|
|
892
|
+
// commitment that hasn't been closed yet.
|
|
893
|
+
const activeMissions = loadActiveMissions(workspaceDir);
|
|
894
|
+
const liveMissionsCount = activeMissions.length;
|
|
895
|
+
// Mission needs a tick when: it has a verifier configured AND that verifier
|
|
896
|
+
// hasn't passed yet. Planning-state missions count too — first tick is what
|
|
897
|
+
// moves them to running.
|
|
898
|
+
const needsTickMission = activeMissions.find(
|
|
899
|
+
(m) => m.verifier && !m.verifier_passed
|
|
900
|
+
);
|
|
901
|
+
|
|
573
902
|
// Build status line
|
|
574
903
|
const parts = [];
|
|
575
904
|
const wipCount = inProgressTasksCount + inProgressFeaturesCount;
|
|
576
905
|
if (wipCount > 0) {
|
|
577
906
|
parts.push(`WIP: ${wipCount}`);
|
|
578
907
|
}
|
|
908
|
+
if (liveMissionsCount > 0) {
|
|
909
|
+
parts.push(`Missions: ${liveMissionsCount}`);
|
|
910
|
+
}
|
|
579
911
|
if (inboxCount > 0) {
|
|
580
912
|
parts.push(`Inbox: ${inboxCount}`);
|
|
581
913
|
}
|
|
@@ -627,16 +959,32 @@ async function interactiveEntry(userInput) {
|
|
|
627
959
|
return;
|
|
628
960
|
}
|
|
629
961
|
|
|
630
|
-
//
|
|
962
|
+
// Surface live missions so the operator sees durable goals alongside dev WIP.
|
|
963
|
+
if (liveMissionsCount > 0) {
|
|
964
|
+
console.log('\nLive missions:');
|
|
965
|
+
for (const m of activeMissions.slice(0, 5)) {
|
|
966
|
+
const tickGate = m.verifier && !m.verifier_passed ? ' [needs tick]' : '';
|
|
967
|
+
const obj = m.objective.length > 70 ? `${m.objective.slice(0, 67)}...` : m.objective;
|
|
968
|
+
console.log(`- [${m.owner}] ${obj} (${m.status})${tickGate}`);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
// Cold start auto-advance.
|
|
973
|
+
// ORDER MATTERS: missions outrank pipeline state because a mission's verifier
|
|
974
|
+
// is the contract that gates the Stop hook. Closing it unblocks everything else.
|
|
975
|
+
if (needsTickMission) {
|
|
976
|
+
console.log(`\nNext: atris mission tick (${needsTickMission.owner} mission has unverified verifier)`);
|
|
977
|
+
console.log(`Run: atris mission tick ${needsTickMission.id} --verify --complete-on-pass`);
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
|
|
631
981
|
if (completedTasksCount > 0) {
|
|
632
982
|
const preview = context.completedTasks.slice(0, 3).map((t) => (t.length > 70 ? `${t.slice(0, 67)}...` : t));
|
|
633
983
|
if (preview.length > 0) {
|
|
634
|
-
console.log('\nCompleted (
|
|
984
|
+
console.log('\nCompleted (history):');
|
|
635
985
|
preview.forEach((t) => console.log(`- ${t}`));
|
|
986
|
+
console.log('Completed tasks are history, not pending review.');
|
|
636
987
|
}
|
|
637
|
-
console.log('\nNext: atris review (pending validation)');
|
|
638
|
-
await reviewCmd();
|
|
639
|
-
return;
|
|
640
988
|
}
|
|
641
989
|
|
|
642
990
|
if (wipCount > 0 || backlogCount > 0) {
|
|
@@ -670,6 +1018,11 @@ async function interactiveEntry(userInput) {
|
|
|
670
1018
|
return;
|
|
671
1019
|
}
|
|
672
1020
|
|
|
1021
|
+
if (completedTasksCount > 0) {
|
|
1022
|
+
console.log('Next: atris plan (new work)');
|
|
1023
|
+
return;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
673
1026
|
// No obvious next step - prompt for input
|
|
674
1027
|
const rl = readline.createInterface({
|
|
675
1028
|
input: process.stdin,
|
|
@@ -799,6 +1152,13 @@ function showWelcomeVisualization() {
|
|
|
799
1152
|
}
|
|
800
1153
|
|
|
801
1154
|
if (command === 'init') {
|
|
1155
|
+
// Help flag must short-circuit before initCmd() (which scaffolds files)
|
|
1156
|
+
// and before interactiveEntry (which loads workspace context).
|
|
1157
|
+
const initArg = process.argv[3];
|
|
1158
|
+
if (initArg === '-h' || initArg === '--help' || initArg === 'help') {
|
|
1159
|
+
initCmd();
|
|
1160
|
+
process.exit(0);
|
|
1161
|
+
}
|
|
802
1162
|
initCmd();
|
|
803
1163
|
// Flow directly into interactive prompt
|
|
804
1164
|
interactiveEntry()
|
|
@@ -812,15 +1172,36 @@ if (command === 'init') {
|
|
|
812
1172
|
Promise.resolve(require('../commands/task').run(process.argv.slice(3)))
|
|
813
1173
|
.then(() => process.exit(0))
|
|
814
1174
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
1175
|
+
} else if (command === 'mission') {
|
|
1176
|
+
Promise.resolve(require('../commands/mission').missionCommand(process.argv.slice(3)))
|
|
1177
|
+
.then(() => process.exit(0))
|
|
1178
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
1179
|
+
} else if (command === 'worktree') {
|
|
1180
|
+
Promise.resolve(require('../commands/worktree').worktreeCommand(process.argv.slice(3)))
|
|
1181
|
+
.then((code) => process.exit(code || 0))
|
|
1182
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
1183
|
+
} else if (command === 'codex-goal') {
|
|
1184
|
+
Promise.resolve(require('../commands/codex-goal').codexGoalCommand(process.argv.slice(3)))
|
|
1185
|
+
.then(() => process.exit(process.exitCode || 0))
|
|
1186
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
815
1187
|
} else if (command === 'aeo') {
|
|
816
1188
|
// AEO: AI Engine Optimization — credit-metered citation drafting against the customer workspace.
|
|
817
1189
|
Promise.resolve(require('../commands/aeo').run(process.argv.slice(3)))
|
|
818
1190
|
.then(() => process.exit(0))
|
|
819
1191
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
820
1192
|
} else if (command === 'brain') {
|
|
821
|
-
Promise.resolve(
|
|
1193
|
+
Promise.resolve()
|
|
1194
|
+
.then(() => require('../commands/brain').brainCommand(process.argv.slice(3)))
|
|
822
1195
|
.then(() => process.exit(0))
|
|
823
|
-
.catch((err) => {
|
|
1196
|
+
.catch((err) => {
|
|
1197
|
+
const message = err.message || String(err);
|
|
1198
|
+
if (process.argv.slice(3).includes('--json')) {
|
|
1199
|
+
console.log(JSON.stringify({ ok: false, error: message }, null, 2));
|
|
1200
|
+
} else {
|
|
1201
|
+
console.error(`\n✗ Error: ${message}`);
|
|
1202
|
+
}
|
|
1203
|
+
process.exit(1);
|
|
1204
|
+
});
|
|
824
1205
|
} else if (command === 'agent') {
|
|
825
1206
|
agentAtris().then(() => process.exit(0)).catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
826
1207
|
} else if (command === 'log') {
|
|
@@ -832,7 +1213,14 @@ if (command === 'init') {
|
|
|
832
1213
|
console.error(`✗ Log sync failed: ${error.message || error}`);
|
|
833
1214
|
process.exit(1);
|
|
834
1215
|
});
|
|
835
|
-
} else if (subcommand
|
|
1216
|
+
} else if (subcommand === '--help' || subcommand === '-h' || subcommand === 'help') {
|
|
1217
|
+
console.log('Usage: atris log [business-slug | sync | help]');
|
|
1218
|
+
console.log('');
|
|
1219
|
+
console.log(' atris log Open today\'s journal REPL (write to ## Inbox)');
|
|
1220
|
+
console.log(' atris log <slug> Show business log history');
|
|
1221
|
+
console.log(' atris log sync Sync the local journal to cloud');
|
|
1222
|
+
process.exit(0);
|
|
1223
|
+
} else if (subcommand && !subcommand.startsWith('-')) {
|
|
836
1224
|
// Business log: atris log <business-slug>
|
|
837
1225
|
require('../commands/context-sync').businessLog(subcommand)
|
|
838
1226
|
.then(() => process.exit(0))
|
|
@@ -841,10 +1229,21 @@ if (command === 'init') {
|
|
|
841
1229
|
logCmd();
|
|
842
1230
|
}
|
|
843
1231
|
} else if (command === 'now') {
|
|
844
|
-
|
|
1232
|
+
const args = process.argv.slice(3);
|
|
1233
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
1234
|
+
require('../commands/now').nowAtris(args);
|
|
1235
|
+
process.exit(0);
|
|
1236
|
+
}
|
|
1237
|
+
require('../commands/now').nowAtris(args);
|
|
845
1238
|
} else if (command === 'activate') {
|
|
1239
|
+
const args = process.argv.slice(3);
|
|
1240
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
1241
|
+
showActivateHelp();
|
|
1242
|
+
process.exit(0);
|
|
1243
|
+
}
|
|
846
1244
|
activateCmd();
|
|
847
1245
|
} else if (command === 'update' || command === 'sync') {
|
|
1246
|
+
const args = process.argv.slice(3);
|
|
848
1247
|
const firstSyncArg = process.argv[3];
|
|
849
1248
|
const isBusinessSync = command === 'sync'
|
|
850
1249
|
&& (
|
|
@@ -853,6 +1252,10 @@ if (command === 'init') {
|
|
|
853
1252
|
|| (firstSyncArg && !firstSyncArg.startsWith('-'))
|
|
854
1253
|
)
|
|
855
1254
|
&& firstSyncArg !== 'all';
|
|
1255
|
+
if ((args.includes('--help') || args.includes('-h') || args[0] === 'help') && !isBusinessSync) {
|
|
1256
|
+
showUpdateHelp(command);
|
|
1257
|
+
process.exit(0);
|
|
1258
|
+
}
|
|
856
1259
|
if (isBusinessSync) {
|
|
857
1260
|
Promise.resolve(require('../commands/business-sync').businessSync(process.argv.slice(3)))
|
|
858
1261
|
.then(() => process.exit(0))
|
|
@@ -867,6 +1270,11 @@ if (command === 'init') {
|
|
|
867
1270
|
syncCmd();
|
|
868
1271
|
}
|
|
869
1272
|
} else if (command === 'upgrade') {
|
|
1273
|
+
const args = process.argv.slice(3);
|
|
1274
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
1275
|
+
showUpgradeHelp();
|
|
1276
|
+
process.exit(0);
|
|
1277
|
+
}
|
|
870
1278
|
upgradeAtris().then(() => process.exit(0)).catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
871
1279
|
} else if (command === 'chat') {
|
|
872
1280
|
chatAtris()
|
|
@@ -881,6 +1289,10 @@ if (command === 'init') {
|
|
|
881
1289
|
// Start the local AI Computer bridge — make this directory addressable
|
|
882
1290
|
// by cloud agents via the Atris API
|
|
883
1291
|
const serveArgs = process.argv.slice(3);
|
|
1292
|
+
if (serveArgs.includes('--help') || serveArgs.includes('-h') || serveArgs[0] === 'help') {
|
|
1293
|
+
showServeHelp();
|
|
1294
|
+
process.exit(0);
|
|
1295
|
+
}
|
|
884
1296
|
const serveOptions = {};
|
|
885
1297
|
for (let i = 0; i < serveArgs.length; i++) {
|
|
886
1298
|
if (serveArgs[i] === '--agent' && serveArgs[i + 1]) {
|
|
@@ -898,16 +1310,46 @@ if (command === 'init') {
|
|
|
898
1310
|
} else if (command === 'version') {
|
|
899
1311
|
require('../commands/version').showVersion();
|
|
900
1312
|
} else if (command === 'login') {
|
|
1313
|
+
const args = process.argv.slice(3);
|
|
1314
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
1315
|
+
showAuthHelp('login');
|
|
1316
|
+
process.exit(0);
|
|
1317
|
+
}
|
|
901
1318
|
require('../commands/auth').loginAtris();
|
|
902
1319
|
} else if (command === 'logout') {
|
|
1320
|
+
const args = process.argv.slice(3);
|
|
1321
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
1322
|
+
showAuthHelp('logout');
|
|
1323
|
+
process.exit(0);
|
|
1324
|
+
}
|
|
903
1325
|
require('../commands/auth').logoutAtris();
|
|
904
1326
|
} else if (command === 'whoami') {
|
|
1327
|
+
const args = process.argv.slice(3);
|
|
1328
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
1329
|
+
showAuthHelp('whoami');
|
|
1330
|
+
process.exit(0);
|
|
1331
|
+
}
|
|
905
1332
|
require('../commands/auth').whoamiAtris();
|
|
906
1333
|
} else if (command === 'switch') {
|
|
1334
|
+
const args = process.argv.slice(3);
|
|
1335
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
1336
|
+
showAuthHelp('switch');
|
|
1337
|
+
process.exit(0);
|
|
1338
|
+
}
|
|
907
1339
|
require('../commands/auth').switchAccount();
|
|
908
1340
|
} else if (command === 'use') {
|
|
1341
|
+
const args = process.argv.slice(3);
|
|
1342
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
1343
|
+
showAuthHelp('use');
|
|
1344
|
+
process.exit(0);
|
|
1345
|
+
}
|
|
909
1346
|
require('../commands/auth').useAccount();
|
|
910
1347
|
} else if (command === 'accounts') {
|
|
1348
|
+
const args = process.argv.slice(3);
|
|
1349
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
1350
|
+
showAuthHelp('accounts');
|
|
1351
|
+
process.exit(0);
|
|
1352
|
+
}
|
|
911
1353
|
require('../commands/auth').accountsCmd();
|
|
912
1354
|
} else if (command === '_resolve') {
|
|
913
1355
|
// Hidden: resolve a profile name query → print exact profile name
|
|
@@ -929,7 +1371,7 @@ if (command === 'init') {
|
|
|
929
1371
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
930
1372
|
} else if (command === 'run') {
|
|
931
1373
|
const args = process.argv.slice(3);
|
|
932
|
-
if (args.includes('--help') || args.includes('-h')) {
|
|
1374
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
933
1375
|
console.log('');
|
|
934
1376
|
console.log('Usage: atris run [options]');
|
|
935
1377
|
console.log('');
|
|
@@ -965,7 +1407,7 @@ if (command === 'init') {
|
|
|
965
1407
|
});
|
|
966
1408
|
} else if (command === 'autopilot') {
|
|
967
1409
|
const args = process.argv.slice(3);
|
|
968
|
-
if (args.includes('--help') || args.includes('-h')) {
|
|
1410
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
969
1411
|
showAutopilotHelp();
|
|
970
1412
|
process.exit(0);
|
|
971
1413
|
}
|
|
@@ -1008,6 +1450,10 @@ if (command === 'init') {
|
|
|
1008
1450
|
});
|
|
1009
1451
|
} else if (command === 'next' || command === 'atris') {
|
|
1010
1452
|
const rawArgs = process.argv.slice(3);
|
|
1453
|
+
if (rawArgs.includes('--help') || rawArgs.includes('-h') || rawArgs[0] === 'help') {
|
|
1454
|
+
showNextHelp(command);
|
|
1455
|
+
process.exit(0);
|
|
1456
|
+
}
|
|
1011
1457
|
const userInput = rawArgs.filter((arg) => !arg.startsWith('-')).join(' ').trim();
|
|
1012
1458
|
interactiveEntry(userInput || null)
|
|
1013
1459
|
.then(() => process.exit(0))
|
|
@@ -1052,6 +1498,11 @@ if (command === 'init') {
|
|
|
1052
1498
|
process.exit(1);
|
|
1053
1499
|
});
|
|
1054
1500
|
} else if (command === 'status') {
|
|
1501
|
+
const args = process.argv.slice(3);
|
|
1502
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
1503
|
+
showStatusHelp();
|
|
1504
|
+
process.exit(0);
|
|
1505
|
+
}
|
|
1055
1506
|
let subcommand = process.argv[3];
|
|
1056
1507
|
if (subcommand && !subcommand.startsWith('-')) {
|
|
1057
1508
|
require('../commands/context-sync').businessStatus(subcommand)
|
|
@@ -1064,11 +1515,26 @@ if (command === 'init') {
|
|
|
1064
1515
|
statusCmd(isQuick, isJson, verbose);
|
|
1065
1516
|
}
|
|
1066
1517
|
} else if (command === 'analytics') {
|
|
1518
|
+
const args = process.argv.slice(3);
|
|
1519
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
1520
|
+
showAnalyticsHelp();
|
|
1521
|
+
process.exit(0);
|
|
1522
|
+
}
|
|
1067
1523
|
require('../commands/analytics').analyticsAtris();
|
|
1068
1524
|
} else if (command === 'clean') {
|
|
1525
|
+
const args = process.argv.slice(3);
|
|
1526
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
1527
|
+
showCleanHelp();
|
|
1528
|
+
process.exit(0);
|
|
1529
|
+
}
|
|
1069
1530
|
const dryRun = process.argv.includes('--dry-run') || process.argv.includes('-n');
|
|
1070
1531
|
require('../commands/clean').cleanAtris({ dryRun });
|
|
1071
1532
|
} else if (command === 'verify') {
|
|
1533
|
+
const args = process.argv.slice(3);
|
|
1534
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
1535
|
+
showVerifyHelp();
|
|
1536
|
+
process.exit(0);
|
|
1537
|
+
}
|
|
1072
1538
|
const sectionIdx = process.argv.indexOf('--section');
|
|
1073
1539
|
if (sectionIdx > 0 && process.argv[sectionIdx + 1]) {
|
|
1074
1540
|
const slug = process.argv[3] && !process.argv[3].startsWith('--') ? process.argv[3] : null;
|
|
@@ -1079,6 +1545,11 @@ if (command === 'init') {
|
|
|
1079
1545
|
const taskId = process.argv[3] || null;
|
|
1080
1546
|
require('../commands/verify').verifyAtris(taskId);
|
|
1081
1547
|
} else if (command === 'release') {
|
|
1548
|
+
const args = process.argv.slice(3);
|
|
1549
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
1550
|
+
showReleaseHelp();
|
|
1551
|
+
process.exit(0);
|
|
1552
|
+
}
|
|
1082
1553
|
const dryRun = process.argv.includes('--dry-run');
|
|
1083
1554
|
require('../commands/release').releaseAtris({ dryRun })
|
|
1084
1555
|
.then(() => process.exit(0))
|
|
@@ -1086,6 +1557,18 @@ if (command === 'init') {
|
|
|
1086
1557
|
} else if (command === 'search') {
|
|
1087
1558
|
const keyword = process.argv.slice(3).join(' ');
|
|
1088
1559
|
searchJournal(keyword);
|
|
1560
|
+
} else if (command === 'xp') {
|
|
1561
|
+
require('../commands/xp').xpCommand(...process.argv.slice(3))
|
|
1562
|
+
.then(() => process.exit(0))
|
|
1563
|
+
.catch((err) => { console.error(`✗ Error: ${err.message || err}`); process.exit(1); });
|
|
1564
|
+
} else if (command === 'play') {
|
|
1565
|
+
require('../commands/play').playCommand(...process.argv.slice(3))
|
|
1566
|
+
.then(() => process.exit(0))
|
|
1567
|
+
.catch((err) => { console.error(`✗ Error: ${err.message || err}`); process.exit(1); });
|
|
1568
|
+
} else if (command === 'gm') {
|
|
1569
|
+
require('../commands/gm').gmCommand(...process.argv.slice(3))
|
|
1570
|
+
.then(() => process.exit(0))
|
|
1571
|
+
.catch((err) => { console.error(`✗ Error: ${err.message || err}`); process.exit(1); });
|
|
1089
1572
|
} else if (command === 'gmail') {
|
|
1090
1573
|
const { gmailCommand } = require('../commands/integrations');
|
|
1091
1574
|
const subcommand = process.argv[3];
|
|
@@ -1122,6 +1605,11 @@ if (command === 'init') {
|
|
|
1122
1605
|
.then(() => process.exit(0))
|
|
1123
1606
|
.catch((err) => { console.error(`✗ Error: ${err.message || err}`); process.exit(1); });
|
|
1124
1607
|
} else if (command === 'integrations') {
|
|
1608
|
+
const args = process.argv.slice(3);
|
|
1609
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
1610
|
+
showIntegrationsHelp();
|
|
1611
|
+
process.exit(0);
|
|
1612
|
+
}
|
|
1125
1613
|
const { integrationsStatus } = require('../commands/integrations');
|
|
1126
1614
|
integrationsStatus()
|
|
1127
1615
|
.then(() => process.exit(0))
|
|
@@ -1130,6 +1618,10 @@ if (command === 'init') {
|
|
|
1130
1618
|
const subcommand = process.argv[3];
|
|
1131
1619
|
const args = process.argv.slice(4);
|
|
1132
1620
|
require('../commands/learn')(subcommand, ...args);
|
|
1621
|
+
} else if (command === 'lesson') {
|
|
1622
|
+
const subcommand = process.argv[3];
|
|
1623
|
+
const args = process.argv.slice(4);
|
|
1624
|
+
require('../commands/lesson')(subcommand, ...args);
|
|
1133
1625
|
} else if (command === 'skill') {
|
|
1134
1626
|
const subcommand = process.argv[3];
|
|
1135
1627
|
const args = process.argv.slice(4);
|
|
@@ -1162,13 +1654,28 @@ if (command === 'init') {
|
|
|
1162
1654
|
require('../commands/terminal').terminalAtris()
|
|
1163
1655
|
.then(() => process.exit(0))
|
|
1164
1656
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
1657
|
+
} else if (command === 'x') {
|
|
1658
|
+
// Fast Agent SDK execution - like "atris x echo hello" or "atris x ls -la"
|
|
1659
|
+
const userInput = process.argv.slice(3).join(' ').trim();
|
|
1660
|
+
if (!userInput) {
|
|
1661
|
+
console.log('Usage: atris x <command>');
|
|
1662
|
+
console.log('Example: atris x echo "hello world"');
|
|
1663
|
+
console.log('Example: atris x ls -la');
|
|
1664
|
+
process.exit(1);
|
|
1665
|
+
}
|
|
1666
|
+
require('../commands/workflow').executeAgentSDKFast(userInput);
|
|
1165
1667
|
} else if (command === 'computer') {
|
|
1166
1668
|
require('../commands/computer').runComputer()
|
|
1167
1669
|
.then(() => process.exit(0))
|
|
1168
1670
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
1169
1671
|
} else if (command === 'diff') {
|
|
1170
1672
|
let diffSlug = process.argv[3];
|
|
1673
|
+
if (diffSlug === '-h' || diffSlug === '--help') {
|
|
1674
|
+
console.log('Usage: atris diff [business] [path]');
|
|
1675
|
+
process.exit(0);
|
|
1676
|
+
}
|
|
1171
1677
|
if (!diffSlug || diffSlug.startsWith('-')) {
|
|
1678
|
+
diffSlug = undefined;
|
|
1172
1679
|
const bizFile = require('path').join(process.cwd(), '.atris', 'business.json');
|
|
1173
1680
|
if (require('fs').existsSync(bizFile)) {
|
|
1174
1681
|
try { diffSlug = JSON.parse(require('fs').readFileSync(bizFile, 'utf8')).slug; } catch {}
|
|
@@ -1210,6 +1717,10 @@ if (command === 'init') {
|
|
|
1210
1717
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
1211
1718
|
} else if (command === 'loop') {
|
|
1212
1719
|
const args = process.argv.slice(3);
|
|
1720
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
1721
|
+
showLoopHelp();
|
|
1722
|
+
process.exit(0);
|
|
1723
|
+
}
|
|
1213
1724
|
require('../commands/loop').loopAtris(args)
|
|
1214
1725
|
.then(() => process.exit(0))
|
|
1215
1726
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
@@ -1231,6 +1742,11 @@ if (command === 'init') {
|
|
|
1231
1742
|
const args = process.argv.slice(4);
|
|
1232
1743
|
require('../commands/proof').proofCommand(subcommand, ...args);
|
|
1233
1744
|
} else if (command === 'setup') {
|
|
1745
|
+
const args = process.argv.slice(3);
|
|
1746
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
1747
|
+
showSetupHelp();
|
|
1748
|
+
process.exit(0);
|
|
1749
|
+
}
|
|
1234
1750
|
require('../commands/setup').setupAtris()
|
|
1235
1751
|
.then(() => process.exit(0))
|
|
1236
1752
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
@@ -1276,6 +1792,11 @@ async function upgradeAtris() {
|
|
|
1276
1792
|
console.log('');
|
|
1277
1793
|
console.log(`Current version: ${CLI_VERSION}`);
|
|
1278
1794
|
console.log('');
|
|
1795
|
+
const installWarning = formatInstallGitWarning(inspectInstallGitState(path.join(__dirname, '..')));
|
|
1796
|
+
if (installWarning) {
|
|
1797
|
+
console.log(installWarning);
|
|
1798
|
+
console.log('');
|
|
1799
|
+
}
|
|
1279
1800
|
console.log('Checking for updates...');
|
|
1280
1801
|
|
|
1281
1802
|
// Force check npm for latest version
|
|
@@ -1331,7 +1852,112 @@ function showVersion() {
|
|
|
1331
1852
|
// Agent Selection
|
|
1332
1853
|
// ============================================
|
|
1333
1854
|
|
|
1855
|
+
function fileContains(relPath, pattern) {
|
|
1856
|
+
try {
|
|
1857
|
+
const fullPath = path.join(process.cwd(), relPath);
|
|
1858
|
+
if (!fs.existsSync(fullPath)) return false;
|
|
1859
|
+
const text = fs.readFileSync(fullPath, 'utf8');
|
|
1860
|
+
return pattern instanceof RegExp ? pattern.test(text) : text.includes(pattern);
|
|
1861
|
+
} catch {
|
|
1862
|
+
return false;
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1866
|
+
function commandOnPath(name) {
|
|
1867
|
+
const result = spawnSync('which', [name], { encoding: 'utf8', timeout: 1000 });
|
|
1868
|
+
return result.status === 0 ? result.stdout.trim() : null;
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
function inspectAgentCliWiring() {
|
|
1872
|
+
const checks = [
|
|
1873
|
+
{
|
|
1874
|
+
id: 'atris-core',
|
|
1875
|
+
label: 'Atris core',
|
|
1876
|
+
ok: fs.existsSync(path.join(process.cwd(), 'atris', 'MAP.md'))
|
|
1877
|
+
&& fs.existsSync(path.join(process.cwd(), 'atris', 'TODO.md')),
|
|
1878
|
+
fix: 'Run `atris init` from the workspace root.',
|
|
1879
|
+
},
|
|
1880
|
+
{
|
|
1881
|
+
id: 'codex',
|
|
1882
|
+
label: 'Codex / OpenAI agents',
|
|
1883
|
+
ok: fileContains('AGENTS.md', /atris\/MAP\.md|atris atris\.md|atris task/),
|
|
1884
|
+
fix: 'Add AGENTS.md with Atris boot, MAP, and task instructions.',
|
|
1885
|
+
},
|
|
1886
|
+
{
|
|
1887
|
+
id: 'claude',
|
|
1888
|
+
label: 'Claude Code',
|
|
1889
|
+
ok: fileContains('.claude/commands/atris.md', /atris|AGENTS\.md/)
|
|
1890
|
+
|| fileContains('.claude/settings.json', /atris atris\.md|atris\/skills/)
|
|
1891
|
+
|| fileContains('CLAUDE.md', /Atris|atris/),
|
|
1892
|
+
fix: 'Run `atris init` to create .claude commands/settings.',
|
|
1893
|
+
},
|
|
1894
|
+
{
|
|
1895
|
+
id: 'cursor',
|
|
1896
|
+
label: 'Cursor',
|
|
1897
|
+
ok: fileContains('.cursor/rules/atris.mdc', /atris\/MAP\.md|AGENTS\.md|atris task/)
|
|
1898
|
+
|| fileContains('.cursorrules', /atris\/MAP\.md|AGENTS\.md|atris task/)
|
|
1899
|
+
|| fileContains('.cursor/commands/atris.md', /atris\/MAP\.md|atris\.md/),
|
|
1900
|
+
fix: 'Run `atris init` to create Cursor rules, or add .cursor/commands/atris.md.',
|
|
1901
|
+
},
|
|
1902
|
+
{
|
|
1903
|
+
id: 'devin',
|
|
1904
|
+
label: 'Devin',
|
|
1905
|
+
ok: fileContains('.devin/config.local.json', /Exec\(atris\)/),
|
|
1906
|
+
fix: 'Run `atris init` or add .devin/config.local.json allowing Exec(atris).',
|
|
1907
|
+
},
|
|
1908
|
+
];
|
|
1909
|
+
|
|
1910
|
+
const binaries = ['atris', 'claude', 'codex', 'cursor-agent', 'devin'].map((name) => ({
|
|
1911
|
+
name,
|
|
1912
|
+
path: commandOnPath(name),
|
|
1913
|
+
}));
|
|
1914
|
+
return { checks, binaries };
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1917
|
+
function agentDoctor() {
|
|
1918
|
+
const args = process.argv.slice(4);
|
|
1919
|
+
const json = args.includes('--json');
|
|
1920
|
+
const { checks, binaries } = inspectAgentCliWiring();
|
|
1921
|
+
const ok = checks.every((check) => check.ok);
|
|
1922
|
+
const payload = { ok, action: 'agent_doctor', checks, binaries };
|
|
1923
|
+
|
|
1924
|
+
if (json) {
|
|
1925
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
1926
|
+
process.exit(ok ? 0 : 1);
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1929
|
+
console.log('Atris agent CLI doctor');
|
|
1930
|
+
console.log('');
|
|
1931
|
+
for (const check of checks) {
|
|
1932
|
+
console.log(`${check.ok ? '✓' : '✗'} ${check.label}`);
|
|
1933
|
+
if (!check.ok) console.log(` fix: ${check.fix}`);
|
|
1934
|
+
}
|
|
1935
|
+
console.log('');
|
|
1936
|
+
console.log('Local binaries');
|
|
1937
|
+
for (const binary of binaries) {
|
|
1938
|
+
console.log(`${binary.path ? '✓' : '·'} ${binary.name}${binary.path ? ` -> ${binary.path}` : ' not on PATH'}`);
|
|
1939
|
+
}
|
|
1940
|
+
process.exit(ok ? 0 : 1);
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1334
1943
|
async function agentAtris() {
|
|
1944
|
+
// Respect -h / --help / help before any auth/state work
|
|
1945
|
+
const firstArg = process.argv[3];
|
|
1946
|
+
if (firstArg === '-h' || firstArg === '--help' || firstArg === 'help') {
|
|
1947
|
+
console.log('Usage: atris agent [doctor]');
|
|
1948
|
+
console.log('');
|
|
1949
|
+
console.log(' Pick which cloud agent to chat with from this workspace.');
|
|
1950
|
+
console.log(' Run `atris agent doctor` to verify local AI CLIs can see Atris context.');
|
|
1951
|
+
console.log(' Requires `atris login` first.');
|
|
1952
|
+
console.log('');
|
|
1953
|
+
console.log(' After selecting, use: atris chat ["message"]');
|
|
1954
|
+
process.exit(0);
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1957
|
+
if (firstArg === 'doctor') {
|
|
1958
|
+
agentDoctor();
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1335
1961
|
const targetDir = path.join(process.cwd(), 'atris');
|
|
1336
1962
|
|
|
1337
1963
|
// Check if atris/ folder exists
|
|
@@ -1423,6 +2049,18 @@ async function chatAtris() {
|
|
|
1423
2049
|
// Get message from command line args
|
|
1424
2050
|
const message = process.argv.slice(3).join(' ').trim();
|
|
1425
2051
|
|
|
2052
|
+
// Respect -h / --help before any auth/state checks
|
|
2053
|
+
if (message === '-h' || message === '--help' || message === 'help') {
|
|
2054
|
+
console.log('Usage: atris chat ["message"]');
|
|
2055
|
+
console.log('');
|
|
2056
|
+
console.log(' Open an interactive session with the selected agent, or send a one-shot message.');
|
|
2057
|
+
console.log(' Requires `atris login` and `atris agent` to be run first.');
|
|
2058
|
+
console.log('');
|
|
2059
|
+
console.log(' atris chat Interactive REPL with selected agent');
|
|
2060
|
+
console.log(' atris chat "what now?" One-shot message');
|
|
2061
|
+
process.exit(0);
|
|
2062
|
+
}
|
|
2063
|
+
|
|
1426
2064
|
// Check atris/ exists
|
|
1427
2065
|
const targetDir = path.join(process.cwd(), 'atris');
|
|
1428
2066
|
if (!fs.existsSync(targetDir)) {
|