atris 3.26.0 → 3.28.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/AGENTS.md +1 -1
- package/README.md +7 -5
- package/atris/features/company-brain-sync/build.md +4 -4
- package/atris/features/company-brain-sync/idea.md +2 -2
- package/atris/features/company-brain-sync/validate.md +19 -19
- package/atris/skills/aeo/SKILL.md +1 -1
- package/atris/skills/autopilot/SKILL.md +2 -2
- package/atris/skills/slides/SKILL.md +2 -2
- package/bin/atris.js +32 -14
- package/commands/activate.js +24 -0
- package/commands/aeo.js +1 -1
- package/commands/autopilot.js +1 -1
- package/commands/clarity.js +125 -0
- package/commands/computer.js +9 -9
- package/commands/feedback.js +1 -1
- package/commands/init.js +2 -2
- package/commands/live.js +3 -3
- package/commands/moves.js +156 -0
- package/commands/plugin.js +1 -1
- package/commands/pull.js +4 -4
- package/commands/security-review.js +132 -0
- package/commands/signup.js +101 -0
- package/commands/task.js +0 -1
- package/lib/clarity.js +97 -0
- package/lib/next-moves.js +362 -0
- package/lib/security-scan.js +188 -0
- package/package.json +1 -8
- package/utils/update-check.js +77 -24
- package/atris/wiki/concepts/agent-activation-contract.md +0 -81
- package/atris/wiki/concepts/workspace-initialization-contract.md +0 -73
- package/atris/wiki/index.md +0 -31
- package/atris/wiki/sources/atris-labs-2026-05-10.txt +0 -14
- package/atris/wiki/sources/atris-labs-goals-2026-05-10.txt +0 -14
- package/atris/wiki/sources/atrisos-generative-ui-product-surface-2026-05-10.txt +0 -10
- package/atris/wiki/sources/jack-dorsey-2026-05-10.txt +0 -12
package/AGENTS.md
CHANGED
|
@@ -110,7 +110,7 @@ member -> mission start --verify -> status --status active -> one bounded step -
|
|
|
110
110
|
- [ ] Only use `atris task accept <id>` when the human has approved the proof
|
|
111
111
|
- [ ] Keep durable learning in Atris-owned policy/skill/wiki/task state; keep `AGENTS.md` as a generated/pointer layer
|
|
112
112
|
- [ ] Treat `atris/TODO.md` as a rendered view; do not manually use it as the source of truth
|
|
113
|
-
- [ ] Use
|
|
113
|
+
- [ ] Use the real business slug from local Atris state; do not hardcode private slugs in generated docs
|
|
114
114
|
|
|
115
115
|
## Anti-patterns
|
|
116
116
|
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Owner has many Computers
|
|
|
10
10
|
Computer = workspace + files + tools + secrets + memory + agents + validation loop
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
A computer can be personal or shared by a business. It can run a job like code, research, CRM, reporting,
|
|
13
|
+
A computer can be personal or shared by a business. It can run a job like code, research, CRM, reporting, event ops, support, or business ops.
|
|
14
14
|
|
|
15
15
|
## For Coding Agents
|
|
16
16
|
|
|
@@ -142,9 +142,9 @@ leaderboard.
|
|
|
142
142
|
If you want a shared owner for a company, lab, collective, community, artist, team, or project, use the business command instead of raw `atris init`.
|
|
143
143
|
|
|
144
144
|
```bash
|
|
145
|
-
atris business init "
|
|
146
|
-
cd ~/arena/atris-business/
|
|
147
|
-
atris business onboard --website https://
|
|
145
|
+
atris business init "Example Co" --owner-email operator@example.com
|
|
146
|
+
cd ~/arena/atris-business/example-co
|
|
147
|
+
atris business onboard --website https://example.com --contact "Example Owner" --note "sample customer workspace"
|
|
148
148
|
atris align --fix
|
|
149
149
|
```
|
|
150
150
|
|
|
@@ -166,7 +166,7 @@ You can also use bare input:
|
|
|
166
166
|
atris business onboard https://example.com "founder-led b2b ops" ./notes.md
|
|
167
167
|
```
|
|
168
168
|
|
|
169
|
-
If you already have a folder full of source material, run it from there with `atris business init "
|
|
169
|
+
If you already have a folder full of source material, run it from there with `atris business init "Example Co" --here`.
|
|
170
170
|
|
|
171
171
|
When the first recap is done, record it into the RL state logs:
|
|
172
172
|
|
|
@@ -319,6 +319,8 @@ atris upgrade # Install latest from npm
|
|
|
319
319
|
atris update # Sync local workspace files to new version
|
|
320
320
|
```
|
|
321
321
|
|
|
322
|
+
Packaged npm installs check for new versions during normal commands and start a background update automatically. Git checkout installs stay manual so linked development copies are not overwritten unexpectedly.
|
|
323
|
+
|
|
322
324
|
---
|
|
323
325
|
|
|
324
326
|
**License:** MIT | **Repo:** [github.com/atrislabs/atris](https://github.com/atrislabs/atris.git)
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## Current Patch
|
|
4
4
|
|
|
5
|
-
The immediate
|
|
5
|
+
The immediate Example Co lane now follows the correct company-brain model:
|
|
6
6
|
|
|
7
|
-
- `atris push` keeps the business root as the path root so `
|
|
7
|
+
- `atris push` keeps the business root as the path root so `example-co/atris/MAP.md` maps to cloud `/atris/MAP.md`
|
|
8
8
|
- business `pull` and `push` default to the `atris/` scope
|
|
9
9
|
- root-level duplicates such as `MAP.md`, `TODO.md`, and `security-report.md` are ignored by default
|
|
10
10
|
- manifests record the local workspace root to prevent a manifest from one folder authorizing pushes from another folder
|
|
@@ -114,7 +114,7 @@ Later it should also let the user ask Atris to merge semantically with model ass
|
|
|
114
114
|
|
|
115
115
|
`atris sync --watch` is the current always-on lane:
|
|
116
116
|
|
|
117
|
-
- watch `
|
|
117
|
+
- watch `example-co/atris/`
|
|
118
118
|
- debounce local edits
|
|
119
119
|
- fetch cloud hashes periodically
|
|
120
120
|
- sync clean changes
|
|
@@ -136,5 +136,5 @@ Required before broad customer use:
|
|
|
136
136
|
- retry-policy tests proving watch failures do not kill the alive loop
|
|
137
137
|
- fixture tests proving parent-folder junk is ignored
|
|
138
138
|
- fixture tests proving no cloud deletes without explicit opt-in
|
|
139
|
-
- end-to-end dry-run against a real
|
|
139
|
+
- end-to-end dry-run against a real Example Co-shaped workspace
|
|
140
140
|
- command copy that never recommends `--force` for normal use
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Problem
|
|
4
4
|
|
|
5
|
-
Atris business workspaces are company brains, not plain folders. The canonical knowledge surface is the `atris/` folder inside each business workspace, for example `
|
|
5
|
+
Atris business workspaces are company brains, not plain folders. The canonical knowledge surface is the `atris/` folder inside each business workspace, for example `example-co/atris/`.
|
|
6
6
|
|
|
7
7
|
Raw push/pull is the wrong abstraction for this surface. It makes a shared knowledge base feel like file mirroring, which creates merge anxiety and makes users responsible for sync safety.
|
|
8
8
|
|
|
@@ -19,7 +19,7 @@ Cloud Atris is canonical. Local Atris is a working copy. Sync publishes proposed
|
|
|
19
19
|
|
|
20
20
|
## User Model
|
|
21
21
|
|
|
22
|
-
Jonathan should be able to work inside `
|
|
22
|
+
Jonathan should be able to work inside `example-co/atris/` and run one command:
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
25
|
atris sync
|
|
@@ -51,47 +51,47 @@ node -c commands/pull.js
|
|
|
51
51
|
node -c commands/push.js
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
Fresh
|
|
54
|
+
Fresh Example Co-shaped workspace dry-run:
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
atris sync
|
|
57
|
+
atris sync example-co --dry-run
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
Observed result:
|
|
61
61
|
|
|
62
62
|
```text
|
|
63
|
-
Syncing
|
|
63
|
+
Syncing example-co knowledge wiki...
|
|
64
64
|
scope: atris/
|
|
65
65
|
...
|
|
66
|
-
Pushing to
|
|
66
|
+
Pushing to Example Co...
|
|
67
67
|
Checking cloud freshness... fresh
|
|
68
68
|
Already up to date.
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
Fresh
|
|
71
|
+
Fresh Example Co-shaped workspace real command with no local edits:
|
|
72
72
|
|
|
73
73
|
```bash
|
|
74
|
-
atris sync
|
|
74
|
+
atris sync example-co
|
|
75
75
|
```
|
|
76
76
|
|
|
77
77
|
Observed result:
|
|
78
78
|
|
|
79
79
|
```text
|
|
80
|
-
Pulling
|
|
80
|
+
Pulling Example Co...
|
|
81
81
|
Already up to date.
|
|
82
82
|
122 unchanged.
|
|
83
|
-
Pushing to
|
|
83
|
+
Pushing to Example Co...
|
|
84
84
|
Checking cloud freshness... fresh
|
|
85
85
|
Already up to date.
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
No cloud writes were required in the validation case because the clean workspace had no local changes to publish.
|
|
89
89
|
|
|
90
|
-
Local edit dry-run in
|
|
90
|
+
Local edit dry-run in an Example Co-shaped workspace:
|
|
91
91
|
|
|
92
92
|
```bash
|
|
93
93
|
printf '# Sync smoke\n\nLocal-only knowledge update.\n' > atris/wiki/smoke/local-edit.md
|
|
94
|
-
atris sync
|
|
94
|
+
atris sync example-co --dry-run
|
|
95
95
|
```
|
|
96
96
|
|
|
97
97
|
Observed result:
|
|
@@ -101,11 +101,11 @@ Observed result:
|
|
|
101
101
|
1 would be pushed, 122 unchanged. (--dry-run, nothing sent)
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
-
Local delete dry-run in
|
|
104
|
+
Local delete dry-run in an Example Co-shaped workspace:
|
|
105
105
|
|
|
106
106
|
```bash
|
|
107
107
|
rm -f atris/wiki/index.md
|
|
108
|
-
atris sync
|
|
108
|
+
atris sync example-co --dry-run
|
|
109
109
|
```
|
|
110
110
|
|
|
111
111
|
Observed result:
|
|
@@ -118,7 +118,7 @@ Deletes require an explicit real push with --delete.
|
|
|
118
118
|
Real delete attempt without `--delete`:
|
|
119
119
|
|
|
120
120
|
```bash
|
|
121
|
-
atris sync
|
|
121
|
+
atris sync example-co
|
|
122
122
|
```
|
|
123
123
|
|
|
124
124
|
Observed result:
|
|
@@ -148,10 +148,10 @@ Slug auto-detection:
|
|
|
148
148
|
atris sync --dry-run
|
|
149
149
|
```
|
|
150
150
|
|
|
151
|
-
Observed result from
|
|
151
|
+
Observed result from an Example Co-shaped workspace:
|
|
152
152
|
|
|
153
153
|
```text
|
|
154
|
-
Syncing
|
|
154
|
+
Syncing example-co knowledge wiki...
|
|
155
155
|
scope: atris/
|
|
156
156
|
```
|
|
157
157
|
|
|
@@ -165,7 +165,7 @@ Observed shape:
|
|
|
165
165
|
|
|
166
166
|
```text
|
|
167
167
|
Company brain status
|
|
168
|
-
business:
|
|
168
|
+
business: example-co
|
|
169
169
|
brain: atris/ (...)
|
|
170
170
|
conflicts: none
|
|
171
171
|
watcher: ...
|
|
@@ -218,12 +218,12 @@ atris pull example-co --keep-local --only atris/wiki --timeout 120
|
|
|
218
218
|
atris push example-co --only atris/wiki --dry-run
|
|
219
219
|
```
|
|
220
220
|
|
|
221
|
-
-
|
|
221
|
+
- Example Co post-publish smoke:
|
|
222
222
|
|
|
223
223
|
```bash
|
|
224
|
-
cd ~/arena/atris-business/
|
|
224
|
+
cd ~/arena/atris-business/example-co
|
|
225
225
|
atris wiki verify
|
|
226
|
-
atris push
|
|
226
|
+
atris push example-co --dry-run
|
|
227
227
|
```
|
|
228
228
|
|
|
229
229
|
- Packaged CLI smoke already passed locally for `3.15.12`: tarball install exposes `atris pull --no-manifest` and `atris wiki verify`.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: aeo
|
|
3
3
|
description: "AI Engine Optimization — write content engineered to get cited by ChatGPT, Claude, and Gemini. Not SEO. Triggers on: aeo, AI engine, llm citation, get cited, write for ai."
|
|
4
|
-
when_to_use: "Use when the user wants content that ranks in AI answers (not Google SERP). Examples: 'write an AEO page', 'get ExampleCo cited by ChatGPT', 'aeo for our
|
|
4
|
+
when_to_use: "Use when the user wants content that ranks in AI answers (not Google SERP). Examples: 'write an AEO page', 'get ExampleCo cited by ChatGPT', 'aeo for our pricing page', 'make this quotable by LLMs'."
|
|
5
5
|
version: 0.1.0
|
|
6
6
|
allowed-tools: Read, Write, Edit, Glob, Grep, Bash
|
|
7
7
|
tags:
|
|
@@ -20,8 +20,8 @@ Every tick prints this BEFORE scanning for work, so you can see the loop's state
|
|
|
20
20
|
┌──────────────────────────────────────────────────────────────┐
|
|
21
21
|
│ tick · 14:23 │
|
|
22
22
|
│ identity: building atris-business cloud for design partners │
|
|
23
|
-
│ horizon:
|
|
24
|
-
│
|
|
23
|
+
│ horizon: customer-onboarding │
|
|
24
|
+
│ three setup checks are ready to ship │
|
|
25
25
|
│ progress: ████████░░░░ 6/9 endgame steps │
|
|
26
26
|
└──────────────────────────────────────────────────────────────┘
|
|
27
27
|
```
|
|
@@ -121,7 +121,7 @@ curl -s -X POST "https://api.atris.ai/api/integrations/google-slides/presentatio
|
|
|
121
121
|
{
|
|
122
122
|
"insertText": {
|
|
123
123
|
"objectId": "subtitleId",
|
|
124
|
-
"text": "
|
|
124
|
+
"text": "{{company_name}} - Confidential"
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
]
|
|
@@ -207,7 +207,7 @@ curl -s -X POST "https://api.atris.ai/api/integrations/google-slides/presentatio
|
|
|
207
207
|
{
|
|
208
208
|
"replaceAllText": {
|
|
209
209
|
"containsText": {"text": "{{company_name}}"},
|
|
210
|
-
"replaceText": "
|
|
210
|
+
"replaceText": "Example Co"
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
213
|
]
|
package/bin/atris.js
CHANGED
|
@@ -92,14 +92,10 @@ if (!skipUpdateCheck && (!updateCommand || (updateCommand && !['version', 'updat
|
|
|
92
92
|
.then((updateInfo) => {
|
|
93
93
|
// Show notification if update available (after command completes)
|
|
94
94
|
if (updateInfo) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
showUpdateNotification(updateInfo);
|
|
100
|
-
}
|
|
101
|
-
}, 100);
|
|
102
|
-
} else {
|
|
95
|
+
const autoUpdateStarted = autoUpdate(updateInfo, {
|
|
96
|
+
packageRoot: path.join(__dirname, '..'),
|
|
97
|
+
});
|
|
98
|
+
if (!autoUpdateStarted) {
|
|
103
99
|
showUpdateNotification(updateInfo);
|
|
104
100
|
}
|
|
105
101
|
}
|
|
@@ -349,7 +345,7 @@ function showHelp() {
|
|
|
349
345
|
console.log('Atris Computers:');
|
|
350
346
|
console.log(' Owner = User | Business');
|
|
351
347
|
console.log(' Owners have Computers: workspace + files + tools + secrets + memory + agents + validation');
|
|
352
|
-
console.log(' Types: code, research, CRM, reporting,
|
|
348
|
+
console.log(' Types: code, research, CRM, reporting, events, support, business ops');
|
|
353
349
|
console.log('');
|
|
354
350
|
console.log('Setup:');
|
|
355
351
|
console.log(' setup - Guided first-time setup (login, pick business, pull)');
|
|
@@ -644,6 +640,7 @@ function showUpgradeHelp() {
|
|
|
644
640
|
console.log('');
|
|
645
641
|
console.log('Description:');
|
|
646
642
|
console.log(' Check npm for the latest Atris CLI and install it globally if newer.');
|
|
643
|
+
console.log(' Normal packaged installs also auto-update in the background.');
|
|
647
644
|
console.log('');
|
|
648
645
|
console.log('Options:');
|
|
649
646
|
console.log(' --help, -h Show this help.');
|
|
@@ -826,7 +823,7 @@ if (command === '2' && ['fast', 'pro'].includes(String(firstCommandArg || '').to
|
|
|
826
823
|
const knownCommands = ['init', 'log', 'now', 'radar', 'ctop', 'status', 'analytics', 'visualize', 'brain', 'brainstorm', 'autopilot', 'run', 'plan', 'do', 'review', 'release',
|
|
827
824
|
'activate', '_activate', 'agent', 'chat', 'fast', 'ax', 'console', 'serve', 'login', 'logout', 'whoami', 'switch', 'use', 'accounts', '_resolve', '_profile-email', '_switch-session', 'shell-init', 'update', 'upgrade', 'version', 'help', 'next', 'atris',
|
|
828
825
|
'clean', 'verify', 'search', 'skill', 'member', 'codex-goal', 'app', 'apps', 'learn', 'lesson', 'plugin', 'experiments', 'receipt', 'proof', 'openclaw', 'pull', 'push', 'live', 'align', 'terminal', 'computer', 'diff', 'business', 'sync', 'youtube',
|
|
829
|
-
'ingest', 'query', 'lint', 'loop', 'pulse', 'task', 'mission', 'probe', 'worktree', 'aeo', 'slop', 'deck', 'site', 'theme', 'card', 'reel', 'improve', 'xp', 'play', 'gm', 'x', 'recap',
|
|
826
|
+
'ingest', 'query', 'lint', 'loop', 'pulse', 'task', 'mission', 'probe', 'worktree', 'aeo', 'slop', 'security-review', 'secure', 'deck', 'site', 'theme', 'card', 'reel', 'improve', 'xp', 'play', 'gm', 'x', 'recap', 'signup', 'clarity', 'moves',
|
|
830
827
|
'gmail', 'calendar', 'twitter', 'slack', 'imessage', 'integrations', 'setup', 'clean-workspace', 'cw',
|
|
831
828
|
'fork', 'browse', 'publish', 'sleep', 'wake', 'feedback', 'errors', 'wiki', 'code-review', 'cr', 'soul', 'fleet', 'compile', 'spaceship'];
|
|
832
829
|
|
|
@@ -2064,6 +2061,27 @@ if (command === 'init') {
|
|
|
2064
2061
|
Promise.resolve(require('../commands/slop').slopCommand(process.argv.slice(3)))
|
|
2065
2062
|
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2066
2063
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2064
|
+
} else if (command === 'security-review' || command === 'secure') {
|
|
2065
|
+
// Security review: deterministic secrets/PII/code-risk scan (no LLM). Exit 1 = HIGH finding,
|
|
2066
|
+
// for the autopilot/mission/CI gate + a SOC 2 evidence artifact via --json.
|
|
2067
|
+
Promise.resolve(require('../commands/security-review').securityReviewCommand(process.argv.slice(3)))
|
|
2068
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2069
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2070
|
+
} else if (command === 'signup') {
|
|
2071
|
+
// Signup: one-call seedless agent signup → writes the active profile (install→signup→play seam).
|
|
2072
|
+
Promise.resolve(require('../commands/signup').signupCommand(process.argv.slice(3)))
|
|
2073
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2074
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2075
|
+
} else if (command === 'moves') {
|
|
2076
|
+
// Moves: your 3 next moves — approve one into the loop, kill, or skip.
|
|
2077
|
+
Promise.resolve(require('../commands/moves').movesCommand(process.argv.slice(3)))
|
|
2078
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2079
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2080
|
+
} else if (command === 'clarity') {
|
|
2081
|
+
// Clarity: interview yourself once; agents read how you work so you stop repeating it.
|
|
2082
|
+
Promise.resolve(require('../commands/clarity').clarityCommand(process.argv.slice(3)))
|
|
2083
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2084
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2067
2085
|
} else if (command === 'deck') {
|
|
2068
2086
|
// Deck: premium Google Slides from a plain content spec, via the Atris deck engine (anti-slop design system).
|
|
2069
2087
|
Promise.resolve(require('../commands/deck').run(process.argv.slice(3)))
|
|
@@ -2167,8 +2185,8 @@ async function upgradeAtris() {
|
|
|
2167
2185
|
console.log('Installing update...');
|
|
2168
2186
|
console.log('');
|
|
2169
2187
|
|
|
2170
|
-
// Run npm
|
|
2171
|
-
const result = spawnSync('npm', ['
|
|
2188
|
+
// Run npm install -g atris@latest
|
|
2189
|
+
const result = spawnSync('npm', ['install', '-g', 'atris@latest'], {
|
|
2172
2190
|
stdio: 'inherit',
|
|
2173
2191
|
shell: true
|
|
2174
2192
|
});
|
|
@@ -2182,10 +2200,10 @@ async function upgradeAtris() {
|
|
|
2182
2200
|
} else {
|
|
2183
2201
|
console.log('');
|
|
2184
2202
|
console.log('✗ Upgrade failed. Try running manually:');
|
|
2185
|
-
console.log(' npm
|
|
2203
|
+
console.log(' npm install -g atris@latest');
|
|
2186
2204
|
console.log('');
|
|
2187
2205
|
console.log('If you see permission errors, try:');
|
|
2188
|
-
console.log(' sudo npm
|
|
2206
|
+
console.log(' sudo npm install -g atris@latest');
|
|
2189
2207
|
console.log('');
|
|
2190
2208
|
}
|
|
2191
2209
|
}
|
package/commands/activate.js
CHANGED
|
@@ -158,6 +158,30 @@ function activateAtris() {
|
|
|
158
158
|
wikiStatus.bullets.forEach((line) => console.log(`- ${line.replace(/^- /, '')}`));
|
|
159
159
|
}
|
|
160
160
|
console.log('');
|
|
161
|
+
try {
|
|
162
|
+
const { nextMoves } = require('../lib/next-moves');
|
|
163
|
+
const { readProfile, isEmptyProfile } = require('../lib/clarity');
|
|
164
|
+
const root = process.cwd();
|
|
165
|
+
const moves = nextMoves(root, 3);
|
|
166
|
+
console.log('Your next moves:');
|
|
167
|
+
if (moves.length) {
|
|
168
|
+
moves.forEach((m, i) => console.log(` ${i + 1}. ${m.title}`));
|
|
169
|
+
console.log(' steer them: atris moves');
|
|
170
|
+
} else {
|
|
171
|
+
console.log(' none queued. add to ROADMAP.md under "## Open loop items", or jot one with atris log');
|
|
172
|
+
}
|
|
173
|
+
const profile = readProfile(root);
|
|
174
|
+
console.log('');
|
|
175
|
+
if (isEmptyProfile(profile)) {
|
|
176
|
+
console.log('Tip: run atris clarity once so agents learn how you work.');
|
|
177
|
+
} else {
|
|
178
|
+
console.log('How you work (atris clarity):');
|
|
179
|
+
['focus', 'voice', 'cadence', 'done', 'leash']
|
|
180
|
+
.filter((k) => profile[k])
|
|
181
|
+
.forEach((k) => console.log(` ${k}: ${profile[k]}`));
|
|
182
|
+
}
|
|
183
|
+
console.log('');
|
|
184
|
+
} catch { /* alive onboarding is best-effort; never block activate */ }
|
|
161
185
|
console.log('Next: atris plan → do → review (or atris log)');
|
|
162
186
|
console.log('');
|
|
163
187
|
}
|
package/commands/aeo.js
CHANGED
|
@@ -173,7 +173,7 @@ function printHelp() {
|
|
|
173
173
|
console.log('');
|
|
174
174
|
console.log('Examples:');
|
|
175
175
|
console.log(' atris aeo log --engine perplexity --limit 5');
|
|
176
|
-
console.log(' atris aeo packet
|
|
176
|
+
console.log(' atris aeo packet <slug>');
|
|
177
177
|
console.log(' atris aeo status');
|
|
178
178
|
console.log(' atris aeo discover https://atris.ai/aeo --canonical-url https://atris.ai/aeo');
|
|
179
179
|
}
|
package/commands/autopilot.js
CHANGED
|
@@ -42,7 +42,7 @@ function looksOwnerGatedTitle(title) {
|
|
|
42
42
|
/\bhuman[- ](?:approval|input|gate|gated)\b/.test(text) ||
|
|
43
43
|
/\bmanual send\b/.test(text) ||
|
|
44
44
|
/\broute confirmation\b/.test(text) ||
|
|
45
|
-
/\bconfirm
|
|
45
|
+
/\bconfirm customer destination\b/.test(text) ||
|
|
46
46
|
/\bconfirm .+ destination before .+ approval\b/.test(text) ||
|
|
47
47
|
/\bapprove and manually send\b/.test(text)
|
|
48
48
|
);
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// `atris clarity`: interview the operator for how they work, write it down once.
|
|
4
|
+
// The interview moves one question at a time so you stay in flow. The result is
|
|
5
|
+
// a durable profile (.atris/clarity.json + atris/CLARITY.md) that agents read.
|
|
6
|
+
|
|
7
|
+
const readline = require('readline');
|
|
8
|
+
const {
|
|
9
|
+
QUESTIONS,
|
|
10
|
+
KEYS,
|
|
11
|
+
mergeProfile,
|
|
12
|
+
isEmptyProfile,
|
|
13
|
+
renderClarityMd,
|
|
14
|
+
readProfile,
|
|
15
|
+
writeProfile,
|
|
16
|
+
profilePaths,
|
|
17
|
+
} = require('../lib/clarity');
|
|
18
|
+
|
|
19
|
+
function parseSets(args) {
|
|
20
|
+
const answers = {};
|
|
21
|
+
for (let i = 0; i < args.length; i++) {
|
|
22
|
+
if (args[i] === '--set' && args[i + 1]) {
|
|
23
|
+
const eq = args[i + 1].indexOf('=');
|
|
24
|
+
if (eq > 0) {
|
|
25
|
+
const key = args[i + 1].slice(0, eq).trim();
|
|
26
|
+
const val = args[i + 1].slice(eq + 1).trim();
|
|
27
|
+
if (KEYS.includes(key)) answers[key] = val;
|
|
28
|
+
}
|
|
29
|
+
i++;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return answers;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function ask(rl, question) {
|
|
36
|
+
return new Promise((resolve) => rl.question(question, (a) => resolve(a)));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function clarityCommand(args = [], root = process.cwd()) {
|
|
40
|
+
const sub = args[0];
|
|
41
|
+
const stamp = new Date().toISOString();
|
|
42
|
+
|
|
43
|
+
if (args.includes('--help') || args.includes('-h') || sub === 'help') {
|
|
44
|
+
console.log('');
|
|
45
|
+
console.log('Usage: atris clarity [show|--json|--set key=value|--reset]');
|
|
46
|
+
console.log('');
|
|
47
|
+
console.log('Interview the operator for how they work, once. Agents read the result.');
|
|
48
|
+
console.log('');
|
|
49
|
+
console.log(' atris clarity Run the interview (one question at a time)');
|
|
50
|
+
console.log(' atris clarity show Show the current profile');
|
|
51
|
+
console.log(' atris clarity --json Print the profile as JSON');
|
|
52
|
+
console.log(' atris clarity --set voice=plain Set one field without prompting');
|
|
53
|
+
console.log(' atris clarity --reset Clear the profile');
|
|
54
|
+
console.log('');
|
|
55
|
+
console.log(`Fields: ${KEYS.join(', ')}`);
|
|
56
|
+
console.log('');
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (args.includes('--reset')) {
|
|
61
|
+
writeProfile(root, { updated_at: stamp });
|
|
62
|
+
console.log('clarity profile reset.');
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const existing = readProfile(root);
|
|
67
|
+
|
|
68
|
+
if (args.includes('--json')) {
|
|
69
|
+
console.log(JSON.stringify(existing, null, 2));
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (sub === 'show') {
|
|
74
|
+
console.log(renderClarityMd(existing));
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Non-interactive set: write fields and exit.
|
|
79
|
+
const sets = parseSets(args);
|
|
80
|
+
if (Object.keys(sets).length) {
|
|
81
|
+
const merged = mergeProfile(existing, sets, stamp);
|
|
82
|
+
// Only the keys whose values actually landed (mergeProfile drops empties).
|
|
83
|
+
const changed = Object.keys(sets).filter((k) => sets[k].trim() && merged[k] === sets[k].trim());
|
|
84
|
+
if (!changed.length) {
|
|
85
|
+
console.log('nothing to set (empty value ignored). use --reset to clear all.');
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
const { md } = writeProfile(root, merged);
|
|
89
|
+
console.log(`saved ${changed.join(', ')} to ${md.replace(`${root}/`, '')}`);
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Interactive interview. Only on a terminal, so spawns never hang.
|
|
94
|
+
if (!process.stdin.isTTY) {
|
|
95
|
+
console.log(renderClarityMd(existing));
|
|
96
|
+
if (isEmptyProfile(existing)) {
|
|
97
|
+
console.log('Run `atris clarity` in a terminal to fill this in, or use --set key=value.');
|
|
98
|
+
}
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
console.log('');
|
|
103
|
+
console.log('clarity interview. plain answers, one at a time. enter to keep the current value.');
|
|
104
|
+
console.log('');
|
|
105
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
106
|
+
const answers = {};
|
|
107
|
+
for (const { key, q } of QUESTIONS) {
|
|
108
|
+
const current = existing[key] ? ` [${existing[key]}]` : '';
|
|
109
|
+
// eslint-disable-next-line no-await-in-loop
|
|
110
|
+
const a = (await ask(rl, `${q}${current}\n> `)).trim();
|
|
111
|
+
if (a) answers[key] = a;
|
|
112
|
+
console.log('');
|
|
113
|
+
}
|
|
114
|
+
rl.close();
|
|
115
|
+
|
|
116
|
+
const merged = mergeProfile(existing, answers, stamp);
|
|
117
|
+
const { md } = writeProfile(root, merged);
|
|
118
|
+
console.log('clarity saved. agents will read it from:');
|
|
119
|
+
console.log(` ${md.replace(`${root}/`, '')}`);
|
|
120
|
+
console.log('');
|
|
121
|
+
console.log(renderClarityMd(merged));
|
|
122
|
+
return 0;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
module.exports = { clarityCommand, parseSets };
|
package/commands/computer.js
CHANGED
|
@@ -1601,8 +1601,8 @@ async function computerCreate(token, args = [], defaults = {}) {
|
|
|
1601
1601
|
console.log('Create a business computer, activate it, and wake it in one command.');
|
|
1602
1602
|
console.log('');
|
|
1603
1603
|
console.log('Examples:');
|
|
1604
|
-
console.log(' atris computer create "My Business Computer" --business
|
|
1605
|
-
console.log(' atris computer create "
|
|
1604
|
+
console.log(' atris computer create "My Business Computer" --business <business>');
|
|
1605
|
+
console.log(' atris computer create "Support Computer"');
|
|
1606
1606
|
if (!options.name && !options.help) process.exitCode = 1;
|
|
1607
1607
|
return;
|
|
1608
1608
|
}
|
|
@@ -1810,8 +1810,8 @@ async function computerDelete(token, ctx, options = {}, args = []) {
|
|
|
1810
1810
|
console.log('Sleeps the computer first, then deletes the non-default workspace after confirmation.');
|
|
1811
1811
|
console.log('');
|
|
1812
1812
|
console.log('Examples:');
|
|
1813
|
-
console.log(' atris computer delete --business
|
|
1814
|
-
console.log(' atris computer delete --business
|
|
1813
|
+
console.log(' atris computer delete --business <business> --workspace ws_123');
|
|
1814
|
+
console.log(' atris computer delete --business <business> --workspace ws_123 --confirm "delete ws_123"');
|
|
1815
1815
|
return;
|
|
1816
1816
|
}
|
|
1817
1817
|
|
|
@@ -3291,7 +3291,7 @@ async function runComputer() {
|
|
|
3291
3291
|
console.log(' Owner has many Computers');
|
|
3292
3292
|
console.log(' Computer = workspace + files + tools + secrets + memory + agents + validation');
|
|
3293
3293
|
console.log('');
|
|
3294
|
-
console.log('Common types: codeops, research, CRM, reporting,
|
|
3294
|
+
console.log('Common types: codeops, research, CRM, reporting, event ops, support, business ops.');
|
|
3295
3295
|
console.log('A business can be a company, lab, collective, community, artist, team, or project.');
|
|
3296
3296
|
console.log('');
|
|
3297
3297
|
console.log('First use:');
|
|
@@ -3342,10 +3342,10 @@ async function runComputer() {
|
|
|
3342
3342
|
console.log(' atris computer');
|
|
3343
3343
|
console.log(' atris computer card --write');
|
|
3344
3344
|
console.log(' atris business init "My Lab" # first/default computer with Atris + operator');
|
|
3345
|
-
console.log(' atris computer create "
|
|
3346
|
-
console.log(' atris computer --business
|
|
3347
|
-
console.log(' atris computer sleep --business
|
|
3348
|
-
console.log(' atris computer delete --business
|
|
3345
|
+
console.log(' atris computer create "Support Computer" --business <business>');
|
|
3346
|
+
console.log(' atris computer --business <business> --workspace <workspace-id>');
|
|
3347
|
+
console.log(' atris computer sleep --business <business> --workspace <workspace-id>');
|
|
3348
|
+
console.log(' atris computer delete --business <business> --workspace <workspace-id>');
|
|
3349
3349
|
console.log(' atris computer proof');
|
|
3350
3350
|
console.log(' atris computer local');
|
|
3351
3351
|
console.log(' atris computer codex');
|
package/commands/feedback.js
CHANGED
|
@@ -231,7 +231,7 @@ function printHelp(write = console.log) {
|
|
|
231
231
|
write(' atris feedback delete <id> Delete feedback (admin)');
|
|
232
232
|
write('');
|
|
233
233
|
write('IDs may be the first 8 chars of the UUID.');
|
|
234
|
-
write('Business slugs come from ~/.atris/businesses.json
|
|
234
|
+
write('Business slugs come from ~/.atris/businesses.json.');
|
|
235
235
|
write('');
|
|
236
236
|
}
|
|
237
237
|
|
package/commands/init.js
CHANGED
|
@@ -257,7 +257,7 @@ function initAtris() {
|
|
|
257
257
|
}
|
|
258
258
|
// GUARD: Refuse nested init.
|
|
259
259
|
// Bug: running `atris init` inside an existing `atris/` folder creates
|
|
260
|
-
// `atris/atris/` nesting hell.
|
|
260
|
+
// `atris/atris/` nesting hell. A cloud business workspace had this exact problem.
|
|
261
261
|
// Fix: detect three nesting conditions and refuse with a clear error.
|
|
262
262
|
const cwd = process.cwd();
|
|
263
263
|
const cwdBase = path.basename(cwd);
|
|
@@ -705,7 +705,7 @@ member -> mission start --verify -> status --status active -> one bounded step -
|
|
|
705
705
|
- [ ] Only use \`atris task accept <id>\` when the human has approved the proof
|
|
706
706
|
- [ ] Keep durable learning in Atris-owned policy/skill/wiki/task state; keep \`AGENTS.md\` as a generated/pointer layer
|
|
707
707
|
- [ ] Treat \`atris/TODO.md\` as a rendered view; do not manually use it as the source of truth
|
|
708
|
-
- [ ] Use
|
|
708
|
+
- [ ] Use the real business slug from local Atris state; do not hardcode private slugs in generated docs
|
|
709
709
|
|
|
710
710
|
## Anti-patterns
|
|
711
711
|
|
package/commands/live.js
CHANGED
|
@@ -101,10 +101,10 @@ function printLiveHelp() {
|
|
|
101
101
|
console.log('Keeps a business brain fresh: doctor, pull, watch local changes, push after quiet, and periodically pull.');
|
|
102
102
|
console.log('');
|
|
103
103
|
console.log('Examples:');
|
|
104
|
-
console.log(' atris live
|
|
104
|
+
console.log(' atris live <business>');
|
|
105
105
|
console.log(' atris live --once');
|
|
106
|
-
console.log(' atris live
|
|
107
|
-
console.log(' atris live
|
|
106
|
+
console.log(' atris live <business> --dry-run');
|
|
107
|
+
console.log(' atris live <business> --interval=120 --debounce=30');
|
|
108
108
|
console.log('');
|
|
109
109
|
console.log('Options:');
|
|
110
110
|
console.log(' --once Run one freshness cycle and exit');
|