atris 3.52.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/engines/SKILL.md +8 -7
- package/atris/skills/x-search/SKILL.md +24 -22
- package/atris/skills/youtube/SKILL.md +89 -40
- package/atris/team/_template/SOUL.md +40 -0
- package/atris/team/validator/MEMBER.md +1 -2
- package/ax +592 -91
- package/bin/atris +21 -0
- package/bin/atris.js +580 -378
- 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/computer.js +2 -2
- 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 +339 -74
- package/commands/now.js +25 -6
- 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 +96 -40
- 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 -33
- package/lib/account-bound.js +47 -0
- package/lib/auto-accept-certified.js +10 -2
- 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/engine-ask.js +11 -3
- package/lib/engine-registry.js +32 -7
- 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-ledger-compact.js +127 -0
- package/lib/mission-root.js +4 -2
- package/lib/mission-runtime-loop.js +30 -2
- package/lib/next-moves.js +34 -34
- package/lib/noninteractive.js +88 -0
- package/lib/permission-grants.js +10 -1
- package/lib/policy-lessons.js +4 -1
- package/lib/revision-metric.js +279 -0
- package/lib/runner-command.js +5 -4
- package/lib/scratch-root.js +48 -0
- package/lib/skill-eval-gate.js +249 -0
- package/lib/task-db.js +22 -2
- package/lib/task-proof.js +75 -9
- package/lib/task-receipt.js +5 -1
- 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 +4 -2
- package/scripts/det/checklist-score.js +191 -0
- package/scripts/det/ytsearch +31 -0
- package/scripts/outbound-artifact-gate.js +227 -0
- package/utils/update-check.js +15 -0
package/commands/spaceship.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* atris spaceship — bounded, self-reporting overnight runner.
|
|
3
5
|
*
|
|
@@ -7,26 +9,87 @@
|
|
|
7
9
|
* `atris spaceship ...` and integrates with the CLI's command dispatch.
|
|
8
10
|
*
|
|
9
11
|
* Examples:
|
|
10
|
-
* atris spaceship --hours 4
|
|
11
|
-
* atris spaceship --hours 4 --repo /path/to/repo --interval 780
|
|
12
|
-
* atris spaceship --hours 0.01 --tick-cmd /tmp/stub.sh --no-email
|
|
12
|
+
* atris spaceship --hours 4 --yes
|
|
13
|
+
* atris spaceship --hours 4 --repo /path/to/repo --interval 780 --yes
|
|
14
|
+
* atris spaceship --hours 0.01 --tick-cmd /tmp/stub.sh --no-email --yes
|
|
15
|
+
*
|
|
16
|
+
* Without --yes, spaceship only prints the plan (no email, no overnight run).
|
|
17
|
+
* `--json` without --yes prints a JSON refuse and still does not start.
|
|
13
18
|
*/
|
|
14
19
|
|
|
15
20
|
const path = require('path');
|
|
16
21
|
const fs = require('fs');
|
|
17
22
|
const { spawn } = require('child_process');
|
|
23
|
+
const { hasYesFlag, argsWantHelp, wantsJson } = require('../lib/noninteractive');
|
|
18
24
|
|
|
19
25
|
const SCRIPT = path.join(__dirname, '..', 'scripts', 'spaceship.sh');
|
|
20
26
|
|
|
27
|
+
function printUsage() {
|
|
28
|
+
const lines = [
|
|
29
|
+
'Usage: atris spaceship [--hours N] [--interval SEC] [--repo PATH]',
|
|
30
|
+
' [--tick-cmd CMD] [--tick-timeout SEC]',
|
|
31
|
+
' [--idle-alert N] [--halt-alert N] [--label NAME]',
|
|
32
|
+
' [--no-email] [--yes]',
|
|
33
|
+
'',
|
|
34
|
+
'Bounded overnight runner. Survives bad ticks and emails on state changes.',
|
|
35
|
+
'Without --yes, prints the plan only (no email, no overnight run).',
|
|
36
|
+
'Defaults: --hours 4, --interval 780, tick = atris autopilot --auto --iterations=1',
|
|
37
|
+
];
|
|
38
|
+
console.log(lines.join('\n'));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function planLines(args = []) {
|
|
42
|
+
const hoursIdx = args.indexOf('--hours');
|
|
43
|
+
const hours = hoursIdx !== -1 && args[hoursIdx + 1] ? args[hoursIdx + 1] : '4';
|
|
44
|
+
return [
|
|
45
|
+
'spaceship plan (no run):',
|
|
46
|
+
` budget: ${hours}h`,
|
|
47
|
+
' email: on meaningful state changes (unless --no-email)',
|
|
48
|
+
' tick: atris autopilot --auto --iterations=1',
|
|
49
|
+
'Pass --yes to start the overnight run.',
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
|
|
21
53
|
function spaceship(args = []) {
|
|
54
|
+
const list = Array.isArray(args) ? args : [];
|
|
55
|
+
if (argsWantHelp(list) || list.includes('--help') || list.includes('-h')) {
|
|
56
|
+
printUsage();
|
|
57
|
+
return Promise.resolve({ success: true, help: true });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Same proceed-flag gate as autopilot: --json is not consent, --once is
|
|
61
|
+
// not consent. Only --yes / -y start the overnight run.
|
|
62
|
+
if (wantsJson(list) && !hasYesFlag(list)) {
|
|
63
|
+
console.log(JSON.stringify({
|
|
64
|
+
ok: false,
|
|
65
|
+
command: 'spaceship',
|
|
66
|
+
running: false,
|
|
67
|
+
error: 'pass --yes to start',
|
|
68
|
+
usage: 'atris spaceship [--yes|--auto] [--once]',
|
|
69
|
+
}, null, 2));
|
|
70
|
+
process.exit(2);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!hasYesFlag(list)) {
|
|
74
|
+
for (const line of planLines(list)) console.log(line);
|
|
75
|
+
process.exit(2);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const runArgs = list.filter((a) => a !== '--yes' && a !== '-y' && a !== '--json');
|
|
22
79
|
return new Promise((resolve, reject) => {
|
|
23
80
|
if (!fs.existsSync(SCRIPT)) {
|
|
24
81
|
reject(new Error(`spaceship.sh not found at ${SCRIPT}`));
|
|
25
82
|
return;
|
|
26
83
|
}
|
|
27
|
-
const
|
|
84
|
+
const env = { ...process.env };
|
|
85
|
+
if (!process.stdout.isTTY) {
|
|
86
|
+
env.NO_COLOR = '1';
|
|
87
|
+
env.CLICOLOR = '0';
|
|
88
|
+
env.FORCE_COLOR = '0';
|
|
89
|
+
}
|
|
90
|
+
const child = spawn('bash', [SCRIPT, ...runArgs], {
|
|
28
91
|
stdio: 'inherit',
|
|
29
|
-
env
|
|
92
|
+
env,
|
|
30
93
|
});
|
|
31
94
|
child.on('error', reject);
|
|
32
95
|
child.on('close', (code) => {
|
|
@@ -36,4 +99,4 @@ function spaceship(args = []) {
|
|
|
36
99
|
});
|
|
37
100
|
}
|
|
38
101
|
|
|
39
|
-
module.exports = { spaceship, SCRIPT };
|
|
102
|
+
module.exports = { spaceship, SCRIPT, printUsage, planLines };
|
package/commands/stream.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { hasFlag, readFlag } = require('../lib/arg-parser');
|
|
6
|
+
const { isNonInteractive } = require('../lib/noninteractive');
|
|
6
7
|
const escapeRegExp = require('../lib/escape-regexp');
|
|
7
8
|
const { runGit: spawnGit } = require('../lib/git-spawn');
|
|
8
9
|
const { collectBoard } = require('./land');
|
|
@@ -716,12 +717,16 @@ function parseArgs(args = [], nowMs = Date.now()) {
|
|
|
716
717
|
const sinceRaw = readFlag(args, '--since', '');
|
|
717
718
|
const intervalRaw = readFlag(args, '--interval', '');
|
|
718
719
|
const interval = Number(intervalRaw);
|
|
720
|
+
const onceFlag = hasFlag(args, '--once');
|
|
721
|
+
// Watch loops must exit in agent/non-TTY sessions. --once is explicit;
|
|
722
|
+
// ATRIS_NONINTERACTIVE / non-TTY stdin also force a one-shot snapshot.
|
|
723
|
+
const once = onceFlag || isNonInteractive(args) || !process.stdin.isTTY || !process.stdout.isTTY;
|
|
719
724
|
return {
|
|
720
725
|
agent: readFlag(args, '--agent', ''),
|
|
721
726
|
sinceMs: parseSince(sinceRaw, nowMs),
|
|
722
727
|
json: hasFlag(args, '--json'),
|
|
723
728
|
raw: hasFlag(args, '--raw'),
|
|
724
|
-
once
|
|
729
|
+
once,
|
|
725
730
|
intervalMs: Number.isFinite(interval) && interval > 0 ? Math.max(250, interval * 1000) : DEFAULT_INTERVAL_MS,
|
|
726
731
|
};
|
|
727
732
|
}
|
|
@@ -750,12 +755,14 @@ function showHelp() {
|
|
|
750
755
|
console.log('atris stream - watch the whole team work live');
|
|
751
756
|
console.log('');
|
|
752
757
|
console.log(' atris stream');
|
|
758
|
+
console.log(' atris stream --once');
|
|
753
759
|
console.log(' atris stream --agent codex');
|
|
754
760
|
console.log(' atris stream --since 1h');
|
|
755
761
|
console.log(' atris stream --json');
|
|
756
762
|
console.log(' atris stream --raw');
|
|
757
763
|
console.log('');
|
|
758
764
|
console.log('Default lines hide ids, branch names, and paths. Use --raw or --json for source records.');
|
|
765
|
+
console.log('--once (or non-TTY / ATRIS_NONINTERACTIVE) prints one snapshot and exits.');
|
|
759
766
|
console.log('');
|
|
760
767
|
return 0;
|
|
761
768
|
}
|
package/commands/study.js
CHANGED
|
@@ -16,7 +16,6 @@ const path = require('path');
|
|
|
16
16
|
const http = require('http');
|
|
17
17
|
const { spawn, spawnSync } = require('child_process');
|
|
18
18
|
|
|
19
|
-
const BACKEND_ROOT = '/Users/keshavrao/arena/atrisos-backend';
|
|
20
19
|
const FEED_URL = 'http://localhost:8777';
|
|
21
20
|
const FEED_STATS_URL = `${FEED_URL}/api/stats`;
|
|
22
21
|
const FEED_NEXT_URL = `${FEED_URL}/api/next`;
|
|
@@ -91,18 +90,31 @@ function parseArgs(argv = []) {
|
|
|
91
90
|
return opts;
|
|
92
91
|
}
|
|
93
92
|
|
|
93
|
+
function resolveStudyRoot(cwd = process.cwd()) {
|
|
94
|
+
const candidates = [
|
|
95
|
+
process.env.ATRIS_STUDY_ROOT,
|
|
96
|
+
process.env.ATRIS_BACKEND_ROOT,
|
|
97
|
+
path.join(path.resolve(cwd), 'atris', 'study'),
|
|
98
|
+
].filter(Boolean);
|
|
99
|
+
for (const root of candidates) {
|
|
100
|
+
const resolved = path.resolve(String(root));
|
|
101
|
+
if (fs.existsSync(resolved)) return resolved;
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
|
|
94
106
|
function requireBackend() {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
107
|
+
const backendRoot = resolveStudyRoot();
|
|
108
|
+
if (!backendRoot) {
|
|
109
|
+
console.error('not installed');
|
|
110
|
+
process.exit(2);
|
|
98
111
|
}
|
|
99
|
-
const venvPython = path.join(
|
|
112
|
+
const venvPython = path.join(backendRoot, 'venv/bin/python');
|
|
100
113
|
if (!fs.existsSync(venvPython)) {
|
|
101
|
-
console.error(
|
|
102
|
-
|
|
103
|
-
process.exit(1);
|
|
114
|
+
console.error('not installed');
|
|
115
|
+
process.exit(2);
|
|
104
116
|
}
|
|
105
|
-
return venvPython;
|
|
117
|
+
return { venvPython, backendRoot };
|
|
106
118
|
}
|
|
107
119
|
|
|
108
120
|
function detectLanguage(topic) {
|
|
@@ -608,11 +620,11 @@ async function runWhileMode(opts) {
|
|
|
608
620
|
const topic = opts.topic;
|
|
609
621
|
|
|
610
622
|
if (topic) {
|
|
611
|
-
const venvPython = requireBackend();
|
|
623
|
+
const { venvPython, backendRoot } = requireBackend();
|
|
612
624
|
const language = detectLanguage(topic);
|
|
613
|
-
if (language) printTutorLoopBlock(
|
|
625
|
+
if (language) printTutorLoopBlock(backendRoot, language);
|
|
614
626
|
try {
|
|
615
|
-
await runIngest(venvPython,
|
|
627
|
+
await runIngest(venvPython, backendRoot, topic, opts.personal);
|
|
616
628
|
} catch (err) {
|
|
617
629
|
console.error(`\n✗ ${err.message || err}`);
|
|
618
630
|
}
|
|
@@ -625,9 +637,10 @@ async function runWhileMode(opts) {
|
|
|
625
637
|
let statsAvailable = false;
|
|
626
638
|
let useCards = false;
|
|
627
639
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
640
|
+
const studyRoot = resolveStudyRoot();
|
|
641
|
+
if (studyRoot && fs.existsSync(path.join(studyRoot, 'venv/bin/python'))) {
|
|
642
|
+
const venvPython = path.join(studyRoot, 'venv/bin/python');
|
|
643
|
+
statsAvailable = await tryEnsureFeedServerSilent(venvPython, studyRoot);
|
|
631
644
|
useCards = statsAvailable;
|
|
632
645
|
}
|
|
633
646
|
|
|
@@ -663,21 +676,21 @@ async function run(argv = []) {
|
|
|
663
676
|
return 0;
|
|
664
677
|
}
|
|
665
678
|
|
|
666
|
-
const venvPython = requireBackend();
|
|
679
|
+
const { venvPython, backendRoot } = requireBackend();
|
|
667
680
|
const language = detectLanguage(opts.topic);
|
|
668
681
|
|
|
669
682
|
if (language) {
|
|
670
|
-
printTutorLoopBlock(
|
|
683
|
+
printTutorLoopBlock(backendRoot, language);
|
|
671
684
|
}
|
|
672
685
|
|
|
673
686
|
try {
|
|
674
|
-
await runIngest(venvPython,
|
|
687
|
+
await runIngest(venvPython, backendRoot, opts.topic, opts.personal);
|
|
675
688
|
} catch (err) {
|
|
676
689
|
console.error(`\n✗ ${err.message || err}`);
|
|
677
690
|
return 1;
|
|
678
691
|
}
|
|
679
692
|
|
|
680
|
-
await ensureFeedServer(venvPython,
|
|
693
|
+
await ensureFeedServer(venvPython, backendRoot);
|
|
681
694
|
openFeed();
|
|
682
695
|
return 0;
|
|
683
696
|
}
|
package/commands/sync.js
CHANGED
|
@@ -9,6 +9,7 @@ const {
|
|
|
9
9
|
upsertCursorVoiceCard,
|
|
10
10
|
voiceCardForRoot,
|
|
11
11
|
} = require('../lib/voice-card');
|
|
12
|
+
const { isNonInteractive } = require('../lib/noninteractive');
|
|
12
13
|
|
|
13
14
|
const TEMPLATE_ROOT_DIR = path.join(__dirname, '..', 'templates');
|
|
14
15
|
const WORKSPACE_TEMPLATES = {
|
|
@@ -437,18 +438,28 @@ function syncBusinessCanonical(targetRoot, bizMeta, options = {}) {
|
|
|
437
438
|
}
|
|
438
439
|
|
|
439
440
|
function syncAtris(options = {}) {
|
|
440
|
-
const
|
|
441
|
+
const explicitDryRun = options.dryRun != null ? options.dryRun : process.argv.includes('--dry-run');
|
|
442
|
+
const yes = options.yes != null
|
|
443
|
+
? options.yes
|
|
444
|
+
: (process.argv.includes('--yes') || process.argv.includes('-y'));
|
|
445
|
+
// Default is plan-only. Writes require an explicit --yes.
|
|
446
|
+
const dryRun = explicitDryRun || !yes;
|
|
441
447
|
const force = options.force != null ? options.force : process.argv.includes('--force');
|
|
442
448
|
// Business mode detection: if .atris/business.json exists, use canonical templates
|
|
443
449
|
const bizFile = path.join(process.cwd(), '.atris', 'business.json');
|
|
444
450
|
if (fs.existsSync(bizFile)) {
|
|
445
451
|
try {
|
|
446
452
|
const bizMeta = JSON.parse(fs.readFileSync(bizFile, 'utf8'));
|
|
447
|
-
|
|
453
|
+
const result = syncWorkspaceTemplate(process.cwd(), bizMeta, {
|
|
448
454
|
templateName: bizMeta.workspace_template || 'business',
|
|
449
455
|
dryRun,
|
|
450
456
|
force,
|
|
451
457
|
});
|
|
458
|
+
if (!yes) {
|
|
459
|
+
console.log('\nPlan only. Re-run with --yes to write these files.');
|
|
460
|
+
if (!explicitDryRun && isNonInteractive()) process.exit(2);
|
|
461
|
+
}
|
|
462
|
+
return result;
|
|
452
463
|
} catch (e) {
|
|
453
464
|
console.error(`✗ Failed to read .atris/business.json: ${e.message}`);
|
|
454
465
|
process.exit(1);
|
|
@@ -672,6 +683,10 @@ Key behaviors:
|
|
|
672
683
|
|
|
673
684
|
if (dryRun) {
|
|
674
685
|
console.log(`\nDry run: ${updated} file(s) would update, ${skipped} unchanged; no changes made.`);
|
|
686
|
+
if (!yes) {
|
|
687
|
+
console.log('Plan only. Re-run with --yes to write these files.');
|
|
688
|
+
if (!explicitDryRun && isNonInteractive()) process.exit(2);
|
|
689
|
+
}
|
|
675
690
|
} else if (updated === 0) {
|
|
676
691
|
ensureWikiScaffold(process.cwd());
|
|
677
692
|
console.log('✓ Already up to date');
|
|
@@ -892,9 +907,13 @@ function buildSyncAllPlan({ root, pkgRoot, filesToSync = SYNC_ALL_FILES } = {})
|
|
|
892
907
|
return { projects, plan };
|
|
893
908
|
}
|
|
894
909
|
|
|
895
|
-
function syncAtrisAll({ dryRun = false, force = false } = {}) {
|
|
910
|
+
function syncAtrisAll({ dryRun = false, force = false, yes = false } = {}) {
|
|
896
911
|
const root = process.cwd();
|
|
897
912
|
const pkgRoot = path.join(__dirname, '..');
|
|
913
|
+
const writeYes = yes || process.argv.includes('--yes') || process.argv.includes('-y');
|
|
914
|
+
const explicitDryRun = dryRun || process.argv.includes('--dry-run');
|
|
915
|
+
// Default is plan-only. Writes require --yes.
|
|
916
|
+
const planOnly = explicitDryRun || !writeYes;
|
|
898
917
|
|
|
899
918
|
console.log('');
|
|
900
919
|
console.log(`Scanning ${root} for atris projects...`);
|
|
@@ -931,8 +950,12 @@ function syncAtrisAll({ dryRun = false, force = false } = {}) {
|
|
|
931
950
|
}
|
|
932
951
|
console.log('');
|
|
933
952
|
|
|
934
|
-
if (
|
|
953
|
+
if (planOnly) {
|
|
935
954
|
console.log(`Dry run: ${wouldUpdate} project(s) would update, ${unchanged} unchanged, ${skipped} skipped.`);
|
|
955
|
+
if (!writeYes) {
|
|
956
|
+
console.log('Plan only. Re-run with --yes to write these files.');
|
|
957
|
+
if (!explicitDryRun && isNonInteractive()) process.exit(2);
|
|
958
|
+
}
|
|
936
959
|
return;
|
|
937
960
|
}
|
|
938
961
|
|
|
@@ -941,24 +964,7 @@ function syncAtrisAll({ dryRun = false, force = false } = {}) {
|
|
|
941
964
|
return;
|
|
942
965
|
}
|
|
943
966
|
|
|
944
|
-
//
|
|
945
|
-
if (!force) {
|
|
946
|
-
const readline = require('readline');
|
|
947
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
948
|
-
return new Promise((resolve) => {
|
|
949
|
-
rl.question(`Sync ${wouldUpdate} project(s)? (y/N) `, (answer) => {
|
|
950
|
-
rl.close();
|
|
951
|
-
if (!/^y(es)?$/i.test(answer.trim())) {
|
|
952
|
-
console.log('Cancelled.');
|
|
953
|
-
resolve();
|
|
954
|
-
return;
|
|
955
|
-
}
|
|
956
|
-
_executeSyncAll(plan, pkgRoot, filesToSync, root);
|
|
957
|
-
resolve();
|
|
958
|
-
});
|
|
959
|
-
});
|
|
960
|
-
}
|
|
961
|
-
|
|
967
|
+
// --yes already consented; skip the interactive confirm.
|
|
962
968
|
_executeSyncAll(plan, pkgRoot, filesToSync, root);
|
|
963
969
|
}
|
|
964
970
|
|