kanban 0.1.9 → 0.1.11

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 (74) hide show
  1. package/README.md +12 -30
  2. package/dist/cli.js +53 -88
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/hooks.d.ts +2 -3
  5. package/dist/commands/hooks.d.ts.map +1 -1
  6. package/dist/commands/hooks.js +67 -131
  7. package/dist/commands/hooks.js.map +1 -1
  8. package/dist/commands/task.d.ts +3 -0
  9. package/dist/commands/task.d.ts.map +1 -0
  10. package/dist/commands/task.js +485 -0
  11. package/dist/commands/task.js.map +1 -0
  12. package/dist/config/runtime-config.js +1 -1
  13. package/dist/config/runtime-config.js.map +1 -1
  14. package/dist/core/agent-catalog.js +10 -10
  15. package/dist/core/agent-catalog.js.map +1 -1
  16. package/dist/core/api-contract.d.ts +9 -21
  17. package/dist/core/api-contract.d.ts.map +1 -1
  18. package/dist/core/api-contract.js +5 -9
  19. package/dist/core/api-contract.js.map +1 -1
  20. package/dist/skills/kanban-skill.d.ts +15 -0
  21. package/dist/skills/kanban-skill.d.ts.map +1 -0
  22. package/dist/skills/kanban-skill.js +174 -0
  23. package/dist/skills/kanban-skill.js.map +1 -0
  24. package/dist/terminal/agent-registry.d.ts.map +1 -1
  25. package/dist/terminal/agent-registry.js +3 -66
  26. package/dist/terminal/agent-registry.js.map +1 -1
  27. package/dist/terminal/agent-session-adapters.d.ts.map +1 -1
  28. package/dist/terminal/agent-session-adapters.js +10 -2
  29. package/dist/terminal/agent-session-adapters.js.map +1 -1
  30. package/dist/terminal/command-discovery.d.ts +8 -0
  31. package/dist/terminal/command-discovery.d.ts.map +1 -0
  32. package/dist/terminal/command-discovery.js +69 -0
  33. package/dist/terminal/command-discovery.js.map +1 -0
  34. package/dist/terminal/session-manager.d.ts.map +1 -1
  35. package/dist/terminal/session-manager.js +22 -80
  36. package/dist/terminal/session-manager.js.map +1 -1
  37. package/dist/terminal/task-start-setup-detection.d.ts +3 -0
  38. package/dist/terminal/task-start-setup-detection.d.ts.map +1 -0
  39. package/dist/terminal/task-start-setup-detection.js +163 -0
  40. package/dist/terminal/task-start-setup-detection.js.map +1 -0
  41. package/dist/terminal/terminal-protocol-filter.d.ts +16 -0
  42. package/dist/terminal/terminal-protocol-filter.d.ts.map +1 -0
  43. package/dist/terminal/terminal-protocol-filter.js +128 -0
  44. package/dist/terminal/terminal-protocol-filter.js.map +1 -0
  45. package/dist/trpc/app-router.d.ts +9 -17
  46. package/dist/trpc/app-router.d.ts.map +1 -1
  47. package/dist/trpc/app-router.js +1 -7
  48. package/dist/trpc/app-router.js.map +1 -1
  49. package/dist/trpc/runtime-api.d.ts.map +1 -1
  50. package/dist/trpc/runtime-api.js +0 -51
  51. package/dist/trpc/runtime-api.js.map +1 -1
  52. package/dist/web-ui/assets/{allPaths-DOTpTORM.js → allPaths-SWuS45nz.js} +1 -1
  53. package/dist/web-ui/assets/{allPathsLoader-QnqMU9zv.js → allPathsLoader-53qxMr_f.js} +3 -3
  54. package/dist/web-ui/assets/{index-DZcGgUMk.js → index-BFqTZ35u.js} +10090 -9934
  55. package/dist/web-ui/assets/{splitPathsBySizeLoader-BpwicruJ.js → splitPathsBySizeLoader-Dv0e6IpA.js} +1 -1
  56. package/dist/web-ui/index.html +1 -1
  57. package/man/kanban.1 +109 -7
  58. package/package.json +2 -2
  59. package/dist/commands/mcp.d.ts +0 -3
  60. package/dist/commands/mcp.d.ts.map +0 -1
  61. package/dist/commands/mcp.js +0 -32
  62. package/dist/commands/mcp.js.map +0 -1
  63. package/dist/mcp/server.d.ts +0 -4
  64. package/dist/mcp/server.d.ts.map +0 -1
  65. package/dist/mcp/server.js +0 -531
  66. package/dist/mcp/server.js.map +0 -1
  67. package/dist/mcp/task-state.d.ts +0 -2
  68. package/dist/mcp/task-state.d.ts.map +0 -1
  69. package/dist/mcp/task-state.js +0 -2
  70. package/dist/mcp/task-state.js.map +0 -1
  71. package/dist/terminal/slash-commands.d.ts +0 -7
  72. package/dist/terminal/slash-commands.d.ts.map +0 -1
  73. package/dist/terminal/slash-commands.js +0 -322
  74. package/dist/terminal/slash-commands.js.map +0 -1
package/README.md CHANGED
@@ -39,44 +39,26 @@ npx kanban
39
39
 
40
40
  1. Install an agent like Claude Code, Codex, Gemini, OpenCode, Cline
41
41
  2. Run `kanban` (install with `npm i -g kanban`) in your repo to launch a web GUI
42
- 3. Create tasks, link dependencies, hit the play button, and watch agents work in parallel. You can even use Kanban MCP to tell an agent to create parallelizable tasks and links in clever ways to get projects done quickly.
42
+ 3. Create tasks, link dependencies, hit the play button, and watch agents work in parallel. You can also ask your agent to manage tasks through Kanban's built-in skill and task CLI.
43
43
  4. When they finish, you review diffs, leave comments, and commit or make a PR.
44
44
 
45
- Use MCP to let the agent add and start tasks on the kanban board itself, decomposing large work into parallelizable linked tasks in clever ways to get work done quicker.
45
+ ## Agent Skill Setup
46
46
 
47
- ```bash
48
- claude mcp add --transport stdio --scope user kanban -- kanban mcp
49
- ```
50
-
51
- <details>
52
- <summary>Using Cline?</summary>
47
+ Kanban writes a `kanban` skill file on every launch so your agent can add, update, link, and start tasks using `kanban task` commands.
53
48
 
54
- Add this to your `~/.cline/data/settings/cline_mcp_settings.json`:
55
-
56
- ```json
57
- {
58
- "mcpServers": {
59
- "kanban": {
60
- "command": "kanban",
61
- "args": ["mcp"],
62
- "transportType": "stdio"
63
- }
64
- }
65
- }
66
- ```
49
+ Generated skill paths:
67
50
 
68
- </details>
51
+ - `~/.agents/skills/kanban/SKILL.md`
52
+ - `~/.claude/skills/kanban/SKILL.md` (written when Claude is installed)
69
53
 
70
- With the MCP tools, your agent can:
54
+ The file is regenerated each launch so new Kanban releases can update the instructions automatically.
71
55
 
72
- - `list_tasks`: see what's on the board, including task links and auto-review settings
73
- - `create_task`: add a new task to backlog, optionally with auto-review enabled
74
- - `update_task`: change a task's prompt, base ref, plan mode, or auto-review settings
75
- - `link_tasks`: link tasks so backlog work waits on another task to finish first
76
- - `unlink_tasks`: remove a task link
77
- - `start_task`: kick off a task (creates the worktree, launches the agent)
56
+ The skill includes:
78
57
 
79
- Task linking handles both parallelization and dependencies. Link multiple backlog tasks to the same dependency and they all become ready once it finishes. Auto-review settings let a task automatically commit, open a PR, or move to trash.
58
+ - command reference for `kanban task list|create|update|link|unlink|start`
59
+ - parameter guidance for each command
60
+ - dependency and auto-review workflow notes
61
+ - ephemeral worktree handling (`.kanban/worktrees`) so commands target the main workspace
80
62
 
81
63
  ## License
82
64
 
package/dist/cli.js CHANGED
@@ -2,9 +2,10 @@
2
2
  import { spawn, spawnSync } from "node:child_process";
3
3
  import { stat } from "node:fs/promises";
4
4
  import { createServer as createNetServer } from "node:net";
5
+ import { Command } from "commander";
5
6
  import packageJson from "../package.json" with { type: "json" };
6
- import { isHooksSubcommand, runHooksSubcommand } from "./commands/hooks.js";
7
- import { isMcpSubcommand, runMcpSubcommand } from "./commands/mcp.js";
7
+ import { registerHooksCommand } from "./commands/hooks.js";
8
+ import { registerTaskCommand } from "./commands/task.js";
8
9
  import { loadRuntimeConfig, updateRuntimeConfig } from "./config/runtime-config.js";
9
10
  import { createGitProcessEnv } from "./core/git-process-env.js";
10
11
  import { buildKanbanRuntimeUrl, DEFAULT_KANBAN_RUNTIME_PORT, getKanbanRuntimeOrigin, getKanbanRuntimePort, parseRuntimePort, setKanbanRuntimePort, } from "./core/runtime-endpoint.js";
