atris 3.58.6 → 3.58.8
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/GETTING_STARTED.md +2 -2
- package/PERSONA.md +11 -11
- package/README.md +9 -1
- package/atris/GEMINI.md +7 -6
- package/atris/PERSONA.md +4 -4
- package/atris/features/README.md +77 -6
- package/atris/policies/engineering-principles.md +129 -0
- package/atris/policies/genesis.md +112 -0
- package/atris/policies/product-design-principles.md +100 -0
- package/atris/skills/README.md +44 -15
- package/atris/skills/aeo/SKILL.md +10 -10
- package/atris/skills/atris/SKILL.md +1 -1
- package/atris/skills/design/SKILL.md +3 -1
- package/atris/skills/engines/SKILL.md +42 -50
- package/atris/skills/meta/SKILL.md +4 -4
- package/atris/skills/youtube/SKILL.md +11 -11
- package/bin/atris.js +60 -8
- package/commands/aeo.js +9 -12
- package/commands/analytics.js +8 -11
- package/commands/auth.js +8 -2
- package/commands/autopilot.js +4 -3
- package/commands/avail.js +1 -1
- package/commands/brain.js +4 -1
- package/commands/business.js +13 -8
- package/commands/close.js +2 -1
- package/commands/computer.js +15 -10
- package/commands/context-sync.js +3 -3
- package/commands/design.js +362 -0
- package/commands/doc-health.js +377 -0
- package/commands/drive.js +32 -0
- package/commands/experiments.js +13 -4
- package/commands/improve.js +68 -2
- package/commands/integrations.js +2 -5
- package/commands/land.js +144 -4
- package/commands/learn.js +7 -2
- package/commands/member.js +239 -58
- package/commands/mission.js +94 -18
- package/commands/pack.js +2 -2
- package/commands/probe.js +11 -5
- package/commands/pull.js +1 -1
- package/commands/pulse.js +38 -0
- package/commands/push.js +1 -1
- package/commands/rainmaker.js +3 -16
- package/commands/rsi.js +156 -0
- package/commands/spaceship.js +1 -1
- package/commands/stream.js +27 -2
- package/commands/study.js +15 -9
- package/commands/sync.js +1 -1
- package/commands/task.js +54 -3
- package/commands/workflow.js +17 -7
- package/commands/youtube.js +76 -8
- package/lib/apply-gate.js +22 -4
- package/lib/codex-flight.js +28 -5
- package/lib/daily-log.js +88 -0
- package/lib/design-api.js +130 -0
- package/lib/engine-ask.js +1 -1
- package/lib/first-minute.js +1 -6
- package/lib/fleet.js +4 -1
- package/lib/improve-vitals-html.js +3 -2
- package/lib/known-commands.js +3 -3
- package/lib/lesson-contradiction.js +2 -2
- package/lib/map-refs.js +183 -0
- package/lib/member-context.js +42 -0
- package/lib/mission-room.js +4 -4
- package/lib/noninteractive.js +15 -4
- package/lib/policy-lessons.js +1 -1
- package/lib/receipt-block.js +137 -28
- package/lib/rsi-record.js +335 -0
- package/lib/runner-command.js +1 -1
- package/lib/scorecard.js +4 -4
- package/lib/sleep-sync.js +11 -0
- package/lib/state-detection.js +36 -17
- package/lib/task-db.js +74 -53
- package/lib/task-list-keeper.js +192 -0
- package/lib/todo-fallback.js +10 -4
- package/lib/todo.js +22 -10
- package/lib/wish-delegate.js +19 -5
- package/mcp/atris-mcp/index.mjs +227 -0
- package/package.json +4 -2
- package/scripts/det/det.js +2 -2
- package/scripts/det/pr-description.js +2 -2
- package/scripts/det/test.js +2 -2
- package/scripts/det/ytnotes +43 -8
- package/utils/api.js +1 -1
- package/utils/auth.js +79 -14
- package/utils/backend-root.js +31 -0
- package/utils/config.js +5 -4
- package/utils/owner-identity.js +61 -0
- package/atris/policies/LESSONS.md +0 -13
- package/atris/skills/autopilot/atris-autopilot.md +0 -71
package/commands/aeo.js
CHANGED
|
@@ -15,32 +15,29 @@
|
|
|
15
15
|
* atris aeo discover <source> [...] # discovery audit
|
|
16
16
|
* atris aeo audit <source> [...] # agent-usability audit
|
|
17
17
|
*
|
|
18
|
-
* Local workspace resolution: $ATRIS_AEO_ROOT or
|
|
18
|
+
* Local workspace resolution: $ATRIS_AEO_ROOT or the configured backend root.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
const fs = require('fs');
|
|
22
22
|
const os = require('os');
|
|
23
23
|
const path = require('path');
|
|
24
24
|
const { spawnSync } = require('child_process');
|
|
25
|
+
const { BACKEND_ROOT_HINT, resolveBackendRoot: resolveConfiguredBackendRoot } = require('../utils/backend-root');
|
|
25
26
|
const { loadCredentials, abortOnAuthFailure } = require('../utils/auth');
|
|
26
27
|
const { apiRequestJson } = require('../utils/api');
|
|
27
28
|
const { loadBusinesses, saveBusinesses } = require('./business');
|
|
28
29
|
|
|
29
|
-
function
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
for (const root of candidates) {
|
|
35
|
-
if (fs.existsSync(path.join(root, 'atris', 'features', 'aeo'))) return root;
|
|
36
|
-
}
|
|
37
|
-
return null;
|
|
30
|
+
function resolveAeoRoot() {
|
|
31
|
+
const explicit = process.env.ATRIS_AEO_ROOT;
|
|
32
|
+
if (explicit && fs.existsSync(path.join(explicit, 'atris', 'features', 'aeo'))) return explicit;
|
|
33
|
+
const backend = resolveConfiguredBackendRoot();
|
|
34
|
+
return backend && fs.existsSync(path.join(backend, 'atris', 'features', 'aeo')) ? backend : null;
|
|
38
35
|
}
|
|
39
36
|
|
|
40
37
|
function requireBackendRoot() {
|
|
41
|
-
const root =
|
|
38
|
+
const root = resolveAeoRoot();
|
|
42
39
|
if (!root) {
|
|
43
|
-
console.error(
|
|
40
|
+
console.error(`cannot find local aeo workspace; ${BACKEND_ROOT_HINT}`);
|
|
44
41
|
process.exit(1);
|
|
45
42
|
}
|
|
46
43
|
return root;
|
package/commands/analytics.js
CHANGED
|
@@ -68,17 +68,14 @@ function analyticsAtris() {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
// Parse timestamps for productivity hours. Match the journal heading
|
|
71
|
-
//
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
hourCounts[hour] = (hourCounts[hour] || 0) + 1;
|
|
80
|
-
}
|
|
81
|
-
});
|
|
71
|
+
// formats `### Title -- HH:MM`, `### Title - HH:MM`, and legacy `**HH:MM:SS**`.
|
|
72
|
+
// Only heading lines count, so a prose range like "10:00 - 12:30" is not a timestamp.
|
|
73
|
+
const timestampPattern = /^#{2,4} .*(?:\u2014|--| - )\s*(\d{2}):\d{2}(?::\d{2})?\s*$|\*\*(\d{2}):\d{2}(?::\d{2})?\*\*/gm;
|
|
74
|
+
for (const match of content.matchAll(timestampPattern)) {
|
|
75
|
+
const hour = parseInt(match[1] || match[2], 10);
|
|
76
|
+
if (Number.isFinite(hour) && hour >= 0 && hour < 24) {
|
|
77
|
+
hourCounts[hour] = (hourCounts[hour] || 0) + 1;
|
|
78
|
+
}
|
|
82
79
|
}
|
|
83
80
|
});
|
|
84
81
|
|
package/commands/auth.js
CHANGED
|
@@ -102,6 +102,10 @@ function scopedTokenCandidate(credentials = {}) {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
function canMintFromLogin(credentials = {}) {
|
|
105
|
+
if (credentials.source === 'agent_token_file') return false;
|
|
106
|
+
if (credentials.source === 'env' && Array.isArray(credentials.scopes) && credentials.scopes.length) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
105
109
|
const login = firstNonEmptyString(credentials.token);
|
|
106
110
|
const refresh = firstNonEmptyString(credentials.refresh_token);
|
|
107
111
|
if (isAgentAccessToken(login) && !refresh) return false;
|
|
@@ -227,8 +231,10 @@ async function ensureBilledCommandAuth(scope, deps = {}) {
|
|
|
227
231
|
const credentials = ensured?.credentials || await load(api) || {};
|
|
228
232
|
const candidate = scopedTokenCandidate(credentials);
|
|
229
233
|
const claims = decodeJwtClaims(candidate);
|
|
230
|
-
const scopes = claims?.scopes || credentials.agent_token_scopes || [];
|
|
231
|
-
const expiry = claims?.exp
|
|
234
|
+
const scopes = claims?.scopes || credentials.agent_token_scopes || credentials.scopes || [];
|
|
235
|
+
const expiry = claims?.exp
|
|
236
|
+
? claims.exp * 1000
|
|
237
|
+
: Date.parse(credentials.agent_token_expires_at || credentials.expires_at);
|
|
232
238
|
if (!deps.forceMint && candidate && Array.isArray(scopes) && scopes.includes(wanted) && Number.isFinite(expiry) && expiry > Date.now()) {
|
|
233
239
|
return { ok: true, token: candidate, minted: false, credentials };
|
|
234
240
|
}
|
package/commands/autopilot.js
CHANGED
|
@@ -25,14 +25,15 @@ const {
|
|
|
25
25
|
detectEndgameCompletion
|
|
26
26
|
} = require('../lib/scorecard');
|
|
27
27
|
const { REWARD_CONFIG, REWARD_CHECKSUM } = require('../lib/reward-config');
|
|
28
|
+
const { ownerIdentity } = require('../utils/owner-identity');
|
|
28
29
|
|
|
29
30
|
const pkg = require('../package.json');
|
|
30
31
|
|
|
31
32
|
const PHASE_TIMEOUT = 600000; // 10 min per phase
|
|
32
33
|
|
|
33
34
|
function looksOwnerClaimed(claimed) {
|
|
34
|
-
const text = String(claimed || '').toLowerCase();
|
|
35
|
-
return /\
|
|
35
|
+
const text = String(claimed || '').trim().toLowerCase();
|
|
36
|
+
return /\b(owner|human|operator)\b/.test(text) || ownerIdentity().names.includes(text.split(/\s+/)[0]);
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
function looksOwnerGatedTitle(title) {
|
|
@@ -640,7 +641,7 @@ function getContextFiles(phase, options = {}) {
|
|
|
640
641
|
// checkout is forbidden (COORDINATION.md Rule 4). Interpolated into the
|
|
641
642
|
// default and self-heal do prompts, never the benchmark prompt (it never
|
|
642
643
|
// commits).
|
|
643
|
-
const SHARED_CHECKOUT_GIT_CONTRACT = `- Shared-checkout git safety (COORDINATION.md Rule 4): edits to any repo OTHER than this tick's cwd (
|
|
644
|
+
const SHARED_CHECKOUT_GIT_CONTRACT = `- Shared-checkout git safety (COORDINATION.md Rule 4): edits to any repo OTHER than this tick's cwd (including sibling repos) go through a per-tick worktree, start with \`atris worktree start --member <member> --task "<task>"\`, land with \`atris worktree ship --message "<msg>" --verify "<cmd>"\`. Never edit a sibling repo's shared checkout directly.
|
|
644
645
|
- On a shared checkout, \`git reset\`, \`git checkout --\`, \`git clean\`, and stashing other agents' work are FORBIDDEN, concurrent ticks' uncommitted work lives there.`;
|
|
645
646
|
|
|
646
647
|
/**
|
package/commands/avail.js
CHANGED
|
@@ -308,7 +308,7 @@ async function slotsAvail(argv) {
|
|
|
308
308
|
if (!username) {
|
|
309
309
|
const identity = await apiRequestJson('/identity/me', { method: 'GET', token });
|
|
310
310
|
if (!identity.ok || !identity.data?.username) {
|
|
311
|
-
console.error('
|
|
311
|
+
console.error('could not resolve username; pass --user <username>.');
|
|
312
312
|
return 1;
|
|
313
313
|
}
|
|
314
314
|
username = identity.data.username;
|
package/commands/brain.js
CHANGED
|
@@ -3,6 +3,7 @@ const path = require('path');
|
|
|
3
3
|
const crypto = require('crypto');
|
|
4
4
|
const { spawnSync } = require('child_process');
|
|
5
5
|
const { refreshNowFile } = require('./now');
|
|
6
|
+
const { ownerIdentity } = require('../utils/owner-identity');
|
|
6
7
|
const escapeRegExp = require('../lib/escape-regexp');
|
|
7
8
|
const { hasRenderedSections, isOpenSection, isDoneSection } = require('../lib/todo-sections');
|
|
8
9
|
const { isNonInteractive } = require('../lib/noninteractive');
|
|
@@ -794,7 +795,8 @@ function memberNextMove(member, state = null) {
|
|
|
794
795
|
if (member.slug === 'justin' || /justin/i.test(member.name || '')) {
|
|
795
796
|
return `${name}: run one customer-moving GTM rep, update the relevant workspace state within 10 minutes, and leave a scorecard.`;
|
|
796
797
|
}
|
|
797
|
-
|
|
798
|
+
const ownerNames = ownerIdentity().names;
|
|
799
|
+
if (ownerNames.includes(String(member.slug || '').toLowerCase()) || ownerNames.includes(String(member.name || '').toLowerCase())) {
|
|
798
800
|
return `${name}: act as Customer 0: choose one allocation, narrative, system, or talent leverage move; leave proof and route the next owner.`;
|
|
799
801
|
}
|
|
800
802
|
if (/opus|overnight/i.test(identity)) {
|
|
@@ -1774,6 +1776,7 @@ function brainCommand(args = process.argv.slice(3)) {
|
|
|
1774
1776
|
}
|
|
1775
1777
|
|
|
1776
1778
|
module.exports = {
|
|
1779
|
+
readText,
|
|
1777
1780
|
brainCommand,
|
|
1778
1781
|
collectState,
|
|
1779
1782
|
renderStatus,
|
package/commands/business.js
CHANGED
|
@@ -13,6 +13,10 @@ const {
|
|
|
13
13
|
renderDryRun,
|
|
14
14
|
} = require('../lib/business-simulate');
|
|
15
15
|
|
|
16
|
+
function businessWorkspaceBase() {
|
|
17
|
+
return process.env.ATRIS_BUSINESS_ROOT || path.join(os.homedir(), 'arena', 'atris-business');
|
|
18
|
+
}
|
|
19
|
+
|
|
16
20
|
function getBusinessConfigPath() {
|
|
17
21
|
const home = require('os').homedir();
|
|
18
22
|
const dir = path.join(home, '.atris');
|
|
@@ -179,7 +183,7 @@ function buildBusinessCacheEntry(business, localSlug, existing = {}) {
|
|
|
179
183
|
return entry;
|
|
180
184
|
}
|
|
181
185
|
|
|
182
|
-
function readBusinessFolderBindings(rootDir =
|
|
186
|
+
function readBusinessFolderBindings(rootDir = businessWorkspaceBase()) {
|
|
183
187
|
const skip = new Set([
|
|
184
188
|
'.git', '.DS_Store', 'archive', 'archives', '_archive', 'bench', 'deals',
|
|
185
189
|
'node_modules', 'shelf', '_shelf', 'templates',
|
|
@@ -510,7 +514,7 @@ function resolveWorkspaceRoot(slug, options = {}) {
|
|
|
510
514
|
if (options.noLocal) return null;
|
|
511
515
|
if (options.here) return options.cwd || process.cwd();
|
|
512
516
|
if (options.root) return path.join(options.root, slug);
|
|
513
|
-
return path.join(
|
|
517
|
+
return path.join(businessWorkspaceBase(), slug);
|
|
514
518
|
}
|
|
515
519
|
|
|
516
520
|
function createCanonicalBusinessWorkspace(targetRoot, bizMeta, options = {}) {
|
|
@@ -1851,7 +1855,7 @@ async function addBusiness(slug) {
|
|
|
1851
1855
|
}
|
|
1852
1856
|
|
|
1853
1857
|
async function listBusinesses(opts = {}) {
|
|
1854
|
-
// --local mode: walk
|
|
1858
|
+
// --local mode: walk the configured business workspace folder
|
|
1855
1859
|
// (no API calls, rate-limit safe). Different from API-mode below which lists
|
|
1856
1860
|
// businesses cached from the API.
|
|
1857
1861
|
if (opts.local) {
|
|
@@ -1877,7 +1881,7 @@ async function listBusinesses(opts = {}) {
|
|
|
1877
1881
|
}
|
|
1878
1882
|
|
|
1879
1883
|
/**
|
|
1880
|
-
* Walk
|
|
1884
|
+
* Walk the configured business folder and print a fleet status table for every
|
|
1881
1885
|
* customer workspace. Pure local, no API calls, no rate-limit risk.
|
|
1882
1886
|
*
|
|
1883
1887
|
* Classifies each dir as: ready, flat, unbound, nested, bare, or superseded.
|
|
@@ -1891,7 +1895,7 @@ function listBusinessesLocal(opts = {}) {
|
|
|
1891
1895
|
const SKIP_DIRS = new Set(['deals', 'archive', 'archives', '_archive', 'templates', 'node_modules', '.git']);
|
|
1892
1896
|
const SKIP_FILES = new Set(['.DS_Store', 'Thumbs.db']);
|
|
1893
1897
|
|
|
1894
|
-
const rootDir = opts.root ||
|
|
1898
|
+
const rootDir = opts.root || businessWorkspaceBase();
|
|
1895
1899
|
const jsonMode = opts.json === true;
|
|
1896
1900
|
|
|
1897
1901
|
if (!fs.existsSync(rootDir)) {
|
|
@@ -2609,7 +2613,7 @@ function parseBusinessDoctorOptions(args = []) {
|
|
|
2609
2613
|
const options = {
|
|
2610
2614
|
fix: args.includes('--fix'),
|
|
2611
2615
|
json: args.includes('--json'),
|
|
2612
|
-
root:
|
|
2616
|
+
root: businessWorkspaceBase(),
|
|
2613
2617
|
};
|
|
2614
2618
|
const rootIdx = args.indexOf('--root');
|
|
2615
2619
|
if (rootIdx !== -1 && args[rootIdx + 1]) {
|
|
@@ -2623,7 +2627,7 @@ function printBusinessDoctorHelp() {
|
|
|
2623
2627
|
console.log('');
|
|
2624
2628
|
console.log('Checks cloud-active businesses against:');
|
|
2625
2629
|
console.log(' - ~/.atris/businesses.json');
|
|
2626
|
-
console.log(
|
|
2630
|
+
console.log(` - ${businessWorkspaceBase()}/*/.atris/business.json`);
|
|
2627
2631
|
console.log(' - canonical slug + alias bindings');
|
|
2628
2632
|
console.log('');
|
|
2629
2633
|
console.log('--fix rewrites only safe local cache entries. It does not rename folders or touch cloud data.');
|
|
@@ -3454,7 +3458,7 @@ async function quickstart() {
|
|
|
3454
3458
|
atris business init "My Company" --template saas
|
|
3455
3459
|
|
|
3456
3460
|
2. Open the local workspace:
|
|
3457
|
-
cd
|
|
3461
|
+
cd ${businessWorkspaceBase()}/my-company
|
|
3458
3462
|
|
|
3459
3463
|
3. See what Atris knows:
|
|
3460
3464
|
atris
|
|
@@ -3675,6 +3679,7 @@ async function businessCommand(subcommand, ...args) {
|
|
|
3675
3679
|
|
|
3676
3680
|
module.exports = {
|
|
3677
3681
|
businessCommand,
|
|
3682
|
+
businessWorkspaceBase,
|
|
3678
3683
|
loadBusinesses,
|
|
3679
3684
|
saveBusinesses,
|
|
3680
3685
|
businessMatchesSlug,
|
package/commands/close.js
CHANGED
|
@@ -5,6 +5,7 @@ const { spawnSync } = require('child_process');
|
|
|
5
5
|
const { knownCommands } = require('../lib/known-commands');
|
|
6
6
|
const { readUsage, usagePath } = require('../lib/usage');
|
|
7
7
|
const pulse = require('../lib/pulse');
|
|
8
|
+
const { isOwner } = require('../utils/owner-identity');
|
|
8
9
|
const { parseLessons } = require('./autopilot');
|
|
9
10
|
|
|
10
11
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
@@ -240,7 +241,7 @@ function parkedFlags(cwd = process.cwd(), options = {}) {
|
|
|
240
241
|
}
|
|
241
242
|
|
|
242
243
|
function ownerWaitRank(flag) {
|
|
243
|
-
return
|
|
244
|
+
return isOwner(flag.owner) ? 0 : 1;
|
|
244
245
|
}
|
|
245
246
|
|
|
246
247
|
function compareOpenFlags(a, b) {
|
package/commands/computer.js
CHANGED
|
@@ -23,8 +23,9 @@ const path = require('path');
|
|
|
23
23
|
const readline = require('readline');
|
|
24
24
|
const { spawnSync } = require('child_process');
|
|
25
25
|
const { loadCredentials, decodeJwtClaims, promptUser, abortOnAuthFailure } = require('../utils/auth');
|
|
26
|
+
const { resolveBackendRoot } = require('../utils/backend-root');
|
|
26
27
|
const { apiRequestJson, getApiBaseUrl, getAppBaseUrl } = require('../utils/api');
|
|
27
|
-
const { loadBusinesses, saveBusinesses } = require('./business');
|
|
28
|
+
const { businessWorkspaceBase, loadBusinesses, saveBusinesses } = require('./business');
|
|
28
29
|
const {
|
|
29
30
|
engineLoginSeatError,
|
|
30
31
|
formatEngineSeats,
|
|
@@ -37,6 +38,7 @@ const {
|
|
|
37
38
|
const { consoleCommand, gatherAtrisContext, buildSystemPrompt } = require('./console');
|
|
38
39
|
const { streamSession } = require('./serve');
|
|
39
40
|
const { buildRemoteAtrisBootstrapCommand } = require('../lib/runtime-bootstrap');
|
|
41
|
+
const { envForcesNonInteractive } = require('../lib/noninteractive');
|
|
40
42
|
|
|
41
43
|
function getToken() {
|
|
42
44
|
const creds = loadCredentials();
|
|
@@ -270,11 +272,11 @@ const ui = {
|
|
|
270
272
|
};
|
|
271
273
|
|
|
272
274
|
function useInteractiveCloudUi() {
|
|
273
|
-
return Boolean(process.stdin.isTTY && process.stdout.isTTY && !
|
|
275
|
+
return Boolean(process.stdin.isTTY && process.stdout.isTTY && !envForcesNonInteractive());
|
|
274
276
|
}
|
|
275
277
|
|
|
276
278
|
function useInteractiveTerminalUi() {
|
|
277
|
-
return Boolean(process.stdin.isTTY && process.stdout.isTTY && !
|
|
279
|
+
return Boolean(process.stdin.isTTY && process.stdout.isTTY && !envForcesNonInteractive());
|
|
278
280
|
}
|
|
279
281
|
|
|
280
282
|
async function readPipedStdin() {
|
|
@@ -517,7 +519,7 @@ function displayHomeRelativePath(targetPath) {
|
|
|
517
519
|
}
|
|
518
520
|
|
|
519
521
|
function recruitingBusinessWorkspacePath(slug = RECRUITING_BUSINESS_SLUG) {
|
|
520
|
-
const root =
|
|
522
|
+
const root = businessWorkspaceBase();
|
|
521
523
|
return path.join(root, slug);
|
|
522
524
|
}
|
|
523
525
|
|
|
@@ -1371,11 +1373,12 @@ function printModeBanner(mode, root, lines = []) {
|
|
|
1371
1373
|
|
|
1372
1374
|
function findAtrisCodeTerminal() {
|
|
1373
1375
|
const envPath = process.env.ATRIS_CODE_PY;
|
|
1376
|
+
const backend = resolveBackendRoot();
|
|
1374
1377
|
const candidates = [
|
|
1375
1378
|
envPath,
|
|
1376
1379
|
path.join(__dirname, '..', 'cli', 'atris_code.py'),
|
|
1377
1380
|
path.join(process.cwd(), 'cli', 'atris_code.py'),
|
|
1378
|
-
path.join(
|
|
1381
|
+
...(backend ? [path.join(backend, 'cli', 'atris_code.py')] : []),
|
|
1379
1382
|
].filter(Boolean);
|
|
1380
1383
|
|
|
1381
1384
|
let dir = process.cwd();
|
|
@@ -2534,7 +2537,7 @@ async function computerCreate(token, args = [], defaults = {}) {
|
|
|
2534
2537
|
console.log(` atris computer --business ${owner} --workspace ${workspaceId}`);
|
|
2535
2538
|
console.log('');
|
|
2536
2539
|
console.log('Org workspace:');
|
|
2537
|
-
console.log(` cd
|
|
2540
|
+
console.log(` cd ${businessWorkspaceBase()}/${owner}`);
|
|
2538
2541
|
console.log(' atris member activate operator');
|
|
2539
2542
|
console.log(' atris member activate validator');
|
|
2540
2543
|
console.log('');
|
|
@@ -3500,7 +3503,7 @@ async function sendBusinessChat(token, ctx, message, sessionId, resetContext = f
|
|
|
3500
3503
|
async function computerChat(token, ctx, initialOptions = {}) {
|
|
3501
3504
|
if (!ctx) {
|
|
3502
3505
|
console.error('Cloud computer mode requires a bound business workspace.');
|
|
3503
|
-
console.error('
|
|
3506
|
+
console.error('run this inside a bound business workspace, or use `atris computer --local` for local mode.');
|
|
3504
3507
|
return;
|
|
3505
3508
|
}
|
|
3506
3509
|
|
|
@@ -3741,7 +3744,7 @@ async function computerChat(token, ctx, initialOptions = {}) {
|
|
|
3741
3744
|
async function computerLocalAtris(token, ctx, initialOptions = {}) {
|
|
3742
3745
|
if (!ctx) {
|
|
3743
3746
|
console.error('Atris local mode needs a bound business workspace for the cloud brain.');
|
|
3744
|
-
console.error('
|
|
3747
|
+
console.error('run inside a bound business workspace, or use `atris computer local-byo`.');
|
|
3745
3748
|
return;
|
|
3746
3749
|
}
|
|
3747
3750
|
|
|
@@ -3976,7 +3979,7 @@ async function computerLocalAtris(token, ctx, initialOptions = {}) {
|
|
|
3976
3979
|
async function computerProof(token, ctx, initialOptions = {}) {
|
|
3977
3980
|
if (!ctx) {
|
|
3978
3981
|
console.error('Atris computer proof needs a bound business workspace.');
|
|
3979
|
-
console.error('
|
|
3982
|
+
console.error('run inside a bound business workspace first.');
|
|
3980
3983
|
process.exitCode = 1;
|
|
3981
3984
|
return;
|
|
3982
3985
|
}
|
|
@@ -4290,7 +4293,7 @@ async function runComputer(argv = process.argv.slice(3), deps = {}) {
|
|
|
4290
4293
|
console.log('A business can be a company, lab, collective, community, artist, team, or project.');
|
|
4291
4294
|
console.log('');
|
|
4292
4295
|
console.log('First use:');
|
|
4293
|
-
console.log(
|
|
4296
|
+
console.log(` cd ${businessWorkspaceBase()}/<business>`);
|
|
4294
4297
|
console.log(' atris computer');
|
|
4295
4298
|
console.log(' Choose Cloud workspace or Local folder, then type the outcome in plain English.');
|
|
4296
4299
|
console.log('');
|
|
@@ -4470,6 +4473,8 @@ module.exports = {
|
|
|
4470
4473
|
extractAttachedWorkspaceMismatch,
|
|
4471
4474
|
contextForAttachedWorkspaceMismatch,
|
|
4472
4475
|
printRecruitingLocalSyncOutcome,
|
|
4476
|
+
useInteractiveCloudUi,
|
|
4477
|
+
useInteractiveTerminalUi,
|
|
4473
4478
|
// Hermetic parsing/formatting layer, exported for test/computer.test.js.
|
|
4474
4479
|
parseComputerOptions,
|
|
4475
4480
|
parseComputerCreateArgs,
|
package/commands/context-sync.js
CHANGED
|
@@ -64,7 +64,7 @@ async function businessStatus(slug) {
|
|
|
64
64
|
const timeSince = manifest ? _timeSince(manifest.last_sync) : null;
|
|
65
65
|
|
|
66
66
|
console.log('');
|
|
67
|
-
console.log(`${biz.name}` + (timeSince ?
|
|
67
|
+
console.log(`${biz.name}` + (timeSince ? `: last synced ${timeSince}` : ': never synced'));
|
|
68
68
|
|
|
69
69
|
// Determine local directory
|
|
70
70
|
let localDir = null;
|
|
@@ -254,11 +254,11 @@ async function businessLog(slug) {
|
|
|
254
254
|
|
|
255
255
|
const commits = result.data.commits || [];
|
|
256
256
|
if (commits.length === 0) {
|
|
257
|
-
console.log(`\n ${biz.name}
|
|
257
|
+
console.log(`\n ${biz.name}: no history yet.\n`);
|
|
258
258
|
return;
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
console.log(`\n ${biz.name}
|
|
261
|
+
console.log(`\n ${biz.name}: history\n`);
|
|
262
262
|
|
|
263
263
|
for (const commit of commits) {
|
|
264
264
|
const date = _timeSince(commit.date) || commit.date;
|