atris 2.0.0 → 2.0.2
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/PERSONA.md +1 -1
- package/atris/PERSONA.md +1 -1
- package/atris/atris.md +61 -2
- package/atris.md +61 -2
- package/bin/atris.js +112 -29
- package/commands/init.js +21 -1
- package/commands/workflow.js +51 -10
- package/package.json +1 -1
package/PERSONA.md
CHANGED
|
@@ -60,7 +60,7 @@ Delete when done. Clean workspace = clear mind.
|
|
|
60
60
|
|
|
61
61
|
## Collaboration
|
|
62
62
|
|
|
63
|
-
**Trust the system.** MAP.md is truth. TODO.md is current work (formerly `
|
|
63
|
+
**Trust the system.** MAP.md is truth. TODO.md is current work (formerly `TODO.md`).
|
|
64
64
|
|
|
65
65
|
Navigator finds, executor builds, validator verifies. Stay in your lane.
|
|
66
66
|
|
package/atris/PERSONA.md
CHANGED
|
@@ -60,7 +60,7 @@ Delete when done. Clean workspace = clear mind.
|
|
|
60
60
|
|
|
61
61
|
## Collaboration
|
|
62
62
|
|
|
63
|
-
**Trust the system.** MAP.md is truth. TODO.md is current work (formerly `
|
|
63
|
+
**Trust the system.** MAP.md is truth. TODO.md is current work (formerly `TODO.md`).
|
|
64
64
|
|
|
65
65
|
Navigator finds, executor builds, validator verifies. Stay in your lane.
|
|
66
66
|
|
package/atris/atris.md
CHANGED
|
@@ -146,7 +146,7 @@ ATRIS ships with pre-built agent templates in `/atris/agent_team/` (copied durin
|
|
|
146
146
|
|
|
147
147
|
---
|
|
148
148
|
|
|
149
|
-
## Phase 3: Task Context System (TODO.md in `/atris/`, formerly `
|
|
149
|
+
## Phase 3: Task Context System (TODO.md in `/atris/`, formerly `TODO.md`)
|
|
150
150
|
|
|
151
151
|
**Goal:** Automatic task extraction with exact file/component context, so agents never guess.
|
|
152
152
|
|
|
@@ -218,7 +218,7 @@ ATRIS ships with pre-built agent templates in `/atris/agent_team/` (copied durin
|
|
|
218
218
|
|
|
219
219
|
3. Output: `/atris/TODO.md` (maintains and evolves as system changes)
|
|
220
220
|
|
|
221
|
-
4. On each MAP.md update, regenerate
|
|
221
|
+
4. On each MAP.md update, regenerate TODO.md to reflect new state
|
|
222
222
|
|
|
223
223
|
---
|
|
224
224
|
|
|
@@ -592,6 +592,65 @@ Contents:
|
|
|
592
592
|
|
|
593
593
|
---
|
|
594
594
|
|
|
595
|
+
## Phase 5.3: Claude Code Integration
|
|
596
|
+
|
|
597
|
+
Auto-inject ATRIS context into Claude Code sessions via skills and commands.
|
|
598
|
+
|
|
599
|
+
### Slash Command Setup
|
|
600
|
+
|
|
601
|
+
Create `.claude/commands/atris.md`:
|
|
602
|
+
|
|
603
|
+
```markdown
|
|
604
|
+
---
|
|
605
|
+
description: Activate ATRIS context - loads TODO.md, journal, and persona
|
|
606
|
+
allowed-tools: Read, Bash, Glob, Grep
|
|
607
|
+
---
|
|
608
|
+
|
|
609
|
+
# ATRIS Activate
|
|
610
|
+
|
|
611
|
+
Load these files:
|
|
612
|
+
1. @atris/PERSONA.md (communication style)
|
|
613
|
+
2. @atris/TODO.md (current tasks)
|
|
614
|
+
3. @atris/MAP.md (navigation)
|
|
615
|
+
|
|
616
|
+
Workflow: plan → do → review
|
|
617
|
+
Rules: 3-4 sentences max, ASCII visuals, check MAP.md first
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### Skill Setup
|
|
621
|
+
|
|
622
|
+
Create `.claude/skills/atris/SKILL.md`:
|
|
623
|
+
|
|
624
|
+
```markdown
|
|
625
|
+
---
|
|
626
|
+
name: atris
|
|
627
|
+
description: ATRIS workspace navigation. Use when user mentions atris, TODO, tasks, MAP.md, or asks "where is X?"
|
|
628
|
+
allowed-tools: Read, Bash, Glob, Grep, Write, Edit
|
|
629
|
+
---
|
|
630
|
+
|
|
631
|
+
# ATRIS Skill
|
|
632
|
+
|
|
633
|
+
Detect: Project has `atris/` folder with MAP.md, TODO.md, PERSONA.md
|
|
634
|
+
|
|
635
|
+
Workflow: Navigator (plan) → Executor (build) → Validator (verify)
|
|
636
|
+
|
|
637
|
+
Key behaviors:
|
|
638
|
+
- Read PERSONA.md first (3-4 sentences, ASCII visuals)
|
|
639
|
+
- Check MAP.md for file:line refs
|
|
640
|
+
- Update TODO.md (claim tasks, delete when done)
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### Checklist
|
|
644
|
+
|
|
645
|
+
- [ ] Create `.claude/commands/` directory
|
|
646
|
+
- [ ] Create `.claude/skills/atris/` directory
|
|
647
|
+
- [ ] Add `atris.md` command file
|
|
648
|
+
- [ ] Add `SKILL.md` skill file
|
|
649
|
+
- [ ] Test with `/atris` in Claude Code
|
|
650
|
+
- [ ] Verify skill triggers on "atris" or "tasks" mentions
|
|
651
|
+
|
|
652
|
+
---
|
|
653
|
+
|
|
595
654
|
## Phase 6: Future Roadmap (Vision)
|
|
596
655
|
|
|
597
656
|
**See [`ATRIS_NOTES.md`](./ATRIS_NOTES.md) for full roadmap. Preview:**
|
package/atris.md
CHANGED
|
@@ -146,7 +146,7 @@ ATRIS ships with pre-built agent templates in `/atris/agent_team/` (copied durin
|
|
|
146
146
|
|
|
147
147
|
---
|
|
148
148
|
|
|
149
|
-
## Phase 3: Task Context System (TODO.md in `/atris/`, formerly `
|
|
149
|
+
## Phase 3: Task Context System (TODO.md in `/atris/`, formerly `TODO.md`)
|
|
150
150
|
|
|
151
151
|
**Goal:** Automatic task extraction with exact file/component context, so agents never guess.
|
|
152
152
|
|
|
@@ -218,7 +218,7 @@ ATRIS ships with pre-built agent templates in `/atris/agent_team/` (copied durin
|
|
|
218
218
|
|
|
219
219
|
3. Output: `/atris/TODO.md` (maintains and evolves as system changes)
|
|
220
220
|
|
|
221
|
-
4. On each MAP.md update, regenerate
|
|
221
|
+
4. On each MAP.md update, regenerate TODO.md to reflect new state
|
|
222
222
|
|
|
223
223
|
---
|
|
224
224
|
|
|
@@ -592,6 +592,65 @@ Contents:
|
|
|
592
592
|
|
|
593
593
|
---
|
|
594
594
|
|
|
595
|
+
## Phase 5.3: Claude Code Integration
|
|
596
|
+
|
|
597
|
+
Auto-inject ATRIS context into Claude Code sessions via skills and commands.
|
|
598
|
+
|
|
599
|
+
### Slash Command Setup
|
|
600
|
+
|
|
601
|
+
Create `.claude/commands/atris.md`:
|
|
602
|
+
|
|
603
|
+
```markdown
|
|
604
|
+
---
|
|
605
|
+
description: Activate ATRIS context - loads TODO.md, journal, and persona
|
|
606
|
+
allowed-tools: Read, Bash, Glob, Grep
|
|
607
|
+
---
|
|
608
|
+
|
|
609
|
+
# ATRIS Activate
|
|
610
|
+
|
|
611
|
+
Load these files:
|
|
612
|
+
1. @atris/PERSONA.md (communication style)
|
|
613
|
+
2. @atris/TODO.md (current tasks)
|
|
614
|
+
3. @atris/MAP.md (navigation)
|
|
615
|
+
|
|
616
|
+
Workflow: plan → do → review
|
|
617
|
+
Rules: 3-4 sentences max, ASCII visuals, check MAP.md first
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### Skill Setup
|
|
621
|
+
|
|
622
|
+
Create `.claude/skills/atris/SKILL.md`:
|
|
623
|
+
|
|
624
|
+
```markdown
|
|
625
|
+
---
|
|
626
|
+
name: atris
|
|
627
|
+
description: ATRIS workspace navigation. Use when user mentions atris, TODO, tasks, MAP.md, or asks "where is X?"
|
|
628
|
+
allowed-tools: Read, Bash, Glob, Grep, Write, Edit
|
|
629
|
+
---
|
|
630
|
+
|
|
631
|
+
# ATRIS Skill
|
|
632
|
+
|
|
633
|
+
Detect: Project has `atris/` folder with MAP.md, TODO.md, PERSONA.md
|
|
634
|
+
|
|
635
|
+
Workflow: Navigator (plan) → Executor (build) → Validator (verify)
|
|
636
|
+
|
|
637
|
+
Key behaviors:
|
|
638
|
+
- Read PERSONA.md first (3-4 sentences, ASCII visuals)
|
|
639
|
+
- Check MAP.md for file:line refs
|
|
640
|
+
- Update TODO.md (claim tasks, delete when done)
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### Checklist
|
|
644
|
+
|
|
645
|
+
- [ ] Create `.claude/commands/` directory
|
|
646
|
+
- [ ] Create `.claude/skills/atris/` directory
|
|
647
|
+
- [ ] Add `atris.md` command file
|
|
648
|
+
- [ ] Add `SKILL.md` skill file
|
|
649
|
+
- [ ] Test with `/atris` in Claude Code
|
|
650
|
+
- [ ] Verify skill triggers on "atris" or "tasks" mentions
|
|
651
|
+
|
|
652
|
+
---
|
|
653
|
+
|
|
595
654
|
## Phase 6: Future Roadmap (Vision)
|
|
596
655
|
|
|
597
656
|
**See [`ATRIS_NOTES.md`](./ATRIS_NOTES.md) for full roadmap. Preview:**
|
package/bin/atris.js
CHANGED
|
@@ -198,6 +198,19 @@ function showAutopilotHelp() {
|
|
|
198
198
|
console.log('');
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
+
// Command handlers - must load BEFORE interactiveEntry() is called (TDZ issue)
|
|
202
|
+
const { initAtris: initCmd } = require('../commands/init');
|
|
203
|
+
const { syncAtris: syncCmd } = require('../commands/sync');
|
|
204
|
+
const { logAtris: logCmd } = require('../commands/log');
|
|
205
|
+
const { logSyncAtris: logSyncCmd } = require('../commands/log-sync');
|
|
206
|
+
const { loginAtris: loginCmd, logoutAtris: logoutCmd, whoamiAtris: whoamiCmd } = require('../commands/auth');
|
|
207
|
+
const { showVersion: versionCmd } = require('../commands/version');
|
|
208
|
+
const { planAtris: planCmd, doAtris: doCmd, reviewAtris: reviewCmd } = require('../commands/workflow');
|
|
209
|
+
const { visualizeAtris: visualizeCmd } = require('../commands/visualize');
|
|
210
|
+
const { brainstormAtris: brainstormCmd, autopilotAtris: autopilotCmd } = require('../commands/brainstorm');
|
|
211
|
+
const { statusAtris: statusCmd } = require('../commands/status');
|
|
212
|
+
const { analyticsAtris: analyticsCmd } = require('../commands/analytics');
|
|
213
|
+
|
|
201
214
|
// Check if this is a known command or natural language input
|
|
202
215
|
const knownCommands = ['init', 'log', 'status', 'analytics', 'visualize', 'brainstorm', 'autopilot', 'plan', 'do', 'review',
|
|
203
216
|
'agent', 'chat', 'login', 'logout', 'whoami', 'update', 'version', 'help'];
|
|
@@ -206,23 +219,13 @@ const knownCommands = ['init', 'log', 'status', 'analytics', 'visualize', 'brain
|
|
|
206
219
|
if (!command || !knownCommands.includes(command)) {
|
|
207
220
|
const userInput = process.argv.slice(2).join(' ');
|
|
208
221
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
});
|
|
217
|
-
} else {
|
|
218
|
-
// Hot start - user provided task description
|
|
219
|
-
atrisDevEntry(userInput)
|
|
220
|
-
.then(() => process.exit(0))
|
|
221
|
-
.catch((error) => {
|
|
222
|
-
console.error(`✗ Error: ${error.message || error}`);
|
|
223
|
-
process.exit(1);
|
|
224
|
-
});
|
|
225
|
-
}
|
|
222
|
+
// Launch interactive entry (the "Performance")
|
|
223
|
+
interactiveEntry(userInput)
|
|
224
|
+
.then(() => process.exit(0))
|
|
225
|
+
.catch((error) => {
|
|
226
|
+
console.error(`✗ Error: ${error.message || error}`);
|
|
227
|
+
process.exit(1);
|
|
228
|
+
});
|
|
226
229
|
return;
|
|
227
230
|
}
|
|
228
231
|
|
|
@@ -231,18 +234,98 @@ if (command === 'help' || command === '--help' || command === '-h') {
|
|
|
231
234
|
process.exit(0);
|
|
232
235
|
}
|
|
233
236
|
|
|
234
|
-
|
|
235
|
-
const
|
|
236
|
-
const
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
237
|
+
async function interactiveEntry(userInput) {
|
|
238
|
+
const workspaceDir = process.cwd();
|
|
239
|
+
const state = detectWorkspaceState(workspaceDir);
|
|
240
|
+
const context = loadContext(workspaceDir);
|
|
241
|
+
|
|
242
|
+
// Case 1: Hot Start (User provided input: "atris fix bug")
|
|
243
|
+
if (userInput) {
|
|
244
|
+
console.log('');
|
|
245
|
+
console.log(`✨ Request: "${userInput}"`);
|
|
246
|
+
console.log(' Initializing Navigator...');
|
|
247
|
+
await planCmd(userInput);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Case 2: Cold Start (User typed "atris")
|
|
252
|
+
// We present a "Warm Up" interface based on state
|
|
253
|
+
|
|
254
|
+
console.log('');
|
|
255
|
+
console.log('┌─────────────────────────────────────────────────────────────┐');
|
|
256
|
+
console.log('│ ATRIS │');
|
|
257
|
+
console.log('└─────────────────────────────────────────────────────────────┘');
|
|
258
|
+
|
|
259
|
+
const rl = readline.createInterface({
|
|
260
|
+
input: process.stdin,
|
|
261
|
+
output: process.stdout
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
const ask = (q) => new Promise(r => rl.question(q, r));
|
|
265
|
+
|
|
266
|
+
// Logic: Detect State -> Offer "Path of Least Resistance"
|
|
267
|
+
|
|
268
|
+
// State: Fresh Install
|
|
269
|
+
if (state.state === 'fresh') {
|
|
270
|
+
console.log('\n👋 Welcome to ATRIS.');
|
|
271
|
+
console.log(' This folder is not initialized yet.');
|
|
272
|
+
const answer = await ask('\n Initialize project structure? [Y/n] ');
|
|
273
|
+
rl.close();
|
|
274
|
+
if (answer.toLowerCase() === '' || answer.toLowerCase() === 'y') {
|
|
275
|
+
initCmd();
|
|
276
|
+
} else {
|
|
277
|
+
console.log('Cancelled.');
|
|
278
|
+
}
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// State: In-Progress Work
|
|
283
|
+
if (context.inProgressFeatures.length > 0) {
|
|
284
|
+
const active = context.inProgressFeatures[0].replace('.md', '');
|
|
285
|
+
console.log(`\n🔥 Active Feature: ${active}`);
|
|
286
|
+
const answer = await ask(` Resume building this? [Y/n] `);
|
|
287
|
+
if (answer.toLowerCase() === '' || answer.toLowerCase() === 'y') {
|
|
288
|
+
console.log('\n🚀 Starting Executor...');
|
|
289
|
+
rl.close();
|
|
290
|
+
await doCmd();
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// State: Inbox Items
|
|
296
|
+
if (context.hasInbox && context.inboxItems.length > 0) {
|
|
297
|
+
console.log(`\n📥 Inbox: You have ${context.inboxItems.length} unprocessed items.`);
|
|
298
|
+
const answer = await ask(` Process into a plan? [Y/n] `);
|
|
299
|
+
if (answer.toLowerCase() === '' || answer.toLowerCase() === 'y') {
|
|
300
|
+
console.log('\n🚀 Starting Navigator...');
|
|
301
|
+
rl.close();
|
|
302
|
+
await planCmd();
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// State: Idle / Default
|
|
308
|
+
console.log('\n✨ Canvas is clean. What are we building?');
|
|
309
|
+
console.log(' (Type a request, "brainstorm", "status", or press Enter to exit)');
|
|
310
|
+
|
|
311
|
+
const request = await ask('\n> ');
|
|
312
|
+
rl.close();
|
|
313
|
+
|
|
314
|
+
if (!request.trim()) {
|
|
315
|
+
console.log('See you later! 👋');
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (request.toLowerCase() === 'brainstorm') {
|
|
320
|
+
await brainstormCmd();
|
|
321
|
+
} else if (request.toLowerCase() === 'status') {
|
|
322
|
+
await statusCmd();
|
|
323
|
+
} else {
|
|
324
|
+
// Treat as new plan request
|
|
325
|
+
console.log('\n🚀 Starting Navigator...');
|
|
326
|
+
await planCmd(request);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
246
329
|
|
|
247
330
|
if (command === 'init') {
|
|
248
331
|
initCmd();
|
package/commands/init.js
CHANGED
|
@@ -287,13 +287,33 @@ function initAtris() {
|
|
|
287
287
|
|
|
288
288
|
// Create features directory and README
|
|
289
289
|
const featuresDir = path.join(targetDir, 'features');
|
|
290
|
+
const templatesDir = path.join(featuresDir, '_templates');
|
|
291
|
+
|
|
290
292
|
if (!fs.existsSync(featuresDir)) {
|
|
291
293
|
fs.mkdirSync(featuresDir, { recursive: true });
|
|
292
294
|
const featuresReadme = path.join(featuresDir, 'README.md');
|
|
293
|
-
fs.writeFileSync(featuresReadme, '# Features\n\nThis directory tracks all features built using the atrisDev protocol.\n\nEach feature has:\n- `[feature-name]/idea.md` - Problem, solution, diagrams, success criteria\n- `[feature-name]/build.md` - Implementation plan, files changed, testing\n\n---\n\n## Features Built\n\n*Features will appear here as you build them.*\n');
|
|
295
|
+
fs.writeFileSync(featuresReadme, '# Features\n\nThis directory tracks all features built using the atrisDev protocol.\n\nEach feature has:\n- `[feature-name]/idea.md` - Problem, solution, diagrams, success criteria\n- `[feature-name]/build.md` - Implementation plan, files changed, testing\n- `[feature-name]/validate.md` - End-to-end simulation script\n\n---\n\n## Features Built\n\n*Features will appear here as you build them.*\n');
|
|
294
296
|
console.log('✓ Created features/ directory with README');
|
|
295
297
|
}
|
|
296
298
|
|
|
299
|
+
// Create _templates/validate.md.template if not exists
|
|
300
|
+
if (!fs.existsSync(templatesDir)) {
|
|
301
|
+
fs.mkdirSync(templatesDir, { recursive: true });
|
|
302
|
+
}
|
|
303
|
+
const validateTemplateSource = path.join(__dirname, '..', 'atris', 'features', '_templates', 'validate.md.template');
|
|
304
|
+
const validateTemplateTarget = path.join(templatesDir, 'validate.md.template');
|
|
305
|
+
|
|
306
|
+
if (fs.existsSync(validateTemplateSource)) {
|
|
307
|
+
fs.copyFileSync(validateTemplateSource, validateTemplateTarget);
|
|
308
|
+
console.log('✓ Created features/_templates/validate.md.template');
|
|
309
|
+
} else {
|
|
310
|
+
// Fallback if source not found (for safety)
|
|
311
|
+
const fallbackContent = `# Validation — [Feature Name]\n\n> **Role:** System Validation Script\n> **Executor:** Validator Agent\n> **Instructions:** Run these steps sequentially. If ANY step fails, the feature is broken.\n\n---\n\n## 1. Environment Check\n- [ ] **Pre-flight:**\n - Command: \`npm run type-check\` (or relevant)\n - Expect: No errors\n\n## 2. Simulation Steps (The "Real" Test)\n\n### Step 1: [Name]\n- **Action:** [Exact command]\n- **Expect:** [Exact output regex]\n\n---\n\n**Status:** [Pending | Verified]\n`;
|
|
312
|
+
fs.writeFileSync(validateTemplateTarget, fallbackContent);
|
|
313
|
+
console.log('✓ Created features/_templates/validate.md.template (fallback)');
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
|
|
297
317
|
const navigatorSource = path.join(__dirname, '..', 'atris', 'agent_team', 'navigator.md');
|
|
298
318
|
const executorSource = path.join(__dirname, '..', 'atris', 'agent_team', 'executor.md');
|
|
299
319
|
const validatorSource = path.join(__dirname, '..', 'atris', 'agent_team', 'validator.md');
|
package/commands/workflow.js
CHANGED
|
@@ -197,6 +197,10 @@ async function planAtris() {
|
|
|
197
197
|
userPrompt += ` - Add tasks to Backlog section\n`;
|
|
198
198
|
userPrompt += ` - Format: Task number, description, file refs, acceptance criteria\n`;
|
|
199
199
|
userPrompt += ` - Quality over speed - tasks must be perfect for systems player execution\n\n`;
|
|
200
|
+
userPrompt += `STEP 4: Create Validation Artifact (validate.md)\n`;
|
|
201
|
+
userPrompt += ` - You MUST create a validate.md file for the feature.\n`;
|
|
202
|
+
userPrompt += ` - This file acts as the executable simulation script for the Validator.\n`;
|
|
203
|
+
userPrompt += ` - Include verifiable steps (e.g., 'Run curl...', 'Check DB...').\n\n`;
|
|
200
204
|
userPrompt += `Start planning now. Read MAP.md for file references.`;
|
|
201
205
|
|
|
202
206
|
console.log('');
|
|
@@ -608,11 +612,40 @@ async function reviewAtris() {
|
|
|
608
612
|
taskContexts = fs.readFileSync(taskFilePath, 'utf8');
|
|
609
613
|
}
|
|
610
614
|
|
|
611
|
-
// Read journal for timestamp context
|
|
615
|
+
// Read journal for timestamp context (History)
|
|
612
616
|
const { logFile, dateFormatted } = getLogPath();
|
|
613
|
-
let
|
|
617
|
+
let journalHistory = '';
|
|
618
|
+
|
|
619
|
+
// Load today's log
|
|
614
620
|
if (fs.existsSync(logFile)) {
|
|
615
|
-
|
|
621
|
+
journalHistory += `## TODAY (${dateFormatted}):\n` + fs.readFileSync(logFile, 'utf8') + '\n\n';
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
// Load previous 3 days of logs for Drift Detection
|
|
625
|
+
// (We need to find them in the logs directory)
|
|
626
|
+
const targetLogsDir = path.join(targetDir, 'logs');
|
|
627
|
+
if (fs.existsSync(targetLogsDir)) {
|
|
628
|
+
// Simple recursive search for last 3 .md files
|
|
629
|
+
const allLogs = [];
|
|
630
|
+
const yearDirs = fs.readdirSync(targetLogsDir).filter(d => /^\d{4}$/.test(d));
|
|
631
|
+
for (const year of yearDirs) {
|
|
632
|
+
const yearPath = path.join(targetLogsDir, year);
|
|
633
|
+
if (fs.statSync(yearPath).isDirectory()) {
|
|
634
|
+
const files = fs.readdirSync(yearPath).filter(f => f.endsWith('.md') && f !== path.basename(logFile));
|
|
635
|
+
files.forEach(f => allLogs.push(path.join(yearPath, f)));
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
// Sort desc, take top 3
|
|
639
|
+
allLogs.sort().reverse();
|
|
640
|
+
const recentLogs = allLogs.slice(0, 3);
|
|
641
|
+
|
|
642
|
+
if (recentLogs.length > 0) {
|
|
643
|
+
journalHistory += `## RECENT HISTORY (Drift Check):\n`;
|
|
644
|
+
for (const log of recentLogs) {
|
|
645
|
+
journalHistory += `--- ${path.basename(log)} ---\n`;
|
|
646
|
+
journalHistory += fs.readFileSync(log, 'utf8').substring(0, 1000) + '\n... (truncated)\n\n'; // Read first 1kb
|
|
647
|
+
}
|
|
648
|
+
}
|
|
616
649
|
}
|
|
617
650
|
|
|
618
651
|
const mapFile = path.join(targetDir, 'MAP.md');
|
|
@@ -648,7 +681,9 @@ async function reviewAtris() {
|
|
|
648
681
|
console.log('');
|
|
649
682
|
console.log('─────────────────────────────────────────────────────────────');
|
|
650
683
|
console.log('');
|
|
651
|
-
console.log('📅 JOURNAL
|
|
684
|
+
console.log('📅 JOURNAL HISTORY (Drift Detection):');
|
|
685
|
+
console.log(' Reading past logs to check for recurring friction...');
|
|
686
|
+
// We don't print the full history to console to avoid noise, but it's in the prompt
|
|
652
687
|
console.log('');
|
|
653
688
|
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
654
689
|
console.log('📋 INSTRUCTION PROMPT FOR YOUR CODING AGENT:');
|
|
@@ -660,8 +695,9 @@ async function reviewAtris() {
|
|
|
660
695
|
console.log(' 1. Ultrathink (say "ultrathink", think 3 times)');
|
|
661
696
|
console.log(' 2. Check requirements → build → edge cases → errors → integration');
|
|
662
697
|
console.log(' 3. Run tests (unit, integration, linting, type checking)');
|
|
663
|
-
console.log(' 4.
|
|
664
|
-
console.log(' 5.
|
|
698
|
+
console.log(' 4. Detect Drift (check recent logs for repeated struggle)');
|
|
699
|
+
console.log(' 5. If issues found: report → "atris do" fixes → "atris review" again');
|
|
700
|
+
console.log(' 6. Repeat until: "✅ All good. Ready for human testing."');
|
|
665
701
|
console.log('');
|
|
666
702
|
console.log('Your job:');
|
|
667
703
|
console.log(' • Verify everything works');
|
|
@@ -669,7 +705,7 @@ async function reviewAtris() {
|
|
|
669
705
|
console.log(' • Update docs if needed');
|
|
670
706
|
console.log(' • Clean TODO.md (move completed tasks)');
|
|
671
707
|
console.log(' • Extract learnings for journal');
|
|
672
|
-
console.log(' •
|
|
708
|
+
console.log(' • PROPOSE TOOLS if you see repetition (Evolution)');
|
|
673
709
|
console.log('');
|
|
674
710
|
console.log('The cycle: do → review → [issues] → do → review → ✅ Ready');
|
|
675
711
|
console.log('');
|
|
@@ -711,12 +747,17 @@ async function reviewAtris() {
|
|
|
711
747
|
userPrompt += ` 1. Ultrathink (say "ultrathink", think 3 times)\n`;
|
|
712
748
|
userPrompt += ` 2. Check requirements → build → edge cases → errors → integration\n`;
|
|
713
749
|
userPrompt += ` 3. Run tests (unit, integration, linting, type checking)\n`;
|
|
714
|
-
userPrompt += ` 4.
|
|
715
|
-
userPrompt += ` 5.
|
|
750
|
+
userPrompt += ` 4. Detect Drift: Scan the Journal History below. Do you see the same friction 2x?\n`;
|
|
751
|
+
userPrompt += ` 5. If issues found: report → "atris do" fixes → "atris review" again\n`;
|
|
752
|
+
userPrompt += ` 6. Repeat until: "✅ All good. Ready for human testing."\n\n`;
|
|
716
753
|
|
|
717
754
|
if (taskContexts) {
|
|
718
755
|
userPrompt += `## TODO.md:\n${taskContexts}\n\n`;
|
|
719
756
|
}
|
|
757
|
+
|
|
758
|
+
if (journalHistory) {
|
|
759
|
+
userPrompt += `## JOURNAL HISTORY (For Evolution/Drift Check):\n${journalHistory}\n\n`;
|
|
760
|
+
}
|
|
720
761
|
|
|
721
762
|
userPrompt += `Your job:\n`;
|
|
722
763
|
userPrompt += ` • Verify everything works\n`;
|
|
@@ -724,7 +765,7 @@ async function reviewAtris() {
|
|
|
724
765
|
userPrompt += ` • Update docs if needed (MAP.md, TODO.md)\n`;
|
|
725
766
|
userPrompt += ` • Clean TODO.md (move completed tasks to Completed section, then delete)\n`;
|
|
726
767
|
userPrompt += ` • Extract learnings for journal\n`;
|
|
727
|
-
userPrompt += ` •
|
|
768
|
+
userPrompt += ` • EVOLUTION: If you see drift in the logs, propose a tool upgrade.\n\n`;
|
|
728
769
|
userPrompt += `The cycle: do → review → [issues] → do → review → ✅ Ready\n`;
|
|
729
770
|
userPrompt += `Start validating now. Read files, run tests, verify implementation.`;
|
|
730
771
|
|