atris 3.53.0 → 3.55.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/FOR_AGENTS.md +7 -0
- package/README.md +1 -1
- package/atris/policies/ANTISLOP.md +2 -1
- package/atris/skills/copy-editor/SKILL.md +2 -1
- package/atris/skills/design/SKILL.md +1 -1
- package/atris/skills/x-search/SKILL.md +24 -22
- package/atris/skills/youtube/SKILL.md +82 -33
- package/atris/team/_template/SOUL.md +40 -0
- package/atris/team/validator/MEMBER.md +1 -2
- package/bin/atris +21 -0
- package/bin/atris.js +563 -373
- package/commands/api-key.js +170 -0
- package/commands/auth.js +453 -43
- package/commands/autoland.js +3 -1
- package/commands/autopilot-front.js +58 -11
- package/commands/avail.js +5 -4
- package/commands/balance.js +55 -0
- package/commands/bench.js +29 -1
- package/commands/brain.js +63 -12
- package/commands/brainstorm.js +18 -0
- package/commands/business.js +149 -1
- package/commands/chat-scan.js +17 -4
- package/commands/close.js +5 -1
- package/commands/doctor.js +174 -0
- package/commands/dream.js +7 -0
- package/commands/drill.js +34 -2
- package/commands/engine.js +47 -35
- package/commands/errors.js +58 -8
- package/commands/experiments.js +14 -0
- package/commands/feedback.js +61 -2
- package/commands/fleet-report.js +27 -7
- package/commands/fleet.js +98 -11
- package/commands/founder.js +60 -21
- package/commands/human-missions.js +79 -4
- package/commands/improve.js +54 -4
- package/commands/init.js +68 -92
- package/commands/install.js +40 -0
- package/commands/integrations.js +399 -30
- package/commands/interview.js +8 -0
- package/commands/land.js +48 -17
- package/commands/learn.js +29 -4
- package/commands/log.js +51 -0
- package/commands/member.js +68 -10
- package/commands/mission.js +287 -50
- package/commands/now.js +15 -3
- package/commands/orb.js +97 -2
- package/commands/pack.js +83 -9
- package/commands/playbook.js +381 -0
- package/commands/plugin.js +16 -0
- package/commands/radar.js +31 -7
- package/commands/recap.js +128 -21
- package/commands/release.js +102 -2
- package/commands/review.js +5 -10
- package/commands/revisions.js +55 -0
- package/commands/run-front.js +12 -4
- package/commands/scout.js +12 -1
- package/commands/search.js +123 -28
- package/commands/sign.js +2 -2
- package/commands/signup.js +12 -3
- package/commands/site-deploy.js +17 -4
- package/commands/site.js +2 -2
- package/commands/skill-eval.js +289 -0
- package/commands/skill.js +56 -6
- package/commands/social.js +603 -0
- package/commands/spaceship.js +69 -6
- package/commands/stream.js +8 -1
- package/commands/study.js +32 -19
- package/commands/sync.js +28 -22
- package/commands/task.js +418 -60
- package/commands/teach.js +72 -63
- package/commands/terminal.js +25 -9
- package/commands/topup.js +88 -0
- package/commands/truth.js +52 -6
- package/commands/usage.js +91 -0
- package/commands/verify.js +3 -2
- package/commands/version.js +3 -1
- package/commands/voice.js +5 -1
- package/commands/who.js +69 -11
- package/commands/wiki.js +7 -4
- package/commands/wish.js +76 -5
- package/commands/workflow.js +327 -145
- package/commands/worktree.js +1 -0
- package/commands/write.js +5 -0
- package/commands/x-search.js +340 -0
- package/commands/xp.js +5 -1
- package/commands/youtube.js +551 -25
- package/lib/account-bound.js +47 -0
- package/lib/auto-accept-certified.js +8 -1
- package/lib/auto-lessons.js +186 -0
- package/lib/autoland.js +4 -2
- package/lib/chat-log-scan.js +7 -4
- package/lib/cli-json.js +77 -0
- package/lib/cli-scope.js +26 -0
- package/lib/codex-flight.js +1 -0
- package/lib/conductor-artifacts.js +1 -1
- package/lib/context-gatherer.js +11 -0
- package/lib/developer-api.js +116 -0
- package/lib/feedback-triage.js +274 -0
- package/lib/first-minute.js +398 -0
- package/lib/fleet.js +115 -34
- package/lib/functional-owner.js +22 -0
- package/lib/known-commands.js +31 -5
- package/lib/member-scaffold.js +197 -0
- package/lib/mission-root.js +4 -2
- package/lib/noninteractive.js +88 -0
- package/lib/policy-lessons.js +4 -1
- package/lib/revision-metric.js +279 -0
- package/lib/scratch-root.js +48 -0
- package/lib/skill-eval-gate.js +249 -0
- package/lib/task-db.js +4 -0
- package/lib/task-proof.js +69 -8
- package/lib/verifier-quality.js +69 -0
- package/lib/wish-audit.js +2 -2
- package/lib/wish-delegate.js +10 -1
- package/lib/workspace-scaffold.js +270 -0
- package/package.json +3 -2
- package/scripts/det/checklist-score.js +191 -0
- package/scripts/det/ytsearch +31 -0
- package/utils/update-check.js +15 -0
package/bin/atris.js
CHANGED
|
@@ -41,7 +41,13 @@ const {
|
|
|
41
41
|
autoUpdate,
|
|
42
42
|
inspectInstallGitState,
|
|
43
43
|
formatInstallGitWarning,
|
|
44
|
+
formatCliVersionLine,
|
|
44
45
|
} = require('../utils/update-check');
|
|
46
|
+
const {
|
|
47
|
+
requireAccountBound,
|
|
48
|
+
refuseAccountGlobal,
|
|
49
|
+
} = require('../lib/account-bound');
|
|
50
|
+
const { isHelpToken, argsWantHelp } = require('../lib/noninteractive');
|
|
45
51
|
|
|
46
52
|
// State detection for smart default
|
|
47
53
|
const { detectWorkspaceState, loadContext } = require('../lib/state-detection');
|
|
@@ -52,6 +58,12 @@ const {
|
|
|
52
58
|
isAtrisMetaQuestion,
|
|
53
59
|
renderPrompt: renderContextGathererPrompt,
|
|
54
60
|
} = require('../lib/context-gatherer');
|
|
61
|
+
const {
|
|
62
|
+
buildFirstMinute,
|
|
63
|
+
freshMinuteJson,
|
|
64
|
+
isBareAtrisFlag,
|
|
65
|
+
shouldAutoInitFresh,
|
|
66
|
+
} = require('../lib/first-minute');
|
|
55
67
|
|
|
56
68
|
// Journal & config utilities (canonical modules)
|
|
57
69
|
const { getLogPath, ensureLogDirectory, createLogFile } = require('../lib/file-ops');
|
|
@@ -75,7 +87,7 @@ const {
|
|
|
75
87
|
DEFAULT_CLIENT_ID, DEFAULT_USER_AGENT,
|
|
76
88
|
} = require('../utils/api');
|
|
77
89
|
const missionRuntime = require('../lib/mission-runtime-loop');
|
|
78
|
-
const { knownCommands, suggestCommand } = require('../lib/known-commands');
|
|
90
|
+
const { knownCommands, suggestCommand, suggestCommands } = require('../lib/known-commands');
|
|
79
91
|
const { recordUsage } = require('../lib/usage');
|
|
80
92
|
|
|
81
93
|
// Bind DI wrappers (utils/auth uses dependency injection for apiRequestJson)
|
|
@@ -153,6 +165,12 @@ function parseNaturalEntryArgs(args = []) {
|
|
|
153
165
|
asJson = true;
|
|
154
166
|
continue;
|
|
155
167
|
}
|
|
168
|
+
if (value === '--yes' || value === '-y' || value === '--verbose') {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (isHelpToken(value)) {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
156
174
|
const inlineFlag = NATURAL_VALUE_FLAGS.find((name) => value.startsWith(`${name}=`));
|
|
157
175
|
if (inlineFlag) {
|
|
158
176
|
const optionValue = value.slice(inlineFlag.length + 1);
|
|
@@ -262,7 +280,13 @@ const isBusinessSyncSafetyCommand = command === 'sync'
|
|
|
262
280
|
|
|
263
281
|
// Auto-sync skills only for commands that modify workspace state. Help must
|
|
264
282
|
// stay read-only, including global ~/.claude and ~/.codex skill directories.
|
|
265
|
-
|
|
283
|
+
// update/sync stay plan-only until --yes, so do not write skills on a bare update.
|
|
284
|
+
const updateWriteYes = updateArgs.includes('--yes') || updateArgs.includes('-y');
|
|
285
|
+
if (!helpRequested && !dryRunRequested && (
|
|
286
|
+
['init', 'upgrade'].includes(command)
|
|
287
|
+
|| (command === 'update' && updateWriteYes)
|
|
288
|
+
|| (command === 'sync' && !isBusinessSyncSafetyCommand && updateWriteYes)
|
|
289
|
+
)) {
|
|
266
290
|
try {
|
|
267
291
|
const { syncSkills } = require('../commands/sync');
|
|
268
292
|
const skillsUpdated = syncSkills({ silent: true });
|
|
@@ -446,40 +470,83 @@ function consoleCmd() {
|
|
|
446
470
|
process.exit(result.status ?? 0);
|
|
447
471
|
}
|
|
448
472
|
|
|
449
|
-
function
|
|
473
|
+
function showStartHelp() {
|
|
474
|
+
console.log('');
|
|
475
|
+
console.log('Usage: atris start [options]');
|
|
476
|
+
console.log('');
|
|
477
|
+
console.log('Starts the durable mission loop for one useful self-improvement mission.');
|
|
478
|
+
console.log('');
|
|
479
|
+
console.log('Options:');
|
|
480
|
+
console.log(' --json Print the mission route without starting it.');
|
|
481
|
+
console.log(' --owner X Override mission owner.');
|
|
482
|
+
console.log(' --cadence X Override mission cadence.');
|
|
483
|
+
console.log('');
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function showHelpShort() {
|
|
487
|
+
console.log('atris: you say what you want; atris builds it, checks it, and shows proof.');
|
|
488
|
+
console.log('');
|
|
489
|
+
console.log('Golden path:');
|
|
490
|
+
console.log(' atris init [--yes] [--minimal] scaffold this project');
|
|
491
|
+
console.log(' atris load context (MAP, tasks, journal)');
|
|
492
|
+
console.log(' atris task new "..." file work');
|
|
493
|
+
console.log(' atris task claim <id> --as <m> take ownership');
|
|
494
|
+
console.log(' atris task ready <id> --proof "..."');
|
|
495
|
+
console.log(' atris review validate');
|
|
496
|
+
console.log(' atris recap spoken recap of what landed');
|
|
497
|
+
console.log(' atris mission status active goals + next move');
|
|
498
|
+
console.log('');
|
|
499
|
+
console.log('More: atris help --all · machine list: atris help --json');
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
function helpCatalog() {
|
|
503
|
+
return [
|
|
504
|
+
{ name: 'init', summary: 'scaffold atris/ in this project', json: false, interactive_risk: 'medium' },
|
|
505
|
+
{ name: 'task', summary: 'local task plane: new, claim, ready, accept', json: true, interactive_risk: 'low' },
|
|
506
|
+
{ name: 'review', summary: 'validate work and capture learnings', json: false, interactive_risk: 'low' },
|
|
507
|
+
{ name: 'recap', summary: 'spoken recap of what your team did', json: true, interactive_risk: 'low' },
|
|
508
|
+
{ name: 'mission', summary: 'durable goal + owner + verifier + tick', json: true, interactive_risk: 'medium' },
|
|
509
|
+
{ name: 'log', summary: 'append an idea to today inbox (or --repl)', json: false, interactive_risk: 'medium' },
|
|
510
|
+
{ name: 'wish', summary: 'headless inbox / mission intake', json: true, interactive_risk: 'low' },
|
|
511
|
+
{ name: 'learn', summary: 'structured project learnings', json: false, interactive_risk: 'low' },
|
|
512
|
+
{ name: 'activate', summary: 'load atris context for this session', json: false, interactive_risk: 'low' },
|
|
513
|
+
{ name: 'status', summary: 'local work and completions', json: true, interactive_risk: 'low' },
|
|
514
|
+
{ name: 'engine', summary: 'engine roster, ask, validate, dispatch', json: true, interactive_risk: 'low' },
|
|
515
|
+
{ name: 'help', summary: 'this help (default short; --all full)', json: true, interactive_risk: 'none' },
|
|
516
|
+
];
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
function showHelpAll() {
|
|
450
520
|
console.log('');
|
|
451
521
|
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
452
522
|
console.log('atris');
|
|
453
523
|
console.log('you say what you want in plain words. atris builds it, checks it, and shows you proof.');
|
|
454
524
|
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
455
525
|
console.log('');
|
|
456
|
-
console.log('Quick
|
|
526
|
+
console.log('Quick start:');
|
|
457
527
|
console.log('');
|
|
458
|
-
console.log(' 1. atris
|
|
459
|
-
console.log(' npx atris
|
|
460
|
-
console.log(' 2.
|
|
461
|
-
console.log(' 3.
|
|
528
|
+
console.log(' 1. atris load context (MAP, tasks, journal)');
|
|
529
|
+
console.log(' npx atris same after a local install');
|
|
530
|
+
console.log(' 2. say what you want built, checked, or researched');
|
|
531
|
+
console.log(' 3. atris files the work, then you review');
|
|
462
532
|
console.log('');
|
|
463
533
|
console.log('Common invocations:');
|
|
464
|
-
console.log(' atris "<request>"
|
|
534
|
+
console.log(' atris "<request>" one isolated change, then Review');
|
|
465
535
|
console.log(' atris "<request>" --verify "<cmd>" --json');
|
|
466
|
-
console.log('
|
|
467
|
-
console.log(' atris init [--yes]
|
|
468
|
-
console.log('
|
|
536
|
+
console.log(' atris init [--yes] scaffold this project');
|
|
537
|
+
console.log(' npx atris init [--yes] same after a local install');
|
|
538
|
+
console.log(' atris mission status current mission + next move');
|
|
539
|
+
console.log(' atris task ready <id> --proof "..."');
|
|
469
540
|
console.log(' atris computer');
|
|
470
|
-
console.log(' atris
|
|
471
|
-
console.log(' atris
|
|
472
|
-
console.log(' atris approve Approve the step waiting for you');
|
|
473
|
-
console.log(' atris stop Stop the current mission');
|
|
474
|
-
console.log(' atris check <run-id> Show the checks for a mission');
|
|
475
|
-
console.log(' atris ready --json Show which mission features are ready');
|
|
476
|
-
console.log(' atris engine validate latest check the newest ask receipt with a cheap referee');
|
|
541
|
+
console.log(' atris engine validate latest');
|
|
542
|
+
console.log(' atris playbook workspace style rules and paired trials');
|
|
477
543
|
console.log(' atris business init "My Company"');
|
|
478
544
|
console.log(' atris run');
|
|
479
545
|
console.log(' atris drill');
|
|
480
546
|
console.log(' atris status');
|
|
481
547
|
console.log(' atris soul');
|
|
482
548
|
console.log(' atris fleet status');
|
|
549
|
+
console.log(' ask/stop/ready see atris mission and atris task ready');
|
|
483
550
|
console.log('');
|
|
484
551
|
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
485
552
|
console.log('');
|
|
@@ -490,7 +557,8 @@ function showHelp() {
|
|
|
490
557
|
console.log('');
|
|
491
558
|
console.log('Setup:');
|
|
492
559
|
console.log(' setup - Guided first-time setup (login, pick business, pull)');
|
|
493
|
-
console.log(' init - Initialize Atris in current project (--yes skips prompts)');
|
|
560
|
+
console.log(' init - Initialize Atris in current project (--yes skips prompts; --minimal for lean scaffold)');
|
|
561
|
+
console.log(' install - Install the atris/ brain if missing (alias: workspace install)');
|
|
494
562
|
console.log(' update - Update local files to latest version');
|
|
495
563
|
console.log(' upgrade - Install latest Atris from npm');
|
|
496
564
|
console.log('');
|
|
@@ -505,7 +573,7 @@ function showHelp() {
|
|
|
505
573
|
console.log(' spaceship - Bounded overnight runner that survives bad ticks and emails updates');
|
|
506
574
|
console.log('');
|
|
507
575
|
console.log('Context & tracking:');
|
|
508
|
-
console.log(' log - Add ideas to inbox');
|
|
576
|
+
console.log(' log - Add ideas to inbox (`atris log "note"`; `log --repl` for the editor; see also `wish`)');
|
|
509
577
|
console.log(' wish - Say one plain sentence, then Atris asks only for gaps or delegates it');
|
|
510
578
|
console.log(' now - Show atris/now.md, the current operating truth');
|
|
511
579
|
console.log(' goal - goal, distance, and what moved today (alias: wtf)');
|
|
@@ -518,13 +586,15 @@ function showHelp() {
|
|
|
518
586
|
console.log(' team - One team view: members, roles, engine assignments (presence for live)');
|
|
519
587
|
console.log(' watch - Turn one sentence into an always-on background watcher');
|
|
520
588
|
console.log(' ctop - Show a process-first live agent CPU/memory view');
|
|
589
|
+
console.log(' doctor - Node/task/auth/workspace readiness (--json for agents)');
|
|
521
590
|
console.log(' launchpad - Show the next action from local brain, task, mission, and proof state');
|
|
522
591
|
console.log(' brief - Show the one-glance operator brief');
|
|
523
592
|
console.log(' status - See local work and completions (`atris status <business>` for remote)');
|
|
524
|
-
console.log(' recap - What your AI team did, in
|
|
593
|
+
console.log(' recap - What your AI team did, in spoken lines (--verbose for the old report)');
|
|
525
594
|
console.log(' report - Weekly block: landings, journal completions, and Career XP');
|
|
526
595
|
console.log(' xp - Show Career XP and contribution graph');
|
|
527
596
|
console.log(' analytics - Show recent productivity from journals');
|
|
597
|
+
console.log(' revisions - show possible human revisions after atris-assisted landings');
|
|
528
598
|
console.log(' search - Search workspace memory (atris search <keyword>)');
|
|
529
599
|
console.log(' clean - Housekeeping (stale tasks, archive journals, broken refs)');
|
|
530
600
|
console.log(' close - track open loops with deadlines and daily escalation');
|
|
@@ -542,14 +612,14 @@ function showHelp() {
|
|
|
542
612
|
console.log(' atris autoland tick # second check runs, task lands');
|
|
543
613
|
console.log(' mission - Goal + loop + member owner + verifier + receipt; --budget quick|long|deep sets bounded tiers');
|
|
544
614
|
console.log(' decide - Answer open mission asks and send the decision to the next tick');
|
|
545
|
-
console.log(' release - Tag release, bump version, create GitHub release, draft /launch');
|
|
615
|
+
console.log(' release - Tag release, bump version, create GitHub release, draft /launch; atris release preflight before a v* tag');
|
|
546
616
|
console.log(' learn - Project learnings (patterns, pitfalls, preferences)');
|
|
547
617
|
console.log(' study - On-demand learning feed: ingest topic, start server, open browser');
|
|
548
618
|
console.log(' rainmaker - Relationship manager dashboard (atrisos-backend/scripts/rainmaker.py)');
|
|
549
619
|
console.log(' meet - onboard a stranger in one sitting and print their /book link');
|
|
550
620
|
console.log(' avail - Booking availability (/book/{username} weekly windows)');
|
|
551
621
|
console.log(' brain - Compile MAP/TODO/wiki/state into a loadable agent brain');
|
|
552
|
-
console.log(' lesson -
|
|
622
|
+
console.log(' lesson - atris lesson add <slug> <pass|fail> "<text>" (mine/sweep/resolve/revert/ledger; --detector validates the falsifier at write time)');
|
|
553
623
|
console.log(' taste - Record the operator\'s keep, kill, and more creative verdicts');
|
|
554
624
|
console.log(' teach - Turn a bad turn into a failing benchmark, then a permanent guard (red gate: no promotion without a proven failure)');
|
|
555
625
|
console.log(' ingest - Local-first wiki ingest into atris/wiki/');
|
|
@@ -572,7 +642,8 @@ function showHelp() {
|
|
|
572
642
|
console.log(' router - inspect ax lane outcomes and promote gated reflex overrides');
|
|
573
643
|
console.log(' sign - Co-author trailer on every commit in an atris workspace (on/off/status)');
|
|
574
644
|
console.log(' visualize - Generate a Slack/deck-ready visual from a prompt');
|
|
575
|
-
console.log(' youtube - Free
|
|
645
|
+
console.log(' youtube - Free search + notes, weekly digest, 5-credit paid search, or 5-credit cloud process for YouTube videos');
|
|
646
|
+
console.log(' x-search - 5-credit X/Twitter search (tweet text + x.com links)');
|
|
576
647
|
console.log('');
|
|
577
648
|
console.log('Experiments:');
|
|
578
649
|
console.log(' experiments init [slug] - Prepare atris/experiments/ or scaffold a pack');
|
|
@@ -640,12 +711,16 @@ function showHelp() {
|
|
|
640
711
|
console.log(' agent - Select cloud agent, spawn worker requests, or run `agent doctor`');
|
|
641
712
|
console.log(' chat - Chat with Atris 2 Fast in this workspace (--agent for cloud agent; or: atris chat scan)');
|
|
642
713
|
console.log(' fast - Chat with Atris2 Fast');
|
|
643
|
-
console.log(' login - Sign in or
|
|
714
|
+
console.log(' login - Sign in, add an account, or mint a scoped agent token (--agent)');
|
|
644
715
|
console.log(' logout - Sign out of current account');
|
|
645
716
|
console.log(' whoami - Show active account');
|
|
646
717
|
console.log(' switch - Switch account globally (atris switch <name>)');
|
|
647
718
|
console.log(' use - Set account for this terminal only (atris use <name>)');
|
|
648
719
|
console.log(' accounts - Manage accounts (list, add, remove)');
|
|
720
|
+
console.log(' balance - Show credit balance in dollars');
|
|
721
|
+
console.log(' usage - Show developer API usage');
|
|
722
|
+
console.log(' api-key - Create, list, rotate, or revoke a developer API key');
|
|
723
|
+
console.log(' topup - Buy credits and print a Stripe checkout URL');
|
|
649
724
|
console.log('');
|
|
650
725
|
console.log('Integrations:');
|
|
651
726
|
console.log(' github - github cli wrapper (doctor, auth, pr list/create/checks/view)');
|
|
@@ -653,7 +728,7 @@ function showHelp() {
|
|
|
653
728
|
console.log(' supabase - supabase cli wrapper (doctor, auth, status/db/functions)');
|
|
654
729
|
console.log(' linear - linear cli wrapper (doctor, auth, issue list/create/view/update)');
|
|
655
730
|
console.log(' stripe - stripe cli wrapper (doctor, auth, listen/trigger/products)');
|
|
656
|
-
console.log(' gmail -
|
|
731
|
+
console.log(' gmail - email commands (connect, inbox, read, archive, accounts, use)');
|
|
657
732
|
console.log(' calendar - Calendar commands (today, week)');
|
|
658
733
|
console.log(' twitter - Twitter commands (post)');
|
|
659
734
|
console.log(' slack - Slack commands (channels)');
|
|
@@ -666,6 +741,7 @@ function showHelp() {
|
|
|
666
741
|
console.log(' skill list - Show all skills with compliance status');
|
|
667
742
|
console.log(' skill audit [name] - Validate skill against Anthropic guide');
|
|
668
743
|
console.log(' skill fix [name] - Auto-fix common compliance issues');
|
|
744
|
+
console.log(' skill eval <path> - Run an independent rubric review and write its receipt');
|
|
669
745
|
console.log(' skill delete <name> - Delete a skill and its symlinks');
|
|
670
746
|
console.log('');
|
|
671
747
|
console.log('Team:');
|
|
@@ -682,47 +758,64 @@ function showHelp() {
|
|
|
682
758
|
console.log('Feedback:');
|
|
683
759
|
console.log(' feedback "msg" - Submit feedback');
|
|
684
760
|
console.log(' feedback - List feedback queue');
|
|
761
|
+
console.log(' feedback triage <id> - Print a reproduction brief (--dispatch to run)');
|
|
685
762
|
console.log(' feedback resolve <id> "<note>" - Mark resolved (admin)');
|
|
686
763
|
console.log(' feedback close <id> - Close as wontfix (admin)');
|
|
687
764
|
console.log(' feedback delete <id> - Delete feedback (admin)');
|
|
688
765
|
console.log('');
|
|
689
766
|
console.log('Other:');
|
|
690
767
|
console.log(' version - Show Atris version');
|
|
691
|
-
console.log(' help -
|
|
768
|
+
console.log(' help - Short golden path (help --all for every command)');
|
|
692
769
|
console.log('');
|
|
693
|
-
console.log('
|
|
770
|
+
console.log('Tip: Just run "atris" to get started');
|
|
694
771
|
console.log('');
|
|
695
772
|
}
|
|
696
773
|
|
|
774
|
+
function showHelp(options = {}) {
|
|
775
|
+
const args = options.args || process.argv.slice(3);
|
|
776
|
+
const asJson = options.json === true || args.includes('--json');
|
|
777
|
+
const all = options.all === true || args.includes('--all');
|
|
778
|
+
if (asJson) {
|
|
779
|
+
console.log(JSON.stringify({ ok: true, commands: helpCatalog() }, null, 2));
|
|
780
|
+
return;
|
|
781
|
+
}
|
|
782
|
+
if (all) {
|
|
783
|
+
showHelpAll();
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
showHelpShort();
|
|
787
|
+
}
|
|
788
|
+
|
|
697
789
|
function showPlanHelp() {
|
|
698
790
|
console.log('');
|
|
699
|
-
console.log('Usage: atris plan [--execute] [--full]');
|
|
791
|
+
console.log('Usage: atris plan [--execute] [--prompt|--verbose|--full]');
|
|
700
792
|
console.log('');
|
|
701
793
|
console.log('Description:');
|
|
702
|
-
console.log('
|
|
703
|
-
console.log('
|
|
704
|
-
console.log('
|
|
794
|
+
console.log(' Same two spoken lines as bare atris.');
|
|
795
|
+
console.log(' --prompt prints the navigator copy/paste prompt.');
|
|
796
|
+
console.log(' Leftover words stay a request.');
|
|
705
797
|
console.log('');
|
|
706
798
|
console.log('Options:');
|
|
707
|
-
console.log(' --execute
|
|
708
|
-
console.log(' --
|
|
709
|
-
console.log(' --verbose Alias for --full.');
|
|
799
|
+
console.log(' --execute ACTION TAKEN: run in agent mode via Atris cloud (requires login + agent).');
|
|
800
|
+
console.log(' --prompt Print the navigator copy/paste prompt.');
|
|
801
|
+
console.log(' --verbose Alias for --prompt, plus full spec dumps.');
|
|
802
|
+
console.log(' --full Alias for --verbose.');
|
|
710
803
|
console.log('');
|
|
711
804
|
}
|
|
712
805
|
|
|
713
806
|
function showDoHelp() {
|
|
714
807
|
console.log('');
|
|
715
|
-
console.log('Usage: atris do [--execute] [--full]');
|
|
808
|
+
console.log('Usage: atris do [--execute] [--prompt|--verbose|--full]');
|
|
716
809
|
console.log('');
|
|
717
810
|
console.log('Description:');
|
|
718
|
-
console.log('
|
|
719
|
-
console.log('
|
|
720
|
-
console.log(' execution instructions (and, in agent mode, edits code + runs commands).');
|
|
811
|
+
console.log(' Same two spoken lines as bare atris.');
|
|
812
|
+
console.log(' --prompt prints the executor copy/paste prompt.');
|
|
721
813
|
console.log('');
|
|
722
814
|
console.log('Options:');
|
|
723
|
-
console.log(' --execute
|
|
724
|
-
console.log(' --
|
|
725
|
-
console.log(' --verbose Alias for --full.');
|
|
815
|
+
console.log(' --execute ACTION TAKEN: edit code + run commands via Atris cloud.');
|
|
816
|
+
console.log(' --prompt Print the executor copy/paste prompt.');
|
|
817
|
+
console.log(' --verbose Alias for --prompt, plus full spec dumps.');
|
|
818
|
+
console.log(' --full Alias for --verbose.');
|
|
726
819
|
console.log('');
|
|
727
820
|
}
|
|
728
821
|
|
|
@@ -731,8 +824,9 @@ function showReviewHelp() {
|
|
|
731
824
|
console.log('Usage: atris review [--limit N|--all|--json] [--full|--execute]');
|
|
732
825
|
console.log('');
|
|
733
826
|
console.log('Description:');
|
|
734
|
-
console.log(' Show the
|
|
735
|
-
console.log('
|
|
827
|
+
console.log(' Show the one finished thing waiting for your ok.');
|
|
828
|
+
console.log(' Certified work leads with atris task accept. Uncertified stays');
|
|
829
|
+
console.log(' still being checked. Use --json/--all for the full queue.');
|
|
736
830
|
console.log(' Use --full/--verbose for the legacy Validator prompt.');
|
|
737
831
|
console.log('');
|
|
738
832
|
console.log('Options:');
|
|
@@ -773,6 +867,21 @@ function showAnalyticsHelp() {
|
|
|
773
867
|
console.log('');
|
|
774
868
|
}
|
|
775
869
|
|
|
870
|
+
function showRevisionsHelp() {
|
|
871
|
+
console.log('');
|
|
872
|
+
console.log('usage: atris revisions [--json]');
|
|
873
|
+
console.log('');
|
|
874
|
+
console.log('description:');
|
|
875
|
+
console.log(' count possible human revisions after atris-assisted landings.');
|
|
876
|
+
console.log(' uses same-file git follow-ups as a signal, not proof of intent.');
|
|
877
|
+
console.log(' saves one rolling seven-day summary row per utc day.');
|
|
878
|
+
console.log('');
|
|
879
|
+
console.log('options:');
|
|
880
|
+
console.log(' --json print the measured landings and revision signals as json.');
|
|
881
|
+
console.log(' --help, -h show this help.');
|
|
882
|
+
console.log('');
|
|
883
|
+
}
|
|
884
|
+
|
|
776
885
|
function showActivateHelp() {
|
|
777
886
|
console.log('');
|
|
778
887
|
console.log('Usage: atris activate');
|
|
@@ -820,15 +929,18 @@ function showVerifyHelp() {
|
|
|
820
929
|
function showUpdateHelp(commandName = 'update') {
|
|
821
930
|
console.log('');
|
|
822
931
|
const selfFlag = commandName === 'update' ? ' [--self]' : '';
|
|
823
|
-
console.log(`Usage: atris ${commandName} [--all] [--dry-run] [--force]${selfFlag}`);
|
|
932
|
+
console.log(`Usage: atris ${commandName} [--all] [--dry-run] [--yes] [--force]${selfFlag}`);
|
|
824
933
|
console.log('');
|
|
825
934
|
console.log('Description:');
|
|
826
935
|
console.log(' Sync Atris workspace files from the installed CLI templates.');
|
|
936
|
+
console.log(' Default is plan-only: print the file list and exit without writing.');
|
|
937
|
+
console.log(' Pass --yes to apply writes. Non-TTY sessions without --yes exit 2.');
|
|
827
938
|
console.log('');
|
|
828
939
|
console.log('Options:');
|
|
829
940
|
console.log(' --all Update Atris files across projects under the current tree.');
|
|
830
941
|
console.log(' --dry-run Preview update work without writing files.');
|
|
831
|
-
console.log(' --
|
|
942
|
+
console.log(' --yes, -y Apply the planned writes.');
|
|
943
|
+
console.log(' --force Overwrite existing template files where supported (with --yes).');
|
|
832
944
|
if (commandName === 'update') {
|
|
833
945
|
console.log(' --self Update the installed atris cli from npm (packaged installs only).');
|
|
834
946
|
}
|
|
@@ -852,9 +964,11 @@ function showUpgradeHelp() {
|
|
|
852
964
|
function showReleaseHelp() {
|
|
853
965
|
console.log('');
|
|
854
966
|
console.log('Usage: atris release [--dry-run]');
|
|
967
|
+
console.log(' atris release preflight');
|
|
855
968
|
console.log('');
|
|
856
969
|
console.log('Description:');
|
|
857
970
|
console.log(' Draft or publish a release from local git history.');
|
|
971
|
+
console.log(' preflight checks master, a clean tree, origin/master, the version tag, and the full test suite with CI=true.');
|
|
858
972
|
console.log('');
|
|
859
973
|
console.log('Options:');
|
|
860
974
|
console.log(' --dry-run Print the planned release without committing, tagging, or pushing.');
|
|
@@ -864,9 +978,9 @@ function showReleaseHelp() {
|
|
|
864
978
|
|
|
865
979
|
function showAuthHelp(commandName) {
|
|
866
980
|
const usage = {
|
|
867
|
-
login: 'Usage: atris login [--token <token>] [--force]',
|
|
981
|
+
login: 'Usage: atris login [--token <token>] [--force] [--agent]',
|
|
868
982
|
logout: 'Usage: atris logout',
|
|
869
|
-
whoami: 'Usage: atris whoami',
|
|
983
|
+
whoami: 'Usage: atris whoami [--json]',
|
|
870
984
|
switch: 'Usage: atris switch [account] [--global]',
|
|
871
985
|
use: 'Usage: atris use [account]',
|
|
872
986
|
accounts: 'Usage: atris accounts [add|remove <account>|remove --all]',
|
|
@@ -877,6 +991,7 @@ function showAuthHelp(commandName) {
|
|
|
877
991
|
console.log('Description:');
|
|
878
992
|
if (commandName === 'login') {
|
|
879
993
|
console.log(' Sign in with browser OAuth or a pasted API token.');
|
|
994
|
+
console.log(' --agent mints a scoped agent token from stored credentials. No browser.');
|
|
880
995
|
} else if (commandName === 'logout') {
|
|
881
996
|
console.log(' Sign out of the current Atris account.');
|
|
882
997
|
} else if (commandName === 'whoami') {
|
|
@@ -891,8 +1006,11 @@ function showAuthHelp(commandName) {
|
|
|
891
1006
|
console.log('');
|
|
892
1007
|
console.log('Options:');
|
|
893
1008
|
if (commandName === 'login') {
|
|
894
|
-
console.log(' --token <token>
|
|
895
|
-
console.log(' --force, -f
|
|
1009
|
+
console.log(' --token <token> Save an API token without prompting.');
|
|
1010
|
+
console.log(' --force, -f Re-run login even if credentials already exist.');
|
|
1011
|
+
console.log(' --agent Mint a scoped agent token from the stored login.');
|
|
1012
|
+
console.log(' --scopes <list> Comma-separated scopes (default: x-search,youtube).');
|
|
1013
|
+
console.log(' --daily-credit-cap <n> Daily credit cap (default: 50).');
|
|
896
1014
|
} else if (commandName === 'switch') {
|
|
897
1015
|
console.log(' --global, -g Switch the account for all terminals.');
|
|
898
1016
|
}
|
|
@@ -1002,7 +1120,7 @@ function showAutopilotHelp() {
|
|
|
1002
1120
|
}
|
|
1003
1121
|
|
|
1004
1122
|
if (command === 'help' || command === '--help' || command === '-h') {
|
|
1005
|
-
showHelp();
|
|
1123
|
+
showHelp({ args: process.argv.slice(3) });
|
|
1006
1124
|
process.exit(0);
|
|
1007
1125
|
}
|
|
1008
1126
|
|
|
@@ -1043,26 +1161,20 @@ if (isSpecFile(command)) {
|
|
|
1043
1161
|
|
|
1044
1162
|
// --version flag (works anywhere: atris --version, atris -v)
|
|
1045
1163
|
if (command === '--version' || command === '-v' || process.argv.includes('--version')) {
|
|
1046
|
-
console.log(
|
|
1164
|
+
console.log(formatCliVersionLine(CLI_VERSION, path.join(__dirname, '..')));
|
|
1047
1165
|
process.exit(0);
|
|
1048
1166
|
}
|
|
1049
1167
|
|
|
1050
1168
|
// If no command OR command is not recognized, treat as natural language
|
|
1051
1169
|
// Voice-friendly aliases — natural language → command mapping
|
|
1052
1170
|
// Solves speech-to-text issues (inspired by gstack v0.14.6 voice-triggers)
|
|
1053
|
-
|
|
1054
|
-
|
|
1171
|
+
// One-word voice aliases like start/go/audit/deploy must not spawn runners.
|
|
1172
|
+
// Unmatched single verbs exit 2 with did-you-mean (see below). Keep phrases
|
|
1173
|
+
// that name a real command without overnight side effects.
|
|
1055
1174
|
const voiceTriggers = {
|
|
1056
|
-
'start': '_start',
|
|
1057
|
-
'start now': '_start',
|
|
1058
|
-
'go': '_start',
|
|
1059
|
-
'keep going': '_start',
|
|
1060
|
-
'keepgoing': '_start',
|
|
1061
|
-
'keep-going': '_start',
|
|
1062
1175
|
'review my code': 'code-review',
|
|
1063
1176
|
'check my code': 'code-review',
|
|
1064
1177
|
'run a review': 'code-review',
|
|
1065
|
-
'audit': 'code-review',
|
|
1066
1178
|
'create a business': 'business',
|
|
1067
1179
|
'start a business': 'business',
|
|
1068
1180
|
'new business': 'business',
|
|
@@ -1072,7 +1184,6 @@ const voiceTriggers = {
|
|
|
1072
1184
|
'what is going on': 'radar',
|
|
1073
1185
|
'run tests': 'verify',
|
|
1074
1186
|
'check health': 'status',
|
|
1075
|
-
'deploy': 'business',
|
|
1076
1187
|
'show my businesses': 'business',
|
|
1077
1188
|
'pull latest': 'pull',
|
|
1078
1189
|
'push changes': 'push',
|
|
@@ -1080,6 +1191,17 @@ const voiceTriggers = {
|
|
|
1080
1191
|
'what did i learn': 'learn',
|
|
1081
1192
|
};
|
|
1082
1193
|
|
|
1194
|
+
// -h/--help/help on argv[1] (including voice words like start) is usage
|
|
1195
|
+
// + exit 2 before NL and before _start. Never file a task titled a flag.
|
|
1196
|
+
if (command && !knownCommands.includes(command) && argsWantHelp(process.argv.slice(2))) {
|
|
1197
|
+
if (String(command).toLowerCase() === 'start') showStartHelp();
|
|
1198
|
+
else {
|
|
1199
|
+
showHelpShort();
|
|
1200
|
+
console.log('Usage: atris help');
|
|
1201
|
+
}
|
|
1202
|
+
process.exit(2);
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1083
1205
|
if (!command || !knownCommands.includes(command)) {
|
|
1084
1206
|
// Check voice triggers before falling through to natural language
|
|
1085
1207
|
const fullInput = process.argv.slice(2).join(' ').toLowerCase().trim();
|
|
@@ -1099,11 +1221,31 @@ if (!command || !knownCommands.includes(command)) {
|
|
|
1099
1221
|
if (!command || !knownCommands.includes(command)) {
|
|
1100
1222
|
const rawNaturalArgs = process.argv.slice(2);
|
|
1101
1223
|
const natural = parseNaturalEntryArgs(rawNaturalArgs);
|
|
1224
|
+
if (command && isBareAtrisFlag(command)) {
|
|
1225
|
+
command = '';
|
|
1226
|
+
}
|
|
1102
1227
|
const userInput = natural.input;
|
|
1103
|
-
const directSingleWordNatural = !natural.multiword
|
|
1104
|
-
&& SINGLE_WORD_NATURAL_INTENTS.has(userInput.toLowerCase());
|
|
1105
1228
|
|
|
1106
|
-
|
|
1229
|
+
// An unmatched first token that looks like a command (or a typo of one)
|
|
1230
|
+
// is not a request to create work, even when extra args follow
|
|
1231
|
+
// (`atris taks list`). A lone verb (`atris build`) is also unknown:
|
|
1232
|
+
// never mint a task from argv[1]. Quoted sentences (`atris "build
|
|
1233
|
+
// the site"`), multiword phrases (`atris build a thing`), task new,
|
|
1234
|
+
// and wish still create work.
|
|
1235
|
+
const firstToken = String((natural.positionals && natural.positionals[0]) || command || '').trim();
|
|
1236
|
+
const firstLooksLikeCommand = Boolean(firstToken) && !/\s/.test(firstToken);
|
|
1237
|
+
const firstIsWorkVerb = SINGLE_WORD_NATURAL_INTENTS.has(firstToken.toLowerCase());
|
|
1238
|
+
// `atris test` is the documented first-minute alias, not an unknown command
|
|
1239
|
+
// and not a new first task. Extra words (`atris test the login`) still
|
|
1240
|
+
// create work once MAP is real.
|
|
1241
|
+
const firstMinuteAlias = firstToken.toLowerCase() === 'test' && !natural.multiword;
|
|
1242
|
+
const unknownCommandToken = Boolean(command)
|
|
1243
|
+
&& firstLooksLikeCommand
|
|
1244
|
+
&& !knownCommands.includes(firstToken)
|
|
1245
|
+
&& !firstMinuteAlias
|
|
1246
|
+
&& (!natural.multiword || !firstIsWorkVerb);
|
|
1247
|
+
|
|
1248
|
+
if (unknownCommandToken && natural.asJson) {
|
|
1107
1249
|
console.log(JSON.stringify({
|
|
1108
1250
|
ok: false,
|
|
1109
1251
|
error: command ? `unknown command: ${command}` : 'unknown command',
|
|
@@ -1114,18 +1256,26 @@ if (!command || !knownCommands.includes(command)) {
|
|
|
1114
1256
|
process.exit(2);
|
|
1115
1257
|
}
|
|
1116
1258
|
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
console.
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1259
|
+
if (unknownCommandToken) {
|
|
1260
|
+
const suggestions = suggestCommands(command);
|
|
1261
|
+
console.error(`Unknown command: "${command}". Run "atris help" for available commands.`);
|
|
1262
|
+
if (suggestions.length) {
|
|
1263
|
+
console.error(`Did you mean ${suggestions.map((name) => `"atris ${name}"`).join(' or ')}?`);
|
|
1264
|
+
} else {
|
|
1265
|
+
console.error('To create work from a sentence, run: atris "<request>" (quoted), or atris task new / atris wish.');
|
|
1123
1266
|
}
|
|
1124
|
-
|
|
1267
|
+
process.exit(2);
|
|
1125
1268
|
}
|
|
1126
1269
|
|
|
1127
1270
|
// Launch interactive entry (the "Performance")
|
|
1128
|
-
interactiveEntry(
|
|
1271
|
+
interactiveEntry(firstMinuteAlias ? '' : userInput, {
|
|
1272
|
+
oneLap: true,
|
|
1273
|
+
asJson: natural.asJson,
|
|
1274
|
+
engine: natural.engine,
|
|
1275
|
+
verifier: natural.verifier,
|
|
1276
|
+
optionError: natural.error,
|
|
1277
|
+
firstMinuteAlias,
|
|
1278
|
+
})
|
|
1129
1279
|
.then((code) => process.exit(Number.isInteger(code) ? code : 0))
|
|
1130
1280
|
.catch((error) => {
|
|
1131
1281
|
console.error(`✗ Error: ${error.message || error}`);
|
|
@@ -1149,7 +1299,12 @@ function printAtrisOverview() {
|
|
|
1149
1299
|
}
|
|
1150
1300
|
|
|
1151
1301
|
function useInteractiveAtrisUi() {
|
|
1152
|
-
return Boolean(
|
|
1302
|
+
return Boolean(
|
|
1303
|
+
process.stdin.isTTY
|
|
1304
|
+
&& process.stdout.isTTY
|
|
1305
|
+
&& !process.env.ATRIS_NO_INTERACTIVE
|
|
1306
|
+
&& process.env.ATRIS_NONINTERACTIVE !== '1'
|
|
1307
|
+
);
|
|
1153
1308
|
}
|
|
1154
1309
|
|
|
1155
1310
|
function initNonInteractiveFlag() {
|
|
@@ -1189,21 +1344,44 @@ function printFirstUseNext() {
|
|
|
1189
1344
|
console.log(`Then: ${firstUseCommand()}`);
|
|
1190
1345
|
}
|
|
1191
1346
|
|
|
1192
|
-
function
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1347
|
+
function runMinimalInit() {
|
|
1348
|
+
const script = process.argv[1] || path.join(__dirname, 'atris.js');
|
|
1349
|
+
const result = spawnSync(process.execPath, [script, 'init', '--minimal', '--yes'], {
|
|
1350
|
+
cwd: process.cwd(),
|
|
1351
|
+
env: process.env,
|
|
1352
|
+
encoding: 'utf8',
|
|
1353
|
+
stdio: 'inherit',
|
|
1354
|
+
});
|
|
1355
|
+
return Number.isInteger(result.status) ? result.status : 1;
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
function printFirstMinuteScreen(options) {
|
|
1359
|
+
const screen = buildFirstMinute(options);
|
|
1360
|
+
console.log('');
|
|
1361
|
+
console.log(screen.text);
|
|
1362
|
+
return screen;
|
|
1199
1363
|
}
|
|
1200
1364
|
|
|
1201
1365
|
async function interactiveEntry(userInput, options = {}) {
|
|
1202
1366
|
const workspaceDir = process.cwd();
|
|
1203
1367
|
const state = detectWorkspaceState(workspaceDir);
|
|
1368
|
+
|
|
1369
|
+
// Fresh folder is the first-minute product: one next command, no menu.
|
|
1370
|
+
if (state.state === 'fresh') {
|
|
1371
|
+
if (options.asJson) {
|
|
1372
|
+
console.log(JSON.stringify(freshMinuteJson(), null, 2));
|
|
1373
|
+
return 2;
|
|
1374
|
+
}
|
|
1375
|
+
if (shouldAutoInitFresh(process.argv.slice(2))) {
|
|
1376
|
+
return runMinimalInit();
|
|
1377
|
+
}
|
|
1378
|
+
printFirstMinuteScreen({ root: workspaceDir, fresh: true });
|
|
1379
|
+
return 0;
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1204
1382
|
const context = loadContext(workspaceDir);
|
|
1205
1383
|
|
|
1206
|
-
if (options.asJson && !String(userInput || '').trim()) {
|
|
1384
|
+
if (options.asJson && !String(userInput || '').trim() && !options.firstMinuteAlias) {
|
|
1207
1385
|
console.log(JSON.stringify({
|
|
1208
1386
|
schema: 'atris.one_lap.v1',
|
|
1209
1387
|
ok: false,
|
|
@@ -1229,25 +1407,6 @@ async function interactiveEntry(userInput, options = {}) {
|
|
|
1229
1407
|
return;
|
|
1230
1408
|
}
|
|
1231
1409
|
|
|
1232
|
-
// Fresh install - offer init
|
|
1233
|
-
if (state.state === 'fresh') {
|
|
1234
|
-
if (options.asJson) {
|
|
1235
|
-
console.log(JSON.stringify({
|
|
1236
|
-
schema: 'atris.one_lap.v1',
|
|
1237
|
-
ok: false,
|
|
1238
|
-
status: 'stuck',
|
|
1239
|
-
reason: 'this workspace is not initialized',
|
|
1240
|
-
next_action: 'atris init --yes',
|
|
1241
|
-
}, null, 2));
|
|
1242
|
-
return 2;
|
|
1243
|
-
}
|
|
1244
|
-
console.log('\nNo atris/ folder found.');
|
|
1245
|
-
console.log('');
|
|
1246
|
-
console.log('Next: atris init');
|
|
1247
|
-
console.log('Local project install instead? Run: npx atris init');
|
|
1248
|
-
return;
|
|
1249
|
-
}
|
|
1250
|
-
|
|
1251
1410
|
// Ensure today's journal exists (so "atris" always has somewhere to write/read)
|
|
1252
1411
|
try {
|
|
1253
1412
|
ensureLogDirectory();
|
|
@@ -1302,6 +1461,29 @@ async function interactiveEntry(userInput, options = {}) {
|
|
|
1302
1461
|
return 2;
|
|
1303
1462
|
}
|
|
1304
1463
|
|
|
1464
|
+
// Placeholder or missing MAP is already a first-minute job. Do not send the
|
|
1465
|
+
// operator to a rewrite lobby, and do not treat `test` as a new first task.
|
|
1466
|
+
if (mapStatus !== 'ready') {
|
|
1467
|
+
const screenOptions = {
|
|
1468
|
+
root: workspaceDir,
|
|
1469
|
+
context,
|
|
1470
|
+
missions: activeMissions,
|
|
1471
|
+
};
|
|
1472
|
+
if (options.asJson) {
|
|
1473
|
+
const screen = buildFirstMinute(screenOptions);
|
|
1474
|
+
console.log(JSON.stringify({
|
|
1475
|
+
schema: 'atris.one_lap.v1',
|
|
1476
|
+
ok: false,
|
|
1477
|
+
status: 'stuck',
|
|
1478
|
+
reason: 'the generate-map task is already waiting',
|
|
1479
|
+
next_action: screen.nextCommand,
|
|
1480
|
+
}, null, 2));
|
|
1481
|
+
return 2;
|
|
1482
|
+
}
|
|
1483
|
+
printFirstMinuteScreen(screenOptions);
|
|
1484
|
+
return 0;
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1305
1487
|
if (userInput && mapStatus === 'ready' && !gatherContext && options.oneLap !== false) {
|
|
1306
1488
|
return require('../commands/one-lap').runOneLap(userInput, {
|
|
1307
1489
|
root: workspaceDir,
|
|
@@ -1316,75 +1498,17 @@ async function interactiveEntry(userInput, options = {}) {
|
|
|
1316
1498
|
schema: 'atris.one_lap.v1',
|
|
1317
1499
|
ok: false,
|
|
1318
1500
|
status: 'stuck',
|
|
1319
|
-
reason:
|
|
1320
|
-
next_action:
|
|
1501
|
+
reason: 'first-contact context is required',
|
|
1502
|
+
next_action: 'atris "<first direction>"',
|
|
1321
1503
|
}, null, 2));
|
|
1322
1504
|
return 2;
|
|
1323
1505
|
}
|
|
1324
|
-
|
|
1325
|
-
// hasn't passed yet. Planning-state missions count too — first tick is what
|
|
1326
|
-
// moves them to running.
|
|
1327
|
-
const needsTickMission = activeMissions.find(
|
|
1328
|
-
(m) => m.verifier && !m.verifier_passed
|
|
1329
|
-
);
|
|
1330
|
-
|
|
1331
|
-
// Build status line
|
|
1332
|
-
const parts = [];
|
|
1333
|
-
if (wipCount > 0) {
|
|
1334
|
-
parts.push(`work in progress: ${wipCount}`);
|
|
1335
|
-
}
|
|
1336
|
-
if (liveMissionsCount > 0) {
|
|
1337
|
-
parts.push(`missions: ${liveMissionsCount}`);
|
|
1338
|
-
}
|
|
1339
|
-
if (inboxCount > 0) {
|
|
1340
|
-
parts.push(`inbox: ${inboxCount}`);
|
|
1341
|
-
}
|
|
1342
|
-
if (backlogCount > 0) {
|
|
1343
|
-
parts.push(`backlog: ${backlogCount}`);
|
|
1344
|
-
}
|
|
1345
|
-
if (completedTasksCount > 0) {
|
|
1346
|
-
parts.push(`done: ${completedTasksCount}`);
|
|
1347
|
-
}
|
|
1348
|
-
const statusLine = parts.length > 0 ? parts.join(' | ') : 'clean slate';
|
|
1506
|
+
const hasRequest = Boolean(String(userInput || '').trim());
|
|
1349
1507
|
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
if (gatherContext) {
|
|
1356
|
-
const hotAnswer = String(userInput || '').trim();
|
|
1357
|
-
if (hotAnswer) {
|
|
1358
|
-
const answer = hotAnswer;
|
|
1359
|
-
if (isAtrisMetaQuestion(answer)) {
|
|
1360
|
-
printAtrisOverview();
|
|
1361
|
-
return;
|
|
1362
|
-
}
|
|
1363
|
-
const profile = saveContextProfile(workspaceDir, answer, { source: 'hot_start' });
|
|
1364
|
-
const starter = createStarterTask(workspaceDir, answer);
|
|
1365
|
-
console.log('');
|
|
1366
|
-
console.log('Got it. I saved your first direction.');
|
|
1367
|
-
console.log(`Focus: ${profile.first_answer}`);
|
|
1368
|
-
if (starter && starter.display_id) {
|
|
1369
|
-
console.log(`First task: ${starter.display_id} — ${starter.title}`);
|
|
1370
|
-
} else if (starter && starter.title) {
|
|
1371
|
-
console.log(`First task: ${starter.title}`);
|
|
1372
|
-
}
|
|
1373
|
-
if (mapStatus !== 'ready') {
|
|
1374
|
-
printStarterTaskNext(starter);
|
|
1375
|
-
return;
|
|
1376
|
-
}
|
|
1377
|
-
await planCmd(answer);
|
|
1378
|
-
return;
|
|
1379
|
-
}
|
|
1380
|
-
if (shouldSkipContextGatherer()) {
|
|
1381
|
-
console.log('');
|
|
1382
|
-
if (process.argv.includes('--verbose')) {
|
|
1383
|
-
console.log('context gatherer skipped (non-interactive).');
|
|
1384
|
-
}
|
|
1385
|
-
printFirstUseNext();
|
|
1386
|
-
return;
|
|
1387
|
-
} else {
|
|
1508
|
+
// Bare `atris` is the first-minute screen: one win, one next command.
|
|
1509
|
+
// Interactive first-contact still asks once when the folder has no work yet.
|
|
1510
|
+
if (!hasRequest) {
|
|
1511
|
+
if (gatherContext && !shouldSkipContextGatherer()) {
|
|
1388
1512
|
const answer = await askContextGatherer(workspaceDir);
|
|
1389
1513
|
if (isAtrisMetaQuestion(answer)) {
|
|
1390
1514
|
printAtrisOverview();
|
|
@@ -1406,105 +1530,39 @@ async function interactiveEntry(userInput, options = {}) {
|
|
|
1406
1530
|
} else if (starter && starter.title) {
|
|
1407
1531
|
console.log(`First task: ${starter.title}`);
|
|
1408
1532
|
}
|
|
1409
|
-
if (mapStatus !== 'ready') {
|
|
1410
|
-
printStarterTaskNext(starter);
|
|
1411
|
-
return;
|
|
1412
|
-
}
|
|
1413
1533
|
await planCmd(answer);
|
|
1414
1534
|
return;
|
|
1415
1535
|
}
|
|
1536
|
+
printFirstMinuteScreen({
|
|
1537
|
+
root: workspaceDir,
|
|
1538
|
+
context,
|
|
1539
|
+
missions: activeMissions,
|
|
1540
|
+
});
|
|
1541
|
+
return 0;
|
|
1416
1542
|
}
|
|
1417
1543
|
|
|
1418
|
-
if (
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
// Hot start - user provided input directly
|
|
1424
|
-
if (userInput) {
|
|
1425
|
-
console.log(`\n> ${userInput}`);
|
|
1426
|
-
await planCmd(userInput);
|
|
1427
|
-
return;
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
|
-
// Surface live missions so the operator sees durable goals alongside dev WIP.
|
|
1431
|
-
if (liveMissionsCount > 0) {
|
|
1432
|
-
console.log('\nLive missions:');
|
|
1433
|
-
for (const m of activeMissions.slice(0, 5)) {
|
|
1434
|
-
const tickGate = m.verifier && !m.verifier_passed ? ' [needs tick]' : '';
|
|
1435
|
-
const obj = m.objective.length > 70 ? `${m.objective.slice(0, 67)}...` : m.objective;
|
|
1436
|
-
console.log(`- [${m.owner}] ${obj} (${m.status})${tickGate}`);
|
|
1437
|
-
}
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
|
-
// Cold start auto-advance.
|
|
1441
|
-
// ORDER MATTERS: missions outrank pipeline state because a mission's verifier
|
|
1442
|
-
// is the contract that gates the Stop hook. Closing it unblocks everything else.
|
|
1443
|
-
if (needsTickMission) {
|
|
1444
|
-
console.log(`\nNext: atris mission tick (${needsTickMission.owner} mission has unverified verifier)`);
|
|
1445
|
-
console.log(`Run: atris mission tick ${needsTickMission.id} --verify --complete-on-pass`);
|
|
1446
|
-
return;
|
|
1447
|
-
}
|
|
1448
|
-
|
|
1449
|
-
if (completedTasksCount > 0) {
|
|
1450
|
-
const preview = context.completedTasks.slice(0, 3).map((t) => (t.length > 70 ? `${t.slice(0, 67)}...` : t));
|
|
1451
|
-
if (preview.length > 0) {
|
|
1452
|
-
console.log('\nCompleted (history):');
|
|
1453
|
-
preview.forEach((t) => console.log(`- ${t}`));
|
|
1454
|
-
console.log('Completed tasks are history, not pending review.');
|
|
1455
|
-
}
|
|
1456
|
-
}
|
|
1457
|
-
|
|
1458
|
-
if (wipCount > 0 || backlogCount > 0) {
|
|
1459
|
-
const featurePreview = Array.isArray(context.inProgressFeatures) ? context.inProgressFeatures : [];
|
|
1460
|
-
const inProgressPreview = context.inProgressTasks.slice(0, 2).map((t) => (t.length > 70 ? `${t.slice(0, 67)}...` : t));
|
|
1461
|
-
const backlogPreview = context.backlogTasks.slice(0, 2).map((t) => (t.length > 70 ? `${t.slice(0, 67)}...` : t));
|
|
1462
|
-
if (featurePreview.length > 0) {
|
|
1463
|
-
console.log(`\nIn-progress features: ${featurePreview.join(', ')}`);
|
|
1464
|
-
}
|
|
1465
|
-
if (inProgressPreview.length > 0) {
|
|
1466
|
-
console.log('\nIn Progress (preview):');
|
|
1467
|
-
inProgressPreview.forEach((t) => console.log(`- ${t}`));
|
|
1468
|
-
}
|
|
1469
|
-
if (backlogPreview.length > 0) {
|
|
1470
|
-
console.log('\nBacklog (preview):');
|
|
1471
|
-
backlogPreview.forEach((t) => console.log(`- ${t}`));
|
|
1544
|
+
if (gatherContext) {
|
|
1545
|
+
const answer = String(userInput || '').trim();
|
|
1546
|
+
if (isAtrisMetaQuestion(answer)) {
|
|
1547
|
+
printAtrisOverview();
|
|
1548
|
+
return;
|
|
1472
1549
|
}
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
if (
|
|
1481
|
-
console.log(
|
|
1482
|
-
preview.forEach((t) => console.log(`- ${t}`));
|
|
1550
|
+
const profile = saveContextProfile(workspaceDir, answer, { source: 'hot_start' });
|
|
1551
|
+
const starter = createStarterTask(workspaceDir, answer);
|
|
1552
|
+
console.log('');
|
|
1553
|
+
console.log('Got it. I saved your first direction.');
|
|
1554
|
+
console.log(`Focus: ${profile.first_answer}`);
|
|
1555
|
+
if (starter && starter.display_id) {
|
|
1556
|
+
console.log(`First task: ${starter.display_id} — ${starter.title}`);
|
|
1557
|
+
} else if (starter && starter.title) {
|
|
1558
|
+
console.log(`First task: ${starter.title}`);
|
|
1483
1559
|
}
|
|
1484
|
-
|
|
1485
|
-
await planCmd();
|
|
1486
|
-
return;
|
|
1487
|
-
}
|
|
1488
|
-
|
|
1489
|
-
if (completedTasksCount > 0) {
|
|
1490
|
-
console.log('Next: atris plan (new work)');
|
|
1491
|
-
return;
|
|
1492
|
-
}
|
|
1493
|
-
|
|
1494
|
-
// No obvious next step - prompt for input
|
|
1495
|
-
const rl = readline.createInterface({
|
|
1496
|
-
input: process.stdin,
|
|
1497
|
-
output: process.stdout
|
|
1498
|
-
});
|
|
1499
|
-
|
|
1500
|
-
const request = await new Promise(r => rl.question('\nWhat do you want to build?\n> ', r));
|
|
1501
|
-
rl.close();
|
|
1502
|
-
|
|
1503
|
-
if (!request.trim()) {
|
|
1560
|
+
await planCmd(answer);
|
|
1504
1561
|
return;
|
|
1505
1562
|
}
|
|
1506
1563
|
|
|
1507
|
-
|
|
1564
|
+
console.log(`\n> ${userInput}`);
|
|
1565
|
+
await planCmd(userInput);
|
|
1508
1566
|
}
|
|
1509
1567
|
|
|
1510
1568
|
async function askContextGatherer(workspaceDir) {
|
|
@@ -1518,30 +1576,6 @@ async function askContextGatherer(workspaceDir) {
|
|
|
1518
1576
|
return answer;
|
|
1519
1577
|
}
|
|
1520
1578
|
|
|
1521
|
-
function printMapBootstrap({ userInput, prefix = 'Bootstrap required' } = {}) {
|
|
1522
|
-
console.log('');
|
|
1523
|
-
console.log('┌─────────────────────────────────────────────────────────────┐');
|
|
1524
|
-
console.log(`│ ${String(prefix).toUpperCase().padEnd(60)}│`);
|
|
1525
|
-
console.log('└─────────────────────────────────────────────────────────────┘');
|
|
1526
|
-
console.log('');
|
|
1527
|
-
console.log('Atris needs a real `atris/MAP.md` so future steps are grounded in the workspace.');
|
|
1528
|
-
console.log('');
|
|
1529
|
-
console.log('For an agent:');
|
|
1530
|
-
console.log('─────────────────────────────────────────────────────────────');
|
|
1531
|
-
console.log('Read `atris/atris.md`, then generate a complete `atris/MAP.md` for this repo.');
|
|
1532
|
-
console.log('Rules: include file:line refs, keep it grep-friendly, do NOT change code.');
|
|
1533
|
-
if (userInput) {
|
|
1534
|
-
console.log('');
|
|
1535
|
-
console.log('After MAP is generated, continue with:');
|
|
1536
|
-
console.log(`- ${userInput}`);
|
|
1537
|
-
} else {
|
|
1538
|
-
console.log('');
|
|
1539
|
-
console.log('Then rerun: atris');
|
|
1540
|
-
}
|
|
1541
|
-
console.log('─────────────────────────────────────────────────────────────');
|
|
1542
|
-
console.log('');
|
|
1543
|
-
}
|
|
1544
|
-
|
|
1545
1579
|
// Boot status: plain rows, honest numbers, one next action.
|
|
1546
1580
|
// The banner only renders in a real terminal; when a hook or agent captures
|
|
1547
1581
|
// this output it stays compact so it costs almost nothing in context.
|
|
@@ -1787,40 +1821,10 @@ if (command === 'init') {
|
|
|
1787
1821
|
console.error(`✗ Error: ${error.message || error}`);
|
|
1788
1822
|
process.exit(1);
|
|
1789
1823
|
});
|
|
1790
|
-
} else if (command === '
|
|
1791
|
-
const
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
console.log('Usage: atris start [options]');
|
|
1795
|
-
console.log('');
|
|
1796
|
-
console.log('Starts the durable mission loop for one useful self-improvement mission.');
|
|
1797
|
-
console.log('');
|
|
1798
|
-
console.log('Options:');
|
|
1799
|
-
console.log(' --json Print the mission route without starting it.');
|
|
1800
|
-
console.log(' --owner X Override mission owner.');
|
|
1801
|
-
console.log(' --cadence X Override mission cadence.');
|
|
1802
|
-
console.log('');
|
|
1803
|
-
process.exit(0);
|
|
1804
|
-
}
|
|
1805
|
-
|
|
1806
|
-
if (args.includes('--json')) {
|
|
1807
|
-
console.log(JSON.stringify({
|
|
1808
|
-
ok: true,
|
|
1809
|
-
action: 'start_mission_run',
|
|
1810
|
-
route: `atris mission run "${START_MISSION_OBJECTIVE}"`,
|
|
1811
|
-
reason: 'casual_launch',
|
|
1812
|
-
objective: START_MISSION_OBJECTIVE,
|
|
1813
|
-
expected_loop: 'mission_run',
|
|
1814
|
-
}, null, 2));
|
|
1815
|
-
process.exit(0);
|
|
1816
|
-
}
|
|
1817
|
-
|
|
1818
|
-
Promise.resolve(require('../commands/mission').missionCommand(['run', START_MISSION_OBJECTIVE, ...args]))
|
|
1819
|
-
.then(() => process.exit(process.exitCode || 0))
|
|
1820
|
-
.catch((error) => {
|
|
1821
|
-
console.error(`✗ Start failed: ${error.message || error}`);
|
|
1822
|
-
process.exit(1);
|
|
1823
|
-
});
|
|
1824
|
+
} else if (command === 'install' || command === 'workspace') {
|
|
1825
|
+
const { installCommand } = require('../commands/install');
|
|
1826
|
+
const code = installCommand(process.argv.slice(3), { verb: command });
|
|
1827
|
+
process.exit(typeof code === 'number' ? code : 0);
|
|
1824
1828
|
} else if (command === 'task') {
|
|
1825
1829
|
// SQLite-backed task plane. ~/.atris/tasks.db, gitignored, per-workspace.
|
|
1826
1830
|
Promise.resolve(require('../commands/task').run(process.argv.slice(3)))
|
|
@@ -1916,9 +1920,20 @@ if (command === 'init') {
|
|
|
1916
1920
|
.then((code) => process.exit(code || 0))
|
|
1917
1921
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
1918
1922
|
} else if (command === 'land') {
|
|
1919
|
-
|
|
1923
|
+
// landCommand can throw synchronously on empty repos; wrap so callers get a
|
|
1924
|
+
// one-line error instead of an uncaught stack from Promise.resolve(fn()).
|
|
1925
|
+
Promise.resolve()
|
|
1926
|
+
.then(() => require('../commands/land').landCommand(process.argv.slice(3)))
|
|
1920
1927
|
.then((code) => process.exit(code || 0))
|
|
1921
|
-
.catch((err) => {
|
|
1928
|
+
.catch((err) => {
|
|
1929
|
+
const msg = String(err && err.message || err || '');
|
|
1930
|
+
if (/no master\/main|no commits|not a git/i.test(msg)) {
|
|
1931
|
+
console.error(msg);
|
|
1932
|
+
} else {
|
|
1933
|
+
console.error(`land: ${msg}`);
|
|
1934
|
+
}
|
|
1935
|
+
process.exit(1);
|
|
1936
|
+
});
|
|
1922
1937
|
} else if (command === 'caretaker') {
|
|
1923
1938
|
Promise.resolve(require('../commands/caretaker').caretakerCommand(process.argv.slice(3)))
|
|
1924
1939
|
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
@@ -1956,7 +1971,7 @@ if (command === 'init') {
|
|
|
1956
1971
|
} else if (command === 'truth') {
|
|
1957
1972
|
// Truth: one table rolling up mission state, tasks, feature proof receipts, and loop heartbeats.
|
|
1958
1973
|
Promise.resolve(require('../commands/truth').truthCommand(process.argv.slice(3)))
|
|
1959
|
-
.then((code) => process.exit(code
|
|
1974
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
1960
1975
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
1961
1976
|
} else if (command === 'codex-goal') {
|
|
1962
1977
|
Promise.resolve(require('../commands/codex-goal').codexGoalCommand(process.argv.slice(3)))
|
|
@@ -1978,12 +1993,20 @@ if (command === 'init') {
|
|
|
1978
1993
|
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
1979
1994
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
1980
1995
|
} else if (command === 'rainmaker') {
|
|
1981
|
-
|
|
1982
|
-
|
|
1996
|
+
{
|
|
1997
|
+
const gate = requireAccountBound(process.argv.slice(3));
|
|
1998
|
+
if (!gate.ok) process.exit(refuseAccountGlobal());
|
|
1999
|
+
const code = require('../commands/rainmaker').rainmakerCommand(gate.args);
|
|
2000
|
+
process.exit(typeof code === 'number' ? code : 0);
|
|
2001
|
+
}
|
|
1983
2002
|
} else if (command === 'avail') {
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
2003
|
+
{
|
|
2004
|
+
const gate = requireAccountBound(process.argv.slice(3));
|
|
2005
|
+
if (!gate.ok) process.exit(refuseAccountGlobal());
|
|
2006
|
+
Promise.resolve(require('../commands/avail').availCommand(gate.args))
|
|
2007
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2008
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2009
|
+
}
|
|
1987
2010
|
} else if (command === 'meet') {
|
|
1988
2011
|
Promise.resolve(require('../commands/meet').meetCommand(process.argv.slice(3)))
|
|
1989
2012
|
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
@@ -1991,7 +2014,7 @@ if (command === 'init') {
|
|
|
1991
2014
|
} else if (command === 'brain') {
|
|
1992
2015
|
Promise.resolve()
|
|
1993
2016
|
.then(() => require('../commands/brain').brainCommand(process.argv.slice(3)))
|
|
1994
|
-
.then(() => process.exit(0))
|
|
2017
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
1995
2018
|
.catch((err) => {
|
|
1996
2019
|
const message = err.message || String(err);
|
|
1997
2020
|
if (process.argv.slice(3).includes('--json')) {
|
|
@@ -2002,9 +2025,17 @@ if (command === 'init') {
|
|
|
2002
2025
|
process.exit(1);
|
|
2003
2026
|
});
|
|
2004
2027
|
} else if (command === 'agent') {
|
|
2005
|
-
|
|
2028
|
+
{
|
|
2029
|
+
const gate = requireAccountBound(process.argv.slice(3));
|
|
2030
|
+
if (!gate.ok) process.exit(refuseAccountGlobal());
|
|
2031
|
+
// Re-slice argv so agentAtris sees args without --account.
|
|
2032
|
+
process.argv = [process.argv[0], process.argv[1], 'agent', ...gate.args];
|
|
2033
|
+
agentAtris().then(() => process.exit(0)).catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2034
|
+
}
|
|
2006
2035
|
} else if (command === 'log') {
|
|
2007
|
-
const
|
|
2036
|
+
const logArgs = process.argv.slice(3);
|
|
2037
|
+
const subcommand = logArgs[0];
|
|
2038
|
+
const positional = logArgs.filter((arg) => !String(arg).startsWith('-'));
|
|
2008
2039
|
if (subcommand === 'sync') {
|
|
2009
2040
|
require('../commands/log-sync').logSyncAtris()
|
|
2010
2041
|
.then(() => process.exit(0))
|
|
@@ -2013,15 +2044,22 @@ if (command === 'init') {
|
|
|
2013
2044
|
process.exit(1);
|
|
2014
2045
|
});
|
|
2015
2046
|
} else if (subcommand === '--help' || subcommand === '-h' || subcommand === 'help') {
|
|
2016
|
-
console.log('Usage: atris log [
|
|
2047
|
+
console.log('Usage: atris log ["note"] | --repl | sync | <business-slug> | help');
|
|
2017
2048
|
console.log('');
|
|
2018
|
-
console.log(' atris log
|
|
2019
|
-
console.log(' atris log
|
|
2049
|
+
console.log(' atris log "an idea" Append a note to today\'s ## Inbox');
|
|
2050
|
+
console.log(' atris log --repl Open today\'s journal REPL');
|
|
2051
|
+
console.log(' atris log Open the REPL (needs a terminal)');
|
|
2020
2052
|
console.log(' atris log sync Sync the local journal to cloud');
|
|
2053
|
+
console.log(' atris log <slug> Show business log history (single slug token)');
|
|
2054
|
+
console.log(' atris wish "..." Headless inbox write; add --json --no-mission for agents');
|
|
2021
2055
|
process.exit(0);
|
|
2022
|
-
} else if (
|
|
2023
|
-
|
|
2024
|
-
|
|
2056
|
+
} else if (
|
|
2057
|
+
positional.length === 1
|
|
2058
|
+
&& !logArgs.includes('--repl')
|
|
2059
|
+
&& /^[a-z0-9][a-z0-9_-]{0,63}$/i.test(positional[0])
|
|
2060
|
+
) {
|
|
2061
|
+
// Business log: atris log <business-slug> (single slug token only)
|
|
2062
|
+
require('../commands/context-sync').businessLog(positional[0])
|
|
2025
2063
|
.then(() => process.exit(0))
|
|
2026
2064
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2027
2065
|
} else {
|
|
@@ -2090,13 +2128,15 @@ if (command === 'init') {
|
|
|
2090
2128
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2091
2129
|
} else if (process.argv.includes('--all')) {
|
|
2092
2130
|
const dryRun = process.argv.includes('--dry-run');
|
|
2093
|
-
const
|
|
2094
|
-
|
|
2131
|
+
const yes = process.argv.includes('--yes') || process.argv.includes('-y');
|
|
2132
|
+
const force = process.argv.includes('--force') || yes;
|
|
2133
|
+
Promise.resolve(syncAllCmd({ dryRun, force, yes }))
|
|
2095
2134
|
.then(() => process.exit(0))
|
|
2096
2135
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2097
2136
|
} else {
|
|
2098
2137
|
syncCmd({
|
|
2099
2138
|
dryRun: args.includes('--dry-run'),
|
|
2139
|
+
yes: args.includes('--yes') || args.includes('-y'),
|
|
2100
2140
|
force: args.includes('--force') || args.includes('--yes') || args.includes('-y'),
|
|
2101
2141
|
});
|
|
2102
2142
|
}
|
|
@@ -2140,6 +2180,14 @@ if (command === 'init') {
|
|
|
2140
2180
|
showServeHelp();
|
|
2141
2181
|
process.exit(0);
|
|
2142
2182
|
}
|
|
2183
|
+
const { refuseHeadlessUnless } = require('../lib/noninteractive');
|
|
2184
|
+
if (refuseHeadlessUnless(serveArgs, {
|
|
2185
|
+
allowYes: false,
|
|
2186
|
+
allowOnce: true,
|
|
2187
|
+
usage: 'Usage: atris serve [--agent <id>] [--allow-bash] [--once <op_id>]\nHeadless serve needs --once <op_id>.',
|
|
2188
|
+
})) {
|
|
2189
|
+
process.exit(2);
|
|
2190
|
+
}
|
|
2143
2191
|
const serveOptions = {};
|
|
2144
2192
|
for (let i = 0; i < serveArgs.length; i++) {
|
|
2145
2193
|
if (serveArgs[i] === '--agent' && serveArgs[i + 1]) {
|
|
@@ -2147,6 +2195,9 @@ if (command === 'init') {
|
|
|
2147
2195
|
i++;
|
|
2148
2196
|
} else if (serveArgs[i] === '--allow-bash') {
|
|
2149
2197
|
serveOptions.allowBash = true;
|
|
2198
|
+
} else if (serveArgs[i] === '--once' && serveArgs[i + 1]) {
|
|
2199
|
+
serveOptions.once = serveArgs[i + 1];
|
|
2200
|
+
i++;
|
|
2150
2201
|
}
|
|
2151
2202
|
}
|
|
2152
2203
|
require('../commands/serve').serveAtris(serveOptions)
|
|
@@ -2155,7 +2206,7 @@ if (command === 'init') {
|
|
|
2155
2206
|
process.exit(1);
|
|
2156
2207
|
});
|
|
2157
2208
|
} else if (command === 'version') {
|
|
2158
|
-
require('../commands/version').showVersion();
|
|
2209
|
+
require('../commands/version').showVersion(process.argv.slice(3));
|
|
2159
2210
|
} else if (command === 'login') {
|
|
2160
2211
|
const args = process.argv.slice(3);
|
|
2161
2212
|
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
@@ -2197,7 +2248,23 @@ if (command === 'init') {
|
|
|
2197
2248
|
showAuthHelp('accounts');
|
|
2198
2249
|
process.exit(0);
|
|
2199
2250
|
}
|
|
2200
|
-
require('../commands/auth').accountsCmd();
|
|
2251
|
+
require('../commands/auth').accountsCmd(args);
|
|
2252
|
+
} else if (command === 'balance') {
|
|
2253
|
+
Promise.resolve(require('../commands/balance').balanceCommand(process.argv.slice(3)))
|
|
2254
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2255
|
+
.catch((err) => { console.error(String(err.message || err).replace(/\s+/g, ' ')); process.exit(1); });
|
|
2256
|
+
} else if (command === 'usage') {
|
|
2257
|
+
Promise.resolve(require('../commands/usage').usageCommand(process.argv.slice(3)))
|
|
2258
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2259
|
+
.catch((err) => { console.error(String(err.message || err).replace(/\s+/g, ' ')); process.exit(1); });
|
|
2260
|
+
} else if (command === 'api-key') {
|
|
2261
|
+
Promise.resolve(require('../commands/api-key').apiKeyCommand(process.argv.slice(3)))
|
|
2262
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2263
|
+
.catch((err) => { console.error(String(err.message || err).replace(/\s+/g, ' ')); process.exit(1); });
|
|
2264
|
+
} else if (command === 'topup') {
|
|
2265
|
+
Promise.resolve(require('../commands/topup').topupCommand(process.argv.slice(3)))
|
|
2266
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2267
|
+
.catch((err) => { console.error(String(err.message || err).replace(/\s+/g, ' ')); process.exit(1); });
|
|
2201
2268
|
} else if (command === '_resolve') {
|
|
2202
2269
|
// Hidden: resolve a profile name query → print exact profile name
|
|
2203
2270
|
require('../commands/auth').resolveProfile();
|
|
@@ -2220,6 +2287,10 @@ if (command === 'init') {
|
|
|
2220
2287
|
require('../commands/youtube').youtubeCommand(process.argv.slice(3))
|
|
2221
2288
|
.then(() => exitWhenFlushed(0))
|
|
2222
2289
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); exitWhenFlushed(1); });
|
|
2290
|
+
} else if (command === 'x-search') {
|
|
2291
|
+
require('../commands/x-search').xSearchCommand(process.argv.slice(3))
|
|
2292
|
+
.then((code) => exitWhenFlushed(Number.isInteger(code) ? code : 0))
|
|
2293
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); exitWhenFlushed(1); });
|
|
2223
2294
|
} else if (command === 'run') {
|
|
2224
2295
|
const args = process.argv.slice(3);
|
|
2225
2296
|
if (args[0] === 'logs') {
|
|
@@ -2536,6 +2607,14 @@ if (command === 'init') {
|
|
|
2536
2607
|
process.exit(0);
|
|
2537
2608
|
}
|
|
2538
2609
|
require('../commands/analytics').analyticsAtris();
|
|
2610
|
+
} else if (command === 'revisions') {
|
|
2611
|
+
const args = process.argv.slice(3);
|
|
2612
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
2613
|
+
showRevisionsHelp();
|
|
2614
|
+
process.exit(0);
|
|
2615
|
+
}
|
|
2616
|
+
const code = require('../commands/revisions').revisionsCommand(args);
|
|
2617
|
+
process.exit(code);
|
|
2539
2618
|
} else if (command === 'clean') {
|
|
2540
2619
|
const args = process.argv.slice(3);
|
|
2541
2620
|
if (args.includes('--help') || args.includes('-h')) {
|
|
@@ -2551,6 +2630,10 @@ if (command === 'init') {
|
|
|
2551
2630
|
console.error(err.message || err);
|
|
2552
2631
|
process.exit(1);
|
|
2553
2632
|
});
|
|
2633
|
+
} else if (command === 'doctor') {
|
|
2634
|
+
Promise.resolve(require('../commands/doctor').doctorCommand(process.argv.slice(3)))
|
|
2635
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2636
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2554
2637
|
} else if (command === 'verify') {
|
|
2555
2638
|
const args = process.argv.slice(3);
|
|
2556
2639
|
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
@@ -2584,14 +2667,19 @@ if (command === 'init') {
|
|
|
2584
2667
|
const code = require('../commands/verify').verifyRubric(slug, section);
|
|
2585
2668
|
process.exit(code);
|
|
2586
2669
|
}
|
|
2587
|
-
const taskId = process.argv[3]
|
|
2588
|
-
require('../commands/verify').verifyAtris(taskId);
|
|
2670
|
+
const taskId = process.argv[3] && !String(process.argv[3]).startsWith('--') ? process.argv[3] : null;
|
|
2671
|
+
const code = require('../commands/verify').verifyAtris(taskId);
|
|
2672
|
+
process.exit(typeof code === 'number' ? code : 0);
|
|
2589
2673
|
} else if (command === 'release') {
|
|
2590
2674
|
const args = process.argv.slice(3);
|
|
2591
2675
|
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
2592
2676
|
showReleaseHelp();
|
|
2593
2677
|
process.exit(0);
|
|
2594
2678
|
}
|
|
2679
|
+
if (args[0] === 'preflight') {
|
|
2680
|
+
const code = require('../commands/release').releasePreflight();
|
|
2681
|
+
process.exit(typeof code === 'number' ? code : 1);
|
|
2682
|
+
}
|
|
2595
2683
|
const dryRun = process.argv.includes('--dry-run');
|
|
2596
2684
|
require('../commands/release').releaseAtris({ dryRun })
|
|
2597
2685
|
.then(() => process.exit(0))
|
|
@@ -2647,12 +2735,23 @@ if (command === 'init') {
|
|
|
2647
2735
|
const status = require('../commands/stripe').stripeCommand(process.argv.slice(3));
|
|
2648
2736
|
process.exit(status);
|
|
2649
2737
|
} else if (command === 'gmail') {
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
.
|
|
2655
|
-
|
|
2738
|
+
{
|
|
2739
|
+
const raw = process.argv.slice(3);
|
|
2740
|
+
const { gmailCommand, extractGmailMailboxAccount } = require('../commands/integrations');
|
|
2741
|
+
const mailbox = extractGmailMailboxAccount(raw);
|
|
2742
|
+
const gateInput = mailbox.mailboxAccountId ? ['--account', ...mailbox.args] : mailbox.args;
|
|
2743
|
+
const gate = requireAccountBound(gateInput);
|
|
2744
|
+
if (!gate.ok) {
|
|
2745
|
+
process.exit(refuseAccountGlobal());
|
|
2746
|
+
return;
|
|
2747
|
+
}
|
|
2748
|
+
const subcommand = gate.args[0];
|
|
2749
|
+
const args = gate.args.slice(1);
|
|
2750
|
+
if (mailbox.mailboxAccountId) args.push('--account', mailbox.mailboxAccountId);
|
|
2751
|
+
gmailCommand(subcommand, ...args)
|
|
2752
|
+
.then(() => process.exit(process.exitCode || 0))
|
|
2753
|
+
.catch((err) => { console.error(`✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2754
|
+
}
|
|
2656
2755
|
} else if (command === 'calendar') {
|
|
2657
2756
|
const { calendarCommand } = require('../commands/integrations');
|
|
2658
2757
|
const subcommand = process.argv[3];
|
|
@@ -2661,19 +2760,30 @@ if (command === 'init') {
|
|
|
2661
2760
|
.then(() => process.exit(0))
|
|
2662
2761
|
.catch((err) => { console.error(`✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2663
2762
|
} else if (command === 'twitter') {
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
.
|
|
2669
|
-
|
|
2763
|
+
{
|
|
2764
|
+
const raw = process.argv.slice(3);
|
|
2765
|
+
const helpOnly = raw.length === 0 || raw.includes('--help') || raw.includes('-h') || raw[0] === 'help';
|
|
2766
|
+
const gate = helpOnly ? { ok: true, args: raw } : requireAccountBound(raw);
|
|
2767
|
+
if (!gate.ok) process.exit(refuseAccountGlobal());
|
|
2768
|
+
const { twitterCommand } = require('../commands/integrations');
|
|
2769
|
+
const subcommand = gate.args[0];
|
|
2770
|
+
const args = gate.args.slice(1);
|
|
2771
|
+
twitterCommand(subcommand, ...args)
|
|
2772
|
+
.then(() => process.exit(0))
|
|
2773
|
+
.catch((err) => { console.error(`✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2774
|
+
}
|
|
2670
2775
|
} else if (command === 'slack') {
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2776
|
+
{
|
|
2777
|
+
const raw = process.argv.slice(3);
|
|
2778
|
+
const gate = requireAccountBound(raw);
|
|
2779
|
+
if (!gate.ok) process.exit(refuseAccountGlobal());
|
|
2780
|
+
const { slackCommand } = require('../commands/integrations');
|
|
2781
|
+
const subcommand = gate.args[0];
|
|
2782
|
+
const args = gate.args.slice(1);
|
|
2783
|
+
slackCommand(subcommand, ...args)
|
|
2784
|
+
.then(() => process.exit(0))
|
|
2785
|
+
.catch((err) => { console.error(`✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2786
|
+
}
|
|
2677
2787
|
} else if (command === 'imessage') {
|
|
2678
2788
|
const { imessageCommand } = require('../commands/integrations');
|
|
2679
2789
|
const subcommand = process.argv[3];
|
|
@@ -2688,8 +2798,8 @@ if (command === 'init') {
|
|
|
2688
2798
|
process.exit(0);
|
|
2689
2799
|
}
|
|
2690
2800
|
const { integrationsStatus } = require('../commands/integrations');
|
|
2691
|
-
integrationsStatus()
|
|
2692
|
-
.then(() => process.exit(0))
|
|
2801
|
+
integrationsStatus(args)
|
|
2802
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2693
2803
|
.catch((err) => { console.error(`✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2694
2804
|
} else if (command === 'apps') {
|
|
2695
2805
|
// Keep APP.md app-pack operations independent from the heavier workspace boot
|
|
@@ -2714,11 +2824,13 @@ if (command === 'init') {
|
|
|
2714
2824
|
} else if (command === 'teach') {
|
|
2715
2825
|
const subcommand = process.argv[3];
|
|
2716
2826
|
const args = process.argv.slice(4);
|
|
2717
|
-
require('../commands/teach')(subcommand, ...args);
|
|
2827
|
+
const teachCode = require('../commands/teach')(subcommand, ...args);
|
|
2828
|
+
process.exit(typeof teachCode === 'number' ? teachCode : 0);
|
|
2718
2829
|
} else if (command === 'skill') {
|
|
2719
2830
|
const subcommand = process.argv[3];
|
|
2720
2831
|
const args = process.argv.slice(4);
|
|
2721
|
-
require('../commands/skill').skillCommand(subcommand, ...args);
|
|
2832
|
+
const code = require('../commands/skill').skillCommand(subcommand, ...args);
|
|
2833
|
+
if (Number.isInteger(code) && code !== 0) process.exitCode = code;
|
|
2722
2834
|
} else if (command === 'member') {
|
|
2723
2835
|
const subcommand = process.argv[3];
|
|
2724
2836
|
const args = process.argv.slice(4);
|
|
@@ -2756,12 +2868,14 @@ if (command === 'init') {
|
|
|
2756
2868
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2757
2869
|
} else if (command === 'x') {
|
|
2758
2870
|
// Fast Agent SDK execution - like "atris x echo hello" or "atris x ls -la"
|
|
2759
|
-
const
|
|
2760
|
-
|
|
2871
|
+
const xArgs = process.argv.slice(3);
|
|
2872
|
+
const userInput = xArgs.join(' ').trim();
|
|
2873
|
+
const helpOnly = xArgs.length === 1 && (xArgs[0] === '--help' || xArgs[0] === '-h' || xArgs[0] === 'help' || xArgs[0] === '-?');
|
|
2874
|
+
if (!userInput || helpOnly) {
|
|
2761
2875
|
console.log('Usage: atris x <command>');
|
|
2762
2876
|
console.log('Example: atris x echo "hello world"');
|
|
2763
2877
|
console.log('Example: atris x ls -la');
|
|
2764
|
-
process.exit(1);
|
|
2878
|
+
process.exit(helpOnly ? 2 : 1);
|
|
2765
2879
|
}
|
|
2766
2880
|
require('../commands/workflow').executeAgentSDKFast(userInput);
|
|
2767
2881
|
} else if (command === 'computer') {
|
|
@@ -2786,11 +2900,21 @@ if (command === 'init') {
|
|
|
2786
2900
|
.then(() => process.exit(0))
|
|
2787
2901
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2788
2902
|
} else if (command === 'business') {
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2903
|
+
{
|
|
2904
|
+
const raw = process.argv.slice(3);
|
|
2905
|
+
const helpOnly = raw.length === 0
|
|
2906
|
+
|| raw.includes('--help')
|
|
2907
|
+
|| raw.includes('-h')
|
|
2908
|
+
|| raw[0] === 'help'
|
|
2909
|
+
|| raw[0] === 'quickstart';
|
|
2910
|
+
const gate = helpOnly ? { ok: true, args: raw } : requireAccountBound(raw);
|
|
2911
|
+
if (!gate.ok) process.exit(refuseAccountGlobal());
|
|
2912
|
+
const subcommand = gate.args[0];
|
|
2913
|
+
const args = gate.args.slice(1);
|
|
2914
|
+
require('../commands/business').businessCommand(subcommand, ...args)
|
|
2915
|
+
.then(() => process.exit(process.exitCode || 0))
|
|
2916
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2917
|
+
}
|
|
2794
2918
|
} else if (command === 'soul') {
|
|
2795
2919
|
const args = process.argv.slice(3);
|
|
2796
2920
|
require('../commands/soul').soul(args)
|
|
@@ -2875,6 +2999,11 @@ if (command === 'init') {
|
|
|
2875
2999
|
Promise.resolve(require('../commands/engine').engineCommand(engineArgs))
|
|
2876
3000
|
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2877
3001
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
3002
|
+
} else if (command === 'playbook') {
|
|
3003
|
+
Promise.resolve()
|
|
3004
|
+
.then(() => require('../commands/playbook').playbookCommand(process.argv.slice(3)))
|
|
3005
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
3006
|
+
.catch((err) => { console.error(`playbook could not continue: ${err.message || err}`); process.exit(1); });
|
|
2878
3007
|
} else if (command === 'sign') {
|
|
2879
3008
|
// Sign: prepare-commit-msg hook that credits Atris as co-author on commits in atris workspaces.
|
|
2880
3009
|
try { process.exit(require('../commands/sign').signCommand(process.argv[3]) || 0); }
|
|
@@ -2943,9 +3072,17 @@ if (command === 'init') {
|
|
|
2943
3072
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2944
3073
|
} else if (command === 'site') {
|
|
2945
3074
|
// Site: beautiful static site from a folder of markdown, in the anti-slop design system.
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
3075
|
+
{
|
|
3076
|
+
const raw = process.argv.slice(3);
|
|
3077
|
+
const deployWrite = raw[0] === 'deploy'
|
|
3078
|
+
&& !argsWantHelp(raw)
|
|
3079
|
+
&& !raw.includes('--dry-run');
|
|
3080
|
+
const gate = deployWrite ? requireAccountBound(raw) : { ok: true, args: raw };
|
|
3081
|
+
if (!gate.ok) process.exit(refuseAccountGlobal());
|
|
3082
|
+
Promise.resolve(require('../commands/site').run(gate.args))
|
|
3083
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
3084
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
3085
|
+
}
|
|
2949
3086
|
} else if (command === 'theme') {
|
|
2950
3087
|
// Theme: brand themes (.atris/theme.json) for the whole design system (deck/html/site).
|
|
2951
3088
|
Promise.resolve(require('../commands/theme').run(process.argv.slice(3)))
|
|
@@ -3004,11 +3141,64 @@ if (command === 'init') {
|
|
|
3004
3141
|
.then(() => process.exit(0))
|
|
3005
3142
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
3006
3143
|
} else if (command === 'feedback') {
|
|
3007
|
-
|
|
3144
|
+
{
|
|
3145
|
+
const gate = requireAccountBound(process.argv.slice(3));
|
|
3146
|
+
if (!gate.ok) process.exit(refuseAccountGlobal());
|
|
3147
|
+
process.argv = [process.argv[0], process.argv[1], 'feedback', ...gate.args];
|
|
3148
|
+
require('../commands/feedback').feedbackCommand()
|
|
3149
|
+
.then(() => process.exit(0))
|
|
3150
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
3151
|
+
}
|
|
3152
|
+
} else if (command === 'errors') {
|
|
3153
|
+
{
|
|
3154
|
+
const gate = requireAccountBound(process.argv.slice(3));
|
|
3155
|
+
if (!gate.ok) process.exit(refuseAccountGlobal());
|
|
3156
|
+
// Keep --account so errors can default to --local inside bound workspaces.
|
|
3157
|
+
const errorArgs = gate.account ? ['--account', ...gate.args] : gate.args;
|
|
3158
|
+
process.argv = [process.argv[0], process.argv[1], 'errors', ...errorArgs];
|
|
3159
|
+
require('../commands/errors').errorsCommand()
|
|
3160
|
+
.then(() => process.exit(0))
|
|
3161
|
+
.catch((err) => { console.error(`✗ Error: ${err.message || err}`); process.exit(1); });
|
|
3162
|
+
}
|
|
3163
|
+
} else if (command === 'social') {
|
|
3164
|
+
require('../commands/social').socialCommand()
|
|
3008
3165
|
.then(() => process.exit(0))
|
|
3009
3166
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
3010
|
-
} else if (command === '
|
|
3011
|
-
require('../commands/
|
|
3167
|
+
} else if (command === 'people') {
|
|
3168
|
+
require('../commands/social').peopleCommand()
|
|
3169
|
+
.then(() => process.exit(0))
|
|
3170
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
3171
|
+
} else if (command === 'follow') {
|
|
3172
|
+
require('../commands/social').followCommand()
|
|
3173
|
+
.then(() => process.exit(0))
|
|
3174
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
3175
|
+
} else if (command === 'unfollow') {
|
|
3176
|
+
require('../commands/social').unfollowCommand()
|
|
3177
|
+
.then(() => process.exit(0))
|
|
3178
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
3179
|
+
} else if (command === 'friends') {
|
|
3180
|
+
require('../commands/social').friendsCommand()
|
|
3181
|
+
.then(() => process.exit(0))
|
|
3182
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
3183
|
+
} else if (command === 'msg') {
|
|
3184
|
+
require('../commands/social').msgCommand()
|
|
3185
|
+
.then(() => process.exit(0))
|
|
3186
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
3187
|
+
} else if (command === 'inbox') {
|
|
3188
|
+
{
|
|
3189
|
+
const gate = requireAccountBound(process.argv.slice(3));
|
|
3190
|
+
if (!gate.ok) process.exit(refuseAccountGlobal());
|
|
3191
|
+
process.argv = [process.argv[0], process.argv[1], 'inbox', ...gate.args];
|
|
3192
|
+
require('../commands/social').inboxCommand()
|
|
3193
|
+
.then(() => process.exit(0))
|
|
3194
|
+
.catch((err) => { console.error(`✗ Error: ${err.message || err}`); process.exit(1); });
|
|
3195
|
+
}
|
|
3196
|
+
} else if (command === 'join') {
|
|
3197
|
+
require('../commands/social').joinCommand()
|
|
3198
|
+
.then(() => process.exit(0))
|
|
3199
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
3200
|
+
} else if (command === 'invite') {
|
|
3201
|
+
require('../commands/social').inviteCommand()
|
|
3012
3202
|
.then(() => process.exit(0))
|
|
3013
3203
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
3014
3204
|
} else {
|