@songsid/agend 2.1.1-beta.11 → 2.1.1-beta.13

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 (88) hide show
  1. package/dist/backend/antigravity.js +5 -2
  2. package/dist/backend/antigravity.js.map +1 -1
  3. package/dist/backend/claude-code.js +3 -0
  4. package/dist/backend/claude-code.js.map +1 -1
  5. package/dist/backend/codex.d.ts +16 -0
  6. package/dist/backend/codex.js +248 -56
  7. package/dist/backend/codex.js.map +1 -1
  8. package/dist/backend/grok.js +20 -0
  9. package/dist/backend/grok.js.map +1 -1
  10. package/dist/backend/kiro.js +18 -2
  11. package/dist/backend/kiro.js.map +1 -1
  12. package/dist/backend/types.d.ts +7 -0
  13. package/dist/backend/types.js +1 -1
  14. package/dist/backend/types.js.map +1 -1
  15. package/dist/channel/adapters/discord.js +4 -5
  16. package/dist/channel/adapters/discord.js.map +1 -1
  17. package/dist/channel/adapters/telegram.js +50 -15
  18. package/dist/channel/adapters/telegram.js.map +1 -1
  19. package/dist/channel/ipc-bridge.d.ts +8 -0
  20. package/dist/channel/ipc-bridge.js +41 -14
  21. package/dist/channel/ipc-bridge.js.map +1 -1
  22. package/dist/channel/mcp-server.js +25 -10
  23. package/dist/channel/mcp-server.js.map +1 -1
  24. package/dist/channel/mcp-tools.js +25 -0
  25. package/dist/channel/mcp-tools.js.map +1 -1
  26. package/dist/channel/message-queue.d.ts +1 -0
  27. package/dist/channel/message-queue.js +49 -17
  28. package/dist/channel/message-queue.js.map +1 -1
  29. package/dist/channel/reconnect-backoff.d.ts +17 -0
  30. package/dist/channel/reconnect-backoff.js +21 -0
  31. package/dist/channel/reconnect-backoff.js.map +1 -0
  32. package/dist/cli.js +71 -26
  33. package/dist/cli.js.map +1 -1
  34. package/dist/completion.d.ts +27 -0
  35. package/dist/completion.js +121 -0
  36. package/dist/completion.js.map +1 -0
  37. package/dist/config-validator.js +9 -0
  38. package/dist/config-validator.js.map +1 -1
  39. package/dist/config.js +1 -0
  40. package/dist/config.js.map +1 -1
  41. package/dist/daemon.d.ts +74 -8
  42. package/dist/daemon.js +254 -18
  43. package/dist/daemon.js.map +1 -1
  44. package/dist/fleet-manager.d.ts +7 -1
  45. package/dist/fleet-manager.js +89 -16
  46. package/dist/fleet-manager.js.map +1 -1
  47. package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +22 -0
  48. package/dist/general-knowledge/skills/model-discovery/SKILL.md +14 -23
  49. package/dist/general-knowledge/skills/session-management/SKILL.md +15 -34
  50. package/dist/instance-lifecycle.d.ts +13 -1
  51. package/dist/instance-lifecycle.js +70 -3
  52. package/dist/instance-lifecycle.js.map +1 -1
  53. package/dist/instructions.d.ts +5 -0
  54. package/dist/instructions.js +9 -11
  55. package/dist/instructions.js.map +1 -1
  56. package/dist/logger.js +14 -0
  57. package/dist/logger.js.map +1 -1
  58. package/dist/mcp-liveness.d.ts +21 -0
  59. package/dist/mcp-liveness.js +27 -0
  60. package/dist/mcp-liveness.js.map +1 -0
  61. package/dist/outbound-handlers.d.ts +9 -0
  62. package/dist/outbound-handlers.js +46 -26
  63. package/dist/outbound-handlers.js.map +1 -1
  64. package/dist/outbound-schemas.js +1 -1
  65. package/dist/outbound-schemas.js.map +1 -1
  66. package/dist/tmux-control.js +4 -2
  67. package/dist/tmux-control.js.map +1 -1
  68. package/dist/tmux-manager.d.ts +14 -0
  69. package/dist/tmux-manager.js +20 -6
  70. package/dist/tmux-manager.js.map +1 -1
  71. package/dist/topic-commands.d.ts +22 -1
  72. package/dist/topic-commands.js +95 -57
  73. package/dist/topic-commands.js.map +1 -1
  74. package/dist/tui-glyphs.d.ts +25 -0
  75. package/dist/tui-glyphs.js +26 -0
  76. package/dist/tui-glyphs.js.map +1 -0
  77. package/dist/types.d.ts +6 -0
  78. package/dist/ui/view.html +114 -2
  79. package/dist/usage/providers.d.ts +26 -0
  80. package/dist/usage/providers.js +577 -0
  81. package/dist/usage/providers.js.map +1 -0
  82. package/dist/usage/usage-api.d.ts +35 -0
  83. package/dist/usage/usage-api.js +52 -0
  84. package/dist/usage/usage-api.js.map +1 -0
  85. package/dist/view-api.d.ts +3 -0
  86. package/dist/view-api.js +10 -2
  87. package/dist/view-api.js.map +1 -1
  88. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -13,6 +13,8 @@ import { spawn, execSync, execFileSync } from "node:child_process";