@@ -15,7 +16,9 @@ import { createRuntimeStateHub } from "./server/runtime-state-hub.js";
15
16
  import { resolveInteractiveShellCommand } from "./server/shell.js";
16
17
  import { shutdownRuntimeServer } from "./server/shutdown-coordinator.js";
17
18
  import { collectProjectWorktreeTaskIdsForRemoval, createWorkspaceRegistry } from "./server/workspace-registry.js";
19
+ import { installKanbanSkillFiles, resolveKanbanSkillCommandPrefix } from "./skills/kanban-skill.js";
18
20
  import { loadWorkspaceContext } from "./state/workspace-state.js";
21
+ import { detectInstalledCommands } from "./terminal/agent-registry.js";
19
22
  import { autoUpdateOnStartup, runPendingAutoUpdateOnShutdown } from "./update/auto-update.js";
20
23
  const CLI_AGENT_IDS = ["claude", "codex", "gemini", "opencode", "droid", "cline"];
21
24
  const KANBAN_VERSION = typeof packageJson.version === "string" ? packageJson.version : "0.1.0";
@@ -46,73 +49,6 @@ function parseCliPortValue(rawValue) {
46
49
  throw new Error(`Invalid port value: ${rawValue}. Expected an integer from 1-65535 or "auto".`);
47
50
  }
48
51
  }
