@kernlang/agon 0.1.3 → 0.1.4

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.
@@ -380,6 +380,7 @@ var DEFAULT_AGON_CONFIG = {
380
380
  allowedCommands: [],
381
381
  toolPermissions: {},
382
382
  hiddenEngines: [],
383
+ removedEngines: [],
383
384
  engineModels: {},
384
385
  engineEfforts: {},
385
386
  engineIsolation: "workspace-pure",
@@ -396,6 +397,7 @@ var DEFAULT_AGON_CONFIG = {
396
397
  var DEFAULT_CONFIG = DEFAULT_AGON_CONFIG;
397
398
 
398
399
  // ../core/src/generated/models/errors.ts
400
+ var AGON_MODE_NAMES = ["forge", "brainstorm", "tribunal", "campfire", "council", "synthesis", "conquer", "goal", "agent", "pipeline", "review", "nero", "think"];
399
401
  var AgonError = class extends Error {
400
402
  constructor(message) {
401
403
  super(message);
@@ -404,7 +406,8 @@ var AgonError = class extends Error {
404
406
  };
405
407
  var EngineNotFoundError = class extends AgonError {
406
408
  constructor(engineId, installHint) {
407
- const hint = installHint ? `. Install: ${installHint}` : "";
409
+ const modeId = engineId.toLowerCase();
410
+ const hint = AGON_MODE_NAMES.includes(modeId) ? `. "${engineId}" is an Agon mode (a command), not an engine \u2014 run /${modeId} instead. Engines are backends like codex, claude, or agy.` : installHint ? `. Install: ${installHint}` : "";
408
411
  super(`Engine "${engineId}" not found${hint}`);
409
412
  this.engineId = engineId;
410
413
  this.installHint = installHint;
@@ -504,6 +507,7 @@ function loadConfig(cwd) {
504
507
  const merged = { ...DEFAULT_AGON_CONFIG, ...global, ...local, ...localPrivate };
505
508
  if (!Array.isArray(merged.forgeEnabledEngines)) merged.forgeEnabledEngines = [];
506
509
  if (!Array.isArray(merged.hiddenEngines)) merged.hiddenEngines = [];
510
+ if (!Array.isArray(merged.removedEngines)) merged.removedEngines = [];
507
511
  if (!["auto", "explicit"].includes(String(merged.engineActivationMode))) merged.engineActivationMode = "auto";
508
512
  if (!merged.hooks || typeof merged.hooks === "string") merged.hooks = {};
509
513
  if (!merged.allowedCommands || typeof merged.allowedCommands === "string") merged.allowedCommands = [];
@@ -16361,8 +16365,8 @@ var EngineRegistry = class {
16361
16365
  return this.availableEngines().map((e) => e.id);
16362
16366
  }
16363
16367
  activeEngines(config2) {
16364
- const hidden = new Set(config2?.hiddenEngines ?? []);
16365
- const available = this.availableEngines().filter((e) => !hidden.has(e.id));
16368
+ const excluded = /* @__PURE__ */ new Set([...config2?.hiddenEngines ?? [], ...config2?.removedEngines ?? []]);
16369
+ const available = this.availableEngines().filter((e) => !excluded.has(e.id));
16366
16370
  if (!config2 || config2.engineActivationMode !== "explicit") {
16367
16371
  return available;
16368
16372
  }
@@ -16372,6 +16376,24 @@ var EngineRegistry = class {
16372
16376
  activeIds(config2) {
16373
16377
  return this.activeEngines(config2).map((e) => e.id);
16374
16378
  }
16379
+ partitionRoster(requested, config2) {
16380
+ if (!requested) {
16381
+ return { active: this.activeIds(config2), removed: [] };
16382
+ }
16383
+ const removedSet = new Set(config2?.removedEngines ?? []);
16384
+ const active = [];
16385
+ const removed = [];
16386
+ for (const raw of requested) {
16387
+ const id = this.resolveId(String(raw ?? "").trim());
16388
+ if (id && removedSet.has(id) && !removed.includes(id)) {
16389
+ removed.push(id);
16390
+ }
16391
+ if (id && !removedSet.has(id) && !active.includes(id)) {
16392
+ active.push(id);
16393
+ }
16394
+ }
16395
+ return { active, removed };
16396
+ }
16375
16397
  pickStarter(available, strategy, preferred) {
16376
16398
  if (available.length === 0) {
16377
16399
  throw new EngineNotFoundError("(any)", "No engines available");
@@ -16408,6 +16430,25 @@ var EngineRegistry = class {
16408
16430
  // ../core/src/generated/blocks/context-scanner.ts
16409
16431
  import { readFileSync as readFileSync8, readdirSync as readdirSync6, statSync as statSync6, existsSync as existsSync6 } from "fs";
16410
16432
  import { join as join9, basename } from "path";
16433
+ var PROJECT_BRIEF_FILES = [".agon/project.md", "AGON.md", "AGENT.md", "CLAUDE.md", "CODEX.md"];
16434
+ var MAX_PROJECT_BRIEF_BYTES = 512 * 1024;
16435
+ function projectBriefCap(file2) {
16436
+ return file2 === ".agon/project.md" || file2 === "AGON.md" ? 4e3 : 2e3;
16437
+ }
16438
+ function hasProjectBrief(cwd) {
16439
+ for (const file2 of PROJECT_BRIEF_FILES) {
16440
+ try {
16441
+ const path = join9(cwd, file2);
16442
+ const st = existsSync6(path) ? statSync6(path) : null;
16443
+ if (st && st.isFile() && st.size > 0) {
16444
+ if (st.size > MAX_PROJECT_BRIEF_BYTES) return true;
16445
+ if (readFileSync8(path, "utf-8").trim().length > 0) return true;
16446
+ }
16447
+ } catch {
16448
+ }
16449
+ }
16450
+ return false;
16451
+ }
16411
16452
  function isKernProject(cwd) {
16412
16453
  if (existsSync6(join9(cwd, "kern.config.ts"))) return true;
16413
16454
  try {
@@ -16519,14 +16560,15 @@ ${tree}`);
16519
16560
  ${diff}`);
16520
16561
  }
16521
16562
  }
16522
- const instructionFiles = ["AGON.md", "AGENT.md", "CLAUDE.md", "CODEX.md"];
16523
- for (const file2 of instructionFiles) {
16563
+ for (const file2 of PROJECT_BRIEF_FILES) {
16524
16564
  try {
16525
16565
  const path = join9(cwd, file2);
16526
16566
  if (existsSync6(path)) {
16527
16567
  const content = readFileSync8(path, "utf-8").trim();
16528
16568
  if (content) {
16529
- const capped = content.length > 2e3 ? content.slice(0, 2e3) + "\n... (truncated)" : content;
16569
+ const cap = projectBriefCap(file2);
16570
+ const capped = content.length > cap ? content.slice(0, cap) + `
16571
+ ... (truncated at ${cap} chars)` : content;
16530
16572
  sections.push(`Project instructions (${file2}):
16531
16573
  ${capped}`);
16532
16574
  break;
@@ -19642,6 +19684,13 @@ function extractBaseCommand(command) {
19642
19684
  }
19643
19685
  return cmd;
19644
19686
  }
19687
+ function guiUnavailableHint(command, stderr) {
19688
+ const cmd = (command ?? "").trim();
19689
+ const launchesGui = /(^|\s)electron(\s|$)/i.test(cmd) || /(^|\s)(pnpm|npm|yarn|bun)\s+(run\s+)?(studio|gui)(\s|$)/i.test(cmd);
19690
+ const displayFailure = /(DISPLAY\s+not\s+set|cannot\s+open\s+display|Missing X server)/i.test(stderr ?? "");
19691
+ if (!launchesGui && !displayFailure) return null;
19692
+ return "This looks like a GUI/desktop app, which cannot run in this headless shell. Use a headless equivalent (a build/test/CLI script, or a --headless flag), or run the GUI on your own machine.";
19693
+ }
19645
19694
  function createBashTool() {
19646
19695
  const definition = {
19647
19696
  name: "Bash",
@@ -19758,19 +19807,23 @@ function createBashTool() {
19758
19807
  }
19759
19808
  const durationMs = Date.now() - start;
19760
19809
  const exitCode = closeResult?.exitCode ?? 1;
19810
+ const guiHint = guiUnavailableHint(command, stderr);
19761
19811
  if (closeResult?.timedOut) {
19762
19812
  return {
19763
19813
  ok: false,
19764
19814
  content: stdout,
19765
- error: `Command timed out after ${timeout}ms`,
19815
+ error: `Command timed out after ${timeout}ms` + (guiHint ? `
19816
+ ${guiHint}` : ""),
19766
19817
  metadata: { exitCode: 124, durationMs, timedOut: true }
19767
19818
  };
19768
19819
  }
19769
19820
  if (exitCode !== 0) {
19821
+ const baseErr = stderr || `Process exited with code ${exitCode}`;
19770
19822
  return {
19771
19823
  ok: false,
19772
19824
  content: stdout,
19773
- error: stderr || `Process exited with code ${exitCode}`,
19825
+ error: guiHint ? `${baseErr}
19826
+ ${guiHint}` : baseErr,
19774
19827
  metadata: { exitCode, durationMs, timedOut: false }
19775
19828
  };
19776
19829
  }
@@ -29000,12 +29053,14 @@ function registerBuiltinCommands(registry2) {
29000
29053
  { name: "chats", desc: "[id|resume <id>] \u2014 chat history or resume session", category: "info" },
29001
29054
  { name: "jobs", desc: " \u2014 list running/completed jobs", category: "info" },
29002
29055
  { name: "focus", desc: "<id> \u2014 switch to background job output", category: "info" },
29056
+ { name: "update", desc: "[version] [--check] \u2014 self-update from npm (also runs from the in-app banner)", category: "info" },
29003
29057
  // Session
29004
29058
  { name: "mcp", desc: "connect <name|url> | disconnect | list \u2014 manage session MCP servers", category: "session" },
29005
29059
  { name: "explore", desc: " \u2014 toggle exploration mode (read-only)", category: "session" },
29006
29060
  { name: "nero", desc: " \u2014 toggle Nero mode (adversarial)", category: "session" },
29007
29061
  { name: "btw", desc: "<question> \u2014 ask something while engines work", category: "session" },
29008
- { name: "clear", desc: " \u2014 reset session", category: "session", aliases: ["clean"] },
29062
+ { name: "compact", desc: " \u2014 shrink Cesar context without clearing transcript", category: "session" },
29063
+ { name: "clear", desc: " \u2014 reset session (saves chat, clears brain)", category: "session", aliases: ["clean"] },
29009
29064
  // Utility
29010
29065
  { name: "worktree", desc: "new|list|rm|prune|rehydrate <branch> \u2014 isolated per-session git worktrees", category: "utility", aliases: ["wt"] },
29011
29066
  { name: "create-skill", desc: "<name> \u2014 scaffold a new skill (.agon/skills/)", category: "utility" },
@@ -29365,6 +29420,7 @@ function updateTeamElo(match, kFactor) {
29365
29420
  export {
29366
29421
  DEFAULT_AGON_CONFIG,
29367
29422
  DEFAULT_CONFIG,
29423
+ AGON_MODE_NAMES,
29368
29424
  AgonError,
29369
29425
  EngineNotFoundError,
29370
29426
  EngineTimeoutError,
@@ -29469,6 +29525,7 @@ export {
29469
29525
  validateEngineConfig,
29470
29526
  validateEngineDir,
29471
29527
  EngineRegistry,
29528
+ hasProjectBrief,
29472
29529
  isKernProject,
29473
29530
  scanProjectContext,
29474
29531
  collectSourceFiles,
@@ -29772,4 +29829,4 @@ export {
29772
29829
  predictTeamRating,
29773
29830
  updateTeamElo
29774
29831
  };
29775
- //# sourceMappingURL=chunk-PFHGKBQT.js.map
29832
+ //# sourceMappingURL=chunk-C22VTCS6.js.map