atris 3.30.12 → 3.32.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 +16 -3
- package/FOR_AGENTS.md +81 -0
- package/README.md +6 -4
- package/atris/CLAUDE.md +8 -0
- package/atris/atris.md +51 -19
- package/atris/skills/README.md +1 -0
- package/atris/skills/blocks/SKILL.md +134 -0
- package/atris/skills/clawhub/philosophy-of-work/SKILL.md +56 -0
- package/atris/skills/youtube/SKILL.md +31 -11
- package/atris.md +15 -0
- package/ax +189 -7
- package/bin/atris.js +273 -225
- package/commands/autoland.js +379 -0
- package/commands/autopilot-front.js +273 -0
- package/commands/autopilot.js +94 -4
- package/commands/business.js +1 -1
- package/commands/clean.js +72 -9
- package/commands/codex-goal.js +72 -22
- package/commands/computer.js +48 -3
- package/commands/gm.js +1 -1
- package/commands/harvest.js +179 -0
- package/commands/init.js +22 -1
- package/commands/land.js +442 -0
- package/commands/loop-front.js +122 -4
- package/commands/member.js +551 -19
- package/commands/mission.js +3674 -278
- package/commands/play.js +1 -1
- package/commands/pulse.js +65 -7
- package/commands/run-front.js +144 -0
- package/commands/run.js +10 -7
- package/commands/sign.js +90 -0
- package/commands/strings.js +301 -0
- package/commands/task.js +782 -108
- package/commands/truth.js +171 -0
- package/commands/xp.js +32 -8
- package/commands/youtube.js +72 -5
- package/decks/README.md +6 -12
- package/lib/auto-accept-certified.js +10 -0
- package/lib/autoland.js +391 -0
- package/lib/context-gatherer.js +0 -8
- package/lib/mission-artifact.js +504 -0
- package/lib/mission-room.js +846 -0
- package/lib/next-moves.js +212 -6
- package/lib/operator-next.js +7 -0
- package/lib/pulse.js +78 -4
- package/lib/runner-command.js +51 -20
- package/lib/runs-prune.js +242 -0
- package/lib/task-db.js +19 -2
- package/lib/task-proof.js +1 -1
- package/package.json +4 -4
- package/decks/atris-seed-pitch-v3.json +0 -118
- package/decks/atris-seed-pitch-v4-skeleton.json +0 -106
- package/decks/atris-seed-pitch-v5.json +0 -109
- package/decks/atris-seed-pitch-v6.json +0 -137
- package/decks/atris-seed-pitch-v7.json +0 -133
- package/decks/mark-pincus-narrative.json +0 -102
- package/decks/mark-pincus-sourcery.json +0 -94
- package/decks/yash-applied-compute-detailed.json +0 -150
- package/decks/yash-applied-compute-generalist.json +0 -82
- package/decks/yash-applied-compute-narrative.json +0 -54
- package/lib/ax-chat-input.js +0 -164
- package/lib/ax-goal.js +0 -307
- package/lib/ax-prefs.js +0 -63
- package/lib/ax-shimmer.js +0 -63
package/commands/loop-front.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
// atris loop status liveness, last tick, reward -> pulse.js
|
|
15
15
|
// atris loop stop remove the durable heartbeat -> pulse.js
|
|
16
16
|
// atris loop wiki wiki upkeep (the old `loop`) -> loop.js
|
|
17
|
+
// atris loop create-next create + claim the suggested task
|
|
17
18
|
//
|
|
18
19
|
// The loop reads ROADMAP.md for what to pursue.
|
|
19
20
|
|
|
@@ -21,6 +22,13 @@ function isFlag(arg) {
|
|
|
21
22
|
return typeof arg === 'string' && arg.startsWith('-');
|
|
22
23
|
}
|
|
23
24
|
|
|
25
|
+
function flagValue(argv, name) {
|
|
26
|
+
const index = argv.indexOf(name);
|
|
27
|
+
if (index === -1) return null;
|
|
28
|
+
const value = argv[index + 1];
|
|
29
|
+
return value && !isFlag(value) ? value : true;
|
|
30
|
+
}
|
|
31
|
+
|
|
24
32
|
// Pure router: decide what `atris loop ...` means without executing anything.
|
|
25
33
|
// Kept side-effect-free so it is trivially testable.
|
|
26
34
|
function routeLoop(argv = []) {
|
|
@@ -36,6 +44,10 @@ function routeLoop(argv = []) {
|
|
|
36
44
|
return { action: 'status' };
|
|
37
45
|
case 'stop':
|
|
38
46
|
return { action: 'stop' };
|
|
47
|
+
case 'create-next':
|
|
48
|
+
case 'claim-next':
|
|
49
|
+
case 'take-next':
|
|
50
|
+
return { action: 'create-next' };
|
|
39
51
|
case 'wiki':
|
|
40
52
|
// Forward the remaining args (e.g. --json, --limit=) to wiki upkeep.
|
|
41
53
|
return { action: 'wiki', rest: argv.filter((a) => a.toLowerCase() !== 'wiki') };
|
|
@@ -57,7 +69,7 @@ function routeLoop(argv = []) {
|
|
|
57
69
|
}
|
|
58
70
|
}
|
|
59
71
|
|
|
60
|
-
function renderLoopHome(route = { action: 'home' }) {
|
|
72
|
+
function renderLoopHome(route = { action: 'home' }, moves = []) {
|
|
61
73
|
const lines = [
|
|
62
74
|
'',
|
|
63
75
|
'atris loop: the self-improvement loop',
|
|
@@ -73,6 +85,7 @@ function renderLoopHome(route = { action: 'home' }) {
|
|
|
73
85
|
' atris loop start run it now, here (local)',
|
|
74
86
|
' atris loop start --once one cycle, then stop',
|
|
75
87
|
' atris loop start --overnight install the durable heartbeat (~15m)',
|
|
88
|
+
' atris loop start --overnight --hours 6',
|
|
76
89
|
'',
|
|
77
90
|
' watch it',
|
|
78
91
|
' atris loop status liveness, last tick, reward',
|
|
@@ -85,6 +98,16 @@ function renderLoopHome(route = { action: 'home' }) {
|
|
|
85
98
|
' wiki upkeep is at: atris loop wiki',
|
|
86
99
|
'',
|
|
87
100
|
];
|
|
101
|
+
if (Array.isArray(moves) && moves.length) {
|
|
102
|
+
lines.splice(lines.length - 2, 0, ' ranked next moves');
|
|
103
|
+
moves.slice(0, 3).forEach((move) => {
|
|
104
|
+
lines.splice(lines.length - 2, 0, ` [${move.source}] ${move.title}`);
|
|
105
|
+
});
|
|
106
|
+
lines.splice(lines.length - 2, 0, '');
|
|
107
|
+
}
|
|
108
|
+
lines.splice(lines.length - 2, 0, ' act on it');
|
|
109
|
+
lines.splice(lines.length - 2, 0, ' atris loop create-next create + claim the suggested task');
|
|
110
|
+
lines.splice(lines.length - 2, 0, '');
|
|
88
111
|
if (route && route.unknown) {
|
|
89
112
|
lines.splice(1, 0, ` (unknown: "${route.unknown}". here is the loop:)`);
|
|
90
113
|
}
|
|
@@ -95,7 +118,11 @@ function renderLoopHome(route = { action: 'home' }) {
|
|
|
95
118
|
}
|
|
96
119
|
|
|
97
120
|
function printLoopHome(route) {
|
|
98
|
-
|
|
121
|
+
let moves = [];
|
|
122
|
+
try {
|
|
123
|
+
moves = require('../lib/next-moves').nextMoves(process.cwd(), 3);
|
|
124
|
+
} catch { /* next moves are optional on a fresh checkout */ }
|
|
125
|
+
console.log(renderLoopHome(route, moves));
|
|
99
126
|
}
|
|
100
127
|
|
|
101
128
|
// Parse the handful of local-run flags `atris loop start` forwards to run.js.
|
|
@@ -148,7 +175,7 @@ function printLocalRunSummary() {
|
|
|
148
175
|
// Combined machine-readable status: the overnight pulse heartbeat and the local
|
|
149
176
|
// runs in one object. Best-effort per engine so a missing one does not fail it.
|
|
150
177
|
function loopStatusJson(root = process.cwd()) {
|
|
151
|
-
const out = { ok: true, action: 'loop_status', pulse: null, local_runs: { count: 0, latest: null } };
|
|
178
|
+
const out = { ok: true, action: 'loop_status', pulse: null, local_runs: { count: 0, latest: null }, next_moves: [] };
|
|
152
179
|
try {
|
|
153
180
|
const lp = require('../lib/pulse');
|
|
154
181
|
const { cronInstalled } = require('./pulse');
|
|
@@ -158,9 +185,88 @@ function loopStatusJson(root = process.cwd()) {
|
|
|
158
185
|
try {
|
|
159
186
|
out.local_runs = localRunSummary(require('./run').getRunLogDir());
|
|
160
187
|
} catch { /* runs optional */ }
|
|
188
|
+
try {
|
|
189
|
+
out.next_moves = require('../lib/next-moves').nextMoves(root, 5);
|
|
190
|
+
} catch { /* next moves optional */ }
|
|
161
191
|
return out;
|
|
162
192
|
}
|
|
163
193
|
|
|
194
|
+
function loopSeedMove(root = process.cwd()) {
|
|
195
|
+
const moves = require('../lib/next-moves').nextMoves(root, 5);
|
|
196
|
+
const activeTask = moves.find((move) => move && move.source === 'task');
|
|
197
|
+
if (activeTask) return { ok: false, reason: 'active_task', move: activeTask, moves };
|
|
198
|
+
const seed = moves.find((move) => (
|
|
199
|
+
move
|
|
200
|
+
&& move.source === 'mission'
|
|
201
|
+
&& (
|
|
202
|
+
move.why === 'active mission has no concrete task queued'
|
|
203
|
+
|| move.why === 'latest proof timeline suggested this self-improvement target'
|
|
204
|
+
)
|
|
205
|
+
));
|
|
206
|
+
if (!seed) return { ok: false, reason: 'no_seed', moves };
|
|
207
|
+
return { ok: true, move: seed, moves };
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function createNextLoopTask(argv = [], root = process.cwd(), options = {}) {
|
|
211
|
+
const shouldPrint = options.print !== false;
|
|
212
|
+
const json = argv.includes('--json');
|
|
213
|
+
const owner = flagValue(argv, '--as') || flagValue(argv, '--owner') || process.env.ATRIS_AGENT_ID || 'auto-improver';
|
|
214
|
+
const seed = loopSeedMove(root);
|
|
215
|
+
if (!seed.ok) {
|
|
216
|
+
const payload = { ok: false, action: 'create_next_skipped', reason: seed.reason, move: seed.move || null };
|
|
217
|
+
if (shouldPrint) {
|
|
218
|
+
if (json) console.log(JSON.stringify(payload, null, 2));
|
|
219
|
+
else if (seed.reason === 'active_task') console.log(`not created: active task already exists (${seed.move.ref || seed.move.title})`);
|
|
220
|
+
else console.log('not created: no loop seed is available');
|
|
221
|
+
}
|
|
222
|
+
return payload;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const note = `Goal: ${seed.move.title}. Files: inspect atris/MAP.md first, then the relevant code. Done: one bounded proof-backed self-improvement task is moved to Review. Check: focused verifier; git diff --check; atris clean --dry-run --json; atris brain compile --root . --verify.`;
|
|
226
|
+
const taskArgs = [
|
|
227
|
+
'task',
|
|
228
|
+
'delegate',
|
|
229
|
+
seed.move.title,
|
|
230
|
+
'--tag', 'loop',
|
|
231
|
+
'--claim',
|
|
232
|
+
'--as', String(owner),
|
|
233
|
+
'--note', note,
|
|
234
|
+
'--json',
|
|
235
|
+
];
|
|
236
|
+
const { spawnSync } = require('child_process');
|
|
237
|
+
const path = require('path');
|
|
238
|
+
const cli = path.join(__dirname, '..', 'bin', 'atris.js');
|
|
239
|
+
const child = spawnSync(process.execPath, [cli, ...taskArgs], {
|
|
240
|
+
cwd: root,
|
|
241
|
+
encoding: 'utf8',
|
|
242
|
+
timeout: 20000,
|
|
243
|
+
env: { ...process.env, ATRIS_SKIP_UPDATE_CHECK: '1' },
|
|
244
|
+
});
|
|
245
|
+
if (child.status !== 0) {
|
|
246
|
+
const payload = { ok: false, action: 'create_next_failed', reason: 'task_delegate_failed', stderr: child.stderr, stdout: child.stdout };
|
|
247
|
+
if (shouldPrint) {
|
|
248
|
+
if (json) console.log(JSON.stringify(payload, null, 2));
|
|
249
|
+
else console.error(child.stderr || child.stdout || 'task creation failed');
|
|
250
|
+
}
|
|
251
|
+
return payload;
|
|
252
|
+
}
|
|
253
|
+
let delegated = null;
|
|
254
|
+
try { delegated = JSON.parse(child.stdout); } catch { delegated = null; }
|
|
255
|
+
const task = delegated && delegated.task ? delegated.task : null;
|
|
256
|
+
const payload = { ok: true, action: 'created_next', owner: String(owner), move: seed.move, task, delegated };
|
|
257
|
+
if (shouldPrint) {
|
|
258
|
+
if (json) {
|
|
259
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
260
|
+
} else {
|
|
261
|
+
const ref = task?.display_id || task?.id || 'task';
|
|
262
|
+
console.log(`created next loop task: ${ref} ${seed.move.title}`);
|
|
263
|
+
console.log(`claimed by: ${owner}`);
|
|
264
|
+
console.log(`next: atris task show ${ref}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return payload;
|
|
268
|
+
}
|
|
269
|
+
|
|
164
270
|
// The evidence that the loop is improving things: ROADMAP items it has handled,
|
|
165
271
|
// what is in flight and queued, and the heartbeat's reward/verify trend. Pure of
|
|
166
272
|
// console so it is testable.
|
|
@@ -170,7 +276,7 @@ function loopReport(root = process.cwd()) {
|
|
|
170
276
|
try {
|
|
171
277
|
roadmap = require('../lib/next-moves').roadmapItemsByState(root);
|
|
172
278
|
} catch { /* roadmap optional */ }
|
|
173
|
-
return { ok: true, action: 'loop_report', roadmap, pulse: status.pulse, local_runs: status.local_runs };
|
|
279
|
+
return { ok: true, action: 'loop_report', roadmap, next_moves: status.next_moves, pulse: status.pulse, local_runs: status.local_runs };
|
|
174
280
|
}
|
|
175
281
|
|
|
176
282
|
function renderLoopReport(rep) {
|
|
@@ -193,6 +299,11 @@ function renderLoopReport(rep) {
|
|
|
193
299
|
lines.push(' next up:');
|
|
194
300
|
r.open.slice(0, 4).forEach((t) => lines.push(` [ ] ${t}`));
|
|
195
301
|
}
|
|
302
|
+
if (Array.isArray(rep.next_moves) && rep.next_moves.length) {
|
|
303
|
+
lines.push('');
|
|
304
|
+
lines.push(' ranked next:');
|
|
305
|
+
rep.next_moves.slice(0, 5).forEach((move) => lines.push(` [${move.source}] ${move.title}`));
|
|
306
|
+
}
|
|
196
307
|
if (rep.pulse) {
|
|
197
308
|
lines.push('');
|
|
198
309
|
lines.push(` heartbeat: ${rep.pulse.total_ticks} ticks, reward ${rep.pulse.reward_sum}, verify ${rep.pulse.verify_pass}/${rep.pulse.verify_fail}`);
|
|
@@ -236,6 +347,11 @@ function loopFront(argv = []) {
|
|
|
236
347
|
return Promise.resolve(0);
|
|
237
348
|
}
|
|
238
349
|
|
|
350
|
+
case 'create-next': {
|
|
351
|
+
const result = createNextLoopTask(argv, process.cwd());
|
|
352
|
+
return Promise.resolve(result.ok ? 0 : 1);
|
|
353
|
+
}
|
|
354
|
+
|
|
239
355
|
case 'status': {
|
|
240
356
|
if (jsonFlag.length) {
|
|
241
357
|
// One machine-readable object covering BOTH engines (overnight pulse
|
|
@@ -284,6 +400,8 @@ module.exports = {
|
|
|
284
400
|
startLocalOptions,
|
|
285
401
|
localRunSummary,
|
|
286
402
|
loopStatusJson,
|
|
403
|
+
loopSeedMove,
|
|
404
|
+
createNextLoopTask,
|
|
287
405
|
loopReport,
|
|
288
406
|
renderLoopReport,
|
|
289
407
|
loopFront,
|