13
13
  import { getAgendHome, getTmuxSocketName } from "./paths.js";
14
14
  import { readClassicLastActivityAt } from "./classic-channel-manager.js";
15
15
  import { hasPausedMarker } from "./pause-marker.js";
16
+ import { PIE_PERCENT_RE } from "./tui-glyphs.js";
17
+ import { COMPLETION_SHELLS, completionScript } from "./completion.js";
16
18
  import { getUpdateSelector, lookupTargetVersion, reportUpdateRestart, shouldSkipUpdate, } from "./update-check.js";
17
19
  /** Prefix tmux args with -L when socket isolation is active. */
18
20
  function tmuxArgs(args) {
@@ -1834,28 +1836,7 @@ async function fuzzyMatch(query, names) {
1834
1836
  return null;
1835
1837
  }
1836
1838
  async function resolveInstance(query, config) {
1837
- const names = Object.keys(config.instances);
1838
- // Include classic instances from classicBot.yaml
1839
- try {
1840
- const classicPath = join(DATA_DIR, "classicBot.yaml");
1841
- if (existsSync(classicPath)) {
1842
- const yamlMod = (await import("js-yaml")).default;
1843
- const classic = yamlMod.load(readFileSync(classicPath, "utf-8"));
1844
- if (classic?.channels) {
1845
- for (const [key, val] of Object.entries(classic.channels)) {
1846
- // New format persists instanceName; old format keyed by channelId.
1847
- if (val.instanceName) {
1848
- names.push(val.instanceName);
1849
- continue;
1850
- }
1851
- const channelId = val.channelId ?? key;
1852
- const chName = (val.name ?? channelId).toLowerCase().replace(/[^\p{L}\d-]/gu, "-").replace(/-+/g, "-").replace(/^-|-$/g, "") || "project";
1853
- names.push(`classic-${chName}-${channelId.slice(-4)}`);
1854
- }
1855
- }
1856
- }
1857
- }
1858
- catch { /* ignore */ }
1839
+ const names = await listInstanceNames(config);
1859
1840
  const match = await fuzzyMatch(query, names);
1860
1841
  if (!match) {
1861
1842
  console.error(`No instance matching "${query}". Available: ${names.join(", ")}`);
@@ -1950,7 +1931,7 @@ function formatTimeSince(isoStr) {
1950
1931
  * Universal context-% parser for `agend ls` (all backends). Kept in sync with
1951
1932
  * parseContextPercent() in topic-commands.ts — same formats, bottom-up so the
1952
1933
  * most recent prompt wins:
1953
- * kiro classic "8% !>" / TUI " 1%" / bracket "[8%]" / prompt "8% ❯"
1934
+ * kiro classic "8% !>" / TUI " 1%" (any pie glyph) / bracket "[8%]" / prompt "8% ❯"
1954
1935
  * codex "Context N% left" (remaining → 100-N) or "Context N% used"
1955
1936
  * opencode "1.2K (6%)"
1956
1937
  * grok "12K / 500K" (used tokens / context window)
@@ -1977,7 +1958,7 @@ const defaultParser = (output) => {
1977
1958
  return used / total * 100;
1978
1959
  }
1979
1960
  const m = line.match(/(\d+)%.*[!❯>]/)
1980
- || line.match(/◔\s*(\d+)%/)
1961
+ || line.match(PIE_PERCENT_RE)
1981
1962
  || line.match(/\[(\d+)%\]/)
1982
1963
  || line.match(/Context\s+(\d+)%\s+used/i)
1983
1964
  || line.match(/\d+(?:\.\d+)?[KM]?\s*\((\d+)%\)/);
@@ -1988,10 +1969,48 @@ const defaultParser = (output) => {
1988
1969
  };
1989
1970
  /** Optional backend-specific overrides; none needed — defaultParser covers all. */
1990
1971
  const contextParsers = {};
1972
+ /**
1973
+ * Every instance name the CLI accepts: fleet.yaml instances plus the
1974
+ * dynamically-created ClassicBot ones. Shared by `resolveInstance` (fuzzy
1975
+ * matching for `attach`) and `ls --names-only` (shell completion), so the
1976
+ * candidates offered by tab-completion are exactly the ones `attach` resolves.
1977
+ */
1978
+ async function listInstanceNames(config) {
1979
+ const names = Object.keys(config.instances);
1980
+ try {
1981
+ const classicPath = join(DATA_DIR, "classicBot.yaml");
1982
+ if (existsSync(classicPath)) {
1983
+ const yamlMod = (await import("js-yaml")).default;
1984
+ const classic = yamlMod.load(readFileSync(classicPath, "utf-8"));
1985
+ if (classic?.channels) {
1986
+ for (const [key, val] of Object.entries(classic.channels)) {
1987
+ // New format persists instanceName; old format keyed by channelId.
1988
+ if (val.instanceName) {
1989
+ names.push(val.instanceName);
1990
+ continue;
1991
+ }
1992
+ const channelId = val.channelId ?? key;
1993
+ const chName = (val.name ?? channelId).toLowerCase().replace(/[^\p{L}\d-]/gu, "-").replace(/-+/g, "-").replace(/^-|-$/g, "") || "project";
1994
+ names.push(`classic-${chName}-${channelId.slice(-4)}`);
1995
+ }
1996
+ }
1997
+ }
1998
+ }
1999
+ catch { /* ignore */ }
2000
+ return names;
2001
+ }
1991
2002
  async function lsAction(opts) {
1992
2003
  const yaml = (await import("js-yaml")).default;
1993
2004
  const config = yaml.load(readFileSync(FLEET_CONFIG_PATH, "utf-8"));
1994
2005
  const names = Object.keys(config.instances);
2006
+ // --names-only feeds shell completion, so it must return before any tmux or
2007
+ // status work (a tab press should not wait on the fleet) and must print
2008
+ // nothing but names — a "no instances" notice would become a candidate.
2009
+ if (opts.namesOnly) {
2010
+ for (const n of await listInstanceNames(config))
2011
+ console.log(n);
2012
+ return;
2013
+ }
1995
2014
  // Load classic channels from classicBot.yaml (keyed by channelId)
1996
2015
  const classicPath = join(DATA_DIR, "classicBot.yaml");
1997
2016
  let classicConfig = null;
@@ -2277,12 +2296,38 @@ program
2277
2296
  .command("ls")
2278
2297
  .description("List all instances with status, backend, team, and last activity")
2279
2298
  .option("--json", "Output as JSON")
2299
+ .option("--names-only", "Print instance names one per line (for shell completion)")
2280
2300
  .action(async (opts) => {
2281
2301
  await lsAction(opts);
2282
2302
  });
2283
2303
  program
2284
- .command("health")
2285
- .description("Fleet health check shows problems and diagnostics")
2304
+ .command("completion")
2305
+ .description("Print a shell completion script (bash or zsh)")
2306
+ .argument("<shell>", `Shell to generate for (${COMPLETION_SHELLS.join(", ")})`)
2307
+ .addHelpText("after", `
2308
+ Install:
2309
+ bash echo 'eval "$(agend completion bash)"' >> ~/.bashrc
2310
+ zsh echo 'eval "$(agend completion zsh)"' >> ~/.zshrc
2311
+
2312
+ Then reload the shell. Tab-completes instance names for \`agend attach\` and
2313
+ \`agend fleet start|stop|restart\`, and subcommands elsewhere.`)
2314
+ .action((shell) => {
2315
+ if (!COMPLETION_SHELLS.includes(shell)) {
2316
+ console.error(`Unsupported shell: ${shell}. Supported: ${COMPLETION_SHELLS.join(", ")}`);
2317
+ process.exit(2);
2318
+ }
2319
+ // Subcommand names come from commander itself, so the script can't drift
2320
+ // out of sync with the CLI the way a hardcoded list would.
2321
+ const fleetCmd = program.commands.find(c => c.name() === "fleet");
2322
+ console.log(completionScript(shell, {
2323
+ topLevel: program.commands.map(c => c.name()),
2324
+ fleetSub: fleetCmd?.commands.map(c => c.name()) ?? [],
2325
+ instanceCommands: ["attach"],
2326
+ fleetInstanceCommands: ["start", "stop", "restart"],
2327
+ }));
2328
+ });
2329
+ program
2330
+ .command("health").description("Fleet health check — shows problems and diagnostics")
2286
2331
  .option("--json", "Output as JSON")
2287
2332
  .option("-q, --quiet", "One-line summary only")
2288
2333
  .action(async (opts) => {