atris 3.57.4 → 3.58.5
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/README.md +12 -1
- package/atris/skills/clawhub/member-runtime/SKILL.md +9 -9
- package/atris/skills/create-member/SKILL.md +16 -13
- package/atris/skills/design/SKILL.md +27 -4
- package/atris/skills/engines/SKILL.md +55 -12
- package/atris/skills/x-search/SKILL.md +8 -6
- package/atris/skills/youtube/SKILL.md +37 -8
- package/atris/team/brainstormer/MEMBER.md +2 -2
- package/atris/team/executor/MEMBER.md +3 -3
- package/atris/team/launcher/MEMBER.md +4 -4
- package/atris/team/navigator/MEMBER.md +3 -3
- package/atris/team/researcher/MEMBER.md +2 -2
- package/atris/team/validator/MEMBER.md +1 -1
- package/atris.md +14 -0
- package/ax +153 -23
- package/bin/atris.js +78 -30
- package/commands/aeo.js +4 -4
- package/commands/agents.js +1 -1
- package/commands/align.js +12 -12
- package/commands/analytics.js +3 -3
- package/commands/app.js +5 -5
- package/commands/ask.js +175 -0
- package/commands/auth.js +7 -7
- package/commands/autoland.js +29 -5
- package/commands/autopilot-front.js +6 -6
- package/commands/autopilot.js +90 -90
- package/commands/avail.js +5 -5
- package/commands/bench.js +63 -1
- package/commands/browse.js +2 -2
- package/commands/business.js +12 -12
- package/commands/card.js +2 -2
- package/commands/clean.js +13 -13
- package/commands/close.js +3 -3
- package/commands/compile.js +13 -13
- package/commands/computer.js +94 -27
- package/commands/console.js +5 -5
- package/commands/decide.js +1 -1
- package/commands/deck.js +9 -9
- package/commands/drive.js +4 -4
- package/commands/engine.js +173 -19
- package/commands/errors.js +3 -3
- package/commands/experiments.js +18 -1
- package/commands/feed.js +2 -2
- package/commands/feedback.js +4 -4
- package/commands/fleet.js +12 -12
- package/commands/game.js +1 -1
- package/commands/guide.js +49 -0
- package/commands/improve.js +19 -17
- package/commands/init.js +67 -19
- package/commands/interview.js +7 -7
- package/commands/land.js +40 -15
- package/commands/learn.js +12 -12
- package/commands/lesson.js +2 -2
- package/commands/log.js +1 -1
- package/commands/loops.js +4 -4
- package/commands/member.js +75 -50
- package/commands/mission.js +90 -82
- package/commands/one-lap.js +1 -1
- package/commands/pack.js +74 -8
- package/commands/plugin.js +6 -6
- package/commands/probe.js +9 -9
- package/commands/pull.js +35 -35
- package/commands/pulse.js +1 -1
- package/commands/push.js +21 -21
- package/commands/rainmaker.js +1 -1
- package/commands/recap.js +7 -7
- package/commands/reel.js +2 -2
- package/commands/release.js +3 -3
- package/commands/report.js +1 -1
- package/commands/review.js +5 -5
- package/commands/revisions.js +1 -1
- package/commands/run.js +1 -1
- package/commands/scout.js +3 -3
- package/commands/security-review.js +7 -7
- package/commands/serve.js +9 -9
- package/commands/setup.js +1 -1
- package/commands/sign.js +4 -4
- package/commands/signup.js +4 -4
- package/commands/site.js +8 -3
- package/commands/skill.js +6 -6
- package/commands/slop.js +18 -18
- package/commands/social.js +3 -3
- package/commands/soul.js +14 -14
- package/commands/spaceship.js +1 -1
- package/commands/status.js +2 -2
- package/commands/strings.js +13 -13
- package/commands/study.js +4 -4
- package/commands/sync.js +8 -8
- package/commands/task.js +50 -25
- package/commands/teach.js +2 -2
- package/commands/team.js +1 -1
- package/commands/theme.js +2 -2
- package/commands/tree.js +34 -0
- package/commands/truth.js +7 -7
- package/commands/verify.js +12 -12
- package/commands/visualize.js +2 -2
- package/commands/workflow.js +97 -40
- package/commands/worktree.js +1 -1
- package/commands/write.js +9 -9
- package/commands/x-search.js +89 -17
- package/commands/xp.js +6 -3
- package/commands/youtube.js +601 -48
- package/lib/accept-verify-gate.js +3 -3
- package/lib/activity-stream.js +1 -1
- package/lib/auto-accept-certified.js +28 -12
- package/lib/autoland.js +6 -6
- package/lib/bench/engines.js +59 -8
- package/lib/bench/report.js +1 -1
- package/lib/bench/runner.js +204 -5
- package/lib/bench/tree-render.js +76 -0
- package/lib/card.js +1 -1
- package/lib/chat-log-scan.js +1 -1
- package/lib/claude-boot-block.js +2 -0
- package/lib/deck-compose.js +1 -1
- package/lib/deck-history.js +2 -2
- package/lib/deck-layout.js +1 -1
- package/lib/deck-review.js +5 -5
- package/lib/deck-schema.js +1 -1
- package/lib/default-verifier.js +1 -1
- package/lib/developer-api.js +3 -0
- package/lib/engine-ask.js +45 -7
- package/lib/engine-registry.js +15 -2
- package/lib/file-ops.js +1 -1
- package/lib/fleet.js +71 -35
- package/lib/html-render.js +1 -1
- package/lib/intents.js +172 -0
- package/lib/journal.js +1 -1
- package/lib/known-commands.js +2 -2
- package/lib/land-green.js +364 -0
- package/lib/lesson-contradiction.js +2 -2
- package/lib/lesson-preflight.js +1 -1
- package/lib/manifest.js +5 -5
- package/lib/member-alive.js +9 -5
- package/lib/memory-view.js +3 -3
- package/lib/mission-protected-lane.js +1 -1
- package/lib/mission-root.js +2 -2
- package/lib/orb-context.js +10 -10
- package/lib/pack-capabilities.js +861 -3
- package/lib/permission-grants.js +2 -2
- package/lib/policy-lessons.js +6 -6
- package/lib/pulse.js +8 -8
- package/lib/receipt-evidence.js +1 -1
- package/lib/reel.js +1 -1
- package/lib/review-integrity.js +1 -1
- package/lib/runner-command.js +35 -5
- package/lib/scorecard.js +4 -4
- package/lib/security-scan.js +5 -5
- package/lib/self-drive.js +1 -1
- package/lib/site-publish.js +372 -0
- package/lib/site.js +1 -1
- package/lib/slides-deck.js +2 -2
- package/lib/state-detection.js +2 -2
- package/lib/sync-telemetry.js +2 -2
- package/lib/task-db.js +17 -10
- package/lib/task-explanation.js +1 -1
- package/lib/task-proof.js +2 -2
- package/lib/task-receipt.js +3 -3
- package/lib/theme.js +12 -12
- package/lib/todo-fallback.js +3 -3
- package/lib/todo-sections.js +1 -1
- package/lib/tree-hash.js +79 -0
- package/lib/usage.js +1 -1
- package/lib/wish-delegate.js +1 -1
- package/lib/workspace-safety.js +4 -4
- package/lib/workspace-scaffold.js +3 -3
- package/package.json +1 -1
- package/scripts/det/concierge-bakeoff.sh +26 -0
- package/scripts/det/ytquote-repair.js +0 -1
- package/scripts/det/ytrail-race.js +0 -5
- package/scripts/member-operate.mjs +52 -14
- package/scripts/outbound-artifact-gate.js +0 -3
- package/utils/auth.js +0 -3
- package/utils/config.js +0 -1
- package/scripts/det/checklist-score.js +0 -191
package/commands/computer.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Atris Computer
|
|
2
|
+
* Atris Computer: interact with your EC2 AI Computer
|
|
3
3
|
*
|
|
4
|
-
* atris computer
|
|
5
|
-
* atris computer setup
|
|
6
|
-
* atris computer --cloud
|
|
7
|
-
* atris computer create <name>
|
|
8
|
-
* atris computer wake
|
|
9
|
-
* atris computer sleep
|
|
10
|
-
* atris computer delete
|
|
11
|
-
* atris computer card
|
|
12
|
-
* atris computer run <command>
|
|
13
|
-
* atris computer grep <pattern>
|
|
14
|
-
* atris computer ls [path]
|
|
15
|
-
* atris computer cat <path>
|
|
16
|
-
* atris computer exec <prompt>
|
|
17
|
-
* atris computer recruiting
|
|
4
|
+
* atris computer : Open SMART mode (cloud in business workspace, local elsewhere)
|
|
5
|
+
* atris computer setup : Connect coding accounts to a computer
|
|
6
|
+
* atris computer --cloud : Open CLOUD workspace mode
|
|
7
|
+
* atris computer create <name> : Create and wake a business computer
|
|
8
|
+
* atris computer wake : Start the computer
|
|
9
|
+
* atris computer sleep : Stop (files persist)
|
|
10
|
+
* atris computer delete : Sleep, confirm, and delete a business computer
|
|
11
|
+
* atris computer card : Show the local computer card
|
|
12
|
+
* atris computer run <command> : Run bash on EC2 (no LLM)
|
|
13
|
+
* atris computer grep <pattern> : Search files on EC2
|
|
14
|
+
* atris computer ls [path] : List files
|
|
15
|
+
* atris computer cat <path> : Read a file
|
|
16
|
+
* atris computer exec <prompt> : Run with LLM (Claude Code)
|
|
17
|
+
* atris computer recruiting : Open the recruiting workflow shortcut
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
const fs = require('fs');
|
|
@@ -440,7 +440,7 @@ function appendSystemPrompt(basePrompt, extraPrompt) {
|
|
|
440
440
|
function codeOpsCloudOptions(options = {}) {
|
|
441
441
|
return {
|
|
442
442
|
...options,
|
|
443
|
-
worker: options.worker ||
|
|
443
|
+
worker: options.worker || null,
|
|
444
444
|
mode: 'codeops',
|
|
445
445
|
systemPrompt: appendSystemPrompt(options.systemPrompt, CODEOPS_WORKFLOW_PROMPT),
|
|
446
446
|
};
|
|
@@ -449,7 +449,7 @@ function codeOpsCloudOptions(options = {}) {
|
|
|
449
449
|
function recruitingCloudOptions(options = {}) {
|
|
450
450
|
return {
|
|
451
451
|
...options,
|
|
452
|
-
worker: options.worker ||
|
|
452
|
+
worker: options.worker || null,
|
|
453
453
|
mode: 'recruiting',
|
|
454
454
|
systemPrompt: appendSystemPrompt(options.systemPrompt, RECRUITING_WORKFLOW_PROMPT),
|
|
455
455
|
};
|
|
@@ -1124,7 +1124,7 @@ async function chooseComputerSurface(hasBusinessBinding, hasLocalHarness) {
|
|
|
1124
1124
|
}
|
|
1125
1125
|
|
|
1126
1126
|
async function chooseCloudLane(token, ctx, initialOptions = {}) {
|
|
1127
|
-
let worker = initialOptions.worker || null;
|
|
1127
|
+
let worker = initialOptions.worker || ctx?.worker || null;
|
|
1128
1128
|
let model = initialOptions.model || null;
|
|
1129
1129
|
|
|
1130
1130
|
if (!worker && useInteractiveCloudUi()) {
|
|
@@ -1664,6 +1664,19 @@ function computerCard(args = [], cwd = process.cwd()) {
|
|
|
1664
1664
|
return card;
|
|
1665
1665
|
}
|
|
1666
1666
|
|
|
1667
|
+
function savedBusinessWorker(slug) {
|
|
1668
|
+
if (!slug) return null;
|
|
1669
|
+
const wanted = String(slug).toLowerCase();
|
|
1670
|
+
const businesses = loadBusinesses();
|
|
1671
|
+
const entry = businesses[slug] || Object.values(businesses).find((item) => {
|
|
1672
|
+
if (!item) return false;
|
|
1673
|
+
return String(item.slug || '').toLowerCase() === wanted
|
|
1674
|
+
|| String(item.canonical_slug || '').toLowerCase() === wanted
|
|
1675
|
+
|| String(item.name || '').toLowerCase() === wanted;
|
|
1676
|
+
});
|
|
1677
|
+
return entry?.worker || null;
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1667
1680
|
async function resolveBusinessContext(token) {
|
|
1668
1681
|
const binding = readBusinessBinding();
|
|
1669
1682
|
if (!binding) return null;
|
|
@@ -1674,6 +1687,7 @@ async function resolveBusinessContext(token) {
|
|
|
1674
1687
|
businessId: binding.business_id,
|
|
1675
1688
|
workspaceId: binding.workspace_id,
|
|
1676
1689
|
businessName: binding.name || binding.slug || 'business',
|
|
1690
|
+
worker: savedBusinessWorker(binding.slug),
|
|
1677
1691
|
};
|
|
1678
1692
|
}
|
|
1679
1693
|
|
|
@@ -1688,6 +1702,7 @@ async function resolveBusinessContext(token) {
|
|
|
1688
1702
|
);
|
|
1689
1703
|
if (match) {
|
|
1690
1704
|
businesses[slug] = {
|
|
1705
|
+
...(businesses[slug] || {}),
|
|
1691
1706
|
business_id: match.id,
|
|
1692
1707
|
workspace_id: match.workspace_id,
|
|
1693
1708
|
name: match.name,
|
|
@@ -1700,6 +1715,7 @@ async function resolveBusinessContext(token) {
|
|
|
1700
1715
|
businessId: match.id,
|
|
1701
1716
|
workspaceId: match.workspace_id,
|
|
1702
1717
|
businessName: match.name || match.slug,
|
|
1718
|
+
worker: businesses[slug].worker || null,
|
|
1703
1719
|
};
|
|
1704
1720
|
}
|
|
1705
1721
|
}
|
|
@@ -1711,6 +1727,7 @@ async function resolveBusinessContext(token) {
|
|
|
1711
1727
|
businessId: cached.business_id,
|
|
1712
1728
|
workspaceId: cached.workspace_id,
|
|
1713
1729
|
businessName: cached.name || slug,
|
|
1730
|
+
worker: cached.worker || null,
|
|
1714
1731
|
};
|
|
1715
1732
|
}
|
|
1716
1733
|
|
|
@@ -1733,6 +1750,7 @@ function cachedBusinessContext(slug) {
|
|
|
1733
1750
|
businessId: cached.business_id,
|
|
1734
1751
|
workspaceId: cached.workspace_id || null,
|
|
1735
1752
|
businessName: cached.name || cached.slug || slug,
|
|
1753
|
+
worker: cached.worker || null,
|
|
1736
1754
|
};
|
|
1737
1755
|
}
|
|
1738
1756
|
|
|
@@ -1751,7 +1769,9 @@ async function resolveBusinessContextBySlug(token, slug, options = {}) {
|
|
|
1751
1769
|
(b) => b.slug === slug || (b.name || '').toLowerCase() === slug.toLowerCase()
|
|
1752
1770
|
);
|
|
1753
1771
|
if (match) {
|
|
1754
|
-
|
|
1772
|
+
const key = match.slug || slug;
|
|
1773
|
+
businesses[key] = {
|
|
1774
|
+
...(businesses[key] || {}),
|
|
1755
1775
|
business_id: match.id,
|
|
1756
1776
|
workspace_id: match.workspace_id,
|
|
1757
1777
|
name: match.name,
|
|
@@ -1764,6 +1784,7 @@ async function resolveBusinessContextBySlug(token, slug, options = {}) {
|
|
|
1764
1784
|
businessId: match.id,
|
|
1765
1785
|
workspaceId: match.workspace_id,
|
|
1766
1786
|
businessName: match.name || match.slug,
|
|
1787
|
+
worker: businesses[key].worker || null,
|
|
1767
1788
|
};
|
|
1768
1789
|
}
|
|
1769
1790
|
}
|
|
@@ -1790,6 +1811,7 @@ async function resolveSingleBusinessShortcutFallback(token, slug) {
|
|
|
1790
1811
|
const businesses = loadBusinesses();
|
|
1791
1812
|
const businessName = shortcutBusinessLabel(wantedSlug, match.name || match.slug);
|
|
1792
1813
|
businesses[wantedSlug] = {
|
|
1814
|
+
...(businesses[wantedSlug] || {}),
|
|
1793
1815
|
business_id: match.id,
|
|
1794
1816
|
workspace_id: match.workspace_id,
|
|
1795
1817
|
name: businessName,
|
|
@@ -1803,6 +1825,7 @@ async function resolveSingleBusinessShortcutFallback(token, slug) {
|
|
|
1803
1825
|
businessId: match.id,
|
|
1804
1826
|
workspaceId: match.workspace_id,
|
|
1805
1827
|
businessName,
|
|
1828
|
+
worker: businesses[wantedSlug].worker || null,
|
|
1806
1829
|
};
|
|
1807
1830
|
}
|
|
1808
1831
|
|
|
@@ -2839,12 +2862,12 @@ async function computerDiff(token, remotePath, ctx = null) {
|
|
|
2839
2862
|
for (const f of remoteFiles) {
|
|
2840
2863
|
const localPath = path.join(localDir, f.name);
|
|
2841
2864
|
if (!fs.existsSync(localPath)) {
|
|
2842
|
-
console.log(` + ${f.name} (${f.size}b)
|
|
2865
|
+
console.log(` + ${f.name} (${f.size}b), new on EC2`);
|
|
2843
2866
|
added++;
|
|
2844
2867
|
} else {
|
|
2845
2868
|
const localSize = fs.statSync(localPath).size;
|
|
2846
2869
|
if (Math.abs(localSize - (f.size || 0)) > 10) {
|
|
2847
|
-
console.log(` ~ ${f.name} (local: ${localSize}b, EC2: ${f.size}b)
|
|
2870
|
+
console.log(` ~ ${f.name} (local: ${localSize}b, EC2: ${f.size}b), changed`);
|
|
2848
2871
|
modified++;
|
|
2849
2872
|
} else {
|
|
2850
2873
|
same++;
|
|
@@ -2857,7 +2880,7 @@ async function computerDiff(token, remotePath, ctx = null) {
|
|
|
2857
2880
|
const remoteNames = new Set(remoteFiles.map(f => f.name));
|
|
2858
2881
|
for (const localFile of fs.readdirSync(localDir)) {
|
|
2859
2882
|
if (!remoteNames.has(localFile) && localFile.endsWith('.md')) {
|
|
2860
|
-
console.log(` - ${localFile}
|
|
2883
|
+
console.log(` - ${localFile}, deleted on EC2`);
|
|
2861
2884
|
deleted++;
|
|
2862
2885
|
}
|
|
2863
2886
|
}
|
|
@@ -2924,7 +2947,7 @@ async function computerOnboard(token, businessSlug) {
|
|
|
2924
2947
|
|
|
2925
2948
|
// Step 1: Push soul template
|
|
2926
2949
|
console.log('\n 1. Pushing soul template...');
|
|
2927
|
-
const soulTemplate = `# Soul
|
|
2950
|
+
const soulTemplate = `# Soul: ${businessSlug}\n\n## Identity\nBusiness computer for ${businessSlug}. Self-improving context system.\n\n## Goals\n- Learn the business overnight\n- Accumulate context that makes the agent smarter\n- Track what works and what doesn't\n\n## Rules\n- No emails without approval\n- No destructive actions\n- Save everything to soul/\n`;
|
|
2928
2951
|
|
|
2929
2952
|
const templateResult = await apiRequestJson('/ai-computer/terminal', {
|
|
2930
2953
|
method: 'POST', token,
|
|
@@ -2949,7 +2972,7 @@ async function computerOnboard(token, businessSlug) {
|
|
|
2949
2972
|
' NAME=$(basename $f .md)',
|
|
2950
2973
|
' FIRST_LINE=$(head -1 $f | sed "s/^# //")',
|
|
2951
2974
|
' SIZE=$(wc -c < $f | tr -d " ")',
|
|
2952
|
-
' echo "- [$NAME]($NAME.md)
|
|
2975
|
+
' echo "- [$NAME]($NAME.md), $FIRST_LINE ($SIZE bytes)" >> soul/INDEX.md',
|
|
2953
2976
|
' COUNT=$((COUNT + 1)); TOTAL_SIZE=$((TOTAL_SIZE + SIZE))',
|
|
2954
2977
|
'done',
|
|
2955
2978
|
'echo "" >> soul/INDEX.md',
|
|
@@ -3024,6 +3047,48 @@ async function computerLearn(token, ctx = null) {
|
|
|
3024
3047
|
console.log(` The computer is thinking... check back with: atris computer diff soul`);
|
|
3025
3048
|
}
|
|
3026
3049
|
|
|
3050
|
+
function computerLane(rest, ctx) {
|
|
3051
|
+
if (!ctx?.slug && !ctx?.businessId) {
|
|
3052
|
+
console.error('No business selected. Pass --business <slug>.');
|
|
3053
|
+
process.exitCode = 1;
|
|
3054
|
+
return;
|
|
3055
|
+
}
|
|
3056
|
+
const businesses = loadBusinesses();
|
|
3057
|
+
const key = Object.keys(businesses).find((slug) => {
|
|
3058
|
+
const entry = businesses[slug] || {};
|
|
3059
|
+
return slug === ctx.slug || entry.business_id === ctx.businessId;
|
|
3060
|
+
});
|
|
3061
|
+
if (!key) {
|
|
3062
|
+
console.error(`Business ${ctx.slug || ctx.businessId} is not in the local business list yet. Run any computer command against it once, then retry.`);
|
|
3063
|
+
process.exitCode = 1;
|
|
3064
|
+
return;
|
|
3065
|
+
}
|
|
3066
|
+
const requested = (rest || '').trim().toLowerCase();
|
|
3067
|
+
if (!requested) {
|
|
3068
|
+
const current = businesses[key].worker || null;
|
|
3069
|
+
console.log(current
|
|
3070
|
+
? ` Saved lane for ${key}: ${formatWorkerName(current)}`
|
|
3071
|
+
: ` No saved lane for ${key}. Runs default to Claude unless you pass --worker.`);
|
|
3072
|
+
console.log(` Set one: atris computer lane <claude|openai> --business ${key}`);
|
|
3073
|
+
return;
|
|
3074
|
+
}
|
|
3075
|
+
if (requested === 'clear' || requested === 'none') {
|
|
3076
|
+
delete businesses[key].worker;
|
|
3077
|
+
saveBusinesses(businesses);
|
|
3078
|
+
console.log(` Cleared saved lane for ${key}.`);
|
|
3079
|
+
return;
|
|
3080
|
+
}
|
|
3081
|
+
if (!['claude', 'openai', 'codex'].includes(requested)) {
|
|
3082
|
+
console.error(`Unknown lane "${requested}". Use claude, openai, or clear.`);
|
|
3083
|
+
process.exitCode = 1;
|
|
3084
|
+
return;
|
|
3085
|
+
}
|
|
3086
|
+
const normalized = requested === 'codex' ? 'openai' : requested;
|
|
3087
|
+
businesses[key].worker = normalized;
|
|
3088
|
+
saveBusinesses(businesses);
|
|
3089
|
+
console.log(` Saved lane for ${key}: ${formatWorkerName(normalized)}. Every run for this business now uses it unless you pass --worker.`);
|
|
3090
|
+
}
|
|
3091
|
+
|
|
3027
3092
|
async function computerExec(token, prompt, ctx = null, options = {}) {
|
|
3028
3093
|
if (!prompt) {
|
|
3029
3094
|
console.error('Usage: atris computer exec "<prompt>"');
|
|
@@ -3037,8 +3102,9 @@ async function computerExec(token, prompt, ctx = null, options = {}) {
|
|
|
3037
3102
|
console.error(' Computer did not become ready in time.');
|
|
3038
3103
|
return;
|
|
3039
3104
|
}
|
|
3040
|
-
const worker = activeWorker(options.worker);
|
|
3041
|
-
|
|
3105
|
+
const worker = activeWorker(options.worker || ctx.worker);
|
|
3106
|
+
const laneSource = options.worker ? '' : ctx.worker ? ' (saved for this business)' : '';
|
|
3107
|
+
console.log(` Lane: ${formatWorkerName(worker)} ${formatCloudSelection({ worker, model: options.model })}${laneSource}`);
|
|
3042
3108
|
const result = await apiRequestJson(`/business/${ctx.businessId}/chat`, {
|
|
3043
3109
|
method: 'POST',
|
|
3044
3110
|
token,
|
|
@@ -3451,7 +3517,7 @@ async function computerChat(token, ctx, initialOptions = {}) {
|
|
|
3451
3517
|
const scriptedInput = initialOptions.message != null ? String(initialOptions.message) : pipedInput;
|
|
3452
3518
|
if (!oneShotMessage) printCloudWordmark();
|
|
3453
3519
|
const selection = oneShotMessage
|
|
3454
|
-
? { worker: initialOptions.worker, model: initialOptions.model }
|
|
3520
|
+
? { worker: initialOptions.worker || ctx?.worker || null, model: initialOptions.model }
|
|
3455
3521
|
: await chooseCloudLane(token, ctx, initialOptions);
|
|
3456
3522
|
if (selection.cancelled) return;
|
|
3457
3523
|
let worker = activeWorker(selection.worker);
|
|
@@ -4377,6 +4443,7 @@ async function runComputer(argv = process.argv.slice(3), deps = {}) {
|
|
|
4377
4443
|
case 'ls': return computerLs(token, rest || undefined, ctx);
|
|
4378
4444
|
case 'cat': return computerCat(token, rest, ctx);
|
|
4379
4445
|
case 'exec': return computerExec(token, rest, ctx, cloudOptions);
|
|
4446
|
+
case 'lane': return computerLane(rest, ctx);
|
|
4380
4447
|
case 'pull': {
|
|
4381
4448
|
const parts = rest.split(' ').filter(Boolean);
|
|
4382
4449
|
return computerPull(token, parts[0], parts[1], ctx);
|
package/commands/console.js
CHANGED
|
@@ -15,7 +15,7 @@ const { resolveClaudeRunnerBin } = require('../lib/runner-command');
|
|
|
15
15
|
//
|
|
16
16
|
// packet: <dir>/{pack.json,skills,team,docs,...}
|
|
17
17
|
// A packet built in root mode (pack.js exports with prefix '' when the
|
|
18
|
-
// source dir has pack.json at its root
|
|
18
|
+
// source dir has pack.json at its root, this is how the shipped packs are
|
|
19
19
|
// built and what the web /packs/<slug>/download route serves). `pack
|
|
20
20
|
// install` preserves that flat layout, so the packet folder IS the atris
|
|
21
21
|
// root; there is no nested atris/ to find.
|
|
@@ -50,7 +50,7 @@ function gatherAtrisContext(workspaceDir) {
|
|
|
50
50
|
|
|
51
51
|
if (!ctx.hasAtris) return ctx;
|
|
52
52
|
|
|
53
|
-
// Skills
|
|
53
|
+
// Skills, scan atris/skills/ and .claude/skills/
|
|
54
54
|
for (const skillsRoot of [
|
|
55
55
|
path.join(atrisDir, 'skills'),
|
|
56
56
|
path.join(workspaceDir, '.claude', 'skills'),
|
|
@@ -92,7 +92,7 @@ function gatherAtrisContext(workspaceDir) {
|
|
|
92
92
|
return true;
|
|
93
93
|
});
|
|
94
94
|
|
|
95
|
-
// Team members
|
|
95
|
+
// Team members, scan atris/team/
|
|
96
96
|
const teamDir = path.join(atrisDir, 'team');
|
|
97
97
|
if (fs.existsSync(teamDir)) {
|
|
98
98
|
for (const name of fs.readdirSync(teamDir)) {
|
|
@@ -137,7 +137,7 @@ function buildSystemPrompt(ctx) {
|
|
|
137
137
|
const lines = [];
|
|
138
138
|
|
|
139
139
|
lines.push('# Atris Console');
|
|
140
|
-
lines.push('You are running inside the Atris Console
|
|
140
|
+
lines.push('You are running inside the Atris Console, an AI workspace operating system.');
|
|
141
141
|
lines.push('');
|
|
142
142
|
|
|
143
143
|
if (ctx.persona) {
|
|
@@ -293,7 +293,7 @@ function offerInstall(target, callback) {
|
|
|
293
293
|
|
|
294
294
|
function checkAuth(backend) {
|
|
295
295
|
if (backend === 'claude') {
|
|
296
|
-
// Claude handles its own auth interactively
|
|
296
|
+
// Claude handles its own auth interactively, always allow
|
|
297
297
|
return true;
|
|
298
298
|
}
|
|
299
299
|
if (backend === 'codex') {
|
package/commands/decide.js
CHANGED
|
@@ -132,7 +132,7 @@ function decideCommand(args = []) {
|
|
|
132
132
|
const decision = decisions[number - 1];
|
|
133
133
|
if (!decision) return fail(`decision ${number} is not open`, asJson, 1);
|
|
134
134
|
|
|
135
|
-
const message = `Decision on "${decision.text}": ${answer.toUpperCase()}${note ?
|
|
135
|
+
const message = `Decision on "${decision.text}": ${answer.toUpperCase()}${note ? `, ${note}` : ''}`;
|
|
136
136
|
pingMission([decision.mission_id, message, '--from', 'decide'], { silent: true });
|
|
137
137
|
const mission = answerMissionHumanAsk(decision.mission_id, decision.ask_index, answer, note);
|
|
138
138
|
const remainingOpenAsks = openHumanAsks(mission.human_asks).length;
|
package/commands/deck.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// atris deck
|
|
1
|
+
// atris deck: generate a premium, on-brand Google Slides deck from a plain
|
|
2
2
|
// content spec, using the Atris deck engine (lib/slides-deck.js). The pitch:
|
|
3
3
|
// describe the deck, get the design system for free. No Arial-on-white slop.
|
|
4
4
|
//
|
|
@@ -171,7 +171,7 @@ function printLint(findings) {
|
|
|
171
171
|
async function runReviewFlow({ presentationId, spec, specPath, json, auto = false }) {
|
|
172
172
|
const tok = token();
|
|
173
173
|
if (!tok) {
|
|
174
|
-
console.error(' no credentials at ~/.atris/credentials.json
|
|
174
|
+
console.error(' no credentials at ~/.atris/credentials.json. run `atris login` and connect Google Drive.');
|
|
175
175
|
return 1;
|
|
176
176
|
}
|
|
177
177
|
const { packet, manifestPath, outDir } = await reviewDeck({
|
|
@@ -278,7 +278,7 @@ async function videoToDeck({ analysisText, title, theme, style, url, api: apiFn,
|
|
|
278
278
|
async function runBatch(specPaths, { themeOverride }) {
|
|
279
279
|
const tok = token();
|
|
280
280
|
if (!tok) {
|
|
281
|
-
console.error(' no credentials at ~/.atris/credentials.json
|
|
281
|
+
console.error(' no credentials at ~/.atris/credentials.json. run `atris login` and connect Google Drive.');
|
|
282
282
|
return 1;
|
|
283
283
|
}
|
|
284
284
|
let failures = 0;
|
|
@@ -456,7 +456,7 @@ async function run(argv) {
|
|
|
456
456
|
}
|
|
457
457
|
const tok = token();
|
|
458
458
|
if (!tok) {
|
|
459
|
-
console.error(' no credentials at ~/.atris/credentials.json
|
|
459
|
+
console.error(' no credentials at ~/.atris/credentials.json. run `atris login` and connect Google Drive.');
|
|
460
460
|
return 1;
|
|
461
461
|
}
|
|
462
462
|
let analysisText;
|
|
@@ -484,7 +484,7 @@ async function run(argv) {
|
|
|
484
484
|
token: tok,
|
|
485
485
|
});
|
|
486
486
|
if (!result.ok) {
|
|
487
|
-
console.error('\n ✗ composed spec failed lint
|
|
487
|
+
console.error('\n ✗ composed spec failed lint, not building:');
|
|
488
488
|
printLint(result.findings);
|
|
489
489
|
return 1;
|
|
490
490
|
}
|
|
@@ -521,7 +521,7 @@ async function run(argv) {
|
|
|
521
521
|
const schemaFindings = validateSpec(spec);
|
|
522
522
|
if (hasErrors(schemaFindings)) {
|
|
523
523
|
printLint(schemaFindings);
|
|
524
|
-
console.error('\n ✗ spec invalid
|
|
524
|
+
console.error('\n ✗ spec invalid, fix the errors above before building\n');
|
|
525
525
|
return 2;
|
|
526
526
|
}
|
|
527
527
|
const title = flag(argv, '--title') || `${(spec.brand && spec.brand.name) || 'Atris'} deck`;
|
|
@@ -532,14 +532,14 @@ async function run(argv) {
|
|
|
532
532
|
const findings = lintSpec(spec);
|
|
533
533
|
printLint(findings);
|
|
534
534
|
if (findings.some((f) => f.severity === 'error')) {
|
|
535
|
-
console.error('\n ✗ lint failed
|
|
535
|
+
console.error('\n ✗ lint failed, fix spec before building\n');
|
|
536
536
|
return 1;
|
|
537
537
|
}
|
|
538
538
|
}
|
|
539
539
|
|
|
540
540
|
const tok = token();
|
|
541
541
|
if (!tok) {
|
|
542
|
-
console.error(' no credentials at ~/.atris/credentials.json
|
|
542
|
+
console.error(' no credentials at ~/.atris/credentials.json. run `atris login` and connect Google Drive.');
|
|
543
543
|
return 1;
|
|
544
544
|
}
|
|
545
545
|
|
|
@@ -556,7 +556,7 @@ async function run(argv) {
|
|
|
556
556
|
}
|
|
557
557
|
|
|
558
558
|
console.log(`
|
|
559
|
-
atris deck
|
|
559
|
+
atris deck: premium Google Slides from a plain content spec
|
|
560
560
|
|
|
561
561
|
atris deck sample [--theme paper] > my.json
|
|
562
562
|
atris deck compose --md notes.md --out my.json [--style narrative]
|
package/commands/drive.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// atris drive
|
|
1
|
+
// atris drive: self-driving tick over the mission plane.
|
|
2
2
|
// One tick: run mission doctor, auto-execute the fixes it prescribes that are
|
|
3
3
|
// safe to run (stale ready receipts -> verify tick), and log everything that
|
|
4
4
|
// still needs a human as an explicit disengagement. The metric that matters:
|
|
@@ -66,7 +66,7 @@ async function driveCommand(argv) {
|
|
|
66
66
|
const history = loadHistory(cwd);
|
|
67
67
|
if (!history.length) { console.log('No drive ticks yet. Run: atris drive'); return 0; }
|
|
68
68
|
if (json) { console.log(JSON.stringify({ ok: true, ticks: history }, null, 2)); return 0; }
|
|
69
|
-
console.log('drive
|
|
69
|
+
console.log('drive: disengagements per tick (goal: 0)\n');
|
|
70
70
|
for (const t of history) {
|
|
71
71
|
console.log(` ${t.at} fixed ${t.fixed}/${t.findings} disengagements ${t.disengagements}`);
|
|
72
72
|
}
|
|
@@ -86,7 +86,7 @@ async function driveCommand(argv) {
|
|
|
86
86
|
|
|
87
87
|
// Missions the doctor says have no verifier. A verify-tick physically cannot
|
|
88
88
|
// pass without one, so promising to verify-tick such a mission is a phantom
|
|
89
|
-
// fix that never sticks
|
|
89
|
+
// fix that never sticks, count it as a wheel-grab instead.
|
|
90
90
|
const noVerifier = new Set(
|
|
91
91
|
report.findings.filter((f) => f.code === 'missing_verifier' && f.mission_id).map((f) => f.mission_id),
|
|
92
92
|
);
|
|
@@ -169,7 +169,7 @@ async function driveCommand(argv) {
|
|
|
169
169
|
|
|
170
170
|
if (json) { console.log(JSON.stringify({ ok: true, ...record }, null, 2)); return 0; }
|
|
171
171
|
|
|
172
|
-
console.log(`drive tick
|
|
172
|
+
console.log(`drive tick: ${report.checked_count} missions checked, ${report.findings.length} findings`);
|
|
173
173
|
console.log(` auto-fixed: ${fixed.length}`);
|
|
174
174
|
for (const x of fixed) console.log(` ✓ ${x.action} ${x.mission_id}`);
|
|
175
175
|
console.log(` disengagements: ${disengagements.length} (a human has to grab the wheel)`);
|