abtars 0.2.1 → 0.2.3-alpha.0

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 (71) hide show
  1. package/bundle/{_registry.generated-FNJOX7VV.js → _registry.generated-KM6LXTNJ.js} +3 -3
  2. package/bundle/abtars-cli.js +69 -14
  3. package/bundle/abtars-cli.js.map +3 -3
  4. package/bundle/abtars.js +122 -65
  5. package/bundle/abtars.js.map +3 -3
  6. package/bundle/{agent-registry-S2MNHQYQ.js → agent-registry-ABPFQXNL.js} +3 -3
  7. package/bundle/{chunk-QIAFGDRL.js → chunk-2SFN2VYD.js} +4 -4
  8. package/bundle/{chunk-3X6VGRL6.js → chunk-2W6JIHZ5.js} +4 -1
  9. package/bundle/chunk-2W6JIHZ5.js.map +7 -0
  10. package/bundle/{chunk-HCYENZAB.js → chunk-6TSCOXF6.js} +58 -27
  11. package/bundle/chunk-6TSCOXF6.js.map +7 -0
  12. package/bundle/{chunk-2SWKJX64.js → chunk-7B3GK5JQ.js} +3 -3
  13. package/bundle/{chunk-KL5QRHHK.js → chunk-ENXQMPV3.js} +1 -2
  14. package/bundle/chunk-ENXQMPV3.js.map +7 -0
  15. package/bundle/{chunk-WLAVZSVZ.js → chunk-GXKJKYU4.js} +70 -2
  16. package/bundle/chunk-GXKJKYU4.js.map +7 -0
  17. package/bundle/{chunk-Z4SWEFIY.js → chunk-HFPXN6NM.js} +4 -4
  18. package/bundle/chunk-HFPXN6NM.js.map +7 -0
  19. package/bundle/{chunk-MHK4UPM6.js → chunk-PKHYCNTT.js} +1 -1
  20. package/bundle/{chunk-OGZXYN6E.js → chunk-SEXVA3GK.js} +224 -46
  21. package/bundle/chunk-SEXVA3GK.js.map +7 -0
  22. package/bundle/chunk-W6ELWLAR.js +143 -0
  23. package/bundle/chunk-W6ELWLAR.js.map +7 -0
  24. package/bundle/{commands-AXW7L2MZ.js → commands-L6VIMPCR.js} +5 -5
  25. package/bundle/{direct-api-transport-LSAUIP5S.js → direct-api-transport-BK72AP3I.js} +18 -2
  26. package/bundle/direct-api-transport-BK72AP3I.js.map +7 -0
  27. package/bundle/{discord-adapter-LNWTIOUK.js → discord-adapter-DWIQRNDI.js} +6 -6
  28. package/bundle/{doctor-PIPSGI3H.js → doctor-WHTVSUOF.js} +36 -26
  29. package/bundle/doctor-WHTVSUOF.js.map +7 -0
  30. package/bundle/{install-FZT43PTH.js → install-Q4XNCPG7.js} +2 -2
  31. package/bundle/kanban-board-I52RHNHQ.js +31 -0
  32. package/bundle/{message-pipeline-QX272U5X.js → message-pipeline-GCSZCQWO.js} +5 -5
  33. package/bundle/meta.json +971 -768
  34. package/bundle/{phase-transport-BSGROTHY.js → phase-transport-F7GQRRYE.js} +4 -4
  35. package/bundle/{sleep-K7EXAFGW.js → sleep-MYOZ73IU.js} +3 -3
  36. package/bundle/{subagent-runtime-FQAT3564.js → subagent-runtime-QA4LVU4C.js} +2 -2
  37. package/bundle/{system-status-7K2QTH3J.js → system-status-KMKPAC5Z.js} +4 -2
  38. package/bundle/system-status-KMKPAC5Z.js.map +7 -0
  39. package/bundle/{telegram-adapter-LXLSG4SK.js → telegram-adapter-TRMCC634.js} +10 -7
  40. package/bundle/telegram-adapter-TRMCC634.js.map +7 -0
  41. package/bundle/{tool-registry-5PXNSYOI.js → tool-registry-CG7GIS64.js} +3 -2
  42. package/bundle/tool-registry-CG7GIS64.js.map +7 -0
  43. package/config/transport.default.json +2 -1
  44. package/install-manifest.json +1 -0
  45. package/package.json +2 -1
  46. package/scripts/abtars-daemon.service +0 -1
  47. package/scripts/abtars@.service +0 -1
  48. package/scripts/build-and-deploy.sh +35 -7
  49. package/bundle/chunk-3X6VGRL6.js.map +0 -7
  50. package/bundle/chunk-HCYENZAB.js.map +0 -7
  51. package/bundle/chunk-KL5QRHHK.js.map +0 -7
  52. package/bundle/chunk-OGZXYN6E.js.map +0 -7
  53. package/bundle/chunk-WLAVZSVZ.js.map +0 -7
  54. package/bundle/chunk-Z4SWEFIY.js.map +0 -7
  55. package/bundle/direct-api-transport-LSAUIP5S.js.map +0 -7
  56. package/bundle/doctor-PIPSGI3H.js.map +0 -7
  57. package/bundle/system-status-7K2QTH3J.js.map +0 -7
  58. package/bundle/telegram-adapter-LXLSG4SK.js.map +0 -7
  59. /package/bundle/{_registry.generated-FNJOX7VV.js.map → _registry.generated-KM6LXTNJ.js.map} +0 -0
  60. /package/bundle/{agent-registry-S2MNHQYQ.js.map → agent-registry-ABPFQXNL.js.map} +0 -0
  61. /package/bundle/{chunk-QIAFGDRL.js.map → chunk-2SFN2VYD.js.map} +0 -0
  62. /package/bundle/{chunk-2SWKJX64.js.map → chunk-7B3GK5JQ.js.map} +0 -0
  63. /package/bundle/{chunk-MHK4UPM6.js.map → chunk-PKHYCNTT.js.map} +0 -0
  64. /package/bundle/{commands-AXW7L2MZ.js.map → commands-L6VIMPCR.js.map} +0 -0
  65. /package/bundle/{discord-adapter-LNWTIOUK.js.map → discord-adapter-DWIQRNDI.js.map} +0 -0
  66. /package/bundle/{install-FZT43PTH.js.map → install-Q4XNCPG7.js.map} +0 -0
  67. /package/bundle/{message-pipeline-QX272U5X.js.map → kanban-board-I52RHNHQ.js.map} +0 -0
  68. /package/bundle/{phase-transport-BSGROTHY.js.map → message-pipeline-GCSZCQWO.js.map} +0 -0
  69. /package/bundle/{sleep-K7EXAFGW.js.map → phase-transport-F7GQRRYE.js.map} +0 -0
  70. /package/bundle/{subagent-runtime-FQAT3564.js.map → sleep-MYOZ73IU.js.map} +0 -0
  71. /package/bundle/{tool-registry-5PXNSYOI.js.map → subagent-runtime-QA4LVU4C.js.map} +0 -0
