atris 3.34.0 → 3.36.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 +35 -0
- package/FOR_AGENTS.md +5 -3
- package/README.md +5 -3
- package/atris/GETTING_STARTED.md +1 -1
- package/atris/atris.md +3 -0
- package/atris/policies/day-loop-voice.md +102 -0
- package/atris/policies/outbound-artifact-gate.md +2 -0
- package/atris/skills/design/SKILL.md +56 -32
- package/atris/skills/endgame/SKILL.md +12 -6
- package/atris/skills/engines/SKILL.md +35 -8
- package/atris/skills/fable-method/SKILL.md +66 -0
- package/atris/skills/improve/SKILL.md +65 -45
- package/atris/skills/render-cli/SKILL.md +88 -0
- package/atris/skills/youtube/SKILL.md +10 -1
- package/atris.md +6 -2
- package/ax +617 -31
- package/bin/atris.js +719 -266
- package/commands/activate.js +194 -88
- package/commands/aeo.js +52 -0
- package/commands/agents.js +166 -0
- package/commands/autoland.js +718 -72
- package/commands/autopilot-front.js +20 -2
- package/commands/autopilot.js +118 -2
- package/commands/avail.js +407 -0
- package/commands/bench.js +188 -0
- package/commands/brain.js +3 -0
- package/commands/brief.js +651 -0
- package/commands/business-sync.js +192 -6
- package/commands/business.js +91 -8
- package/commands/clean.js +50 -24
- package/commands/close.js +1083 -0
- package/commands/cloud.js +245 -0
- package/commands/codex-goal.js +26 -2
- package/commands/compile.js +292 -1
- package/commands/computer.js +150 -3
- package/commands/dream.js +365 -0
- package/commands/drill.js +371 -0
- package/commands/drive.js +187 -0
- package/commands/engine.js +1061 -29
- package/commands/experiments.js +28 -0
- package/commands/feed.js +202 -0
- package/commands/feedback.js +34 -12
- package/commands/fleet-report.js +206 -0
- package/commands/github.js +38 -0
- package/commands/gm.js +285 -3
- package/commands/goal.js +247 -0
- package/commands/improve.js +642 -26
- package/commands/init.js +83 -43
- package/commands/integrations.js +39 -11
- package/commands/interview.js +209 -0
- package/commands/land.js +253 -52
- package/commands/lesson.js +112 -1
- package/commands/lifecycle.js +39 -3
- package/commands/linear.js +38 -0
- package/commands/log.js +84 -1
- package/commands/loops.js +220 -16
- package/commands/meet.js +220 -0
- package/commands/member.js +899 -66
- package/commands/mission.js +3512 -332
- package/commands/next.js +137 -0
- package/commands/now.js +240 -21
- package/commands/one-lap.js +776 -0
- package/commands/orb.js +314 -0
- package/commands/pack-craft.js +179 -0
- package/commands/pack.js +823 -0
- package/commands/play.js +3 -2
- package/commands/probe.js +30 -3
- package/commands/pulse.js +241 -46
- package/commands/push.js +260 -82
- package/commands/radar.js +259 -14
- package/commands/rainmaker.js +49 -0
- package/commands/report.js +415 -0
- package/commands/scout.js +147 -0
- package/commands/search.js +363 -0
- package/commands/serve.js +54 -0
- package/commands/skill.js +47 -3
- package/commands/slop.js +50 -2
- package/commands/soul.js +1 -1
- package/commands/status.js +50 -5
- package/commands/stream.js +861 -0
- package/commands/stripe.js +38 -0
- package/commands/study.js +693 -0
- package/commands/supabase.js +39 -0
- package/commands/sync.js +67 -54
- package/commands/task.js +2275 -182
- package/commands/team.js +73 -0
- package/commands/truth.js +29 -3
- package/commands/unknowns.js +627 -0
- package/commands/update.js +44 -0
- package/commands/vercel.js +38 -0
- package/commands/verify.js +96 -0
- package/commands/watch.js +303 -0
- package/commands/wish.js +500 -0
- package/commands/workflow.js +11 -5
- package/commands/worktree.js +299 -20
- package/commands/write.js +399 -0
- package/commands/xp.js +29 -11
- package/lib/auto-accept-certified.js +391 -43
- package/lib/autoland.js +353 -52
- package/lib/ax-auto-lane.js +79 -0
- package/lib/bench/context.js +147 -0
- package/lib/bench/engines.js +141 -0
- package/lib/bench/report.js +140 -0
- package/lib/bench/runner.js +512 -0
- package/lib/brief-ledger.js +350 -0
- package/lib/cloud-mission.js +259 -0
- package/lib/codex-flight.js +154 -0
- package/lib/default-runner.js +45 -0
- package/lib/default-verifier.js +70 -0
- package/lib/engine-registry.js +232 -0
- package/lib/experiments/daily.js +640 -0
- package/lib/fleet.js +2431 -38
- package/lib/improve-vitals-html.js +171 -0
- package/lib/known-commands.js +58 -0
- package/lib/loop-doctor.js +416 -0
- package/lib/member-switches.js +144 -0
- package/lib/memory-view.js +14 -5
- package/lib/mission-room.js +1 -0
- package/lib/mission-root.js +52 -0
- package/lib/mission-runtime-loop.js +7 -0
- package/lib/next-moves.js +327 -10
- package/lib/official-cli-integration.js +174 -0
- package/lib/one-lap-validator.js +60 -0
- package/lib/orb-context.js +477 -0
- package/lib/orb-scorecard.js +224 -0
- package/lib/outbound-send-gate.js +165 -0
- package/lib/permission-grants.js +293 -0
- package/lib/policy-lessons.js +52 -1
- package/lib/pulse.js +277 -3
- package/lib/receipt-block.js +168 -0
- package/lib/receipt-evidence.js +65 -4
- package/lib/review-integrity.js +147 -0
- package/lib/router-brain.js +352 -0
- package/lib/runner-command.js +33 -0
- package/lib/self-drive.js +258 -0
- package/lib/short-name.js +103 -0
- package/lib/spawn-env.js +18 -0
- package/lib/state-detection.js +56 -1
- package/lib/sync-status.js +59 -0
- package/lib/task-db.js +319 -27
- package/lib/task-proof.js +43 -1
- package/lib/task-receipt.js +93 -0
- package/lib/team-presence.js +260 -0
- package/lib/tool-result-encode.js +7 -0
- package/lib/trust-tiers.js +90 -0
- package/lib/usage.js +107 -0
- package/lib/voice-gate.js +163 -0
- package/lib/wish-audit.js +1368 -0
- package/lib/wish-delegate.js +1840 -0
- package/lib/wish-design.js +110 -0
- package/lib/wish-stats.js +183 -0
- package/lib/wish-store.js +354 -0
- package/lib/zip.js +221 -0
- package/package.json +3 -1
- package/templates/loops/atris/loops/LOOPS.md +55 -0
- package/templates/loops/atris/loops/TICK.md +24 -0
- package/templates/loops/atris/loops/feedback.md +22 -0
- package/templates/loops/atris/loops/quality.md +22 -0
- package/templates/loops/atris/wiki/systems/loops.md +41 -0
- package/utils/api.js +5 -1
- package/utils/auth.js +57 -21
- package/utils/update-check.js +27 -6
- package/atris/learnings.jsonl +0 -1
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// `atris interview [subject]`: the interlinked 1-on-1. Launches a live Claude
|
|
4
|
+
// interview that extracts judgment into a member file (create or amend).
|
|
5
|
+
//
|
|
6
|
+
// atris interview Interview the operator (warm start from logs)
|
|
7
|
+
// atris interview me Same as above
|
|
8
|
+
// atris interview neo Re-interview a member about its own logs
|
|
9
|
+
// atris interview darvo (any atris/team/<slug> works)
|
|
10
|
+
// atris interview "Priya" Cold-start interview of a new expert → new member
|
|
11
|
+
//
|
|
12
|
+
// The command gathers context paths, composes the interview brief, and hands
|
|
13
|
+
// off to an interactive `claude` session. The conversation IS the product;
|
|
14
|
+
// this command just makes sure it opens with what the system already knows.
|
|
15
|
+
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
const path = require('path');
|
|
18
|
+
const { spawn } = require('child_process');
|
|
19
|
+
const readline = require('readline');
|
|
20
|
+
|
|
21
|
+
function findWorkspaceRoot(start) {
|
|
22
|
+
let dir = start;
|
|
23
|
+
while (dir !== path.dirname(dir)) {
|
|
24
|
+
if (fs.existsSync(path.join(dir, 'atris'))) return dir;
|
|
25
|
+
dir = path.dirname(dir);
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function today(offsetDays = 0) {
|
|
31
|
+
const d = new Date(Date.now() - offsetDays * 86400000);
|
|
32
|
+
return d.toISOString().slice(0, 10);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function existing(...candidates) {
|
|
36
|
+
return candidates.filter((p) => p && fs.existsSync(p));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function showHelp() {
|
|
40
|
+
console.log('');
|
|
41
|
+
console.log('Usage: atris interview [subject]');
|
|
42
|
+
console.log('');
|
|
43
|
+
console.log('The interlinked 1-on-1. A live interview that extracts judgment into a');
|
|
44
|
+
console.log('member file. One question at a time, opens with observed behavior, ends');
|
|
45
|
+
console.log('with the verify question. The transcript becomes a MEMBER.md create/amend.');
|
|
46
|
+
console.log('');
|
|
47
|
+
console.log(' atris interview Interview the operator (reads recent journal first)');
|
|
48
|
+
console.log(' atris interview <member> Performance review: member vs its own logs');
|
|
49
|
+
console.log(' atris interview "<Name>" Cold-start a new expert into a new member');
|
|
50
|
+
console.log(' --help, -h Show this help');
|
|
51
|
+
console.log('');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function unquote(value) {
|
|
55
|
+
const text = String(value);
|
|
56
|
+
if ((text.startsWith('"') && text.endsWith('"')) || (text.startsWith("'") && text.endsWith("'"))) {
|
|
57
|
+
return text.slice(1, -1);
|
|
58
|
+
}
|
|
59
|
+
return text;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function parseSimpleFlags(args = [], valueFlagNames = []) {
|
|
63
|
+
const valueFlags = new Set(valueFlagNames);
|
|
64
|
+
const values = {};
|
|
65
|
+
const positionals = [];
|
|
66
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
67
|
+
const arg = String(args[i] || '');
|
|
68
|
+
if (arg.startsWith('--')) {
|
|
69
|
+
const flagName = arg.split('=')[0];
|
|
70
|
+
if (valueFlags.has(flagName)) {
|
|
71
|
+
const prefix = `${flagName}=`;
|
|
72
|
+
if (arg.startsWith(prefix)) values[flagName] = unquote(arg.slice(prefix.length));
|
|
73
|
+
else if (args[i + 1] && !String(args[i + 1]).startsWith('--')) {
|
|
74
|
+
values[flagName] = unquote(args[i + 1]);
|
|
75
|
+
i += 1;
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
values[flagName] = true;
|
|
79
|
+
}
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
positionals.push(args[i]);
|
|
83
|
+
}
|
|
84
|
+
return { values, positionals };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function askPlain(rl, question) {
|
|
88
|
+
return new Promise((resolve) => rl.question(question, (answer) => resolve(answer)));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function runPlainInterview({ args = [], fields = [], input = process.stdin, output = process.stdout } = {}) {
|
|
92
|
+
const parsed = parseSimpleFlags(args, fields.map((field) => field.flag));
|
|
93
|
+
const answers = {};
|
|
94
|
+
for (const field of fields) {
|
|
95
|
+
const value = String(parsed.values[field.flag] || '').trim();
|
|
96
|
+
if (value) answers[field.key] = value;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const missing = fields.filter((field) => !answers[field.key]);
|
|
100
|
+
if (!missing.length) return { ok: true, answers, positionals: parsed.positionals };
|
|
101
|
+
if (!input.isTTY) return { ok: false, missing: missing.map((field) => field.flag), answers, positionals: parsed.positionals };
|
|
102
|
+
|
|
103
|
+
const rl = readline.createInterface({ input, output });
|
|
104
|
+
try {
|
|
105
|
+
for (const field of missing) {
|
|
106
|
+
// eslint-disable-next-line no-await-in-loop
|
|
107
|
+
const answer = (await askPlain(rl, field.question)).trim();
|
|
108
|
+
if (answer) answers[field.key] = answer;
|
|
109
|
+
}
|
|
110
|
+
} finally {
|
|
111
|
+
rl.close();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const stillMissing = fields.filter((field) => !answers[field.key]);
|
|
115
|
+
if (stillMissing.length) return { ok: false, missing: stillMissing.map((field) => field.flag), answers, positionals: parsed.positionals };
|
|
116
|
+
return { ok: true, answers, positionals: parsed.positionals };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function composePrompt(mode, subject, contextPaths, root) {
|
|
120
|
+
const ctx = contextPaths.length
|
|
121
|
+
? `Read these first (this is what the system already knows — open with an observation from them, never a blank question):\n${contextPaths.map((p) => `- ${p}`).join('\n')}`
|
|
122
|
+
: 'No system data exists for this subject — this is a cold start.';
|
|
123
|
+
|
|
124
|
+
const laws = `Rules of conduct (the six laws — non-negotiable):
|
|
125
|
+
1. Never render a form. ONE question per turn; the next question comes from the answer.
|
|
126
|
+
2. Never ask what the system already knows. Open with an observation, not a blank ask.
|
|
127
|
+
3. The verify question is the whole game: "how do you know it worked?" Prefer countable process receipts.
|
|
128
|
+
4. Interview a person, not a profession. Hunt the last real instance, actual names, where they paused.
|
|
129
|
+
5. Living file. The transcript ends as a MEMBER.md create or amend + immediate commit and push.
|
|
130
|
+
6. Arrival, not initiation. Reversible edits land done with the diff shown; question marks only for judgment that is genuinely theirs.
|
|
131
|
+
Warmth without glazing: claims that cannot survive a follow-up die politely and stay out of the file.
|
|
132
|
+
5-10 questions is a full session. Stop when the verify condition lands.
|
|
133
|
+
Full skill (read if present): .claude/skills/interview/SKILL.md · spec: atris/features/md-builder/idea.md`;
|
|
134
|
+
|
|
135
|
+
const modes = {
|
|
136
|
+
operator: `Mode: OPERATOR WARM START. Interview the human at the keyboard. Open with the sharpest observed behavior in their recent journal/logs — especially repeated manual actions (unextracted members) and policies their own behavior contradicts. Output: a new member, an amendment, or a policy change.`,
|
|
137
|
+
member: `Mode: MEMBER RE-INTERVIEW (performance review). Subject: the team member "${subject}". Read its folder (MEMBER.md, logs/, now.md, proofs) and interview the human ABOUT it — where it failed, what it should defend, what taste is missing from its file. Honest failure → document the lesson, no penalty. A false "done" is the one unforgivable act. Output: amend atris/team/${subject}/MEMBER.md.`,
|
|
138
|
+
expert: `Mode: COLD START. Subject: a new expert called "${subject}". No system data. Opener: "when someone is stuck, what's the problem where they say 'just ask you'?" (civilian variant: "what are you the designated one for?"). Then last real instance → live method demo → quality bar → verify question. Output: create atris/team/<slug>/MEMBER.md.`,
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
return [
|
|
142
|
+
`You are running /interview — the interlinked 1-on-1 (workspace: ${root}).`,
|
|
143
|
+
modes[mode],
|
|
144
|
+
ctx,
|
|
145
|
+
laws,
|
|
146
|
+
`Begin the interview now with your single opening question.`,
|
|
147
|
+
].join('\n\n');
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async function interviewCommand(args = [], root = process.cwd()) {
|
|
151
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
152
|
+
showHelp();
|
|
153
|
+
return 0;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const ws = findWorkspaceRoot(root);
|
|
157
|
+
if (!ws) {
|
|
158
|
+
console.error('✗ Not inside an Atris workspace (no atris/ directory found).');
|
|
159
|
+
return 1;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const subjectRaw = (args.find((a) => !a.startsWith('--')) || 'me').trim();
|
|
163
|
+
const slug = subjectRaw.toLowerCase().replace(/\s+/g, '-');
|
|
164
|
+
const memberDir = path.join(ws, 'atris', 'team', slug);
|
|
165
|
+
|
|
166
|
+
let mode;
|
|
167
|
+
let contextPaths = [];
|
|
168
|
+
|
|
169
|
+
if (subjectRaw === 'me' || subjectRaw === '') {
|
|
170
|
+
mode = 'operator';
|
|
171
|
+
contextPaths = existing(
|
|
172
|
+
path.join(ws, 'atris', 'logs', '2026', `${today()}.md`),
|
|
173
|
+
path.join(ws, 'atris', 'logs', '2026', `${today(1)}.md`),
|
|
174
|
+
path.join(ws, 'atris', 'now.md'),
|
|
175
|
+
path.join(ws, 'atris', 'TODO.md')
|
|
176
|
+
);
|
|
177
|
+
} else if (fs.existsSync(memberDir)) {
|
|
178
|
+
mode = 'member';
|
|
179
|
+
contextPaths = existing(
|
|
180
|
+
path.join(memberDir, 'MEMBER.md'),
|
|
181
|
+
path.join(memberDir, 'now.md'),
|
|
182
|
+
path.join(memberDir, 'logs'),
|
|
183
|
+
path.join(memberDir, 'proofs'),
|
|
184
|
+
path.join(ws, 'atris', 'logs', '2026', `${today()}.md`)
|
|
185
|
+
);
|
|
186
|
+
} else {
|
|
187
|
+
mode = 'expert';
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const prompt = composePrompt(mode, mode === 'member' ? slug : subjectRaw, contextPaths, ws);
|
|
191
|
+
|
|
192
|
+
console.log('');
|
|
193
|
+
console.log(`◈ interview — ${mode === 'operator' ? 'you, from your logs' : mode === 'member' ? `1-on-1 about ${slug}` : `cold start: ${subjectRaw}`}`);
|
|
194
|
+
if (contextPaths.length) console.log(` context: ${contextPaths.length} source${contextPaths.length > 1 ? 's' : ''} loaded`);
|
|
195
|
+
console.log('');
|
|
196
|
+
|
|
197
|
+
const child = spawn('claude', [prompt], { cwd: ws, stdio: 'inherit' });
|
|
198
|
+
return await new Promise((resolve) => {
|
|
199
|
+
child.on('exit', (code) => resolve(code || 0));
|
|
200
|
+
child.on('error', (err) => {
|
|
201
|
+
console.error(`✗ Could not launch claude: ${err.message}`);
|
|
202
|
+
console.error(' Install Claude Code or run the prompt manually:');
|
|
203
|
+
console.log('\n' + prompt + '\n');
|
|
204
|
+
resolve(1);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
module.exports = { interviewCommand, parseSimpleFlags, runPlainInterview };
|