@struere/cli 0.2.2 → 0.2.3
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/index.js +10 -104
- package/package.json +12 -4
package/dist/index.js
CHANGED
|
@@ -165,7 +165,7 @@ class ApiError extends Error {
|
|
|
165
165
|
|
|
166
166
|
// src/commands/login.ts
|
|
167
167
|
var AUTH_CALLBACK_PORT = 9876;
|
|
168
|
-
var loginCommand = new Command("login").description("Log in to Struere").
|
|
168
|
+
var loginCommand = new Command("login").description("Log in to Struere").action(async () => {
|
|
169
169
|
const spinner = ora();
|
|
170
170
|
console.log();
|
|
171
171
|
console.log(chalk.bold("Struere Login"));
|
|
@@ -177,22 +177,14 @@ var loginCommand = new Command("login").description("Log in to Struere").option(
|
|
|
177
177
|
console.log();
|
|
178
178
|
return;
|
|
179
179
|
}
|
|
180
|
-
|
|
181
|
-
await headlessLogin(spinner);
|
|
182
|
-
} else {
|
|
183
|
-
await browserLogin(spinner);
|
|
184
|
-
}
|
|
180
|
+
await browserLogin(spinner);
|
|
185
181
|
});
|
|
186
|
-
async function performLogin(
|
|
182
|
+
async function performLogin() {
|
|
187
183
|
const spinner = ora();
|
|
188
184
|
console.log();
|
|
189
185
|
console.log(chalk.bold("Struere Login"));
|
|
190
186
|
console.log();
|
|
191
|
-
|
|
192
|
-
return headlessLoginInternal(spinner);
|
|
193
|
-
} else {
|
|
194
|
-
return browserLoginInternal(spinner);
|
|
195
|
-
}
|
|
187
|
+
return browserLoginInternal(spinner);
|
|
196
188
|
}
|
|
197
189
|
async function browserLogin(spinner) {
|
|
198
190
|
const result = await browserLoginInternal(spinner);
|
|
@@ -212,6 +204,7 @@ async function browserLoginInternal(spinner) {
|
|
|
212
204
|
const sessionId = url.searchParams.get("session_id");
|
|
213
205
|
if (token && sessionId) {
|
|
214
206
|
resolve({ token, sessionId });
|
|
207
|
+
setTimeout(() => server.stop(), 1000);
|
|
215
208
|
return new Response(getSuccessHtml(), {
|
|
216
209
|
headers: { "Content-Type": "text/html" }
|
|
217
210
|
});
|
|
@@ -279,60 +272,6 @@ async function browserLoginInternal(spinner) {
|
|
|
279
272
|
console.log();
|
|
280
273
|
console.log(chalk.red("Error:"), error instanceof Error ? error.message : String(error));
|
|
281
274
|
console.log();
|
|
282
|
-
console.log(chalk.gray("Try"), chalk.cyan("struere login --headless"), chalk.gray("for email/password login"));
|
|
283
|
-
console.log();
|
|
284
|
-
return null;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
async function headlessLogin(spinner) {
|
|
288
|
-
const result = await headlessLoginInternal(spinner);
|
|
289
|
-
if (result) {
|
|
290
|
-
printNextSteps();
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
async function headlessLoginInternal(spinner) {
|
|
294
|
-
const email = await prompt("Email: ");
|
|
295
|
-
const password = await prompt("Password: ", true);
|
|
296
|
-
if (!email || !password) {
|
|
297
|
-
console.log(chalk.red("Email and password are required"));
|
|
298
|
-
return null;
|
|
299
|
-
}
|
|
300
|
-
spinner.start("Logging in");
|
|
301
|
-
try {
|
|
302
|
-
const api = new ApiClient;
|
|
303
|
-
const { token, user } = await api.login(email, password);
|
|
304
|
-
const { organization } = await api.getMe();
|
|
305
|
-
const credentials = {
|
|
306
|
-
token,
|
|
307
|
-
user: {
|
|
308
|
-
id: user.id,
|
|
309
|
-
email: user.email,
|
|
310
|
-
name: user.name,
|
|
311
|
-
organizationId: user.organizationId
|
|
312
|
-
},
|
|
313
|
-
organization: {
|
|
314
|
-
id: organization.id,
|
|
315
|
-
name: organization.name,
|
|
316
|
-
slug: organization.slug
|
|
317
|
-
},
|
|
318
|
-
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString()
|
|
319
|
-
};
|
|
320
|
-
saveCredentials(credentials);
|
|
321
|
-
spinner.succeed("Logged in successfully");
|
|
322
|
-
console.log();
|
|
323
|
-
console.log(chalk.green("Welcome,"), chalk.cyan(user.name));
|
|
324
|
-
console.log(chalk.gray("Organization:"), organization.name);
|
|
325
|
-
console.log();
|
|
326
|
-
return credentials;
|
|
327
|
-
} catch (error) {
|
|
328
|
-
spinner.fail("Login failed");
|
|
329
|
-
console.log();
|
|
330
|
-
if (error instanceof ApiError) {
|
|
331
|
-
console.log(chalk.red("Error:"), error.message);
|
|
332
|
-
} else {
|
|
333
|
-
console.log(chalk.red("Error:"), error instanceof Error ? error.message : String(error));
|
|
334
|
-
}
|
|
335
|
-
console.log();
|
|
336
275
|
return null;
|
|
337
276
|
}
|
|
338
277
|
}
|
|
@@ -344,9 +283,9 @@ function printNextSteps() {
|
|
|
344
283
|
console.log();
|
|
345
284
|
}
|
|
346
285
|
function getAuthUrl() {
|
|
347
|
-
const baseUrl = process.env.STRUERE_AUTH_URL || "https://struere.dev";
|
|
286
|
+
const baseUrl = process.env.STRUERE_AUTH_URL || "https://app.struere.dev";
|
|
348
287
|
const callbackUrl = `http://localhost:${AUTH_CALLBACK_PORT}/callback`;
|
|
349
|
-
return `${baseUrl}/
|
|
288
|
+
return `${baseUrl}/authorize?callback=${encodeURIComponent(callbackUrl)}`;
|
|
350
289
|
}
|
|
351
290
|
function getSuccessHtml() {
|
|
352
291
|
return `<!DOCTYPE html>
|
|
@@ -389,39 +328,6 @@ function getErrorHtml(message) {
|
|
|
389
328
|
</body>
|
|
390
329
|
</html>`;
|
|
391
330
|
}
|
|
392
|
-
async function prompt(message, hidden = false) {
|
|
393
|
-
process.stdout.write(chalk.gray(message));
|
|
394
|
-
return new Promise((resolve) => {
|
|
395
|
-
let input = "";
|
|
396
|
-
if (hidden) {
|
|
397
|
-
process.stdin.setRawMode(true);
|
|
398
|
-
}
|
|
399
|
-
process.stdin.resume();
|
|
400
|
-
process.stdin.setEncoding("utf8");
|
|
401
|
-
const onData = (char) => {
|
|
402
|
-
if (char === `
|
|
403
|
-
` || char === "\r") {
|
|
404
|
-
process.stdin.removeListener("data", onData);
|
|
405
|
-
process.stdin.pause();
|
|
406
|
-
if (hidden) {
|
|
407
|
-
process.stdin.setRawMode(false);
|
|
408
|
-
console.log();
|
|
409
|
-
}
|
|
410
|
-
resolve(input);
|
|
411
|
-
} else if (char === "\x03") {
|
|
412
|
-
process.exit();
|
|
413
|
-
} else if (char === "\x7F") {
|
|
414
|
-
input = input.slice(0, -1);
|
|
415
|
-
} else {
|
|
416
|
-
input += char;
|
|
417
|
-
if (!hidden) {
|
|
418
|
-
process.stdout.write(char);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
};
|
|
422
|
-
process.stdin.on("data", onData);
|
|
423
|
-
});
|
|
424
|
-
}
|
|
425
331
|
|
|
426
332
|
// src/utils/project.ts
|
|
427
333
|
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
@@ -774,7 +680,7 @@ function hasAgentFiles(cwd) {
|
|
|
774
680
|
}
|
|
775
681
|
|
|
776
682
|
// src/commands/init.ts
|
|
777
|
-
var initCommand = new Command2("init").description("Initialize a new Struere project").argument("[project-name]", "Project name").option("-y, --yes", "Skip prompts and use defaults").
|
|
683
|
+
var initCommand = new Command2("init").description("Initialize a new Struere project").argument("[project-name]", "Project name").option("-y, --yes", "Skip prompts and use defaults").action(async (projectNameArg, options) => {
|
|
778
684
|
const cwd = process.cwd();
|
|
779
685
|
const spinner = ora2();
|
|
780
686
|
console.log();
|
|
@@ -802,7 +708,7 @@ var initCommand = new Command2("init").description("Initialize a new Struere pro
|
|
|
802
708
|
if (!credentials) {
|
|
803
709
|
console.log(chalk2.gray("Authentication required"));
|
|
804
710
|
console.log();
|
|
805
|
-
credentials = await performLogin(
|
|
711
|
+
credentials = await performLogin();
|
|
806
712
|
if (!credentials) {
|
|
807
713
|
console.log(chalk2.red("Authentication failed"));
|
|
808
714
|
process.exit(1);
|
|
@@ -2208,7 +2114,7 @@ var whoamiCommand = new Command11("whoami").description("Show current logged in
|
|
|
2208
2114
|
});
|
|
2209
2115
|
|
|
2210
2116
|
// src/index.ts
|
|
2211
|
-
program.name("struere").description("Struere CLI - Build, test, and deploy AI agents").version("0.2.
|
|
2117
|
+
program.name("struere").description("Struere CLI - Build, test, and deploy AI agents").version("0.2.3");
|
|
2212
2118
|
program.addCommand(initCommand);
|
|
2213
2119
|
program.addCommand(loginCommand);
|
|
2214
2120
|
program.addCommand(logoutCommand);
|
package/package.json
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@struere/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "CLI tool for developing, testing, and deploying AI agents",
|
|
5
|
-
"keywords": [
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ai",
|
|
7
|
+
"agents",
|
|
8
|
+
"cli",
|
|
9
|
+
"developer-tools",
|
|
10
|
+
"llm"
|
|
11
|
+
],
|
|
6
12
|
"author": "struere",
|
|
7
13
|
"license": "MIT",
|
|
8
14
|
"publishConfig": {
|
|
@@ -22,13 +28,15 @@
|
|
|
22
28
|
"struere": "./dist/index.js"
|
|
23
29
|
},
|
|
24
30
|
"main": "./dist/index.js",
|
|
25
|
-
"files": [
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
26
34
|
"scripts": {
|
|
27
35
|
"build": "bun build ./src/index.ts --outdir ./dist --target bun --external commander --external chalk --external ora --external chokidar --external yaml --external @struere/runtime && chmod +x ./dist/index.js",
|
|
28
36
|
"dev": "tsc --watch",
|
|
29
37
|
"test": "bun test",
|
|
30
38
|
"prepublishOnly": "bun run build && bun run verify-build",
|
|
31
|
-
"bump": "node scripts/bump-version.
|
|
39
|
+
"bump": "node scripts/bump-version.cjs",
|
|
32
40
|
"verify-build": "node -e \"const pkg = require('./package.json'); const fs = require('fs'); const bundle = fs.readFileSync('./dist/index.js', 'utf8'); const match = bundle.match(/version\\(\\\"([^\\\"]+)\\\"\\)/); if (!match || match[1] !== pkg.version) { console.error('Version mismatch: package.json=' + pkg.version + ' bundle=' + (match ? match[1] : 'not found')); process.exit(1); } console.log('Build verified: v' + pkg.version);\""
|
|
33
41
|
},
|
|
34
42
|
"dependencies": {
|