@ai-support-agent/cli 0.0.1

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.
Files changed (52) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/LICENSE +21 -0
  3. package/README.md +159 -0
  4. package/dist/agent-runner.d.ts +21 -0
  5. package/dist/agent-runner.d.ts.map +1 -0
  6. package/dist/agent-runner.js +251 -0
  7. package/dist/agent-runner.js.map +1 -0
  8. package/dist/api-client.d.ts +14 -0
  9. package/dist/api-client.d.ts.map +1 -0
  10. package/dist/api-client.js +112 -0
  11. package/dist/api-client.js.map +1 -0
  12. package/dist/auth-server.d.ts +12 -0
  13. package/dist/auth-server.d.ts.map +1 -0
  14. package/dist/auth-server.js +151 -0
  15. package/dist/auth-server.js.map +1 -0
  16. package/dist/command-executor.d.ts +3 -0
  17. package/dist/command-executor.d.ts.map +1 -0
  18. package/dist/command-executor.js +306 -0
  19. package/dist/command-executor.js.map +1 -0
  20. package/dist/config-manager.d.ts +18 -0
  21. package/dist/config-manager.d.ts.map +1 -0
  22. package/dist/config-manager.js +175 -0
  23. package/dist/config-manager.js.map +1 -0
  24. package/dist/constants.d.ts +30 -0
  25. package/dist/constants.d.ts.map +1 -0
  26. package/dist/constants.js +50 -0
  27. package/dist/constants.js.map +1 -0
  28. package/dist/i18n.d.ts +3 -0
  29. package/dist/i18n.d.ts.map +1 -0
  30. package/dist/i18n.js +109 -0
  31. package/dist/i18n.js.map +1 -0
  32. package/dist/index.d.ts +3 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +214 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/locales/en.json +78 -0
  37. package/dist/locales/ja.json +78 -0
  38. package/dist/locales/locales/en.json +78 -0
  39. package/dist/locales/locales/ja.json +78 -0
  40. package/dist/logger.d.ts +9 -0
  41. package/dist/logger.d.ts.map +1 -0
  42. package/dist/logger.js +41 -0
  43. package/dist/logger.js.map +1 -0
  44. package/dist/types.d.ts +82 -0
  45. package/dist/types.d.ts.map +1 -0
  46. package/dist/types.js +3 -0
  47. package/dist/types.js.map +1 -0
  48. package/dist/utils.d.ts +5 -0
  49. package/dist/utils.d.ts.map +1 -0
  50. package/dist/utils.js +32 -0
  51. package/dist/utils.js.map +1 -0
  52. package/package.json +51 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.0.1] - 2026-02-22
