@takemo101/mikan 0.0.3 → 0.0.5

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 (3) hide show
  1. package/README.md +8 -3
  2. package/dist/bin.js +944 -164
  3. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -23139,8 +23139,8 @@ var __create2, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __getProtoOf2,
23139
23139
  if (queuedMessage.type === "response")
23140
23140
  resolver(message);
23141
23141
  else {
23142
- const errorMessage = message;
23143
- resolver(new ProtocolError(errorMessage.error.code, errorMessage.error.message, errorMessage.error.data));
23142
+ const errorMessage2 = message;
23143
+ resolver(new ProtocolError(errorMessage2.error.code, errorMessage2.error.message, errorMessage2.error.data));
23144
23144
  }
23145
23145
  } else {
23146
23146
  const messageType = queuedMessage.type === "response" ? "Response" : "Error";
@@ -32224,11 +32224,11 @@ var COMPLETABLE_SYMBOL, InMemoryTaskStore = class {
32224
32224
  });
32225
32225
  this._toolHandlersInitialized = true;
32226
32226
  }
32227
- createToolError(errorMessage) {
32227
+ createToolError(errorMessage2) {
32228
32228
  return {
32229
32229
  content: [{
32230
32230
  type: "text",
32231
- text: errorMessage
32231
+ text: errorMessage2
32232
32232
  }],
32233
32233
  isError: true
32234
32234
  };
@@ -33319,23 +33319,23 @@ var init_dist = __esm(() => {
33319
33319
  const wrappedHandler = async (request, ctx) => {
33320
33320
  const validatedRequest = parseSchema(CallToolRequestSchema, request);
33321
33321
  if (!validatedRequest.success) {
33322
- const errorMessage = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
33323
- throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid tools/call request: ${errorMessage}`);
33322
+ const errorMessage2 = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
33323
+ throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid tools/call request: ${errorMessage2}`);
33324
33324
  }
33325
33325
  const { params } = validatedRequest.data;
33326
33326
  const result = await Promise.resolve(handler(request, ctx));
33327
33327
  if (params.task) {
33328
33328
  const taskValidationResult = parseSchema(CreateTaskResultSchema, result);
33329
33329
  if (!taskValidationResult.success) {
33330
- const errorMessage = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
33331
- throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage}`);
33330
+ const errorMessage2 = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
33331
+ throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage2}`);
33332
33332
  }
33333
33333
  return taskValidationResult.data;
33334
33334
  }
33335
33335
  const validationResult = parseSchema(CallToolResultSchema, result);
33336
33336
  if (!validationResult.success) {
33337
- const errorMessage = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
33338
- throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid tools/call result: ${errorMessage}`);
33337
+ const errorMessage2 = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
33338
+ throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid tools/call result: ${errorMessage2}`);
33339
33339
  }
33340
33340
  return validationResult.data;
33341
33341
  };
@@ -33568,7 +33568,7 @@ var init_dist = __esm(() => {
33568
33568
  } };
33569
33569
  });
33570
33570
 