@@ -3,19 +3,19 @@
3
3
  import {
4
4
  require_ws
5
5
  } from "./chunk-NIRYBWUW.js";
6
+ import {
7
+ loadMinimalSoul,
8
+ loadSoulBundle
9
+ } from "./chunk-L33WNMCP.js";
6
10
  import {
7
11
  transcribeAudio
8
12
  } from "./chunk-SA6YEFNG.js";
9
13
  import {
10
14
  ModelNotFoundError
11
- } from "./chunk-MHK4UPM6.js";
15
+ } from "./chunk-PKHYCNTT.js";
12
16
  import {
13
17
  sanitizeOutbound
14
18
  } from "./chunk-YWZPKBO6.js";
15
- import {
16
- loadMinimalSoul,
17
- loadSoulBundle
18
- } from "./chunk-L33WNMCP.js";
19
19
  import {
20
20
  abmind
21
21
  } from "./chunk-JAJ3DUQ2.js";
@@ -1286,6 +1286,7 @@ function buildSessionStartPrompt(prompt, memory, userId, sessionKey, maxContext,
1286
1286
  const type = typeMap[sessionType] ?? sessionType;
1287
1287
  const index = parseInt(parts[2], 10);
1288
1288
  contextParts.push(`[SESSION] #${index} (${type})`);
1289
+ logInfo(TAG3, `Injected session identity: #${index} (${type})`);
1289
1290
  }
1290
1291
  }
1291
1292
  const isCodeSession = sessionType === "C";
