atris 3.53.0 → 3.56.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 +565 -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 +435 -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/commands/interview.js
CHANGED
|
@@ -153,6 +153,14 @@ async function interviewCommand(args = [], root = process.cwd()) {
|
|
|
153
153
|
return 0;
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
const { refuseHeadlessUnless } = require('../lib/noninteractive');
|
|
157
|
+
if (refuseHeadlessUnless(args, {
|
|
158
|
+
allowYes: true,
|
|
159
|
+
usage: 'Usage: atris interview [subject] [--yes]\nHeadless interview needs --yes.',
|
|
160
|
+
})) {
|
|
161
|
+
return 2;
|
|
162
|
+
}
|
|
163
|
+
|
|
156
164
|
const ws = findWorkspaceRoot(root);
|
|
157
165
|
if (!ws) {
|
|
158
166
|
console.error('✗ Not inside an Atris workspace (no atris/ directory found).');
|
package/commands/land.js
CHANGED
|
@@ -19,6 +19,10 @@ function repoRoot(cwd = process.cwd()) {
|
|
|
19
19
|
return result.stdout.trim();
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
function hasCommits(root) {
|
|
23
|
+
return runGit(['rev-parse', '--verify', '--quiet', 'HEAD'], { cwd: root, check: false }).status === 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
22
26
|
function refExists(root, ref) {
|
|
23
27
|
return runGit(['rev-parse', '--verify', '--quiet', ref], { cwd: root, check: false }).status === 0;
|
|
24
28
|
}
|
|
@@ -111,7 +115,11 @@ function cherryStats(root, base, ref) {
|
|
|
111
115
|
// due — has unlanded commits, older than TTL; --reap collects it
|
|
112
116
|
function collectBoard(root, { ttlDays = DEFAULT_TTL_DAYS, staleHours = DEFAULT_STALE_HOURS, base: baseOverride = '', now = Date.now(), light = false } = {}) {
|
|
113
117
|
const base = baseBranch(root, baseOverride);
|
|
114
|
-
if (!base)
|
|
118
|
+
if (!base) {
|
|
119
|
+
const err = new Error('no master/main branch found. fix: git checkout -b main');
|
|
120
|
+
err.code = 'LAND_NO_BASE';
|
|
121
|
+
throw err;
|
|
122
|
+
}
|
|
115
123
|
|
|
116
124
|
const branches = [];
|
|
117
125
|
const lastCommitMsByBranch = new Map();
|
|
@@ -457,7 +465,11 @@ function reap(root, { ttlDays = DEFAULT_TTL_DAYS, staleHours = DEFAULT_STALE_HOU
|
|
|
457
465
|
// into master some other way, and what would be lost if it were cleared.
|
|
458
466
|
function collectStory(root, name, { base: baseOverride = '' } = {}) {
|
|
459
467
|
const base = baseBranch(root, baseOverride);
|
|
460
|
-
if (!base)
|
|
468
|
+
if (!base) {
|
|
469
|
+
const err = new Error('no master/main branch found. fix: git checkout -b main');
|
|
470
|
+
err.code = 'LAND_NO_BASE';
|
|
471
|
+
throw err;
|
|
472
|
+
}
|
|
461
473
|
if (!refExists(root, name)) return null;
|
|
462
474
|
|
|
463
475
|
const logResult = runGit(
|
|
@@ -656,7 +668,11 @@ function landCommand(args = []) {
|
|
|
656
668
|
}
|
|
657
669
|
const root = repoRoot();
|
|
658
670
|
if (!root) {
|
|
659
|
-
console.error('not a git repository');
|
|
671
|
+
console.error('not a git repository. fix: git init -b main');
|
|
672
|
+
return 1;
|
|
673
|
+
}
|
|
674
|
+
if (!hasCommits(root)) {
|
|
675
|
+
console.error('no commits yet. fix: git commit --allow-empty -m init');
|
|
660
676
|
return 1;
|
|
661
677
|
}
|
|
662
678
|
const ttlRaw = readFollowingFlag(args, '--ttl', '');
|
|
@@ -666,29 +682,44 @@ function landCommand(args = []) {
|
|
|
666
682
|
const json = args.includes('--json');
|
|
667
683
|
|
|
668
684
|
if (args.includes('--reap')) {
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
685
|
+
try {
|
|
686
|
+
const receipt = reap(root, { ttlDays, base, dryRun: args.includes('--dry-run'), remote: !args.includes('--no-remote'), force: args.includes('--force') });
|
|
687
|
+
if (json) console.log(JSON.stringify(receipt, null, 2));
|
|
688
|
+
else printReceipt(receipt);
|
|
689
|
+
return 0;
|
|
690
|
+
} catch (err) {
|
|
691
|
+
console.error(String(err && err.message || err));
|
|
692
|
+
return 1;
|
|
693
|
+
}
|
|
673
694
|
}
|
|
674
695
|
|
|
675
696
|
const lookupArgs = args[0] === 'status' ? args.slice(1) : args;
|
|
676
697
|
const name = lookupArgs.find((a) => !a.startsWith('-') && a !== readFollowingFlag(lookupArgs, '--ttl') && a !== readFollowingFlag(lookupArgs, '--base'));
|
|
677
698
|
if (name) {
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
699
|
+
try {
|
|
700
|
+
const story = collectStory(root, name, { base });
|
|
701
|
+
if (!story) {
|
|
702
|
+
console.error(`nothing called '${name}' is in the air right now`);
|
|
703
|
+
return 1;
|
|
704
|
+
}
|
|
705
|
+
if (json) console.log(JSON.stringify(story, null, 2));
|
|
706
|
+
else printStory(story);
|
|
707
|
+
return 0;
|
|
708
|
+
} catch (err) {
|
|
709
|
+
console.error(String(err && err.message || err));
|
|
681
710
|
return 1;
|
|
682
711
|
}
|
|
683
|
-
if (json) console.log(JSON.stringify(story, null, 2));
|
|
684
|
-
else printStory(story);
|
|
685
|
-
return 0;
|
|
686
712
|
}
|
|
687
713
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
714
|
+
try {
|
|
715
|
+
const board = collectBoard(root, { ttlDays, base });
|
|
716
|
+
if (json) console.log(JSON.stringify(board, null, 2));
|
|
717
|
+
else printBoard(board);
|
|
718
|
+
return 0;
|
|
719
|
+
} catch (err) {
|
|
720
|
+
console.error(String(err && err.message || err));
|
|
721
|
+
return 1;
|
|
722
|
+
}
|
|
692
723
|
}
|
|
693
724
|
|
|
694
725
|
module.exports = {
|
package/commands/learn.js
CHANGED
|
@@ -227,21 +227,42 @@ function interactiveAdd() {
|
|
|
227
227
|
})();
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
+
function learnLogSchemaLines() {
|
|
231
|
+
return [
|
|
232
|
+
'Schema: {"type":"pattern|pitfall|preference|architecture|tool","key":"...","insight":"...","confidence":1-10,"source":"observed|user-stated|inferred|review"}',
|
|
233
|
+
'Required: type, key, insight. Aliases: title→key, detail→insight. Optional: confidence (default 5), source (default observed), files[].',
|
|
234
|
+
'Example: atris learn log \'{"type":"pattern","title":"map-first","detail":"check MAP.md before grep","confidence":8}\'',
|
|
235
|
+
];
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function printLearnLogSchema(stream = console.error) {
|
|
239
|
+
for (const line of learnLogSchemaLines()) stream(` ${line}`);
|
|
240
|
+
}
|
|
241
|
+
|
|
230
242
|
/**
|
|
231
243
|
* Non-interactive log: `atris learn log '{"type":"pattern","key":"...","insight":"...","confidence":8,"source":"observed"}'`
|
|
232
244
|
* For agents and scripts — no prompts, no quality gate.
|
|
245
|
+
* Aliases: title→key, detail→insight.
|
|
233
246
|
*/
|
|
234
247
|
function logDirect(jsonStr) {
|
|
235
248
|
if (!jsonStr) {
|
|
236
|
-
console.error(' ✗ Usage: atris learn log \'
|
|
249
|
+
console.error(' ✗ Usage: atris learn log \'<json>\'');
|
|
250
|
+
printLearnLogSchema();
|
|
251
|
+
process.exit(1);
|
|
252
|
+
}
|
|
253
|
+
let data;
|
|
254
|
+
try {
|
|
255
|
+
data = JSON.parse(jsonStr);
|
|
256
|
+
} catch (err) {
|
|
257
|
+
console.error(` ✗ Invalid JSON: ${err.message}`);
|
|
258
|
+
printLearnLogSchema();
|
|
237
259
|
process.exit(1);
|
|
238
260
|
}
|
|
239
261
|
try {
|
|
240
|
-
const data = JSON.parse(jsonStr);
|
|
241
262
|
const entry = addLearning({
|
|
242
263
|
type: data.type,
|
|
243
|
-
key: data.key,
|
|
244
|
-
insight: data.insight,
|
|
264
|
+
key: data.key || data.title,
|
|
265
|
+
insight: data.insight || data.detail,
|
|
245
266
|
confidence: data.confidence || 5,
|
|
246
267
|
source: data.source || 'observed',
|
|
247
268
|
files: data.files || [],
|
|
@@ -249,6 +270,7 @@ function logDirect(jsonStr) {
|
|
|
249
270
|
console.log(` ✓ [${entry.confidence}/10] ${entry.type}/${entry.key}`);
|
|
250
271
|
} catch (err) {
|
|
251
272
|
console.error(` ✗ ${err.message}`);
|
|
273
|
+
printLearnLogSchema();
|
|
252
274
|
process.exit(1);
|
|
253
275
|
}
|
|
254
276
|
}
|
|
@@ -362,6 +384,9 @@ function showLearnHelp() {
|
|
|
362
384
|
console.log(' export Export as markdown');
|
|
363
385
|
console.log(' count Print learning count (for integrations)');
|
|
364
386
|
console.log('');
|
|
387
|
+
console.log(' learn log schema:');
|
|
388
|
+
for (const line of learnLogSchemaLines()) console.log(` ${line}`);
|
|
389
|
+
console.log('');
|
|
365
390
|
}
|
|
366
391
|
|
|
367
392
|
function learnAtris(subcommand, ...args) {
|
package/commands/log.js
CHANGED
|
@@ -2,6 +2,15 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const readline = require('readline');
|
|
4
4
|
const { getLogPath, ensureLogDirectory, createLogFile, addInboxIdea } = require('../lib/file-ops');
|
|
5
|
+
const { isForcedNonInteractive } = require('../lib/noninteractive');
|
|
6
|
+
|
|
7
|
+
function readPipedStdin() {
|
|
8
|
+
try {
|
|
9
|
+
return fs.readFileSync(0, 'utf8');
|
|
10
|
+
} catch {
|
|
11
|
+
return '';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
5
14
|
|
|
6
15
|
function logAtris() {
|
|
7
16
|
const targetDir = path.join(process.cwd(), 'atris');
|
|
@@ -18,6 +27,48 @@ function logAtris() {
|
|
|
18
27
|
createLogFile(logFile, dateFormatted);
|
|
19
28
|
}
|
|
20
29
|
|
|
30
|
+
const args = process.argv.slice(3);
|
|
31
|
+
const rel = path.relative(process.cwd(), logFile) || logFile;
|
|
32
|
+
const forced = isForcedNonInteractive(args);
|
|
33
|
+
const wantsRepl = args.includes('--repl');
|
|
34
|
+
const positional = args.filter((arg) => !String(arg).startsWith('-'));
|
|
35
|
+
const note = positional.join(' ').trim();
|
|
36
|
+
|
|
37
|
+
// `atris log "sentence"` (or multi-word args) appends to today's Inbox.
|
|
38
|
+
if (note && !wantsRepl) {
|
|
39
|
+
const id = addInboxIdea(logFile, note);
|
|
40
|
+
console.log(`captured I${id}: ${note}`);
|
|
41
|
+
console.log(`journal: ${rel}`);
|
|
42
|
+
console.log('Next: atris logs');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Forced headless: never open a REPL.
|
|
47
|
+
if (forced) {
|
|
48
|
+
console.log(`Daily log REPL needs a terminal (${dateFormatted}).`);
|
|
49
|
+
console.log(`journal: ${rel}`);
|
|
50
|
+
console.log('Next: atris log --repl # in a terminal, or atris log "note" / atris wish --json --no-mission');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Piped stdin (tests and scripts): consume lines once, never hang waiting.
|
|
55
|
+
if (!process.stdin.isTTY) {
|
|
56
|
+
const piped = readPipedStdin();
|
|
57
|
+
const lines = piped.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
58
|
+
const notes = lines.filter((line) => line.toLowerCase() !== 'exit');
|
|
59
|
+
if (notes.length === 0) {
|
|
60
|
+
console.log(`Daily log REPL needs a terminal (${dateFormatted}).`);
|
|
61
|
+
console.log(`journal: ${rel}`);
|
|
62
|
+
console.log('Next: atris log --repl # in a terminal, or atris log "note" / atris logs --json');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
for (const noteLine of notes) {
|
|
66
|
+
addInboxIdea(logFile, noteLine);
|
|
67
|
+
}
|
|
68
|
+
console.log(`captured ${notes.length} note${notes.length === 1 ? '' : 's'} in ${rel}`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
21
72
|
console.log(`┌─────────────────────────────────────────────────────────┐`);
|
|
22
73
|
console.log(`│ Daily Log — ${dateFormatted} [type "exit" to quit] │`);
|
|
23
74
|
console.log(`└─────────────────────────────────────────────────────────┘`);
|
package/commands/member.js
CHANGED
|
@@ -9,6 +9,7 @@ const { runAliveTick } = require('../lib/member-alive');
|
|
|
9
9
|
const { defaultObjectiveRunner } = require('../lib/default-runner');
|
|
10
10
|
const { readJson, writeJson } = require('../lib/json-file');
|
|
11
11
|
const { hasFlag, readFlag, readNumberFlag } = require('../lib/arg-parser');
|
|
12
|
+
const { ensureMemberBundle, memberBundlePresent } = require('../lib/member-scaffold');
|
|
12
13
|
|
|
13
14
|
function findWorkspaceBusinessId(startDir = process.cwd()) {
|
|
14
15
|
let dir = path.resolve(startDir);
|
|
@@ -113,7 +114,7 @@ function readRepeatedFlag(args, name) {
|
|
|
113
114
|
function stripKnownFlags(args, valueNames, booleanNames = []) {
|
|
114
115
|
const out = [];
|
|
115
116
|
const valueSet = new Set(valueNames);
|
|
116
|
-
const booleanSet = new Set(booleanNames);
|
|
117
|
+
const booleanSet = new Set(['--full', '--verbose', ...booleanNames]);
|
|
117
118
|
for (let i = 0; i < args.length; i += 1) {
|
|
118
119
|
const arg = String(args[i]);
|
|
119
120
|
const key = arg.includes('=') ? arg.slice(0, arg.indexOf('=')) : arg;
|
|
@@ -3933,10 +3934,27 @@ function findAllMembers(teamDir) {
|
|
|
3933
3934
|
|
|
3934
3935
|
// --- LIST subcommand ---
|
|
3935
3936
|
|
|
3936
|
-
function memberList() {
|
|
3937
|
+
function memberList(...flags) {
|
|
3938
|
+
const asJson = flags.includes('--json') || process.argv.includes('--json');
|
|
3937
3939
|
const teamDir = path.join(process.cwd(), 'atris', 'team');
|
|
3938
3940
|
const members = findAllMembers(teamDir);
|
|
3939
3941
|
|
|
3942
|
+
if (asJson) {
|
|
3943
|
+
console.log(JSON.stringify({
|
|
3944
|
+
ok: true,
|
|
3945
|
+
count: members.length,
|
|
3946
|
+
members: members.map((m) => ({
|
|
3947
|
+
name: m.name,
|
|
3948
|
+
role: m.role,
|
|
3949
|
+
format: m.format,
|
|
3950
|
+
skills: m.format === 'directory' ? m.skillCount : null,
|
|
3951
|
+
context: m.format === 'directory' ? m.contextCount : null,
|
|
3952
|
+
version: m.version || null,
|
|
3953
|
+
})),
|
|
3954
|
+
}, null, 2));
|
|
3955
|
+
return;
|
|
3956
|
+
}
|
|
3957
|
+
|
|
3940
3958
|
if (members.length === 0) {
|
|
3941
3959
|
console.log('No team members found in atris/team/.');
|
|
3942
3960
|
console.log('Run "atris member create <name>" to create one.');
|
|
@@ -3969,11 +3987,11 @@ function memberList() {
|
|
|
3969
3987
|
const context = m.format === 'directory' ? String(m.contextCount) : '-';
|
|
3970
3988
|
console.log(
|
|
3971
3989
|
' ' +
|
|
3972
|
-
m.name
|
|
3973
|
-
m.role
|
|
3974
|
-
(m.format === 'directory' ? 'dir' : 'flat'
|
|
3975
|
-
skills
|
|
3976
|
-
context
|
|
3990
|
+
clipCell(m.name, nameW) +
|
|
3991
|
+
clipCell(m.role, roleW) +
|
|
3992
|
+
clipCell(m.format === 'directory' ? 'dir' : 'flat', fmtW) +
|
|
3993
|
+
clipCell(skills, skillW) +
|
|
3994
|
+
clipCell(context, ctxW) +
|
|
3977
3995
|
(m.version || '-')
|
|
3978
3996
|
);
|
|
3979
3997
|
}
|
|
@@ -4119,6 +4137,42 @@ tools: []
|
|
|
4119
4137
|
}
|
|
4120
4138
|
}
|
|
4121
4139
|
|
|
4140
|
+
function printMemberInstallUsage(stream = console.log) {
|
|
4141
|
+
stream('Usage: atris member install <slug>');
|
|
4142
|
+
}
|
|
4143
|
+
|
|
4144
|
+
function memberInstall(slug) {
|
|
4145
|
+
if (slug === '--help' || slug === '-h') {
|
|
4146
|
+
printMemberInstallUsage();
|
|
4147
|
+
return;
|
|
4148
|
+
}
|
|
4149
|
+
if (!slug || String(slug).startsWith('-')) {
|
|
4150
|
+
printMemberInstallUsage(console.error);
|
|
4151
|
+
process.exit(1);
|
|
4152
|
+
}
|
|
4153
|
+
if (!/^[a-zA-Z0-9._-]+$/.test(slug)) {
|
|
4154
|
+
console.error('Member name must be a local slug: letters, numbers, dots, underscores, or dashes.');
|
|
4155
|
+
process.exit(1);
|
|
4156
|
+
}
|
|
4157
|
+
|
|
4158
|
+
const memberDir = path.join(process.cwd(), 'atris', 'team', slug);
|
|
4159
|
+
const already = memberBundlePresent(memberDir);
|
|
4160
|
+
fs.mkdirSync(path.join(memberDir, 'logs'), { recursive: true });
|
|
4161
|
+
if (already) {
|
|
4162
|
+
console.log(`MEMBER already installed for ${slug}`);
|
|
4163
|
+
return;
|
|
4164
|
+
}
|
|
4165
|
+
|
|
4166
|
+
const { created } = ensureMemberBundle(memberDir, {
|
|
4167
|
+
name: slug,
|
|
4168
|
+
source: 'install',
|
|
4169
|
+
});
|
|
4170
|
+
for (const rel of created) {
|
|
4171
|
+
console.log(`atris/team/${slug}/${rel.split(path.sep).join('/')}`);
|
|
4172
|
+
}
|
|
4173
|
+
console.log(`MEMBER installed for ${slug}.`);
|
|
4174
|
+
}
|
|
4175
|
+
|
|
4122
4176
|
// --- ACTIVATE subcommand ---
|
|
4123
4177
|
|
|
4124
4178
|
function memberActivate(name) {
|
|
@@ -9010,17 +9064,19 @@ async function memberCommand(subcommand, ...args) {
|
|
|
9010
9064
|
// Subcommands that take a member name as args[0] otherwise treat `--help` as
|
|
9011
9065
|
// a name and error with "Member '--help' not found". `create`/`new` handle
|
|
9012
9066
|
// help themselves (with subcommand-specific usage) — leave those alone.
|
|
9013
|
-
const HELP_AWARE_SUBCOMMANDS = new Set(['create', 'new', 'run']);
|
|
9067
|
+
const HELP_AWARE_SUBCOMMANDS = new Set(['create', 'new', 'run', 'install']);
|
|
9014
9068
|
if (!HELP_AWARE_SUBCOMMANDS.has(subcommand) && (args[0] === '-h' || args[0] === '--help')) {
|
|
9015
9069
|
subcommand = undefined;
|
|
9016
9070
|
}
|
|
9017
9071
|
switch (subcommand) {
|
|
9018
9072
|
case 'list':
|
|
9019
9073
|
case 'ls':
|
|
9020
|
-
return memberList();
|
|
9074
|
+
return memberList(...args);
|
|
9021
9075
|
case 'create':
|
|
9022
9076
|
case 'new':
|
|
9023
9077
|
return memberCreate(args[0], ...args.slice(1));
|
|
9078
|
+
case 'install':
|
|
9079
|
+
return memberInstall(args[0]);
|
|
9024
9080
|
case 'activate':
|
|
9025
9081
|
return memberActivate(args[0]);
|
|
9026
9082
|
case 'upgrade':
|
|
@@ -9082,8 +9138,9 @@ async function memberCommand(subcommand, ...args) {
|
|
|
9082
9138
|
console.log('');
|
|
9083
9139
|
console.log('Subcommands:');
|
|
9084
9140
|
console.log(' create <name> Scaffold a new team member (MEMBER.md + dirs) [--push]');
|
|
9141
|
+
console.log(' install <slug> Install the full MEMBER bundle if missing; never overwrite');
|
|
9085
9142
|
console.log(' chat <name> "..." Send a message to this member\'s desk in Atris Desktop');
|
|
9086
|
-
console.log(' list
|
|
9143
|
+
console.log(' list [--json] Show all team members');
|
|
9087
9144
|
console.log(' activate <name> Symlink member skills, show context and permissions');
|
|
9088
9145
|
console.log(' upgrade <name> Convert flat file (name.md) to directory format');
|
|
9089
9146
|
console.log(' push <name> Push a local team member to the cloud');
|
|
@@ -9116,6 +9173,7 @@ async function memberCommand(subcommand, ...args) {
|
|
|
9116
9173
|
console.log('');
|
|
9117
9174
|
console.log('Examples:');
|
|
9118
9175
|
console.log(' atris member create sdr --role="Sales Development Rep"');
|
|
9176
|
+
console.log(' atris member install orb');
|
|
9119
9177
|
console.log(' atris member list');
|
|
9120
9178
|
console.log(' atris member activate navigator');
|
|
9121
9179
|
console.log(' atris member upgrade executor');
|