atris 1.5.3 → 1.5.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 +2 -2
- package/commands/auth.js +134 -0
- package/commands/brainstorm.js +180 -0
- package/commands/init.js +104 -0
- package/commands/log-sync.js +261 -0
- package/commands/log.js +56 -0
- package/commands/stubs.txt +10 -0
- package/commands/sync.js +60 -0
- package/commands/version.js +16 -0
- package/lib/file-ops.js +289 -0
- package/lib/journal.js +172 -0
- package/package.json +4 -1
- package/utils/api.js +299 -0
- package/utils/auth.js +382 -0
- package/utils/config.js +66 -0
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ See [`ENGINEERING_CYCLE.md`](./ENGINEERING_CYCLE.md) for the full vision.
|
|
|
10
10
|
atris init → atris brainstorm → atris plan → atris do → atris review → atris launch
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Each command provides clear instruction prompts for your coding agent (
|
|
13
|
+
Each command provides clear instruction prompts for your coding agent (Cursor, Claude, etc.).
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
@@ -79,7 +79,7 @@ Need a structured prompt for an agent-led ideation session?
|
|
|
79
79
|
atris brainstorm
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
Answer a couple quick questions, get a ready-to-send conversation opener for
|
|
82
|
+
Answer a couple quick questions, get a ready-to-send conversation opener for your coding agent (with context + ASCII cue), and optionally log the session summary plus next steps.
|
|
83
83
|
|
|
84
84
|
---
|
|
85
85
|
|
package/commands/auth.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
const { loadCredentials, saveCredentials, deleteCredentials, getCredentialsPath, openBrowser, promptUser, displayAccountSummary } = require('../utils/auth');
|
|
2
|
+
const { getAppBaseUrl, apiRequestJson } = require('../utils/api');
|
|
3
|
+
|
|
4
|
+
async function loginAtris() {
|
|
5
|
+
|
|
6
|
+
try {
|
|
7
|
+
console.log('🔐 Login to AtrisOS\n');
|
|
8
|
+
|
|
9
|
+
const existing = loadCredentials();
|
|
10
|
+
if (existing) {
|
|
11
|
+
const label = existing.email || existing.user_id || 'unknown user';
|
|
12
|
+
console.log(`Already logged in as: ${label}`);
|
|
13
|
+
const confirm = await promptUser('Do you want to login again? (y/N): ');
|
|
14
|
+
if (confirm.toLowerCase() !== 'y') {
|
|
15
|
+
console.log('Login cancelled.');
|
|
16
|
+
process.exit(0);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
console.log('Choose login method:');
|
|
21
|
+
console.log(' 1. Browser OAuth (recommended)');
|
|
22
|
+
console.log(' 2. Paste existing API token');
|
|
23
|
+
console.log(' 3. Cancel');
|
|
24
|
+
|
|
25
|
+
const choice = await promptUser('\nEnter choice (1-3): ');
|
|
26
|
+
|
|
27
|
+
if (choice === '1') {
|
|
28
|
+
const loginUrl = `${getAppBaseUrl()}/auth/cli`;
|
|
29
|
+
console.log('\n🌐 Opening browser for OAuth login…');
|
|
30
|
+
console.log('If it does not open automatically, visit:');
|
|
31
|
+
console.log(loginUrl);
|
|
32
|
+
console.log('\nAfter signing in, copy the CLI code shown in the browser and paste it below.');
|
|
33
|
+
console.log('Codes expire after five minutes.\n');
|
|
34
|
+
|
|
35
|
+
openBrowser(loginUrl);
|
|
36
|
+
|
|
37
|
+
const code = await promptUser('Paste the CLI code here: ');
|
|
38
|
+
if (!code) {
|
|
39
|
+
console.error('✗ Error: Code is required');
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const exchange = await apiRequestJson('/auth/cli/exchange', {
|
|
44
|
+
method: 'POST',
|
|
45
|
+
body: { code: code.trim() },
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
if (!exchange.ok || !exchange.data) {
|
|
49
|
+
console.error(`✗ Error: ${exchange.error || 'Invalid or expired code'}`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const payload = exchange.data;
|
|
54
|
+
const token = payload.token;
|
|
55
|
+
const refreshToken = payload.refresh_token;
|
|
56
|
+
|
|
57
|
+
if (!token || !refreshToken) {
|
|
58
|
+
console.error('✗ Error: Backend did not return tokens. Please try again.');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const email = payload.email || existing?.email || null;
|
|
63
|
+
const userId = payload.user_id || existing?.user_id || null;
|
|
64
|
+
const provider = payload.provider || 'atris';
|
|
65
|
+
|
|
66
|
+
saveCredentials(token, refreshToken, email, userId, provider);
|
|
67
|
+
console.log('\n✓ Successfully logged in!');
|
|
68
|
+
await displayAccountSummary(apiRequestJson);
|
|
69
|
+
console.log('\nYou can now use cloud features with atris commands.');
|
|
70
|
+
process.exit(0);
|
|
71
|
+
} else if (choice === '2') {
|
|
72
|
+
console.log('\n📋 Manual Token Entry');
|
|
73
|
+
console.log('Get your token from: https://app.atris.ai/settings/api\n');
|
|
74
|
+
|
|
75
|
+
const tokenInput = await promptUser('Paste your API token: ');
|
|
76
|
+
|
|
77
|
+
if (!tokenInput) {
|
|
78
|
+
console.error('✗ Error: Token is required');
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const trimmed = tokenInput.trim();
|
|
83
|
+
saveCredentials(trimmed, null, existing?.email || null, existing?.user_id || null, existing?.provider || 'manual');
|
|
84
|
+
console.log('\nAttempting to validate token…\n');
|
|
85
|
+
|
|
86
|
+
const summary = await displayAccountSummary(apiRequestJson);
|
|
87
|
+
if (summary.error) {
|
|
88
|
+
console.log('\n⚠️ Token saved, but validation failed. You may need to relogin.');
|
|
89
|
+
} else {
|
|
90
|
+
console.log('\n✓ Token validated successfully.');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
console.log('\nYou can now use cloud features with atris commands.');
|
|
94
|
+
process.exit(0);
|
|
95
|
+
} else {
|
|
96
|
+
console.log('Login cancelled.');
|
|
97
|
+
process.exit(0);
|
|
98
|
+
}
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.error(`\n✗ Login failed: ${error.message || error}`);
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function logoutAtris() {
|
|
106
|
+
const credentials = loadCredentials();
|
|
107
|
+
|
|
108
|
+
if (!credentials) {
|
|
109
|
+
console.log('Not currently logged in.');
|
|
110
|
+
process.exit(0);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
deleteCredentials();
|
|
114
|
+
console.log('✓ Successfully logged out');
|
|
115
|
+
console.log(`✓ Removed credentials from ${getCredentialsPath()}`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async function whoamiAtris() {
|
|
119
|
+
const { apiRequestJson } = require('../utils/api');
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
const summary = await displayAccountSummary(apiRequestJson);
|
|
123
|
+
if (summary.error) {
|
|
124
|
+
console.log('\nRun "atris login" to authenticate with AtrisOS.');
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
process.exit(0);
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error(`✗ Failed to fetch account details: ${error.message || error}`);
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
module.exports = { loginAtris, logoutAtris, whoamiAtris };
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { getLogPath, ensureLogDirectory, createLogFile, parseInboxItems, addInboxIdea, removeInboxItemFromContent, recordBrainstormSession } = require('../lib/file-ops');
|
|
4
|
+
const { loadConfig } = require('../utils/config');
|
|
5
|
+
const { loadCredentials } = require('../utils/auth');
|
|
6
|
+
const { apiRequestJson } = require('../utils/api');
|
|
7
|
+
|
|
8
|
+
function brainstormAbortError() {
|
|
9
|
+
const error = new Error('Brainstorm cancelled by user.');
|
|
10
|
+
error.__brainstormAbort = true;
|
|
11
|
+
return error;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async function brainstormAtris() {
|
|
15
|
+
// Check for args: atris brainstorm "topic" --outcome "..." --vibe "..." --constraints "..."
|
|
16
|
+
const args = process.argv.slice(3);
|
|
17
|
+
let topicArg = null;
|
|
18
|
+
let outcomeArg = null;
|
|
19
|
+
let vibeArg = null;
|
|
20
|
+
let constraintsArg = null;
|
|
21
|
+
|
|
22
|
+
for (let i = 0; i < args.length; i++) {
|
|
23
|
+
if (args[i] === '--outcome' && args[i + 1]) {
|
|
24
|
+
outcomeArg = args[i + 1];
|
|
25
|
+
i++;
|
|
26
|
+
} else if (args[i] === '--vibe' && args[i + 1]) {
|
|
27
|
+
vibeArg = args[i + 1];
|
|
28
|
+
i++;
|
|
29
|
+
} else if (args[i] === '--constraints' && args[i + 1]) {
|
|
30
|
+
constraintsArg = args[i + 1];
|
|
31
|
+
i++;
|
|
32
|
+
} else if (!args[i].startsWith('--') && !topicArg) {
|
|
33
|
+
topicArg = args[i];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const targetDir = path.join(process.cwd(), 'atris');
|
|
37
|
+
if (!fs.existsSync(targetDir)) {
|
|
38
|
+
throw new Error('atris/ folder not found. Run "atris init" first.');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
ensureLogDirectory();
|
|
42
|
+
const { logFile, dateFormatted } = getLogPath();
|
|
43
|
+
if (!fs.existsSync(logFile)) {
|
|
44
|
+
createLogFile(logFile, dateFormatted);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Show current stats for game-like feel
|
|
48
|
+
let todayStats = { completions: 0, inbox: 0 };
|
|
49
|
+
if (fs.existsSync(logFile)) {
|
|
50
|
+
const logContent = fs.readFileSync(logFile, 'utf8');
|
|
51
|
+
const completionMatches = logContent.match(/- \*\*C\d+:/g);
|
|
52
|
+
todayStats.completions = completionMatches ? completionMatches.length : 0;
|
|
53
|
+
const inboxMatch = logContent.match(/## Inbox\n([\s\S]*?)(?=\n##|---)/);
|
|
54
|
+
if (inboxMatch && inboxMatch[1].trim()) {
|
|
55
|
+
const inboxMatches = inboxMatch[1].match(/- \*\*I\d+:/g);
|
|
56
|
+
todayStats.inbox = inboxMatches ? inboxMatches.length : 0;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
console.log('');
|
|
61
|
+
console.log('┌─────────────────────────────────────────────────────────────┐');
|
|
62
|
+
console.log('│ ATRIS Brainstorm — structured prompt generator │');
|
|
63
|
+
console.log('└─────────────────────────────────────────────────────────────┘');
|
|
64
|
+
console.log('');
|
|
65
|
+
console.log(`📅 Date: ${dateFormatted}`);
|
|
66
|
+
console.log(`📊 Today: ${todayStats.completions} completions | ${todayStats.inbox} inbox items`);
|
|
67
|
+
console.log('💡 Type "exit" at any prompt to cancel.');
|
|
68
|
+
console.log('');
|
|
69
|
+
|
|
70
|
+
// Try to fetch latest journal entry from backend (optional)
|
|
71
|
+
let journalContext = '';
|
|
72
|
+
const config = loadConfig();
|
|
73
|
+
const credentials = loadCredentials();
|
|
74
|
+
|
|
75
|
+
if (config.agent_id && credentials && credentials.token) {
|
|
76
|
+
try {
|
|
77
|
+
console.log('📖 Fetching latest journal entry from AtrisOS...');
|
|
78
|
+
const journalResult = await apiRequestJson(`/agents/${config.agent_id}/journal/today`, {
|
|
79
|
+
method: 'GET',
|
|
80
|
+
token: credentials.token,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
if (journalResult.ok && journalResult.data?.content) {
|
|
84
|
+
journalContext = journalResult.data.content;
|
|
85
|
+
console.log('✓ Loaded journal entry from backend');
|
|
86
|
+
} else {
|
|
87
|
+
const listResult = await apiRequestJson(`/agents/${config.agent_id}/journal/?limit=1`, {
|
|
88
|
+
method: 'GET',
|
|
89
|
+
token: credentials.token,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
if (listResult.ok && listResult.data?.entries?.length > 0) {
|
|
93
|
+
journalContext = listResult.data.entries[0].content || '';
|
|
94
|
+
console.log('✓ Loaded latest journal entry from backend');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
} catch (error) {
|
|
98
|
+
console.log('ℹ️ Using local journal file (backend unavailable)');
|
|
99
|
+
}
|
|
100
|
+
console.log('');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Fallback to local log file if no backend context
|
|
104
|
+
if (!journalContext) {
|
|
105
|
+
if (fs.existsSync(logFile)) {
|
|
106
|
+
journalContext = fs.readFileSync(logFile, 'utf8');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Determine topic and inputs
|
|
111
|
+
let selectedInboxItem = null;
|
|
112
|
+
let topicSummary = topicArg || '';
|
|
113
|
+
let userStory = outcomeArg || '';
|
|
114
|
+
let feelingsVibe = vibeArg || '';
|
|
115
|
+
let constraints = constraintsArg || '';
|
|
116
|
+
|
|
117
|
+
// If no args provided, use inbox or prompt user
|
|
118
|
+
if (!topicArg) {
|
|
119
|
+
const initialContent = journalContext || (fs.existsSync(logFile) ? fs.readFileSync(logFile, 'utf8') : '');
|
|
120
|
+
let inboxItems = parseInboxItems(initialContent);
|
|
121
|
+
|
|
122
|
+
if (inboxItems.length > 0) {
|
|
123
|
+
// Use first inbox item if available
|
|
124
|
+
selectedInboxItem = inboxItems[0];
|
|
125
|
+
topicSummary = selectedInboxItem.text;
|
|
126
|
+
console.log(`📌 Using inbox item I${selectedInboxItem.id}: ${topicSummary}`);
|
|
127
|
+
} else {
|
|
128
|
+
throw new Error('No topic provided. Usage: atris brainstorm "topic" [--outcome "..."] [--vibe "..."] [--constraints "..."]');
|
|
129
|
+
}
|
|
130
|
+
} else {
|
|
131
|
+
// Add new idea to inbox
|
|
132
|
+
const newId = addInboxIdea(logFile, topicSummary);
|
|
133
|
+
selectedInboxItem = { id: newId, text: topicSummary };
|
|
134
|
+
console.log(`✓ Added I${newId} to today's Inbox.`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const sourceLabel = selectedInboxItem ? `I${selectedInboxItem.id}` : 'Ad-hoc';
|
|
138
|
+
|
|
139
|
+
// Build the brainstorm message (structured for AI to read)
|
|
140
|
+
const brainstormMessage = [
|
|
141
|
+
`I want to brainstorm: ${topicSummary}`,
|
|
142
|
+
'',
|
|
143
|
+
userStory ? `The outcome should be: ${userStory}` : '',
|
|
144
|
+
feelingsVibe ? `Vibe we're going for: ${feelingsVibe}` : '',
|
|
145
|
+
journalContext ? `Recent context from journal:\n${journalContext.substring(0, 500)}${journalContext.length > 500 ? '...' : ''}` : '',
|
|
146
|
+
constraints ? `Constraints: ${constraints}` : '',
|
|
147
|
+
'',
|
|
148
|
+
'Help me uncover what we need to build. Keep responses short (4-5 sentences), pause for alignment, sketch ASCII when structure helps.',
|
|
149
|
+
].filter(line => line !== '').join('\n');
|
|
150
|
+
|
|
151
|
+
console.log('');
|
|
152
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
153
|
+
console.log('🧠 BRAINSTORM SESSION READY');
|
|
154
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
155
|
+
console.log('');
|
|
156
|
+
console.log('📝 INSTRUCTIONS FOR YOUR CODING AGENT:');
|
|
157
|
+
console.log('');
|
|
158
|
+
console.log('ACTION REQUIRED: Start brainstorming with the user NOW. Then execute CLI commands as needed.');
|
|
159
|
+
console.log('');
|
|
160
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
161
|
+
console.log('');
|
|
162
|
+
console.log('BRAINSTORM PROMPT:');
|
|
163
|
+
console.log(brainstormMessage);
|
|
164
|
+
console.log('');
|
|
165
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
166
|
+
console.log('');
|
|
167
|
+
console.log('⚠️ CRITICAL: You MUST execute CLI commands, not just discuss them!');
|
|
168
|
+
console.log('');
|
|
169
|
+
console.log('After brainstorming, execute:');
|
|
170
|
+
console.log(' 1. `atris plan` - to break ideas into tasks');
|
|
171
|
+
console.log(' 2. `atris do` - to execute the tasks');
|
|
172
|
+
console.log(' 3. `atris review` - to validate');
|
|
173
|
+
console.log(' 4. `atris launch` - to ship');
|
|
174
|
+
console.log('');
|
|
175
|
+
console.log('Use your terminal tool to run these commands. Do not just talk about them!');
|
|
176
|
+
console.log('');
|
|
177
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
module.exports = { brainstormAtris };
|
package/commands/init.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
function initAtris() {
|
|
5
|
+
const targetDir = path.join(process.cwd(), 'atris');
|
|
6
|
+
const agentTeamDir = path.join(targetDir, 'agent_team');
|
|
7
|
+
const sourceFile = path.join(__dirname, '..', 'atris.md');
|
|
8
|
+
const targetFile = path.join(targetDir, 'atris.md');
|
|
9
|
+
|
|
10
|
+
if (!fs.existsSync(targetDir)) {
|
|
11
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
12
|
+
console.log('✓ Created atris/ folder');
|
|
13
|
+
} else {
|
|
14
|
+
console.log('✓ atris/ folder already exists');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (!fs.existsSync(agentTeamDir)) {
|
|
18
|
+
fs.mkdirSync(agentTeamDir, { recursive: true });
|
|
19
|
+
console.log('✓ Created atris/agent_team/ folder');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const gettingStartedFile = path.join(targetDir, 'GETTING_STARTED.md');
|
|
23
|
+
const personaFile = path.join(targetDir, 'PERSONA.md');
|
|
24
|
+
const mapFile = path.join(targetDir, 'MAP.md');
|
|
25
|
+
const taskContextsFile = path.join(targetDir, 'TASK_CONTEXTS.md');
|
|
26
|
+
const navigatorFile = path.join(agentTeamDir, 'navigator.md');
|
|
27
|
+
const executorFile = path.join(agentTeamDir, 'executor.md');
|
|
28
|
+
const validatorFile = path.join(agentTeamDir, 'validator.md');
|
|
29
|
+
const launcherFile = path.join(agentTeamDir, 'launcher.md');
|
|
30
|
+
|
|
31
|
+
const gettingStartedSource = path.join(__dirname, '..', 'GETTING_STARTED.md');
|
|
32
|
+
const personaSource = path.join(__dirname, '..', 'PERSONA.md');
|
|
33
|
+
|
|
34
|
+
if (!fs.existsSync(gettingStartedFile) && fs.existsSync(gettingStartedSource)) {
|
|
35
|
+
fs.copyFileSync(gettingStartedSource, gettingStartedFile);
|
|
36
|
+
console.log('✓ Created GETTING_STARTED.md');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!fs.existsSync(personaFile) && fs.existsSync(personaSource)) {
|
|
40
|
+
fs.copyFileSync(personaSource, personaFile);
|
|
41
|
+
console.log('✓ Created PERSONA.md');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!fs.existsSync(mapFile)) {
|
|
45
|
+
fs.writeFileSync(mapFile, '# MAP.md\n\n> Generated by your AI agent after reading atris.md\n\nRun your AI agent with atris.md to populate this file.\n');
|
|
46
|
+
console.log('✓ Created MAP.md placeholder');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!fs.existsSync(taskContextsFile)) {
|
|
50
|
+
fs.writeFileSync(taskContextsFile, '# TASK_CONTEXTS.md\n\n> Generated by your AI agent after reading atris.md\n\nRun your AI agent with atris.md to populate this file.\n');
|
|
51
|
+
console.log('✓ Created TASK_CONTEXTS.md placeholder');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const navigatorSource = path.join(__dirname, '..', 'atris', 'agent_team', 'navigator.md');
|
|
55
|
+
const executorSource = path.join(__dirname, '..', 'atris', 'agent_team', 'executor.md');
|
|
56
|
+
const validatorSource = path.join(__dirname, '..', 'atris', 'agent_team', 'validator.md');
|
|
57
|
+
const launcherSource = path.join(__dirname, '..', 'atris', 'agent_team', 'launcher.md');
|
|
58
|
+
|
|
59
|
+
if (!fs.existsSync(navigatorFile) && fs.existsSync(navigatorSource)) {
|
|
60
|
+
fs.copyFileSync(navigatorSource, navigatorFile);
|
|
61
|
+
console.log('✓ Created agent_team/navigator.md');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!fs.existsSync(executorFile) && fs.existsSync(executorSource)) {
|
|
65
|
+
fs.copyFileSync(executorSource, executorFile);
|
|
66
|
+
console.log('✓ Created agent_team/executor.md');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!fs.existsSync(validatorFile) && fs.existsSync(validatorSource)) {
|
|
70
|
+
fs.copyFileSync(validatorSource, validatorFile);
|
|
71
|
+
console.log('✓ Created agent_team/validator.md');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!fs.existsSync(launcherFile) && fs.existsSync(launcherSource)) {
|
|
75
|
+
fs.copyFileSync(launcherSource, launcherFile);
|
|
76
|
+
console.log('✓ Created agent_team/launcher.md');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (fs.existsSync(sourceFile)) {
|
|
80
|
+
fs.copyFileSync(sourceFile, targetFile);
|
|
81
|
+
console.log('✓ Copied atris.md to atris/ folder');
|
|
82
|
+
console.log('\n✨ ATRIS initialized! Full structure created:');
|
|
83
|
+
console.log(' atris/');
|
|
84
|
+
console.log(' ├── GETTING_STARTED.md (read this first!)');
|
|
85
|
+
console.log(' ├── PERSONA.md (agent personality)');
|
|
86
|
+
console.log(' ├── atris.md (AI agent instructions)');
|
|
87
|
+
console.log(' ├── MAP.md (placeholder)');
|
|
88
|
+
console.log(' ├── TASK_CONTEXTS.md (placeholder)');
|
|
89
|
+
console.log(' └── agent_team/');
|
|
90
|
+
console.log(' ├── navigator.md (placeholder)');
|
|
91
|
+
console.log(' ├── executor.md (placeholder)');
|
|
92
|
+
console.log(' ├── validator.md (placeholder)');
|
|
93
|
+
console.log(' └── launcher.md (placeholder)');
|
|
94
|
+
console.log('\nNext steps:');
|
|
95
|
+
console.log('1. Read atris/GETTING_STARTED.md for the full guide');
|
|
96
|
+
console.log('2. Open atris/atris.md and paste it to your AI agent');
|
|
97
|
+
console.log('3. Your agent will populate all placeholder files in ~10 mins');
|
|
98
|
+
} else {
|
|
99
|
+
console.error('✗ Error: atris.md not found in package');
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
module.exports = { initAtris };
|