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/commands/worktree.js
CHANGED
package/commands/write.js
CHANGED
|
@@ -23,6 +23,7 @@ const fs = require('fs');
|
|
|
23
23
|
const path = require('path');
|
|
24
24
|
const { spawnSync } = require('child_process');
|
|
25
25
|
const { scanFile, RULES, loadProjectRules } = require('./slop');
|
|
26
|
+
const { isHelpToken } = require('../lib/noninteractive');
|
|
26
27
|
|
|
27
28
|
const WRITING_DIR = path.join('atris', 'writing');
|
|
28
29
|
// Beats are question-shaped (Pollan: "almost everything I write is a quest to
|
|
@@ -125,6 +126,10 @@ function syncStates(slug, root = process.cwd()) {
|
|
|
125
126
|
}
|
|
126
127
|
|
|
127
128
|
function start(argv, root = process.cwd()) {
|
|
129
|
+
if ((argv || []).some(isHelpToken)) {
|
|
130
|
+
console.error(' usage: atris write start "<topic>" [--dump "..."] [--beats "a | b | c"]');
|
|
131
|
+
return 2;
|
|
132
|
+
}
|
|
128
133
|
const topic = argv.find((a) => !a.startsWith('-'));
|
|
129
134
|
if (!topic) { console.error(' usage: atris write start "<topic>" [--dump "..."] [--beats "a | b | c"]'); return 2; }
|
|
130
135
|
const flag = (name) => { const i = argv.indexOf(name); return i !== -1 ? argv[i + 1] : null; };
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { apiRequestJson } = require('../utils/api');
|
|
4
|
+
const { ensureBilledCommandAuth } = require('./auth');
|
|
5
|
+
|
|
6
|
+
const DEFAULT_TIMEOUT_MS = 120000;
|
|
7
|
+
const COST_HINT = '5 credits per search';
|
|
8
|
+
|
|
9
|
+
function showXSearchHelp(output = console.log, commandName = 'atris x-search') {
|
|
10
|
+
output('');
|
|
11
|
+
output(`Usage: ${commandName} "<query>" [--limit N] [--days N] [--json]`);
|
|
12
|
+
output(` ${commandName} person --name <name> [--handle <h>] [--company <c>] [--context <text>] [--json]`);
|
|
13
|
+
output('');
|
|
14
|
+
output(`Search X/Twitter via Atris (${COST_HINT}).`);
|
|
15
|
+
output('Requires login. Same auth path as atris youtube process.');
|
|
16
|
+
output('');
|
|
17
|
+
output('Options:');
|
|
18
|
+
output(' --limit <n> Max results hint (search only)');
|
|
19
|
+
output(' --days <n> Only tweets from the last N days (search only)');
|
|
20
|
+
output(' --json Print the raw JSON response');
|
|
21
|
+
output(' -h, --help This help');
|
|
22
|
+
output('');
|
|
23
|
+
output('Person options:');
|
|
24
|
+
output(' --name <text> Person to research (required)');
|
|
25
|
+
output(' --handle <text> X handle without @');
|
|
26
|
+
output(' --company <text> Company or org');
|
|
27
|
+
output(' --context <text> Why you are researching them');
|
|
28
|
+
output('');
|
|
29
|
+
output('Examples:');
|
|
30
|
+
output(` ${commandName} "MCP agents"`);
|
|
31
|
+
output(` ${commandName} "MCP agents" --limit 5 --days 2`);
|
|
32
|
+
output(` ${commandName} person --name "Leah Bonvissuto" --handle leahbon`);
|
|
33
|
+
output('');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function readValue(args, index, name) {
|
|
37
|
+
if (index >= args.length - 1 || String(args[index + 1]).startsWith('--')) {
|
|
38
|
+
throw new Error(`${name} requires a value`);
|
|
39
|
+
}
|
|
40
|
+
return args[index + 1];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function parsePositiveInt(raw, name) {
|
|
44
|
+
const value = Number(raw);
|
|
45
|
+
if (!Number.isInteger(value) || value <= 0) {
|
|
46
|
+
throw new Error(`${name} must be a positive integer`);
|
|
47
|
+
}
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function parseSearchArgs(argv = []) {
|
|
52
|
+
const args = [...argv];
|
|
53
|
+
const options = {
|
|
54
|
+
mode: 'search',
|
|
55
|
+
help: false,
|
|
56
|
+
json: false,
|
|
57
|
+
query: null,
|
|
58
|
+
limit: null,
|
|
59
|
+
daysBack: null,
|
|
60
|
+
timeoutMs: DEFAULT_TIMEOUT_MS,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
if (args.length === 0 || ['help', '--help', '-h'].includes(args[0])) {
|
|
64
|
+
options.help = true;
|
|
65
|
+
return options;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
for (let i = 0; i < args.length; i++) {
|
|
69
|
+
const arg = args[i];
|
|
70
|
+
if (arg === '--help' || arg === '-h' || arg === 'help') {
|
|
71
|
+
options.help = true;
|
|
72
|
+
} else if (arg === '--json') {
|
|
73
|
+
options.json = true;
|
|
74
|
+
} else if (arg === '--limit') {
|
|
75
|
+
options.limit = parsePositiveInt(readValue(args, i, arg), '--limit');
|
|
76
|
+
i++;
|
|
77
|
+
} else if (arg.startsWith('--limit=')) {
|
|
78
|
+
options.limit = parsePositiveInt(arg.slice('--limit='.length), '--limit');
|
|
79
|
+
} else if (arg === '--days' || arg === '--days-back' || arg === '--days_back') {
|
|
80
|
+
options.daysBack = parsePositiveInt(readValue(args, i, arg), '--days');
|
|
81
|
+
i++;
|
|
82
|
+
} else if (arg.startsWith('--days=')) {
|
|
83
|
+
options.daysBack = parsePositiveInt(arg.slice('--days='.length), '--days');
|
|
84
|
+
} else if (arg.startsWith('--days-back=') || arg.startsWith('--days_back=')) {
|
|
85
|
+
const raw = arg.includes('=') ? arg.slice(arg.indexOf('=') + 1) : '';
|
|
86
|
+
options.daysBack = parsePositiveInt(raw, '--days');
|
|
87
|
+
} else if (arg === '--timeout') {
|
|
88
|
+
const seconds = Number(readValue(args, i, arg));
|
|
89
|
+
if (!Number.isFinite(seconds) || seconds <= 0) {
|
|
90
|
+
throw new Error('--timeout must be a positive number of seconds');
|
|
91
|
+
}
|
|
92
|
+
options.timeoutMs = Math.round(seconds * 1000);
|
|
93
|
+
i++;
|
|
94
|
+
} else if (arg.startsWith('--timeout=')) {
|
|
95
|
+
const seconds = Number(arg.slice('--timeout='.length));
|
|
96
|
+
if (!Number.isFinite(seconds) || seconds <= 0) {
|
|
97
|
+
throw new Error('--timeout must be a positive number of seconds');
|
|
98
|
+
}
|
|
99
|
+
options.timeoutMs = Math.round(seconds * 1000);
|
|
100
|
+
} else if (arg.startsWith('-')) {
|
|
101
|
+
throw new Error(`Unknown option: ${arg}`);
|
|
102
|
+
} else if (!options.query) {
|
|
103
|
+
options.query = arg;
|
|
104
|
+
} else {
|
|
105
|
+
throw new Error(`Unexpected argument: ${arg}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (options.help) return options;
|
|
110
|
+
if (!options.query) throw new Error('Missing query. Run "atris x-search --help".');
|
|
111
|
+
return options;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function parsePersonArgs(argv = []) {
|
|
115
|
+
const args = [...argv];
|
|
116
|
+
const options = {
|
|
117
|
+
mode: 'person',
|
|
118
|
+
help: false,
|
|
119
|
+
json: false,
|
|
120
|
+
name: null,
|
|
121
|
+
handle: null,
|
|
122
|
+
company: null,
|
|
123
|
+
context: null,
|
|
124
|
+
timeoutMs: DEFAULT_TIMEOUT_MS,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
if (args.length === 0 || ['help', '--help', '-h'].includes(args[0])) {
|
|
128
|
+
options.help = true;
|
|
129
|
+
return options;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
for (let i = 0; i < args.length; i++) {
|
|
133
|
+
const arg = args[i];
|
|
134
|
+
if (arg === '--help' || arg === '-h' || arg === 'help') {
|
|
135
|
+
options.help = true;
|
|
136
|
+
} else if (arg === '--json') {
|
|
137
|
+
options.json = true;
|
|
138
|
+
} else if (arg === '--name') {
|
|
139
|
+
options.name = readValue(args, i, arg);
|
|
140
|
+
i++;
|
|
141
|
+
} else if (arg.startsWith('--name=')) {
|
|
142
|
+
options.name = arg.slice('--name='.length);
|
|
143
|
+
} else if (arg === '--handle') {
|
|
144
|
+
options.handle = String(readValue(args, i, arg)).replace(/^@/, '');
|
|
145
|
+
i++;
|
|
146
|
+
} else if (arg.startsWith('--handle=')) {
|
|
147
|
+
options.handle = arg.slice('--handle='.length).replace(/^@/, '');
|
|
148
|
+
} else if (arg === '--company') {
|
|
149
|
+
options.company = readValue(args, i, arg);
|
|
150
|
+
i++;
|
|
151
|
+
} else if (arg.startsWith('--company=')) {
|
|
152
|
+
options.company = arg.slice('--company='.length);
|
|
153
|
+
} else if (arg === '--context') {
|
|
154
|
+
options.context = readValue(args, i, arg);
|
|
155
|
+
i++;
|
|
156
|
+
} else if (arg.startsWith('--context=')) {
|
|
157
|
+
options.context = arg.slice('--context='.length);
|
|
158
|
+
} else if (arg === '--timeout') {
|
|
159
|
+
const seconds = Number(readValue(args, i, arg));
|
|
160
|
+
if (!Number.isFinite(seconds) || seconds <= 0) {
|
|
161
|
+
throw new Error('--timeout must be a positive number of seconds');
|
|
162
|
+
}
|
|
163
|
+
options.timeoutMs = Math.round(seconds * 1000);
|
|
164
|
+
i++;
|
|
165
|
+
} else if (arg.startsWith('--timeout=')) {
|
|
166
|
+
const seconds = Number(arg.slice('--timeout='.length));
|
|
167
|
+
if (!Number.isFinite(seconds) || seconds <= 0) {
|
|
168
|
+
throw new Error('--timeout must be a positive number of seconds');
|
|
169
|
+
}
|
|
170
|
+
options.timeoutMs = Math.round(seconds * 1000);
|
|
171
|
+
} else if (arg.startsWith('-')) {
|
|
172
|
+
throw new Error(`Unknown option: ${arg}`);
|
|
173
|
+
} else {
|
|
174
|
+
throw new Error(`Unexpected argument: ${arg}`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (options.help) return options;
|
|
179
|
+
if (!options.name) throw new Error('Missing --name. Run "atris x-search person --help".');
|
|
180
|
+
return options;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function parseXSearchArgs(argv = []) {
|
|
184
|
+
const args = [...argv];
|
|
185
|
+
if (args[0] === 'person') {
|
|
186
|
+
return parsePersonArgs(args.slice(1));
|
|
187
|
+
}
|
|
188
|
+
return parseSearchArgs(args);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function buildSearchPayload(options) {
|
|
192
|
+
const payload = { query: options.query };
|
|
193
|
+
if (options.limit != null) payload.limit = options.limit;
|
|
194
|
+
if (options.daysBack != null) payload.days_back = options.daysBack;
|
|
195
|
+
return payload;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function buildPersonPayload(options) {
|
|
199
|
+
const payload = { name: options.name };
|
|
200
|
+
if (options.handle) payload.handle = options.handle;
|
|
201
|
+
if (options.company) payload.company = options.company;
|
|
202
|
+
if (options.context) payload.context = options.context;
|
|
203
|
+
return payload;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function resultErrorText(result) {
|
|
207
|
+
const raw = result?.error || result?.text || 'unknown error';
|
|
208
|
+
if (typeof raw === 'string') return raw;
|
|
209
|
+
try {
|
|
210
|
+
return JSON.stringify(raw);
|
|
211
|
+
} catch {
|
|
212
|
+
return String(raw);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function xSearchFailureError(result) {
|
|
217
|
+
const hint = result.status === 401
|
|
218
|
+
? ' Run "atris login --force".'
|
|
219
|
+
: result.status === 402
|
|
220
|
+
? ' Check Atris credits.'
|
|
221
|
+
: result.status === 502
|
|
222
|
+
? ' xAI is unavailable; retry in a few seconds.'
|
|
223
|
+
: '';
|
|
224
|
+
return new Error(`X search failed (${result.status}): ${resultErrorText(result)}.${hint}`);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async function ensureToken(deps = {}) {
|
|
228
|
+
const ensureBilled = deps.ensureBilledCommandAuth || ensureBilledCommandAuth;
|
|
229
|
+
const auth = await ensureBilled('x-search', deps);
|
|
230
|
+
if (!auth?.ok || !auth.token) {
|
|
231
|
+
throw new Error(auth?.error || 'not signed in. run atris login first.');
|
|
232
|
+
}
|
|
233
|
+
return auth;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
async function runXSearch(options, deps = {}) {
|
|
237
|
+
const apiFn = deps.apiRequestJson || apiRequestJson;
|
|
238
|
+
let auth = await ensureToken(deps);
|
|
239
|
+
const pathname = options.mode === 'person' ? '/x-search/research-person' : '/x-search/search';
|
|
240
|
+
const body = options.mode === 'person' ? buildPersonPayload(options) : buildSearchPayload(options);
|
|
241
|
+
|
|
242
|
+
const call = (token) => apiFn(pathname, {
|
|
243
|
+
method: 'POST',
|
|
244
|
+
token,
|
|
245
|
+
timeoutMs: options.timeoutMs,
|
|
246
|
+
retries: 0,
|
|
247
|
+
body,
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
let result = await call(auth.token);
|
|
251
|
+
if (!result.ok && result.status === 401 && !auth.minted) {
|
|
252
|
+
const remint = await (deps.ensureBilledCommandAuth || ensureBilledCommandAuth)('x-search', {
|
|
253
|
+
...deps,
|
|
254
|
+
forceMint: true,
|
|
255
|
+
});
|
|
256
|
+
if (remint?.ok && remint.token) {
|
|
257
|
+
auth = remint;
|
|
258
|
+
result = await call(auth.token);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (!result.ok) {
|
|
263
|
+
throw xSearchFailureError(result);
|
|
264
|
+
}
|
|
265
|
+
return result.data;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function formatXSearchResult(data) {
|
|
269
|
+
const lines = [];
|
|
270
|
+
const payload = data?.data && typeof data.data === 'object' ? data.data : data;
|
|
271
|
+
const content = payload?.content != null ? String(payload.content).trim() : '';
|
|
272
|
+
const citations = Array.isArray(payload?.citations)
|
|
273
|
+
? payload.citations
|
|
274
|
+
: (Array.isArray(data?.citations) ? data.citations : []);
|
|
275
|
+
|
|
276
|
+
if (content) {
|
|
277
|
+
lines.push(content);
|
|
278
|
+
} else if (data?.message) {
|
|
279
|
+
lines.push(String(data.message).trim());
|
|
280
|
+
} else {
|
|
281
|
+
lines.push('X search completed');
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (citations.length) {
|
|
285
|
+
lines.push('');
|
|
286
|
+
lines.push('Citations:');
|
|
287
|
+
for (const cite of citations) {
|
|
288
|
+
lines.push(` ${cite}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const used = data?.credits_used !== undefined ? data.credits_used : payload?.credits_used;
|
|
293
|
+
const remaining = data?.credits_remaining !== undefined
|
|
294
|
+
? data.credits_remaining
|
|
295
|
+
: payload?.credits_remaining;
|
|
296
|
+
if (used !== undefined || remaining !== undefined) {
|
|
297
|
+
lines.push('');
|
|
298
|
+
lines.push(`Credits: ${used !== undefined ? used : '?'} used, ${remaining !== undefined ? remaining : '?'} remaining`);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return lines.join('\n');
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
async function xSearchCommand(argv = process.argv.slice(3), deps = {}) {
|
|
305
|
+
const output = deps.output || ((line = '') => console.log(line));
|
|
306
|
+
let options;
|
|
307
|
+
try {
|
|
308
|
+
options = parseXSearchArgs(argv);
|
|
309
|
+
} catch (err) {
|
|
310
|
+
output(err.message);
|
|
311
|
+
return 2;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (options.help) {
|
|
315
|
+
showXSearchHelp(output, deps.commandName || 'atris x-search');
|
|
316
|
+
return 0;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
let status = 0;
|
|
320
|
+
try {
|
|
321
|
+
const data = await runXSearch(options, deps);
|
|
322
|
+
output(options.json ? JSON.stringify(data, null, 2) : formatXSearchResult(data));
|
|
323
|
+
} catch (err) {
|
|
324
|
+
output(err.message);
|
|
325
|
+
status = 1;
|
|
326
|
+
}
|
|
327
|
+
if (!deps.output && !deps.apiRequestJson && !deps.ensureValidCredentials && !deps.ensureBilledCommandAuth) {
|
|
328
|
+
process.exit(status);
|
|
329
|
+
}
|
|
330
|
+
return status;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
module.exports = {
|
|
334
|
+
DEFAULT_TIMEOUT_MS,
|
|
335
|
+
parseXSearchArgs,
|
|
336
|
+
buildSearchPayload,
|
|
337
|
+
buildPersonPayload,
|
|
338
|
+
formatXSearchResult,
|
|
339
|
+
xSearchCommand,
|
|
340
|
+
};
|
package/commands/xp.js
CHANGED
|
@@ -112,6 +112,7 @@ function showHelp() {
|
|
|
112
112
|
console.log(' atris xp [--json] [--local] [--workspace <path>] [--operator <name>]');
|
|
113
113
|
console.log('');
|
|
114
114
|
console.log('Show your AgentXP graph for the active Atris account.');
|
|
115
|
+
console.log('With no bound business (.atris/business.json), defaults to --local workspace receipts.');
|
|
115
116
|
console.log('Use status to show account-level AgentXP across verified local ledgers.');
|
|
116
117
|
console.log('Use collect or status --local to project accepted task proof in the current workspace.');
|
|
117
118
|
console.log('Use session to encapsulate the current work window into a local XP capsule.');
|
|
@@ -2327,7 +2328,10 @@ async function xpCommand(...args) {
|
|
|
2327
2328
|
}
|
|
2328
2329
|
|
|
2329
2330
|
const jsonMode = args.includes('--json');
|
|
2330
|
-
const
|
|
2331
|
+
const explicitLocal = hasFlagOrValue(args, '--local') || hasFlagOrValue(args, '--workspace') || hasFlagOrValue(args, '--operator');
|
|
2332
|
+
// No bound business means cloud graph has nothing useful; default to local receipts.
|
|
2333
|
+
const boundBusiness = publicWorkspaceBinding(defaultXpWorkspace());
|
|
2334
|
+
const localMode = explicitLocal || !boundBusiness;
|
|
2331
2335
|
if (localMode) {
|
|
2332
2336
|
let payload;
|
|
2333
2337
|
try {
|