@moxxy/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.
- package/bin/moxxy.js +2 -0
- package/dist/chunk-2FZEA3NG.mjs +457 -0
- package/dist/chunk-CTBVTTBG.mjs +440 -0
- package/dist/chunk-TYD7NMMI.mjs +581 -0
- package/dist/cli-LY74GWKR.mjs +6 -0
- package/dist/cli-TNJHCBQA.mjs +6 -0
- package/dist/cli-XZ5RESNB.mjs +6 -0
- package/dist/index.d.mts +23 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +695 -0
- package/dist/index.mjs +16 -0
- package/package.json +70 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,695 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
11
|
+
var __export = (target, all) => {
|
|
12
|
+
for (var name in all)
|
|
13
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
+
};
|
|
15
|
+
var __copyProps = (to, from, except, desc) => {
|
|
16
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
+
for (let key of __getOwnPropNames(from))
|
|
18
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
31
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
|
+
|
|
33
|
+
// src/config/config-defaults.ts
|
|
34
|
+
var DEFAULT_CONFIG, CONFIG_DIR, CONFIG_FILE;
|
|
35
|
+
var init_config_defaults = __esm({
|
|
36
|
+
"src/config/config-defaults.ts"() {
|
|
37
|
+
"use strict";
|
|
38
|
+
DEFAULT_CONFIG = {
|
|
39
|
+
version: 1,
|
|
40
|
+
webhook: { port: 3456, host: "0.0.0.0", path: "/webhook/github" },
|
|
41
|
+
repos: []
|
|
42
|
+
};
|
|
43
|
+
CONFIG_DIR = ".moxxy";
|
|
44
|
+
CONFIG_FILE = "config.json";
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// src/config/config-manager.ts
|
|
49
|
+
var import_promises, import_node_fs, import_node_path, import_node_os, import_types, ConfigManager;
|
|
50
|
+
var init_config_manager = __esm({
|
|
51
|
+
"src/config/config-manager.ts"() {
|
|
52
|
+
"use strict";
|
|
53
|
+
import_promises = require("fs/promises");
|
|
54
|
+
import_node_fs = require("fs");
|
|
55
|
+
import_node_path = require("path");
|
|
56
|
+
import_node_os = require("os");
|
|
57
|
+
import_types = require("@moxxy/types");
|
|
58
|
+
init_config_defaults();
|
|
59
|
+
ConfigManager = class {
|
|
60
|
+
configPath;
|
|
61
|
+
config = null;
|
|
62
|
+
constructor(configDir) {
|
|
63
|
+
const base = configDir || (0, import_node_path.join)((0, import_node_os.homedir)(), CONFIG_DIR);
|
|
64
|
+
this.configPath = (0, import_node_path.join)(base, CONFIG_FILE);
|
|
65
|
+
}
|
|
66
|
+
async load() {
|
|
67
|
+
if (!(0, import_node_fs.existsSync)(this.configPath)) {
|
|
68
|
+
throw new Error(`Config not found at ${this.configPath}. Run 'moxxy config init' first.`);
|
|
69
|
+
}
|
|
70
|
+
const raw = await (0, import_promises.readFile)(this.configPath, "utf-8");
|
|
71
|
+
const parsed = JSON.parse(raw);
|
|
72
|
+
this.config = import_types.moxxyConfigSchema.parse(parsed);
|
|
73
|
+
return this.config;
|
|
74
|
+
}
|
|
75
|
+
async save(config) {
|
|
76
|
+
const dir = (0, import_node_path.join)(this.configPath, "..");
|
|
77
|
+
if (!(0, import_node_fs.existsSync)(dir)) {
|
|
78
|
+
await (0, import_promises.mkdir)(dir, { recursive: true });
|
|
79
|
+
}
|
|
80
|
+
this.config = import_types.moxxyConfigSchema.parse(config);
|
|
81
|
+
await (0, import_promises.writeFile)(this.configPath, JSON.stringify(this.config, null, 2) + "\n");
|
|
82
|
+
}
|
|
83
|
+
async init(config) {
|
|
84
|
+
const merged = { ...DEFAULT_CONFIG, ...config };
|
|
85
|
+
await this.save(merged);
|
|
86
|
+
return merged;
|
|
87
|
+
}
|
|
88
|
+
getConfig() {
|
|
89
|
+
if (!this.config) throw new Error("Config not loaded. Call load() first.");
|
|
90
|
+
return this.config;
|
|
91
|
+
}
|
|
92
|
+
async addRepo(repo) {
|
|
93
|
+
const config = this.getConfig();
|
|
94
|
+
const exists = config.repos.find((r) => r.owner === repo.owner && r.repo === repo.repo);
|
|
95
|
+
if (exists) throw new Error(`Repo ${repo.owner}/${repo.repo} already configured.`);
|
|
96
|
+
config.repos.push(repo);
|
|
97
|
+
await this.save(config);
|
|
98
|
+
}
|
|
99
|
+
async removeRepo(owner, repo) {
|
|
100
|
+
const config = this.getConfig();
|
|
101
|
+
config.repos = config.repos.filter((r) => !(r.owner === owner && r.repo === repo));
|
|
102
|
+
await this.save(config);
|
|
103
|
+
}
|
|
104
|
+
async set(key, value) {
|
|
105
|
+
const config = this.getConfig();
|
|
106
|
+
const keys = key.split(".");
|
|
107
|
+
let obj = config;
|
|
108
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
109
|
+
obj = obj[keys[i]] ??= {};
|
|
110
|
+
}
|
|
111
|
+
obj[keys[keys.length - 1]] = value;
|
|
112
|
+
await this.save(config);
|
|
113
|
+
}
|
|
114
|
+
get(key) {
|
|
115
|
+
const config = this.getConfig();
|
|
116
|
+
const keys = key.split(".");
|
|
117
|
+
let obj = config;
|
|
118
|
+
for (const k of keys) {
|
|
119
|
+
obj = obj?.[k];
|
|
120
|
+
}
|
|
121
|
+
return obj;
|
|
122
|
+
}
|
|
123
|
+
get path() {
|
|
124
|
+
return this.configPath;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// src/utils/logger.ts
|
|
131
|
+
function info(message) {
|
|
132
|
+
console.log(`${import_chalk.default.cyan("i")} ${message}`);
|
|
133
|
+
}
|
|
134
|
+
function success(message) {
|
|
135
|
+
console.log(`${import_chalk.default.green("\u2714")} ${message}`);
|
|
136
|
+
}
|
|
137
|
+
function error(message) {
|
|
138
|
+
console.error(`${import_chalk.default.red("\u2716")} ${message}`);
|
|
139
|
+
}
|
|
140
|
+
function warn(message) {
|
|
141
|
+
console.warn(`${import_chalk.default.yellow("\u26A0")} ${message}`);
|
|
142
|
+
}
|
|
143
|
+
function spinner(text) {
|
|
144
|
+
return (0, import_ora.default)({ text, color: "cyan" }).start();
|
|
145
|
+
}
|
|
146
|
+
function printBanner() {
|
|
147
|
+
console.log();
|
|
148
|
+
console.log(import_chalk.default.bold.cyan(" Moxxy"));
|
|
149
|
+
console.log(import_chalk.default.dim(" Agent orchestration platform"));
|
|
150
|
+
console.log();
|
|
151
|
+
}
|
|
152
|
+
function section(title) {
|
|
153
|
+
console.log();
|
|
154
|
+
console.log(import_chalk.default.bold(title));
|
|
155
|
+
console.log(import_chalk.default.dim("\u2500".repeat(title.length)));
|
|
156
|
+
}
|
|
157
|
+
function keyValue(key, value) {
|
|
158
|
+
console.log(` ${import_chalk.default.dim(key + ":")} ${value}`);
|
|
159
|
+
}
|
|
160
|
+
function listItem(text) {
|
|
161
|
+
console.log(` ${import_chalk.default.dim("\u2022")} ${text}`);
|
|
162
|
+
}
|
|
163
|
+
var import_chalk, import_ora;
|
|
164
|
+
var init_logger = __esm({
|
|
165
|
+
"src/utils/logger.ts"() {
|
|
166
|
+
"use strict";
|
|
167
|
+
import_chalk = __toESM(require("chalk"));
|
|
168
|
+
import_ora = __toESM(require("ora"));
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// src/commands/start.ts
|
|
173
|
+
async function createSDK(config) {
|
|
174
|
+
const provider = config.sdk || "molt";
|
|
175
|
+
const sdkName = SDK_NAMES[provider] || provider;
|
|
176
|
+
if (provider === "claude") {
|
|
177
|
+
const { ClaudeSDK } = await import("@moxxy/claude");
|
|
178
|
+
const claudeConfig = config.claude || {};
|
|
179
|
+
const sdk2 = await ClaudeSDK.create({
|
|
180
|
+
cliPath: claudeConfig.cliPath,
|
|
181
|
+
model: claudeConfig.model,
|
|
182
|
+
timeout: claudeConfig.timeout,
|
|
183
|
+
permissionMode: claudeConfig.permissionMode
|
|
184
|
+
});
|
|
185
|
+
return { sdk: sdk2, sdkName };
|
|
186
|
+
}
|
|
187
|
+
if (!config.gateway) {
|
|
188
|
+
throw new Error('Gateway configuration is required for the molt SDK. Run "moxxy config init --sdk molt --gateway-url <url>".');
|
|
189
|
+
}
|
|
190
|
+
const { MoltSDK } = await import("@moxxy/molt");
|
|
191
|
+
const sdk = await MoltSDK.create({
|
|
192
|
+
gatewayUrl: config.gateway.url,
|
|
193
|
+
authToken: config.gateway.authToken,
|
|
194
|
+
deviceId: config.gateway.deviceId,
|
|
195
|
+
devicePrivateKey: config.gateway.devicePrivateKey
|
|
196
|
+
});
|
|
197
|
+
return { sdk, sdkName };
|
|
198
|
+
}
|
|
199
|
+
function registerStartCommand(program) {
|
|
200
|
+
program.command("start").description("Start Moxxy orchestration").action(async () => {
|
|
201
|
+
const configManager = new ConfigManager();
|
|
202
|
+
try {
|
|
203
|
+
const config = await configManager.load();
|
|
204
|
+
printBanner();
|
|
205
|
+
const { MoltAgentSupervisor } = await import("@moxxy/agents");
|
|
206
|
+
const { IntegrationManager } = await import("@moxxy/integration-base");
|
|
207
|
+
const { GitHubIntegration } = await import("@moxxy/integration-github");
|
|
208
|
+
const provider = config.sdk || "molt";
|
|
209
|
+
const sdkName = SDK_NAMES[provider] || provider;
|
|
210
|
+
const connectSpinner = spinner(`Connecting to ${sdkName}`);
|
|
211
|
+
try {
|
|
212
|
+
const { sdk } = await createSDK(config);
|
|
213
|
+
connectSpinner.succeed(`Connected to ${sdkName}`);
|
|
214
|
+
const supervisorSpinner = spinner("Initializing agent supervisor");
|
|
215
|
+
const supervisor = new MoltAgentSupervisor(sdk);
|
|
216
|
+
const agentId = config.agent?.moltAgentId;
|
|
217
|
+
if (agentId) {
|
|
218
|
+
await supervisor.assignAgent(agentId, "developer");
|
|
219
|
+
supervisorSpinner.succeed(`Agent ${import_chalk.default.bold(agentId)} assigned`);
|
|
220
|
+
} else {
|
|
221
|
+
supervisorSpinner.succeed("Supervisor ready (no agent configured)");
|
|
222
|
+
}
|
|
223
|
+
const integrationManager = new IntegrationManager();
|
|
224
|
+
const github = new GitHubIntegration();
|
|
225
|
+
integrationManager.register(github);
|
|
226
|
+
integrationManager.on("*", (event) => {
|
|
227
|
+
info(
|
|
228
|
+
`${import_chalk.default.dim(`[${event.integration}]`)} ${event.type}: ${JSON.stringify(event.data).slice(0, 200)}`
|
|
229
|
+
);
|
|
230
|
+
});
|
|
231
|
+
const webhookConfig = config.webhook || {
|
|
232
|
+
port: 3456,
|
|
233
|
+
host: "0.0.0.0",
|
|
234
|
+
path: "/webhook/github"
|
|
235
|
+
};
|
|
236
|
+
const webhookSpinner = spinner("Starting webhook server");
|
|
237
|
+
await github.connect({
|
|
238
|
+
github: config.github,
|
|
239
|
+
webhook: webhookConfig,
|
|
240
|
+
sdk,
|
|
241
|
+
supervisor,
|
|
242
|
+
moltAgentId: agentId || ""
|
|
243
|
+
});
|
|
244
|
+
webhookSpinner.succeed(
|
|
245
|
+
`Webhook server listening on ${import_chalk.default.cyan(`${webhookConfig.host}:${webhookConfig.port}${webhookConfig.path}`)}`
|
|
246
|
+
);
|
|
247
|
+
if (config.repos.length > 0) {
|
|
248
|
+
const watchSpinner = spinner(
|
|
249
|
+
`Watching ${config.repos.length} repositories`
|
|
250
|
+
);
|
|
251
|
+
const targets = config.repos.map((r) => `${r.owner}/${r.repo}`);
|
|
252
|
+
await github.watch(targets);
|
|
253
|
+
watchSpinner.succeed(
|
|
254
|
+
`Watching ${import_chalk.default.bold(String(targets.length))} repositories: ${targets.join(", ")}`
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
console.log();
|
|
258
|
+
success(import_chalk.default.bold("Moxxy is running.") + " Press Ctrl+C to stop.");
|
|
259
|
+
const shutdown = async () => {
|
|
260
|
+
console.log();
|
|
261
|
+
info("Shutting down...");
|
|
262
|
+
await integrationManager.stopAll();
|
|
263
|
+
sdk.disconnect();
|
|
264
|
+
success("Shutdown complete.");
|
|
265
|
+
process.exit(0);
|
|
266
|
+
};
|
|
267
|
+
process.on("SIGINT", shutdown);
|
|
268
|
+
process.on("SIGTERM", shutdown);
|
|
269
|
+
await new Promise(() => {
|
|
270
|
+
});
|
|
271
|
+
} catch (innerErr) {
|
|
272
|
+
connectSpinner.fail(
|
|
273
|
+
`Failed to start: ${innerErr instanceof Error ? innerErr.message : innerErr}`
|
|
274
|
+
);
|
|
275
|
+
process.exitCode = 1;
|
|
276
|
+
}
|
|
277
|
+
} catch (err) {
|
|
278
|
+
error(`Failed to start: ${err instanceof Error ? err.message : err}`);
|
|
279
|
+
process.exitCode = 1;
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
var SDK_NAMES;
|
|
284
|
+
var init_start = __esm({
|
|
285
|
+
"src/commands/start.ts"() {
|
|
286
|
+
"use strict";
|
|
287
|
+
init_config_manager();
|
|
288
|
+
init_logger();
|
|
289
|
+
SDK_NAMES = {
|
|
290
|
+
molt: "Molt Gateway",
|
|
291
|
+
claude: "Claude CLI"
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
// src/commands/repo.ts
|
|
297
|
+
function registerRepoCommand(program) {
|
|
298
|
+
const repo = program.command("repo").description("Manage watched repositories");
|
|
299
|
+
repo.command("add").description("Add a repository to watch").argument("<repo>", "Repository in owner/repo format").option("--branch <branch>", "Default branch", "main").option("--events <events>", "Comma-separated events to watch", "issues.opened,issues.labeled").action(async (repoStr, options) => {
|
|
300
|
+
const [owner, name] = repoStr.split("/");
|
|
301
|
+
if (!owner || !name) {
|
|
302
|
+
error("Repository must be in owner/repo format");
|
|
303
|
+
process.exitCode = 1;
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
const manager = new ConfigManager();
|
|
307
|
+
try {
|
|
308
|
+
await manager.load();
|
|
309
|
+
await manager.addRepo({
|
|
310
|
+
owner,
|
|
311
|
+
repo: name,
|
|
312
|
+
defaultBranch: options.branch,
|
|
313
|
+
enabledEvents: options.events.split(",")
|
|
314
|
+
});
|
|
315
|
+
success(`Added ${import_chalk.default.bold(`${owner}/${name}`)}`);
|
|
316
|
+
} catch (err) {
|
|
317
|
+
error(`Failed: ${err instanceof Error ? err.message : err}`);
|
|
318
|
+
process.exitCode = 1;
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
repo.command("list").description("List watched repositories").action(async () => {
|
|
322
|
+
const manager = new ConfigManager();
|
|
323
|
+
try {
|
|
324
|
+
await manager.load();
|
|
325
|
+
const config = manager.getConfig();
|
|
326
|
+
if (config.repos.length === 0) {
|
|
327
|
+
info("No repositories configured.");
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
section(`Repositories (${config.repos.length})`);
|
|
331
|
+
for (const r of config.repos) {
|
|
332
|
+
listItem(
|
|
333
|
+
`${import_chalk.default.bold(`${r.owner}/${r.repo}`)} ${import_chalk.default.dim(`branch: ${r.defaultBranch}`)} ${import_chalk.default.dim(`events: ${r.enabledEvents.join(", ")}`)}`
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
console.log();
|
|
337
|
+
} catch (err) {
|
|
338
|
+
error(`Failed: ${err instanceof Error ? err.message : err}`);
|
|
339
|
+
process.exitCode = 1;
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
repo.command("remove").description("Remove a watched repository").argument("<repo>", "Repository in owner/repo format").action(async (repoStr) => {
|
|
343
|
+
const [owner, name] = repoStr.split("/");
|
|
344
|
+
if (!owner || !name) {
|
|
345
|
+
error("Repository must be in owner/repo format");
|
|
346
|
+
process.exitCode = 1;
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
const manager = new ConfigManager();
|
|
350
|
+
try {
|
|
351
|
+
await manager.load();
|
|
352
|
+
await manager.removeRepo(owner, name);
|
|
353
|
+
success(`Removed ${import_chalk.default.bold(`${owner}/${name}`)}`);
|
|
354
|
+
} catch (err) {
|
|
355
|
+
error(`Failed: ${err instanceof Error ? err.message : err}`);
|
|
356
|
+
process.exitCode = 1;
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
var init_repo = __esm({
|
|
361
|
+
"src/commands/repo.ts"() {
|
|
362
|
+
"use strict";
|
|
363
|
+
init_config_manager();
|
|
364
|
+
init_logger();
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
// src/utils/prompt.ts
|
|
369
|
+
async function interactiveInit() {
|
|
370
|
+
console.log();
|
|
371
|
+
console.log(import_chalk2.default.bold.cyan(" Moxxy Config Setup"));
|
|
372
|
+
console.log(import_chalk2.default.dim(" Answer the prompts below to initialize your configuration.\n"));
|
|
373
|
+
const { sdk } = await (0, import_prompts.default)({
|
|
374
|
+
type: "select",
|
|
375
|
+
name: "sdk",
|
|
376
|
+
message: "SDK provider",
|
|
377
|
+
choices: [
|
|
378
|
+
{ title: "Molt", value: "molt" },
|
|
379
|
+
{ title: "Claude", value: "claude" }
|
|
380
|
+
]
|
|
381
|
+
});
|
|
382
|
+
if (!sdk) return null;
|
|
383
|
+
let gatewayUrl;
|
|
384
|
+
let authToken;
|
|
385
|
+
let claudeApiKey;
|
|
386
|
+
let claudeModel;
|
|
387
|
+
let claudeCliPath;
|
|
388
|
+
if (sdk === "molt") {
|
|
389
|
+
const molt = await (0, import_prompts.default)([
|
|
390
|
+
{
|
|
391
|
+
type: "text",
|
|
392
|
+
name: "gatewayUrl",
|
|
393
|
+
message: "Gateway URL",
|
|
394
|
+
validate: (v) => v.length > 0 ? true : "Gateway URL is required"
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
type: "text",
|
|
398
|
+
name: "authToken",
|
|
399
|
+
message: "Auth token (optional, press Enter to skip)"
|
|
400
|
+
}
|
|
401
|
+
]);
|
|
402
|
+
if (!molt.gatewayUrl) return null;
|
|
403
|
+
gatewayUrl = molt.gatewayUrl;
|
|
404
|
+
authToken = molt.authToken || void 0;
|
|
405
|
+
} else {
|
|
406
|
+
const claude = await (0, import_prompts.default)([
|
|
407
|
+
{
|
|
408
|
+
type: "text",
|
|
409
|
+
name: "apiKey",
|
|
410
|
+
message: "Anthropic API key (optional, press Enter to skip)"
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
type: "text",
|
|
414
|
+
name: "model",
|
|
415
|
+
message: "Claude model",
|
|
416
|
+
initial: "claude-sonnet-4-5"
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
type: "text",
|
|
420
|
+
name: "cliPath",
|
|
421
|
+
message: "Claude CLI path",
|
|
422
|
+
initial: "claude"
|
|
423
|
+
}
|
|
424
|
+
]);
|
|
425
|
+
if (claude.model === void 0) return null;
|
|
426
|
+
claudeApiKey = claude.apiKey || void 0;
|
|
427
|
+
claudeModel = claude.model;
|
|
428
|
+
claudeCliPath = claude.cliPath;
|
|
429
|
+
}
|
|
430
|
+
const shared = await (0, import_prompts.default)([
|
|
431
|
+
{
|
|
432
|
+
type: "password",
|
|
433
|
+
name: "githubToken",
|
|
434
|
+
message: "GitHub personal access token",
|
|
435
|
+
validate: (v) => v.length > 0 ? true : "GitHub token is required"
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
type: "password",
|
|
439
|
+
name: "webhookSecret",
|
|
440
|
+
message: "Webhook secret (optional, press Enter to skip)"
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
type: "number",
|
|
444
|
+
name: "webhookPort",
|
|
445
|
+
message: "Webhook port",
|
|
446
|
+
initial: 3456
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
type: "text",
|
|
450
|
+
name: "agentId",
|
|
451
|
+
message: "Agent ID (optional, press Enter to skip)"
|
|
452
|
+
}
|
|
453
|
+
]);
|
|
454
|
+
if (!shared.githubToken) return null;
|
|
455
|
+
return {
|
|
456
|
+
sdk,
|
|
457
|
+
gatewayUrl,
|
|
458
|
+
authToken,
|
|
459
|
+
claudeApiKey,
|
|
460
|
+
claudeModel,
|
|
461
|
+
claudeCliPath,
|
|
462
|
+
githubToken: shared.githubToken,
|
|
463
|
+
webhookSecret: shared.webhookSecret || void 0,
|
|
464
|
+
webhookPort: String(shared.webhookPort ?? 3456),
|
|
465
|
+
agentId: shared.agentId || void 0
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
var import_prompts, import_chalk2;
|
|
469
|
+
var init_prompt = __esm({
|
|
470
|
+
"src/utils/prompt.ts"() {
|
|
471
|
+
"use strict";
|
|
472
|
+
import_prompts = __toESM(require("prompts"));
|
|
473
|
+
import_chalk2 = __toESM(require("chalk"));
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
// src/commands/config.ts
|
|
478
|
+
function registerConfigCommand(program) {
|
|
479
|
+
const config = program.command("config").description("Manage Moxxy configuration");
|
|
480
|
+
config.command("init").description("Initialize Moxxy configuration").option("--sdk <provider>", "SDK provider (molt or claude)").option("--github-token <token>", "GitHub personal access token").option("--gateway-url <url>", "Gateway URL (molt SDK)").option("--auth-token <token>", "Gateway auth token (molt SDK)").option("--claude-api-key <key>", "Anthropic API key (claude SDK)").option("--claude-model <model>", "Claude model (claude SDK)", "claude-sonnet-4-5").option("--claude-cli-path <path>", "Claude CLI path (claude SDK)", "claude").option("--webhook-secret <secret>", "GitHub webhook secret").option("--webhook-port <port>", "Webhook server port", "3456").option("--agent-id <id>", "Agent ID").action(async (options) => {
|
|
481
|
+
if (!options.sdk) {
|
|
482
|
+
const result = await interactiveInit();
|
|
483
|
+
if (!result) {
|
|
484
|
+
warn("Config init cancelled.");
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
options = { ...options, ...result };
|
|
488
|
+
}
|
|
489
|
+
const sdk = options.sdk;
|
|
490
|
+
if (sdk !== "molt" && sdk !== "claude") {
|
|
491
|
+
error('--sdk must be "molt" or "claude"');
|
|
492
|
+
process.exitCode = 1;
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
if (!options.githubToken) {
|
|
496
|
+
error("--github-token is required");
|
|
497
|
+
process.exitCode = 1;
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
if (sdk === "molt" && !options.gatewayUrl) {
|
|
501
|
+
error("--gateway-url is required when using the molt SDK");
|
|
502
|
+
process.exitCode = 1;
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
const manager = new ConfigManager();
|
|
506
|
+
try {
|
|
507
|
+
await manager.init({
|
|
508
|
+
version: 1,
|
|
509
|
+
sdk,
|
|
510
|
+
gateway: sdk === "molt" ? { url: options.gatewayUrl, authToken: options.authToken } : void 0,
|
|
511
|
+
github: { token: options.githubToken, webhookSecret: options.webhookSecret },
|
|
512
|
+
webhook: {
|
|
513
|
+
port: parseInt(options.webhookPort, 10),
|
|
514
|
+
host: "0.0.0.0",
|
|
515
|
+
path: "/webhook/github"
|
|
516
|
+
},
|
|
517
|
+
repos: [],
|
|
518
|
+
agent: options.agentId ? { moltAgentId: options.agentId } : void 0,
|
|
519
|
+
claude: sdk === "claude" ? {
|
|
520
|
+
apiKey: options.claudeApiKey,
|
|
521
|
+
cliPath: options.claudeCliPath,
|
|
522
|
+
model: options.claudeModel
|
|
523
|
+
} : void 0
|
|
524
|
+
});
|
|
525
|
+
success(`Config created at ${import_chalk.default.dim(manager.path)}`);
|
|
526
|
+
} catch (err) {
|
|
527
|
+
error(`Failed to init config: ${err instanceof Error ? err.message : err}`);
|
|
528
|
+
process.exitCode = 1;
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
config.command("set").description("Set a config value").argument("<key>", "Config key (dot notation)").argument("<value>", "Config value").action(async (key, value) => {
|
|
532
|
+
const manager = new ConfigManager();
|
|
533
|
+
try {
|
|
534
|
+
await manager.load();
|
|
535
|
+
let parsed = value;
|
|
536
|
+
try {
|
|
537
|
+
parsed = JSON.parse(value);
|
|
538
|
+
} catch {
|
|
539
|
+
}
|
|
540
|
+
await manager.set(key, parsed);
|
|
541
|
+
success(`Set ${import_chalk.default.bold(key)}`);
|
|
542
|
+
} catch (err) {
|
|
543
|
+
error(`Failed: ${err instanceof Error ? err.message : err}`);
|
|
544
|
+
process.exitCode = 1;
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
config.command("get").description("Get a config value").argument("<key>", "Config key (dot notation)").action(async (key) => {
|
|
548
|
+
const manager = new ConfigManager();
|
|
549
|
+
try {
|
|
550
|
+
await manager.load();
|
|
551
|
+
const value = manager.get(key);
|
|
552
|
+
console.log(import_chalk.default.cyan(JSON.stringify(value, null, 2)));
|
|
553
|
+
} catch (err) {
|
|
554
|
+
error(`Failed: ${err instanceof Error ? err.message : err}`);
|
|
555
|
+
process.exitCode = 1;
|
|
556
|
+
}
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
var init_config = __esm({
|
|
560
|
+
"src/commands/config.ts"() {
|
|
561
|
+
"use strict";
|
|
562
|
+
init_config_manager();
|
|
563
|
+
init_logger();
|
|
564
|
+
init_prompt();
|
|
565
|
+
}
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
// src/commands/status.ts
|
|
569
|
+
function registerStatusCommand(program) {
|
|
570
|
+
program.command("status").description("Show Moxxy configuration status").action(async () => {
|
|
571
|
+
const configManager = new ConfigManager();
|
|
572
|
+
try {
|
|
573
|
+
const config = await configManager.load();
|
|
574
|
+
printBanner();
|
|
575
|
+
const provider = config.sdk || "molt";
|
|
576
|
+
section("SDK");
|
|
577
|
+
keyValue("Provider", import_chalk.default.bold(provider));
|
|
578
|
+
if (provider === "molt" && config.gateway) {
|
|
579
|
+
section("Gateway");
|
|
580
|
+
keyValue("URL", import_chalk.default.cyan(config.gateway.url));
|
|
581
|
+
keyValue(
|
|
582
|
+
"Auth",
|
|
583
|
+
config.gateway.authToken ? import_chalk.default.green("configured") : import_chalk.default.dim("not set")
|
|
584
|
+
);
|
|
585
|
+
keyValue(
|
|
586
|
+
"Device",
|
|
587
|
+
config.gateway.deviceId || import_chalk.default.dim("not set")
|
|
588
|
+
);
|
|
589
|
+
}
|
|
590
|
+
if (provider === "claude" && config.claude) {
|
|
591
|
+
section("Claude");
|
|
592
|
+
keyValue(
|
|
593
|
+
"API Key",
|
|
594
|
+
config.claude.apiKey ? import_chalk.default.yellow("***" + config.claude.apiKey.slice(-4)) : import_chalk.default.dim("not set")
|
|
595
|
+
);
|
|
596
|
+
keyValue("CLI Path", import_chalk.default.cyan(config.claude.cliPath || "claude"));
|
|
597
|
+
keyValue("Model", import_chalk.default.cyan(config.claude.model || "claude-sonnet-4-5"));
|
|
598
|
+
}
|
|
599
|
+
section("GitHub");
|
|
600
|
+
keyValue(
|
|
601
|
+
"Token",
|
|
602
|
+
config.github.token ? import_chalk.default.yellow("***" + config.github.token.slice(-4)) : import_chalk.default.dim("not set")
|
|
603
|
+
);
|
|
604
|
+
keyValue(
|
|
605
|
+
"Webhook Secret",
|
|
606
|
+
config.github.webhookSecret ? import_chalk.default.green("configured") : import_chalk.default.dim("not set")
|
|
607
|
+
);
|
|
608
|
+
if (config.webhook) {
|
|
609
|
+
section("Webhook Server");
|
|
610
|
+
keyValue("Port", import_chalk.default.cyan(String(config.webhook.port)));
|
|
611
|
+
keyValue("Path", import_chalk.default.cyan(config.webhook.path));
|
|
612
|
+
}
|
|
613
|
+
section(`Repositories (${config.repos.length})`);
|
|
614
|
+
if (config.repos.length === 0) {
|
|
615
|
+
keyValue("", import_chalk.default.dim("None configured"));
|
|
616
|
+
} else {
|
|
617
|
+
for (const r of config.repos) {
|
|
618
|
+
listItem(
|
|
619
|
+
`${import_chalk.default.bold(`${r.owner}/${r.repo}`)} ${import_chalk.default.dim(`(${r.defaultBranch})`)}`
|
|
620
|
+
);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
if (config.agent) {
|
|
624
|
+
section("Agent");
|
|
625
|
+
keyValue(
|
|
626
|
+
"Agent ID",
|
|
627
|
+
config.agent.moltAgentId || import_chalk.default.dim("not set")
|
|
628
|
+
);
|
|
629
|
+
keyValue(
|
|
630
|
+
"Max Concurrent",
|
|
631
|
+
String(config.agent.maxConcurrentTasks || 1)
|
|
632
|
+
);
|
|
633
|
+
}
|
|
634
|
+
console.log();
|
|
635
|
+
} catch (err) {
|
|
636
|
+
error(`${err instanceof Error ? err.message : err}`);
|
|
637
|
+
process.exitCode = 1;
|
|
638
|
+
}
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
var init_status = __esm({
|
|
642
|
+
"src/commands/status.ts"() {
|
|
643
|
+
"use strict";
|
|
644
|
+
init_config_manager();
|
|
645
|
+
init_logger();
|
|
646
|
+
}
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
// src/cli.ts
|
|
650
|
+
var cli_exports = {};
|
|
651
|
+
__export(cli_exports, {
|
|
652
|
+
createProgram: () => createProgram
|
|
653
|
+
});
|
|
654
|
+
function createProgram() {
|
|
655
|
+
const program = new import_commander.Command();
|
|
656
|
+
program.name("moxxy").description("Moxxy - Agent orchestration platform").version("1.0.0");
|
|
657
|
+
registerStartCommand(program);
|
|
658
|
+
registerRepoCommand(program);
|
|
659
|
+
registerConfigCommand(program);
|
|
660
|
+
registerStatusCommand(program);
|
|
661
|
+
return program;
|
|
662
|
+
}
|
|
663
|
+
var import_commander;
|
|
664
|
+
var init_cli = __esm({
|
|
665
|
+
"src/cli.ts"() {
|
|
666
|
+
"use strict";
|
|
667
|
+
import_commander = require("commander");
|
|
668
|
+
init_start();
|
|
669
|
+
init_repo();
|
|
670
|
+
init_config();
|
|
671
|
+
init_status();
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
// src/index.ts
|
|
676
|
+
var index_exports = {};
|
|
677
|
+
__export(index_exports, {
|
|
678
|
+
ConfigManager: () => ConfigManager,
|
|
679
|
+
createProgram: () => createProgram,
|
|
680
|
+
run: () => run
|
|
681
|
+
});
|
|
682
|
+
module.exports = __toCommonJS(index_exports);
|
|
683
|
+
init_cli();
|
|
684
|
+
init_config_manager();
|
|
685
|
+
async function run() {
|
|
686
|
+
const { createProgram: createProgram2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
|
|
687
|
+
const program = createProgram2();
|
|
688
|
+
await program.parseAsync(process.argv);
|
|
689
|
+
}
|
|
690
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
691
|
+
0 && (module.exports = {
|
|
692
|
+
ConfigManager,
|
|
693
|
+
createProgram,
|
|
694
|
+
run
|
|
695
|
+
});
|