@@ -1329,7 +1330,12 @@ You are now talking to ${user.userId} (${user.role}, ${CLASS_NAMES[user.maxClass
1329
1330
  if (platform2) {
1330
1331
  const CAPS = { telegram: "voice, reactions, typing, TTS, groups", discord: "reactions, typing, threads", irc: "text only" };
1331
1332
  contextParts.push(`[SYSTEM] Platform: ${platform2} (${CAPS[platform2] ?? "unknown"})`);
1333
+ logInfo(TAG3, `Injected platform: ${platform2}`);
1332
1334
  }
1335
+ const transportType = getEnv().defaultTransport === "acp" ? "ACP" : "Direct API";
1336
+ const runtimeLine = `[SYSTEM] Runtime: abtars bridge (${transportType}). All registered bridge tools are available.`;
1337
+ contextParts.push(runtimeLine);
1338
+ logInfo(TAG3, `Injected runtime identity: ${transportType}`);
1333
1339
  const compSummary = null;
1334
1340
  if (compSummary && sessionKey) {
1335
1341
  } else {
@@ -1359,7 +1365,10 @@ You are now talking to ${user.userId} (${user.role}, ${CLASS_NAMES[user.maxClass
1359
1365
  }
1360
1366
  if (sessionKey && !sessionKey.includes("_C_")) {
1361
1367
  const status = abmind().buildStatusBlock(memory);
1362
- if (status) contextParts.push(status);
1368
+ if (status) {
1369
+ contextParts.push(status);
1370
+ logInfo(TAG3, `Injected system status (${status.length} chars)`);
1371
+ }
1363
1372
  }
1364
1373
  }
1365
1374
  } catch (err) {
@@ -1373,6 +1382,8 @@ ${contextParts.join("\n\n")}
1373
1382
  ` : "";
1374
1383
  const result = contextBlock + prompt;
1375
1384
  logTrace(TAG3, `session-start assembled: ${contextParts.length} parts, context=${contextBlock.length} chars, prompt=${prompt.length} chars, total=${result.length} chars`);
1385
+ logTrace(TAG3, `session-start injections:
1386
+ ${contextParts.filter((p) => p.startsWith("[")).map((p) => " " + p.slice(0, 120)).join("\n")}`);
1376
1387
  if (result.length < 5e3) {
1377
1388
  logInfo(TAG3, `Session-start prompt suspiciously small (${result.length} chars) \u2014 SOUL may be missing`);
1378
1389
  }
@@ -1750,6 +1761,10 @@ ${prompt}`;
1750
1761
  const rawResponse = sessions.get(activeSessionId)?.fullMode ? response : cleanAnswer || response;
1751
1762
  const { text: cleanedText, reactionEmoji, noReply, topics } = cleanResponse(rawResponse);
1752
1763
  let userResponse = cleanedText;
1764
+ const reasoningSession = transport.getActiveSession?.();
1765
+ if (!reasoningSession?.showReasoning) {
1766
+ userResponse = userResponse.replace(/<thinking>[\s\S]*?<\/thinking>\s*/g, "");
1767
+ }
1753
1768
  for (const [key, val] of Object.entries(process.env)) {
1754
1769
  if (key.startsWith("SECRET_") && val && userResponse.includes(val)) {
1755
1770
  userResponse = userResponse.replaceAll(val, `[REDACTED:$${key}]`);
@@ -1945,7 +1960,32 @@ var TAG5 = "cmd_registry";
1945
1960
  var exactCommands = {};
1946
1961
  var prefixCommands = [];
1947
1962
  var KNOWN_COMMANDS = /* @__PURE__ */ new Set();
1948
- var NON_MASTER_COMMANDS = /* @__PURE__ */ new Set(["/new", "/reset", "/stop", "/ctrlc", "/status", "/help", "/whoami"]);
1963
+ var NON_MASTER_COMMANDS = /* @__PURE__ */ new Set([
1964
+ "/status",
1965
+ "/help",
1966
+ "/whoami",
1967
+ "/doctor",
1968
+ "/software",
1969
+ "/update",
1970
+ "/models",
1971
+ "/model",
1972
+ "/skills",
1973
+ "/skill",
1974
+ "/facts",
1975
+ "/tasks",
1976
+ "/task",
1977
+ "/usage",
1978
+ "/openrouter",
1979
+ "/session",
1980
+ "/hooks",
1981
+ "/memory",
1982
+ "/kanban",
1983
+ "/heartbeat",
1984
+ "/new",
1985
+ "/reset",
1986
+ "/stop",
1987
+ "/ctrlc"
1988
+ ]);
1949
1989
  function registerExact(name, handler) {
1950
1990
  exactCommands[name] = handler;
1951
1991
  KNOWN_COMMANDS.add(name);
@@ -1979,6 +2019,11 @@ async function handleCommand(text, ctx) {
1979
2019
  if (text.startsWith("/") && /^\/\w+/.test(text) && !text.startsWith("//")) {
1980
2020
  const cmd = text.split(/\s/)[0];
1981
2021
  if (!KNOWN_COMMANDS.has(cmd)) {
2022
+ const match = fuzzyMatch(cmd);
2023
+ if (match) {
2024
+ const corrected = text.replace(cmd, match);
2025
+ return handleCommand(corrected, ctx);
2026
+ }
1982
2027
  await ctx.reply(`\u2753 Unknown command: ${cmd}
1983
2028
  Type /help for available commands.`);
1984
2029
  return true;
@@ -2042,6 +2087,32 @@ function killWakeInhibit() {
2042
2087
  function setWakeInhibitPid(pid) {
2043
2088
  _wakeInhibitPid = pid;
2044
2089
  }
2090
+ function levenshtein(a, b) {
2091
+ const m = a.length, n = b.length;
2092
+ const d = Array.from({ length: n + 1 }, (_, i) => i);
2093
+ for (let i = 1; i <= m; i++) {
2094
+ let prev = i - 1;
2095
+ d[0] = i;
2096
+ for (let j = 1; j <= n; j++) {
2097
+ const tmp = d[j];
2098
+ d[j] = a[i - 1] === b[j - 1] ? prev : 1 + Math.min(prev, d[j], d[j - 1]);
2099
+ prev = tmp;
2100
+ }
2101
+ }
2102
+ return d[n];
2103
+ }
2104
+ function fuzzyMatch(cmd) {
2105
+ let best = null;
2106
+ let bestDist = 3;
2107
+ for (const known of KNOWN_COMMANDS) {
2108
+ const dist = levenshtein(cmd, known);
2109
+ if (dist < bestDist) {
2110
+ best = known;
2111
+ bestDist = dist;
2112
+ }
2113
+ }
2114
+ return best;
2115
+ }
2045
2116
 
2046
2117
  // src/components/commands/handlers-transport.ts
2047
2118
  init_logger();
@@ -2364,6 +2435,37 @@ Use /model quick <name> to switch.`);
2364
2435
  await ctx.reply(lines.join("\n"));
2365
2436
  return true;
2366
2437
  }
2438
+ async function handleReasoning(text, ctx) {
2439
+ const arg = text.replace(/^\/(reasoning)\s*/i, "").trim().toLowerCase();
2440
+ const session = ctx.transport.getActiveSession?.();
2441
+ if (!session) {
2442
+ await ctx.reply("No active session.");
2443
+ return true;
2444
+ }
2445
+ if (arg === "show" || arg === "on") {
2446
+ session.showReasoning = true;
2447
+ await ctx.reply("Reasoning display: on");
2448
+ } else if (arg === "hide" || arg === "off") {
2449
+ session.showReasoning = false;
2450
+ await ctx.reply("Reasoning display: off");
2451
+ } else if (["none", "low", "medium", "high"].includes(arg)) {
2452
+ session.reasoningEffort = arg === "none" ? null : arg;
2453
+ await ctx.reply(`Reasoning effort: ${arg}`);
2454
+ } else {
2455
+ await ctx.reply(`Reasoning: effort=${session.reasoningEffort ?? "default"}, display=${session.showReasoning ? "show" : "hide"}`);
2456
+ }
2457
+ return true;
2458
+ }
2459
+ async function handleContinue(_text, ctx) {
2460
+ const response = await ctx.transport.sendPrompt(
2461
+ ctx.sessionKey,
2462
+ "[SYSTEM] Something went wrong during your previous response. Continue from where you left off.",
2463
+ void 0,
2464
+ ctx.userId
2465
+ );
2466
+ if (response) await ctx.reply(response);
2467
+ return true;
2468
+ }
2367
2469
 
2368
2470
  // src/components/commands/exec-async.ts
2369
2471
  import { execFile } from "node:child_process";
@@ -2397,7 +2499,7 @@ ${raw || "(no output)"}`);
2397
2499
  }
2398
2500
  return true;
2399
2501
  }
2400
- const { getDoctorReport, renderDoctorText } = await import("./doctor-PIPSGI3H.js");
2502
+ const { getDoctorReport, renderDoctorText } = await import("./doctor-WHTVSUOF.js");
2401
2503
  const force = arg === "force";
2402
2504
  const svcStates = ctx.registry?.getStates() ?? {};
2403
2505
  await ctx.reply("\u{1FA7A} Running diagnostics...");
@@ -2406,6 +2508,7 @@ ${raw || "(no output)"}`);
2406
2508
  transport: ctx.transport,
2407
2509
  telegramRunning: svcStates.telegram?.running ?? false,
2408
2510
  discordRunning: svcStates.discord?.running ?? false,
2511
+ ircRunning: svcStates.irc?.running ?? false,
2409
2512
  phaseHealth: ctx.phaseHealth
2410
2513
  }, { force });
2411
2514
  await ctx.reply(renderDoctorText(report));
@@ -2413,7 +2516,7 @@ ${raw || "(no output)"}`);
2413
2516
  }
2414
2517
  async function handleStatus(_text, ctx) {
2415
2518
  if (ctx.phaseHealth && ctx.registry) {
2416
- const { getSystemStatus, renderStatusText } = await import("./system-status-7K2QTH3J.js");
2519
+ const { getSystemStatus, renderStatusText } = await import("./system-status-KMKPAC5Z.js");
2417
2520
  const status = await getSystemStatus({
2418
2521
  phaseHealth: ctx.phaseHealth,
2419
2522
  registry: ctx.registry,
@@ -2452,6 +2555,12 @@ async function handleStop(_text, ctx) {
2452
2555
  return true;
2453
2556
  }
2454
2557
  async function handleRestart(_text, ctx) {
2558
+ const arg = _text.replace(/^\/restart\s*/i, "").trim().toLowerCase();
2559
+ if (arg === "cold") {
2560
+ await ctx.reply("\u{1F9CA} Cold restart (process exit \u2192 supervisor respawn)...");
2561
+ setTimeout(() => process.exit(0), 500);
2562
+ return true;
2563
+ }
2455
2564
  await ctx.reply("\u267B\uFE0F Restarting bridge...");
2456
2565
  setTimeout(() => ctx.requestShutdown?.(0), 500);
2457
2566
  return true;
@@ -2699,9 +2808,12 @@ async function handleWhoami(_text, ctx) {
2699
2808
  const user = ctx.userId ? reg.byUserId.get(ctx.userId) : void 0;
2700
2809
  if (user) {
2701
2810
  const clearance = CLASS_NAMES[user.maxClass] ?? `class ${user.maxClass}`;
2702
- await ctx.reply(`${user.displayName ?? user.userId} (${user.role}, ${clearance} clearance)`);
2811
+ await ctx.reply(`${user.displayName ?? user.userId} (${user.role})
2812
+ Clearance: ${clearance}
2813
+ chatId: ${ctx.chatId}`);
2703
2814
  } else {
2704
- await ctx.reply(`${ctx.userId ?? "unknown"} (unregistered)`);
2815
+ await ctx.reply(`${ctx.userId ?? "unknown"} (unregistered)
2816
+ chatId: ${ctx.chatId}`);
2705
2817
  }
2706
2818
  return true;
2707
2819
  }
@@ -2757,41 +2869,37 @@ async function handleSoftware(_text, ctx) {
2757
2869
  }
2758
2870
  try {
2759
2871
  const { spawnSync } = await import("node:child_process");
2760
- const { mkdirSync: mkdirSync2 } = await import("node:fs");
2872
+ const { mkdirSync: mkdirSync2, rmSync: rms } = await import("node:fs");
2761
2873
  const srcDir = join2(home, "src", "abtars");
2762
2874
  const abmindDir = join2(home, "src", "abmind");
2763
2875
  logInfo("update", "Pull requested");
2764
- if (!existsSync(join2(srcDir, ".git"))) {
2765
- await ctx.reply("Cloning abtars repo...");
2876
+ const pullOrReclone = (dir, repo) => {
2766
2877
  mkdirSync2(join2(home, "src"), { recursive: true });
2767
- const cl = spawnSync("git", ["clone", "git@github.com:aksika/abtars.git", srcDir], { encoding: "utf-8", timeout: 6e4 });
2768
- if (cl.status !== 0) {
2769
- logInfo("update", "Clone failed");
2770
- await ctx.reply(`Clone failed:
2771
- ${(cl.stderr || "").trim().slice(0, 300)}`);
2772
- return true;
2878
+ if (existsSync(join2(dir, ".git"))) {
2879
+ spawnSync("git", ["-C", dir, "fetch", "origin", "dev"], { encoding: "utf-8", timeout: 3e4 });
2880
+ const r = spawnSync("git", ["-C", dir, "reset", "--hard", "origin/dev"], { encoding: "utf-8" });
2881
+ const hasConflicts = spawnSync("git", ["-C", dir, "grep", "-q", "^<<<<<<<"], { encoding: "utf-8" }).status === 0;
2882
+ if (r.status === 0 && !hasConflicts) {
2883
+ return { ok: true, msg: (r.stdout || "").trim().slice(0, 300) };
2884
+ }
2885
+ logInfo("update", `${dir}: reset failed or conflicts \u2014 recloning`);
2886
+ rms(dir, { recursive: true, force: true });
2773
2887
  }
2774
- }
2775
- spawnSync("git", ["-C", srcDir, "checkout", "--", "package-lock.json"], { encoding: "utf-8" });
2776
- const r = spawnSync("git", ["-C", srcDir, "pull", "--ff-only", "origin", "dev"], { encoding: "utf-8", timeout: 3e4 });
2777
- if (r.status !== 0) {
2888
+ const cl = spawnSync("git", ["clone", "-b", "dev", repo, dir], { encoding: "utf-8", timeout: 6e4 });
2889
+ if (cl.status === 0) return { ok: true, msg: "cloned fresh" };
2890
+ return { ok: false, msg: (cl.stderr || "").trim().slice(0, 300) };
2891
+ };
2892
+ const abtarsResult = pullOrReclone(srcDir, "git@github.com:aksika/abtars.git");
2893
+ if (!abtarsResult.ok) {
2778
2894
  await ctx.reply(`Pull failed (abtars):
2779
- ${(r.stderr || "").trim().slice(0, 300)}`);
2895
+ ${abtarsResult.msg}`);
2780
2896
  return true;
2781
2897
  }
2782
2898
  let pulled = `Pulled:
2783
- ${(r.stdout || "").trim().slice(0, 300)}`;
2784
- if (existsSync(join2(abmindDir, ".git"))) {
2785
- spawnSync("git", ["-C", abmindDir, "checkout", "--", "package-lock.json"], { encoding: "utf-8" });
2786
- const ab = spawnSync("git", ["-C", abmindDir, "pull", "--ff-only", "origin", "dev"], { encoding: "utf-8", timeout: 3e4 });
2787
- if (ab.status !== 0) {
2788
- await ctx.reply(`Pull failed (abmind):
2789
- ${(ab.stderr || "").trim().slice(0, 300)}`);
2790
- return true;
2791
- }
2792
- pulled += `
2793
- abmind: ${(ab.stdout || "").trim().slice(0, 200)}`;
2794
- }
2899
+ ${abtarsResult.msg}`;
2900
+ const abmindResult = pullOrReclone(abmindDir, "git@github.com:aksika/abmind.git");
2901
+ pulled += `
2902
+ abmind: ${abmindResult.msg}`;
2795
2903
  logInfo("update", `Pull complete`);
2796
2904
  await ctx.reply(`${pulled}
2797
2905
 
@@ -2821,7 +2929,18 @@ Ready to deploy: /update deploy`);
2821
2929
  return true;
2822
2930
  }
2823
2931
  logInfo("update", `Deploy starting (non-blocking)`);
2932
+ const markers = spawnSync("git", ["-C", srcDir, "grep", "-l", "^<<<<<<<"], { encoding: "utf-8", timeout: 1e4 });
2933
+ if (markers.stdout.trim()) {
2934
+ const files = markers.stdout.trim().split("\n").join(", ");
2935
+ await ctx.reply(`\u26A0\uFE0F Conflict markers found in source \u2014 refusing to deploy.
2936
+ Files: ${files}
2937
+ Repo has a broken commit. Notify dev team.`);
2938
+ return true;
2939
+ }
2824
2940
  await ctx.reply("\u2699\uFE0F Deploying (building in background)...");
2941
+ const logFile = `deploy-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").slice(0, 15)}.log`;
2942
+ const { writeFileSync: wfs } = await import("node:fs");
2943
+ wfs(join2(home, "deploy.state"), JSON.stringify({ status: "running", startedAt: (/* @__PURE__ */ new Date()).toISOString(), logFile }) + "\n");
2825
2944
  const script = join2(srcDir, "scripts", "build-and-deploy.sh");
2826
2945
  spawn2("bash", [script, srcDir, abmindDir], {
2827
2946
  detached: true,
@@ -2831,7 +2950,7 @@ Ready to deploy: /update deploy`);
2831
2950
  await ctx.reply(`Deploy failed: ${err instanceof Error ? err.message : String(err)}`);
2832
2951
  }
2833
2952
  return true;
2834
- } else if (arg === "update") {
2953
+ } else if (arg === "npm" || arg === "update npm") {
2835
2954
  if (!isMaster) {
2836
2955
  await ctx.reply("Requires master role.");
2837
2956
  return true;
@@ -2896,7 +3015,7 @@ Ready to deploy: /update deploy`);
2896
3015
  const { execFileSync } = await import("node:child_process");
2897
3016
  const raw = execFileSync("npm", ["view", "abmind", "dist-tags", "--json"], { encoding: "utf-8", timeout: 5e3 });
2898
3017
  const latest = JSON.parse(raw).alpha ?? JSON.parse(raw).latest;
2899
- if (latest) lines.push(` npm latest: abmind@${latest} ${latest === pkg.version ? "\u2713" : "\u26A0\uFE0F"}`);
3018
+ if (latest) lines.push(` npm latest: abmind@${latest} ${latest === pkg.version || pkg.version.startsWith(latest) ? "\u2713" : "\u26A0\uFE0F"}`);
2900
3019
  } catch {
2901
3020
  }
2902
3021
  } catch {
@@ -2912,7 +3031,7 @@ Ready to deploy: /update deploy`);
2912
3031
  const { execFileSync } = await import("node:child_process");
2913
3032
  const raw = execFileSync("npm", ["view", "abmind", "dist-tags", "--json"], { encoding: "utf-8", timeout: 5e3 });
2914
3033
  const latest = JSON.parse(raw).alpha ?? JSON.parse(raw).latest;
2915
- if (latest) lines.push(` npm latest: abmind@${latest} ${latest === m.version ? "\u2713" : "\u26A0\uFE0F"}`);
3034
+ if (latest) lines.push(` npm latest: abmind@${latest} ${latest === m.version || m.version.startsWith(latest) ? "\u2713" : "\u26A0\uFE0F"}`);
2916
3035
  } catch {
2917
3036
  }
2918
3037
  } catch {
@@ -2932,8 +3051,25 @@ Ready to deploy: /update deploy`);
2932
3051
  lines.push(` ${i}: (empty)`);
2933
3052
  }
2934
3053
  }
3054
+ try {
3055
+ const stateRaw = readFileSync(join2(home, "deploy.state"), "utf-8");
3056
+ const ds = JSON.parse(stateRaw);
3057
+ if (ds.status === "running") {
3058
+ const ago = Math.round((Date.now() - new Date(ds.startedAt).getTime()) / 6e4);
3059
+ lines.push(`
3060
+ \u{1F504} Deploy in progress (${ago}min ago)`);
3061
+ } else if (ds.status === "failed") {
3062
+ lines.push(`
3063
+ \u274C Last deploy failed: ${ds.error}
3064
+ Log: ~/.abtars/logs/${ds.logFile}`);
3065
+ } else if (ds.status === "partial") {
3066
+ lines.push(`
3067
+ \u26A0\uFE0F Last deploy incomplete: missing ${ds.missing?.join(", ")}`);
3068
+ }
3069
+ } catch {
3070
+ }
2935
3071
  lines.push("");
2936
- lines.push(" /software update [pull|deploy] | update (npm) | rollback");
3072
+ lines.push(" /update [pull|deploy|npm] | /software rollback <version>");
2937
3073
  await ctx.reply(lines.join("\n"));
2938
3074
  return true;
2939
3075
  }
@@ -3365,6 +3501,45 @@ async function handleTaskPause(text, ctx) {
3365
3501
  }
3366
3502
  return true;
3367
3503
  }
3504
+ async function handleKanban(text, ctx) {
3505
+ try {
3506
+ const { kanbanList } = await import("./kanban-board-I52RHNHQ.js");
3507
+ const arg = text.replace(/^\/kanban\s*/, "").trim();
3508
+ const ALLOWED_FILTERS = /* @__PURE__ */ new Set(["status", "source", "priority", "labels", "type"]);
3509
+ let filterVal;
3510
+ let filterKey;
3511
+ let showAll = false;
3512
+ if (arg === "all") {
3513
+ showAll = true;
3514
+ } else if (arg && arg.includes("=")) {
3515
+ const [key, val] = arg.split("=", 2);
3516
+ if (!key || !val || !ALLOWED_FILTERS.has(key)) {
3517
+ await ctx.reply(`\u274C Invalid filter. Use: /kanban [all | status=X | source=X | priority=X | labels=X | type=X]`);
3518
+ return true;
3519
+ }
3520
+ filterKey = key;
3521
+ filterVal = val.replace(/[^a-zA-Z0-9_,-]/g, "").slice(0, 30);
3522
+ } else if (arg) {
3523
+ filterVal = arg.replace(/[^a-zA-Z0-9_,-]/g, "").slice(0, 30);
3524
+ }
3525
+ const cards = showAll ? kanbanList("*") : kanbanList(filterVal, filterKey);
3526
+ if (cards.length === 0) {
3527
+ await ctx.reply("\u{1F4CB} Kanban board is empty.");
3528
+ return true;
3529
+ }
3530
+ const lines = cards.map((c) => {
3531
+ const icon = c.status === "delivered" ? "\u2713" : c.status === "done" ? "+" : c.status === "running" ? "~" : c.status === "failed" ? "\u2717" : "-";
3532
+ const due = c.due_at ? ` due:${c.due_at.slice(0, 10)}` : "";
3533
+ const doneAt = c.delivered_at ? ` ${c.delivered_at.slice(2, 10).replace(/-/g, "")}:${c.delivered_at.slice(11, 16).replace(":", "")}` : "";
3534
+ return `${icon} #${c.id} ${c.title} (${c.source}/${c.priority})${doneAt}${due}`;
3535
+ });
3536
+ await ctx.reply(`\u{1F4CB} Kanban Board (${cards.length}):
3537
+ ${lines.join("\n")}`);
3538
+ } catch (err) {
3539
+ await ctx.reply(`\u274C Failed: ${err instanceof Error ? err.message : String(err)}`);
3540
+ }
3541
+ return true;
3542
+ }
3368
3543
 
3369
3544
  // src/components/commands/handlers-admin.ts
3370
3545
  init_log_and_swallow();
@@ -3557,7 +3732,9 @@ async function handleHelp(_text, ctx) {
3557
3732
  "/restart \u2014 Restart bridge",
3558
3733
  "/wakeup \u2014 Wake Mac from sleep",
3559
3734
  "/sleep \u2014 Sleep status / /sleep resume / /sleep now",
3560
- "/whoami \u2014 Your user info & clearance"
3735
+ "/whoami \u2014 Your user info & clearance",
3736
+ "/reasoning \u2014 Reasoning effort (low/medium/high/none) + show/hide thinking",
3737
+ "/kanban \u2014 Kanban board"
3561
3738
  ];
3562
3739
  if (ctx.platform === "telegram") {
3563
3740
  cmds.push("/full \u2014 Raw output, TTS disabled", "/short \u2014 Clean responses (default)", "/healing \u2014 Toggle self-healer on/off");
@@ -3928,12 +4105,15 @@ registerExact("/update", handleSoftware);
3928
4105
  registerExact("/facts", handleFacts);
3929
4106
  registerExact("/tasks", handleTasksList);
3930
4107
  registerExact("/task", handleTasksList);
3931
- registerExact("/cron", handleTasksList);
4108
+ registerExact("/kanban", handleKanban);
4109
+ registerPrefix("/kanban ", handleKanban);
3932
4110
  registerExact("/memory", handleMemory);
3933
4111
  registerExact("/heartbeat", handleHeartbeat);
3934
4112
  registerExact("/models", handleModels);
3935
4113
  registerExact("/model", handleModels);
3936
4114
  registerExact("/change", (_, ctx) => handleModels("/model change", ctx));
4115
+ registerExact("/reasoning", handleReasoning);
4116
+ registerExact("/continue", handleContinue);
3937
4117
  registerExact("/emergency", handleEmergencyAlias);
3938
4118
  registerExact("/help", handleHelp);
3939
4119
  registerExact("/users", handleUsers);
@@ -3950,10 +4130,8 @@ registerExact("/session", handleSession);
3950
4130
  registerPrefix("/session ", handleSession);
3951
4131
  registerPrefix("/tasks run ", handleTasksTrigger);
3952
4132
  registerPrefix("/task run ", handleTasksTrigger);
3953
- registerPrefix("/cron run ", handleTasksTrigger);
3954
4133
  registerPrefix("/tasks log ", handleTasksLog);
3955
4134
  registerPrefix("/task log ", handleTasksLog);
3956
- registerPrefix("/cron log ", handleTasksLog);
3957
4135
  registerPrefix("/nlm", handleNlm);
3958
4136
  registerPrefix("/sleep ", handleSleepSub);
3959
4137
  registerPrefix("/usage ", handleUsage);
@@ -3981,4 +4159,4 @@ export {
3981
4159
  handleInboundMessage,
3982
4160
  startSession
3983
4161
  };
3984
- //# sourceMappingURL=chunk-OGZXYN6E.js.map
4162
+ //# sourceMappingURL=chunk-SEXVA3GK.js.map