33571
- // ../../node_modules/.bun/react@19.2.6/node_modules/react/cjs/react.development.js
33571
+ // ../../node_modules/.bun/react@19.2.7/node_modules/react/cjs/react.development.js
33572
33572
  var require_react_development = __commonJS((exports, module) => {
33573
33573
  (function() {
33574
33574
  function defineDeprecationWarning(methodName, info) {
@@ -34386,12 +34386,12 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
34386
34386
  exports.useTransition = function() {
34387
34387
  return resolveDispatcher().useTransition();
34388
34388
  };
34389
- exports.version = "19.2.6";
34389
+ exports.version = "19.2.7";
34390
34390
  typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === "function" && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
34391
34391
  })();
34392
34392
  });
34393
34393
 
34394
- // ../../node_modules/.bun/react@19.2.6/node_modules/react/index.js
34394
+ // ../../node_modules/.bun/react@19.2.7/node_modules/react/index.js
34395
34395
  var require_react = __commonJS((exports, module) => {
34396
34396
  var react_development = __toESM(require_react_development());
34397
34397
  if (false) {} else {
@@ -34399,62 +34399,62 @@ var require_react = __commonJS((exports, module) => {
34399
34399
  }
34400
34400
  });
34401
34401
 
34402
- // ../../node_modules/.bun/@opentui+core@0.3.0+64015adf11caec84/node_modules/@opentui/core/assets/javascript/highlights.scm
34402
+ // ../../node_modules/.bun/@opentui+core@0.3.1+64015adf11caec84/node_modules/@opentui/core/assets/javascript/highlights.scm
34403
34403
  var require_highlights = __commonJS((exports, module) => {
34404
34404
  module.exports = "./highlights-ghv9g403.scm";
34405
34405
  });
34406
34406
 
34407
- // ../../node_modules/.bun/@opentui+core@0.3.0+64015adf11caec84/node_modules/@opentui/core/assets/javascript/tree-sitter-javascript.wasm
34407
+ // ../../node_modules/.bun/@opentui+core@0.3.1+64015adf11caec84/node_modules/@opentui/core/assets/javascript/tree-sitter-javascript.wasm
34408
34408
  var require_tree_sitter_javascript = __commonJS((exports, module) => {
34409
34409
  module.exports = "./tree-sitter-javascript-nd0q4pe9.wasm";
34410
34410
  });
34411
34411
 
34412
- // ../../node_modules/.bun/@opentui+core@0.3.0+64015adf11caec84/node_modules/@opentui/core/assets/typescript/highlights.scm
34412
+ // ../../node_modules/.bun/@opentui+core@0.3.1+64015adf11caec84/node_modules/@opentui/core/assets/typescript/highlights.scm
34413
34413
  var require_highlights2 = __commonJS((exports, module) => {
34414
34414
  module.exports = "./highlights-eq9cgrbb.scm";
34415
34415
  });
34416
34416
 
34417
- // ../../node_modules/.bun/@opentui+core@0.3.0+64015adf11caec84/node_modules/@opentui/core/assets/typescript/tree-sitter-typescript.wasm
34417
+ // ../../node_modules/.bun/@opentui+core@0.3.1+64015adf11caec84/node_modules/@opentui/core/assets/typescript/tree-sitter-typescript.wasm
34418
34418
  var require_tree_sitter_typescript = __commonJS((exports, module) => {
34419
34419
  module.exports = "./tree-sitter-typescript-zxjzwt75.wasm";
34420
34420
  });
34421
34421
 
34422
- // ../../node_modules/.bun/@opentui+core@0.3.0+64015adf11caec84/node_modules/@opentui/core/assets/markdown/highlights.scm
34422
+ // ../../node_modules/.bun/@opentui+core@0.3.1+64015adf11caec84/node_modules/@opentui/core/assets/markdown/highlights.scm
34423
34423
  var require_highlights3 = __commonJS((exports, module) => {
34424
34424
  module.exports = "./highlights-r812a2qc.scm";
34425
34425
  });
34426
34426
 
34427
- // ../../node_modules/.bun/@opentui+core@0.3.0+64015adf11caec84/node_modules/@opentui/core/assets/markdown/tree-sitter-markdown.wasm
34427
+ // ../../node_modules/.bun/@opentui+core@0.3.1+64015adf11caec84/node_modules/@opentui/core/assets/markdown/tree-sitter-markdown.wasm
34428
34428
  var require_tree_sitter_markdown = __commonJS((exports, module) => {
34429
34429
  module.exports = "./tree-sitter-markdown-411r6y9b.wasm";
34430
34430
  });
34431
34431
 
34432
- // ../../node_modules/.bun/@opentui+core@0.3.0+64015adf11caec84/node_modules/@opentui/core/assets/markdown/injections.scm
34432
+ // ../../node_modules/.bun/@opentui+core@0.3.1+64015adf11caec84/node_modules/@opentui/core/assets/markdown/injections.scm
34433
34433
  var require_injections = __commonJS((exports, module) => {
34434
34434
  module.exports = "./injections-73j83es3.scm";
34435
34435
  });
34436
34436
 
34437
- // ../../node_modules/.bun/@opentui+core@0.3.0+64015adf11caec84/node_modules/@opentui/core/assets/markdown_inline/highlights.scm
34437
+ // ../../node_modules/.bun/@opentui+core@0.3.1+64015adf11caec84/node_modules/@opentui/core/assets/markdown_inline/highlights.scm
34438
34438
  var require_highlights4 = __commonJS((exports, module) => {
34439
34439
  module.exports = "./highlights-x6tmsnaa.scm";
34440
34440
  });
34441
34441
 
34442
- // ../../node_modules/.bun/@opentui+core@0.3.0+64015adf11caec84/node_modules/@opentui/core/assets/markdown_inline/tree-sitter-markdown_inline.wasm
34442
+ // ../../node_modules/.bun/@opentui+core@0.3.1+64015adf11caec84/node_modules/@opentui/core/assets/markdown_inline/tree-sitter-markdown_inline.wasm
34443
34443
  var require_tree_sitter_markdown_inline = __commonJS((exports, module) => {
34444
34444
  module.exports = "./tree-sitter-markdown_inline-j5349f42.wasm";
34445
34445
  });
34446
34446
 
34447
- // ../../node_modules/.bun/@opentui+core@0.3.0+64015adf11caec84/node_modules/@opentui/core/assets/zig/highlights.scm
34447
+ // ../../node_modules/.bun/@opentui+core@0.3.1+64015adf11caec84/node_modules/@opentui/core/assets/zig/highlights.scm
34448
34448
  var require_highlights5 = __commonJS((exports, module) => {
34449
34449
  module.exports = "./highlights-hk7bwhj4.scm";
34450
34450
  });
34451
34451
 
34452
- // ../../node_modules/.bun/@opentui+core@0.3.0+64015adf11caec84/node_modules/@opentui/core/assets/zig/tree-sitter-zig.wasm
34452
+ // ../../node_modules/.bun/@opentui+core@0.3.1+64015adf11caec84/node_modules/@opentui/core/assets/zig/tree-sitter-zig.wasm
34453
34453
  var require_tree_sitter_zig = __commonJS((exports, module) => {
34454
34454
  module.exports = "./tree-sitter-zig-e78zbjpm.wasm";
34455
34455
  });
34456
34456
 
34457
- // ../../node_modules/.bun/@opentui+core@0.3.0+64015adf11caec84/node_modules/@opentui/core/index-081xws23.js
34457
+ // ../../node_modules/.bun/@opentui+core@0.3.1+64015adf11caec84/node_modules/@opentui/core/index-jx0p1c2f.js
34458
34458
  import { EventEmitter } from "events";
34459
34459
  import { Buffer as Buffer2 } from "buffer";
34460
34460
  import { Buffer as Buffer3 } from "buffer";
@@ -34464,14 +34464,14 @@ import { dirname as dirname7, isAbsolute, resolve as resolve4 } from "path";
34464
34464
  import { fileURLToPath } from "url";
34465
34465
  import { resolve as resolve22, isAbsolute as isAbsolute2, parse as parse7 } from "path";
34466
34466
  import { existsSync as existsSync8 } from "fs";
34467
- import { basename as basename4, join as join9 } from "path";
34467
+ import { basename as basename4, join as join10 } from "path";
34468
34468
  import os4 from "os";
34469
34469
  import path4 from "path";
34470
34470
  import { EventEmitter as EventEmitter3 } from "events";
34471
34471
  import path22 from "path";
34472
34472
  import { createRequire } from "module";
34473
34473
  import { fileURLToPath as fileURLToPath2 } from "url";
34474
- import { existsSync as existsSync22, writeFileSync as writeFileSync5 } from "fs";
34474
+ import { existsSync as existsSync22, writeFileSync as writeFileSync6 } from "fs";
34475
34475
  import { EventEmitter as EventEmitter4 } from "events";
34476
34476
  import { EventEmitter as EventEmitter5 } from "events";
34477
34477
  import util from "util";
@@ -38115,7 +38115,7 @@ function getBunfsRootPath() {
38115
38115
  return process.platform === "win32" ? "B:\\~BUN\\root" : "/$bunfs/root";
38116
38116
  }
38117
38117
  function normalizeBunfsPath(fileName) {
38118
- return join9(getBunfsRootPath(), basename4(fileName));
38118
+ return join10(getBunfsRootPath(), basename4(fileName));
38119
38119
  }
38120
38120
 
38121
38121
  class UnsupportedWorker {
@@ -41732,7 +41732,7 @@ function convertToDebugSymbols(symbols) {
41732
41732
  if (env.OTUI_DEBUG_FFI && globalFFILogPath) {
41733
41733
  const logPath = globalFFILogPath;
41734
41734
  const writeSync = (msg) => {
41735
- writeFileSync5(logPath, msg + `
41735
+ writeFileSync6(logPath, msg + `
41736
41736
  `, { flag: "a" });
41737
41737
  };
41738
41738
  Object.entries(symbols).forEach(([key, value]) => {
@@ -45417,7 +45417,7 @@ var __defProp3, __returnValue2 = (v) => v, __export2 = (target, all2) => {
45417
45417
  }, MouseParser, singletonCacheSymbol, envRegistry, envStore, env, DEFAULT_TIMEOUT_MS = 20, DEFAULT_MAX_PENDING_BYTES, INITIAL_PENDING_CAPACITY = 256, ESC = 27, BEL = 7, BRACKETED_PASTE_START, BRACKETED_PASTE_END, EMPTY_BYTES, KEY_DECODER, DEFAULT_PROTOCOL_CONTEXT, RXVT_DOLLAR_CSI_RE, SYSTEM_CLOCK, TIMERS_MAP, regex2, emoji_regex_default = () => {
45418
45418
  return /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E-\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED8\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])))?))?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3C-\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC2\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF]|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g;
45419
45419
  }, segmenter, defaultIgnorableCodePointRegex, TEXT_ENCODER, bun, sleep, stringWidth2, stripANSI, writeFile, _cachedParsers, WORKER_UNAVAILABLE = "OpenTUI tree-sitter workers are not available for this runtime yet.", Worker, DEFAULT_PARSER_OVERRIDES, isUrl = (path5) => path5.startsWith("http://") || path5.startsWith("https://"), TreeSitterClient, DataPathsManager, extensionToFiletype, basenameToFiletype, SYSTEM_CLOCK2, OSC4_RESPONSE, OSC_SPECIAL_RESPONSE, DEFAULT_FOREGROUND_FALLBACK, DEFAULT_BACKGROUND_FALLBACK, fallbackAnsi256Palette = null, PASTE_TEXT_DECODER, URL_SCOPES, FFIType, FFI_UNAVAILABLE = "OpenTUI native FFI is not available for this runtime yet", BUN_DLOPEN_NULL = "Bun FFI backend does not support dlopen(null)", LIBRARY_CLOSED = "Cannot create FFI callback after library.close() has been called", NODE_CALLBACK_THREADSAFE = "Node FFI callbacks are same-thread only and do not support threadsafe callbacks", NODE_NAPI_UNSUPPORTED = "Node FFI backend does not support Bun N-API FFI types", NODE_POINTER_OVERRIDE = "Node FFI backend does not support FFIFunction.ptr overrides", NODE_PTR_VALUE = "node:ffi ptr() only supports ArrayBuffer and ArrayBufferView values backed by ArrayBuffer", NODE_STRING_RETURN = "Node FFI backend does not normalize string return values (yet)", NODE_USIZE_UNSUPPORTED = "Node FFI backend does not support usize until (yet)", POINTER_NEGATIVE = "Pointer must be non-negative", POINTER_UNSAFE = "Pointer exceeds safe integer range", isBun, requireModule, backend, dlopen, ptr, suffix, toArrayBuffer, FFI_LOAD_ERROR = "bun-ffi-structs requires Bun or Node.js with node:ffi enabled (--experimental-ffi --allow-ffi).", backend2, ptr2, toArrayBuffer2, pointerSize, isBun2, typeSizes, primitiveKeys, typeAlignments, typeGetters, pointerPacker, pointerUnpacker, retainedPointerTargets, encoder, decoder, rgbaPackTransform = (rgba) => rgba ? ptr(rgba.buffer) : null, rgbaUnpackTransform = (ptr3) => ptr3 ? RGBA.fromArray(new Uint16Array(toArrayBuffer(ptr3, 0, 8))) : undefined, StyledChunkStruct, HighlightStruct, LogicalCursorStruct, VisualCursorStruct, UnicodeMethodEnum, TerminalMultiplexerEnum, TerminalCapabilitiesStruct, EncodedCharStruct, LineInfoStruct, MeasureResultStruct, CursorStateStruct, CursorStyleOptionsStruct, GridDrawOptionsStruct, BuildOptionsStruct, AllocatorStatsStruct, NativeRenderStatsStruct, GrowthPolicyEnum, NativeSpanFeedOptionsStruct, NativeSpanFeedStatsStruct, SpanInfoStruct, ReserveInfoStruct, AudioCreateOptionsStruct, AudioStartOptionsStruct, AudioVoiceOptionsStruct, AudioStatsStruct, nativePackage, targetLibPath, CURSOR_STYLE_TO_ID, CURSOR_ID_TO_STYLE, MOUSE_STYLE_TO_ID, globalTraceSymbols = null, globalFFILogPath = null, exitHandlerRegistered = false, LogLevel2, opentuiLibPath, opentuiLib, BrandedRenderable, LayoutEvents, RenderableEvents, BaseRenderable, yogaConfig, Renderable, RootRenderable, BrandedVNode, EditBuffer, BoxRenderable, TextBufferRenderable, CodeRenderable, BrandedTextNodeRenderable, TextNodeRenderable, RootTextNodeRenderable, TextRenderable, Capture, CapturedWritableStream, defaultKeyAliases, capture, TerminalConsoleCache, terminalConsoleCache, ConsolePosition, defaultConsoleKeybindings, DEFAULT_CONSOLE_OPTIONS, INDENT_WIDTH = 2, TerminalConsole, BrandedEditBufferRenderable, EditBufferRenderableEvents, EditBufferRenderable, ANSI, OSC_THEME_RESPONSE, DEFAULT_FOOTER_HEIGHT = 12, MAX_SCROLLBACK_SURFACE_HEIGHT_PASSES = 4, TRANSPARENT_RGBA, scrollbackSurfaceCounter = 0, CHAR_FLAG_CONTINUATION = 3221225472, CHAR_FLAG_MASK = 3221225472, ScrollbackSnapshotRenderContext, DEFAULT_FORWARDED_ENV_KEYS, NATIVE_RENDER_STATUS_SKIPPED = 1, NATIVE_RENDER_STATUS_FAILED = 2, KITTY_FLAG_DISAMBIGUATE = 1, KITTY_FLAG_EVENT_TYPES = 2, KITTY_FLAG_ALTERNATE_KEYS = 4, KITTY_FLAG_ALL_KEYS_AS_ESCAPES = 8, KITTY_FLAG_REPORT_TEXT = 16, DEFAULT_STDIN_PARSER_MAX_BUFFER_BYTES = 67108864, NATIVE_PALETTE_QUERY_SIZE = 16, MouseButton, rendererTracker, CliRenderEvents, RendererControlState, CliRenderer;
45420
- var init_index_081xws23 = __esm(async () => {
45420
+ var init_index_jx0p1c2f = __esm(async () => {
45421
45421
  __defProp3 = Object.defineProperty;
45422
45422
  exports_src = {};
45423
45423
  __export2(exports_src, {
@@ -56204,6 +56204,10 @@ var init_index_081xws23 = __esm(async () => {
56204
56204
  switchToAlternateScreen: "\x1B[?1049h",
56205
56205
  switchToMainScreen: "\x1B[?1049l",
56206
56206
  reset: "\x1B[0m",
56207
+ resetScrollRegion: "\x1B[r",
56208
+ home: "\x1B[H",
56209
+ clearScreen: "\x1B[2J",
56210
+ clearSavedLines: "\x1B[3J",
56207
56211
  scrollDown: (lines) => `\x1B[${lines}T`,
56208
56212
  scrollUp: (lines) => `\x1B[${lines}S`,
56209
56213
  moveCursor: (row, col) => `\x1B[${row};${col}H`,
@@ -57509,6 +57513,26 @@ Captured external output:
57509
57513
  }
57510
57514
  }
57511
57515
  }
57516
+ resetSplitFooterForReplay(options = {}) {
57517
+ if (this._isDestroyed)
57518
+ return;
57519
+ if (this._screenMode !== "split-footer" || this._externalOutputMode !== "capture-stdout") {
57520
+ throw new Error('resetSplitFooterForReplay requires screenMode "split-footer" and externalOutputMode "capture-stdout"');
57521
+ }
57522
+ if (!this._terminalIsSetup || this._controlState === "explicit_suspended") {
57523
+ throw new Error("resetSplitFooterForReplay requires an active terminal");
57524
+ }
57525
+ this.flushPendingSplitOutputBeforeTransition(true);
57526
+ this.externalOutputQueue.clear();
57527
+ this.abortSplitStartupCursorSeed();
57528
+ this.clearPendingSplitFooterTransition();
57529
+ this.resetSplitScrollback();
57530
+ this.currentRenderBuffer.clear(this.backgroundColor);
57531
+ this.nextRenderBuffer.clear(this.backgroundColor);
57532
+ this.forceFullRepaintRequested = true;
57533
+ this.writeOut(ANSI.resetScrollRegion + ANSI.reset + ANSI.home + ANSI.clearScreen + (options.clearSavedLines ? ANSI.clearSavedLines : "") + ANSI.home);
57534
+ this.requestRender();
57535
+ }
57512
57536
  getSnapshotWidth(value, fallback) {
57513
57537
  const rawValue = value ?? fallback;
57514
57538
  if (!Number.isFinite(rawValue)) {
@@ -59400,7 +59424,7 @@ Captured external output:
59400
59424
  };
59401
59425
  });
59402
59426
 
59403
- // ../../node_modules/.bun/@opentui+core@0.3.0+64015adf11caec84/node_modules/@opentui/core/index-sq86yyfz.js
59427
+ // ../../node_modules/.bun/@opentui+core@0.3.1+64015adf11caec84/node_modules/@opentui/core/index-zv319bjp.js
59404
59428
  import { EventEmitter as EventEmitter10 } from "events";
59405
59429
  import { readFile as readFile2 } from "fs/promises";
59406
59430
  function toU82(value) {
@@ -62718,8 +62742,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
62718
62742
  };
62719
62743
  }
62720
62744
  }, _, Dt, Ht, Zt, Gt, Nt, Ft, jt, TRAILING_MARKDOWN_BLOCK_BREAKS_RE, TRAILING_MARKDOWN_BLOCK_NEWLINES_RE, MarkdownRenderable, defaultThumbBackgroundColor, defaultTrackBackgroundColor, SliderRenderable, ScrollBarRenderable, ArrowRenderable, ContentRenderable, SCROLLBOX_PADDING_KEYS, ScrollBoxRenderable, defaultSelectKeybindings, SelectRenderableEvents, SelectRenderable, defaultTabSelectKeybindings, TabSelectRenderableEvents, TabSelectRenderable, TimeToFirstDrawRenderable;
62721
- var init_index_sq86yyfz = __esm(async () => {
62722
- await init_index_081xws23();
62745
+ var init_index_zv319bjp = __esm(async () => {
62746
+ await init_index_jx0p1c2f();
62723
62747
  exports_src2 = {};
62724
62748
  __export2(exports_src2, {
62725
62749
  yellow: () => yellow,
@@ -64863,19 +64887,19 @@ var init_index_sq86yyfz = __esm(async () => {
64863
64887
  super.remove(this.rightSide.id);
64864
64888
  this.rightSideAdded = false;
64865
64889
  }
64866
- const errorMessage = `Error parsing diff: ${this._parseError?.message || "Unknown error"}
64890
+ const errorMessage2 = `Error parsing diff: ${this._parseError?.message || "Unknown error"}
64867
64891
  `;
64868
64892
  if (!this.errorTextRenderable) {
64869
64893
  this.errorTextRenderable = new TextRenderable(this.ctx, {
64870
64894
  id: this.id ? `${this.id}-error-text` : undefined,
64871
- content: errorMessage,
64895
+ content: errorMessage2,
64872
64896
  fg: "#ef4444",
64873
64897
  width: "100%",
64874
64898
  flexShrink: 0
64875
64899
  });
64876
64900
  super.add(this.errorTextRenderable);
64877
64901
  } else {
64878
- this.errorTextRenderable.content = errorMessage;
64902
+ this.errorTextRenderable.content = errorMessage2;
64879
64903
  const errorTextIndex = this.getChildren().indexOf(this.errorTextRenderable);
64880
64904
  if (errorTextIndex === -1) {
64881
64905
  super.add(this.errorTextRenderable);
@@ -70689,7 +70713,7 @@ var init_index_sq86yyfz = __esm(async () => {
70689
70713
  };
70690
70714
  });
70691
70715
 
70692
- // ../../node_modules/.bun/@opentui+core@0.3.0+64015adf11caec84/node_modules/@opentui/core/index.js
70716
+ // ../../node_modules/.bun/@opentui+core@0.3.1+64015adf11caec84/node_modules/@opentui/core/index.js
70693
70717
  var exports_core3 = {};
70694
70718
  __export(exports_core3, {
70695
70719
  yellow: () => yellow,
@@ -70939,15 +70963,15 @@ __export(exports_core3, {
70939
70963
  });
70940
70964
  var init_core3 = __esm(async () => {
70941
70965
  await __promiseAll([
70942
- init_index_sq86yyfz(),
70943
- init_index_081xws23()
70966
+ init_index_zv319bjp(),
70967
+ init_index_jx0p1c2f()
70944
70968
  ]);
70945
70969
  });
70946
70970
 
70947
- // ../../node_modules/.bun/@opentui+react@0.3.0+267ab26c85dbf0e3/node_modules/@opentui/react/chunk-2mx7fq49.js
70971
+ // ../../node_modules/.bun/@opentui+react@0.3.1+fd741abea5a7569f/node_modules/@opentui/react/chunk-2mx7fq49.js
70948
70972
  var init_chunk_2mx7fq49 = () => {};
70949
70973
 
70950
- // ../../node_modules/.bun/react@19.2.6/node_modules/react/cjs/react-jsx-dev-runtime.development.js
70974
+ // ../../node_modules/.bun/react@19.2.7/node_modules/react/cjs/react-jsx-dev-runtime.development.js
70951
70975
  var require_react_jsx_dev_runtime_development = __commonJS((exports) => {
70952
70976
  var React4 = __toESM(require_react());
70953
70977
  (function() {
@@ -71162,7 +71186,7 @@ React keys must be passed directly to JSX without using spread:
71162
71186
  })();
71163
71187
  });
71164
71188
 
71165
- // ../../node_modules/.bun/react@19.2.6/node_modules/react/jsx-dev-runtime.js
71189
+ // ../../node_modules/.bun/react@19.2.7/node_modules/react/jsx-dev-runtime.js
71166
71190
  var require_jsx_dev_runtime = __commonJS((exports, module) => {
71167
71191
  var react_jsx_dev_runtime_development = __toESM(require_react_jsx_dev_runtime_development());
71168
71192
  if (false) {} else {
@@ -71433,7 +71457,7 @@ var require_scheduler = __commonJS((exports, module) => {
71433
71457
  }
71434
71458
  });
71435
71459
 
71436
- // ../../node_modules/.bun/react-reconciler@0.33.0+d86b59289c1a13ae/node_modules/react-reconciler/cjs/react-reconciler.development.js
71460
+ // ../../node_modules/.bun/react-reconciler@0.33.0+e14d3f224186685e/node_modules/react-reconciler/cjs/react-reconciler.development.js
71437
71461
  var require_react_reconciler_development = __commonJS((exports, module) => {
71438
71462
  var React4 = __toESM(require_react());
71439
71463
  var Scheduler = __toESM(require_scheduler());
@@ -81883,19 +81907,19 @@ No matching component was found for:
81883
81907
  }, module.exports.default = module.exports, Object.defineProperty(module.exports, "__esModule", { value: true });
81884
81908
  });
81885
81909
 
81886
- // ../../node_modules/.bun/react-reconciler@0.33.0+d86b59289c1a13ae/node_modules/react-reconciler/index.js
81910
+ // ../../node_modules/.bun/react-reconciler@0.33.0+e14d3f224186685e/node_modules/react-reconciler/index.js
81887
81911
  var require_react_reconciler = __commonJS((exports, module) => {
81888
81912
  if (false) {} else {
81889
81913
  module.exports = require_react_reconciler_development();
81890
81914
  }
81891
81915
  });
81892
81916
 
81893
- // ../../node_modules/.bun/react-reconciler@0.33.0+d86b59289c1a13ae/node_modules/react-reconciler/cjs/react-reconciler-constants.development.js
81917
+ // ../../node_modules/.bun/react-reconciler@0.33.0+e14d3f224186685e/node_modules/react-reconciler/cjs/react-reconciler-constants.development.js
81894
81918
  var require_react_reconciler_constants_development = __commonJS((exports) => {
81895
81919
  exports.ConcurrentRoot = 1, exports.ContinuousEventPriority = 8, exports.DefaultEventPriority = 32, exports.DiscreteEventPriority = 2, exports.IdleEventPriority = 268435456, exports.LegacyRoot = 0, exports.NoEventPriority = 0;
81896
81920
  });
81897
81921
 
81898
- // ../../node_modules/.bun/react-reconciler@0.33.0+d86b59289c1a13ae/node_modules/react-reconciler/constants.js
81922
+ // ../../node_modules/.bun/react-reconciler@0.33.0+e14d3f224186685e/node_modules/react-reconciler/constants.js
81899
81923
  var require_constants = __commonJS((exports, module) => {
81900
81924
  if (false) {} else {
81901
81925
  module.exports = require_react_reconciler_constants_development();
@@ -98696,7 +98720,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
98696
98720
  });
98697
98721
  });
98698
98722
 
98699
- // ../../node_modules/.bun/@opentui+react@0.3.0+267ab26c85dbf0e3/node_modules/@opentui/react/chunk-bdqvmfwv.js
98723
+ // ../../node_modules/.bun/@opentui+react@0.3.1+fd741abea5a7569f/node_modules/@opentui/react/chunk-bdqvmfwv.js
98700
98724
  var exports_chunk_bdqvmfwv = {};
98701
98725
  var import_react_devtools_core, g;
98702
98726
  var init_chunk_bdqvmfwv = __esm(async () => {
@@ -98723,7 +98747,7 @@ var init_chunk_bdqvmfwv = __esm(async () => {
98723
98747
  import_react_devtools_core.default.connectToDevTools();
98724
98748
  });
98725
98749
 
98726
- // ../../node_modules/.bun/@opentui+react@0.3.0+267ab26c85dbf0e3/node_modules/@opentui/react/chunk-w83f8rxy.js
98750
+ // ../../node_modules/.bun/@opentui+react@0.3.1+fd741abea5a7569f/node_modules/@opentui/react/chunk-tn7z7cfz.js
98727
98751
  function extend2(objects) {
98728
98752
  Object.assign(componentCatalogue, objects);
98729
98753
  }
@@ -98869,7 +98893,7 @@ function createRoot(renderer) {
98869
98893
  var import_react4, import_react5, import_react6, import_jsx_dev_runtime, import_react_reconciler, import_constants, import_react7, import_constants2, textNodeKeys, SpanRenderable, TextModifierRenderable, BoldSpanRenderable, ItalicSpanRenderable, UnderlineSpanRenderable, LineBreakRenderable, LinkRenderable, baseComponents, componentCatalogue, AppContext, useAppContext = () => {
98870
98894
  return import_react4.useContext(AppContext);
98871
98895
  }, ErrorBoundary, package_default2, idCounter, currentUpdatePriority, hostConfig, reconciler, _r, flushSync, createPortal;
98872
- var init_chunk_w83f8rxy = __esm(async () => {
98896
+ var init_chunk_tn7z7cfz = __esm(async () => {
98873
98897
  init_chunk_2mx7fq49();
98874
98898
  await __promiseAll([
98875
98899
  init_core3(),
@@ -98990,7 +99014,7 @@ var init_chunk_w83f8rxy = __esm(async () => {
98990
99014
  };
98991
99015
  package_default2 = {
98992
99016
  name: "@opentui/react",
98993
- version: "0.3.0",
99017
+ version: "0.3.1",
98994
99018
  description: "React renderer for building terminal user interfaces using OpenTUI core",
98995
99019
  license: "MIT",
98996
99020
  repository: {
@@ -99249,7 +99273,7 @@ $ bun add react-devtools-core@7 -d
99249
99273
  ({ createPortal } = reconciler);
99250
99274
  });
99251
99275
 
99252
- // ../../node_modules/.bun/@opentui+react@0.3.0+267ab26c85dbf0e3/node_modules/@opentui/react/index.js
99276
+ // ../../node_modules/.bun/@opentui+react@0.3.1+fd741abea5a7569f/node_modules/@opentui/react/index.js
99253
99277
  var exports_react = {};
99254
99278
  __export(exports_react, {
99255
99279
  useTimeline: () => useTimeline,
@@ -99553,7 +99577,7 @@ var import_react8, import_react9, import_react10, import_react11, import_react12
99553
99577
  var init_react = __esm(async () => {
99554
99578
  init_chunk_2mx7fq49();
99555
99579
  await __promiseAll([
99556
- init_chunk_w83f8rxy(),
99580
+ init_chunk_tn7z7cfz(),
99557
99581
  init_core3(),
99558
99582
  init_core3(),
99559
99583
  init_core3()
@@ -99605,7 +99629,7 @@ var init_react = __esm(async () => {
99605
99629
  });
99606
99630
 
99607
99631
  // ../mcp/src/index.ts
99608
- import { readFileSync as readFileSync7 } from "fs";
99632
+ import { readFileSync as readFileSync8 } from "fs";
99609
99633
 
99610
99634
  // ../core/src/board-scan.ts
99611
99635
  import { existsSync, readdirSync, readFileSync, statSync } from "fs";
@@ -99788,13 +99812,15 @@ function invalidFrontmatterResult(message) {
99788
99812
  }
99789
99813
 
99790
99814
  // ../core/src/issue-markdown.ts
99815
+ var githubRepoPattern = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
99791
99816
  var frontmatterSchema = exports_external.object({
99792
99817
  id: exports_external.string().min(1),
99793
99818
  title: exports_external.string().min(1),
99794
99819
  labels: exports_external.array(exports_external.string()).optional().default([]),
99795
99820
  depends_on: exports_external.array(exports_external.string()).optional().default([]),
99796
99821
  created_at: exports_external.string().min(1),
99797
- updated_at: exports_external.string().min(1)
99822
+ updated_at: exports_external.string().min(1),
99823
+ github_issue: exports_external.unknown().optional()
99798
99824
  }).passthrough();
99799
99825
  function parseIssueMarkdown(markdown) {
99800
99826
  const parsed = parseIssueDocument(markdown);
@@ -99859,6 +99885,14 @@ function parseIssueDocument(markdown) {
99859
99885
  updatedAt = parsedUpdatedAt.value;
99860
99886
  else
99861
99887
  errors4.push(`updated_at: ${parsedUpdatedAt.error.message}`);
99888
+ let githubIssue;
99889
+ if (parsedFrontmatter.data.github_issue !== undefined) {
99890
+ const parsedGitHubIssue = parseGitHubIssueReference(parsedFrontmatter.data.github_issue);
99891
+ if (parsedGitHubIssue.ok)
99892
+ githubIssue = parsedGitHubIssue.value;
99893
+ else
99894
+ errors4.push(...parsedGitHubIssue.error);
99895
+ }
99862
99896
  if (errors4.length > 0 || !issueId || !createdAt || !updatedAt) {
99863
99897
  return invalidFrontmatterResult(errors4.join("; "));
99864
99898
  }
@@ -99871,6 +99905,7 @@ function parseIssueDocument(markdown) {
99871
99905
  title: parsedFrontmatter.data.title,
99872
99906
  labels,
99873
99907
  dependencies,
99908
+ ...githubIssue ? { githubIssue } : {},
99874
99909
  createdAt,
99875
99910
  updatedAt,
99876
99911
  body: markdown.slice(frontmatter[0].length)
@@ -99886,6 +99921,48 @@ ${input.body.startsWith(`
99886
99921
  `) ? "" : `
99887
99922
  `}${input.body}`;
99888
99923
  }
99924
+ function parseGitHubIssueReference(input) {
99925
+ const errors4 = [];
99926
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
99927
+ return {
99928
+ ok: false,
99929
+ error: ["github_issue must be an object"]
99930
+ };
99931
+ }
99932
+ const raw = input;
99933
+ const repo = typeof raw.repo === "string" ? raw.repo : "";
99934
+ if (!githubRepoPattern.test(repo)) {
99935
+ errors4.push("github_issue.repo must look like owner/name");
99936
+ }
99937
+ const number4 = raw.number;
99938
+ if (typeof number4 !== "number" || !Number.isInteger(number4) || number4 <= 0) {
99939
+ errors4.push("github_issue.number must be a positive integer");
99940
+ }
99941
+ const url2 = typeof raw.url === "string" ? raw.url : "";
99942
+ try {
99943
+ new URL(url2);
99944
+ } catch {
99945
+ errors4.push("github_issue.url must be a URL");
99946
+ }
99947
+ const lastMirroredAt = typeof raw.last_mirrored_at === "string" ? raw.last_mirrored_at : "";
99948
+ const parsedLastMirroredAt = parseUtcTimestamp(lastMirroredAt);
99949
+ const lastMirroredAtValue = parsedLastMirroredAt.ok ? parsedLastMirroredAt.value : undefined;
99950
+ if (!parsedLastMirroredAt.ok) {
99951
+ errors4.push(`github_issue.last_mirrored_at: ${parsedLastMirroredAt.error.message}`);
99952
+ }
99953
+ if (errors4.length > 0 || !lastMirroredAtValue) {
99954
+ return { ok: false, error: errors4 };
99955
+ }
99956
+ return {
99957
+ ok: true,
99958
+ value: {
99959
+ repo,
99960
+ number: number4,
99961
+ url: url2,
99962
+ lastMirroredAt: lastMirroredAtValue
99963
+ }
99964
+ };
99965
+ }
99889
99966
  function formatZodIssue(issue2) {
99890
99967
  const path = issue2.path.length > 0 ? `${issue2.path.join(".")}: ` : "";
99891
99968
  return `${path}${issue2.message}`;
@@ -100471,15 +100548,234 @@ ${message}`;
100471
100548
  function utcNow(now) {
100472
100549
  return (now?.() ?? new Date).toISOString().replace(/\.\d{3}Z$/, "Z");
100473
100550
  }
100551
+ // ../github/src/index.ts
100552
+ import { mkdtempSync, readFileSync as readFileSync3, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
100553
+ import { tmpdir } from "os";
100554
+ import { join as join4 } from "path";
100555
+ var MIKAN_LABEL_COLOR = "f59e0b";
100556
+ async function mirrorIssueToGitHub(options) {
100557
+ return mirrorOrPush(options, { requireExistingMirror: false });
100558
+ }
100559
+ async function pushGitHubMirror(options) {
100560
+ return mirrorOrPush(options, { requireExistingMirror: true });
100561
+ }
100562
+ var defaultGhApiRunner = async (request) => {
100563
+ const args = ["api", request.endpoint, "--method", request.method];
100564
+ let inputPath;
100565
+ try {
100566
+ if (request.body !== undefined) {
100567
+ const dir = mkdtempSync(join4(tmpdir(), "mikan-gh-api-"));
100568
+ inputPath = join4(dir, "body.json");
100569
+ writeFileSync2(inputPath, JSON.stringify(request.body));
100570
+ args.push("--input", inputPath);
100571
+ }
100572
+ const result = Bun.spawnSync(["gh", ...args], {
100573
+ stdout: "pipe",
100574
+ stderr: "pipe"
100575
+ });
100576
+ const stderr = new TextDecoder().decode(result.stderr).trim();
100577
+ if (result.exitCode !== 0) {
100578
+ throw new Error(stderr || `gh api exited ${result.exitCode}`);
100579
+ }
100580
+ const stdout = new TextDecoder().decode(result.stdout).trim();
100581
+ return stdout ? JSON.parse(stdout) : {};
100582
+ } finally {
100583
+ if (inputPath)
100584
+ rmSync2(inputPath, { force: true });
100585
+ }
100586
+ };
100587
+ async function mirrorOrPush(options, mode) {
100588
+ const repo = options.config.github?.repo;
100589
+ if (!repo) {
100590
+ return fail("missing_config", "Set github.repo in .mikan/config.yaml before using GitHub Mirror.");
100591
+ }
100592
+ const found = findIssueById({
100593
+ projectRoot: options.projectRoot,
100594
+ config: options.config,
100595
+ id: options.id
100596
+ });
100597
+ if (!found.ok)
100598
+ return fail(found.error.kind, found.error.message);
100599
+ if (mode.requireExistingMirror && !found.value.issue.githubIssue) {
100600
+ return fail("missing_config", `Issue has no GitHub Mirror: ${options.id}`);
100601
+ }
100602
+ const runner = options.runner ?? defaultGhApiRunner;
100603
+ try {
100604
+ return await writeMirror({
100605
+ projectRoot: options.projectRoot,
100606
+ config: options.config,
100607
+ issue: found.value,
100608
+ repo,
100609
+ runner,
100610
+ now: options.now
100611
+ });
100612
+ } catch (error51) {
100613
+ return fail("github_error", formatGhFailure(error51));
100614
+ }
100615
+ }
100616
+ async function writeMirror(options) {
100617
+ const warnings = [];
100618
+ const issue2 = options.issue.issue;
100619
+ const repo = issue2.githubIssue?.repo ?? options.repo;
100620
+ const managedLabelNames = new Set(options.config.labels.map((label) => label.id));
100621
+ const labels = await ensureGitHubLabels({
100622
+ repo,
100623
+ config: options.config,
100624
+ issueLabels: issue2.labels.map(String),
100625
+ runner: options.runner,
100626
+ warnings
100627
+ });
100628
+ const title = `[${String(issue2.id)}] ${issue2.title}`;
100629
+ const body = buildGitHubIssueBody(options.issue);
100630
+ let response;
100631
+ let action;
100632
+ if (issue2.githubIssue) {
100633
+ const existing = await options.runner({
100634
+ method: "GET",
100635
+ endpoint: `repos/${repo}/issues/${issue2.githubIssue.number}`
100636
+ });
100637
+ const externalLabels = (existing.labels ?? []).map((label) => String(label.name ?? "")).filter((label) => label && !managedLabelNames.has(label));
100638
+ response = await options.runner({
100639
+ method: "PATCH",
100640
+ endpoint: `repos/${repo}/issues/${issue2.githubIssue.number}`,
100641
+ body: { title, body, labels: [...externalLabels, ...labels] }
100642
+ });
100643
+ action = "updated";
100644
+ } else {
100645
+ response = await options.runner({
100646
+ method: "POST",
100647
+ endpoint: `repos/${repo}/issues`,
100648
+ body: { title, body, labels }
100649
+ });
100650
+ action = "created";
100651
+ }
100652
+ const number4 = numberFromResponse(response, issue2.githubIssue?.number);
100653
+ const url2 = urlFromResponse(response, repo, number4, issue2.githubIssue?.url);
100654
+ writeGitHubIssueFrontmatter(options.issue.path, {
100655
+ repo,
100656
+ number: number4,
100657
+ url: url2,
100658
+ last_mirrored_at: utcNow2(options.now)
100659
+ });
100660
+ return {
100661
+ ok: true,
100662
+ value: {
100663
+ issue_id: String(issue2.id),
100664
+ action,
100665
+ github_issue: { repo, number: number4, url: url2 },
100666
+ warnings
100667
+ }
100668
+ };
100669
+ }
100670
+ async function ensureGitHubLabels(options) {
100671
+ const existingLabels = await options.runner({
100672
+ method: "GET",
100673
+ endpoint: `repos/${options.repo}/labels`
100674
+ });
100675
+ const existingNames = new Set(existingLabels.map((label) => String(label.name ?? "")).filter(Boolean));
100676
+ const labelTitles = new Map(options.config.labels.map((label) => [label.id, label.title]));
100677
+ const configuredIssueLabels = options.issueLabels.filter((label) => labelTitles.has(label));
100678
+ const usableLabels = [];
100679
+ for (const label of configuredIssueLabels) {
100680
+ if (!existingNames.has(label)) {
100681
+ try {
100682
+ await options.runner({
100683
+ method: "POST",
100684
+ endpoint: `repos/${options.repo}/labels`,
100685
+ body: {
100686
+ name: label,
100687
+ color: MIKAN_LABEL_COLOR,
100688
+ description: `Mirrored from mikan label "${labelTitles.get(label) ?? label}" (${label})`
100689
+ }
100690
+ });
100691
+ existingNames.add(label);
100692
+ } catch (error51) {
100693
+ options.warnings.push(`Could not create GitHub label ${label}: ${errorMessage(error51)}`);
100694
+ continue;
100695
+ }
100696
+ }
100697
+ usableLabels.push(label);
100698
+ }
100699
+ return usableLabels;
100700
+ }
100701
+ function buildGitHubIssueBody(issue2) {
100702
+ return [
100703
+ "<!-- mikan:mirror -->",
100704
+ `mikan Issue: ${String(issue2.issue.id)}`,
100705
+ `Status: ${String(issue2.status)}`,
100706
+ `Labels: ${issue2.issue.labels.map(String).join(", ") || "-"}`,
100707
+ "",
100708
+ "---",
100709
+ "",
100710
+ issue2.issue.body.trimEnd(),
100711
+ "",
100712
+ "---",
100713
+ "",
100714
+ "Mirrored from mikan. The mikan Markdown Issue is the source of truth."
100715
+ ].join(`
100716
+ `).trimEnd();
100717
+ }
100718
+ function writeGitHubIssueFrontmatter(path, githubIssue) {
100719
+ const document2 = parseIssueDocument(readFileSync3(path, "utf8"));
100720
+ if (!document2.ok)
100721
+ throw new Error(document2.error.message);
100722
+ const frontmatter = {
100723
+ ...document2.value.frontmatter,
100724
+ github_issue: githubIssue
100725
+ };
100726
+ writeFileSync2(path, serializeIssue({ frontmatter, body: document2.value.issue.body }));
100727
+ }
100728
+ function numberFromResponse(response, fallback) {
100729
+ const number4 = response.number;
100730
+ if (typeof number4 === "number" && Number.isInteger(number4) && number4 > 0) {
100731
+ return number4;
100732
+ }
100733
+ if (fallback)
100734
+ return fallback;
100735
+ throw new Error("GitHub response did not include issue number");
100736
+ }
100737
+ function urlFromResponse(response, repo, number4, fallback) {
100738
+ if (typeof response.html_url === "string" && response.html_url.length > 0) {
100739
+ return response.html_url;
100740
+ }
100741
+ return fallback ?? `https://github.com/${repo}/issues/${number4}`;
100742
+ }
100743
+ function utcNow2(now) {
100744
+ return (now ?? (() => new Date))().toISOString().replace(/\.\d{3}Z$/, "Z");
100745
+ }
100746
+ function formatGhFailure(error51) {
100747
+ return `GitHub Mirror requires the gh CLI. Install gh and run \`gh auth login\`. ${errorMessage(error51)}`;
100748
+ }
100749
+ function errorMessage(error51) {
100750
+ return error51 instanceof Error ? error51.message : String(error51);
100751
+ }
100752
+ function fail(kind, message) {
100753
+ return {
100754
+ ok: false,
100755
+ error: {
100756
+ kind: isGitHubMirrorErrorKind(kind) ? kind : "github_error",
100757
+ message
100758
+ }
100759
+ };
100760
+ }
100761
+ function isGitHubMirrorErrorKind(kind) {
100762
+ return [
100763
+ "missing_config",
100764
+ "not_found",
100765
+ "malformed_issue",
100766
+ "github_error"
100767
+ ].includes(kind);
100768
+ }
100769
+
100474
100770
  // ../project-config/src/index.ts
100475
100771
  import {
100476
100772
  existsSync as existsSync4,
100477
100773
  mkdirSync as mkdirSync3,
100478
- readFileSync as readFileSync3,
100774
+ readFileSync as readFileSync4,
100479
100775
  statSync as statSync2,
100480
- writeFileSync as writeFileSync2
100776
+ writeFileSync as writeFileSync3
100481
100777
  } from "fs";
100482
- import { dirname as dirname3, join as join4 } from "path";
100778
+ import { dirname as dirname3, join as join5 } from "path";
100483
100779
  var DEFAULT_COLUMNS = [
100484
100780
  { id: "backlog", title: "Backlog" },
100485
100781
  { id: "ready", title: "Ready" },
@@ -100493,6 +100789,7 @@ var DEFAULT_LABELS = [
100493
100789
  { id: "herdr", title: "Herdr" }
100494
100790
  ];
100495
100791
  var nonEmptyString = exports_external.string().min(1);
100792
+ var githubRepoSchema = nonEmptyString.regex(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/, "github.repo must look like owner/name");
100496
100793
  var columnSchema = exports_external.object({
100497
100794
  id: nonEmptyString,
100498
100795
  title: nonEmptyString
@@ -100505,6 +100802,10 @@ var hookSchema = exports_external.object({
100505
100802
  on_enter: exports_external.record(exports_external.string(), exports_external.array(exports_external.string())).optional(),
100506
100803
  on_transition: exports_external.record(exports_external.string(), exports_external.array(exports_external.string())).optional()
100507
100804
  });
100805
+ var githubSchema = exports_external.object({
100806
+ repo: githubRepoSchema,
100807
+ auto_push_mirrors: exports_external.boolean().optional().default(false)
100808
+ });
100508
100809
  var projectConfigSchema = exports_external.object({
100509
100810
  project: exports_external.object({
100510
100811
  key: nonEmptyString,
@@ -100514,7 +100815,8 @@ var projectConfigSchema = exports_external.object({
100514
100815
  columns: exports_external.array(columnSchema).min(1)
100515
100816
  }),
100516
100817
  labels: exports_external.array(labelSchema).optional().default([]),
100517
- hooks: hookSchema.optional()
100818
+ hooks: hookSchema.optional(),
100819
+ github: githubSchema.optional()
100518
100820
  }).superRefine((config2, context) => {
100519
100821
  const projectKey = parseProjectKey(config2.project.key);
100520
100822
  if (!projectKey.ok) {
@@ -100566,7 +100868,7 @@ var projectConfigSchema = exports_external.object({
100566
100868
  function findProjectConfig(startDir = process.cwd()) {
100567
100869
  let current = normalizeStartDirectory(startDir);
100568
100870
  while (true) {
100569
- const configPath = join4(current, ".mikan", "config.yaml");
100871
+ const configPath = join5(current, ".mikan", "config.yaml");
100570
100872
  if (existsSync4(configPath)) {
100571
100873
  return { ok: true, value: { projectRoot: current, configPath } };
100572
100874
  }
@@ -100589,7 +100891,7 @@ function loadProjectConfig(startDir = process.cwd()) {
100589
100891
  return found;
100590
100892
  let raw;
100591
100893
  try {
100592
- raw = readFileSync3(found.value.configPath, "utf8");
100894
+ raw = readFileSync4(found.value.configPath, "utf8");
100593
100895
  } catch (error51) {
100594
100896
  return {
100595
100897
  ok: false,
@@ -100633,8 +100935,8 @@ function loadProjectConfig(startDir = process.cwd()) {
100633
100935
  };
100634
100936
  }
100635
100937
  function initProject(projectRoot, options) {
100636
- const mikanRoot = join4(projectRoot, ".mikan");
100637
- const configPath = join4(mikanRoot, "config.yaml");
100938
+ const mikanRoot = join5(projectRoot, ".mikan");
100939
+ const configPath = join5(mikanRoot, "config.yaml");
100638
100940
  const configInput = {
100639
100941
  project: {
100640
100942
  key: options.key,
@@ -100660,12 +100962,12 @@ function initProject(projectRoot, options) {
100660
100962
  try {
100661
100963
  mkdirSync3(mikanRoot, { recursive: true });
100662
100964
  for (const column of DEFAULT_COLUMNS) {
100663
- mkdirSync3(join4(mikanRoot, column.id), { recursive: true });
100965
+ mkdirSync3(join5(mikanRoot, column.id), { recursive: true });
100664
100966
  }
100665
- mkdirSync3(join4(mikanRoot, ".state"), { recursive: true });
100666
- mkdirSync3(join4(mikanRoot, "templates"), { recursive: true });
100667
- writeFileSync2(join4(mikanRoot, "templates", "issue.md"), defaultIssueTemplate());
100668
- writeFileSync2(configPath, $stringify(config2));
100967
+ mkdirSync3(join5(mikanRoot, ".state"), { recursive: true });
100968
+ mkdirSync3(join5(mikanRoot, "templates"), { recursive: true });
100969
+ writeFileSync3(join5(mikanRoot, "templates", "issue.md"), defaultIssueTemplate());
100970
+ writeFileSync3(configPath, $stringify(config2));
100669
100971
  } catch (error51) {
100670
100972
  return {
100671
100973
  ok: false,
@@ -103770,9 +104072,9 @@ function resolveTypeName2(prop) {
103770
104072
 
103771
104073
  // ../../node_modules/.bun/incur@0.4.8/node_modules/incur/dist/SyncMcp.js
103772
104074
  import { execFile } from "child_process";
103773
- import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
104075
+ import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
103774
104076
  import { homedir } from "os";
103775
- import { dirname as dirname4, join as join5 } from "path";
104077
+ import { dirname as dirname4, join as join6 } from "path";
103776
104078
  async function register2(name, options = {}) {
103777
104079
  const runner = detectRunner();
103778
104080
  const command = options.command ?? `${runner} ${detectPackageSpecifier(name)} --mcp`;
@@ -103798,11 +104100,11 @@ async function register2(name, options = {}) {
103798
104100
  return { command, agents };
103799
104101
  }
103800
104102
  function registerAmp(name, command) {
103801
- const configPath = join5(homedir(), ".config", "amp", "settings.json");
104103
+ const configPath = join6(homedir(), ".config", "amp", "settings.json");
103802
104104
  let config2 = {};
103803
104105
  if (existsSync5(configPath)) {
103804
104106
  try {
103805
- config2 = JSON.parse(readFileSync4(configPath, "utf-8"));
104107
+ config2 = JSON.parse(readFileSync5(configPath, "utf-8"));
103806
104108
  } catch {
103807
104109
  return false;
103808
104110
  }
@@ -103816,7 +104118,7 @@ function registerAmp(name, command) {
103816
104118
  const dir = dirname4(configPath);
103817
104119
  if (!existsSync5(dir))
103818
104120
  mkdirSync4(dir, { recursive: true });
103819
- writeFileSync3(configPath, JSON.stringify(config2, null, 2) + `
104121
+ writeFileSync4(configPath, JSON.stringify(config2, null, 2) + `
103820
104122
  `);
103821
104123
  return true;
103822
104124
  }
@@ -103828,7 +104130,7 @@ function detectPackageSpecifier(name) {
103828
104130
  if (!match)
103829
104131
  return name;
103830
104132
  try {
103831
- const pkg = JSON.parse(readFileSync4(join5(match[1], "package.json"), "utf-8"));
104133
+ const pkg = JSON.parse(readFileSync5(join6(match[1], "package.json"), "utf-8"));
103832
104134
  const deps = pkg.dependencies ?? {};
103833
104135
  const spec = deps[name];
103834
104136
  if (!spec || Object.keys(deps).length !== 1)
@@ -106437,13 +106739,13 @@ import {
106437
106739
  chmodSync,
106438
106740
  existsSync as existsSync7,
106439
106741
  mkdirSync as mkdirSync6,
106440
- readFileSync as readFileSync6,
106742
+ readFileSync as readFileSync7,
106441
106743
  renameSync as renameSync3,
106442
106744
  statSync as statSync3,
106443
- writeFileSync as writeFileSync4
106745
+ writeFileSync as writeFileSync5
106444
106746
  } from "fs";
106445
106747
  import { homedir as homedir4 } from "os";
106446
- import { dirname as dirname6, join as join8, resolve as resolve3 } from "path";
106748
+ import { dirname as dirname6, join as join9, resolve as resolve3 } from "path";
106447
106749
  var defaultServerName = "mikan";
106448
106750
  var defaultCommand = "mikan";
106449
106751
  var defaultArgs = ["mcp"];
@@ -106454,7 +106756,7 @@ function workspacePath(options, ...segments) {
106454
106756
  return resolve3(options.cwd ?? process.cwd(), ...segments);
106455
106757
  }
106456
106758
  function homePath(options, ...segments) {
106457
- return join8(options.home ?? homedir4(), ...segments);
106759
+ return join9(options.home ?? homedir4(), ...segments);
106458
106760
  }
106459
106761
  function resolveServerName(options) {
106460
106762
  return options.serverName ?? defaultServerName;
@@ -106485,7 +106787,7 @@ function createInstaller(adapter) {
106485
106787
  function readJsonObject(path4) {
106486
106788
  if (!existsSync7(path4))
106487
106789
  return {};
106488
- const parsed = JSON.parse(readFileSync6(path4, "utf8"));
106790
+ const parsed = JSON.parse(readFileSync7(path4, "utf8"));
106489
106791
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
106490
106792
  return {};
106491
106793
  return parsed;
@@ -106494,7 +106796,7 @@ function writeTextFileAtomic(path4, contents) {
106494
106796
  mkdirSync6(dirname6(path4), { recursive: true });
106495
106797
  const tmpPath = `${path4}.${process.pid}.tmp`;
106496
106798
  const mode = existsSync7(path4) ? statSync3(path4).mode & 511 : 384;
106497
- writeFileSync4(tmpPath, contents, "utf8");
106799
+ writeFileSync5(tmpPath, contents, "utf8");
106498
106800
  chmodSync(tmpPath, mode);
106499
106801
  renameSync3(tmpPath, path4);
106500
106802
  }
@@ -106503,7 +106805,7 @@ function writeJsonObject(path4, config2) {
106503
106805
  `);
106504
106806
  }
106505
106807
  function readTextFile(path4) {
106506
- return existsSync7(path4) ? readFileSync6(path4, "utf8") : "";
106808
+ return existsSync7(path4) ? readFileSync7(path4, "utf8") : "";
106507
106809
  }
106508
106810
  function objectProperty(config2, key) {
106509
106811
  const value = config2[key];
@@ -106706,7 +107008,7 @@ function installMcpServerForAgent(agent, options = {}) {
106706
107008
  // ../mcp/src/skills/shared.ts
106707
107009
  var skillDocument = `---
106708
107010
  name: mikan
106709
- description: mikan is a local-first Issue board for AI-assisted development. Use it to read the board and to create, update, move, and append to Issues through the mikan MCP tools. Trigger when the user wants to see the board, add or change an Issue, move an Issue to another Status, record a Report or Note, or decide what to work on next.
107011
+ description: mikan is a local-first Issue board for AI-assisted development. Use it to read the board; create, update, move, and append to Issues; and explicitly publish GitHub Mirrors through the mikan MCP tools. Trigger when the user wants to see the board, add or change an Issue, move an Issue to another Status, record a Report or Note, publish a GitHub Mirror, or decide what to work on next.
106710
107012
  ---
106711
107013
 
106712
107014
  # mikan
@@ -106723,6 +107025,11 @@ directly:
106723
107025
  - \`update_issue\` \u2014 update an Issue's title, labels, dependencies, or body.
106724
107026
  - \`move_issue\` \u2014 move an Issue to another Status, including \`blocked\` and \`completed\`.
106725
107027
  - \`append_issue\` \u2014 append a Report (with a source) or a Note to an Issue.
107028
+ - \`mirror_issue_to_github\` \u2014 explicit external-publication operation that creates the GitHub Issue mirror when missing or updates it when it already exists.
107029
+
107030
+ GitHub Mirror is one-way: mikan Markdown remains the source of truth, and GitHub
107031
+ Issues are external mirrors only. Do not import GitHub Issues or treat GitHub as
107032
+ authoritative.
106726
107033
 
106727
107034
  ## Statuses
106728
107035
 
@@ -106871,7 +107178,7 @@ function getIssueTool(args, runtime = {}) {
106871
107178
  return coreError(found.error.kind, found.error.message);
106872
107179
  return ok({
106873
107180
  ...formatIssue2(found.value, board.value.warnings),
106874
- markdown: readFileSync7(found.value.path, "utf8")
107181
+ markdown: readFileSync8(found.value.path, "utf8")
106875
107182
  });
106876
107183
  }
106877
107184
  function createIssueTool(args, runtime = {}) {
@@ -106943,6 +107250,21 @@ function appendIssueTool(args, runtime = {}) {
106943
107250
  return coreError(result.error.kind, result.error.message);
106944
107251
  return ok(formatIssue2(result.value, []));
106945
107252
  }
107253
+ async function mirrorIssueToGitHubTool(args, runtime = {}) {
107254
+ const loaded = load(runtime.cwd);
107255
+ if (!loaded.ok)
107256
+ return loaded;
107257
+ const mirrorIssueToGitHub2 = runtime.githubMirror?.mirrorIssueToGitHub ?? mirrorIssueToGitHub;
107258
+ const result = await mirrorIssueToGitHub2({
107259
+ projectRoot: loaded.value.projectRoot,
107260
+ config: loaded.value.config,
107261
+ id: args.id,
107262
+ now: runtime.now
107263
+ });
107264
+ if (!result.ok)
107265
+ return coreError(result.error.kind, result.error.message);
107266
+ return ok(result.value);
107267
+ }
106946
107268
  function createMikanMcpCli(runtime = {}) {
106947
107269
  return exports_Cli.create("mikan", {
106948
107270
  description: "mikan local Issue board MCP server"
@@ -106998,6 +107320,10 @@ function createMikanMcpCli(runtime = {}) {
106998
107320
  source: exports_external.string().optional()
106999
107321
  }),
107000
107322
  run: (context) => forIncur(context, appendIssueTool(context.args, runtime))
107323
+ }).command("mirror_issue_to_github", {
107324
+ description: "Explicit external-publication operation: create or update the GitHub Issue mirror for one local mikan Issue. Markdown remains source of truth.",
107325
+ args: exports_external.object({ id: exports_external.string() }),
107326
+ run: async (context) => forIncur(context, await mirrorIssueToGitHubTool(context.args, runtime))
107001
107327
  });
107002
107328
  }
107003
107329
  async function startMcpServer(runtime = {}) {
@@ -107076,6 +107402,7 @@ var package_default = {
107076
107402
  },
107077
107403
  dependencies: {
107078
107404
  "@mikan/core": "workspace:*",
107405
+ "@mikan/github": "workspace:*",
107079
107406
  "@mikan/project-config": "workspace:*",
107080
107407
  "@opentui/core": "latest",
107081
107408
  "@opentui/react": "latest",
@@ -107119,9 +107446,9 @@ function footerText(mode) {
107119
107446
  return "Modal | enter confirm | esc cancel | ? keys";
107120
107447
  }
107121
107448
  if (mode === "detail") {
107122
- return "Detail | \u2191\u2193 scroll | esc board | ? keys";
107449
+ return "Detail | \u2191\u2193 scroll | g github | esc board | ? keys";
107123
107450
  }
107124
- return "Board | \u2191\u2193 card | \u2190\u2192 column | enter detail | ? keys";
107451
+ return "Board | \u2191\u2193 card | \u2190\u2192 column | enter detail | g github | ? keys";
107125
107452
  }
107126
107453
 
107127
107454
  // ../tui/src/selection.ts
@@ -107206,7 +107533,7 @@ function formatWarningSummary(warnings) {
107206
107533
  }
107207
107534
 
107208
107535
  // ../tui/src/model.ts
107209
- import { readFileSync as readFileSync8 } from "fs";
107536
+ import { readFileSync as readFileSync9 } from "fs";
107210
107537
  function loadTuiModel(cwd = process.cwd()) {
107211
107538
  const loaded = loadProjectConfig(cwd);
107212
107539
  if (!loaded.ok)
@@ -107217,9 +107544,9 @@ function loadTuiModel(cwd = process.cwd()) {
107217
107544
  });
107218
107545
  if (!board.ok)
107219
107546
  throw new Error(board.error.message);
107220
- return buildTuiModel(board.value);
107547
+ return buildTuiModel(board.value, loaded.value.config.labels, loaded.value.config.github?.repo);
107221
107548
  }
107222
- function buildTuiModel(board) {
107549
+ function buildTuiModel(board, labels = [], githubRepo) {
107223
107550
  return {
107224
107551
  columns: board.columns.map((column) => ({
107225
107552
  id: column.id,
@@ -107227,7 +107554,9 @@ function buildTuiModel(board) {
107227
107554
  cards: column.issues.map(formatCard)
107228
107555
  })),
107229
107556
  warnings: board.warnings.map(formatWarning),
107230
- ...board.warnings.length > 0 ? { warningDetails: board.warnings.map(formatTuiWarning) } : {}
107557
+ ...board.warnings.length > 0 ? { warningDetails: board.warnings.map(formatTuiWarning) } : {},
107558
+ labelTitles: Object.fromEntries(labels.map((label) => [label.id, label.title])),
107559
+ githubRepo
107231
107560
  };
107232
107561
  }
107233
107562
  function formatWarning(warning) {
@@ -107246,7 +107575,7 @@ function getSelectedDetails(model, selection) {
107246
107575
  const card = model.columns[selection.columnIndex]?.cards[selection.cardIndex];
107247
107576
  if (!card)
107248
107577
  return;
107249
- const markdown = readFileSync8(card.path, "utf8");
107578
+ const markdown = readFileSync9(card.path, "utf8");
107250
107579
  return {
107251
107580
  card,
107252
107581
  markdown,
@@ -107275,7 +107604,15 @@ function formatCard(issue2) {
107275
107604
  path: issue2.path,
107276
107605
  dependsOn: issue2.issue.dependencies.map(String),
107277
107606
  unmetDependencies: issue2.unmetDependencies.map(String),
107278
- dependencyStatus: issue2.dependencyStatus
107607
+ dependencyStatus: issue2.dependencyStatus,
107608
+ ...issue2.issue.githubIssue ? {
107609
+ githubIssue: {
107610
+ repo: issue2.issue.githubIssue.repo,
107611
+ number: issue2.issue.githubIssue.number,
107612
+ url: issue2.issue.githubIssue.url,
107613
+ lastMirroredAt: issue2.issue.githubIssue.lastMirroredAt
107614
+ }
107615
+ } : {}
107279
107616
  };
107280
107617
  }
107281
107618
  function stripFrontmatter(markdown) {
@@ -107451,11 +107788,12 @@ function buildDetailPageViewModel(model, selection, options = {}) {
107451
107788
  id: details.card.id,
107452
107789
  title: details.card.title,
107453
107790
  status: details.card.status,
107454
- labelsText: details.card.labels.join(", "),
107791
+ labelsText: formatDetailLabels(model, details.card),
107455
107792
  dependsOnText: cardDependsOn(details.card).join(", "),
107456
107793
  unmetDependenciesText: cardUnmetDependencies(details.card).join(", "),
107457
107794
  dependencyStatus: cardDependencyStatus(details.card),
107458
107795
  warningCount: warningCountForCard(model.warningDetails, details.card),
107796
+ githubText: details.card.githubIssue ? `GitHub #${details.card.githubIssue.number}` : "",
107459
107797
  markdown,
107460
107798
  visibleMarkdownLines,
107461
107799
  hiddenLinesBefore: offset,
@@ -107469,13 +107807,18 @@ function buildDetailPageViewModel(model, selection, options = {}) {
107469
107807
  })
107470
107808
  };
107471
107809
  }
107810
+ function formatDetailLabels(model, card) {
107811
+ return card.labels.map((label) => model.labelTitles?.[label] ?? label).join(", ");
107812
+ }
107472
107813
  function warningCountForCard(warnings, card) {
107473
107814
  return (warnings ?? []).filter((warning) => warning.issueId === card.id || warning.path === card.path).length;
107474
107815
  }
107475
107816
 
107476
107817
  // ../tui/src/detail-view.ts
107477
107818
  function detailLabelsText(page) {
107478
- return page.labelsText ? formatLabels(page.labelsText.split(", ").filter(Boolean)) : "none";
107819
+ if (!page.labelsText)
107820
+ return "none";
107821
+ return page.labelsText.split(", ").filter(Boolean).map((label) => `#${label}`).join(" ");
107479
107822
  }
107480
107823
  function detailDependencyText(page) {
107481
107824
  if (page.unmetDependenciesText)
@@ -107512,6 +107855,9 @@ function detailMetaContent(page, theme) {
107512
107855
  const dependency = detailDependencyText(page);
107513
107856
  if (dependency)
107514
107857
  chunks.push(fg(theme.feedback.warning)(` \xB7 ${dependency}`));
107858
+ if (page.githubText) {
107859
+ chunks.push(fg(theme.base.muted)(` \xB7 ${page.githubText}`));
107860
+ }
107515
107861
  if (page.warningCount > 0) {
107516
107862
  chunks.push(fg(theme.feedback.warning)(` \xB7 warnings ${page.warningCount}`));
107517
107863
  }
@@ -107601,6 +107947,9 @@ function moveSelection(model, selection, direction, options = {}) {
107601
107947
  if (selection.archiveOpen) {
107602
107948
  return { ...selection, archiveOpen: false };
107603
107949
  }
107950
+ if (selection.githubConfirmOpen) {
107951
+ return { ...selection, githubConfirmOpen: false };
107952
+ }
107604
107953
  if (selection.warningsOpen) {
107605
107954
  return { ...selection, warningsOpen: false };
107606
107955
  }
@@ -107635,7 +107984,17 @@ function moveSelection(model, selection, direction, options = {}) {
107635
107984
  ...selection,
107636
107985
  archiveOpen: true,
107637
107986
  moveOpen: false,
107638
- noteOpen: false
107987
+ noteOpen: false,
107988
+ githubConfirmOpen: false
107989
+ };
107990
+ }
107991
+ if (direction === "github") {
107992
+ return {
107993
+ ...selection,
107994
+ archiveOpen: false,
107995
+ moveOpen: false,
107996
+ noteOpen: false,
107997
+ githubConfirmOpen: true
107639
107998
  };
107640
107999
  }
107641
108000
  if (direction === "warnings") {
@@ -107649,6 +108008,14 @@ function moveSelection(model, selection, direction, options = {}) {
107649
108008
  const cardIndex = clamp(direction === "up" ? selection.cardIndex - 1 : direction === "down" ? selection.cardIndex + 1 : Math.min(selection.cardIndex, maxCardIndex), 0, maxCardIndex);
107650
108009
  return { ...selection, columnIndex, cardIndex };
107651
108010
  }
108011
+ function beginGitHubMirrorSubmission(selection) {
108012
+ return {
108013
+ ...selection,
108014
+ githubConfirmOpen: false,
108015
+ githubBusy: true,
108016
+ message: "GitHub mirror running..."
108017
+ };
108018
+ }
107652
108019
  function getMoveTargets(model, selection) {
107653
108020
  const currentStatus = model.columns[selection.columnIndex]?.id;
107654
108021
  return model.columns.filter((column) => column.id !== currentStatus).map((column) => ({ id: column.id, title: column.title }));
@@ -107674,7 +108041,7 @@ function applyNoteInput(selection, keyName2, shift = false) {
107674
108041
  return { ...selection, noteDraft: `${selection.noteDraft ?? ""}${value}` };
107675
108042
  }
107676
108043
  function footerMode(selection) {
107677
- if (selection.moveOpen || selection.noteOpen || selection.archiveOpen) {
108044
+ if (selection.moveOpen || selection.noteOpen || selection.archiveOpen || selection.githubConfirmOpen) {
107678
108045
  return "modal";
107679
108046
  }
107680
108047
  return selection.detailOpen ? "detail" : "board";
@@ -107714,6 +108081,8 @@ function keyToTuiAction(keyName2, shift = false) {
107714
108081
  return "append-note";
107715
108082
  case "a":
107716
108083
  return "archive";
108084
+ case "g":
108085
+ return "github";
107717
108086
  case "w":
107718
108087
  return "warnings";
107719
108088
  case "?":
@@ -107772,6 +108141,19 @@ Move to archived. It will disappear from the default board.`,
107772
108141
  hint: "enter archive esc cancel"
107773
108142
  };
107774
108143
  }
108144
+ function buildGitHubMirrorPromptViewModel(model, selection) {
108145
+ const card = model.columns[selection.columnIndex]?.cards[selection.cardIndex];
108146
+ if (!card)
108147
+ return;
108148
+ return {
108149
+ title: `Create GitHub Mirror for ${card.id}?`,
108150
+ focused: Boolean(selection.githubConfirmOpen),
108151
+ body: `${card.title}
108152
+ Repo: ${model.githubRepo ?? "(not configured)"}
108153
+ Local Markdown remains the source of truth.`,
108154
+ hint: "enter create esc cancel"
108155
+ };
108156
+ }
107775
108157
 
107776
108158
  // ../tui/src/modals.ts
107777
108159
  function MovePrompt(props) {
@@ -107819,6 +108201,21 @@ function ArchivePrompt(props) {
107819
108201
  `)
107820
108202
  })));
107821
108203
  }
108204
+ function GitHubMirrorPrompt(props) {
108205
+ const theme = props.theme ?? buildTuiTheme();
108206
+ return import_react3.default.createElement("box", {
108207
+ id: "github-mirror-modal-backdrop",
108208
+ style: modalBackdropStyle(theme)
108209
+ }, import_react3.default.createElement("box", {
108210
+ id: "github-mirror-prompt",
108211
+ title: "GitHub Mirror",
108212
+ border: true,
108213
+ style: modalStyle(theme)
108214
+ }, import_react3.default.createElement("text", {
108215
+ content: renderGitHubMirrorInteraction(props.model, props.selection).join(`
108216
+ `)
108217
+ })));
108218
+ }
107822
108219
  function modalBackdropStyle(_theme) {
107823
108220
  return {
107824
108221
  alignItems: "center",
@@ -107897,6 +108294,12 @@ function renderArchiveInteraction(model, selection) {
107897
108294
  return ["Archive", "No Issue selected"];
107898
108295
  return [view.title, view.body, view.hint];
107899
108296
  }
108297
+ function renderGitHubMirrorInteraction(model, selection) {
108298
+ const view = buildGitHubMirrorPromptViewModel(model, selection);
108299
+ if (!view)
108300
+ return ["GitHub Mirror", "No Issue selected"];
108301
+ return [view.title, view.body, view.hint];
108302
+ }
107900
108303
  function renderKeyHelp() {
107901
108304
  return [
107902
108305
  "Key help",
@@ -107908,6 +108311,7 @@ function renderKeyHelp() {
107908
108311
  "m move menu",
107909
108312
  "n append Note",
107910
108313
  "a archive Issue",
108314
+ "g GitHub Mirror",
107911
108315
  "w warning details",
107912
108316
  "r reload",
107913
108317
  "q quit"
@@ -107934,6 +108338,8 @@ function refreshTuiModel(options) {
107934
108338
  noteDraft: stillSelected ? options.selection.noteDraft : undefined,
107935
108339
  message: options.selection.message,
107936
108340
  archiveOpen: stillSelected ? options.selection.archiveOpen : false,
108341
+ githubConfirmOpen: stillSelected ? options.selection.githubConfirmOpen : false,
108342
+ githubBusy: stillSelected ? options.selection.githubBusy : false,
107937
108343
  warningsOpen: options.selection.warningsOpen,
107938
108344
  helpOpen: options.selection.helpOpen
107939
108345
  }
@@ -108022,6 +108428,169 @@ function archiveSelectedIssue(options) {
108022
108428
  selection: { ...result.selection, archiveOpen: false }
108023
108429
  } : result;
108024
108430
  }
108431
+ async function beginSelectedIssueGitHubMirror(options) {
108432
+ if (options.selection.githubBusy)
108433
+ return githubAlreadyRunning(options);
108434
+ const card = selectedCard(options.model, options.selection);
108435
+ if (!card) {
108436
+ return {
108437
+ ok: false,
108438
+ model: options.model,
108439
+ selection: { ...options.selection, githubConfirmOpen: false },
108440
+ message: "No Issue selected"
108441
+ };
108442
+ }
108443
+ const loaded = loadProjectConfig(options.cwd ?? process.cwd());
108444
+ if (!loaded.ok) {
108445
+ return {
108446
+ ok: false,
108447
+ model: options.model,
108448
+ selection: { ...options.selection, githubConfirmOpen: false },
108449
+ message: loaded.error.message
108450
+ };
108451
+ }
108452
+ if (!loaded.value.config.github?.repo) {
108453
+ return {
108454
+ ok: false,
108455
+ model: options.model,
108456
+ selection: { ...options.selection, githubConfirmOpen: false },
108457
+ message: "Set github.repo in .mikan/config.yaml"
108458
+ };
108459
+ }
108460
+ if (!card.githubIssue) {
108461
+ return {
108462
+ ok: true,
108463
+ model: options.model,
108464
+ selection: {
108465
+ ...options.selection,
108466
+ githubConfirmOpen: true,
108467
+ archiveOpen: false,
108468
+ moveOpen: false,
108469
+ noteOpen: false
108470
+ },
108471
+ message: ""
108472
+ };
108473
+ }
108474
+ return pushSelectedIssueGitHubMirror({
108475
+ cwd: options.cwd,
108476
+ model: options.model,
108477
+ selection: options.selection,
108478
+ now: options.now,
108479
+ githubMirror: options.githubMirror
108480
+ });
108481
+ }
108482
+ async function confirmSelectedIssueGitHubMirror(options) {
108483
+ if (options.selection.githubBusy)
108484
+ return githubAlreadyRunning(options);
108485
+ const card = selectedCard(options.model, options.selection);
108486
+ if (!card) {
108487
+ return {
108488
+ ok: false,
108489
+ model: options.model,
108490
+ selection: { ...options.selection, githubConfirmOpen: false },
108491
+ message: "No Issue selected"
108492
+ };
108493
+ }
108494
+ const loaded = loadProjectConfig(options.cwd ?? process.cwd());
108495
+ if (!loaded.ok) {
108496
+ return {
108497
+ ok: false,
108498
+ model: options.model,
108499
+ selection: { ...options.selection, githubConfirmOpen: false },
108500
+ message: loaded.error.message
108501
+ };
108502
+ }
108503
+ const mirrorIssueToGitHub2 = options.githubMirror?.mirrorIssueToGitHub ?? mirrorIssueToGitHub;
108504
+ const result = await mirrorIssueToGitHub2({
108505
+ projectRoot: loaded.value.projectRoot,
108506
+ config: loaded.value.config,
108507
+ id: card.id,
108508
+ now: options.now
108509
+ });
108510
+ if (!result.ok) {
108511
+ return {
108512
+ ok: false,
108513
+ model: options.model,
108514
+ selection: { ...options.selection, githubConfirmOpen: false },
108515
+ message: result.error.message
108516
+ };
108517
+ }
108518
+ return refreshAfterGitHubMirror({
108519
+ cwd: options.cwd,
108520
+ model: options.model,
108521
+ selection: options.selection,
108522
+ cardId: card.id,
108523
+ message: `GitHub mirror created #${result.value.github_issue.number}`
108524
+ });
108525
+ }
108526
+ async function pushSelectedIssueGitHubMirror(options) {
108527
+ const card = selectedCard(options.model, options.selection);
108528
+ if (!card) {
108529
+ return {
108530
+ ok: false,
108531
+ model: options.model,
108532
+ selection: { ...options.selection, githubConfirmOpen: false },
108533
+ message: "No Issue selected"
108534
+ };
108535
+ }
108536
+ const loaded = loadProjectConfig(options.cwd ?? process.cwd());
108537
+ if (!loaded.ok) {
108538
+ return {
108539
+ ok: false,
108540
+ model: options.model,
108541
+ selection: { ...options.selection, githubConfirmOpen: false },
108542
+ message: loaded.error.message
108543
+ };
108544
+ }
108545
+ const pushGitHubMirror2 = options.githubMirror?.pushGitHubMirror ?? pushGitHubMirror;
108546
+ const result = await pushGitHubMirror2({
108547
+ projectRoot: loaded.value.projectRoot,
108548
+ config: loaded.value.config,
108549
+ id: card.id,
108550
+ now: options.now
108551
+ });
108552
+ if (!result.ok) {
108553
+ return {
108554
+ ok: false,
108555
+ model: options.model,
108556
+ selection: { ...options.selection, githubConfirmOpen: false },
108557
+ message: result.error.message
108558
+ };
108559
+ }
108560
+ return refreshAfterGitHubMirror({
108561
+ cwd: options.cwd,
108562
+ model: options.model,
108563
+ selection: options.selection,
108564
+ cardId: card.id,
108565
+ message: `GitHub mirror pushed #${result.value.github_issue.number}`
108566
+ });
108567
+ }
108568
+ function refreshAfterGitHubMirror(options) {
108569
+ const model = loadTuiModel(options.cwd);
108570
+ const selection = findSelectionByCardId(model, options.cardId) ?? clampSelection(model, options.selection);
108571
+ return {
108572
+ ok: true,
108573
+ model,
108574
+ selection: {
108575
+ ...selection,
108576
+ detailOpen: options.selection.detailOpen,
108577
+ githubConfirmOpen: false,
108578
+ githubBusy: false
108579
+ },
108580
+ message: options.message
108581
+ };
108582
+ }
108583
+ function selectedCard(model, selection) {
108584
+ return model.columns[selection.columnIndex]?.cards[selection.cardIndex];
108585
+ }
108586
+ function githubAlreadyRunning(options) {
108587
+ return {
108588
+ ok: false,
108589
+ model: options.model,
108590
+ selection: options.selection,
108591
+ message: "GitHub mirror already running"
108592
+ };
108593
+ }
108025
108594
  function appendSelectedIssueNote(options) {
108026
108595
  const body = options.body.trim();
108027
108596
  if (!body) {
@@ -108118,7 +108687,7 @@ function TuiAppView({
108118
108687
  viewportHeight,
108119
108688
  viewportWidth,
108120
108689
  columns
108121
- })), selection.moveOpen ? import_react20.default.createElement(MovePrompt, { model, selection, theme }) : undefined, selection.noteOpen ? import_react20.default.createElement(NotePrompt, { model, selection, theme }) : undefined, selection.archiveOpen ? import_react20.default.createElement(ArchivePrompt, { model, selection, theme }) : undefined, selection.warningsOpen ? import_react20.default.createElement(WarningPanel, { model, theme }) : undefined, selection.helpOpen ? import_react20.default.createElement(HelpPanel, { theme }) : undefined, import_react20.default.createElement(Footer, {
108690
+ })), selection.moveOpen ? import_react20.default.createElement(MovePrompt, { model, selection, theme }) : undefined, selection.noteOpen ? import_react20.default.createElement(NotePrompt, { model, selection, theme }) : undefined, selection.archiveOpen ? import_react20.default.createElement(ArchivePrompt, { model, selection, theme }) : undefined, selection.githubConfirmOpen ? import_react20.default.createElement(GitHubMirrorPrompt, { model, selection, theme }) : undefined, selection.warningsOpen ? import_react20.default.createElement(WarningPanel, { model, theme }) : undefined, selection.helpOpen ? import_react20.default.createElement(HelpPanel, { theme }) : undefined, import_react20.default.createElement(Footer, {
108122
108691
  message: selection.message,
108123
108692
  mode: footerMode(selection),
108124
108693
  theme
@@ -108151,6 +108720,7 @@ async function launchTui(options = {}) {
108151
108720
  });
108152
108721
  const modelRef = import_react20.default.useRef(model);
108153
108722
  const selectionRef = import_react20.default.useRef(selection);
108723
+ const githubBusyRef = import_react20.default.useRef(false);
108154
108724
  modelRef.current = model;
108155
108725
  selectionRef.current = selection;
108156
108726
  import_react20.default.useEffect(() => {
@@ -108219,6 +108789,37 @@ async function launchTui(options = {}) {
108219
108789
  }
108220
108790
  return;
108221
108791
  }
108792
+ if (selection.githubConfirmOpen) {
108793
+ if (action === "help") {
108794
+ setSelection((current) => moveSelection(model, current, action));
108795
+ return;
108796
+ }
108797
+ if (action === "escape") {
108798
+ setSelection((current) => moveSelection(model, current, action));
108799
+ return;
108800
+ }
108801
+ if (action === "enter") {
108802
+ if (githubBusyRef.current)
108803
+ return;
108804
+ githubBusyRef.current = true;
108805
+ setSelection((current) => beginGitHubMirrorSubmission(current));
108806
+ (async () => {
108807
+ try {
108808
+ const result = await confirmSelectedIssueGitHubMirror({
108809
+ cwd: options.cwd,
108810
+ model,
108811
+ selection
108812
+ });
108813
+ setModel(result.model);
108814
+ setSelection({ ...result.selection, message: result.message });
108815
+ } finally {
108816
+ githubBusyRef.current = false;
108817
+ }
108818
+ })();
108819
+ return;
108820
+ }
108821
+ return;
108822
+ }
108222
108823
  if (!action)
108223
108824
  return;
108224
108825
  if (action === "quit") {
@@ -108268,6 +108869,29 @@ async function launchTui(options = {}) {
108268
108869
  setSelection((current) => moveSelection(model, current, action));
108269
108870
  return;
108270
108871
  }
108872
+ if (action === "github") {
108873
+ if (githubBusyRef.current)
108874
+ return;
108875
+ githubBusyRef.current = true;
108876
+ const card = model.columns[selection.columnIndex]?.cards[selection.cardIndex];
108877
+ if (card?.githubIssue) {
108878
+ setSelection((current) => beginGitHubMirrorSubmission(current));
108879
+ }
108880
+ (async () => {
108881
+ try {
108882
+ const result = await beginSelectedIssueGitHubMirror({
108883
+ cwd: options.cwd,
108884
+ model,
108885
+ selection
108886
+ });
108887
+ setModel(result.model);
108888
+ setSelection({ ...result.selection, message: result.message });
108889
+ } finally {
108890
+ githubBusyRef.current = false;
108891
+ }
108892
+ })();
108893
+ return;
108894
+ }
108271
108895
  setSelection((current) => moveSelection(model, current, action, {
108272
108896
  viewportHeight: renderer.height
108273
108897
  }));
@@ -108293,6 +108917,7 @@ var commands = [
108293
108917
  "update",
108294
108918
  "move",
108295
108919
  "append",
108920
+ "github",
108296
108921
  "mcp",
108297
108922
  "skills",
108298
108923
  "tui",
@@ -108325,6 +108950,7 @@ var commandOptions = {
108325
108950
  { name: "body", short: "b", value: true },
108326
108951
  { name: "source", short: "s", value: true }
108327
108952
  ],
108953
+ github: [],
108328
108954
  mcp: [
108329
108955
  { name: "agent", short: "a", value: true },
108330
108956
  { name: "no-global", value: false },
@@ -108335,7 +108961,10 @@ var commandOptions = {
108335
108961
  { name: "no-global", value: false }
108336
108962
  ],
108337
108963
  tui: [{ name: "columns", short: "c", value: true }],
108338
- watch: [{ name: "quiet", short: "q", value: false }]
108964
+ watch: [
108965
+ { name: "quiet", short: "q", value: false },
108966
+ { name: "github-push", value: false }
108967
+ ]
108339
108968
  };
108340
108969
  function parseArgs(args, command) {
108341
108970
  const positionals = [];
@@ -108408,32 +109037,33 @@ function isCommandName(input) {
108408
109037
  function ok2(stdout) {
108409
109038
  return { exitCode: 0, stdout, stderr: "" };
108410
109039
  }
108411
- function fail(stderr) {
109040
+ function fail2(stderr) {
108412
109041
  return { exitCode: 1, stdout: "", stderr: `${stderr}
108413
109042
  ` };
108414
109043
  }
108415
109044
 
108416
109045
  // src/commands.ts
108417
- import { readFileSync as readFileSync10 } from "fs";
108418
- import { basename as basename5, join as join11 } from "path";
109046
+ import { readFileSync as readFileSync11 } from "fs";
109047
+ import { basename as basename5, join as join12 } from "path";
108419
109048
 
108420
109049
  // src/watch.ts
109050
+ import { createHash as createHash2 } from "crypto";
108421
109051
  import {
108422
109052
  appendFileSync,
108423
109053
  existsSync as existsSync9,
108424
109054
  mkdirSync as mkdirSync7,
108425
- readFileSync as readFileSync9,
109055
+ readFileSync as readFileSync10,
108426
109056
  renameSync as renameSync4,
108427
- writeFileSync as writeFileSync6
109057
+ writeFileSync as writeFileSync7
108428
109058
  } from "fs";
108429
- import { dirname as dirname8, join as join10 } from "path";
108430
- function runWatchOnce(options = {}) {
109059
+ import { dirname as dirname8, join as join11 } from "path";
109060
+ async function runWatchOnce(options = {}) {
108431
109061
  const loaded = loadProjectConfig(options.cwd ?? process.cwd());
108432
109062
  if (!loaded.ok)
108433
109063
  throw new Error(loaded.error.message);
108434
109064
  if (isWriteLocked(loaded.value.projectRoot)) {
108435
109065
  emit(options, "skipped: mikan write lock is held");
108436
- return { observed: 0, transitions: 0, skipped: true };
109066
+ return { observed: 0, transitions: 0, githubPushes: 0, skipped: true };
108437
109067
  }
108438
109068
  const snapshotPath = watcherSnapshotPath(loaded.value.projectRoot);
108439
109069
  const previous = readSnapshot(snapshotPath);
@@ -108445,11 +109075,8 @@ function runWatchOnce(options = {}) {
108445
109075
  if (!board.ok)
108446
109076
  throw new Error(board.error.message);
108447
109077
  const issues = board.value.columns.flatMap((column) => column.issues);
108448
- const current = Object.fromEntries(issues.map((issue2) => [
108449
- String(issue2.issue.id),
108450
- { status: String(issue2.status), path: issue2.path }
108451
- ]));
108452
109078
  let transitions = 0;
109079
+ let githubPushes = 0;
108453
109080
  if (previous) {
108454
109081
  for (const issue2 of issues) {
108455
109082
  const id = String(issue2.issue.id);
@@ -108464,24 +109091,73 @@ function runWatchOnce(options = {}) {
108464
109091
  }
108465
109092
  fireHooks(loaded.value, issue2, before.status, String(issue2.status), options);
108466
109093
  }
109094
+ if (shouldPushGitHubMirrors(loaded.value, options)) {
109095
+ githubPushes = await pushChangedGitHubMirrors(loaded.value, issues, previous, options);
109096
+ }
108467
109097
  }
108468
- writeSnapshot(snapshotPath, current);
109098
+ writeSnapshot(snapshotPath, readCurrentSnapshot(loaded.value));
108469
109099
  if (options.logScanSummary !== false) {
108470
109100
  emit(options, `watch observed ${issues.length} issue(s), ${transitions} transition(s)`);
108471
109101
  }
108472
- return { observed: issues.length, transitions, skipped: false };
109102
+ return { observed: issues.length, transitions, githubPushes, skipped: false };
108473
109103
  }
108474
109104
  function watchProject(options = {}) {
108475
109105
  const logger = options.quiet ? undefined : options.logger ?? console.log;
108476
- const watchOptions = { ...options, logger, logScanSummary: false };
109106
+ const errorLogger = options.errorLogger ?? console.error;
109107
+ const watchOptions = {
109108
+ ...options,
109109
+ logger,
109110
+ errorLogger,
109111
+ logScanSummary: false
109112
+ };
108477
109113
  if (!options.quiet) {
108478
109114
  const loaded = loadProjectConfig(options.cwd ?? process.cwd());
108479
109115
  if (!loaded.ok)
108480
109116
  throw new Error(loaded.error.message);
108481
109117
  logger?.(`watch started: ${loaded.value.projectRoot}`);
108482
109118
  }
108483
- runWatchOnce(watchOptions);
108484
- return setInterval(() => runWatchOnce(watchOptions), options.intervalMs ?? 1000);
109119
+ let running = false;
109120
+ const tick = () => {
109121
+ if (running)
109122
+ return;
109123
+ running = true;
109124
+ runWatchOnce(watchOptions).finally(() => {
109125
+ running = false;
109126
+ });
109127
+ };
109128
+ tick();
109129
+ return setInterval(tick, options.intervalMs ?? 1000);
109130
+ }
109131
+ function shouldPushGitHubMirrors(loaded, options) {
109132
+ return options.githubPush === true || loaded.config.github?.auto_push_mirrors === true;
109133
+ }
109134
+ async function pushChangedGitHubMirrors(loaded, issues, previous, options) {
109135
+ const pushGitHubMirror2 = options.githubMirror?.pushGitHubMirror ?? pushGitHubMirror;
109136
+ let pushes = 0;
109137
+ for (const issue2 of issues) {
109138
+ if (!issue2.issue.githubIssue)
109139
+ continue;
109140
+ const id = String(issue2.issue.id);
109141
+ const before = previous[id];
109142
+ if (!before || !hasIssueChanged(issue2, before))
109143
+ continue;
109144
+ const result = await pushGitHubMirror2({
109145
+ projectRoot: loaded.projectRoot,
109146
+ config: loaded.config,
109147
+ id,
109148
+ now: options.now
109149
+ });
109150
+ if (!result.ok) {
109151
+ recordGitHubMirrorPushFailure(loaded.projectRoot, id, result.error.message, options);
109152
+ continue;
109153
+ }
109154
+ pushes++;
109155
+ emit(options, `github mirror pushed: ${id} ${result.value.github_issue.url}`);
109156
+ }
109157
+ return pushes;
109158
+ }
109159
+ function hasIssueChanged(issue2, before) {
109160
+ return before.status !== String(issue2.status) || before.path !== issue2.path || before.contentHash !== issueContentHash(issue2);
108485
109161
  }
108486
109162
  function appendPlaceholderStatusLog(loaded, issue2, fromStatus, now) {
108487
109163
  if (hasMatchingStatusLogEntry(issue2.issue.body, fromStatus, String(issue2.status))) {
@@ -108518,7 +109194,7 @@ function fireHooks(loaded, issue2, fromStatus, toStatus, options) {
108518
109194
  });
108519
109195
  if (result.exitCode !== 0) {
108520
109196
  appendHookFailure(loaded.projectRoot, {
108521
- timestamp: utcNow2(options.now),
109197
+ timestamp: utcNow3(options.now),
108522
109198
  issue_id: String(issue2.issue.id),
108523
109199
  from_status: fromStatus,
108524
109200
  to_status: toStatus,
@@ -108530,6 +109206,16 @@ function fireHooks(loaded, issue2, fromStatus, toStatus, options) {
108530
109206
  }
108531
109207
  }
108532
109208
  }
109209
+ function recordGitHubMirrorPushFailure(projectRoot, issueId, message, options) {
109210
+ appendHookFailure(projectRoot, {
109211
+ timestamp: utcNow3(options.now),
109212
+ issue_id: issueId,
109213
+ command: `github auto-push ${issueId}`,
109214
+ exit_code: 1,
109215
+ error: message
109216
+ });
109217
+ emitError(options, `github mirror push failed: ${issueId} ${message}`);
109218
+ }
108533
109219
  function hasMatchingStatusLogEntry(body, fromStatus, toStatus) {
108534
109220
  const section = extractStatusLog(body);
108535
109221
  if (!section)
@@ -108560,11 +109246,14 @@ function emit(options, line) {
108560
109246
  return;
108561
109247
  options.logger?.(line);
108562
109248
  }
109249
+ function emitError(options, line) {
109250
+ options.errorLogger?.(line);
109251
+ }
108563
109252
  function renderHookCommand(command, values) {
108564
109253
  return command.replace(/{{\s*([a-z_]+)\s*}}/g, (match, key) => values[key] ?? match);
108565
109254
  }
108566
109255
  function appendHookFailure(projectRoot, entry) {
108567
- const path5 = join10(projectRoot, ".mikan", ".state", "hook-log.ndjson");
109256
+ const path5 = join11(projectRoot, ".mikan", ".state", "hook-log.ndjson");
108568
109257
  mkdirSync7(dirname8(path5), { recursive: true });
108569
109258
  appendFileSync(path5, `${JSON.stringify(entry)}
108570
109259
  `);
@@ -108573,21 +109262,41 @@ function readSnapshot(path5) {
108573
109262
  if (!existsSync9(path5))
108574
109263
  return;
108575
109264
  try {
108576
- return JSON.parse(readFileSync9(path5, "utf8"));
109265
+ return JSON.parse(readFileSync10(path5, "utf8"));
108577
109266
  } catch {
108578
109267
  return;
108579
109268
  }
108580
109269
  }
109270
+ function readCurrentSnapshot(loaded) {
109271
+ const board = scanBoard({
109272
+ projectRoot: loaded.projectRoot,
109273
+ config: loaded.config,
109274
+ includeArchived: true
109275
+ });
109276
+ if (!board.ok)
109277
+ throw new Error(board.error.message);
109278
+ return Object.fromEntries(board.value.columns.flatMap((column) => column.issues.map((issue2) => [
109279
+ String(issue2.issue.id),
109280
+ {
109281
+ status: String(issue2.status),
109282
+ path: issue2.path,
109283
+ contentHash: issueContentHash(issue2)
109284
+ }
109285
+ ])));
109286
+ }
108581
109287
  function writeSnapshot(path5, snapshot) {
108582
109288
  mkdirSync7(dirname8(path5), { recursive: true });
108583
109289
  const tmp = `${path5}.${process.pid}.${Date.now()}.tmp`;
108584
- writeFileSync6(tmp, JSON.stringify(snapshot, null, 2));
109290
+ writeFileSync7(tmp, JSON.stringify(snapshot, null, 2));
108585
109291
  renameSync4(tmp, path5);
108586
109292
  }
108587
109293
  function watcherSnapshotPath(projectRoot) {
108588
- return join10(projectRoot, ".mikan", ".state", "watcher-snapshot.json");
109294
+ return join11(projectRoot, ".mikan", ".state", "watcher-snapshot.json");
108589
109295
  }
108590
- function utcNow2(now) {
109296
+ function issueContentHash(issue2) {
109297
+ return createHash2("sha256").update(readFileSync10(issue2.path)).digest("hex");
109298
+ }
109299
+ function utcNow3(now) {
108591
109300
  return (now?.() ?? new Date).toISOString().replace(".000Z", "Z");
108592
109301
  }
108593
109302
 
@@ -108599,7 +109308,7 @@ function runMcp(cwd, parsed, options) {
108599
109308
  }
108600
109309
  const agent = parsed.flags.get("agent")?.at(-1);
108601
109310
  if (!agent)
108602
- return fail("Usage: mikan mcp add --agent <agent>");
109311
+ return fail2("Usage: mikan mcp add --agent <agent>");
108603
109312
  try {
108604
109313
  const result = installMcpServerForAgent(agent, {
108605
109314
  cwd,
@@ -108612,18 +109321,18 @@ function runMcp(cwd, parsed, options) {
108612
109321
  return ok2(`Registered MCP server '${result.serverName}' for ${result.agent}${scope}: ${result.path}
108613
109322
  ${hint}`);
108614
109323
  } catch (error51) {
108615
- return fail(error51 instanceof Error ? error51.message : String(error51));
109324
+ return fail2(error51 instanceof Error ? error51.message : String(error51));
108616
109325
  }
108617
109326
  }
108618
109327
  async function runMcpLlms(cwd, args) {
108619
109328
  const parsed = parseArgs(args, "mcp");
108620
109329
  if (!parsed.ok) {
108621
- return fail(`${parsed.error}
109330
+ return fail2(`${parsed.error}
108622
109331
 
108623
109332
  Run \`mikan help mcp\` for usage.`);
108624
109333
  }
108625
109334
  if (parsed.value.flags.has("agent")) {
108626
- return fail(`incur-backed discovery only prints a manifest; it cannot install for a specific agent.
109335
+ return fail2(`incur-backed discovery only prints a manifest; it cannot install for a specific agent.
108627
109336
  ` + "Use `mikan mcp add --agent <agent>` for native MCP registration.");
108628
109337
  }
108629
109338
  const manifest = await getMcpManifest({ cwd }, { full: parsed.value.flags.has("full") });
@@ -108633,11 +109342,11 @@ Run \`mikan help mcp\` for usage.`);
108633
109342
  }
108634
109343
  function runSkills(cwd, parsed, options) {
108635
109344
  if (parsed.positionals[0] !== "add") {
108636
- return fail("Usage: mikan skills add --agent <agent>");
109345
+ return fail2("Usage: mikan skills add --agent <agent>");
108637
109346
  }
108638
109347
  const agent = parsed.flags.get("agent")?.at(-1);
108639
109348
  if (!agent)
108640
- return fail("Usage: mikan skills add --agent <agent>");
109349
+ return fail2("Usage: mikan skills add --agent <agent>");
108641
109350
  try {
108642
109351
  const result = installSkillForAgent(agent, {
108643
109352
  cwd,
@@ -108647,36 +109356,67 @@ function runSkills(cwd, parsed, options) {
108647
109356
  return ok2(`Installed mikan skill for ${result.agent} (${result.scope}): ${result.path}
108648
109357
  `);
108649
109358
  } catch (error51) {
108650
- return fail(error51 instanceof Error ? error51.message : String(error51));
109359
+ return fail2(error51 instanceof Error ? error51.message : String(error51));
108651
109360
  }
108652
109361
  }
108653
- function runWatch(cwd, parsed) {
109362
+ async function runGithub(cwd, parsed, options) {
109363
+ const subcommand2 = parsed.positionals[0];
109364
+ const id = parsed.positionals[1];
109365
+ const operations = options.githubMirror ?? {
109366
+ mirrorIssueToGitHub
109367
+ };
109368
+ const loaded = loadProjectConfig(cwd);
109369
+ if (!loaded.ok)
109370
+ return fail2(loaded.error.message);
109371
+ if (subcommand2 === "mirror") {
109372
+ if (!id)
109373
+ return fail2("Usage: mikan github mirror <issue-id>");
109374
+ return formatGitHubMirrorCliResult(await operations.mirrorIssueToGitHub({
109375
+ projectRoot: loaded.value.projectRoot,
109376
+ config: loaded.value.config,
109377
+ id,
109378
+ now: options.now
109379
+ }), "mirrored");
109380
+ }
109381
+ return fail2("Usage: mikan github mirror <issue-id>");
109382
+ }
109383
+ async function runWatch(cwd, parsed, options) {
108654
109384
  const lines = [];
108655
- runWatchOnce({
109385
+ const errors4 = [];
109386
+ await runWatchOnce({
108656
109387
  cwd,
108657
109388
  quiet: parsed.flags.has("quiet"),
108658
- logger: (line) => lines.push(line)
109389
+ githubPush: parsed.flags.has("github-push"),
109390
+ githubMirror: options.githubMirror?.pushGitHubMirror ? { pushGitHubMirror: options.githubMirror.pushGitHubMirror } : undefined,
109391
+ logger: (line) => lines.push(line),
109392
+ errorLogger: (line) => errors4.push(line)
108659
109393
  });
108660
- return ok2(lines.length > 0 ? `${lines.join(`
109394
+ return {
109395
+ exitCode: 0,
109396
+ stdout: lines.length > 0 ? `${lines.join(`
108661
109397
  `)}
108662
- ` : "");
109398
+ ` : "",
109399
+ stderr: errors4.length > 0 ? `${errors4.join(`
109400
+ `)}
109401
+ ` : ""
109402
+ };
108663
109403
  }
108664
109404
  function runInit(cwd, parsed) {
108665
109405
  const key = parsed.flags.get("key")?.at(-1) ?? "MIK";
108666
109406
  const name = parsed.flags.get("name")?.at(-1) ?? basename5(cwd);
108667
109407
  const initialized = initProject(cwd, { key, name });
108668
109408
  if (!initialized.ok)
108669
- return fail(initialized.error.message);
108670
- return ok2(`Initialized mikan project at ${join11(cwd, ".mikan")}
109409
+ return fail2(initialized.error.message);
109410
+ return ok2(`Initialized mikan project at ${join12(cwd, ".mikan")}
108671
109411
  `);
108672
109412
  }
108673
109413
  function runAdd(cwd, parsed, options) {
108674
109414
  const title = parsed.positionals[0];
108675
109415
  if (!title)
108676
- return fail("Usage: mikan add <title> [--status status] [--label label] [--depends-on issue-id]");
109416
+ return fail2("Usage: mikan add <title> [--status status] [--label label] [--depends-on issue-id]");
108677
109417
  const loaded = loadProjectConfig(cwd);
108678
109418
  if (!loaded.ok)
108679
- return fail(loaded.error.message);
109419
+ return fail2(loaded.error.message);
108680
109420
  const result = createIssue({
108681
109421
  projectRoot: loaded.value.projectRoot,
108682
109422
  config: loaded.value.config,
@@ -108687,14 +109427,14 @@ function runAdd(cwd, parsed, options) {
108687
109427
  now: options.now
108688
109428
  });
108689
109429
  if (!result.ok)
108690
- return fail(result.error.message);
109430
+ return fail2(result.error.message);
108691
109431
  return ok2(`${String(result.value.issue.id)} ${result.value.issue.title}
108692
109432
  `);
108693
109433
  }
108694
109434
  function runList(cwd, parsed) {
108695
109435
  const loaded = loadProjectConfig(cwd);
108696
109436
  if (!loaded.ok)
108697
- return fail(loaded.error.message);
109437
+ return fail2(loaded.error.message);
108698
109438
  const includeArchived = parsed.flags.has("include-archived");
108699
109439
  const board = scanBoard({
108700
109440
  projectRoot: loaded.value.projectRoot,
@@ -108702,10 +109442,10 @@ function runList(cwd, parsed) {
108702
109442
  includeArchived
108703
109443
  });
108704
109444
  if (!board.ok)
108705
- return fail(board.error.message);
109445
+ return fail2(board.error.message);
108706
109446
  const statusFilter = parsed.flags.get("status")?.at(-1);
108707
109447
  if (statusFilter && !loaded.value.config.board.columns.some((column) => column.id === statusFilter)) {
108708
- return fail(`Unknown Status: ${statusFilter}`);
109448
+ return fail2(`Unknown Status: ${statusFilter}`);
108709
109449
  }
108710
109450
  const columns = statusFilter ? board.value.columns.filter((column) => column.id === statusFilter) : board.value.columns;
108711
109451
  return {
@@ -108717,30 +109457,30 @@ function runList(cwd, parsed) {
108717
109457
  function runShow(cwd, parsed) {
108718
109458
  const id = parsed.positionals[0];
108719
109459
  if (!id)
108720
- return fail("Usage: mikan show <issue-id>");
109460
+ return fail2("Usage: mikan show <issue-id>");
108721
109461
  const loaded = loadProjectConfig(cwd);
108722
109462
  if (!loaded.ok)
108723
- return fail(loaded.error.message);
109463
+ return fail2(loaded.error.message);
108724
109464
  const found = findIssueById({
108725
109465
  projectRoot: loaded.value.projectRoot,
108726
109466
  config: loaded.value.config,
108727
109467
  id
108728
109468
  });
108729
109469
  if (!found.ok)
108730
- return fail(found.error.message);
109470
+ return fail2(found.error.message);
108731
109471
  return {
108732
109472
  exitCode: 0,
108733
- stdout: readFileSync10(found.value.path, "utf8"),
109473
+ stdout: readFileSync11(found.value.path, "utf8"),
108734
109474
  stderr: formatDependencyShowInfo(found.value)
108735
109475
  };
108736
109476
  }
108737
109477
  function runUpdate(cwd, parsed, options) {
108738
109478
  const id = parsed.positionals[0];
108739
109479
  if (!id)
108740
- return fail("Usage: mikan update <issue-id> [--title title] [--label label] [--depends-on issue-id] [--body body]");
109480
+ return fail2("Usage: mikan update <issue-id> [--title title] [--label label] [--depends-on issue-id] [--body body]");
108741
109481
  const loaded = loadProjectConfig(cwd);
108742
109482
  if (!loaded.ok)
108743
- return fail(loaded.error.message);
109483
+ return fail2(loaded.error.message);
108744
109484
  const result = updateIssue({
108745
109485
  projectRoot: loaded.value.projectRoot,
108746
109486
  config: loaded.value.config,
@@ -108752,7 +109492,7 @@ function runUpdate(cwd, parsed, options) {
108752
109492
  now: options.now
108753
109493
  });
108754
109494
  if (!result.ok)
108755
- return fail(result.error.message);
109495
+ return fail2(result.error.message);
108756
109496
  return ok2(`${String(result.value.issue.id)} updated
108757
109497
  `);
108758
109498
  }
@@ -108760,10 +109500,10 @@ function runMove(cwd, parsed, options) {
108760
109500
  const id = parsed.positionals[0];
108761
109501
  const status = parsed.positionals[1];
108762
109502
  if (!id || !status)
108763
- return fail("Usage: mikan move <issue-id> <status> [--log text]");
109503
+ return fail2("Usage: mikan move <issue-id> <status> [--log text]");
108764
109504
  const loaded = loadProjectConfig(cwd);
108765
109505
  if (!loaded.ok)
108766
- return fail(loaded.error.message);
109506
+ return fail2(loaded.error.message);
108767
109507
  const result = moveIssue({
108768
109508
  projectRoot: loaded.value.projectRoot,
108769
109509
  config: loaded.value.config,
@@ -108773,7 +109513,7 @@ function runMove(cwd, parsed, options) {
108773
109513
  now: options.now
108774
109514
  });
108775
109515
  if (!result.ok)
108776
- return fail(result.error.message);
109516
+ return fail2(result.error.message);
108777
109517
  return ok2(`${String(result.value.issue.id)} moved to ${status}
108778
109518
  `);
108779
109519
  }
@@ -108782,10 +109522,10 @@ function runAppend(cwd, parsed, options) {
108782
109522
  const section = parsed.flags.get("section")?.at(-1);
108783
109523
  const body = parsed.flags.get("body")?.at(-1);
108784
109524
  if (!id || !section || !body)
108785
- return fail("Usage: mikan append <issue-id> --section section --body body [--source source]");
109525
+ return fail2("Usage: mikan append <issue-id> --section section --body body [--source source]");
108786
109526
  const loaded = loadProjectConfig(cwd);
108787
109527
  if (!loaded.ok)
108788
- return fail(loaded.error.message);
109528
+ return fail2(loaded.error.message);
108789
109529
  const result = appendIssue({
108790
109530
  projectRoot: loaded.value.projectRoot,
108791
109531
  config: loaded.value.config,
@@ -108796,10 +109536,27 @@ function runAppend(cwd, parsed, options) {
108796
109536
  now: options.now
108797
109537
  });
108798
109538
  if (!result.ok)
108799
- return fail(result.error.message);
109539
+ return fail2(result.error.message);
108800
109540
  return ok2(`${String(result.value.issue.id)} appended ${section}
108801
109541
  `);
108802
109542
  }
109543
+ function formatGitHubMirrorCliResult(result, verb) {
109544
+ if (!result.ok)
109545
+ return fail2(result.error.message);
109546
+ return {
109547
+ exitCode: 0,
109548
+ stdout: `${formatGitHubMirrorSuccess(result.value, verb)}
109549
+ `,
109550
+ stderr: formatGitHubMirrorWarnings(result.value.warnings)
109551
+ };
109552
+ }
109553
+ function formatGitHubMirrorSuccess(result, verb) {
109554
+ return `${result.issue_id} ${verb} to ${result.github_issue.url}`;
109555
+ }
109556
+ function formatGitHubMirrorWarnings(warnings) {
109557
+ return warnings.map((warning) => `warning: ${warning}
109558
+ `).join("");
109559
+ }
108803
109560
  function formatBoard(columns) {
108804
109561
  const lines = [];
108805
109562
  for (const column of columns) {
@@ -108848,7 +109605,7 @@ function formatWarnings(warnings) {
108848
109605
  // src/help.ts
108849
109606
  function commandHelp(topic) {
108850
109607
  if (!isCommandName(topic)) {
108851
- return fail(`Unknown help topic: ${topic}
109608
+ return fail2(`Unknown help topic: ${topic}
108852
109609
 
108853
109610
  Run \`mikan help\` to see available commands.`);
108854
109611
  }
@@ -108868,6 +109625,7 @@ Commands:
108868
109625
  update Update Issue title, labels, or body
108869
109626
  move Move an Issue to another Status
108870
109627
  append Append Markdown to an Issue section
109628
+ github Create or update GitHub Mirrors
108871
109629
  tui Open the read-only board
108872
109630
  watch Run the polling watcher
108873
109631
  mcp Start the stdio MCP server
@@ -108958,6 +109716,20 @@ Options:
108958
109716
  -b, --body <body> Markdown to append
108959
109717
  -s, --source <source> Source name for timestamped entries
108960
109718
  -h, --help Show this help
109719
+ `;
109720
+ case "github":
109721
+ return `Create or update one-way GitHub Mirrors.
109722
+
109723
+ Usage:
109724
+ mikan github mirror <issue-id>
109725
+
109726
+ Options:
109727
+ -h, --help Show this help
109728
+
109729
+ Notes:
109730
+ Configure github.repo in .mikan/config.yaml first.
109731
+ GitHub Mirror uses the gh CLI; install gh and run gh auth login.
109732
+ mirror creates a GitHub Issue when github_issue is absent and updates it when present.
108961
109733
  `;
108962
109734
  case "tui":
108963
109735
  return `Open the read-only board.
@@ -108987,8 +109759,13 @@ Usage:
108987
109759
  mikan watch [options]
108988
109760
 
108989
109761
  Options:
108990
- -q, --quiet Suppress watch log output
109762
+ -q, --quiet Suppress watch log output except GitHub Mirror failures
109763
+ --github-push Push changed Issues that already have github_issue
108991
109764
  -h, --help Show this help
109765
+
109766
+ Notes:
109767
+ GitHub Mirror auto-push also runs when github.auto_push_mirrors is true.
109768
+ It only pushes existing mirrors and never creates GitHub Issues.
108992
109769
  `;
108993
109770
  case "mcp":
108994
109771
  return `Start the stdio MCP server, register it with an agent, or print its manifest.
@@ -109075,7 +109852,7 @@ async function runCli(argv = process.argv.slice(2), options = {}) {
109075
109852
  return topic ? commandHelp(topic) : ok2(helpText());
109076
109853
  }
109077
109854
  if (!isCommandName(command)) {
109078
- return fail(`Unknown command: ${command}
109855
+ return fail2(`Unknown command: ${command}
109079
109856
 
109080
109857
  Run \`mikan help\` to see available commands.`);
109081
109858
  }
@@ -109083,7 +109860,7 @@ Run \`mikan help\` to see available commands.`);
109083
109860
  return commandHelp(command);
109084
109861
  const parsed = parseArgs(argv.slice(1), command);
109085
109862
  if (!parsed.ok) {
109086
- return fail(`${parsed.error}
109863
+ return fail2(`${parsed.error}
109087
109864
 
109088
109865
  Run \`mikan help ${command}\` for usage.`);
109089
109866
  }
@@ -109103,6 +109880,8 @@ Run \`mikan help ${command}\` for usage.`);
109103
109880
  return runMove(cwd, parsed.value, options);
109104
109881
  case "append":
109105
109882
  return runAppend(cwd, parsed.value, options);
109883
+ case "github":
109884
+ return runGithub(cwd, parsed.value, options);
109106
109885
  case "mcp":
109107
109886
  return runMcp(cwd, parsed.value, options);
109108
109887
  case "skills":
@@ -109110,7 +109889,7 @@ Run \`mikan help ${command}\` for usage.`);
109110
109889
  case "tui": {
109111
109890
  const columns = parseTuiColumnsOption(parsed.value.flags.get("columns")?.at(-1));
109112
109891
  if (!columns.ok) {
109113
- return fail(`${columns.error}
109892
+ return fail2(`${columns.error}
109114
109893
 
109115
109894
  Run \`mikan help tui\` for usage.`);
109116
109895
  }
@@ -109118,12 +109897,12 @@ Run \`mikan help tui\` for usage.`);
109118
109897
  `);
109119
109898
  }
109120
109899
  case "watch":
109121
- return runWatch(cwd, parsed.value);
109900
+ return await runWatch(cwd, parsed.value, options);
109122
109901
  default:
109123
109902
  return ok2(helpText());
109124
109903
  }
109125
109904
  } catch (error51) {
109126
- return fail(error51 instanceof Error ? error51.message : String(error51));
109905
+ return fail2(error51 instanceof Error ? error51.message : String(error51));
109127
109906
  }
109128
109907
  }
109129
109908
  async function main(argv = process.argv.slice(2)) {
@@ -109147,19 +109926,19 @@ async function runInteractiveCommand(argv = process.argv.slice(2), options = {})
109147
109926
  if (argv[0] === "tui") {
109148
109927
  const parsed = parseArgs(argv.slice(1), "tui");
109149
109928
  if (!parsed.ok) {
109150
- return fail(`${parsed.error}
109929
+ return fail2(`${parsed.error}
109151
109930
 
109152
109931
  Run \`mikan help tui\` for usage.`);
109153
109932
  }
109154
109933
  const columns = parseTuiColumnsOption(parsed.value.flags.get("columns")?.at(-1));
109155
109934
  if (!columns.ok) {
109156
- return fail(`${columns.error}
109935
+ return fail2(`${columns.error}
109157
109936
 
109158
109937
  Run \`mikan help tui\` for usage.`);
109159
109938
  }
109160
109939
  const loaded = loadProjectConfig(cwd);
109161
109940
  if (!loaded.ok)
109162
- return fail(loaded.error.message);
109941
+ return fail2(loaded.error.message);
109163
109942
  await (options.launchTui ?? ((launchOptions) => launchTui({ cwd, columns: launchOptions.columns })))({
109164
109943
  columns: columns.value
109165
109944
  });
@@ -109168,12 +109947,13 @@ Run \`mikan help tui\` for usage.`);
109168
109947
  if (argv[0] === "watch") {
109169
109948
  const parsed = parseArgs(argv.slice(1), "watch");
109170
109949
  if (!parsed.ok) {
109171
- return fail(`${parsed.error}
109950
+ return fail2(`${parsed.error}
109172
109951
 
109173
109952
  Run \`mikan help watch\` for usage.`);
109174
109953
  }
109175
109954
  const quiet = parsed.value.flags.has("quiet");
109176
- (options.launchWatch ?? (() => watchProject({ cwd, quiet })))();
109955
+ const githubPush = parsed.value.flags.has("github-push");
109956
+ (options.launchWatch ?? (() => watchProject({ cwd, quiet, githubPush })))();
109177
109957
  return ok2("");
109178
109958
  }
109179
109959
  }