@moxxy/cli 0.0.6 → 0.0.8

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 CHANGED
@@ -1045,15 +1045,45 @@ var init_stream_parser = __esm({
1045
1045
  }
1046
1046
  try {
1047
1047
  return JSON.parse(line);
1048
- } catch (error2) {
1048
+ } catch {
1049
1049
  return null;
1050
1050
  }
1051
1051
  }
1052
1052
  /**
1053
1053
  * Convert stream event to chat stream chunk
1054
+ * Handles both CLI format and API format events
1054
1055
  */
1055
1056
  toChunk(event) {
1056
1057
  switch (event.type) {
1058
+ // --- Claude CLI format events ---
1059
+ case "assistant": {
1060
+ const message = event.message;
1061
+ if (!message?.content) return null;
1062
+ const textBlocks = message.content.filter((b) => b.type === "text");
1063
+ const text = textBlocks.map((b) => b.text || "").join("");
1064
+ const thinkingBlocks = message.content.filter((b) => b.type === "thinking");
1065
+ const thinking = thinkingBlocks.length > 0 ? thinkingBlocks.map((b) => b.thinking || b.text || "").join("") : void 0;
1066
+ if (!text && !thinking) return null;
1067
+ return {
1068
+ content: text,
1069
+ thinking,
1070
+ done: false,
1071
+ sessionKey: this.sessionKey,
1072
+ timestamp: Date.now()
1073
+ };
1074
+ }
1075
+ case "result": {
1076
+ const resultText = event.result || "";
1077
+ return {
1078
+ content: resultText,
1079
+ done: true,
1080
+ sessionKey: this.sessionKey,
1081
+ timestamp: Date.now()
1082
+ };
1083
+ }
1084
+ case "system":
1085
+ return null;
1086
+ // --- Anthropic API format events (legacy/fallback) ---
1057
1087
  case "content_block_delta": {
1058
1088
  const text = event.delta?.text || "";
1059
1089
  return {
@@ -1179,23 +1209,24 @@ var init_chat = __esm({
1179
1209
  });
1180
1210
  this.events.emit("chat:stream:start", sessionKey, agentId);
1181
1211
  options.onStart?.(sessionKey, agentId);
1182
- let proc = processManager.get(sessionKey);
1183
- if (!proc) {
1184
- proc = await processManager.spawn({
1185
- sessionKey,
1186
- model: transport.config.model,
1187
- thinking: options.thinking,
1188
- permissionMode: transport.config.permissionMode,
1189
- workingDirectory: transport.config.workingDirectory,
1190
- timeout: options.timeout
1191
- });
1212
+ const existingProc = processManager.get(sessionKey);
1213
+ if (existingProc) {
1214
+ processManager.kill(sessionKey);
1192
1215
  }
1216
+ const proc = await processManager.spawn({
1217
+ sessionKey,
1218
+ model: transport.config.model,
1219
+ thinking: options.thinking,
1220
+ permissionMode: transport.config.permissionMode,
1221
+ workingDirectory: transport.config.workingDirectory,
1222
+ timeout: options.timeout,
1223
+ message: options.message,
1224
+ outputFormat: "stream-json"
1225
+ });
1193
1226
  processManager.setStatus(sessionKey, "busy");
1194
1227
  let fullResponse = "";
1195
1228
  let thinking;
1196
1229
  try {
1197
- proc.process.stdin?.write(options.message + "\n");
1198
- proc.process.stdin?.end();
1199
1230
  const parser = new ClaudeStreamParser(sessionKey);
1200
1231
  for await (const chunk of parser.parseStream(proc.process.stdout)) {
1201
1232
  if (chunk.content) {
@@ -1392,25 +1423,32 @@ var init_process_manager = __esm({
1392
1423
  * Build CLI arguments
1393
1424
  */
1394
1425
  buildArgs(options) {
1426
+ const outputFormat = options.outputFormat || "json";
1395
1427
  const args = [
1396
1428
  "--print",
1397
- "--output-format=stream-json",
1398
- `--session-id=${options.sessionKey}`
1429
+ "--output-format",
1430
+ outputFormat
1399
1431
  ];
1432
+ if (outputFormat === "stream-json") {
1433
+ args.push("--verbose");
1434
+ }
1400
1435
  const model = options.model || this.config.model;
1401
1436
  if (model) {
1402
- args.push(`--model=${model}`);
1437
+ args.push("--model", model);
1403
1438
  }
1404
1439
  if (options.thinking && options.thinking !== "none") {
1405
- args.push(`--thinking=${options.thinking}`);
1440
+ args.push("--thinking", options.thinking);
1406
1441
  }
1407
1442
  const permissionMode = options.permissionMode || this.config.permissionMode;
1408
1443
  if (permissionMode) {
1409
- args.push(`--permission-mode=${permissionMode}`);
1444
+ args.push("--permission-mode", permissionMode);
1410
1445
  }
1411
1446
  const workingDir = options.workingDirectory || this.config.workingDirectory;
1412
1447
  if (workingDir) {
1413
- args.push(`--add-dir=${workingDir}`);
1448
+ args.push("--add-dir", workingDir);
1449
+ }
1450
+ if (options.message) {
1451
+ args.push(options.message);
1414
1452
  }
1415
1453
  return args;
1416
1454
  }
@@ -1708,7 +1746,6 @@ var init_cli = __esm({
1708
1746
  import_node_util = require("util");
1709
1747
  init_process_manager();
1710
1748
  init_session();
1711
- init_parsers();
1712
1749
  init_errors2();
1713
1750
  execAsync = (0, import_node_util.promisify)(import_node_child_process2.exec);
1714
1751
  CLITransport = class {
@@ -1833,6 +1870,7 @@ var init_cli = __esm({
1833
1870
  }
1834
1871
  /**
1835
1872
  * Handle chat.send request
1873
+ * Uses --output-format=json for single-shot responses
1836
1874
  */
1837
1875
  async handleChatSend(options) {
1838
1876
  const sessionKey = options.sessionKey || `claude-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
@@ -1844,26 +1882,37 @@ var init_cli = __esm({
1844
1882
  content: options.message,
1845
1883
  timestamp: Date.now()
1846
1884
  });
1847
- let proc = this.processManager.get(sessionKey);
1848
- if (!proc) {
1849
- proc = await this.processManager.spawn({
1850
- sessionKey,
1851
- model: this.config.model,
1852
- thinking: options.thinking,
1853
- permissionMode: this.config.permissionMode,
1854
- workingDirectory: this.config.workingDirectory,
1855
- timeout
1856
- });
1885
+ const existingProc = this.processManager.get(sessionKey);
1886
+ if (existingProc) {
1887
+ this.processManager.kill(sessionKey);
1857
1888
  }
1889
+ const proc = await this.processManager.spawn({
1890
+ sessionKey,
1891
+ model: this.config.model,
1892
+ thinking: options.thinking,
1893
+ permissionMode: this.config.permissionMode,
1894
+ workingDirectory: this.config.workingDirectory,
1895
+ timeout,
1896
+ message: options.message,
1897
+ outputFormat: "json"
1898
+ });
1858
1899
  this.processManager.setStatus(sessionKey, "busy");
1859
1900
  try {
1860
- proc.process.stdin?.write(options.message + "\n");
1861
- proc.process.stdin?.end();
1862
- const parser = new ClaudeStreamParser(sessionKey);
1863
- const { content, thinking } = await Promise.race([
1864
- parser.collectFullResponse(proc.process.stdout),
1901
+ const output = await Promise.race([
1902
+ this.collectStdout(proc.process),
1865
1903
  this.createTimeoutPromise(timeout)
1866
1904
  ]);
1905
+ let content = "";
1906
+ let thinking;
1907
+ try {
1908
+ const parsed = JSON.parse(output);
1909
+ content = parsed.result || "";
1910
+ if (parsed.thinking) {
1911
+ thinking = parsed.thinking;
1912
+ }
1913
+ } catch {
1914
+ content = output.trim();
1915
+ }
1867
1916
  this.sessionManager.addMessage(sessionKey, {
1868
1917
  role: "assistant",
1869
1918
  content,
@@ -1884,6 +1933,18 @@ var init_cli = __esm({
1884
1933
  throw error2;
1885
1934
  }
1886
1935
  }
1936
+ /**
1937
+ * Collect full stdout from a child process as a string
1938
+ */
1939
+ collectStdout(proc) {
1940
+ return new Promise((resolve, reject) => {
1941
+ const chunks = [];
1942
+ proc.stdout?.on("data", (chunk) => chunks.push(chunk));
1943
+ proc.stdout?.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8").trim()));
1944
+ proc.stdout?.on("error", reject);
1945
+ proc.on("error", reject);
1946
+ });
1947
+ }
1887
1948
  /**
1888
1949
  * Handle sessions.list request
1889
1950
  */
@@ -24280,9 +24341,42 @@ Handle any errors by adapting. Report the results of each step.`,
24280
24341
  const result = await supervisor.sendInstruction(agentId, instruction);
24281
24342
  return { response: result.response, sessionKey: result.sessionKey };
24282
24343
  }
24344
+ function extractJSON(response, stageName) {
24345
+ const fenceMatch = response.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
24346
+ if (fenceMatch) {
24347
+ try {
24348
+ return JSON.parse(fenceMatch[1].trim());
24349
+ } catch {
24350
+ }
24351
+ }
24352
+ const braceMatch = response.match(/\{[\s\S]*\}/);
24353
+ if (braceMatch) {
24354
+ try {
24355
+ return JSON.parse(braceMatch[0]);
24356
+ } catch {
24357
+ }
24358
+ }
24359
+ const firstBrace = response.indexOf("{");
24360
+ if (firstBrace !== -1) {
24361
+ let depth = 0;
24362
+ for (let i = firstBrace; i < response.length; i++) {
24363
+ if (response[i] === "{") depth++;
24364
+ else if (response[i] === "}") depth--;
24365
+ if (depth === 0) {
24366
+ try {
24367
+ return JSON.parse(response.slice(firstBrace, i + 1));
24368
+ } catch {
24369
+ break;
24370
+ }
24371
+ }
24372
+ }
24373
+ }
24374
+ const snippet = response.length > 200 ? `${response.slice(0, 200)}...` : response;
24375
+ throw new Error(`No valid JSON found in ${stageName} response. Response was: ${snippet}`);
24376
+ }
24283
24377
  async function inspectIssue(supervisor, agentId, payload, research) {
24284
24378
  const instruction = {
24285
- prompt: `Deeply inspect the following files for issue #${payload.issueNumber}: ${payload.title}
24379
+ prompt: `Deeply inspect the following files for issue #${payload.issueNumber}: ${payload.title}. You MUST respond with ONLY a raw JSON object \u2014 no markdown, no explanation, no code fences.
24286
24380
 
24287
24381
  Files to inspect:
24288
24382
  ${research.relevantFiles.map((f) => `- ${f}`).join("\n")}
@@ -24292,17 +24386,16 @@ Provide detailed analysis:
24292
24386
  2. Root cause or implementation location
24293
24387
  3. Required changes
24294
24388
 
24295
- Return JSON: {"findings": [...], "rootCause": "...", "suggestedApproach": "...", "estimatedChanges": [...]}`,
24389
+ Respond with exactly this JSON structure (no other text):
24390
+ {"findings": [...], "rootCause": "...", "suggestedApproach": "...", "estimatedChanges": [{"file": "...", "description": "..."}]}`,
24296
24391
  metadata: { stage: "inspect", issueNumber: payload.issueNumber }
24297
24392
  };
24298
24393
  const result = await supervisor.sendInstruction(agentId, instruction);
24299
- const jsonMatch = result.response.match(/\{[\s\S]*\}/);
24300
- if (!jsonMatch) throw new Error("No JSON found in inspect response");
24301
- return JSON.parse(jsonMatch[0]);
24394
+ return extractJSON(result.response, "inspect");
24302
24395
  }
24303
24396
  async function planIssue(supervisor, agentId, payload, inspection) {
24304
24397
  const instruction = {
24305
- prompt: `Create a detailed implementation plan for issue #${payload.issueNumber}: ${payload.title}
24398
+ prompt: `Create a detailed implementation plan for issue #${payload.issueNumber}: ${payload.title}. You MUST respond with ONLY a raw JSON object \u2014 no markdown, no explanation, no code fences.
24306
24399
 
24307
24400
  Inspection findings:
24308
24401
  ${JSON.stringify(inspection, null, 2)}
@@ -24312,17 +24405,16 @@ Create a step-by-step plan listing:
24312
24405
  2. Specific changes for each file
24313
24406
  3. Testing approach
24314
24407
 
24315
- Return JSON: {"steps": [{"action": "create|modify|delete", "path": "...", "description": "...", "content": "..."}], "testPlan": "...", "commitMessage": "..."}`,
24408
+ Respond with exactly this JSON structure (no other text):
24409
+ {"steps": [{"action": "create|modify|delete", "path": "...", "description": "...", "content": "..."}], "testPlan": "...", "commitMessage": "..."}`,
24316
24410
  metadata: { stage: "plan", issueNumber: payload.issueNumber }
24317
24411
  };
24318
24412
  const result = await supervisor.sendInstruction(agentId, instruction);
24319
- const jsonMatch = result.response.match(/\{[\s\S]*\}/);
24320
- if (!jsonMatch) throw new Error("No JSON found in plan response");
24321
- return JSON.parse(jsonMatch[0]);
24413
+ return extractJSON(result.response, "plan");
24322
24414
  }
24323
24415
  async function researchIssue(supervisor, agentId, payload, classification) {
24324
24416
  const instruction = {
24325
- prompt: `Research this ${classification.type} issue in the codebase.
24417
+ prompt: `Research this ${classification.type} issue in the codebase. You MUST respond with ONLY a raw JSON object \u2014 no markdown, no explanation, no code fences.
24326
24418
 
24327
24419
  Issue #${payload.issueNumber}: ${payload.title}
24328
24420
  ${payload.body || ""}
@@ -24334,29 +24426,27 @@ Analyze the codebase and identify:
24334
24426
  2. Dependencies and related modules
24335
24427
  3. Potential impact areas
24336
24428
 
24337
- Return JSON: {"relevantFiles": [...], "relatedModules": [...], "potentialImpact": "...", "techStack": [...]}`,
24429
+ Respond with exactly this JSON structure (no other text):
24430
+ {"relevantFiles": [...], "relatedModules": [...], "potentialImpact": "...", "techStack": [...]}`,
24338
24431
  metadata: { stage: "research", issueNumber: payload.issueNumber }
24339
24432
  };
24340
24433
  const result = await supervisor.sendInstruction(agentId, instruction);
24341
- const jsonMatch = result.response.match(/\{[\s\S]*\}/);
24342
- if (!jsonMatch) throw new Error("No JSON found in research response");
24343
- return JSON.parse(jsonMatch[0]);
24434
+ return extractJSON(result.response, "research");
24344
24435
  }
24345
24436
  async function triageIssue(supervisor, agentId, payload) {
24346
24437
  const instruction = {
24347
- prompt: `Classify this GitHub issue. Return ONLY a JSON object.
24438
+ prompt: `Classify this GitHub issue. You MUST respond with ONLY a raw JSON object \u2014 no markdown, no explanation, no code fences.
24348
24439
 
24349
24440
  Issue #${payload.issueNumber}: ${payload.title}
24350
24441
  ${payload.body || "No description provided."}
24351
24442
  Labels: ${payload.labels.join(", ") || "none"}
24352
24443
 
24353
- Return JSON: {"type": "feature|bug|refactor|docs|test|chore", "priority": "low|medium|high|urgent", "complexity": "trivial|small|medium|large|epic", "confidence": 0.0-1.0, "reasoning": "..."}`,
24444
+ Respond with exactly this JSON structure (no other text):
24445
+ {"type": "feature|bug|refactor|docs|test|chore", "priority": "low|medium|high|urgent", "complexity": "trivial|small|medium|large|epic", "confidence": 0.0-1.0, "reasoning": "..."}`,
24354
24446
  metadata: { stage: "triage", issueNumber: payload.issueNumber }
24355
24447
  };
24356
24448
  const result = await supervisor.sendInstruction(agentId, instruction);
24357
- const jsonMatch = result.response.match(/\{[\s\S]*\}/);
24358
- if (!jsonMatch) throw new Error("No JSON found in triage response");
24359
- return JSON.parse(jsonMatch[0]);
24449
+ return extractJSON(result.response, "triage");
24360
24450
  }
24361
24451
  function buildWorkflow(payload, plan, branchName) {
24362
24452
  const steps = [];
@@ -25116,7 +25206,7 @@ __export(cli_exports, {
25116
25206
  });
25117
25207
  function createProgram() {
25118
25208
  const program = new import_commander.Command();
25119
- program.name("moxxy").description("Moxxy - Agent orchestration platform").version("0.0.6");
25209
+ program.name("moxxy").description("Moxxy - Agent orchestration platform").version("0.0.8");
25120
25210
  registerStartCommand(program);
25121
25211
  registerRepoCommand(program);
25122
25212
  registerConfigCommand(program);
package/dist/index.mjs CHANGED
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  ConfigManager,
3
3
  createProgram
4
- } from "./chunk-CAUXONEF.mjs";
4
+ } from "./chunk-S7YBOV7E.mjs";
5
5
  import "./chunk-GSNMMI3H.mjs";
6
6
  import "./chunk-6DZX6EAA.mjs";
7
7
 
8
8
  // src/index.ts
9
9
  async function run() {
10
- const { createProgram: createProgram2 } = await import("./cli-CGO2LZ6Z.mjs");
10
+ const { createProgram: createProgram2 } = await import("./cli-REVD6ISM.mjs");
11
11
  const program = createProgram2();
12
12
  await program.parseAsync(process.argv);
13
13
  }