majlis 0.4.2 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +44 -23
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -2305,19 +2305,20 @@ ${contextJson}
2305
2305
 
2306
2306
  ${taskPrompt}`;
2307
2307
  const turns = ROLE_MAX_TURNS[role] ?? 15;
2308
- console.log(`[majlis] Spawning ${role} agent (model: ${agentDef.model}, maxTurns: ${turns})...`);
2308
+ console.log(`[${role}] Spawning (model: ${agentDef.model}, maxTurns: ${turns})...`);
2309
2309
  const { text: markdown, costUsd } = await runQuery({
2310
2310
  prompt,
2311
2311
  model: agentDef.model,
2312
2312
  tools: agentDef.tools,
2313
2313
  systemPrompt: agentDef.systemPrompt,
2314
2314
  cwd: root,
2315
- maxTurns: turns
2315
+ maxTurns: turns,
2316
+ label: role
2316
2317
  });
2317
- console.log(`[majlis] ${role} agent complete (cost: $${costUsd.toFixed(4)})`);
2318
+ console.log(`[${role}] Complete (cost: $${costUsd.toFixed(4)})`);
2318
2319
  const artifactPath = writeArtifact(role, context, markdown, root);
2319
2320
  if (artifactPath) {
2320
- console.log(`[majlis] ${role} artifact written to ${artifactPath}`);
2321
+ console.log(`[${role}] Artifact written to ${artifactPath}`);
2321
2322
  }
2322
2323
  const structured = await extractStructuredData(role, markdown);
2323
2324
  return { output: markdown, structured };
@@ -2334,20 +2335,21 @@ ${contextJson}
2334
2335
 
2335
2336
  ${taskPrompt}`;
2336
2337
  const systemPrompt = 'You are a Synthesis Agent. Be concrete: which decisions failed, which assumptions broke, what constraints must the next approach satisfy. CRITICAL: Your LAST line of output MUST be a <!-- majlis-json --> block. The framework parses this programmatically \u2014 if you omit it, the pipeline breaks. Format: <!-- majlis-json {"guidance": "your guidance here"} -->';
2337
- console.log(`[majlis] Spawning synthesiser micro-agent...`);
2338
+ console.log(`[synthesiser] Spawning (maxTurns: 5)...`);
2338
2339
  const { text: markdown, costUsd } = await runQuery({
2339
2340
  prompt,
2340
2341
  model: "opus",
2341
2342
  tools: ["Read", "Glob", "Grep"],
2342
2343
  systemPrompt,
2343
2344
  cwd: root,
2344
- maxTurns: 5
2345
+ maxTurns: 5,
2346
+ label: "synthesiser"
2345
2347
  });
2346
- console.log(`[majlis] Synthesiser complete (cost: $${costUsd.toFixed(4)})`);
2347
- const structured = await extractStructuredData("synthesiser", markdown);
2348
- return { output: markdown, structured };
2348
+ console.log(`[synthesiser] Complete (cost: $${costUsd.toFixed(4)})`);
2349
+ return { output: markdown, structured: { guidance: markdown } };
2349
2350
  }