9
+
10
+ ### Added
11
+ - Initial public release
12
+ - Multi-project support with `login`, `add-project`, `remove-project` commands
13
+ - Browser-based OAuth authentication
14
+ - Agent heartbeat and command polling
15
+ - Command execution (shell, file read/write/list, process management)
16
+ - i18n support (English default, Japanese locale)
17
+ - Environment variable support (`AI_SUPPORT_AGENT_API_URL`, `AI_SUPPORT_AGENT_TOKEN`)
18
+ - Configuration management with `~/.ai-support-agent/config.json`
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 AI Support Agent Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,159 @@
1
+ # AI Support Agent CLI
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@ai-support-agent/cli.svg)](https://www.npmjs.com/package/@ai-support-agent/cli)
4
+ [![license](https://img.shields.io/npm/l/@ai-support-agent/cli.svg)](https://github.com/mbc-net/ai-support-agent-client/blob/main/LICENSE)
5
+
6
+ Multi-tenant AI support agent CLI that connects to your AI Support Agent server. It runs as a background agent on your machine, receiving and executing commands from the server while reporting results back in real time.
7
+
8
+ ## Features
9
+
10
+ - **Multi-project support** - Manage multiple projects under different tenants from a single CLI
11
+ - **Browser-based OAuth authentication** - Secure login via Cognito with automatic browser redirect
12
+ - **Remote command execution** - Execute shell commands, read/write files, and manage processes
13
+ - **Heartbeat monitoring** - Automatic health reporting to the server
14
+ - **i18n support** - English (default) and Japanese locales with OS locale auto-detection
15
+
16
+ ## Quick Start
17
+
18
+ ```bash
19
+ # Install globally
20
+ npm install -g @ai-support-agent/cli
21
+
22
+ # Login via browser OAuth
23
+ ai-support-agent login --url https://your-web-ui.example.com
24
+
25
+ # Start the agent
26
+ ai-support-agent start
27
+ ```
28
+
29
+ ## Commands
30
+
31
+ | Command | Description |
32
+ |---------|-------------|
33
+ | `start` | Start the agent and begin polling for commands |
34
+ | `login` | Authenticate with the server via browser-based OAuth |
35
+ | `add-project` | Add a project to the agent configuration |
36
+ | `remove-project` | Remove a project from the agent configuration |
37
+ | `configure` | Update agent configuration interactively |
38
+ | `set-language` | Set the display language (`en` or `ja`) |
39
+ | `status` | Show current agent status and configuration |
40
+
41
+ ### Start
42
+
43
+ ```bash
44
+ # Start with default settings
45
+ ai-support-agent start
46
+
47
+ # Start with verbose logging
48
+ ai-support-agent start --verbose
49
+
50
+ # Start with a specific project
51
+ ai-support-agent start --project my_project
52
+ ```
53
+
54
+ ### Login
55
+
56
+ ```bash
57
+ # Login via browser OAuth
58
+ ai-support-agent login --url https://your-web-ui.example.com
59
+
60
+ # Login with explicit API URL
61
+ ai-support-agent login --url https://your-web-ui.example.com --api-url https://api.example.com
62
+ ```
63
+
64
+ ### Project Management
65
+
66
+ ```bash
67
+ # Add another project via browser OAuth
68
+ ai-support-agent add-project --url https://your-web-ui.example.com
69
+
70
+ # Remove a project by code
71
+ ai-support-agent remove-project my_project
72
+
73
+ # Manual token setup (backward compatible)
74
+ ai-support-agent configure --token <token> --api-url <url> --project-code my_project
75
+ ```
76
+
77
+ ## Configuration File
78
+
79
+ The agent stores its configuration at `~/.ai-support-agent/config.json`:
80
+
81
+ ```json
82
+ {
83
+ "agentId": "hostname-a1b2",
84
+ "createdAt": "2025-01-01T00:00:00.000Z",
85
+ "lastConnected": "2025-01-01T12:00:00.000Z",
86
+ "language": "en",
87
+ "projects": [
88
+ {
89
+ "projectCode": "my_project",
90
+ "token": "agt_...",
91
+ "apiUrl": "https://api.example.com"
92
+ }
93
+ ]
94
+ }
95
+ ```
96
+
97
+ | Field | Description |
98
+ |-------|-------------|
99
+ | `agentId` | Auto-generated unique agent identifier (hostname + random hex) |
100
+ | `createdAt` | Timestamp when the config was first created |
101
+ | `lastConnected` | Timestamp of last successful connection |
102
+ | `language` | Display language (`en` or `ja`) |
103
+ | `projects` | Array of registered projects with `projectCode`, `token`, and `apiUrl` |
104
+
105
+ ## Environment Variables
106
+
107
+ | Variable | Description |
108
+ |----------|-------------|
109
+ | `AI_SUPPORT_AGENT_API_URL` | Override the server URL from config |
110
+ | `AI_SUPPORT_AGENT_TOKEN` | Override the auth token from config |
111
+
112
+ Environment variables have the lowest priority (CLI args > config file > env vars).
113
+
114
+ ## Language / i18n
115
+
116
+ The CLI supports English and Japanese. Language is determined in the following order:
117
+
118
+ 1. `--lang` flag on any command (e.g., `ai-support-agent start --lang ja`)
119
+ 2. Value set via `ai-support-agent set-language <lang>`
120
+ 3. Auto-detection from OS locale (`LANG`, `LC_ALL`, or `LC_MESSAGES`)
121
+ 4. Default: `en`
122
+
123
+ ```bash
124
+ # Set language to Japanese
125
+ ai-support-agent set-language ja
126
+
127
+ # Run a single command in Japanese
128
+ ai-support-agent status --lang ja
129
+ ```
130
+
131
+ ## Security
132
+
133
+ - **Config file permissions**: The configuration file is created with mode `0o600` (owner read/write only)
134
+ - **Localhost-only auth server**: The OAuth callback server binds to `127.0.0.1` and shuts down immediately after receiving the callback
135
+ - **CSRF nonce protection**: Each login flow generates a unique nonce to prevent cross-site request forgery
136
+
137
+ ## Development
138
+
139
+ ```bash
140
+ # Clone the repository
141
+ git clone https://github.com/mbc-net/ai-support-agent-client.git
142
+ cd ai-support-agent-client
143
+
144
+ # Install dependencies
145
+ npm install
146
+
147
+ # Run in development mode
148
+ npm run dev -- start --verbose
149
+
150
+ # Run tests
151
+ npm test
152
+
153
+ # Run tests with coverage
154
+ npm run test:cov
155
+ ```
156
+
157
+ ## License
158
+
159
+ [MIT](LICENSE)
@@ -0,0 +1,21 @@
1
+ import type { ProjectRegistration, SystemInfo } from './types';
2
+ export interface RunnerOptions {
3
+ token?: string;
4
+ apiUrl?: string;
5
+ pollInterval?: number;
6
+ heartbeatInterval?: number;
7
+ verbose?: boolean;
8
+ }
9
+ export declare function getSystemInfo(): SystemInfo;
10
+ export declare function getLocalIpAddress(): string | undefined;
11
+ export declare function startProjectAgent(project: ProjectRegistration, agentId: string, options: {
12
+ pollInterval: number;
13
+ heartbeatInterval: number;
14
+ }): {
15
+ stop: () => void;
16
+ };
17
+ export declare function setupShutdownHandlers(agents: {
18
+ stop: () => void;
19
+ }[]): void;
20
+ export declare function startAgent(options: RunnerOptions): Promise<void>;
21
+ //# sourceMappingURL=agent-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-runner.d.ts","sourceRoot":"","sources":["../src/agent-runner.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAG9D,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,aAAa,IAAI,UAAU,CAS1C;AAED,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAUtD;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,mBAAmB,EAC5B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IACP,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;CAC1B,GACA;IAAE,IAAI,EAAE,MAAM,IAAI,CAAA;CAAE,CAmGtB;AAYD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,IAAI,CAAA;CAAE,EAAE,GAAG,IAAI,CAS1E;AAiBD,wBAAsB,UAAU,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgFtE"}
@@ -0,0 +1,251 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getSystemInfo = getSystemInfo;
37
+ exports.getLocalIpAddress = getLocalIpAddress;
38
+ exports.startProjectAgent = startProjectAgent;
39
+ exports.setupShutdownHandlers = setupShutdownHandlers;
40
+ exports.startAgent = startAgent;
41
+ const os = __importStar(require("os"));
42
+ const api_client_1 = require("./api-client");
43
+ const constants_1 = require("./constants");
44
+ const command_executor_1 = require("./command-executor");
45
+ const config_manager_1 = require("./config-manager");
46
+ const i18n_1 = require("./i18n");
47
+ const logger_1 = require("./logger");
48
+ const utils_1 = require("./utils");
49
+ function getSystemInfo() {
50
+ const cpus = os.cpus();
51
+ return {
52
+ platform: os.platform(),
53
+ arch: os.arch(),
54
+ cpuUsage: cpus.length > 0 ? (os.loadavg()[0] / cpus.length) * 100 : 0,
55
+ memoryUsage: (1 - os.freemem() / os.totalmem()) * 100,
56
+ uptime: os.uptime(),
57
+ };
58
+ }
59
+ function getLocalIpAddress() {
60
+ const interfaces = os.networkInterfaces();
61
+ for (const name of Object.keys(interfaces)) {
62
+ for (const iface of interfaces[name] ?? []) {
63
+ if (iface.family === 'IPv4' && !iface.internal) {
64
+ return iface.address;
65
+ }
66
+ }
67
+ }
68
+ return undefined;
69
+ }
70
+ function startProjectAgent(project, agentId, options) {
71
+ const client = new api_client_1.ApiClient(project.apiUrl, project.token);
72
+ const prefix = `[${project.projectCode}]`;
73
+ let heartbeatTimer = null;
74
+ let pollTimer = null;
75
+ let processing = false;
76
+ // 1. Register
77
+ const registerAndStart = async () => {
78
+ try {
79
+ const result = await client.register({
80
+ agentId,
81
+ hostname: os.hostname(),
82
+ os: os.platform(),
83
+ arch: os.arch(),
84
+ ipAddress: getLocalIpAddress(),
85
+ });
86
+ logger_1.logger.success((0, i18n_1.t)('runner.registered', { prefix, agentId: result.agentId }));
87
+ }
88
+ catch (error) {
89
+ logger_1.logger.error((0, i18n_1.t)('runner.registerFailed', { prefix, message: (0, utils_1.getErrorMessage)(error) }));
90
+ return;
91
+ }
92
+ // 2. Heartbeat loop
93
+ const sendHeartbeat = async () => {
94
+ try {
95
+ await client.heartbeat(agentId, getSystemInfo());
96
+ logger_1.logger.debug(`${prefix} Heartbeat sent`);
97
+ }
98
+ catch (error) {
99
+ logger_1.logger.warn((0, i18n_1.t)('runner.heartbeatFailed', { prefix, message: (0, utils_1.getErrorMessage)(error) }));
100
+ }
101
+ };
102
+ heartbeatTimer = setInterval(() => {
103
+ void sendHeartbeat();
104
+ }, options.heartbeatInterval);
105
+ void sendHeartbeat();
106
+ // 3. Command polling loop
107
+ const pollCommands = async () => {
108
+ if (processing)
109
+ return;
110
+ processing = true;
111
+ try {
112
+ const pending = await client.getPendingCommands();
113
+ for (const cmd of pending) {
114
+ logger_1.logger.info((0, i18n_1.t)('runner.commandReceived', { prefix, type: cmd.type, commandId: cmd.commandId }));
115
+ try {
116
+ const detail = await client.getCommand(cmd.commandId);
117
+ const result = await (0, command_executor_1.executeCommand)(detail.type, detail.payload);
118
+ await client.submitResult(cmd.commandId, result);
119
+ logger_1.logger.info((0, i18n_1.t)('runner.commandDone', {
120
+ prefix,
121
+ commandId: cmd.commandId,
122
+ result: result.success ? 'success' : 'failed',
123
+ }));
124
+ }
125
+ catch (error) {
126
+ const message = (0, utils_1.getErrorMessage)(error);
127
+ logger_1.logger.error((0, i18n_1.t)('runner.commandError', { prefix, commandId: cmd.commandId, message }));
128
+ try {
129
+ await client.submitResult(cmd.commandId, {
130
+ success: false,
131
+ error: message,
132
+ });
133
+ }
134
+ catch {
135
+ logger_1.logger.error((0, i18n_1.t)('runner.resultSendFailed', { prefix }));
136
+ }
137
+ }
138
+ }
139
+ }
140
+ catch (error) {
141
+ logger_1.logger.debug(`${prefix} Polling error: ${(0, utils_1.getErrorMessage)(error)}`);
142
+ }
143
+ finally {
144
+ processing = false;
145
+ }
146
+ };
147
+ pollTimer = setInterval(() => {
148
+ void pollCommands();
149
+ }, options.pollInterval);
150
+ };
151
+ registerAndStart().catch((error) => {
152
+ logger_1.logger.error((0, i18n_1.t)('runner.unexpectedError', { message: (0, utils_1.getErrorMessage)(error) }));
153
+ });
154
+ return {
155
+ stop: () => {
156
+ if (heartbeatTimer)
157
+ clearInterval(heartbeatTimer);
158
+ if (pollTimer)
159
+ clearInterval(pollTimer);
160
+ },
161
+ };
162
+ }
163
+ function resolveIntervals(options) {
164
+ return {
165
+ pollInterval: options.pollInterval ?? constants_1.DEFAULT_POLL_INTERVAL,
166
+ heartbeatInterval: options.heartbeatInterval ?? constants_1.DEFAULT_HEARTBEAT_INTERVAL,
167
+ };
168
+ }
169
+ function setupShutdownHandlers(agents) {
170
+ const shutdown = () => {
171
+ logger_1.logger.info((0, i18n_1.t)('runner.shuttingDown'));
172
+ agents.forEach((a) => a.stop());
173
+ logger_1.logger.success((0, i18n_1.t)('runner.stopped'));
174
+ process.exit(0);
175
+ };
176
+ process.on('SIGINT', shutdown);
177
+ process.on('SIGTERM', shutdown);
178
+ }
179
+ function runSingleProject(project, agentId, options) {
180
+ const { pollInterval, heartbeatInterval } = resolveIntervals(options);
181
+ logger_1.logger.info((0, i18n_1.t)('runner.starting'));
182
+ const agent = startProjectAgent(project, agentId, { pollInterval, heartbeatInterval });
183
+ logger_1.logger.info((0, i18n_1.t)('runner.startedSingle', { pollInterval, heartbeatInterval }));
184
+ logger_1.logger.info((0, i18n_1.t)('runner.stopHint'));
185
+ setupShutdownHandlers([agent]);
186
+ }
187
+ async function startAgent(options) {
188
+ if (options.verbose) {
189
+ logger_1.logger.setVerbose(true);
190
+ }
191
+ const config = (0, config_manager_1.loadConfig)();
192
+ // Environment variable support (lowest priority)
193
+ const envToken = process.env.AI_SUPPORT_AGENT_TOKEN;
194
+ const envApiUrl = process.env.AI_SUPPORT_AGENT_API_URL;
195
+ // CLI args > config > env vars
196
+ if (options.token && options.apiUrl) {
197
+ const urlError = (0, utils_1.validateApiUrl)(options.apiUrl);
198
+ if (urlError) {
199
+ logger_1.logger.error(urlError);
200
+ process.exit(1);
201
+ }
202
+ logger_1.logger.warn((0, i18n_1.t)('runner.cliTokenWarning'));
203
+ const agentId = config?.agentId ?? os.hostname();
204
+ const project = {
205
+ projectCode: constants_1.PROJECT_CODE_CLI_DIRECT,
206
+ token: options.token,
207
+ apiUrl: options.apiUrl,
208
+ };
209
+ runSingleProject(project, agentId, options);
210
+ (0, config_manager_1.saveConfig)({ lastConnected: new Date().toISOString() });
211
+ return;
212
+ }
213
+ // Multi-project config
214
+ if (!config) {
215
+ // Fall back to env vars if no config
216
+ if (envToken && envApiUrl) {
217
+ const envUrlError = (0, utils_1.validateApiUrl)(envApiUrl);
218
+ if (envUrlError) {
219
+ logger_1.logger.error(envUrlError);
220
+ process.exit(1);
221
+ }
222
+ logger_1.logger.info((0, i18n_1.t)('runner.envTokenWarning'));
223
+ const project = {
224
+ projectCode: constants_1.PROJECT_CODE_ENV_DEFAULT,
225
+ token: envToken,
226
+ apiUrl: envApiUrl,
227
+ };
228
+ runSingleProject(project, os.hostname(), options);
229
+ return;
230
+ }
231
+ logger_1.logger.error((0, i18n_1.t)('runner.noToken'));
232
+ process.exit(1);
233
+ }
234
+ const projects = (0, config_manager_1.getProjectList)(config);
235
+ if (projects.length === 0) {
236
+ logger_1.logger.error((0, i18n_1.t)('runner.noProjects'));
237
+ process.exit(1);
238
+ }
239
+ const agentId = config.agentId ?? os.hostname();
240
+ const { pollInterval, heartbeatInterval } = resolveIntervals(options);
241
+ logger_1.logger.info((0, i18n_1.t)('runner.startingMulti', { count: projects.length }));
242
+ const agents = projects.map((project) => startProjectAgent(project, agentId, { pollInterval, heartbeatInterval }));
243
+ (0, config_manager_1.saveConfig)({ lastConnected: new Date().toISOString() });
244
+ logger_1.logger.info((0, i18n_1.t)('runner.startedMulti', { count: projects.length, pollInterval, heartbeatInterval }));
245
+ for (const p of projects) {
246
+ logger_1.logger.info(` - ${p.projectCode} (${p.apiUrl})`);
247
+ }
248
+ logger_1.logger.info((0, i18n_1.t)('runner.stopHint'));
249
+ setupShutdownHandlers(agents);
250
+ }
251
+ //# sourceMappingURL=agent-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-runner.js","sourceRoot":"","sources":["../src/agent-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { AgentCommand, CommandResult, PendingCommand, RegisterRequest, RegisterResponse, SystemInfo } from './types';
2
+ export declare class ApiClient {
3
+ private readonly client;
4
+ constructor(apiUrl: string, token: string);
5
+ private shouldRetry;
6
+ private withRetry;
7
+ register(request: RegisterRequest): Promise<RegisterResponse>;
8
+ heartbeat(agentId: string, systemInfo: SystemInfo): Promise<void>;
9
+ getPendingCommands(): Promise<PendingCommand[]>;
10
+ private validateCommandId;
11
+ getCommand(commandId: string): Promise<AgentCommand>;
12
+ submitResult(commandId: string, result: CommandResult): Promise<void>;
13
+ }
14
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,UAAU,EACX,MAAM,SAAS,CAAA;AAEhB,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;gBAE1B,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAgBzC,OAAO,CAAC,WAAW;YAcL,SAAS;IAqBjB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAgB7D,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAYjE,kBAAkB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAUrD,OAAO,CAAC,iBAAiB;IAMnB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAWpD,YAAY,CAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC;CAOjB"}
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ApiClient = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const constants_1 = require("./constants");
9
+ const logger_1 = require("./logger");
10
+ class ApiClient {
11
+ client;
12
+ constructor(apiUrl, token) {
13
+ const parsed = new URL(apiUrl);
14
+ if (parsed.protocol === 'http:' && parsed.hostname !== '127.0.0.1' && parsed.hostname !== 'localhost') {
15
+ logger_1.logger.warn('API URL uses HTTP (not HTTPS). Token may be transmitted in plain text.');
16
+ }
17
+ this.client = axios_1.default.create({
18
+ baseURL: apiUrl,
19
+ headers: {
20
+ Authorization: `Bearer ${token}`,
21
+ 'Content-Type': 'application/json',
22
+ },
23
+ timeout: constants_1.API_REQUEST_TIMEOUT,
24
+ });
25
+ }
26
+ shouldRetry(error) {
27
+ if (!axios_1.default.isAxiosError(error) || !error.response) {
28
+ return true; // Network error — retry
29
+ }
30
+ const status = error.response.status;
31
+ if (status === 408 || status === 429) {
32
+ return true; // Timeout / rate-limit — retry
33
+ }
34
+ if (status >= 500) {
35
+ return true; // Server error — retry
36
+ }
37
+ return false; // Other 4xx — do not retry
38
+ }
39
+ async withRetry(fn) {
40
+ let lastError;
41
+ for (let attempt = 0; attempt < constants_1.API_MAX_RETRIES; attempt++) {
42
+ try {
43
+ return await fn();
44
+ }
45
+ catch (error) {
46
+ lastError = error;
47
+ if (!this.shouldRetry(error)) {
48
+ throw error;
49
+ }
50
+ if (attempt < constants_1.API_MAX_RETRIES - 1) {
51
+ const baseDelay = constants_1.API_BASE_DELAY_MS * Math.pow(2, attempt);
52
+ const delay = Math.round(baseDelay * (0.5 + Math.random() * 0.5));
53
+ logger_1.logger.debug(`Request failed (attempt ${attempt + 1}/${constants_1.API_MAX_RETRIES}), retrying in ${delay}ms`);
54
+ await new Promise((resolve) => setTimeout(resolve, delay));
55
+ }
56
+ }
57
+ }
58
+ throw lastError;
59
+ }
60
+ async register(request) {
61
+ logger_1.logger.debug(`Registering agent: ${request.agentId}`);
62
+ return this.withRetry(async () => {
63
+ const { ipAddress, ...rest } = request;
64
+ const { data } = await this.client.post(constants_1.API_ENDPOINTS.REGISTER, {
65
+ ...rest,
66
+ version: constants_1.AGENT_VERSION,
67
+ ...(ipAddress && { ipAddress }),
68
+ });
69
+ return data;
70
+ });
71
+ }
72
+ async heartbeat(agentId, systemInfo) {
73
+ logger_1.logger.debug('Sending heartbeat');
74
+ await this.withRetry(async () => {
75
+ await this.client.post(constants_1.API_ENDPOINTS.HEARTBEAT, {
76
+ agentId,
77
+ timestamp: Date.now(),
78
+ version: constants_1.AGENT_VERSION,
79
+ systemInfo,
80
+ });
81
+ });
82
+ }
83
+ async getPendingCommands() {
84
+ logger_1.logger.debug('Polling for pending commands');
85
+ return this.withRetry(async () => {
86
+ const { data } = await this.client.get(constants_1.API_ENDPOINTS.COMMANDS_PENDING);
87
+ return data;
88
+ });
89
+ }
90
+ validateCommandId(commandId) {
91
+ if (!/^[a-zA-Z0-9_-]+$/.test(commandId)) {
92
+ throw new Error(`Invalid command ID format: ${commandId}`);
93
+ }
94
+ }
95
+ async getCommand(commandId) {
96
+ this.validateCommandId(commandId);
97
+ logger_1.logger.debug(`Fetching command: ${commandId}`);
98
+ return this.withRetry(async () => {
99
+ const { data } = await this.client.get(constants_1.API_ENDPOINTS.COMMAND(commandId));
100
+ return data;
101
+ });
102
+ }
103
+ async submitResult(commandId, result) {
104
+ this.validateCommandId(commandId);
105
+ logger_1.logger.debug(`Submitting result for command: ${commandId}`);
106
+ await this.withRetry(async () => {
107
+ await this.client.post(constants_1.API_ENDPOINTS.COMMAND_RESULT(commandId), result);
108
+ });
109
+ }
110
+ }
111
+ exports.ApiClient = ApiClient;
112
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export interface AuthResult {
2
+ token: string;
3
+ apiUrl?: string;
4
+ projectCode?: string;
5
+ }
6
+ export declare function startAuthServer(port?: number, allowedOrigin?: string): Promise<{
7
+ url: string;
8
+ nonce: string;
9
+ waitForCallback: () => Promise<AuthResult>;
10
+ stop: () => void;
11
+ }>;
12
+ //# sourceMappingURL=auth-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-server.d.ts","sourceRoot":"","sources":["../src/auth-server.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9E,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAA;IAC1C,IAAI,EAAE,MAAM,IAAI,CAAA;CACjB,CAAC,CA2HD"}