49
- function parseCliOptions(argv) {
50
- let help = false;
51
- let version = false;
52
- let noOpen = false;
53
- let agent = null;
54
- let port = null;
55
- for (let index = 0; index < argv.length; index += 1) {
56
- const arg = argv[index];
57
- if (arg === "--help" || arg === "-h") {
58
- help = true;
59
- continue;
60
- }
61
- if (arg === "--version" || arg === "-v") {
62
- version = true;
63
- continue;
64
- }
65
- if (arg === "--no-open") {
66
- noOpen = true;
67
- continue;
68
- }
69
- if (arg === "--agent") {
70
- const value = argv[index + 1];
71
- if (!value) {
72
- throw new Error("Missing value for --agent.");
73
- }
74
- agent = parseCliAgentId(value);
75
- index += 1;
76
- continue;
77
- }
78
- if (arg.startsWith("--agent=")) {
79
- const value = arg.slice("--agent=".length);
80
- if (!value) {
81
- throw new Error("Missing value for --agent.");
82
- }
83
- agent = parseCliAgentId(value);
84
- continue;
85
- }
86
- if (arg === "--port") {
87
- const value = argv[index + 1];
88
- if (!value) {
89
- throw new Error("Missing value for --port.");
90
- }
91
- port = parseCliPortValue(value);
92
- index += 1;
93
- continue;
94
- }
95
- if (arg.startsWith("--port=")) {
96
- const value = arg.slice("--port=".length);
97
- if (!value) {
98
- throw new Error("Missing value for --port.");
99
- }
100
- port = parseCliPortValue(value);
101
- }
102
- }
103
- return { help, version, noOpen, agent, port };
104
- }
105
- function printHelp() {
106
- console.log("kanban");
107
- console.log("Local orchestration board for coding agents.");
108
- console.log("");
109
- console.log("Usage:");
110
- console.log(" kanban [--agent <id>] [--port <number|auto>] [--no-open] [--help] [--version]");
111
- console.log(" kanban mcp");
112
- console.log("");
113
- console.log(`Runtime URL: ${getKanbanRuntimeOrigin()}`);
114
- console.log(`Agent IDs: ${CLI_AGENT_IDS.join(", ")}`);
115
- }
116
52
  async function isPortAvailable(port) {
117
53
  return await new Promise((resolve) => {
118
54
  const probe = createNetServer();
@@ -383,25 +319,7 @@ async function startServerWithAutoPortRetry(options) {
383
319
  }
384
320
  }
385
321
  }
386
- async function run() {
387
- const argv = process.argv.slice(2);
388
- if (isMcpSubcommand(argv)) {
389
- await runMcpSubcommand(argv);
390
- return;
391
- }
392
- if (isHooksSubcommand(argv)) {
393
- await runHooksSubcommand(argv);
394
- return;
395
- }
396
- const options = parseCliOptions(argv);
397
- if (options.help) {
398
- printHelp();
399
- return;
400
- }
401
- if (options.version) {
402
- console.log(KANBAN_VERSION);
403
- return;
404
- }
322
+ async function runMainCommand(options) {
405
323
  const selectedPort = await applyRuntimePortOption(options.port);
406
324
  if (selectedPort !== null) {
407
325
  console.log(`Using runtime port ${selectedPort}.`);
@@ -415,6 +333,20 @@ async function run() {
415
333
  console.log(`Default agent set to ${options.agent}.`);
416
334
  }
417
335
  }
336
+ try {
337
+ const detectedCommands = detectInstalledCommands();
338
+ const commandPrefix = resolveKanbanSkillCommandPrefix({
339
+ currentVersion: KANBAN_VERSION,
340
+ });
341
+ await installKanbanSkillFiles({
342
+ commandPrefix,
343
+ installClaudeSkill: detectedCommands.includes("claude"),
344
+ });
345
+ }
346
+ catch (error) {
347
+ const message = error instanceof Error ? error.message : String(error);
348
+ console.warn(`Could not install Kanban skill files: ${message}`);
349
+ }
418
350
  let runtime;
419
351
  try {
420
352
  runtime = await startServerWithAutoPortRetry(options);
@@ -470,6 +402,39 @@ async function run() {
470
402
  void shutdown("SIGTERM");
471
403
  });
472
404
  }
405
+ function createProgram() {
406
+ const program = new Command();
407
+ program
408
+ .name("kanban")
409
+ .description("Local orchestration board for coding agents.")
410
+ .version(KANBAN_VERSION, "-v, --version", "Output the version number")
411
+ .option("--agent <id>", `Default agent ID (${CLI_AGENT_IDS.join(", ")}).`, parseCliAgentId)
412
+ .option("--port <number|auto>", "Runtime port (1-65535) or auto.", parseCliPortValue)
413
+ .option("--no-open", "Do not open browser automatically.")
414
+ .showHelpAfterError()
415
+ .addHelpText("after", `\nRuntime URL: ${getKanbanRuntimeOrigin()}\nAgent IDs: ${CLI_AGENT_IDS.join(", ")}`);
416
+ registerTaskCommand(program);
417
+ registerHooksCommand(program);
418
+ program
419
+ .command("mcp")
420
+ .description("Deprecated compatibility command.")
421
+ .action(() => {
422
+ console.warn("Deprecated. Please uninstall Kanban MCP.");
423
+ });
424
+ program.action(async (options) => {
425
+ await runMainCommand({
426
+ agent: options.agent ?? null,
427
+ port: options.port ?? null,
428
+ noOpen: options.open === false,
429
+ });
430
+ });
431
+ return program;
432
+ }
433
+ async function run() {
434
+ const argv = process.argv.slice(2);
435
+ const program = createProgram();
436
+ await program.parseAsync(argv, { from: "user" });
437
+ }
473
438
  run().catch((error) => {
474
439
  const message = error instanceof Error ? error.message : String(error);
475
440
  console.error(`Failed to start Kanban: ${message}`);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,YAAY,IAAI,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,WAAW,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEhE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EACN,qBAAqB,EACrB,2BAA2B,EAC3B,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,GACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,uCAAuC,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAClH,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAElE,OAAO,EAAE,mBAAmB,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAU9F,MAAM,aAAa,GAA8B,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC7G,MAAM,cAAc,GAAG,OAAO,WAAW,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;AAE/F,SAAS,eAAe,CAAC,KAAa;IACrC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,IACC,UAAU,KAAK,QAAQ;QACvB,UAAU,KAAK,OAAO;QACtB,UAAU,KAAK,QAAQ;QACvB,UAAU,KAAK,UAAU;QACzB,UAAU,KAAK,OAAO;QACtB,UAAU,KAAK,OAAO,EACrB,CAAC;QACF,OAAO,UAAU,CAAC;IACnB,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,sBAAsB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC1F,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAgB;IAC1C,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACjD,IAAI,CAAC,UAAU,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;QAC3B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,CAAC;QACJ,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,gBAAgB,CAAC,UAAU,CAAC,EAAE,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,+CAA+C,CAAC,CAAC;IACjG,CAAC;AACF,CAAC;AAED,SAAS,eAAe,CAAC,IAAc;IACtC,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,KAAK,GAA0B,IAAI,CAAC;IACxC,IAAI,IAAI,GAA+D,IAAI,CAAC;IAE5E,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACtC,IAAI,GAAG,IAAI,CAAC;YACZ,SAAS;QACV,CAAC;QACD,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACzC,OAAO,GAAG,IAAI,CAAC;YACf,SAAS;QACV,CAAC;QACD,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YACzB,MAAM,GAAG,IAAI,CAAC;YACd,SAAS;QACV,CAAC;QACD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAC/C,CAAC;YACD,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;YAC/B,KAAK,IAAI,CAAC,CAAC;YACX,SAAS;QACV,CAAC;QACD,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC3C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAC/C,CAAC;YACD,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;YAC/B,SAAS;QACV,CAAC;QACD,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC9C,CAAC;YACD,IAAI,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAChC,KAAK,IAAI,CAAC,CAAC;YACX,SAAS;QACV,CAAC;QACD,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC9C,CAAC;YACD,IAAI,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;IACF,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAC/C,CAAC;AAED,SAAS,SAAS;IACjB,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,iFAAiF,CAAC,CAAC;IAC/F,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,gBAAgB,sBAAsB,EAAE,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,cAAc,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,MAAM,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;QAC7C,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;YACxB,OAAO,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;YACpC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE;gBAChB,OAAO,CAAC,IAAI,CAAC,CAAC;YACf,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,wBAAwB,CAAC,SAAiB;IACxD,KAAK,IAAI,SAAS,GAAG,SAAS,EAAE,SAAS,IAAI,KAAK,EAAE,SAAS,IAAI,CAAC,EAAE,CAAC;QACpE,IAAI,MAAM,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC;YACtC,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;AACrD,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,UAA8B;IACnE,IAAI,CAAC,UAAU,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACjC,oBAAoB,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACvC,OAAO,UAAU,CAAC,KAAK,CAAC;IACzB,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,2BAA2B,CAAC,CAAC;IAC7E,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC/B,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,wBAAwB,CAAC,GAAW,EAAE,eAA+B;IACnF,MAAM,oBAAoB,GAAG,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAC1D,IAAI,oBAAoB,CAAC,eAAe,KAAK,eAAe,EAAE,CAAC;QAC9D,OAAO,KAAK,CAAC;IACd,CAAC;IACD,MAAM,mBAAmB,CAAC,GAAG,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC;IACpD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,IAAY;IAChD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,oCAAoC,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;AACF,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,IAAY;IAC1C,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;AACF,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY;IACrC,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,uBAAuB,CAAC,EAAE;QACvE,GAAG,EAAE,IAAI;QACT,QAAQ,EAAE,MAAM;QAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;QACnC,GAAG,EAAE,mBAAmB,EAAE;KAC1B,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,MAAM,CAAC;AAC/D,CAAC;AAED,SAAS,iCAAiC;IACzC,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,SAAS,CACvB,WAAW,EACX,CAAC,IAAI,EAAE,qEAAqE,CAAC,EAC7E;YACC,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SACjC,CACD,CAAC;QACF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC;QACb,CAAC;QACD,MAAM,QAAQ,GAAG,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,OAAO,QAAQ,IAAI,IAAI,CAAC;IACzB,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,kBAAkB,EAAE,aAAa,EAAE,+BAA+B,CAAC,EAAE;YACxG,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SACjC,CAAC,CAAC;QACH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC;QACb,CAAC;QACD,MAAM,QAAQ,GAAG,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,OAAO,QAAQ,IAAI,IAAI,CAAC;IACzB,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAc;IAC1C,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACd,KAA+B,CAAC,IAAI,KAAK,YAAY,CACtD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,WAA0B;IAC7D,IAAI,CAAC;QACJ,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,IAAI,WAAW,EAAE,CAAC;YACjB,OAAO,CAAC,uBAAuB,CAAC,GAAG,WAAW,CAAC;QAChD,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,qBAAqB,CAAC,yBAAyB,CAAC,EAAE;YAC9E,MAAM,EAAE,KAAK;YACb,OAAO;YACP,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;SAClC,CAAC,CAAC;QACH,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC7B,OAAO,KAAK,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAGhD,CAAC;QACT,OAAO,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;AACF,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,MAAe;IACnD,IAAI,WAAW,GAAkB,IAAI,CAAC;IACtC,IAAI,gBAAgB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC1D,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACnC,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACxD,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,OAAO,KAAK,CAAC;IACd,CAAC;IACD,MAAM,UAAU,GAAG,WAAW;QAC7B,CAAC,CAAC,qBAAqB,CAAC,IAAI,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9D,CAAC,CAAC,sBAAsB,EAAE,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,6BAA6B,sBAAsB,EAAE,EAAE,CAAC,CAAC;IACrE,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,IAAI,CAAC;YACJ,aAAa,CAAC,UAAU,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,OAAO,CAAC,IAAI,CAAC,yCAAyC,OAAO,EAAE,CAAC,CAAC;QAClE,CAAC;IACF,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,gBAAgB,UAAU,EAAE,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC;AACb,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,OAAe,EAAE,GAAW;IAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,gBAAgB,GAAG,EAAE,GAAG,IAAI,CAAC;IAEnC,OAAO,MAAM,IAAI,OAAO,CAA4B,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACvE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE;YAC5B,GAAG;YACH,KAAK,EAAE,IAAI;YACX,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SACjC,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACpC,MAAM,CAAC,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC,CAAC;YACpE,OAAO;QACR,CAAC;QAED,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,MAAM,YAAY,GAAG,CAAC,OAAe,EAAE,KAAa,EAAU,EAAE;YAC/D,MAAM,IAAI,GAAG,OAAO,GAAG,KAAK,CAAC;YAC7B,IAAI,IAAI,CAAC,MAAM,IAAI,gBAAgB,EAAE,CAAC;gBACrC,OAAO,IAAI,CAAC;YACb,CAAC;YACD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;QACxC,CAAC,CAAC;QAEF,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAsB,EAAE,EAAE;YAClD,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAsB,EAAE,EAAE;YAClD,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC3B,MAAM,CAAC,KAAK,CAAC,CAAC;QACf,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC/B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvB,CAAC,EAAE,MAAM,CAAC,CAAC;QAEX,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAC1B,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,MAAM,QAAQ,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM,cAAc,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjF,OAAO,CAAC;gBACP,QAAQ;gBACR,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;gBACrB,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;gBACrB,cAAc;gBACd,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aAClC,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,WAAW;IACzB,IAAI,eAAqE,CAAC;IAC1E,MAAM,iBAAiB,GAAG,MAAM,uBAAuB,CAAC;QACvD,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,iBAAiB;QACjB,gBAAgB;QAChB,eAAe;QACf,sBAAsB,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE;YAChD,eAAe,EAAE,oBAAoB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC7D,CAAC;KACD,CAAC,CAAC;IACH,eAAe,GAAG,qBAAqB,CAAC;QACvC,iBAAiB;KACjB,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,eAAe,CAAC;IACnC,KAAK,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,IAAI,iBAAiB,CAAC,qBAAqB,EAAE,EAAE,CAAC;QAC1F,UAAU,CAAC,oBAAoB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,uBAAuB,GAAG,CAC/B,WAAmB,EACnB,OAEC,EACkF,EAAE;QACrF,MAAM,QAAQ,GAAG,iBAAiB,CAAC,gBAAgB,CAAC,WAAW,EAAE;YAChE,oBAAoB,EAAE,OAAO,EAAE,oBAAoB;SACnD,CAAC,CAAC;QACH,UAAU,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;QACzC,OAAO,QAAQ,CAAC;IACjB,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,MAAM,mBAAmB,CAAC;QAC/C,iBAAiB;QACjB,eAAe,EAAE,UAAU;QAC3B,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE;YACjB,OAAO,CAAC,IAAI,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,iCAAiC,EAAE,iBAAiB,CAAC,iCAAiC;QACtF,8BAA8B;QAC9B,UAAU,EAAE,gBAAgB;QAC5B,uBAAuB;QACvB,qBAAqB;QACrB,gBAAgB;QAChB,gBAAgB,EAAE,uBAAuB;QACzC,uCAAuC;QACvC,iCAAiC;KACjC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,KAAK,IAAI,EAAE;QACxB,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC3B,MAAM,qBAAqB,CAAC;YAC3B,iBAAiB;YACjB,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE;gBACjB,OAAO,CAAC,IAAI,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;YACrC,CAAC;YACD,kBAAkB,EAAE,KAAK;SACzB,CAAC,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO;QACN,GAAG,EAAE,aAAa,CAAC,GAAG;QACtB,KAAK;QACL,QAAQ;KACR,CAAC;AACH,CAAC;AAED,KAAK,UAAU,4BAA4B,CAAC,OAAmB;IAC9D,IAAI,OAAO,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;QACnC,OAAO,MAAM,WAAW,EAAE,CAAC;IAC5B,CAAC;IAED,OAAO,IAAI,EAAE,CAAC;QACb,IAAI,CAAC;YACJ,OAAO,MAAM,WAAW,EAAE,CAAC;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjC,MAAM,KAAK,CAAC;YACb,CAAC;YACD,MAAM,WAAW,GAAG,oBAAoB,EAAE,CAAC;YAC3C,MAAM,SAAS,GAAG,MAAM,wBAAwB,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;YAClE,oBAAoB,CAAC,SAAS,CAAC,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,gBAAgB,WAAW,4CAA4C,SAAS,GAAG,CAAC,CAAC;QACnG,CAAC;IACF,CAAC;AACF,CAAC;AAED,KAAK,UAAU,GAAG;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC7B,OAAO;IACR,CAAC;IACD,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,MAAM,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAC/B,OAAO;IACR,CAAC;IAED,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAEtC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,SAAS,EAAE,CAAC;QACZ,OAAO;IACR,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC5B,OAAO;IACR,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,sBAAsB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,sBAAsB,YAAY,GAAG,CAAC,CAAC;IACpD,CAAC;IAED,mBAAmB,CAAC;QACnB,cAAc,EAAE,cAAc;KAC9B,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,SAAS,GAAG,MAAM,wBAAwB,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAC/E,IAAI,SAAS,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,wBAAwB,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC;QACvD,CAAC;IACF,CAAC;IAED,IAAI,OAAgD,CAAC;IACrD,IAAI,CAAC;QACJ,OAAO,GAAG,MAAM,4BAA4B,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IACC,OAAO,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM;YAC7B,mBAAmB,CAAC,KAAK,CAAC;YAC1B,CAAC,MAAM,qBAAqB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAC5C,CAAC;YACF,OAAO;QACR,CAAC;QACD,MAAM,KAAK,CAAC;IACb,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,qBAAqB,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACrB,IAAI,CAAC;YACJ,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,OAAO,CAAC,IAAI,CAAC,yCAAyC,OAAO,EAAE,CAAC,CAAC;QAClE,CAAC;IACF,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IAErC,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,MAAM,QAAQ,GAAG,KAAK,EAAE,MAA4B,EAAE,EAAE;QACvD,IAAI,cAAc,EAAE,CAAC;YACpB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClB,OAAO;QACR,CAAC;QACD,cAAc,GAAG,IAAI,CAAC;QACtB,8BAA8B,EAAE,CAAC;QACjC,MAAM,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;YACtC,OAAO,CAAC,KAAK,CAAC,qBAAqB,MAAM,WAAW,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,cAAc,CAAC,KAAK,EAAE,CAAC;QACvB,IAAI,CAAC;YACJ,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;YACzB,YAAY,CAAC,cAAc,CAAC,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,YAAY,CAAC,cAAc,CAAC,CAAC;YAC7B,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;YAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;IACF,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACzB,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QAC1B,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,CAAC,KAAK,CAAC,2BAA2B,OAAO,EAAE,CAAC,CAAC;IACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\n\nimport { spawn, spawnSync } from \"node:child_process\";\nimport { stat } from \"node:fs/promises\";\nimport { createServer as createNetServer } from \"node:net\";\nimport packageJson from \"../package.json\" with { type: \"json\" };\n\nimport { isHooksSubcommand, runHooksSubcommand } from \"./commands/hooks.js\";\nimport { isMcpSubcommand, runMcpSubcommand } from \"./commands/mcp.js\";\nimport { loadRuntimeConfig, updateRuntimeConfig } from \"./config/runtime-config.js\";\nimport type { RuntimeAgentId, RuntimeCommandRunResponse } from \"./core/api-contract.js\";\nimport { createGitProcessEnv } from \"./core/git-process-env.js\";\nimport {\n\tbuildKanbanRuntimeUrl,\n\tDEFAULT_KANBAN_RUNTIME_PORT,\n\tgetKanbanRuntimeOrigin,\n\tgetKanbanRuntimePort,\n\tparseRuntimePort,\n\tsetKanbanRuntimePort,\n} from \"./core/runtime-endpoint.js\";\nimport { resolveProjectInputPath } from \"./projects/project-path.js\";\nimport { openInBrowser } from \"./server/browser.js\";\nimport { createRuntimeServer } from \"./server/runtime-server.js\";\nimport { createRuntimeStateHub } from \"./server/runtime-state-hub.js\";\nimport { resolveInteractiveShellCommand } from \"./server/shell.js\";\nimport { shutdownRuntimeServer } from \"./server/shutdown-coordinator.js\";\nimport { collectProjectWorktreeTaskIdsForRemoval, createWorkspaceRegistry } from \"./server/workspace-registry.js\";\nimport { loadWorkspaceContext } from \"./state/workspace-state.js\";\nimport type { TerminalSessionManager } from \"./terminal/session-manager.js\";\nimport { autoUpdateOnStartup, runPendingAutoUpdateOnShutdown } from \"./update/auto-update.js\";\n\ninterface CliOptions {\n\thelp: boolean;\n\tversion: boolean;\n\tnoOpen: boolean;\n\tagent: RuntimeAgentId | null;\n\tport: { mode: \"fixed\"; value: number } | { mode: \"auto\" } | null;\n}\n\nconst CLI_AGENT_IDS: readonly RuntimeAgentId[] = [\"claude\", \"codex\", \"gemini\", \"opencode\", \"droid\", \"cline\"];\nconst KANBAN_VERSION = typeof packageJson.version === \"string\" ? packageJson.version : \"0.1.0\";\n\nfunction parseCliAgentId(value: string): RuntimeAgentId {\n\tconst normalized = value.trim().toLowerCase();\n\tif (\n\t\tnormalized === \"claude\" ||\n\t\tnormalized === \"codex\" ||\n\t\tnormalized === \"gemini\" ||\n\t\tnormalized === \"opencode\" ||\n\t\tnormalized === \"droid\" ||\n\t\tnormalized === \"cline\"\n\t) {\n\t\treturn normalized;\n\t}\n\tthrow new Error(`Invalid agent: ${value}. Expected one of: ${CLI_AGENT_IDS.join(\", \")}`);\n}\n\nfunction parseCliPortValue(rawValue: string): { mode: \"fixed\"; value: number } | { mode: \"auto\" } {\n\tconst normalized = rawValue.trim().toLowerCase();\n\tif (!normalized) {\n\t\tthrow new Error(\"Missing value for --port.\");\n\t}\n\tif (normalized === \"auto\") {\n\t\treturn { mode: \"auto\" };\n\t}\n\ttry {\n\t\treturn { mode: \"fixed\", value: parseRuntimePort(normalized) };\n\t} catch {\n\t\tthrow new Error(`Invalid port value: ${rawValue}. Expected an integer from 1-65535 or \"auto\".`);\n\t}\n}\n\nfunction parseCliOptions(argv: string[]): CliOptions {\n\tlet help = false;\n\tlet version = false;\n\tlet noOpen = false;\n\tlet agent: RuntimeAgentId | null = null;\n\tlet port: { mode: \"fixed\"; value: number } | { mode: \"auto\" } | null = null;\n\n\tfor (let index = 0; index < argv.length; index += 1) {\n\t\tconst arg = argv[index];\n\t\tif (arg === \"--help\" || arg === \"-h\") {\n\t\t\thelp = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg === \"--version\" || arg === \"-v\") {\n\t\t\tversion = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg === \"--no-open\") {\n\t\t\tnoOpen = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg === \"--agent\") {\n\t\t\tconst value = argv[index + 1];\n\t\t\tif (!value) {\n\t\t\t\tthrow new Error(\"Missing value for --agent.\");\n\t\t\t}\n\t\t\tagent = parseCliAgentId(value);\n\t\t\tindex += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg.startsWith(\"--agent=\")) {\n\t\t\tconst value = arg.slice(\"--agent=\".length);\n\t\t\tif (!value) {\n\t\t\t\tthrow new Error(\"Missing value for --agent.\");\n\t\t\t}\n\t\t\tagent = parseCliAgentId(value);\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg === \"--port\") {\n\t\t\tconst value = argv[index + 1];\n\t\t\tif (!value) {\n\t\t\t\tthrow new Error(\"Missing value for --port.\");\n\t\t\t}\n\t\t\tport = parseCliPortValue(value);\n\t\t\tindex += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg.startsWith(\"--port=\")) {\n\t\t\tconst value = arg.slice(\"--port=\".length);\n\t\t\tif (!value) {\n\t\t\t\tthrow new Error(\"Missing value for --port.\");\n\t\t\t}\n\t\t\tport = parseCliPortValue(value);\n\t\t}\n\t}\n\n\treturn { help, version, noOpen, agent, port };\n}\n\nfunction printHelp(): void {\n\tconsole.log(\"kanban\");\n\tconsole.log(\"Local orchestration board for coding agents.\");\n\tconsole.log(\"\");\n\tconsole.log(\"Usage:\");\n\tconsole.log(\" kanban [--agent <id>] [--port <number|auto>] [--no-open] [--help] [--version]\");\n\tconsole.log(\" kanban mcp\");\n\tconsole.log(\"\");\n\tconsole.log(`Runtime URL: ${getKanbanRuntimeOrigin()}`);\n\tconsole.log(`Agent IDs: ${CLI_AGENT_IDS.join(\", \")}`);\n}\n\nasync function isPortAvailable(port: number): Promise<boolean> {\n\treturn await new Promise<boolean>((resolve) => {\n\t\tconst probe = createNetServer();\n\t\tprobe.once(\"error\", () => {\n\t\t\tresolve(false);\n\t\t});\n\t\tprobe.listen(port, \"127.0.0.1\", () => {\n\t\t\tprobe.close(() => {\n\t\t\t\tresolve(true);\n\t\t\t});\n\t\t});\n\t});\n}\n\nasync function findAvailableRuntimePort(startPort: number): Promise<number> {\n\tfor (let candidate = startPort; candidate <= 65535; candidate += 1) {\n\t\tif (await isPortAvailable(candidate)) {\n\t\t\treturn candidate;\n\t\t}\n\t}\n\tthrow new Error(\"No available runtime port found.\");\n}\n\nasync function applyRuntimePortOption(portOption: CliOptions[\"port\"]): Promise<number | null> {\n\tif (!portOption) {\n\t\treturn null;\n\t}\n\tif (portOption.mode === \"fixed\") {\n\t\tsetKanbanRuntimePort(portOption.value);\n\t\treturn portOption.value;\n\t}\n\tconst autoPort = await findAvailableRuntimePort(DEFAULT_KANBAN_RUNTIME_PORT);\n\tsetKanbanRuntimePort(autoPort);\n\treturn autoPort;\n}\n\nasync function persistCliAgentSelection(cwd: string, selectedAgentId: RuntimeAgentId): Promise<boolean> {\n\tconst currentRuntimeConfig = await loadRuntimeConfig(cwd);\n\tif (currentRuntimeConfig.selectedAgentId === selectedAgentId) {\n\t\treturn false;\n\t}\n\tawait updateRuntimeConfig(cwd, { selectedAgentId });\n\treturn true;\n}\n\nasync function assertPathIsDirectory(path: string): Promise<void> {\n\tconst info = await stat(path);\n\tif (!info.isDirectory()) {\n\t\tthrow new Error(`Project path is not a directory: ${path}`);\n\t}\n}\n\nasync function pathIsDirectory(path: string): Promise<boolean> {\n\ttry {\n\t\tconst info = await stat(path);\n\t\treturn info.isDirectory();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction hasGitRepository(path: string): boolean {\n\tconst result = spawnSync(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"], {\n\t\tcwd: path,\n\t\tencoding: \"utf8\",\n\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\tenv: createGitProcessEnv(),\n\t});\n\treturn result.status === 0 && result.stdout.trim() === \"true\";\n}\n\nfunction pickDirectoryPathFromSystemDialog(): string | null {\n\tif (process.platform === \"darwin\") {\n\t\tconst result = spawnSync(\n\t\t\t\"osascript\",\n\t\t\t[\"-e\", 'POSIX path of (choose folder with prompt \"Select a project folder\")'],\n\t\t\t{\n\t\t\t\tencoding: \"utf8\",\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t},\n\t\t);\n\t\tif (result.status !== 0) {\n\t\t\treturn null;\n\t\t}\n\t\tconst selected = typeof result.stdout === \"string\" ? result.stdout.trim() : \"\";\n\t\treturn selected || null;\n\t}\n\n\tif (process.platform === \"linux\") {\n\t\tconst result = spawnSync(\"zenity\", [\"--file-selection\", \"--directory\", \"--title=Select project folder\"], {\n\t\t\tencoding: \"utf8\",\n\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t});\n\t\tif (result.status !== 0) {\n\t\t\treturn null;\n\t\t}\n\t\tconst selected = typeof result.stdout === \"string\" ? result.stdout.trim() : \"\";\n\t\treturn selected || null;\n\t}\n\n\treturn null;\n}\n\nfunction isAddressInUseError(error: unknown): error is NodeJS.ErrnoException {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"code\" in error &&\n\t\t(error as NodeJS.ErrnoException).code === \"EADDRINUSE\"\n\t);\n}\n\nasync function canReachKanbanServer(workspaceId: string | null): Promise<boolean> {\n\ttry {\n\t\tconst headers: Record<string, string> = {};\n\t\tif (workspaceId) {\n\t\t\theaders[\"x-kanban-workspace-id\"] = workspaceId;\n\t\t}\n\t\tconst response = await fetch(buildKanbanRuntimeUrl(\"/api/trpc/projects.list\"), {\n\t\t\tmethod: \"GET\",\n\t\t\theaders,\n\t\t\tsignal: AbortSignal.timeout(1_500),\n\t\t});\n\t\tif (response.status === 404) {\n\t\t\treturn false;\n\t\t}\n\t\tconst payload = (await response.json().catch(() => null)) as {\n\t\t\tresult?: { data?: unknown };\n\t\t\terror?: unknown;\n\t\t} | null;\n\t\treturn Boolean(payload && (payload.result || payload.error));\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function tryOpenExistingServer(noOpen: boolean): Promise<boolean> {\n\tlet workspaceId: string | null = null;\n\tif (hasGitRepository(process.cwd())) {\n\t\tconst context = await loadWorkspaceContext(process.cwd());\n\t\tworkspaceId = context.workspaceId;\n\t}\n\tconst running = await canReachKanbanServer(workspaceId);\n\tif (!running) {\n\t\treturn false;\n\t}\n\tconst projectUrl = workspaceId\n\t\t? buildKanbanRuntimeUrl(`/${encodeURIComponent(workspaceId)}`)\n\t\t: getKanbanRuntimeOrigin();\n\tconsole.log(`Kanban already running at ${getKanbanRuntimeOrigin()}`);\n\tif (!noOpen) {\n\t\ttry {\n\t\t\topenInBrowser(projectUrl);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tconsole.warn(`Could not open browser automatically: ${message}`);\n\t\t}\n\t}\n\tconsole.log(`Project URL: ${projectUrl}`);\n\treturn true;\n}\n\nasync function runScopedCommand(command: string, cwd: string): Promise<RuntimeCommandRunResponse> {\n\tconst startedAt = Date.now();\n\tconst outputLimitBytes = 64 * 1024;\n\n\treturn await new Promise<RuntimeCommandRunResponse>((resolve, reject) => {\n\t\tconst child = spawn(command, {\n\t\t\tcwd,\n\t\t\tshell: true,\n\t\t\tenv: process.env,\n\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t});\n\n\t\tif (!child.stdout || !child.stderr) {\n\t\t\treject(new Error(\"Shortcut process did not expose stdout/stderr.\"));\n\t\t\treturn;\n\t\t}\n\n\t\tlet stdout = \"\";\n\t\tlet stderr = \"\";\n\n\t\tconst appendOutput = (current: string, chunk: string): string => {\n\t\t\tconst next = current + chunk;\n\t\t\tif (next.length <= outputLimitBytes) {\n\t\t\t\treturn next;\n\t\t\t}\n\t\t\treturn next.slice(0, outputLimitBytes);\n\t\t};\n\n\t\tchild.stdout.on(\"data\", (chunk: Buffer | string) => {\n\t\t\tstdout = appendOutput(stdout, String(chunk));\n\t\t});\n\n\t\tchild.stderr.on(\"data\", (chunk: Buffer | string) => {\n\t\t\tstderr = appendOutput(stderr, String(chunk));\n\t\t});\n\n\t\tchild.on(\"error\", (error) => {\n\t\t\treject(error);\n\t\t});\n\n\t\tconst timeout = setTimeout(() => {\n\t\t\tchild.kill(\"SIGTERM\");\n\t\t}, 60_000);\n\n\t\tchild.on(\"close\", (code) => {\n\t\t\tclearTimeout(timeout);\n\t\t\tconst exitCode = typeof code === \"number\" ? code : 1;\n\t\t\tconst combinedOutput = [stdout.trim(), stderr.trim()].filter(Boolean).join(\"\\n\");\n\t\t\tresolve({\n\t\t\t\texitCode,\n\t\t\t\tstdout: stdout.trim(),\n\t\t\t\tstderr: stderr.trim(),\n\t\t\t\tcombinedOutput,\n\t\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\t});\n\t\t});\n\t});\n}\n\nasync function startServer(): Promise<{ url: string; close: () => Promise<void>; shutdown: () => Promise<void> }> {\n\tlet runtimeStateHub: ReturnType<typeof createRuntimeStateHub> | undefined;\n\tconst workspaceRegistry = await createWorkspaceRegistry({\n\t\tcwd: process.cwd(),\n\t\tloadRuntimeConfig,\n\t\thasGitRepository,\n\t\tpathIsDirectory,\n\t\tonTerminalManagerReady: (workspaceId, manager) => {\n\t\t\truntimeStateHub?.trackTerminalManager(workspaceId, manager);\n\t\t},\n\t});\n\truntimeStateHub = createRuntimeStateHub({\n\t\tworkspaceRegistry,\n\t});\n\tconst runtimeHub = runtimeStateHub;\n\tfor (const { workspaceId, terminalManager } of workspaceRegistry.listManagedWorkspaces()) {\n\t\truntimeHub.trackTerminalManager(workspaceId, terminalManager);\n\t}\n\n\tconst disposeTrackedWorkspace = (\n\t\tworkspaceId: string,\n\t\toptions?: {\n\t\t\tstopTerminalSessions?: boolean;\n\t\t},\n\t): { terminalManager: TerminalSessionManager | null; workspacePath: string | null } => {\n\t\tconst disposed = workspaceRegistry.disposeWorkspace(workspaceId, {\n\t\t\tstopTerminalSessions: options?.stopTerminalSessions,\n\t\t});\n\t\truntimeHub.disposeWorkspace(workspaceId);\n\t\treturn disposed;\n\t};\n\n\tconst runtimeServer = await createRuntimeServer({\n\t\tworkspaceRegistry,\n\t\truntimeStateHub: runtimeHub,\n\t\twarn: (message) => {\n\t\t\tconsole.warn(`[kanban] ${message}`);\n\t\t},\n\t\tensureTerminalManagerForWorkspace: workspaceRegistry.ensureTerminalManagerForWorkspace,\n\t\tresolveInteractiveShellCommand,\n\t\trunCommand: runScopedCommand,\n\t\tresolveProjectInputPath,\n\t\tassertPathIsDirectory,\n\t\thasGitRepository,\n\t\tdisposeWorkspace: disposeTrackedWorkspace,\n\t\tcollectProjectWorktreeTaskIdsForRemoval,\n\t\tpickDirectoryPathFromSystemDialog,\n\t});\n\n\tconst close = async () => {\n\t\tawait runtimeServer.close();\n\t};\n\n\tconst shutdown = async () => {\n\t\tawait shutdownRuntimeServer({\n\t\t\tworkspaceRegistry,\n\t\t\twarn: (message) => {\n\t\t\t\tconsole.warn(`[kanban] ${message}`);\n\t\t\t},\n\t\t\tcloseRuntimeServer: close,\n\t\t});\n\t};\n\n\treturn {\n\t\turl: runtimeServer.url,\n\t\tclose,\n\t\tshutdown,\n\t};\n}\n\nasync function startServerWithAutoPortRetry(options: CliOptions): Promise<Awaited<ReturnType<typeof startServer>>> {\n\tif (options.port?.mode !== \"auto\") {\n\t\treturn await startServer();\n\t}\n\n\twhile (true) {\n\t\ttry {\n\t\t\treturn await startServer();\n\t\t} catch (error) {\n\t\t\tif (!isAddressInUseError(error)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tconst currentPort = getKanbanRuntimePort();\n\t\t\tconst retryPort = await findAvailableRuntimePort(currentPort + 1);\n\t\t\tsetKanbanRuntimePort(retryPort);\n\t\t\tconsole.warn(`Runtime port ${currentPort} became busy during startup, retrying on ${retryPort}.`);\n\t\t}\n\t}\n}\n\nasync function run(): Promise<void> {\n\tconst argv = process.argv.slice(2);\n\tif (isMcpSubcommand(argv)) {\n\t\tawait runMcpSubcommand(argv);\n\t\treturn;\n\t}\n\tif (isHooksSubcommand(argv)) {\n\t\tawait runHooksSubcommand(argv);\n\t\treturn;\n\t}\n\n\tconst options = parseCliOptions(argv);\n\n\tif (options.help) {\n\t\tprintHelp();\n\t\treturn;\n\t}\n\tif (options.version) {\n\t\tconsole.log(KANBAN_VERSION);\n\t\treturn;\n\t}\n\n\tconst selectedPort = await applyRuntimePortOption(options.port);\n\tif (selectedPort !== null) {\n\t\tconsole.log(`Using runtime port ${selectedPort}.`);\n\t}\n\n\tautoUpdateOnStartup({\n\t\tcurrentVersion: KANBAN_VERSION,\n\t});\n\n\tif (options.agent) {\n\t\tconst didChange = await persistCliAgentSelection(process.cwd(), options.agent);\n\t\tif (didChange) {\n\t\t\tconsole.log(`Default agent set to ${options.agent}.`);\n\t\t}\n\t}\n\n\tlet runtime: Awaited<ReturnType<typeof startServer>>;\n\ttry {\n\t\truntime = await startServerWithAutoPortRetry(options);\n\t} catch (error) {\n\t\tif (\n\t\t\toptions.port?.mode !== \"auto\" &&\n\t\t\tisAddressInUseError(error) &&\n\t\t\t(await tryOpenExistingServer(options.noOpen))\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\tthrow error;\n\t}\n\tconsole.log(`Kanban running at ${runtime.url}`);\n\tif (!options.noOpen) {\n\t\ttry {\n\t\t\topenInBrowser(runtime.url);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tconsole.warn(`Could not open browser automatically: ${message}`);\n\t\t}\n\t}\n\tconsole.log(\"Press Ctrl+C to stop.\");\n\n\tlet isShuttingDown = false;\n\tconst shutdown = async (signal: \"SIGINT\" | \"SIGTERM\") => {\n\t\tif (isShuttingDown) {\n\t\t\tprocess.exit(130);\n\t\t\treturn;\n\t\t}\n\t\tisShuttingDown = true;\n\t\trunPendingAutoUpdateOnShutdown();\n\t\tconst forceExitTimer = setTimeout(() => {\n\t\t\tconsole.error(`Forced exit after ${signal} timeout.`);\n\t\t\tprocess.exit(130);\n\t\t}, 3000);\n\t\tforceExitTimer.unref();\n\t\ttry {\n\t\t\tawait runtime.shutdown();\n\t\t\tclearTimeout(forceExitTimer);\n\t\t\tprocess.exit(130);\n\t\t} catch (error) {\n\t\t\tclearTimeout(forceExitTimer);\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tconsole.error(`Shutdown failed: ${message}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t};\n\tprocess.on(\"SIGINT\", () => {\n\t\tvoid shutdown(\"SIGINT\");\n\t});\n\tprocess.on(\"SIGTERM\", () => {\n\t\tvoid shutdown(\"SIGTERM\");\n\t});\n}\n\nrun().catch((error) => {\n\tconst message = error instanceof Error ? error.message : String(error);\n\tconsole.error(`Failed to start Kanban: ${message}`);\n\tprocess.exit(1);\n});\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport { spawn, spawnSync } from \"node:child_process\";\nimport { stat } from \"node:fs/promises\";\nimport { createServer as createNetServer } from \"node:net\";\nimport { Command } from \"commander\";\nimport packageJson from \"../package.json\" with { type: \"json\" };\n\nimport { registerHooksCommand } from \"./commands/hooks.js\";\nimport { registerTaskCommand } from \"./commands/task.js\";\nimport { loadRuntimeConfig, updateRuntimeConfig } from \"./config/runtime-config.js\";\nimport type { RuntimeAgentId, RuntimeCommandRunResponse } from \"./core/api-contract.js\";\nimport { createGitProcessEnv } from \"./core/git-process-env.js\";\nimport {\n\tbuildKanbanRuntimeUrl,\n\tDEFAULT_KANBAN_RUNTIME_PORT,\n\tgetKanbanRuntimeOrigin,\n\tgetKanbanRuntimePort,\n\tparseRuntimePort,\n\tsetKanbanRuntimePort,\n} from \"./core/runtime-endpoint.js\";\nimport { resolveProjectInputPath } from \"./projects/project-path.js\";\nimport { openInBrowser } from \"./server/browser.js\";\nimport { createRuntimeServer } from \"./server/runtime-server.js\";\nimport { createRuntimeStateHub } from \"./server/runtime-state-hub.js\";\nimport { resolveInteractiveShellCommand } from \"./server/shell.js\";\nimport { shutdownRuntimeServer } from \"./server/shutdown-coordinator.js\";\nimport { collectProjectWorktreeTaskIdsForRemoval, createWorkspaceRegistry } from \"./server/workspace-registry.js\";\nimport { installKanbanSkillFiles, resolveKanbanSkillCommandPrefix } from \"./skills/kanban-skill.js\";\nimport { loadWorkspaceContext } from \"./state/workspace-state.js\";\nimport { detectInstalledCommands } from \"./terminal/agent-registry.js\";\nimport type { TerminalSessionManager } from \"./terminal/session-manager.js\";\nimport { autoUpdateOnStartup, runPendingAutoUpdateOnShutdown } from \"./update/auto-update.js\";\n\ninterface CliOptions {\n\tnoOpen: boolean;\n\tagent: RuntimeAgentId | null;\n\tport: { mode: \"fixed\"; value: number } | { mode: \"auto\" } | null;\n}\n\nconst CLI_AGENT_IDS: readonly RuntimeAgentId[] = [\"claude\", \"codex\", \"gemini\", \"opencode\", \"droid\", \"cline\"];\nconst KANBAN_VERSION = typeof packageJson.version === \"string\" ? packageJson.version : \"0.1.0\";\n\nfunction parseCliAgentId(value: string): RuntimeAgentId {\n\tconst normalized = value.trim().toLowerCase();\n\tif (\n\t\tnormalized === \"claude\" ||\n\t\tnormalized === \"codex\" ||\n\t\tnormalized === \"gemini\" ||\n\t\tnormalized === \"opencode\" ||\n\t\tnormalized === \"droid\" ||\n\t\tnormalized === \"cline\"\n\t) {\n\t\treturn normalized;\n\t}\n\tthrow new Error(`Invalid agent: ${value}. Expected one of: ${CLI_AGENT_IDS.join(\", \")}`);\n}\n\nfunction parseCliPortValue(rawValue: string): { mode: \"fixed\"; value: number } | { mode: \"auto\" } {\n\tconst normalized = rawValue.trim().toLowerCase();\n\tif (!normalized) {\n\t\tthrow new Error(\"Missing value for --port.\");\n\t}\n\tif (normalized === \"auto\") {\n\t\treturn { mode: \"auto\" };\n\t}\n\ttry {\n\t\treturn { mode: \"fixed\", value: parseRuntimePort(normalized) };\n\t} catch {\n\t\tthrow new Error(`Invalid port value: ${rawValue}. Expected an integer from 1-65535 or \"auto\".`);\n\t}\n}\n\ninterface RootCommandOptions {\n\tagent?: RuntimeAgentId;\n\tport?: { mode: \"fixed\"; value: number } | { mode: \"auto\" };\n\topen?: boolean;\n}\n\nasync function isPortAvailable(port: number): Promise<boolean> {\n\treturn await new Promise<boolean>((resolve) => {\n\t\tconst probe = createNetServer();\n\t\tprobe.once(\"error\", () => {\n\t\t\tresolve(false);\n\t\t});\n\t\tprobe.listen(port, \"127.0.0.1\", () => {\n\t\t\tprobe.close(() => {\n\t\t\t\tresolve(true);\n\t\t\t});\n\t\t});\n\t});\n}\n\nasync function findAvailableRuntimePort(startPort: number): Promise<number> {\n\tfor (let candidate = startPort; candidate <= 65535; candidate += 1) {\n\t\tif (await isPortAvailable(candidate)) {\n\t\t\treturn candidate;\n\t\t}\n\t}\n\tthrow new Error(\"No available runtime port found.\");\n}\n\nasync function applyRuntimePortOption(portOption: CliOptions[\"port\"]): Promise<number | null> {\n\tif (!portOption) {\n\t\treturn null;\n\t}\n\tif (portOption.mode === \"fixed\") {\n\t\tsetKanbanRuntimePort(portOption.value);\n\t\treturn portOption.value;\n\t}\n\tconst autoPort = await findAvailableRuntimePort(DEFAULT_KANBAN_RUNTIME_PORT);\n\tsetKanbanRuntimePort(autoPort);\n\treturn autoPort;\n}\n\nasync function persistCliAgentSelection(cwd: string, selectedAgentId: RuntimeAgentId): Promise<boolean> {\n\tconst currentRuntimeConfig = await loadRuntimeConfig(cwd);\n\tif (currentRuntimeConfig.selectedAgentId === selectedAgentId) {\n\t\treturn false;\n\t}\n\tawait updateRuntimeConfig(cwd, { selectedAgentId });\n\treturn true;\n}\n\nasync function assertPathIsDirectory(path: string): Promise<void> {\n\tconst info = await stat(path);\n\tif (!info.isDirectory()) {\n\t\tthrow new Error(`Project path is not a directory: ${path}`);\n\t}\n}\n\nasync function pathIsDirectory(path: string): Promise<boolean> {\n\ttry {\n\t\tconst info = await stat(path);\n\t\treturn info.isDirectory();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction hasGitRepository(path: string): boolean {\n\tconst result = spawnSync(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"], {\n\t\tcwd: path,\n\t\tencoding: \"utf8\",\n\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\tenv: createGitProcessEnv(),\n\t});\n\treturn result.status === 0 && result.stdout.trim() === \"true\";\n}\n\nfunction pickDirectoryPathFromSystemDialog(): string | null {\n\tif (process.platform === \"darwin\") {\n\t\tconst result = spawnSync(\n\t\t\t\"osascript\",\n\t\t\t[\"-e\", 'POSIX path of (choose folder with prompt \"Select a project folder\")'],\n\t\t\t{\n\t\t\t\tencoding: \"utf8\",\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t},\n\t\t);\n\t\tif (result.status !== 0) {\n\t\t\treturn null;\n\t\t}\n\t\tconst selected = typeof result.stdout === \"string\" ? result.stdout.trim() : \"\";\n\t\treturn selected || null;\n\t}\n\n\tif (process.platform === \"linux\") {\n\t\tconst result = spawnSync(\"zenity\", [\"--file-selection\", \"--directory\", \"--title=Select project folder\"], {\n\t\t\tencoding: \"utf8\",\n\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t});\n\t\tif (result.status !== 0) {\n\t\t\treturn null;\n\t\t}\n\t\tconst selected = typeof result.stdout === \"string\" ? result.stdout.trim() : \"\";\n\t\treturn selected || null;\n\t}\n\n\treturn null;\n}\n\nfunction isAddressInUseError(error: unknown): error is NodeJS.ErrnoException {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"code\" in error &&\n\t\t(error as NodeJS.ErrnoException).code === \"EADDRINUSE\"\n\t);\n}\n\nasync function canReachKanbanServer(workspaceId: string | null): Promise<boolean> {\n\ttry {\n\t\tconst headers: Record<string, string> = {};\n\t\tif (workspaceId) {\n\t\t\theaders[\"x-kanban-workspace-id\"] = workspaceId;\n\t\t}\n\t\tconst response = await fetch(buildKanbanRuntimeUrl(\"/api/trpc/projects.list\"), {\n\t\t\tmethod: \"GET\",\n\t\t\theaders,\n\t\t\tsignal: AbortSignal.timeout(1_500),\n\t\t});\n\t\tif (response.status === 404) {\n\t\t\treturn false;\n\t\t}\n\t\tconst payload = (await response.json().catch(() => null)) as {\n\t\t\tresult?: { data?: unknown };\n\t\t\terror?: unknown;\n\t\t} | null;\n\t\treturn Boolean(payload && (payload.result || payload.error));\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function tryOpenExistingServer(noOpen: boolean): Promise<boolean> {\n\tlet workspaceId: string | null = null;\n\tif (hasGitRepository(process.cwd())) {\n\t\tconst context = await loadWorkspaceContext(process.cwd());\n\t\tworkspaceId = context.workspaceId;\n\t}\n\tconst running = await canReachKanbanServer(workspaceId);\n\tif (!running) {\n\t\treturn false;\n\t}\n\tconst projectUrl = workspaceId\n\t\t? buildKanbanRuntimeUrl(`/${encodeURIComponent(workspaceId)}`)\n\t\t: getKanbanRuntimeOrigin();\n\tconsole.log(`Kanban already running at ${getKanbanRuntimeOrigin()}`);\n\tif (!noOpen) {\n\t\ttry {\n\t\t\topenInBrowser(projectUrl);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tconsole.warn(`Could not open browser automatically: ${message}`);\n\t\t}\n\t}\n\tconsole.log(`Project URL: ${projectUrl}`);\n\treturn true;\n}\n\nasync function runScopedCommand(command: string, cwd: string): Promise<RuntimeCommandRunResponse> {\n\tconst startedAt = Date.now();\n\tconst outputLimitBytes = 64 * 1024;\n\n\treturn await new Promise<RuntimeCommandRunResponse>((resolve, reject) => {\n\t\tconst child = spawn(command, {\n\t\t\tcwd,\n\t\t\tshell: true,\n\t\t\tenv: process.env,\n\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t});\n\n\t\tif (!child.stdout || !child.stderr) {\n\t\t\treject(new Error(\"Shortcut process did not expose stdout/stderr.\"));\n\t\t\treturn;\n\t\t}\n\n\t\tlet stdout = \"\";\n\t\tlet stderr = \"\";\n\n\t\tconst appendOutput = (current: string, chunk: string): string => {\n\t\t\tconst next = current + chunk;\n\t\t\tif (next.length <= outputLimitBytes) {\n\t\t\t\treturn next;\n\t\t\t}\n\t\t\treturn next.slice(0, outputLimitBytes);\n\t\t};\n\n\t\tchild.stdout.on(\"data\", (chunk: Buffer | string) => {\n\t\t\tstdout = appendOutput(stdout, String(chunk));\n\t\t});\n\n\t\tchild.stderr.on(\"data\", (chunk: Buffer | string) => {\n\t\t\tstderr = appendOutput(stderr, String(chunk));\n\t\t});\n\n\t\tchild.on(\"error\", (error) => {\n\t\t\treject(error);\n\t\t});\n\n\t\tconst timeout = setTimeout(() => {\n\t\t\tchild.kill(\"SIGTERM\");\n\t\t}, 60_000);\n\n\t\tchild.on(\"close\", (code) => {\n\t\t\tclearTimeout(timeout);\n\t\t\tconst exitCode = typeof code === \"number\" ? code : 1;\n\t\t\tconst combinedOutput = [stdout.trim(), stderr.trim()].filter(Boolean).join(\"\\n\");\n\t\t\tresolve({\n\t\t\t\texitCode,\n\t\t\t\tstdout: stdout.trim(),\n\t\t\t\tstderr: stderr.trim(),\n\t\t\t\tcombinedOutput,\n\t\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\t});\n\t\t});\n\t});\n}\n\nasync function startServer(): Promise<{ url: string; close: () => Promise<void>; shutdown: () => Promise<void> }> {\n\tlet runtimeStateHub: ReturnType<typeof createRuntimeStateHub> | undefined;\n\tconst workspaceRegistry = await createWorkspaceRegistry({\n\t\tcwd: process.cwd(),\n\t\tloadRuntimeConfig,\n\t\thasGitRepository,\n\t\tpathIsDirectory,\n\t\tonTerminalManagerReady: (workspaceId, manager) => {\n\t\t\truntimeStateHub?.trackTerminalManager(workspaceId, manager);\n\t\t},\n\t});\n\truntimeStateHub = createRuntimeStateHub({\n\t\tworkspaceRegistry,\n\t});\n\tconst runtimeHub = runtimeStateHub;\n\tfor (const { workspaceId, terminalManager } of workspaceRegistry.listManagedWorkspaces()) {\n\t\truntimeHub.trackTerminalManager(workspaceId, terminalManager);\n\t}\n\n\tconst disposeTrackedWorkspace = (\n\t\tworkspaceId: string,\n\t\toptions?: {\n\t\t\tstopTerminalSessions?: boolean;\n\t\t},\n\t): { terminalManager: TerminalSessionManager | null; workspacePath: string | null } => {\n\t\tconst disposed = workspaceRegistry.disposeWorkspace(workspaceId, {\n\t\t\tstopTerminalSessions: options?.stopTerminalSessions,\n\t\t});\n\t\truntimeHub.disposeWorkspace(workspaceId);\n\t\treturn disposed;\n\t};\n\n\tconst runtimeServer = await createRuntimeServer({\n\t\tworkspaceRegistry,\n\t\truntimeStateHub: runtimeHub,\n\t\twarn: (message) => {\n\t\t\tconsole.warn(`[kanban] ${message}`);\n\t\t},\n\t\tensureTerminalManagerForWorkspace: workspaceRegistry.ensureTerminalManagerForWorkspace,\n\t\tresolveInteractiveShellCommand,\n\t\trunCommand: runScopedCommand,\n\t\tresolveProjectInputPath,\n\t\tassertPathIsDirectory,\n\t\thasGitRepository,\n\t\tdisposeWorkspace: disposeTrackedWorkspace,\n\t\tcollectProjectWorktreeTaskIdsForRemoval,\n\t\tpickDirectoryPathFromSystemDialog,\n\t});\n\n\tconst close = async () => {\n\t\tawait runtimeServer.close();\n\t};\n\n\tconst shutdown = async () => {\n\t\tawait shutdownRuntimeServer({\n\t\t\tworkspaceRegistry,\n\t\t\twarn: (message) => {\n\t\t\t\tconsole.warn(`[kanban] ${message}`);\n\t\t\t},\n\t\t\tcloseRuntimeServer: close,\n\t\t});\n\t};\n\n\treturn {\n\t\turl: runtimeServer.url,\n\t\tclose,\n\t\tshutdown,\n\t};\n}\n\nasync function startServerWithAutoPortRetry(options: CliOptions): Promise<Awaited<ReturnType<typeof startServer>>> {\n\tif (options.port?.mode !== \"auto\") {\n\t\treturn await startServer();\n\t}\n\n\twhile (true) {\n\t\ttry {\n\t\t\treturn await startServer();\n\t\t} catch (error) {\n\t\t\tif (!isAddressInUseError(error)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tconst currentPort = getKanbanRuntimePort();\n\t\t\tconst retryPort = await findAvailableRuntimePort(currentPort + 1);\n\t\t\tsetKanbanRuntimePort(retryPort);\n\t\t\tconsole.warn(`Runtime port ${currentPort} became busy during startup, retrying on ${retryPort}.`);\n\t\t}\n\t}\n}\n\nasync function runMainCommand(options: CliOptions): Promise<void> {\n\tconst selectedPort = await applyRuntimePortOption(options.port);\n\tif (selectedPort !== null) {\n\t\tconsole.log(`Using runtime port ${selectedPort}.`);\n\t}\n\n\tautoUpdateOnStartup({\n\t\tcurrentVersion: KANBAN_VERSION,\n\t});\n\n\tif (options.agent) {\n\t\tconst didChange = await persistCliAgentSelection(process.cwd(), options.agent);\n\t\tif (didChange) {\n\t\t\tconsole.log(`Default agent set to ${options.agent}.`);\n\t\t}\n\t}\n\n\ttry {\n\t\tconst detectedCommands = detectInstalledCommands();\n\t\tconst commandPrefix = resolveKanbanSkillCommandPrefix({\n\t\t\tcurrentVersion: KANBAN_VERSION,\n\t\t});\n\t\tawait installKanbanSkillFiles({\n\t\t\tcommandPrefix,\n\t\t\tinstallClaudeSkill: detectedCommands.includes(\"claude\"),\n\t\t});\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tconsole.warn(`Could not install Kanban skill files: ${message}`);\n\t}\n\n\tlet runtime: Awaited<ReturnType<typeof startServer>>;\n\ttry {\n\t\truntime = await startServerWithAutoPortRetry(options);\n\t} catch (error) {\n\t\tif (\n\t\t\toptions.port?.mode !== \"auto\" &&\n\t\t\tisAddressInUseError(error) &&\n\t\t\t(await tryOpenExistingServer(options.noOpen))\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\tthrow error;\n\t}\n\tconsole.log(`Kanban running at ${runtime.url}`);\n\tif (!options.noOpen) {\n\t\ttry {\n\t\t\topenInBrowser(runtime.url);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tconsole.warn(`Could not open browser automatically: ${message}`);\n\t\t}\n\t}\n\tconsole.log(\"Press Ctrl+C to stop.\");\n\n\tlet isShuttingDown = false;\n\tconst shutdown = async (signal: \"SIGINT\" | \"SIGTERM\") => {\n\t\tif (isShuttingDown) {\n\t\t\tprocess.exit(130);\n\t\t\treturn;\n\t\t}\n\t\tisShuttingDown = true;\n\t\trunPendingAutoUpdateOnShutdown();\n\t\tconst forceExitTimer = setTimeout(() => {\n\t\t\tconsole.error(`Forced exit after ${signal} timeout.`);\n\t\t\tprocess.exit(130);\n\t\t}, 3000);\n\t\tforceExitTimer.unref();\n\t\ttry {\n\t\t\tawait runtime.shutdown();\n\t\t\tclearTimeout(forceExitTimer);\n\t\t\tprocess.exit(130);\n\t\t} catch (error) {\n\t\t\tclearTimeout(forceExitTimer);\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tconsole.error(`Shutdown failed: ${message}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t};\n\tprocess.on(\"SIGINT\", () => {\n\t\tvoid shutdown(\"SIGINT\");\n\t});\n\tprocess.on(\"SIGTERM\", () => {\n\t\tvoid shutdown(\"SIGTERM\");\n\t});\n}\n\nfunction createProgram(): Command {\n\tconst program = new Command();\n\tprogram\n\t\t.name(\"kanban\")\n\t\t.description(\"Local orchestration board for coding agents.\")\n\t\t.version(KANBAN_VERSION, \"-v, --version\", \"Output the version number\")\n\t\t.option(\"--agent <id>\", `Default agent ID (${CLI_AGENT_IDS.join(\", \")}).`, parseCliAgentId)\n\t\t.option(\"--port <number|auto>\", \"Runtime port (1-65535) or auto.\", parseCliPortValue)\n\t\t.option(\"--no-open\", \"Do not open browser automatically.\")\n\t\t.showHelpAfterError()\n\t\t.addHelpText(\"after\", `\\nRuntime URL: ${getKanbanRuntimeOrigin()}\\nAgent IDs: ${CLI_AGENT_IDS.join(\", \")}`);\n\n\tregisterTaskCommand(program);\n\tregisterHooksCommand(program);\n\n\tprogram\n\t\t.command(\"mcp\")\n\t\t.description(\"Deprecated compatibility command.\")\n\t\t.action(() => {\n\t\t\tconsole.warn(\"Deprecated. Please uninstall Kanban MCP.\");\n\t\t});\n\n\tprogram.action(async (options: RootCommandOptions) => {\n\t\tawait runMainCommand({\n\t\t\tagent: options.agent ?? null,\n\t\t\tport: options.port ?? null,\n\t\t\tnoOpen: options.open === false,\n\t\t});\n\t});\n\n\treturn program;\n}\n\nasync function run(): Promise<void> {\n\tconst argv = process.argv.slice(2);\n\tconst program = createProgram();\n\tawait program.parseAsync(argv, { from: \"user\" });\n}\n\nrun().catch((error) => {\n\tconst message = error instanceof Error ? error.message : String(error);\n\tconsole.error(`Failed to start Kanban: ${message}`);\n\tprocess.exit(1);\n});\n"]}
@@ -1,4 +1,3 @@
1
- export declare function isHooksSubcommand(argv: string[]): boolean;
2
- export declare function runHooksIngest(argv: string[]): Promise<void>;
3
- export declare function runHooksSubcommand(argv: string[]): Promise<void>;
1
+ import type { Command } from "commander";
2
+ export declare function registerHooksCommand(program: Command): void;
4
3
  //# sourceMappingURL=hooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/commands/hooks.ts"],"names":[],"mappings":"AAskCA,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAEzD;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBlE;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBtE"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/commands/hooks.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8gCzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6D3D"}