2350
2351
  async function runQuery(opts) {
2352
+ const tag = opts.label ?? "majlis";
2351
2353
  const conversation = (0, import_claude_agent_sdk2.query)({
2352
2354
  prompt: opts.prompt,
2353
2355
  options: {
@@ -2381,21 +2383,21 @@ async function runQuery(opts) {
2381
2383
  const toolName = block.name ?? "tool";
2382
2384
  const input = block.input ?? {};
2383
2385
  const detail = formatToolDetail(toolName, input);
2384
- process.stderr.write(`${DIM2}[majlis] ${CYAN2}${toolName}${RESET2}${DIM2}${detail}${RESET2}
2386
+ process.stderr.write(`${DIM2}[${tag}] ${CYAN2}${toolName}${RESET2}${DIM2}${detail}${RESET2}
2385
2387
  `);
2386
2388
  }
2387
2389
  }
2388
2390
  if (hasText) {
2389
2391
  const preview = textParts[textParts.length - 1].slice(0, 120).replace(/\n/g, " ").trim();
2390
2392
  if (preview) {
2391
- process.stderr.write(`${DIM2}[majlis] writing: ${preview}${preview.length >= 120 ? "..." : ""}${RESET2}
2393
+ process.stderr.write(`${DIM2}[${tag}] writing: ${preview}${preview.length >= 120 ? "..." : ""}${RESET2}
2392
2394
  `);
2393
2395
  }
2394
2396
  }
2395
2397
  } else if (message.type === "tool_progress") {
2396
2398
  const elapsed = Math.round(message.elapsed_time_seconds);
2397
2399
  if (elapsed > 0 && elapsed % 5 === 0) {
2398
- process.stderr.write(`${DIM2}[majlis] ${message.tool_name} running (${elapsed}s)...${RESET2}
2400
+ process.stderr.write(`${DIM2}[${tag}] ${message.tool_name} running (${elapsed}s)...${RESET2}
2399
2401
  `);
2400
2402
  }
2401
2403
  } else if (message.type === "result") {
@@ -2403,7 +2405,7 @@ async function runQuery(opts) {
2403
2405
  costUsd = message.total_cost_usd;
2404
2406
  } else if (message.subtype === "error_max_turns") {
2405
2407
  costUsd = "total_cost_usd" in message ? message.total_cost_usd : 0;
2406
- console.warn(`[majlis] Agent hit max turns (${turnCount}). Returning partial output.`);
2408
+ console.warn(`[${tag}] Hit max turns (${turnCount}). Returning partial output.`);
2407
2409
  } else {
2408
2410
  const errors = "errors" in message ? message.errors?.join("; ") ?? "Unknown error" : "Unknown error";
2409
2411
  throw new Error(`Agent query failed (${message.subtype}): ${errors}`);
@@ -2455,7 +2457,7 @@ function writeArtifact(role, context, markdown, projectRoot) {
2455
2457
  }
2456
2458
  const expSlug = context.experiment?.slug ?? "general";
2457
2459
  const existing = fs7.readdirSync(fullDir).filter((f) => f.endsWith(".md") && !f.startsWith("_"));
2458
- const nextNum = String(existing.length + 1).padStart(3, "0");
2460
+ const nextNum = String(context.experiment?.id ?? existing.length + 1).padStart(3, "0");
2459
2461
  const filename = role === "builder" ? `${nextNum}-${expSlug}.md` : `${nextNum}-${role}-${expSlug}.md`;
2460
2462
  const target = path7.join(fullDir, filename);
2461
2463
  fs7.writeFileSync(target, markdown);
@@ -2472,12 +2474,12 @@ var init_spawn = __esm({
2472
2474
  init_connection();
2473
2475
  ROLE_MAX_TURNS = {
2474
2476
  builder: 50,
2475
- critic: 12,
2476
- adversary: 12,
2477
- verifier: 15,
2478
- compressor: 15,
2479
- reframer: 12,
2480
- scout: 12
2477
+ critic: 30,
2478
+ adversary: 30,
2479
+ verifier: 50,
2480
+ compressor: 30,
2481
+ reframer: 20,
2482
+ scout: 20
2481
2483
  };
2482
2484
  DIM2 = "\x1B[2m";
2483
2485
  RESET2 = "\x1B[0m";
@@ -2493,9 +2495,19 @@ function worstGrade(grades) {
2493
2495
  return "sound";
2494
2496
  }
2495
2497
  async function resolve(db, exp, projectRoot) {
2496
- const grades = getVerificationsByExperiment(db, exp.id);
2498
+ let grades = getVerificationsByExperiment(db, exp.id);
2497
2499
  if (grades.length === 0) {
2498
- throw new Error(`No verifications found for experiment ${exp.slug}. Run verify first.`);
2500
+ warn(`No verification records for ${exp.slug}. Defaulting to weak.`);
2501
+ insertVerification(
2502
+ db,
2503
+ exp.id,
2504
+ "auto-default",
2505
+ "weak",
2506
+ null,
2507
+ null,
2508
+ "No structured verification output. Auto-defaulted to weak."
2509
+ );
2510
+ grades = getVerificationsByExperiment(db, exp.id);
2499
2511
  }
2500
2512
  const overallGrade = worstGrade(grades);
2501
2513
  switch (overallGrade) {
@@ -3241,7 +3253,16 @@ async function run(args) {
3241
3253
  continue;
3242
3254
  }
3243
3255
  info(`[Step ${stepCount}] ${exp.slug}: ${exp.status}`);
3244
- await next([exp.slug], false);
3256
+ try {
3257
+ await next([exp.slug], false);
3258
+ } catch (err) {
3259
+ const message = err instanceof Error ? err.message : String(err);
3260
+ warn(`Step failed for ${exp.slug}: ${message}`);
3261
+ try {
3262
+ updateExperimentStatus(db, exp.id, "dead_end");
3263
+ } catch {
3264
+ }
3265
+ }
3245
3266
  }
3246
3267
  if (stepCount >= MAX_STEPS) {
3247
3268
  warn(`Reached max steps (${MAX_STEPS}). Stopping autonomous mode.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "majlis",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "description": "Multi-agent workflow CLI for structured doubt, independent verification, and compressed knowledge",
5
5
  "bin": {
6
6
  "majlis": "./dist/cli.js"