atris 3.15.49 → 3.15.51
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/commands/computer.js +54 -18
- package/commands/radar.js +3 -1
- package/lib/task-db.js +0 -1
- package/package.json +1 -1
package/commands/computer.js
CHANGED
|
@@ -544,6 +544,7 @@ function parseComputerOptions(argv) {
|
|
|
544
544
|
let workspaceId = null;
|
|
545
545
|
let waitForResult = true;
|
|
546
546
|
let message = null;
|
|
547
|
+
let force = false;
|
|
547
548
|
|
|
548
549
|
for (let i = 0; i < argv.length; i++) {
|
|
549
550
|
const arg = argv[i];
|
|
@@ -600,6 +601,10 @@ function parseComputerOptions(argv) {
|
|
|
600
601
|
waitForResult = false;
|
|
601
602
|
continue;
|
|
602
603
|
}
|
|
604
|
+
if (arg === '--force') {
|
|
605
|
+
force = true;
|
|
606
|
+
continue;
|
|
607
|
+
}
|
|
603
608
|
positional.push(arg);
|
|
604
609
|
}
|
|
605
610
|
|
|
@@ -618,6 +623,7 @@ function parseComputerOptions(argv) {
|
|
|
618
623
|
workspaceId: workspaceId ? String(workspaceId).trim() : null,
|
|
619
624
|
waitForResult,
|
|
620
625
|
message,
|
|
626
|
+
force,
|
|
621
627
|
},
|
|
622
628
|
};
|
|
623
629
|
}
|
|
@@ -1174,7 +1180,8 @@ function printComputerCommandFailure(result, ctx = null) {
|
|
|
1174
1180
|
if (result?.status === 409) {
|
|
1175
1181
|
const mismatch = extractAttachedWorkspaceMismatch(detail, result?.data);
|
|
1176
1182
|
const targetWorkspace = mismatch?.requestedWorkspaceId || ctx?.workspaceId || '<workspace-id>';
|
|
1177
|
-
|
|
1183
|
+
const forceFlag = /--force|force to take over|re-run with --force/i.test(detail) ? ' --force' : '';
|
|
1184
|
+
console.error(`Run: atris computer activate --business ${businessSelector(ctx)} --workspace ${targetWorkspace}${forceFlag}`);
|
|
1178
1185
|
}
|
|
1179
1186
|
}
|
|
1180
1187
|
|
|
@@ -1253,6 +1260,17 @@ function formatWorkspaceRef(workspace) {
|
|
|
1253
1260
|
return workspace.name ? `${workspace.name} (${workspace.id})` : workspace.id;
|
|
1254
1261
|
}
|
|
1255
1262
|
|
|
1263
|
+
function formatLeaseAge(seconds) {
|
|
1264
|
+
const value = Number(seconds);
|
|
1265
|
+
if (!Number.isFinite(value) || value < 0) return '-';
|
|
1266
|
+
if (value < 60) return `${Math.floor(value)}s`;
|
|
1267
|
+
const minutes = Math.floor(value / 60);
|
|
1268
|
+
if (minutes < 60) return `${minutes}m`;
|
|
1269
|
+
const hours = Math.floor(minutes / 60);
|
|
1270
|
+
if (hours < 48) return `${hours}h`;
|
|
1271
|
+
return `${Math.floor(hours / 24)}d`;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1256
1274
|
async function probeAttachedWorkspace(token, ctx) {
|
|
1257
1275
|
const result = await apiRequestJson(
|
|
1258
1276
|
`/business/${ctx.businessId}/workspaces/${ctx.workspaceId}/terminal`,
|
|
@@ -1272,7 +1290,7 @@ async function probeAttachedWorkspace(token, ctx) {
|
|
|
1272
1290
|
return { workspaceId: null, health: 'degraded', result };
|
|
1273
1291
|
}
|
|
1274
1292
|
|
|
1275
|
-
async function bootstrapBusinessComputerRuntime(token, ctx, boundary = 'computer-wake') {
|
|
1293
|
+
async function bootstrapBusinessComputerRuntime(token, ctx, boundary = 'computer-wake', options = {}) {
|
|
1276
1294
|
if (!ctx?.businessId || !ctx?.workspaceId) {
|
|
1277
1295
|
return { ok: false, skipped: true, reason: 'missing_workspace' };
|
|
1278
1296
|
}
|
|
@@ -1288,8 +1306,10 @@ async function bootstrapBusinessComputerRuntime(token, ctx, boundary = 'computer
|
|
|
1288
1306
|
});
|
|
1289
1307
|
const result = await runBusinessTerminalCommand(token, ctx, command, 120);
|
|
1290
1308
|
if (!result.ok) {
|
|
1291
|
-
|
|
1292
|
-
|
|
1309
|
+
if (!options.quiet) {
|
|
1310
|
+
console.log(' Runtime: bootstrap could not run.');
|
|
1311
|
+
console.log(` Recovery: atris computer run "npm install --prefix /workspace/.atris-npm atris@latest && /workspace/.atris-npm/node_modules/.bin/atris update" --business ${ctx.slug || ctx.businessId} --workspace ${ctx.workspaceId}`);
|
|
1312
|
+
}
|
|
1293
1313
|
return { ok: false, result };
|
|
1294
1314
|
}
|
|
1295
1315
|
|
|
@@ -1297,13 +1317,15 @@ async function bootstrapBusinessComputerRuntime(token, ctx, boundary = 'computer
|
|
|
1297
1317
|
const output = String(data.stdout || data.output || data.result || '').trim();
|
|
1298
1318
|
const line = output.split('\n').find((entry) => entry.includes('atris_runtime_bootstrap'));
|
|
1299
1319
|
const recovery = output.split('\n').find((entry) => entry.startsWith('recovery='));
|
|
1300
|
-
if (
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1320
|
+
if (!options.quiet) {
|
|
1321
|
+
if (line) {
|
|
1322
|
+
console.log(` Runtime: ${line.replace(/^atris_runtime_bootstrap\s*/, '')}`);
|
|
1323
|
+
} else {
|
|
1324
|
+
console.log(' Runtime: Atris bootstrap receipt written.');
|
|
1325
|
+
}
|
|
1326
|
+
if (recovery) {
|
|
1327
|
+
console.log(` Recovery: atris computer run "${recovery.slice('recovery='.length)}" --business ${ctx.slug || ctx.businessId} --workspace ${ctx.workspaceId}`);
|
|
1328
|
+
}
|
|
1307
1329
|
}
|
|
1308
1330
|
return { ok: true, output };
|
|
1309
1331
|
}
|
|
@@ -1471,7 +1493,7 @@ async function ensureBusinessAwake(token, ctx, maxWaitSec = 90, options = {}) {
|
|
|
1471
1493
|
if (next.ok && next.data && next.data.status === 'running' && next.data.endpoint) {
|
|
1472
1494
|
const elapsed = Math.floor((Date.now() - start) / 1000);
|
|
1473
1495
|
if (!options.quiet) console.log(`awake (${elapsed}s)`);
|
|
1474
|
-
await bootstrapBusinessComputerRuntime(token, ctx, 'computer-auto-wake');
|
|
1496
|
+
await bootstrapBusinessComputerRuntime(token, ctx, 'computer-auto-wake', options);
|
|
1475
1497
|
return true;
|
|
1476
1498
|
}
|
|
1477
1499
|
}
|
|
@@ -1500,10 +1522,24 @@ async function computerStatus(token, ctx = null) {
|
|
|
1500
1522
|
const targetWorkspace = workspaces.find((workspace) => workspace.id === ctx.workspaceId) || (ctx.workspaceId ? { id: ctx.workspaceId } : null);
|
|
1501
1523
|
console.log(` Default workspace: ${formatWorkspaceRef(defaultWorkspace)}`);
|
|
1502
1524
|
console.log(` Target workspace: ${formatWorkspaceRef(targetWorkspace)}`);
|
|
1525
|
+
const attachedFromStatus = d.attached_workspace_id
|
|
1526
|
+
? { workspaceId: d.attached_workspace_id, health: null }
|
|
1527
|
+
: null;
|
|
1528
|
+
if (attachedFromStatus) {
|
|
1529
|
+
const attachedWorkspace = workspaces.find((workspace) => workspace.id === attachedFromStatus.workspaceId)
|
|
1530
|
+
|| { id: attachedFromStatus.workspaceId, name: d.attached_workspace_name || null };
|
|
1531
|
+
console.log(` Attached workspace: ${formatWorkspaceRef(attachedWorkspace)}`);
|
|
1532
|
+
console.log(` Attached by: ${d.attached_by || '-'}`);
|
|
1533
|
+
console.log(` Attached at: ${d.attached_at || '-'}`);
|
|
1534
|
+
console.log(` Lease age: ${formatLeaseAge(d.lease_age_seconds)}`);
|
|
1535
|
+
if (d.takeover_hint) console.log(` Takeover hint: ${d.takeover_hint}`);
|
|
1536
|
+
}
|
|
1503
1537
|
if (status === 'running' && d.endpoint && ctx.workspaceId) {
|
|
1504
1538
|
const attached = await probeAttachedWorkspace(token, ctx);
|
|
1505
|
-
|
|
1506
|
-
|
|
1539
|
+
if (!attachedFromStatus) {
|
|
1540
|
+
const attachedWorkspace = workspaces.find((workspace) => workspace.id === attached.workspaceId) || (attached.workspaceId ? { id: attached.workspaceId } : null);
|
|
1541
|
+
console.log(` Attached workspace: ${formatWorkspaceRef(attachedWorkspace)}`);
|
|
1542
|
+
}
|
|
1507
1543
|
if (attached.health === 'workspace_mismatch') {
|
|
1508
1544
|
printComputerCommandFailure(attached.result, ctx);
|
|
1509
1545
|
} else if (attached.health !== 'ready') {
|
|
@@ -1686,7 +1722,7 @@ async function computerCreate(token, args = [], defaults = {}) {
|
|
|
1686
1722
|
console.log(` atris computer sleep --business ${owner} --workspace ${workspaceId}`);
|
|
1687
1723
|
}
|
|
1688
1724
|
|
|
1689
|
-
async function computerActivate(token, ctx = null) {
|
|
1725
|
+
async function computerActivate(token, ctx = null, options = {}) {
|
|
1690
1726
|
if (!ctx?.businessId || !ctx?.workspaceId) {
|
|
1691
1727
|
console.error('Usage: atris computer activate --business <slug> --workspace <id>');
|
|
1692
1728
|
process.exitCode = 1;
|
|
@@ -1696,7 +1732,7 @@ async function computerActivate(token, ctx = null) {
|
|
|
1696
1732
|
const result = await apiRequestJson(`/business/${ctx.businessId}/workspaces/${ctx.workspaceId}/activate`, {
|
|
1697
1733
|
method: 'POST',
|
|
1698
1734
|
token,
|
|
1699
|
-
body: {},
|
|
1735
|
+
body: { force: Boolean(options.force) },
|
|
1700
1736
|
});
|
|
1701
1737
|
if (!result.ok) {
|
|
1702
1738
|
printComputerCommandFailure(result, ctx);
|
|
@@ -2581,10 +2617,10 @@ async function computerChat(token, ctx, initialOptions = {}) {
|
|
|
2581
2617
|
}
|
|
2582
2618
|
|
|
2583
2619
|
const isCodeOps = initialOptions.mode === 'codeops' || ctx.slug === 'atris-codeops';
|
|
2620
|
+
const oneShotMessage = initialOptions.message != null;
|
|
2584
2621
|
const chatSystemPrompt = isCodeOps
|
|
2585
2622
|
? appendSystemPrompt(initialOptions.systemPrompt, CODEOPS_WORKFLOW_PROMPT)
|
|
2586
2623
|
: initialOptions.systemPrompt;
|
|
2587
|
-
const oneShotMessage = initialOptions.message != null;
|
|
2588
2624
|
let sessionId = `biz-${ctx.businessId.slice(0, 8)}-${Date.now().toString(36)}`;
|
|
2589
2625
|
const pipedInput = initialOptions.message != null ? null : await readPipedStdin();
|
|
2590
2626
|
const scriptedInput = initialOptions.message != null ? String(initialOptions.message) : pipedInput;
|
|
@@ -3398,7 +3434,7 @@ async function runComputer() {
|
|
|
3398
3434
|
case 'chat': return computerChat(token, ctx, cloudOptions);
|
|
3399
3435
|
case 'card': return computerCard(args.slice(1));
|
|
3400
3436
|
case 'proof': return computerProof(token, ctx, cloudOptions);
|
|
3401
|
-
case 'activate': return computerActivate(token, ctx);
|
|
3437
|
+
case 'activate': return computerActivate(token, ctx, cloudOptions);
|
|
3402
3438
|
case 'status': return computerStatus(token, ctx);
|
|
3403
3439
|
case 'up':
|
|
3404
3440
|
case 'wake': return computerWake(token, ctx);
|
package/commands/radar.js
CHANGED
|
@@ -332,6 +332,8 @@ function loadBusinessCollaboration(root, deps, team = {}) {
|
|
|
332
332
|
const episodes = countJsonLines(path.join(root, '.atris', 'state', 'episodes.jsonl'), deps);
|
|
333
333
|
const scorecards = countJsonLines(path.join(root, '.atris', 'state', 'scorecards.jsonl'), deps);
|
|
334
334
|
const computerDirs = countDirectoryEntries(path.join(root, 'atris', 'computers'), deps, name => !name.startsWith('.'));
|
|
335
|
+
const runtimeComputer = runtime && (runtime.workspace_id || runtime.business_id || runtime.scope === 'local-business-computer') ? 1 : 0;
|
|
336
|
+
const computers = Math.max(computerDirs, runtimeComputer);
|
|
335
337
|
const hasOnboarding = ingestPacks > 0 || starterBriefs > 0 || onePagers > 0;
|
|
336
338
|
const hasProofLoop = events > 0 || episodes > 0 || scorecards > 0 || localReceipts > 0;
|
|
337
339
|
const hasTeam = Number(team.total || 0) > 0;
|
|
@@ -360,7 +362,7 @@ function loadBusinessCollaboration(root, deps, team = {}) {
|
|
|
360
362
|
} : null,
|
|
361
363
|
onboarding: { packs: ingestPacks, starter_briefs: starterBriefs, first_loops: firstLoops, one_pagers: onePagers, reports },
|
|
362
364
|
proof: { events, episodes, scorecards, receipts: localReceipts },
|
|
363
|
-
computers
|
|
365
|
+
computers,
|
|
364
366
|
team_members: Number(team.total || 0),
|
|
365
367
|
active_goal_members: Number(team.active_goal_members || 0),
|
|
366
368
|
share_ready: missing.length === 0,
|
package/lib/task-db.js
CHANGED
|
@@ -572,7 +572,6 @@ function reviewTask(db, { id, actor, reward, lesson, nextTask, proof, careerXpEl
|
|
|
572
572
|
const metadata = row.metadata && typeof row.metadata === 'object' ? { ...row.metadata } : {};
|
|
573
573
|
const reviewingPendingProof = row.status === 'review'
|
|
574
574
|
&& metadata.approval_status === 'pending'
|
|
575
|
-
&& numericReward <= 0
|
|
576
575
|
&& metadata.agent_certified !== true;
|
|
577
576
|
let reviewPassCount = Number(metadata.agent_review_pass_count || 0);
|
|
578
577
|
if (reviewingPendingProof) {
|