@stamn/agent 0.6.0 → 0.8.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/dist/{chunk-DJ3HR5OC.js → chunk-6EKA3TV7.js} +2 -2
- package/dist/commands/login.d.ts +8 -0
- package/dist/commands/login.js +34 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/spend.js +1 -1
- package/dist/commands/start.js +6 -6
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/uninstall.d.ts +8 -0
- package/dist/commands/uninstall.js +33 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.js +2 -2
- package/dist/ui/device-login.d.ts +8 -0
- package/dist/ui/device-login.js +153 -0
- package/dist/ui/device-login.js.map +1 -0
- package/dist/ui/setup.js +11 -10
- package/dist/ui/setup.js.map +1 -1
- package/package.json +1 -1
- /package/dist/{chunk-DJ3HR5OC.js.map → chunk-6EKA3TV7.js.map} +0 -0
|
@@ -266,7 +266,7 @@ var WSClient = class {
|
|
|
266
266
|
const payload = {
|
|
267
267
|
agentId: this.options.config.agentId,
|
|
268
268
|
status,
|
|
269
|
-
version: "0.
|
|
269
|
+
version: "0.8.0",
|
|
270
270
|
platform: `${process.platform}-${process.arch}`,
|
|
271
271
|
nodeVersion: process.versions.node
|
|
272
272
|
};
|
|
@@ -373,4 +373,4 @@ export {
|
|
|
373
373
|
WSClient,
|
|
374
374
|
SpendClient
|
|
375
375
|
};
|
|
376
|
-
//# sourceMappingURL=chunk-
|
|
376
|
+
//# sourceMappingURL=chunk-6EKA3TV7.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createRequire } from "module"; const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
ConfigStore
|
|
4
|
+
} from "../chunk-KQC5O25P.js";
|
|
5
|
+
import "../chunk-JVIBUEVN.js";
|
|
6
|
+
|
|
7
|
+
// src/commands/login.ts
|
|
8
|
+
import { Command } from "@oclif/core";
|
|
9
|
+
var Login = class extends Command {
|
|
10
|
+
static description = "Log in to Stamn via the dashboard (device code flow)";
|
|
11
|
+
async run() {
|
|
12
|
+
if (!process.stdout.isTTY) {
|
|
13
|
+
this.error(
|
|
14
|
+
"Interactive login requires a terminal. Use `stamn start` with an existing config."
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
const { runDeviceLogin } = await import("../ui/device-login.js");
|
|
18
|
+
try {
|
|
19
|
+
const result = await runDeviceLogin();
|
|
20
|
+
const store = new ConfigStore();
|
|
21
|
+
store.set("apiKey", result.apiKey);
|
|
22
|
+
store.set("agentId", result.agentId);
|
|
23
|
+
store.set("agentName", result.agentName);
|
|
24
|
+
this.log(`
|
|
25
|
+
Agent "${result.agentName}" ready. Run \`stamn start\` to connect.`);
|
|
26
|
+
} catch (err) {
|
|
27
|
+
this.error(err.message || "Login cancelled.");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
export {
|
|
32
|
+
Login as default
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/commands/login.ts"],"sourcesContent":["import { Command } from '@oclif/core';\nimport { ConfigStore } from '../config/config-store.js';\n\nexport default class Login extends Command {\n static override description =\n 'Log in to Stamn via the dashboard (device code flow)';\n\n async run(): Promise<void> {\n if (!process.stdout.isTTY) {\n this.error(\n 'Interactive login requires a terminal. Use `stamn start` with an existing config.',\n );\n }\n\n const { runDeviceLogin } = await import('../ui/device-login.js');\n\n try {\n const result = await runDeviceLogin();\n const store = new ConfigStore();\n store.set('apiKey', result.apiKey);\n store.set('agentId', result.agentId);\n store.set('agentName', result.agentName);\n this.log(`\\nAgent \"${result.agentName}\" ready. Run \\`stamn start\\` to connect.`);\n } catch (err) {\n this.error((err as Error).message || 'Login cancelled.');\n }\n }\n}\n"],"mappings":";;;;;;;AAAA,SAAS,eAAe;AAGxB,IAAqB,QAArB,cAAmC,QAAQ;AAAA,EACzC,OAAgB,cACd;AAAA,EAEF,MAAM,MAAqB;AACzB,QAAI,CAAC,QAAQ,OAAO,OAAO;AACzB,WAAK;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,UAAM,EAAE,eAAe,IAAI,MAAM,OAAO,uBAAuB;AAE/D,QAAI;AACF,YAAM,SAAS,MAAM,eAAe;AACpC,YAAM,QAAQ,IAAI,YAAY;AAC9B,YAAM,IAAI,UAAU,OAAO,MAAM;AACjC,YAAM,IAAI,WAAW,OAAO,OAAO;AACnC,YAAM,IAAI,aAAa,OAAO,SAAS;AACvC,WAAK,IAAI;AAAA,SAAY,OAAO,SAAS,0CAA0C;AAAA,IACjF,SAAS,KAAK;AACZ,WAAK,MAAO,IAAc,WAAW,kBAAkB;AAAA,IACzD;AAAA,EACF;AACF;","names":[]}
|
package/dist/commands/spend.js
CHANGED
package/dist/commands/start.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
SpendClient,
|
|
7
7
|
WSClient,
|
|
8
8
|
createLogger
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-6EKA3TV7.js";
|
|
10
10
|
import {
|
|
11
11
|
ConfigStore
|
|
12
12
|
} from "../chunk-KQC5O25P.js";
|
|
@@ -38,19 +38,19 @@ var Start = class _Start extends Command {
|
|
|
38
38
|
if (!config.apiKey || !config.agentId) {
|
|
39
39
|
if (flags.daemon || !process.stdout.isTTY) {
|
|
40
40
|
this.error(
|
|
41
|
-
"Not registered. Run `stamn
|
|
41
|
+
"Not registered. Run `stamn login` interactively first."
|
|
42
42
|
);
|
|
43
43
|
}
|
|
44
|
-
const {
|
|
44
|
+
const { runDeviceLogin } = await import("../ui/device-login.js");
|
|
45
45
|
try {
|
|
46
|
-
const result = await
|
|
46
|
+
const result = await runDeviceLogin();
|
|
47
47
|
configStore.set("apiKey", result.apiKey);
|
|
48
48
|
configStore.set("agentId", result.agentId);
|
|
49
49
|
configStore.set("agentName", result.agentName);
|
|
50
50
|
config.apiKey = result.apiKey;
|
|
51
51
|
config.agentId = result.agentId;
|
|
52
|
-
} catch {
|
|
53
|
-
this.error("
|
|
52
|
+
} catch (err) {
|
|
53
|
+
this.error(err.message || "Login cancelled.");
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
const dm = new DaemonManager();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/start.ts"],"sourcesContent":["import { Command, Flags } from '@oclif/core';\nimport { ConfigStore } from '../config/config-store.js';\nimport { SERVER_URL, type AgentConfig } from '../config/config-schema.js';\nimport { createLogger } from '../logging/logger.js';\nimport { WSClient } from '../ws/ws-client.js';\nimport { SpendClient } from '../spend/spend-client.js';\nimport { DaemonManager } from '../daemon/daemon-manager.js';\n\nexport default class Start extends Command {\n static override description = 'Start the Stamn agent daemon';\n\n static override flags = {\n daemon: Flags.boolean({\n char: 'd',\n description: 'Run as background daemon',\n default: false,\n }),\n 'log-level': Flags.string({\n description: 'Override log level',\n options: ['trace', 'debug', 'info', 'warn', 'error', 'fatal'],\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Start);\n const configStore = new ConfigStore();\n const config = { ...configStore.getAll() };\n\n // Apply flag overrides\n if (flags['log-level'])\n config.logLevel = flags['log-level'] as AgentConfig['logLevel'];\n\n // Interactive
|
|
1
|
+
{"version":3,"sources":["../../src/commands/start.ts"],"sourcesContent":["import { Command, Flags } from '@oclif/core';\nimport { ConfigStore } from '../config/config-store.js';\nimport { SERVER_URL, type AgentConfig } from '../config/config-schema.js';\nimport { createLogger } from '../logging/logger.js';\nimport { WSClient } from '../ws/ws-client.js';\nimport { SpendClient } from '../spend/spend-client.js';\nimport { DaemonManager } from '../daemon/daemon-manager.js';\n\nexport default class Start extends Command {\n static override description = 'Start the Stamn agent daemon';\n\n static override flags = {\n daemon: Flags.boolean({\n char: 'd',\n description: 'Run as background daemon',\n default: false,\n }),\n 'log-level': Flags.string({\n description: 'Override log level',\n options: ['trace', 'debug', 'info', 'warn', 'error', 'fatal'],\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Start);\n const configStore = new ConfigStore();\n const config = { ...configStore.getAll() };\n\n // Apply flag overrides\n if (flags['log-level'])\n config.logLevel = flags['log-level'] as AgentConfig['logLevel'];\n\n // Interactive login when not registered\n if (!config.apiKey || !config.agentId) {\n if (flags.daemon || !process.stdout.isTTY) {\n this.error(\n 'Not registered. Run `stamn login` interactively first.',\n );\n }\n\n const { runDeviceLogin } = await import('../ui/device-login.js');\n try {\n const result = await runDeviceLogin();\n configStore.set('apiKey', result.apiKey);\n configStore.set('agentId', result.agentId);\n configStore.set('agentName', result.agentName);\n config.apiKey = result.apiKey;\n config.agentId = result.agentId;\n } catch (err) {\n this.error((err as Error).message || 'Login cancelled.');\n }\n }\n\n // Check for existing daemon\n const dm = new DaemonManager();\n const { running, pid } = dm.isRunning();\n if (running) {\n this.error(`Daemon already running (PID ${pid})`);\n }\n\n // Daemonize if requested\n if (flags.daemon) {\n const { daemonizeProcess } = await import('../daemon/process.js');\n await daemonizeProcess();\n }\n\n // Write PID\n dm.writePid(process.pid);\n\n const logger = createLogger(config);\n logger.info(\n { agentId: config.agentId, server: SERVER_URL },\n 'Starting Stamn agent',\n );\n\n // Create WebSocket client\n const client = new WSClient({\n config,\n logger,\n onCommand: (command, params) => {\n logger.info({ command, params }, 'Received command');\n if (command === 'shutdown') {\n shutdown();\n }\n },\n onDisconnect: () => {\n logger.warn('Disconnected from server');\n },\n onConnected: () => {\n logger.info('Agent is online and ready — spend capability active');\n },\n });\n\n // Create spend client — available for plugin/task integration\n const spendClient = new SpendClient(client, logger);\n\n // Expose on process for external plugin access\n (globalThis as Record<string, unknown>).__stamnSpendClient = spendClient;\n\n // Graceful shutdown\n const shutdown = () => {\n logger.info('Shutting down...');\n client.disconnect();\n dm.removePid();\n process.exit(0);\n };\n\n process.on('SIGTERM', shutdown);\n process.on('SIGINT', shutdown);\n\n // Connect\n client.connect();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA,SAAS,SAAS,aAAa;AAQ/B,IAAqB,QAArB,MAAqB,eAAc,QAAQ;AAAA,EACzC,OAAgB,cAAc;AAAA,EAE9B,OAAgB,QAAQ;AAAA,IACtB,QAAQ,MAAM,QAAQ;AAAA,MACpB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC;AAAA,IACD,aAAa,MAAM,OAAO;AAAA,MACxB,aAAa;AAAA,MACb,SAAS,CAAC,SAAS,SAAS,QAAQ,QAAQ,SAAS,OAAO;AAAA,IAC9D,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAqB;AACzB,UAAM,EAAE,MAAM,IAAI,MAAM,KAAK,MAAM,MAAK;AACxC,UAAM,cAAc,IAAI,YAAY;AACpC,UAAM,SAAS,EAAE,GAAG,YAAY,OAAO,EAAE;AAGzC,QAAI,MAAM,WAAW;AACnB,aAAO,WAAW,MAAM,WAAW;AAGrC,QAAI,CAAC,OAAO,UAAU,CAAC,OAAO,SAAS;AACrC,UAAI,MAAM,UAAU,CAAC,QAAQ,OAAO,OAAO;AACzC,aAAK;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,YAAM,EAAE,eAAe,IAAI,MAAM,OAAO,uBAAuB;AAC/D,UAAI;AACF,cAAM,SAAS,MAAM,eAAe;AACpC,oBAAY,IAAI,UAAU,OAAO,MAAM;AACvC,oBAAY,IAAI,WAAW,OAAO,OAAO;AACzC,oBAAY,IAAI,aAAa,OAAO,SAAS;AAC7C,eAAO,SAAS,OAAO;AACvB,eAAO,UAAU,OAAO;AAAA,MAC1B,SAAS,KAAK;AACZ,aAAK,MAAO,IAAc,WAAW,kBAAkB;AAAA,MACzD;AAAA,IACF;AAGA,UAAM,KAAK,IAAI,cAAc;AAC7B,UAAM,EAAE,SAAS,IAAI,IAAI,GAAG,UAAU;AACtC,QAAI,SAAS;AACX,WAAK,MAAM,+BAA+B,GAAG,GAAG;AAAA,IAClD;AAGA,QAAI,MAAM,QAAQ;AAChB,YAAM,EAAE,iBAAiB,IAAI,MAAM,OAAO,wBAAsB;AAChE,YAAM,iBAAiB;AAAA,IACzB;AAGA,OAAG,SAAS,QAAQ,GAAG;AAEvB,UAAM,SAAS,aAAa,MAAM;AAClC,WAAO;AAAA,MACL,EAAE,SAAS,OAAO,SAAS,QAAQ,WAAW;AAAA,MAC9C;AAAA,IACF;AAGA,UAAM,SAAS,IAAI,SAAS;AAAA,MAC1B;AAAA,MACA;AAAA,MACA,WAAW,CAAC,SAAS,WAAW;AAC9B,eAAO,KAAK,EAAE,SAAS,OAAO,GAAG,kBAAkB;AACnD,YAAI,YAAY,YAAY;AAC1B,mBAAS;AAAA,QACX;AAAA,MACF;AAAA,MACA,cAAc,MAAM;AAClB,eAAO,KAAK,0BAA0B;AAAA,MACxC;AAAA,MACA,aAAa,MAAM;AACjB,eAAO,KAAK,0DAAqD;AAAA,MACnE;AAAA,IACF,CAAC;AAGD,UAAM,cAAc,IAAI,YAAY,QAAQ,MAAM;AAGlD,IAAC,WAAuC,qBAAqB;AAG7D,UAAM,WAAW,MAAM;AACrB,aAAO,KAAK,kBAAkB;AAC9B,aAAO,WAAW;AAClB,SAAG,UAAU;AACb,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,YAAQ,GAAG,WAAW,QAAQ;AAC9B,YAAQ,GAAG,UAAU,QAAQ;AAG7B,WAAO,QAAQ;AAAA,EACjB;AACF;","names":[]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createRequire } from "module"; const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
DaemonManager
|
|
4
|
+
} from "../chunk-DCE6ICKM.js";
|
|
5
|
+
import {
|
|
6
|
+
ConfigStore
|
|
7
|
+
} from "../chunk-KQC5O25P.js";
|
|
8
|
+
import "../chunk-JVIBUEVN.js";
|
|
9
|
+
|
|
10
|
+
// src/commands/uninstall.ts
|
|
11
|
+
import { Command } from "@oclif/core";
|
|
12
|
+
import { execSync } from "child_process";
|
|
13
|
+
var Uninstall = class extends Command {
|
|
14
|
+
static description = "Uninstall the Stamn agent";
|
|
15
|
+
async run() {
|
|
16
|
+
const dm = new DaemonManager();
|
|
17
|
+
const { running } = dm.isRunning();
|
|
18
|
+
if (running) {
|
|
19
|
+
this.log("Stopping daemon...");
|
|
20
|
+
dm.stop();
|
|
21
|
+
}
|
|
22
|
+
this.log("Removing config...");
|
|
23
|
+
const store = new ConfigStore();
|
|
24
|
+
store.clear();
|
|
25
|
+
this.log("Uninstalling...");
|
|
26
|
+
execSync("npm rm -g @stamn/agent", { stdio: "inherit" });
|
|
27
|
+
this.log("Done.");
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
export {
|
|
31
|
+
Uninstall as default
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=uninstall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/commands/uninstall.ts"],"sourcesContent":["import { Command } from '@oclif/core';\nimport { execSync } from 'child_process';\nimport { ConfigStore } from '../config/config-store.js';\nimport { DaemonManager } from '../daemon/daemon-manager.js';\n\nexport default class Uninstall extends Command {\n static override description = 'Uninstall the Stamn agent';\n\n async run(): Promise<void> {\n const dm = new DaemonManager();\n const { running } = dm.isRunning();\n\n if (running) {\n this.log('Stopping daemon...');\n dm.stop();\n }\n\n this.log('Removing config...');\n const store = new ConfigStore();\n store.clear();\n\n this.log('Uninstalling...');\n execSync('npm rm -g @stamn/agent', { stdio: 'inherit' });\n\n this.log('Done.');\n }\n}\n"],"mappings":";;;;;;;;;;AAAA,SAAS,eAAe;AACxB,SAAS,gBAAgB;AAIzB,IAAqB,YAArB,cAAuC,QAAQ;AAAA,EAC7C,OAAgB,cAAc;AAAA,EAE9B,MAAM,MAAqB;AACzB,UAAM,KAAK,IAAI,cAAc;AAC7B,UAAM,EAAE,QAAQ,IAAI,GAAG,UAAU;AAEjC,QAAI,SAAS;AACX,WAAK,IAAI,oBAAoB;AAC7B,SAAG,KAAK;AAAA,IACV;AAEA,SAAK,IAAI,oBAAoB;AAC7B,UAAM,QAAQ,IAAI,YAAY;AAC9B,UAAM,MAAM;AAEZ,SAAK,IAAI,iBAAiB;AAC1B,aAAS,0BAA0B,EAAE,OAAO,UAAU,CAAC;AAEvD,SAAK,IAAI,OAAO;AAAA,EAClB;AACF;","names":[]}
|
package/dist/commands/update.js
CHANGED
|
@@ -6,13 +6,13 @@ import { execSync } from "child_process";
|
|
|
6
6
|
var Update = class extends Command {
|
|
7
7
|
static description = "Update the Stamn agent to the latest version";
|
|
8
8
|
async run() {
|
|
9
|
-
this.log(`Current version: ${"0.
|
|
9
|
+
this.log(`Current version: ${"0.8.0"}`);
|
|
10
10
|
this.log("Checking for updates...");
|
|
11
11
|
try {
|
|
12
12
|
const latest = execSync("npm view @stamn/agent version", {
|
|
13
13
|
encoding: "utf-8"
|
|
14
14
|
}).trim();
|
|
15
|
-
if (latest === "0.
|
|
15
|
+
if (latest === "0.8.0") {
|
|
16
16
|
this.log("Already on the latest version.");
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { createRequire } from "module"; const require = createRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// src/ui/device-login.tsx
|
|
4
|
+
import { render } from "ink";
|
|
5
|
+
|
|
6
|
+
// src/ui/components/device-login-wizard.tsx
|
|
7
|
+
import { useState, useEffect } from "react";
|
|
8
|
+
import { Box, Text } from "ink";
|
|
9
|
+
import { Spinner, StatusMessage } from "@inkjs/ui";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
var POLL_INTERVAL_MS = 5e3;
|
|
12
|
+
function DeviceLoginWizard({ onComplete, onError }) {
|
|
13
|
+
const [step, setStep] = useState("requesting");
|
|
14
|
+
const [flow, setFlow] = useState(null);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
let cancelled = false;
|
|
17
|
+
const initiate = async () => {
|
|
18
|
+
try {
|
|
19
|
+
const { SERVER_URL } = await import("../config-schema-BR4LGISX.js");
|
|
20
|
+
const res = await fetch(`${SERVER_URL}/v1/auth/device-codes`, {
|
|
21
|
+
method: "POST"
|
|
22
|
+
});
|
|
23
|
+
if (!res.ok) {
|
|
24
|
+
const body = await res.text();
|
|
25
|
+
throw new Error(body || `HTTP ${res.status}`);
|
|
26
|
+
}
|
|
27
|
+
const json = await res.json();
|
|
28
|
+
if (!cancelled) {
|
|
29
|
+
setFlow(json.data);
|
|
30
|
+
setStep("waiting");
|
|
31
|
+
}
|
|
32
|
+
} catch (err) {
|
|
33
|
+
if (cancelled) return;
|
|
34
|
+
const msg = err.message;
|
|
35
|
+
if (msg === "fetch failed" || msg.includes("ECONNREFUSED") || msg.includes("ENOTFOUND")) {
|
|
36
|
+
onError("Could not connect to Stamn. Check your network.");
|
|
37
|
+
} else {
|
|
38
|
+
onError(msg);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
initiate();
|
|
43
|
+
return () => {
|
|
44
|
+
cancelled = true;
|
|
45
|
+
};
|
|
46
|
+
}, []);
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (step !== "waiting" || !flow) return;
|
|
49
|
+
let cancelled = false;
|
|
50
|
+
const poll = async () => {
|
|
51
|
+
try {
|
|
52
|
+
const { SERVER_URL } = await import("../config-schema-BR4LGISX.js");
|
|
53
|
+
const res = await fetch(
|
|
54
|
+
`${SERVER_URL}/v1/auth/device-codes/${flow.deviceCode}`
|
|
55
|
+
);
|
|
56
|
+
if (!res.ok) return;
|
|
57
|
+
const json = await res.json();
|
|
58
|
+
if (cancelled) return;
|
|
59
|
+
if (json.data.status === "approved" && json.data.apiKey) {
|
|
60
|
+
setStep("registering");
|
|
61
|
+
await registerAgent(json.data.apiKey);
|
|
62
|
+
} else if (json.data.status === "expired") {
|
|
63
|
+
onError("Login code expired. Run `stamn login` again.");
|
|
64
|
+
}
|
|
65
|
+
} catch {
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const interval = setInterval(poll, POLL_INTERVAL_MS);
|
|
69
|
+
poll();
|
|
70
|
+
return () => {
|
|
71
|
+
cancelled = true;
|
|
72
|
+
clearInterval(interval);
|
|
73
|
+
};
|
|
74
|
+
}, [step, flow]);
|
|
75
|
+
const registerAgent = async (apiKey) => {
|
|
76
|
+
try {
|
|
77
|
+
const { SERVER_URL } = await import("../config-schema-BR4LGISX.js");
|
|
78
|
+
const res = await fetch(`${SERVER_URL}/v1/agents/register`, {
|
|
79
|
+
method: "POST",
|
|
80
|
+
headers: {
|
|
81
|
+
"Content-Type": "application/json",
|
|
82
|
+
Authorization: `Bearer ${apiKey}`
|
|
83
|
+
},
|
|
84
|
+
body: JSON.stringify({
|
|
85
|
+
platform: `${process.platform}-${process.arch}`
|
|
86
|
+
})
|
|
87
|
+
});
|
|
88
|
+
if (!res.ok) {
|
|
89
|
+
const body = await res.text();
|
|
90
|
+
throw new Error(body || `HTTP ${res.status}`);
|
|
91
|
+
}
|
|
92
|
+
const json = await res.json();
|
|
93
|
+
setStep("done");
|
|
94
|
+
onComplete({
|
|
95
|
+
agentId: json.data.id,
|
|
96
|
+
apiKey,
|
|
97
|
+
agentName: json.data.name
|
|
98
|
+
});
|
|
99
|
+
} catch (err) {
|
|
100
|
+
onError(err.message || "Registration failed");
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", padding: 1, children: [
|
|
104
|
+
/* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
105
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "stamn" }),
|
|
106
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " login" })
|
|
107
|
+
] }),
|
|
108
|
+
step === "requesting" && /* @__PURE__ */ jsx(Spinner, { label: "Requesting login code..." }),
|
|
109
|
+
step === "waiting" && flow && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
110
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
111
|
+
"Open",
|
|
112
|
+
" ",
|
|
113
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: flow.verificationUri })
|
|
114
|
+
] }),
|
|
115
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
116
|
+
"and enter code:",
|
|
117
|
+
" ",
|
|
118
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: flow.userCode })
|
|
119
|
+
] }),
|
|
120
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Spinner, { label: "Waiting for approval..." }) }),
|
|
121
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press Ctrl+C to cancel" }) })
|
|
122
|
+
] }),
|
|
123
|
+
step === "registering" && /* @__PURE__ */ jsx(Spinner, { label: "Approved! Registering agent..." }),
|
|
124
|
+
step === "done" && /* @__PURE__ */ jsx(StatusMessage, { variant: "success", children: "Logged in and agent registered." })
|
|
125
|
+
] });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/ui/device-login.tsx
|
|
129
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
130
|
+
function runDeviceLogin() {
|
|
131
|
+
return new Promise((resolve, reject) => {
|
|
132
|
+
const { unmount, waitUntilExit } = render(
|
|
133
|
+
/* @__PURE__ */ jsx2(
|
|
134
|
+
DeviceLoginWizard,
|
|
135
|
+
{
|
|
136
|
+
onComplete: (result) => {
|
|
137
|
+
unmount();
|
|
138
|
+
resolve(result);
|
|
139
|
+
},
|
|
140
|
+
onError: (message) => {
|
|
141
|
+
unmount();
|
|
142
|
+
reject(new Error(message));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
);
|
|
147
|
+
waitUntilExit().catch(reject);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
export {
|
|
151
|
+
runDeviceLogin
|
|
152
|
+
};
|
|
153
|
+
//# sourceMappingURL=device-login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/ui/device-login.tsx","../../src/ui/components/device-login-wizard.tsx"],"sourcesContent":["import { render } from 'ink';\nimport { DeviceLoginWizard } from './components/device-login-wizard.js';\n\nexport interface LoginResult {\n agentId: string;\n apiKey: string;\n agentName: string;\n}\n\nexport function runDeviceLogin(): Promise<LoginResult> {\n return new Promise((resolve, reject) => {\n const { unmount, waitUntilExit } = render(\n <DeviceLoginWizard\n onComplete={(result) => {\n unmount();\n resolve(result);\n }}\n onError={(message) => {\n unmount();\n reject(new Error(message));\n }}\n />,\n );\n\n waitUntilExit().catch(reject);\n });\n}\n","import { useState, useEffect } from 'react';\nimport { Box, Text } from 'ink';\nimport { Spinner, StatusMessage } from '@inkjs/ui';\n\ntype Step = 'requesting' | 'waiting' | 'registering' | 'done';\n\ninterface DeviceFlowData {\n deviceCode: string;\n userCode: string;\n verificationUri: string;\n expiresIn: number;\n}\n\ninterface Props {\n onComplete: (result: {\n agentId: string;\n apiKey: string;\n agentName: string;\n }) => void;\n onError: (message: string) => void;\n}\n\ndeclare const AGENT_VERSION: string;\n\nconst POLL_INTERVAL_MS = 5_000;\n\nexport function DeviceLoginWizard({ onComplete, onError }: Props) {\n const [step, setStep] = useState<Step>('requesting');\n const [flow, setFlow] = useState<DeviceFlowData | null>(null);\n\n // Step 1: Initiate device flow\n useEffect(() => {\n let cancelled = false;\n\n const initiate = async () => {\n try {\n const { SERVER_URL } = await import(\n '../../config/config-schema.js'\n );\n const res = await fetch(`${SERVER_URL}/v1/auth/device-codes`, {\n method: 'POST',\n });\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(body || `HTTP ${res.status}`);\n }\n\n const json = (await res.json()) as { data: DeviceFlowData };\n if (!cancelled) {\n setFlow(json.data);\n setStep('waiting');\n }\n } catch (err) {\n if (cancelled) return;\n const msg = (err as Error).message;\n if (\n msg === 'fetch failed' ||\n msg.includes('ECONNREFUSED') ||\n msg.includes('ENOTFOUND')\n ) {\n onError('Could not connect to Stamn. Check your network.');\n } else {\n onError(msg);\n }\n }\n };\n\n initiate();\n return () => {\n cancelled = true;\n };\n }, []);\n\n // Step 2: Poll for approval\n useEffect(() => {\n if (step !== 'waiting' || !flow) return;\n\n let cancelled = false;\n\n const poll = async () => {\n try {\n const { SERVER_URL } = await import(\n '../../config/config-schema.js'\n );\n const res = await fetch(\n `${SERVER_URL}/v1/auth/device-codes/${flow.deviceCode}`,\n );\n\n if (!res.ok) return;\n\n const json = (await res.json()) as {\n data: { status: string; apiKey?: string };\n };\n\n if (cancelled) return;\n\n if (json.data.status === 'approved' && json.data.apiKey) {\n setStep('registering');\n await registerAgent(json.data.apiKey);\n } else if (json.data.status === 'expired') {\n onError('Login code expired. Run `stamn login` again.');\n }\n } catch {\n // Silently retry on network errors during polling\n }\n };\n\n const interval = setInterval(poll, POLL_INTERVAL_MS);\n // First poll immediately\n poll();\n\n return () => {\n cancelled = true;\n clearInterval(interval);\n };\n }, [step, flow]);\n\n const registerAgent = async (apiKey: string) => {\n try {\n const { SERVER_URL } = await import(\n '../../config/config-schema.js'\n );\n const res = await fetch(`${SERVER_URL}/v1/agents/register`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n platform: `${process.platform}-${process.arch}`,\n }),\n });\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(body || `HTTP ${res.status}`);\n }\n\n const json = (await res.json()) as {\n data: { id: string; name: string };\n };\n\n setStep('done');\n onComplete({\n agentId: json.data.id,\n apiKey,\n agentName: json.data.name,\n });\n } catch (err) {\n onError((err as Error).message || 'Registration failed');\n }\n };\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Box marginBottom={1}>\n <Text bold color=\"cyan\">\n stamn\n </Text>\n <Text dimColor> login</Text>\n </Box>\n\n {step === 'requesting' && (\n <Spinner label=\"Requesting login code...\" />\n )}\n\n {step === 'waiting' && flow && (\n <Box flexDirection=\"column\">\n <Text>\n Open{' '}\n <Text bold color=\"cyan\">\n {flow.verificationUri}\n </Text>\n </Text>\n <Text>\n and enter code:{' '}\n <Text bold color=\"yellow\">\n {flow.userCode}\n </Text>\n </Text>\n <Box marginTop={1}>\n <Spinner label=\"Waiting for approval...\" />\n </Box>\n <Box marginTop={1}>\n <Text dimColor>Press Ctrl+C to cancel</Text>\n </Box>\n </Box>\n )}\n\n {step === 'registering' && (\n <Spinner label=\"Approved! Registering agent...\" />\n )}\n\n {step === 'done' && (\n <StatusMessage variant=\"success\">\n Logged in and agent registered.\n </StatusMessage>\n )}\n </Box>\n );\n}\n"],"mappings":"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","names":["jsx"]}
|
package/dist/ui/setup.js
CHANGED
|
@@ -8,7 +8,7 @@ import { useState } from "react";
|
|
|
8
8
|
import { Box, Text } from "ink";
|
|
9
9
|
import { TextInput, Spinner, StatusMessage } from "@inkjs/ui";
|
|
10
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
-
function SetupWizard({ onComplete }) {
|
|
11
|
+
function SetupWizard({ onComplete, onError }) {
|
|
12
12
|
const [step, setStep] = useState("api-key");
|
|
13
13
|
const [error, setError] = useState("");
|
|
14
14
|
const register = async (apiKey) => {
|
|
@@ -37,8 +37,12 @@ function SetupWizard({ onComplete }) {
|
|
|
37
37
|
agentName: json.data.name
|
|
38
38
|
});
|
|
39
39
|
} catch (err) {
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
const msg = err.message;
|
|
41
|
+
if (msg === "fetch failed" || msg.includes("ECONNREFUSED") || msg.includes("ENOTFOUND")) {
|
|
42
|
+
onError("Could not connect to Stamn. Is the server running?");
|
|
43
|
+
} else {
|
|
44
|
+
onError(msg);
|
|
45
|
+
}
|
|
42
46
|
}
|
|
43
47
|
};
|
|
44
48
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", padding: 1, children: [
|
|
@@ -69,13 +73,6 @@ function SetupWizard({ onComplete }) {
|
|
|
69
73
|
] }),
|
|
70
74
|
step === "registering" && /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Spinner, { label: "Registering agent..." }) }),
|
|
71
75
|
step === "done" && /* @__PURE__ */ jsx(StatusMessage, { variant: "success", children: "Agent registered. Starting..." }),
|
|
72
|
-
step === "error" && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
73
|
-
/* @__PURE__ */ jsxs(StatusMessage, { variant: "error", children: [
|
|
74
|
-
"Registration failed: ",
|
|
75
|
-
error
|
|
76
|
-
] }),
|
|
77
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Check your API key and try again." })
|
|
78
|
-
] }),
|
|
79
76
|
step === "api-key" && /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press Ctrl+C to cancel" }) })
|
|
80
77
|
] });
|
|
81
78
|
}
|
|
@@ -91,6 +88,10 @@ function runSetup() {
|
|
|
91
88
|
onComplete: (result) => {
|
|
92
89
|
unmount();
|
|
93
90
|
resolve(result);
|
|
91
|
+
},
|
|
92
|
+
onError: (message) => {
|
|
93
|
+
unmount();
|
|
94
|
+
reject(new Error(message));
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
)
|
package/dist/ui/setup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ui/setup.tsx","../../src/ui/components/setup-wizard.tsx"],"sourcesContent":["import { render } from 'ink';\nimport { SetupWizard } from './components/setup-wizard.js';\n\nexport interface SetupResult {\n agentId: string;\n apiKey: string;\n agentName: string;\n}\n\nexport function runSetup(): Promise<SetupResult> {\n return new Promise((resolve, reject) => {\n const { unmount, waitUntilExit } = render(\n <SetupWizard\n onComplete={(result) => {\n unmount();\n resolve(result);\n }}\n />,\n );\n\n waitUntilExit().catch(reject);\n });\n}\n","import { useState } from 'react';\nimport { Box, Text } from 'ink';\nimport { TextInput, Spinner, StatusMessage } from '@inkjs/ui';\n\ntype Step = 'api-key' | 'registering' | 'done'
|
|
1
|
+
{"version":3,"sources":["../../src/ui/setup.tsx","../../src/ui/components/setup-wizard.tsx"],"sourcesContent":["import { render } from 'ink';\nimport { SetupWizard } from './components/setup-wizard.js';\n\nexport interface SetupResult {\n agentId: string;\n apiKey: string;\n agentName: string;\n}\n\nexport function runSetup(): Promise<SetupResult> {\n return new Promise((resolve, reject) => {\n const { unmount, waitUntilExit } = render(\n <SetupWizard\n onComplete={(result) => {\n unmount();\n resolve(result);\n }}\n onError={(message) => {\n unmount();\n reject(new Error(message));\n }}\n />,\n );\n\n waitUntilExit().catch(reject);\n });\n}\n","import { useState } from 'react';\nimport { Box, Text } from 'ink';\nimport { TextInput, Spinner, StatusMessage } from '@inkjs/ui';\n\ntype Step = 'api-key' | 'registering' | 'done';\n\ninterface Props {\n onComplete: (result: { agentId: string; apiKey: string; agentName: string }) => void;\n onError: (message: string) => void;\n}\n\ndeclare const AGENT_VERSION: string;\n\nexport function SetupWizard({ onComplete, onError }: Props) {\n const [step, setStep] = useState<Step>('api-key');\n const [error, setError] = useState('');\n\n const register = async (apiKey: string) => {\n setStep('registering');\n\n try {\n const { SERVER_URL } = await import('../../config/config-schema.js');\n const res = await fetch(`${SERVER_URL}/v1/agents/register`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n platform: `${process.platform}-${process.arch}`,\n }),\n });\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(body || `HTTP ${res.status}`);\n }\n\n const json = (await res.json()) as {\n data: { id: string; name: string };\n };\n setStep('done');\n onComplete({\n agentId: json.data.id,\n apiKey,\n agentName: json.data.name,\n });\n } catch (err) {\n const msg = (err as Error).message;\n if (msg === 'fetch failed' || msg.includes('ECONNREFUSED') || msg.includes('ENOTFOUND')) {\n onError('Could not connect to Stamn. Is the server running?');\n } else {\n onError(msg);\n }\n }\n };\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Box marginBottom={1}>\n <Text bold color=\"cyan\">\n stamn\n </Text>\n <Text dimColor> setup</Text>\n </Box>\n\n {step === 'api-key' && (\n <Box flexDirection=\"column\">\n <Text>Enter your API key from the Stamn dashboard.</Text>\n <Box marginTop={1}>\n <Text color=\"cyan\">{\"> \"}</Text>\n <TextInput\n placeholder=\"sk-...\"\n onSubmit={(value: string) => {\n if (!value.trim()) {\n setError('API key cannot be empty');\n return;\n }\n setError('');\n register(value.trim());\n }}\n />\n </Box>\n {error && step === 'api-key' && (\n <StatusMessage variant=\"error\">{error}</StatusMessage>\n )}\n </Box>\n )}\n\n {step === 'registering' && (\n <Box>\n <Spinner label=\"Registering agent...\" />\n </Box>\n )}\n\n {step === 'done' && (\n <StatusMessage variant=\"success\">\n Agent registered. Starting...\n </StatusMessage>\n )}\n\n {step === 'api-key' && (\n <Box marginTop={1}>\n <Text dimColor>Press Ctrl+C to cancel</Text>\n </Box>\n )}\n </Box>\n );\n}\n"],"mappings":"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","names":["jsx"]}
|
package/package.json
CHANGED
|
File without changes
|