@struere/cli 0.2.7 → 0.2.9
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/dist/commands/deploy.js +6 -6
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +166 -267
- package/dist/commands/dev.js.map +1 -1
- package/dist/index.js +154 -259
- package/dist/utils/api.d.ts +33 -3
- package/dist/utils/api.d.ts.map +1 -1
- package/dist/utils/api.js.map +1 -1
- package/package.json +1 -1
package/dist/commands/deploy.js
CHANGED
|
@@ -9,10 +9,10 @@ import { loadCredentials, getApiKey } from '../utils/credentials';
|
|
|
9
9
|
import { ApiClient, ApiError } from '../utils/api';
|
|
10
10
|
import { hasProject, loadProject } from '../utils/project';
|
|
11
11
|
export const deployCommand = new Command('deploy')
|
|
12
|
-
.description('Deploy agent to
|
|
13
|
-
.option('-e, --env <environment>', 'Target environment (preview, staging, production)', 'preview')
|
|
12
|
+
.description('Deploy agent to production')
|
|
14
13
|
.option('--dry-run', 'Show what would be deployed without deploying')
|
|
15
14
|
.action(async (options) => {
|
|
15
|
+
const environment = 'production';
|
|
16
16
|
const spinner = ora();
|
|
17
17
|
const cwd = process.cwd();
|
|
18
18
|
console.log();
|
|
@@ -57,7 +57,7 @@ export const deployCommand = new Command('deploy')
|
|
|
57
57
|
console.log('Would deploy:');
|
|
58
58
|
console.log(chalk.gray(' -'), `Agent: ${chalk.cyan(agent.name)}`);
|
|
59
59
|
console.log(chalk.gray(' -'), `Version: ${chalk.cyan(agent.version)}`);
|
|
60
|
-
console.log(chalk.gray(' -'), `Environment: ${chalk.cyan(
|
|
60
|
+
console.log(chalk.gray(' -'), `Environment: ${chalk.cyan(environment)}`);
|
|
61
61
|
console.log(chalk.gray(' -'), `Agent ID: ${chalk.cyan(project.agentId)}`);
|
|
62
62
|
console.log();
|
|
63
63
|
return;
|
|
@@ -89,13 +89,13 @@ export const deployCommand = new Command('deploy')
|
|
|
89
89
|
}
|
|
90
90
|
const bundle = await result.outputs[0].text();
|
|
91
91
|
spinner.succeed(`Bundle created (${formatBytes(bundle.length)})`);
|
|
92
|
-
spinner.start(`Deploying to ${
|
|
92
|
+
spinner.start(`Deploying to ${environment}`);
|
|
93
93
|
try {
|
|
94
94
|
const api = new ApiClient();
|
|
95
95
|
const { deployment } = await api.deployAgent(project.agentId, {
|
|
96
96
|
bundle,
|
|
97
97
|
version: agent.version,
|
|
98
|
-
environment:
|
|
98
|
+
environment: environment,
|
|
99
99
|
metadata: {
|
|
100
100
|
modelProvider: agent.model?.provider || 'anthropic',
|
|
101
101
|
modelName: agent.model?.name || 'claude-sonnet-4-20250514',
|
|
@@ -103,7 +103,7 @@ export const deployCommand = new Command('deploy')
|
|
|
103
103
|
bundleSize: bundle.length
|
|
104
104
|
}
|
|
105
105
|
});
|
|
106
|
-
spinner.succeed(`Deployed to ${
|
|
106
|
+
spinner.succeed(`Deployed to ${environment}`);
|
|
107
107
|
console.log();
|
|
108
108
|
console.log(chalk.green('Success!'), 'Agent deployed');
|
|
109
109
|
console.log();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AACjE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE1D,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAYnC,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAYnC,eAAO,MAAM,UAAU,SAqKnB,CAAA"}
|
package/dist/commands/dev.js
CHANGED
|
@@ -2,32 +2,32 @@ import { Command } from 'commander';
|
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import ora from 'ora';
|
|
4
4
|
import chokidar from 'chokidar';
|
|
5
|
-
import { join } from 'path';
|
|
5
|
+
import { join, basename } from 'path';
|
|
6
6
|
import { loadConfig } from '../utils/config';
|
|
7
7
|
import { loadAgent } from '../utils/agent';
|
|
8
8
|
import { loadCredentials, getApiKey } from '../utils/credentials';
|
|
9
|
-
import { getSyncUrl } from '../utils/api';
|
|
10
|
-
import { hasProject, loadProject } from '../utils/project';
|
|
9
|
+
import { ApiClient, ApiError, getSyncUrl } from '../utils/api';
|
|
10
|
+
import { hasProject, loadProject, saveProject } from '../utils/project';
|
|
11
|
+
import { performLogin } from './login';
|
|
11
12
|
export const devCommand = new Command('dev')
|
|
12
|
-
.description('
|
|
13
|
-
.
|
|
14
|
-
.option('-c, --channel <channel>', 'Channel to open (web, api)', 'web')
|
|
15
|
-
.option('--no-open', 'Do not open browser')
|
|
16
|
-
.option('--local', 'Run locally without cloud sync')
|
|
17
|
-
.action(async (options) => {
|
|
13
|
+
.description('Sync agent to development environment')
|
|
14
|
+
.action(async () => {
|
|
18
15
|
const spinner = ora();
|
|
19
16
|
const cwd = process.cwd();
|
|
20
17
|
console.log();
|
|
21
|
-
console.log(chalk.bold('Struere Dev
|
|
18
|
+
console.log(chalk.bold('Struere Dev'));
|
|
22
19
|
console.log();
|
|
20
|
+
let project = loadProject(cwd);
|
|
23
21
|
if (!hasProject(cwd)) {
|
|
24
22
|
console.log(chalk.yellow('No struere.json found'));
|
|
25
23
|
console.log();
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
const setupResult = await interactiveSetup(cwd);
|
|
25
|
+
if (!setupResult) {
|
|
26
|
+
process.exit(0);
|
|
27
|
+
}
|
|
28
|
+
project = setupResult;
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
project = loadProject(cwd);
|
|
31
31
|
if (!project) {
|
|
32
32
|
console.log(chalk.red('Failed to load struere.json'));
|
|
33
33
|
process.exit(1);
|
|
@@ -35,8 +35,7 @@ export const devCommand = new Command('dev')
|
|
|
35
35
|
console.log(chalk.gray('Agent:'), chalk.cyan(project.agent.name));
|
|
36
36
|
console.log();
|
|
37
37
|
spinner.start('Loading configuration');
|
|
38
|
-
|
|
39
|
-
const port = parseInt(options.port) || config.port || 3000;
|
|
38
|
+
await loadConfig(cwd);
|
|
40
39
|
spinner.succeed('Configuration loaded');
|
|
41
40
|
spinner.start('Loading agent');
|
|
42
41
|
let agent = await loadAgent(cwd);
|
|
@@ -50,16 +49,10 @@ export const devCommand = new Command('dev')
|
|
|
50
49
|
console.log();
|
|
51
50
|
process.exit(1);
|
|
52
51
|
}
|
|
53
|
-
await runCloudDev(agent, project, cwd, port, options, spinner);
|
|
54
|
-
});
|
|
55
|
-
async function runCloudDev(agent, project, cwd, port, options, spinner) {
|
|
56
|
-
const credentials = loadCredentials();
|
|
57
|
-
const apiKey = getApiKey();
|
|
58
52
|
spinner.start('Connecting to Struere Cloud');
|
|
59
53
|
const syncUrl = getSyncUrl();
|
|
60
54
|
const ws = new WebSocket(`${syncUrl}/v1/dev/sync`);
|
|
61
55
|
let cloudUrl = null;
|
|
62
|
-
let sessionId = null;
|
|
63
56
|
let isConnected = false;
|
|
64
57
|
ws.onopen = () => {
|
|
65
58
|
ws.send(JSON.stringify({
|
|
@@ -85,26 +78,22 @@ async function runCloudDev(agent, project, cwd, port, options, spinner) {
|
|
|
85
78
|
case 'synced':
|
|
86
79
|
isConnected = true;
|
|
87
80
|
cloudUrl = data.url || null;
|
|
88
|
-
|
|
89
|
-
spinner.succeed('Connected to Struere Cloud');
|
|
81
|
+
spinner.succeed('Synced to development');
|
|
90
82
|
console.log();
|
|
91
|
-
console.log(chalk.
|
|
92
|
-
console.log(
|
|
93
|
-
console.log(chalk.
|
|
83
|
+
console.log(chalk.green('Development URL:'), chalk.cyan(cloudUrl));
|
|
84
|
+
console.log();
|
|
85
|
+
console.log(chalk.gray('Watching for changes... Press Ctrl+C to stop'));
|
|
94
86
|
console.log();
|
|
95
|
-
spinner.start('Watching for changes');
|
|
96
87
|
break;
|
|
97
88
|
case 'log':
|
|
98
89
|
const logColor = data.level === 'error' ? chalk.red
|
|
99
90
|
: data.level === 'warn' ? chalk.yellow
|
|
100
91
|
: data.level === 'debug' ? chalk.gray
|
|
101
92
|
: chalk.blue;
|
|
102
|
-
spinner.stop();
|
|
103
93
|
console.log(logColor(`[${data.level}]`), data.message);
|
|
104
|
-
spinner.start('Watching for changes');
|
|
105
94
|
break;
|
|
106
95
|
case 'error':
|
|
107
|
-
spinner.fail(`
|
|
96
|
+
spinner.fail(`Error: ${data.message}`);
|
|
108
97
|
if (data.code === 'INVALID_API_KEY' || data.code === 'NOT_AUTHENTICATED') {
|
|
109
98
|
console.log();
|
|
110
99
|
console.log(chalk.gray('Run'), chalk.cyan('struere login'), chalk.gray('to authenticate'));
|
|
@@ -113,75 +102,20 @@ async function runCloudDev(agent, project, cwd, port, options, spinner) {
|
|
|
113
102
|
}
|
|
114
103
|
};
|
|
115
104
|
ws.onerror = () => {
|
|
116
|
-
spinner.fail('
|
|
117
|
-
console.log(chalk.red('Connection error'));
|
|
105
|
+
spinner.fail('Connection error');
|
|
118
106
|
};
|
|
119
107
|
ws.onclose = () => {
|
|
120
108
|
if (isConnected) {
|
|
121
|
-
spinner.stop();
|
|
122
109
|
console.log(chalk.yellow('Disconnected from cloud'));
|
|
123
110
|
}
|
|
124
111
|
};
|
|
125
|
-
const server = Bun.serve({
|
|
126
|
-
port,
|
|
127
|
-
async fetch(req) {
|
|
128
|
-
const url = new URL(req.url);
|
|
129
|
-
if (url.pathname === '/health') {
|
|
130
|
-
return Response.json({
|
|
131
|
-
status: 'ok',
|
|
132
|
-
agent: agent.name,
|
|
133
|
-
mode: 'cloud',
|
|
134
|
-
cloudUrl
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
if (url.pathname === '/api/chat' && req.method === 'POST') {
|
|
138
|
-
if (!cloudUrl || !sessionId) {
|
|
139
|
-
return Response.json({ error: 'Not connected to cloud' }, { status: 503 });
|
|
140
|
-
}
|
|
141
|
-
const body = await req.json();
|
|
142
|
-
const response = await fetch(`${process.env.STRUERE_GATEWAY_URL || 'https://gateway.struere.dev'}/v1/dev/${sessionId}/chat`, {
|
|
143
|
-
method: 'POST',
|
|
144
|
-
headers: {
|
|
145
|
-
'Content-Type': 'application/json',
|
|
146
|
-
'Authorization': `Bearer ${apiKey || credentials?.token}`
|
|
147
|
-
},
|
|
148
|
-
body: JSON.stringify(body)
|
|
149
|
-
});
|
|
150
|
-
if (body.stream) {
|
|
151
|
-
return new Response(response.body, {
|
|
152
|
-
headers: {
|
|
153
|
-
'Content-Type': 'text/event-stream',
|
|
154
|
-
'Cache-Control': 'no-cache',
|
|
155
|
-
'Connection': 'keep-alive'
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
const responseData = await response.json();
|
|
160
|
-
return Response.json(responseData);
|
|
161
|
-
}
|
|
162
|
-
if (url.pathname === '/' && options.channel === 'web') {
|
|
163
|
-
return new Response(getDevHtml(agent.name, 'cloud', cloudUrl), {
|
|
164
|
-
headers: { 'Content-Type': 'text/html' },
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
return new Response('Not Found', { status: 404 });
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
if (options.channel === 'web' && options.open) {
|
|
171
|
-
const openUrl = `http://localhost:${port}`;
|
|
172
|
-
if (process.platform === 'darwin') {
|
|
173
|
-
Bun.spawn(['open', openUrl]);
|
|
174
|
-
}
|
|
175
|
-
else if (process.platform === 'linux') {
|
|
176
|
-
Bun.spawn(['xdg-open', openUrl]);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
112
|
const watcher = chokidar.watch([join(cwd, 'src'), join(cwd, 'struere.config.ts')], {
|
|
180
113
|
ignoreInitial: true,
|
|
181
114
|
ignored: /node_modules/,
|
|
182
115
|
});
|
|
183
116
|
watcher.on('change', async (path) => {
|
|
184
|
-
|
|
117
|
+
const relativePath = path.replace(cwd, '.');
|
|
118
|
+
console.log(chalk.gray(`Changed: ${relativePath}`));
|
|
185
119
|
try {
|
|
186
120
|
agent = await loadAgent(cwd);
|
|
187
121
|
const bundle = await bundleAgent(cwd);
|
|
@@ -197,23 +131,20 @@ async function runCloudDev(agent, project, cwd, port, options, spinner) {
|
|
|
197
131
|
}
|
|
198
132
|
}
|
|
199
133
|
catch (error) {
|
|
200
|
-
|
|
201
|
-
spinner.start('Watching for changes');
|
|
134
|
+
console.log(chalk.red('Sync failed:'), error);
|
|
202
135
|
}
|
|
203
136
|
});
|
|
204
137
|
process.on('SIGINT', () => {
|
|
205
138
|
console.log();
|
|
206
|
-
spinner.stop();
|
|
207
139
|
if (ws.readyState === WebSocket.OPEN) {
|
|
208
140
|
ws.send(JSON.stringify({ type: 'unsync' }));
|
|
209
141
|
ws.close();
|
|
210
142
|
}
|
|
211
143
|
watcher.close();
|
|
212
|
-
|
|
213
|
-
console.log(chalk.gray('Server stopped'));
|
|
144
|
+
console.log(chalk.gray('Stopped'));
|
|
214
145
|
process.exit(0);
|
|
215
146
|
});
|
|
216
|
-
}
|
|
147
|
+
});
|
|
217
148
|
async function bundleAgent(cwd) {
|
|
218
149
|
const result = await Bun.build({
|
|
219
150
|
entrypoints: [join(cwd, 'src', 'agent.ts')],
|
|
@@ -234,185 +165,153 @@ function hashString(str) {
|
|
|
234
165
|
}
|
|
235
166
|
return Math.abs(hash).toString(16);
|
|
236
167
|
}
|
|
237
|
-
function
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
header .mode { font-size: 0.875rem; }
|
|
253
|
-
header a { text-decoration: none; }
|
|
254
|
-
#messages { flex: 1; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: 0.75rem; }
|
|
255
|
-
.message { max-width: 80%; padding: 0.75rem 1rem; border-radius: 0.75rem; line-height: 1.5; white-space: pre-wrap; }
|
|
256
|
-
.message.user { align-self: flex-end; background: #2563eb; }
|
|
257
|
-
.message.assistant { align-self: flex-start; background: #27272a; }
|
|
258
|
-
.message.tool { align-self: flex-start; background: #1e3a5f; font-family: monospace; font-size: 0.875rem; border-left: 3px solid #3b82f6; }
|
|
259
|
-
.message.streaming { opacity: 0.9; }
|
|
260
|
-
form { padding: 1rem; border-top: 1px solid #333; display: flex; gap: 0.5rem; }
|
|
261
|
-
input { flex: 1; padding: 0.75rem 1rem; background: #18181b; border: 1px solid #333; border-radius: 0.5rem; color: #fafafa; font-size: 1rem; outline: none; }
|
|
262
|
-
input:focus { border-color: #2563eb; }
|
|
263
|
-
input:disabled { opacity: 0.5; }
|
|
264
|
-
button { padding: 0.75rem 1.5rem; background: #2563eb; border: none; border-radius: 0.5rem; color: white; font-size: 1rem; cursor: pointer; }
|
|
265
|
-
button:hover { background: #1d4ed8; }
|
|
266
|
-
button:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
267
|
-
.toggle-container { padding: 0.5rem 1rem; display: flex; align-items: center; gap: 0.5rem; border-top: 1px solid #333; }
|
|
268
|
-
.toggle-container label { font-size: 0.875rem; color: #888; }
|
|
269
|
-
.toggle-container input[type="checkbox"] { width: 1rem; height: 1rem; }
|
|
270
|
-
</style>
|
|
271
|
-
</head>
|
|
272
|
-
<body>
|
|
273
|
-
<header>
|
|
274
|
-
<h1>${agentName}</h1>
|
|
275
|
-
<span class="mode">${modeLabel}</span>
|
|
276
|
-
</header>
|
|
277
|
-
<div id="messages"></div>
|
|
278
|
-
<div class="toggle-container">
|
|
279
|
-
<input type="checkbox" id="stream-toggle" checked />
|
|
280
|
-
<label for="stream-toggle">Enable streaming</label>
|
|
281
|
-
</div>
|
|
282
|
-
<form id="chat-form">
|
|
283
|
-
<input type="text" id="input" placeholder="Type a message..." autocomplete="off" />
|
|
284
|
-
<button type="submit">Send</button>
|
|
285
|
-
</form>
|
|
286
|
-
<script>
|
|
287
|
-
const messages = document.getElementById('messages');
|
|
288
|
-
const form = document.getElementById('chat-form');
|
|
289
|
-
const input = document.getElementById('input');
|
|
290
|
-
const button = form.querySelector('button');
|
|
291
|
-
const streamToggle = document.getElementById('stream-toggle');
|
|
292
|
-
let conversationId = null;
|
|
293
|
-
let isProcessing = false;
|
|
294
|
-
|
|
295
|
-
function addMessage(role, content, isStreaming = false) {
|
|
296
|
-
const div = document.createElement('div');
|
|
297
|
-
div.className = 'message ' + role + (isStreaming ? ' streaming' : '');
|
|
298
|
-
div.textContent = content;
|
|
299
|
-
messages.appendChild(div);
|
|
300
|
-
messages.scrollTop = messages.scrollHeight;
|
|
301
|
-
return div;
|
|
168
|
+
async function interactiveSetup(cwd) {
|
|
169
|
+
const spinner = ora();
|
|
170
|
+
let credentials = loadCredentials();
|
|
171
|
+
if (!credentials) {
|
|
172
|
+
console.log(chalk.gray('Authentication required'));
|
|
173
|
+
console.log();
|
|
174
|
+
credentials = await performLogin();
|
|
175
|
+
if (!credentials) {
|
|
176
|
+
console.log(chalk.red('Authentication failed'));
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
console.log(chalk.green('✓'), 'Logged in as', chalk.cyan(credentials.user.name));
|
|
182
|
+
console.log();
|
|
302
183
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
184
|
+
spinner.start('Fetching agents');
|
|
185
|
+
const api = new ApiClient();
|
|
186
|
+
let agents = [];
|
|
187
|
+
try {
|
|
188
|
+
const { agents: existingAgents } = await api.listAgents();
|
|
189
|
+
agents = existingAgents;
|
|
190
|
+
spinner.succeed(`Found ${agents.length} existing agent(s)`);
|
|
308
191
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
headers: { 'Content-Type': 'application/json' },
|
|
316
|
-
body: JSON.stringify({ message, conversationId, stream: true }),
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
const reader = response.body.getReader();
|
|
320
|
-
const decoder = new TextDecoder();
|
|
321
|
-
let buffer = '';
|
|
322
|
-
let fullText = '';
|
|
323
|
-
|
|
324
|
-
while (true) {
|
|
325
|
-
const { done, value } = await reader.read();
|
|
326
|
-
if (done) break;
|
|
327
|
-
|
|
328
|
-
buffer += decoder.decode(value, { stream: true });
|
|
329
|
-
const lines = buffer.split('\\n');
|
|
330
|
-
buffer = lines.pop() || '';
|
|
331
|
-
|
|
332
|
-
for (const line of lines) {
|
|
333
|
-
if (line.startsWith('data: ')) {
|
|
334
|
-
try {
|
|
335
|
-
const data = JSON.parse(line.slice(6));
|
|
336
|
-
|
|
337
|
-
if (data.conversationId) {
|
|
338
|
-
conversationId = data.conversationId;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
if (data.type === 'text-delta' && (data.textDelta || data.content)) {
|
|
342
|
-
fullText += data.textDelta || data.content;
|
|
343
|
-
assistantDiv.textContent = fullText;
|
|
344
|
-
messages.scrollTop = messages.scrollHeight;
|
|
345
|
-
} else if (data.type === 'tool-call-start') {
|
|
346
|
-
addMessage('tool', 'Calling tool: ' + (data.toolName || data.toolCall?.name));
|
|
347
|
-
} else if (data.type === 'tool-result') {
|
|
348
|
-
const resultText = typeof data.toolResult === 'string'
|
|
349
|
-
? data.toolResult
|
|
350
|
-
: JSON.stringify(data.toolResult || data.toolCall?.result, null, 2);
|
|
351
|
-
addMessage('tool', 'Result: ' + resultText);
|
|
352
|
-
} else if (data.type === 'finish') {
|
|
353
|
-
assistantDiv.classList.remove('streaming');
|
|
354
|
-
} else if (data.type === 'error') {
|
|
355
|
-
assistantDiv.textContent = 'Error: ' + (data.error || data.message);
|
|
356
|
-
assistantDiv.classList.remove('streaming');
|
|
357
|
-
}
|
|
358
|
-
} catch (e) {}
|
|
359
|
-
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
if (error instanceof ApiError && error.status === 401) {
|
|
194
|
+
spinner.fail('Session expired');
|
|
195
|
+
console.log();
|
|
196
|
+
console.log(chalk.gray('Run'), chalk.cyan('struere login'), chalk.gray('to re-authenticate'));
|
|
197
|
+
return null;
|
|
360
198
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
if (!fullText) {
|
|
364
|
-
assistantDiv.remove();
|
|
365
|
-
}
|
|
199
|
+
spinner.succeed('Ready to create agent');
|
|
366
200
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
201
|
+
console.log();
|
|
202
|
+
const choices = [
|
|
203
|
+
{ value: 'link', label: 'Link to an existing agent' },
|
|
204
|
+
{ value: 'create', label: 'Create a new agent' },
|
|
205
|
+
{ value: 'cancel', label: 'Cancel' },
|
|
206
|
+
];
|
|
207
|
+
if (agents.length === 0) {
|
|
208
|
+
choices.shift();
|
|
209
|
+
}
|
|
210
|
+
const action = await promptChoice('No agent configured. Would you like to:', choices);
|
|
211
|
+
if (action === 'cancel') {
|
|
212
|
+
console.log();
|
|
213
|
+
console.log(chalk.gray('Run'), chalk.cyan('struere init'), chalk.gray('when ready to set up'));
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
let selectedAgent = null;
|
|
217
|
+
if (action === 'link' && agents.length > 0) {
|
|
218
|
+
console.log();
|
|
219
|
+
const agentChoices = agents.map((a) => ({ value: a.id, label: `${a.name} (${a.slug})` }));
|
|
220
|
+
const agentId = await promptChoice('Select an agent:', agentChoices);
|
|
221
|
+
selectedAgent = agents.find((a) => a.id === agentId) || null;
|
|
222
|
+
}
|
|
223
|
+
else if (action === 'create') {
|
|
224
|
+
console.log();
|
|
225
|
+
const projectName = slugify(basename(cwd));
|
|
226
|
+
const name = await promptText('Agent name:', projectName);
|
|
227
|
+
const displayName = name
|
|
228
|
+
.split('-')
|
|
229
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
230
|
+
.join(' ');
|
|
231
|
+
spinner.start('Creating agent');
|
|
232
|
+
try {
|
|
233
|
+
const { agent } = await api.createAgent({
|
|
234
|
+
name: displayName,
|
|
235
|
+
slug: name,
|
|
236
|
+
description: `${displayName} Agent`,
|
|
237
|
+
});
|
|
238
|
+
selectedAgent = { id: agent.id, name: displayName, slug: name };
|
|
239
|
+
spinner.succeed(`Created agent "${name}"`);
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
spinner.fail('Failed to create agent');
|
|
243
|
+
console.log();
|
|
244
|
+
if (error instanceof ApiError) {
|
|
245
|
+
console.log(chalk.red('Error:'), error.message);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
console.log(chalk.red('Error:'), error instanceof Error ? error.message : String(error));
|
|
249
|
+
}
|
|
250
|
+
return null;
|
|
383
251
|
}
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
addMessage('assistant', data.response || data.content);
|
|
387
252
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
253
|
+
if (!selectedAgent) {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
const projectData = {
|
|
257
|
+
agentId: selectedAgent.id,
|
|
258
|
+
team: credentials.organization.slug,
|
|
259
|
+
agent: {
|
|
260
|
+
slug: selectedAgent.slug,
|
|
261
|
+
name: selectedAgent.name,
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
saveProject(cwd, projectData);
|
|
265
|
+
console.log(chalk.green('✓'), 'Created struere.json');
|
|
266
|
+
console.log();
|
|
267
|
+
return projectData;
|
|
268
|
+
}
|
|
269
|
+
function slugify(name) {
|
|
270
|
+
return name
|
|
271
|
+
.toLowerCase()
|
|
272
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
273
|
+
.replace(/^-+|-+$/g, '');
|
|
274
|
+
}
|
|
275
|
+
async function promptChoice(message, choices) {
|
|
276
|
+
console.log(chalk.gray(message));
|
|
277
|
+
console.log();
|
|
278
|
+
for (let i = 0; i < choices.length; i++) {
|
|
279
|
+
const prefix = i === 0 ? chalk.cyan('❯') : chalk.gray(' ');
|
|
280
|
+
console.log(`${prefix} ${i + 1}. ${choices[i].label}`);
|
|
281
|
+
}
|
|
282
|
+
console.log();
|
|
283
|
+
process.stdout.write(chalk.gray('Enter choice (1-' + choices.length + '): '));
|
|
284
|
+
const answer = await readLine();
|
|
285
|
+
const num = parseInt(answer, 10);
|
|
286
|
+
if (num >= 1 && num <= choices.length) {
|
|
287
|
+
return choices[num - 1].value;
|
|
288
|
+
}
|
|
289
|
+
return choices[0].value;
|
|
290
|
+
}
|
|
291
|
+
async function promptText(message, defaultValue) {
|
|
292
|
+
process.stdout.write(chalk.gray(`${message} `));
|
|
293
|
+
process.stdout.write(chalk.cyan(`(${defaultValue}) `));
|
|
294
|
+
const answer = await readLine();
|
|
295
|
+
return answer || defaultValue;
|
|
296
|
+
}
|
|
297
|
+
function readLine() {
|
|
298
|
+
return new Promise((resolve) => {
|
|
299
|
+
let buffer = '';
|
|
300
|
+
const onData = (chunk) => {
|
|
301
|
+
const str = chunk.toString();
|
|
302
|
+
buffer += str;
|
|
303
|
+
if (str.includes('\n') || str.includes('\r')) {
|
|
304
|
+
process.stdin.removeListener('data', onData);
|
|
305
|
+
process.stdin.pause();
|
|
306
|
+
process.stdin.setRawMode?.(false);
|
|
307
|
+
resolve(buffer.replace(/[\r\n]/g, '').trim());
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
if (process.stdin.isTTY) {
|
|
311
|
+
process.stdin.setRawMode?.(false);
|
|
405
312
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
} finally {
|
|
409
|
-
setProcessing(false);
|
|
410
|
-
}
|
|
313
|
+
process.stdin.resume();
|
|
314
|
+
process.stdin.on('data', onData);
|
|
411
315
|
});
|
|
412
|
-
|
|
413
|
-
input.focus();
|
|
414
|
-
</script>
|
|
415
|
-
</body>
|
|
416
|
-
</html>`;
|
|
417
316
|
}
|
|
418
317
|
//# sourceMappingURL=dev.js.map
|