@takemo101/mikan 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +8 -3
  2. package/dist/bin.js +999 -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(".000Z", "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 or push a GitHub Mirror, or decide what to work on next.
106710
107012
  ---
106711
107013
 
106712
107014
  # mikan
@@ -106723,6 +107025,12 @@ 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 or updates the GitHub Issue mirror for one local Issue.
107029
+ - \`push_github_mirror\` \u2014 explicit external-publication operation that updates an already-mirrored Issue; it must not create a new GitHub Issue.
107030
+
107031
+ GitHub Mirror is one-way: mikan Markdown remains the source of truth, and GitHub
107032
+ Issues are external mirrors only. Do not import GitHub Issues or treat GitHub as
107033
+ authoritative.
106726
107034
 
106727
107035
  ## Statuses
106728
107036
 
@@ -106871,7 +107179,7 @@ function getIssueTool(args, runtime = {}) {
106871
107179
  return coreError(found.error.kind, found.error.message);
106872
107180
  return ok({
106873
107181
  ...formatIssue2(found.value, board.value.warnings),
106874
- markdown: readFileSync7(found.value.path, "utf8")
107182
+ markdown: readFileSync8(found.value.path, "utf8")
106875
107183
  });
106876
107184
  }
106877
107185
  function createIssueTool(args, runtime = {}) {
@@ -106943,6 +107251,36 @@ function appendIssueTool(args, runtime = {}) {
106943
107251
  return coreError(result.error.kind, result.error.message);
106944
107252
  return ok(formatIssue2(result.value, []));
106945
107253
  }
107254
+ async function mirrorIssueToGitHubTool(args, runtime = {}) {
107255
+ const loaded = load(runtime.cwd);
107256
+ if (!loaded.ok)
107257
+ return loaded;
107258
+ const mirrorIssueToGitHub2 = runtime.githubMirror?.mirrorIssueToGitHub ?? mirrorIssueToGitHub;
107259
+ const result = await mirrorIssueToGitHub2({
107260
+ projectRoot: loaded.value.projectRoot,
107261
+ config: loaded.value.config,
107262
+ id: args.id,
107263
+ now: runtime.now
107264
+ });
107265
+ if (!result.ok)
107266
+ return coreError(result.error.kind, result.error.message);
107267
+ return ok(result.value);
107268
+ }
107269
+ async function pushGitHubMirrorTool(args, runtime = {}) {
107270
+ const loaded = load(runtime.cwd);
107271
+ if (!loaded.ok)
107272
+ return loaded;
107273
+ const pushGitHubMirror2 = runtime.githubMirror?.pushGitHubMirror ?? pushGitHubMirror;
107274
+ const result = await pushGitHubMirror2({
107275
+ projectRoot: loaded.value.projectRoot,
107276
+ config: loaded.value.config,
107277
+ id: args.id,
107278
+ now: runtime.now
107279
+ });
107280
+ if (!result.ok)
107281
+ return coreError(result.error.kind, result.error.message);
107282
+ return ok(result.value);
107283
+ }
106946
107284
  function createMikanMcpCli(runtime = {}) {
106947
107285
  return exports_Cli.create("mikan", {
106948
107286
  description: "mikan local Issue board MCP server"
@@ -106998,6 +107336,14 @@ function createMikanMcpCli(runtime = {}) {
106998
107336
  source: exports_external.string().optional()
106999
107337
  }),
107000
107338
  run: (context) => forIncur(context, appendIssueTool(context.args, runtime))
107339
+ }).command("mirror_issue_to_github", {
107340
+ description: "Explicit external-publication operation: create or update the GitHub Issue mirror for one local mikan Issue. Markdown remains source of truth.",
107341
+ args: exports_external.object({ id: exports_external.string() }),
107342
+ run: async (context) => forIncur(context, await mirrorIssueToGitHubTool(context.args, runtime))
107343
+ }).command("push_github_mirror", {
107344
+ description: "Explicit external-publication operation: push one already-mirrored mikan Issue to its GitHub Issue mirror. Does not create a new GitHub Issue.",
107345
+ args: exports_external.object({ id: exports_external.string() }),
107346
+ run: async (context) => forIncur(context, await pushGitHubMirrorTool(context.args, runtime))
107001
107347
  });
107002
107348
  }
107003
107349
  async function startMcpServer(runtime = {}) {
@@ -107076,6 +107422,7 @@ var package_default = {
107076
107422
  },
107077
107423
  dependencies: {
107078
107424
  "@mikan/core": "workspace:*",
107425
+ "@mikan/github": "workspace:*",
107079
107426
  "@mikan/project-config": "workspace:*",
107080
107427
  "@opentui/core": "latest",
107081
107428
  "@opentui/react": "latest",
@@ -107119,9 +107466,9 @@ function footerText(mode) {
107119
107466
  return "Modal | enter confirm | esc cancel | ? keys";
107120
107467
  }
107121
107468
  if (mode === "detail") {
107122
- return "Detail | \u2191\u2193 scroll | esc board | ? keys";
107469
+ return "Detail | \u2191\u2193 scroll | g github | esc board | ? keys";
107123
107470
  }
107124
- return "Board | \u2191\u2193 card | \u2190\u2192 column | enter detail | ? keys";
107471
+ return "Board | \u2191\u2193 card | \u2190\u2192 column | enter detail | g github | ? keys";
107125
107472
  }
107126
107473
 
107127
107474
  // ../tui/src/selection.ts
@@ -107206,7 +107553,7 @@ function formatWarningSummary(warnings) {
107206
107553
  }
107207
107554
 
107208
107555
  // ../tui/src/model.ts
107209
- import { readFileSync as readFileSync8 } from "fs";
107556
+ import { readFileSync as readFileSync9 } from "fs";
107210
107557
  function loadTuiModel(cwd = process.cwd()) {
107211
107558
  const loaded = loadProjectConfig(cwd);
107212
107559
  if (!loaded.ok)
@@ -107217,9 +107564,9 @@ function loadTuiModel(cwd = process.cwd()) {
107217
107564
  });
107218
107565
  if (!board.ok)
107219
107566
  throw new Error(board.error.message);
107220
- return buildTuiModel(board.value);
107567
+ return buildTuiModel(board.value, loaded.value.config.labels, loaded.value.config.github?.repo);
107221
107568
  }
107222
- function buildTuiModel(board) {
107569
+ function buildTuiModel(board, labels = [], githubRepo) {
107223
107570
  return {
107224
107571
  columns: board.columns.map((column) => ({
107225
107572
  id: column.id,
@@ -107227,7 +107574,9 @@ function buildTuiModel(board) {
107227
107574
  cards: column.issues.map(formatCard)
107228
107575
  })),
107229
107576
  warnings: board.warnings.map(formatWarning),
107230
- ...board.warnings.length > 0 ? { warningDetails: board.warnings.map(formatTuiWarning) } : {}
107577
+ ...board.warnings.length > 0 ? { warningDetails: board.warnings.map(formatTuiWarning) } : {},
107578
+ labelTitles: Object.fromEntries(labels.map((label) => [label.id, label.title])),
107579
+ githubRepo
107231
107580
  };
107232
107581
  }
107233
107582
  function formatWarning(warning) {
@@ -107246,7 +107595,7 @@ function getSelectedDetails(model, selection) {
107246
107595
  const card = model.columns[selection.columnIndex]?.cards[selection.cardIndex];
107247
107596
  if (!card)
107248
107597
  return;
107249
- const markdown = readFileSync8(card.path, "utf8");
107598
+ const markdown = readFileSync9(card.path, "utf8");
107250
107599
  return {
107251
107600
  card,
107252
107601
  markdown,
@@ -107275,7 +107624,15 @@ function formatCard(issue2) {
107275
107624
  path: issue2.path,
107276
107625
  dependsOn: issue2.issue.dependencies.map(String),
107277
107626
  unmetDependencies: issue2.unmetDependencies.map(String),
107278
- dependencyStatus: issue2.dependencyStatus
107627
+ dependencyStatus: issue2.dependencyStatus,
107628
+ ...issue2.issue.githubIssue ? {
107629
+ githubIssue: {
107630
+ repo: issue2.issue.githubIssue.repo,
107631
+ number: issue2.issue.githubIssue.number,
107632
+ url: issue2.issue.githubIssue.url,
107633
+ lastMirroredAt: issue2.issue.githubIssue.lastMirroredAt
107634
+ }
107635
+ } : {}
107279
107636
  };
107280
107637
  }
107281
107638
  function stripFrontmatter(markdown) {
@@ -107451,11 +107808,12 @@ function buildDetailPageViewModel(model, selection, options = {}) {
107451
107808
  id: details.card.id,
107452
107809
  title: details.card.title,
107453
107810
  status: details.card.status,
107454
- labelsText: details.card.labels.join(", "),
107811
+ labelsText: formatDetailLabels(model, details.card),
107455
107812
  dependsOnText: cardDependsOn(details.card).join(", "),
107456
107813
  unmetDependenciesText: cardUnmetDependencies(details.card).join(", "),
107457
107814
  dependencyStatus: cardDependencyStatus(details.card),
107458
107815
  warningCount: warningCountForCard(model.warningDetails, details.card),
107816
+ githubText: details.card.githubIssue ? `GitHub #${details.card.githubIssue.number}` : "",
107459
107817
  markdown,
107460
107818
  visibleMarkdownLines,
107461
107819
  hiddenLinesBefore: offset,
@@ -107469,13 +107827,18 @@ function buildDetailPageViewModel(model, selection, options = {}) {
107469
107827
  })
107470
107828
  };
107471
107829
  }
107830
+ function formatDetailLabels(model, card) {
107831
+ return card.labels.map((label) => model.labelTitles?.[label] ?? label).join(", ");
107832
+ }
107472
107833
  function warningCountForCard(warnings, card) {
107473
107834
  return (warnings ?? []).filter((warning) => warning.issueId === card.id || warning.path === card.path).length;
107474
107835
  }
107475
107836
 
107476
107837
  // ../tui/src/detail-view.ts
107477
107838
  function detailLabelsText(page) {
107478
- return page.labelsText ? formatLabels(page.labelsText.split(", ").filter(Boolean)) : "none";
107839
+ if (!page.labelsText)
107840
+ return "none";
107841
+ return page.labelsText.split(", ").filter(Boolean).map((label) => `#${label}`).join(" ");
107479
107842
  }
107480
107843
  function detailDependencyText(page) {
107481
107844
  if (page.unmetDependenciesText)
@@ -107512,6 +107875,9 @@ function detailMetaContent(page, theme) {
107512
107875
  const dependency = detailDependencyText(page);
107513
107876
  if (dependency)
107514
107877
  chunks.push(fg(theme.feedback.warning)(` \xB7 ${dependency}`));
107878
+ if (page.githubText) {
107879
+ chunks.push(fg(theme.base.muted)(` \xB7 ${page.githubText}`));
107880
+ }
107515
107881
  if (page.warningCount > 0) {
107516
107882
  chunks.push(fg(theme.feedback.warning)(` \xB7 warnings ${page.warningCount}`));
107517
107883
  }
@@ -107601,6 +107967,9 @@ function moveSelection(model, selection, direction, options = {}) {
107601
107967
  if (selection.archiveOpen) {
107602
107968
  return { ...selection, archiveOpen: false };
107603
107969
  }
107970
+ if (selection.githubConfirmOpen) {
107971
+ return { ...selection, githubConfirmOpen: false };
107972
+ }
107604
107973
  if (selection.warningsOpen) {
107605
107974
  return { ...selection, warningsOpen: false };
107606
107975
  }
@@ -107635,7 +108004,17 @@ function moveSelection(model, selection, direction, options = {}) {
107635
108004
  ...selection,
107636
108005
  archiveOpen: true,
107637
108006
  moveOpen: false,
107638
- noteOpen: false
108007
+ noteOpen: false,
108008
+ githubConfirmOpen: false
108009
+ };
108010
+ }
108011
+ if (direction === "github") {
108012
+ return {
108013
+ ...selection,
108014
+ archiveOpen: false,
108015
+ moveOpen: false,
108016
+ noteOpen: false,
108017
+ githubConfirmOpen: true
107639
108018
  };
107640
108019
  }
107641
108020
  if (direction === "warnings") {
@@ -107674,7 +108053,7 @@ function applyNoteInput(selection, keyName2, shift = false) {
107674
108053
  return { ...selection, noteDraft: `${selection.noteDraft ?? ""}${value}` };
107675
108054
  }
107676
108055
  function footerMode(selection) {
107677
- if (selection.moveOpen || selection.noteOpen || selection.archiveOpen) {
108056
+ if (selection.moveOpen || selection.noteOpen || selection.archiveOpen || selection.githubConfirmOpen) {
107678
108057
  return "modal";
107679
108058
  }
107680
108059
  return selection.detailOpen ? "detail" : "board";
@@ -107714,6 +108093,8 @@ function keyToTuiAction(keyName2, shift = false) {
107714
108093
  return "append-note";
107715
108094
  case "a":
107716
108095
  return "archive";
108096
+ case "g":
108097
+ return "github";
107717
108098
  case "w":
107718
108099
  return "warnings";
107719
108100
  case "?":
@@ -107772,6 +108153,19 @@ Move to archived. It will disappear from the default board.`,
107772
108153
  hint: "enter archive esc cancel"
107773
108154
  };
107774
108155
  }
108156
+ function buildGitHubMirrorPromptViewModel(model, selection) {
108157
+ const card = model.columns[selection.columnIndex]?.cards[selection.cardIndex];
108158
+ if (!card)
108159
+ return;
108160
+ return {
108161
+ title: `Create GitHub Mirror for ${card.id}?`,
108162
+ focused: Boolean(selection.githubConfirmOpen),
108163
+ body: `${card.title}
108164
+ Repo: ${model.githubRepo ?? "(not configured)"}
108165
+ Local Markdown remains the source of truth.`,
108166
+ hint: "enter create esc cancel"
108167
+ };
108168
+ }
107775
108169
 
107776
108170
  // ../tui/src/modals.ts
107777
108171
  function MovePrompt(props) {
@@ -107819,6 +108213,21 @@ function ArchivePrompt(props) {
107819
108213
  `)
107820
108214
  })));
107821
108215
  }
108216
+ function GitHubMirrorPrompt(props) {
108217
+ const theme = props.theme ?? buildTuiTheme();
108218
+ return import_react3.default.createElement("box", {
108219
+ id: "github-mirror-modal-backdrop",
108220
+ style: modalBackdropStyle(theme)
108221
+ }, import_react3.default.createElement("box", {
108222
+ id: "github-mirror-prompt",
108223
+ title: "GitHub Mirror",
108224
+ border: true,
108225
+ style: modalStyle(theme)
108226
+ }, import_react3.default.createElement("text", {
108227
+ content: renderGitHubMirrorInteraction(props.model, props.selection).join(`
108228
+ `)
108229
+ })));
108230
+ }
107822
108231
  function modalBackdropStyle(_theme) {
107823
108232
  return {
107824
108233
  alignItems: "center",
@@ -107897,6 +108306,12 @@ function renderArchiveInteraction(model, selection) {
107897
108306
  return ["Archive", "No Issue selected"];
107898
108307
  return [view.title, view.body, view.hint];
107899
108308
  }
108309
+ function renderGitHubMirrorInteraction(model, selection) {
108310
+ const view = buildGitHubMirrorPromptViewModel(model, selection);
108311
+ if (!view)
108312
+ return ["GitHub Mirror", "No Issue selected"];
108313
+ return [view.title, view.body, view.hint];
108314
+ }
107900
108315
  function renderKeyHelp() {
107901
108316
  return [
107902
108317
  "Key help",
@@ -107908,6 +108323,7 @@ function renderKeyHelp() {
107908
108323
  "m move menu",
107909
108324
  "n append Note",
107910
108325
  "a archive Issue",
108326
+ "g GitHub Mirror",
107911
108327
  "w warning details",
107912
108328
  "r reload",
107913
108329
  "q quit"
@@ -107934,6 +108350,8 @@ function refreshTuiModel(options) {
107934
108350
  noteDraft: stillSelected ? options.selection.noteDraft : undefined,
107935
108351
  message: options.selection.message,
107936
108352
  archiveOpen: stillSelected ? options.selection.archiveOpen : false,
108353
+ githubConfirmOpen: stillSelected ? options.selection.githubConfirmOpen : false,
108354
+ githubBusy: stillSelected ? options.selection.githubBusy : false,
107937
108355
  warningsOpen: options.selection.warningsOpen,
107938
108356
  helpOpen: options.selection.helpOpen
107939
108357
  }
@@ -108022,6 +108440,169 @@ function archiveSelectedIssue(options) {
108022
108440
  selection: { ...result.selection, archiveOpen: false }
108023
108441
  } : result;
108024
108442
  }
108443
+ async function beginSelectedIssueGitHubMirror(options) {
108444
+ if (options.selection.githubBusy)
108445
+ return githubAlreadyRunning(options);
108446
+ const card = selectedCard(options.model, options.selection);
108447
+ if (!card) {
108448
+ return {
108449
+ ok: false,
108450
+ model: options.model,
108451
+ selection: { ...options.selection, githubConfirmOpen: false },
108452
+ message: "No Issue selected"
108453
+ };
108454
+ }
108455
+ const loaded = loadProjectConfig(options.cwd ?? process.cwd());
108456
+ if (!loaded.ok) {
108457
+ return {
108458
+ ok: false,
108459
+ model: options.model,
108460
+ selection: { ...options.selection, githubConfirmOpen: false },
108461
+ message: loaded.error.message
108462
+ };
108463
+ }
108464
+ if (!loaded.value.config.github?.repo) {
108465
+ return {
108466
+ ok: false,
108467
+ model: options.model,
108468
+ selection: { ...options.selection, githubConfirmOpen: false },
108469
+ message: "Set github.repo in .mikan/config.yaml"
108470
+ };
108471
+ }
108472
+ if (!card.githubIssue) {
108473
+ return {
108474
+ ok: true,
108475
+ model: options.model,
108476
+ selection: {
108477
+ ...options.selection,
108478
+ githubConfirmOpen: true,
108479
+ archiveOpen: false,
108480
+ moveOpen: false,
108481
+ noteOpen: false
108482
+ },
108483
+ message: ""
108484
+ };
108485
+ }
108486
+ return pushSelectedIssueGitHubMirror({
108487
+ cwd: options.cwd,
108488
+ model: options.model,
108489
+ selection: options.selection,
108490
+ now: options.now,
108491
+ githubMirror: options.githubMirror
108492
+ });
108493
+ }
108494
+ async function confirmSelectedIssueGitHubMirror(options) {
108495
+ if (options.selection.githubBusy)
108496
+ return githubAlreadyRunning(options);
108497
+ const card = selectedCard(options.model, options.selection);
108498
+ if (!card) {
108499
+ return {
108500
+ ok: false,
108501
+ model: options.model,
108502
+ selection: { ...options.selection, githubConfirmOpen: false },
108503
+ message: "No Issue selected"
108504
+ };
108505
+ }
108506
+ const loaded = loadProjectConfig(options.cwd ?? process.cwd());
108507
+ if (!loaded.ok) {
108508
+ return {
108509
+ ok: false,
108510
+ model: options.model,
108511
+ selection: { ...options.selection, githubConfirmOpen: false },
108512
+ message: loaded.error.message
108513
+ };
108514
+ }
108515
+ const mirrorIssueToGitHub2 = options.githubMirror?.mirrorIssueToGitHub ?? mirrorIssueToGitHub;
108516
+ const result = await mirrorIssueToGitHub2({
108517
+ projectRoot: loaded.value.projectRoot,
108518
+ config: loaded.value.config,
108519
+ id: card.id,
108520
+ now: options.now
108521
+ });
108522
+ if (!result.ok) {
108523
+ return {
108524
+ ok: false,
108525
+ model: options.model,
108526
+ selection: { ...options.selection, githubConfirmOpen: false },
108527
+ message: result.error.message
108528
+ };
108529
+ }
108530
+ return refreshAfterGitHubMirror({
108531
+ cwd: options.cwd,
108532
+ model: options.model,
108533
+ selection: options.selection,
108534
+ cardId: card.id,
108535
+ message: `GitHub mirror created #${result.value.github_issue.number}`
108536
+ });
108537
+ }
108538
+ async function pushSelectedIssueGitHubMirror(options) {
108539
+ const card = selectedCard(options.model, options.selection);
108540
+ if (!card) {
108541
+ return {
108542
+ ok: false,
108543
+ model: options.model,
108544
+ selection: { ...options.selection, githubConfirmOpen: false },
108545
+ message: "No Issue selected"
108546
+ };
108547
+ }
108548
+ const loaded = loadProjectConfig(options.cwd ?? process.cwd());
108549
+ if (!loaded.ok) {
108550
+ return {
108551
+ ok: false,
108552
+ model: options.model,
108553
+ selection: { ...options.selection, githubConfirmOpen: false },
108554
+ message: loaded.error.message
108555
+ };
108556
+ }
108557
+ const pushGitHubMirror2 = options.githubMirror?.pushGitHubMirror ?? pushGitHubMirror;
108558
+ const result = await pushGitHubMirror2({
108559
+ projectRoot: loaded.value.projectRoot,
108560
+ config: loaded.value.config,
108561
+ id: card.id,
108562
+ now: options.now
108563
+ });
108564
+ if (!result.ok) {
108565
+ return {
108566
+ ok: false,
108567
+ model: options.model,
108568
+ selection: { ...options.selection, githubConfirmOpen: false },
108569
+ message: result.error.message
108570
+ };
108571
+ }
108572
+ return refreshAfterGitHubMirror({
108573
+ cwd: options.cwd,
108574
+ model: options.model,
108575
+ selection: options.selection,
108576
+ cardId: card.id,
108577
+ message: `GitHub mirror pushed #${result.value.github_issue.number}`
108578
+ });
108579
+ }
108580
+ function refreshAfterGitHubMirror(options) {
108581
+ const model = loadTuiModel(options.cwd);
108582
+ const selection = findSelectionByCardId(model, options.cardId) ?? clampSelection(model, options.selection);
108583
+ return {
108584
+ ok: true,
108585
+ model,
108586
+ selection: {
108587
+ ...selection,
108588
+ detailOpen: options.selection.detailOpen,
108589
+ githubConfirmOpen: false,
108590
+ githubBusy: false
108591
+ },
108592
+ message: options.message
108593
+ };
108594
+ }
108595
+ function selectedCard(model, selection) {
108596
+ return model.columns[selection.columnIndex]?.cards[selection.cardIndex];
108597
+ }
108598
+ function githubAlreadyRunning(options) {
108599
+ return {
108600
+ ok: false,
108601
+ model: options.model,
108602
+ selection: options.selection,
108603
+ message: "GitHub mirror already running"
108604
+ };
108605
+ }
108025
108606
  function appendSelectedIssueNote(options) {
108026
108607
  const body = options.body.trim();
108027
108608
  if (!body) {
@@ -108118,7 +108699,7 @@ function TuiAppView({
108118
108699
  viewportHeight,
108119
108700
  viewportWidth,
108120
108701
  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, {
108702
+ })), 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
108703
  message: selection.message,
108123
108704
  mode: footerMode(selection),
108124
108705
  theme
@@ -108151,6 +108732,7 @@ async function launchTui(options = {}) {
108151
108732
  });
108152
108733
  const modelRef = import_react20.default.useRef(model);
108153
108734
  const selectionRef = import_react20.default.useRef(selection);
108735
+ const githubBusyRef = import_react20.default.useRef(false);
108154
108736
  modelRef.current = model;
108155
108737
  selectionRef.current = selection;
108156
108738
  import_react20.default.useEffect(() => {
@@ -108219,6 +108801,37 @@ async function launchTui(options = {}) {
108219
108801
  }
108220
108802
  return;
108221
108803
  }
108804
+ if (selection.githubConfirmOpen) {
108805
+ if (action === "help") {
108806
+ setSelection((current) => moveSelection(model, current, action));
108807
+ return;
108808
+ }
108809
+ if (action === "escape") {
108810
+ setSelection((current) => moveSelection(model, current, action));
108811
+ return;
108812
+ }
108813
+ if (action === "enter") {
108814
+ if (githubBusyRef.current)
108815
+ return;
108816
+ githubBusyRef.current = true;
108817
+ setSelection((current) => ({ ...current, githubBusy: true }));
108818
+ (async () => {
108819
+ try {
108820
+ const result = await confirmSelectedIssueGitHubMirror({
108821
+ cwd: options.cwd,
108822
+ model,
108823
+ selection
108824
+ });
108825
+ setModel(result.model);
108826
+ setSelection({ ...result.selection, message: result.message });
108827
+ } finally {
108828
+ githubBusyRef.current = false;
108829
+ }
108830
+ })();
108831
+ return;
108832
+ }
108833
+ return;
108834
+ }
108222
108835
  if (!action)
108223
108836
  return;
108224
108837
  if (action === "quit") {
@@ -108268,6 +108881,26 @@ async function launchTui(options = {}) {
108268
108881
  setSelection((current) => moveSelection(model, current, action));
108269
108882
  return;
108270
108883
  }
108884
+ if (action === "github") {
108885
+ if (githubBusyRef.current)
108886
+ return;
108887
+ githubBusyRef.current = true;
108888
+ setSelection((current) => ({ ...current, githubBusy: true }));
108889
+ (async () => {
108890
+ try {
108891
+ const result = await beginSelectedIssueGitHubMirror({
108892
+ cwd: options.cwd,
108893
+ model,
108894
+ selection
108895
+ });
108896
+ setModel(result.model);
108897
+ setSelection({ ...result.selection, message: result.message });
108898
+ } finally {
108899
+ githubBusyRef.current = false;
108900
+ }
108901
+ })();
108902
+ return;
108903
+ }
108271
108904
  setSelection((current) => moveSelection(model, current, action, {
108272
108905
  viewportHeight: renderer.height
108273
108906
  }));
@@ -108293,6 +108926,7 @@ var commands = [
108293
108926
  "update",
108294
108927
  "move",
108295
108928
  "append",
108929
+ "github",
108296
108930
  "mcp",
108297
108931
  "skills",
108298
108932
  "tui",
@@ -108325,6 +108959,7 @@ var commandOptions = {
108325
108959
  { name: "body", short: "b", value: true },
108326
108960
  { name: "source", short: "s", value: true }
108327
108961
  ],
108962
+ github: [{ name: "all", value: false }],
108328
108963
  mcp: [
108329
108964
  { name: "agent", short: "a", value: true },
108330
108965
  { name: "no-global", value: false },
@@ -108335,7 +108970,10 @@ var commandOptions = {
108335
108970
  { name: "no-global", value: false }
108336
108971
  ],
108337
108972
  tui: [{ name: "columns", short: "c", value: true }],
108338
- watch: [{ name: "quiet", short: "q", value: false }]
108973
+ watch: [
108974
+ { name: "quiet", short: "q", value: false },
108975
+ { name: "github-push", value: false }
108976
+ ]
108339
108977
  };
108340
108978
  function parseArgs(args, command) {
108341
108979
  const positionals = [];
@@ -108408,32 +109046,33 @@ function isCommandName(input) {
108408
109046
  function ok2(stdout) {
108409
109047
  return { exitCode: 0, stdout, stderr: "" };
108410
109048
  }
108411
- function fail(stderr) {
109049
+ function fail2(stderr) {
108412
109050
  return { exitCode: 1, stdout: "", stderr: `${stderr}
108413
109051
  ` };
108414
109052
  }
108415
109053
 
108416
109054
  // src/commands.ts
108417
- import { readFileSync as readFileSync10 } from "fs";
108418
- import { basename as basename5, join as join11 } from "path";
109055
+ import { readFileSync as readFileSync11 } from "fs";
109056
+ import { basename as basename5, join as join12 } from "path";
108419
109057
 
108420
109058
  // src/watch.ts
109059
+ import { createHash as createHash2 } from "crypto";
108421
109060
  import {
108422
109061
  appendFileSync,
108423
109062
  existsSync as existsSync9,
108424
109063
  mkdirSync as mkdirSync7,
108425
- readFileSync as readFileSync9,
109064
+ readFileSync as readFileSync10,
108426
109065
  renameSync as renameSync4,
108427
- writeFileSync as writeFileSync6
109066
+ writeFileSync as writeFileSync7
108428
109067
  } from "fs";
108429
- import { dirname as dirname8, join as join10 } from "path";
108430
- function runWatchOnce(options = {}) {
109068
+ import { dirname as dirname8, join as join11 } from "path";
109069
+ async function runWatchOnce(options = {}) {
108431
109070
  const loaded = loadProjectConfig(options.cwd ?? process.cwd());
108432
109071
  if (!loaded.ok)
108433
109072
  throw new Error(loaded.error.message);
108434
109073
  if (isWriteLocked(loaded.value.projectRoot)) {
108435
109074
  emit(options, "skipped: mikan write lock is held");
108436
- return { observed: 0, transitions: 0, skipped: true };
109075
+ return { observed: 0, transitions: 0, githubPushes: 0, skipped: true };
108437
109076
  }
108438
109077
  const snapshotPath = watcherSnapshotPath(loaded.value.projectRoot);
108439
109078
  const previous = readSnapshot(snapshotPath);
@@ -108445,11 +109084,8 @@ function runWatchOnce(options = {}) {
108445
109084
  if (!board.ok)
108446
109085
  throw new Error(board.error.message);
108447
109086
  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
109087
  let transitions = 0;
109088
+ let githubPushes = 0;
108453
109089
  if (previous) {
108454
109090
  for (const issue2 of issues) {
108455
109091
  const id = String(issue2.issue.id);
@@ -108464,24 +109100,73 @@ function runWatchOnce(options = {}) {
108464
109100
  }
108465
109101
  fireHooks(loaded.value, issue2, before.status, String(issue2.status), options);
108466
109102
  }
109103
+ if (shouldPushGitHubMirrors(loaded.value, options)) {
109104
+ githubPushes = await pushChangedGitHubMirrors(loaded.value, issues, previous, options);
109105
+ }
108467
109106
  }
108468
- writeSnapshot(snapshotPath, current);
109107
+ writeSnapshot(snapshotPath, readCurrentSnapshot(loaded.value));
108469
109108
  if (options.logScanSummary !== false) {
108470
109109
  emit(options, `watch observed ${issues.length} issue(s), ${transitions} transition(s)`);
108471
109110
  }
108472
- return { observed: issues.length, transitions, skipped: false };
109111
+ return { observed: issues.length, transitions, githubPushes, skipped: false };
108473
109112
  }
108474
109113
  function watchProject(options = {}) {
108475
109114
  const logger = options.quiet ? undefined : options.logger ?? console.log;
108476
- const watchOptions = { ...options, logger, logScanSummary: false };
109115
+ const errorLogger = options.errorLogger ?? console.error;
109116
+ const watchOptions = {
109117
+ ...options,
109118
+ logger,
109119
+ errorLogger,
109120
+ logScanSummary: false
109121
+ };
108477
109122
  if (!options.quiet) {
108478
109123
  const loaded = loadProjectConfig(options.cwd ?? process.cwd());
108479
109124
  if (!loaded.ok)
108480
109125
  throw new Error(loaded.error.message);
108481
109126
  logger?.(`watch started: ${loaded.value.projectRoot}`);
108482
109127
  }
108483
- runWatchOnce(watchOptions);
108484
- return setInterval(() => runWatchOnce(watchOptions), options.intervalMs ?? 1000);
109128
+ let running = false;
109129
+ const tick = () => {
109130
+ if (running)
109131
+ return;
109132
+ running = true;
109133
+ runWatchOnce(watchOptions).finally(() => {
109134
+ running = false;
109135
+ });
109136
+ };
109137
+ tick();
109138
+ return setInterval(tick, options.intervalMs ?? 1000);
109139
+ }
109140
+ function shouldPushGitHubMirrors(loaded, options) {
109141
+ return options.githubPush === true || loaded.config.github?.auto_push_mirrors === true;
109142
+ }
109143
+ async function pushChangedGitHubMirrors(loaded, issues, previous, options) {
109144
+ const pushGitHubMirror2 = options.githubMirror?.pushGitHubMirror ?? pushGitHubMirror;
109145
+ let pushes = 0;
109146
+ for (const issue2 of issues) {
109147
+ if (!issue2.issue.githubIssue)
109148
+ continue;
109149
+ const id = String(issue2.issue.id);
109150
+ const before = previous[id];
109151
+ if (!before || !hasIssueChanged(issue2, before))
109152
+ continue;
109153
+ const result = await pushGitHubMirror2({
109154
+ projectRoot: loaded.projectRoot,
109155
+ config: loaded.config,
109156
+ id,
109157
+ now: options.now
109158
+ });
109159
+ if (!result.ok) {
109160
+ recordGitHubMirrorPushFailure(loaded.projectRoot, id, result.error.message, options);
109161
+ continue;
109162
+ }
109163
+ pushes++;
109164
+ emit(options, `github mirror pushed: ${id} ${result.value.github_issue.url}`);
109165
+ }
109166
+ return pushes;
109167
+ }
109168
+ function hasIssueChanged(issue2, before) {
109169
+ return before.status !== String(issue2.status) || before.path !== issue2.path || before.contentHash !== issueContentHash(issue2);
108485
109170
  }
108486
109171
  function appendPlaceholderStatusLog(loaded, issue2, fromStatus, now) {
108487
109172
  if (hasMatchingStatusLogEntry(issue2.issue.body, fromStatus, String(issue2.status))) {
@@ -108518,7 +109203,7 @@ function fireHooks(loaded, issue2, fromStatus, toStatus, options) {
108518
109203
  });
108519
109204
  if (result.exitCode !== 0) {
108520
109205
  appendHookFailure(loaded.projectRoot, {
108521
- timestamp: utcNow2(options.now),
109206
+ timestamp: utcNow3(options.now),
108522
109207
  issue_id: String(issue2.issue.id),
108523
109208
  from_status: fromStatus,
108524
109209
  to_status: toStatus,
@@ -108530,6 +109215,16 @@ function fireHooks(loaded, issue2, fromStatus, toStatus, options) {
108530
109215
  }
108531
109216
  }
108532
109217
  }
109218
+ function recordGitHubMirrorPushFailure(projectRoot, issueId, message, options) {
109219
+ appendHookFailure(projectRoot, {
109220
+ timestamp: utcNow3(options.now),
109221
+ issue_id: issueId,
109222
+ command: `github push ${issueId}`,
109223
+ exit_code: 1,
109224
+ error: message
109225
+ });
109226
+ emitError(options, `github mirror push failed: ${issueId} ${message}`);
109227
+ }
108533
109228
  function hasMatchingStatusLogEntry(body, fromStatus, toStatus) {
108534
109229
  const section = extractStatusLog(body);
108535
109230
  if (!section)
@@ -108560,11 +109255,14 @@ function emit(options, line) {
108560
109255
  return;
108561
109256
  options.logger?.(line);
108562
109257
  }
109258
+ function emitError(options, line) {
109259
+ options.errorLogger?.(line);
109260
+ }
108563
109261
  function renderHookCommand(command, values) {
108564
109262
  return command.replace(/{{\s*([a-z_]+)\s*}}/g, (match, key) => values[key] ?? match);
108565
109263
  }
108566
109264
  function appendHookFailure(projectRoot, entry) {
108567
- const path5 = join10(projectRoot, ".mikan", ".state", "hook-log.ndjson");
109265
+ const path5 = join11(projectRoot, ".mikan", ".state", "hook-log.ndjson");
108568
109266
  mkdirSync7(dirname8(path5), { recursive: true });
108569
109267
  appendFileSync(path5, `${JSON.stringify(entry)}
108570
109268
  `);
@@ -108573,21 +109271,41 @@ function readSnapshot(path5) {
108573
109271
  if (!existsSync9(path5))
108574
109272
  return;
108575
109273
  try {
108576
- return JSON.parse(readFileSync9(path5, "utf8"));
109274
+ return JSON.parse(readFileSync10(path5, "utf8"));
108577
109275
  } catch {
108578
109276
  return;
108579
109277
  }
108580
109278
  }
109279
+ function readCurrentSnapshot(loaded) {
109280
+ const board = scanBoard({
109281
+ projectRoot: loaded.projectRoot,
109282
+ config: loaded.config,
109283
+ includeArchived: true
109284
+ });
109285
+ if (!board.ok)
109286
+ throw new Error(board.error.message);
109287
+ return Object.fromEntries(board.value.columns.flatMap((column) => column.issues.map((issue2) => [
109288
+ String(issue2.issue.id),
109289
+ {
109290
+ status: String(issue2.status),
109291
+ path: issue2.path,
109292
+ contentHash: issueContentHash(issue2)
109293
+ }
109294
+ ])));
109295
+ }
108581
109296
  function writeSnapshot(path5, snapshot) {
108582
109297
  mkdirSync7(dirname8(path5), { recursive: true });
108583
109298
  const tmp = `${path5}.${process.pid}.${Date.now()}.tmp`;
108584
- writeFileSync6(tmp, JSON.stringify(snapshot, null, 2));
109299
+ writeFileSync7(tmp, JSON.stringify(snapshot, null, 2));
108585
109300
  renameSync4(tmp, path5);
108586
109301
  }
108587
109302
  function watcherSnapshotPath(projectRoot) {
108588
- return join10(projectRoot, ".mikan", ".state", "watcher-snapshot.json");
109303
+ return join11(projectRoot, ".mikan", ".state", "watcher-snapshot.json");
108589
109304
  }
108590
- function utcNow2(now) {
109305
+ function issueContentHash(issue2) {
109306
+ return createHash2("sha256").update(readFileSync10(issue2.path)).digest("hex");
109307
+ }
109308
+ function utcNow3(now) {
108591
109309
  return (now?.() ?? new Date).toISOString().replace(".000Z", "Z");
108592
109310
  }
108593
109311
 
@@ -108599,7 +109317,7 @@ function runMcp(cwd, parsed, options) {
108599
109317
  }
108600
109318
  const agent = parsed.flags.get("agent")?.at(-1);
108601
109319
  if (!agent)
108602
- return fail("Usage: mikan mcp add --agent <agent>");
109320
+ return fail2("Usage: mikan mcp add --agent <agent>");
108603
109321
  try {
108604
109322
  const result = installMcpServerForAgent(agent, {
108605
109323
  cwd,
@@ -108612,18 +109330,18 @@ function runMcp(cwd, parsed, options) {
108612
109330
  return ok2(`Registered MCP server '${result.serverName}' for ${result.agent}${scope}: ${result.path}
108613
109331
  ${hint}`);
108614
109332
  } catch (error51) {
108615
- return fail(error51 instanceof Error ? error51.message : String(error51));
109333
+ return fail2(error51 instanceof Error ? error51.message : String(error51));
108616
109334
  }
108617
109335
  }
108618
109336
  async function runMcpLlms(cwd, args) {
108619
109337
  const parsed = parseArgs(args, "mcp");
108620
109338
  if (!parsed.ok) {
108621
- return fail(`${parsed.error}
109339
+ return fail2(`${parsed.error}
108622
109340
 
108623
109341
  Run \`mikan help mcp\` for usage.`);
108624
109342
  }
108625
109343
  if (parsed.value.flags.has("agent")) {
108626
- return fail(`incur-backed discovery only prints a manifest; it cannot install for a specific agent.
109344
+ return fail2(`incur-backed discovery only prints a manifest; it cannot install for a specific agent.
108627
109345
  ` + "Use `mikan mcp add --agent <agent>` for native MCP registration.");
108628
109346
  }
108629
109347
  const manifest = await getMcpManifest({ cwd }, { full: parsed.value.flags.has("full") });
@@ -108633,11 +109351,11 @@ Run \`mikan help mcp\` for usage.`);
108633
109351
  }
108634
109352
  function runSkills(cwd, parsed, options) {
108635
109353
  if (parsed.positionals[0] !== "add") {
108636
- return fail("Usage: mikan skills add --agent <agent>");
109354
+ return fail2("Usage: mikan skills add --agent <agent>");
108637
109355
  }
108638
109356
  const agent = parsed.flags.get("agent")?.at(-1);
108639
109357
  if (!agent)
108640
- return fail("Usage: mikan skills add --agent <agent>");
109358
+ return fail2("Usage: mikan skills add --agent <agent>");
108641
109359
  try {
108642
109360
  const result = installSkillForAgent(agent, {
108643
109361
  cwd,
@@ -108647,36 +109365,109 @@ function runSkills(cwd, parsed, options) {
108647
109365
  return ok2(`Installed mikan skill for ${result.agent} (${result.scope}): ${result.path}
108648
109366
  `);
108649
109367
  } catch (error51) {
108650
- return fail(error51 instanceof Error ? error51.message : String(error51));
109368
+ return fail2(error51 instanceof Error ? error51.message : String(error51));
109369
+ }
109370
+ }
109371
+ async function runGithub(cwd, parsed, options) {
109372
+ const subcommand2 = parsed.positionals[0];
109373
+ const id = parsed.positionals[1];
109374
+ const operations = options.githubMirror ?? {
109375
+ mirrorIssueToGitHub,
109376
+ pushGitHubMirror
109377
+ };
109378
+ const loaded = loadProjectConfig(cwd);
109379
+ if (!loaded.ok)
109380
+ return fail2(loaded.error.message);
109381
+ if (subcommand2 === "mirror") {
109382
+ if (!id)
109383
+ return fail2("Usage: mikan github mirror <issue-id>");
109384
+ return formatGitHubMirrorCliResult(await operations.mirrorIssueToGitHub({
109385
+ projectRoot: loaded.value.projectRoot,
109386
+ config: loaded.value.config,
109387
+ id,
109388
+ now: options.now
109389
+ }), "mirrored");
109390
+ }
109391
+ if (subcommand2 === "push") {
109392
+ if (parsed.flags.has("all")) {
109393
+ const board = scanBoard({
109394
+ projectRoot: loaded.value.projectRoot,
109395
+ config: loaded.value.config,
109396
+ includeArchived: true
109397
+ });
109398
+ if (!board.ok)
109399
+ return fail2(board.error.message);
109400
+ const mirroredIssues = board.value.columns.flatMap((column) => column.issues).filter((issue2) => issue2.issue.githubIssue).map((issue2) => String(issue2.issue.id));
109401
+ const outputs = [];
109402
+ const warnings = [];
109403
+ for (const issueId of mirroredIssues) {
109404
+ const result = await operations.pushGitHubMirror({
109405
+ projectRoot: loaded.value.projectRoot,
109406
+ config: loaded.value.config,
109407
+ id: issueId,
109408
+ now: options.now
109409
+ });
109410
+ if (!result.ok)
109411
+ return fail2(result.error.message);
109412
+ outputs.push(formatGitHubMirrorSuccess(result.value, "pushed"));
109413
+ warnings.push(...result.value.warnings);
109414
+ }
109415
+ return {
109416
+ exitCode: 0,
109417
+ stdout: outputs.length > 0 ? `${outputs.join(`
109418
+ `)}
109419
+ ` : "",
109420
+ stderr: formatGitHubMirrorWarnings(warnings)
109421
+ };
109422
+ }
109423
+ if (!id)
109424
+ return fail2("Usage: mikan github push <issue-id>|--all");
109425
+ return formatGitHubMirrorCliResult(await operations.pushGitHubMirror({
109426
+ projectRoot: loaded.value.projectRoot,
109427
+ config: loaded.value.config,
109428
+ id,
109429
+ now: options.now
109430
+ }), "pushed");
108651
109431
  }
109432
+ return fail2("Usage: mikan github <mirror|push> ...");
108652
109433
  }
108653
- function runWatch(cwd, parsed) {
109434
+ async function runWatch(cwd, parsed, options) {
108654
109435
  const lines = [];
108655
- runWatchOnce({
109436
+ const errors4 = [];
109437
+ await runWatchOnce({
108656
109438
  cwd,
108657
109439
  quiet: parsed.flags.has("quiet"),
108658
- logger: (line) => lines.push(line)
109440
+ githubPush: parsed.flags.has("github-push"),
109441
+ githubMirror: options.githubMirror ? { pushGitHubMirror: options.githubMirror.pushGitHubMirror } : undefined,
109442
+ logger: (line) => lines.push(line),
109443
+ errorLogger: (line) => errors4.push(line)
108659
109444
  });
108660
- return ok2(lines.length > 0 ? `${lines.join(`
109445
+ return {
109446
+ exitCode: 0,
109447
+ stdout: lines.length > 0 ? `${lines.join(`
108661
109448
  `)}
108662
- ` : "");
109449
+ ` : "",
109450
+ stderr: errors4.length > 0 ? `${errors4.join(`
109451
+ `)}
109452
+ ` : ""
109453
+ };
108663
109454
  }
108664
109455
  function runInit(cwd, parsed) {
108665
109456
  const key = parsed.flags.get("key")?.at(-1) ?? "MIK";
108666
109457
  const name = parsed.flags.get("name")?.at(-1) ?? basename5(cwd);
108667
109458
  const initialized = initProject(cwd, { key, name });
108668
109459
  if (!initialized.ok)
108669
- return fail(initialized.error.message);
108670
- return ok2(`Initialized mikan project at ${join11(cwd, ".mikan")}
109460
+ return fail2(initialized.error.message);
109461
+ return ok2(`Initialized mikan project at ${join12(cwd, ".mikan")}
108671
109462
  `);
108672
109463
  }
108673
109464
  function runAdd(cwd, parsed, options) {
108674
109465
  const title = parsed.positionals[0];
108675
109466
  if (!title)
108676
- return fail("Usage: mikan add <title> [--status status] [--label label] [--depends-on issue-id]");
109467
+ return fail2("Usage: mikan add <title> [--status status] [--label label] [--depends-on issue-id]");
108677
109468
  const loaded = loadProjectConfig(cwd);
108678
109469
  if (!loaded.ok)
108679
- return fail(loaded.error.message);
109470
+ return fail2(loaded.error.message);
108680
109471
  const result = createIssue({
108681
109472
  projectRoot: loaded.value.projectRoot,
108682
109473
  config: loaded.value.config,
@@ -108687,14 +109478,14 @@ function runAdd(cwd, parsed, options) {
108687
109478
  now: options.now
108688
109479
  });
108689
109480
  if (!result.ok)
108690
- return fail(result.error.message);
109481
+ return fail2(result.error.message);
108691
109482
  return ok2(`${String(result.value.issue.id)} ${result.value.issue.title}
108692
109483
  `);
108693
109484
  }
108694
109485
  function runList(cwd, parsed) {
108695
109486
  const loaded = loadProjectConfig(cwd);
108696
109487
  if (!loaded.ok)
108697
- return fail(loaded.error.message);
109488
+ return fail2(loaded.error.message);
108698
109489
  const includeArchived = parsed.flags.has("include-archived");
108699
109490
  const board = scanBoard({
108700
109491
  projectRoot: loaded.value.projectRoot,
@@ -108702,10 +109493,10 @@ function runList(cwd, parsed) {
108702
109493
  includeArchived
108703
109494
  });
108704
109495
  if (!board.ok)
108705
- return fail(board.error.message);
109496
+ return fail2(board.error.message);
108706
109497
  const statusFilter = parsed.flags.get("status")?.at(-1);
108707
109498
  if (statusFilter && !loaded.value.config.board.columns.some((column) => column.id === statusFilter)) {
108708
- return fail(`Unknown Status: ${statusFilter}`);
109499
+ return fail2(`Unknown Status: ${statusFilter}`);
108709
109500
  }
108710
109501
  const columns = statusFilter ? board.value.columns.filter((column) => column.id === statusFilter) : board.value.columns;
108711
109502
  return {
@@ -108717,30 +109508,30 @@ function runList(cwd, parsed) {
108717
109508
  function runShow(cwd, parsed) {
108718
109509
  const id = parsed.positionals[0];
108719
109510
  if (!id)
108720
- return fail("Usage: mikan show <issue-id>");
109511
+ return fail2("Usage: mikan show <issue-id>");
108721
109512
  const loaded = loadProjectConfig(cwd);
108722
109513
  if (!loaded.ok)
108723
- return fail(loaded.error.message);
109514
+ return fail2(loaded.error.message);
108724
109515
  const found = findIssueById({
108725
109516
  projectRoot: loaded.value.projectRoot,
108726
109517
  config: loaded.value.config,
108727
109518
  id
108728
109519
  });
108729
109520
  if (!found.ok)
108730
- return fail(found.error.message);
109521
+ return fail2(found.error.message);
108731
109522
  return {
108732
109523
  exitCode: 0,
108733
- stdout: readFileSync10(found.value.path, "utf8"),
109524
+ stdout: readFileSync11(found.value.path, "utf8"),
108734
109525
  stderr: formatDependencyShowInfo(found.value)
108735
109526
  };
108736
109527
  }
108737
109528
  function runUpdate(cwd, parsed, options) {
108738
109529
  const id = parsed.positionals[0];
108739
109530
  if (!id)
108740
- return fail("Usage: mikan update <issue-id> [--title title] [--label label] [--depends-on issue-id] [--body body]");
109531
+ return fail2("Usage: mikan update <issue-id> [--title title] [--label label] [--depends-on issue-id] [--body body]");
108741
109532
  const loaded = loadProjectConfig(cwd);
108742
109533
  if (!loaded.ok)
108743
- return fail(loaded.error.message);
109534
+ return fail2(loaded.error.message);
108744
109535
  const result = updateIssue({
108745
109536
  projectRoot: loaded.value.projectRoot,
108746
109537
  config: loaded.value.config,
@@ -108752,7 +109543,7 @@ function runUpdate(cwd, parsed, options) {
108752
109543
  now: options.now
108753
109544
  });
108754
109545
  if (!result.ok)
108755
- return fail(result.error.message);
109546
+ return fail2(result.error.message);
108756
109547
  return ok2(`${String(result.value.issue.id)} updated
108757
109548
  `);
108758
109549
  }
@@ -108760,10 +109551,10 @@ function runMove(cwd, parsed, options) {
108760
109551
  const id = parsed.positionals[0];
108761
109552
  const status = parsed.positionals[1];
108762
109553
  if (!id || !status)
108763
- return fail("Usage: mikan move <issue-id> <status> [--log text]");
109554
+ return fail2("Usage: mikan move <issue-id> <status> [--log text]");
108764
109555
  const loaded = loadProjectConfig(cwd);
108765
109556
  if (!loaded.ok)
108766
- return fail(loaded.error.message);
109557
+ return fail2(loaded.error.message);
108767
109558
  const result = moveIssue({
108768
109559
  projectRoot: loaded.value.projectRoot,
108769
109560
  config: loaded.value.config,
@@ -108773,7 +109564,7 @@ function runMove(cwd, parsed, options) {
108773
109564
  now: options.now
108774
109565
  });
108775
109566
  if (!result.ok)
108776
- return fail(result.error.message);
109567
+ return fail2(result.error.message);
108777
109568
  return ok2(`${String(result.value.issue.id)} moved to ${status}
108778
109569
  `);
108779
109570
  }
@@ -108782,10 +109573,10 @@ function runAppend(cwd, parsed, options) {
108782
109573
  const section = parsed.flags.get("section")?.at(-1);
108783
109574
  const body = parsed.flags.get("body")?.at(-1);
108784
109575
  if (!id || !section || !body)
108785
- return fail("Usage: mikan append <issue-id> --section section --body body [--source source]");
109576
+ return fail2("Usage: mikan append <issue-id> --section section --body body [--source source]");
108786
109577
  const loaded = loadProjectConfig(cwd);
108787
109578
  if (!loaded.ok)
108788
- return fail(loaded.error.message);
109579
+ return fail2(loaded.error.message);
108789
109580
  const result = appendIssue({
108790
109581
  projectRoot: loaded.value.projectRoot,
108791
109582
  config: loaded.value.config,
@@ -108796,10 +109587,27 @@ function runAppend(cwd, parsed, options) {
108796
109587
  now: options.now
108797
109588
  });
108798
109589
  if (!result.ok)
108799
- return fail(result.error.message);
109590
+ return fail2(result.error.message);
108800
109591
  return ok2(`${String(result.value.issue.id)} appended ${section}
108801
109592
  `);
108802
109593
  }
109594
+ function formatGitHubMirrorCliResult(result, verb) {
109595
+ if (!result.ok)
109596
+ return fail2(result.error.message);
109597
+ return {
109598
+ exitCode: 0,
109599
+ stdout: `${formatGitHubMirrorSuccess(result.value, verb)}
109600
+ `,
109601
+ stderr: formatGitHubMirrorWarnings(result.value.warnings)
109602
+ };
109603
+ }
109604
+ function formatGitHubMirrorSuccess(result, verb) {
109605
+ return `${result.issue_id} ${verb} to ${result.github_issue.url}`;
109606
+ }
109607
+ function formatGitHubMirrorWarnings(warnings) {
109608
+ return warnings.map((warning) => `warning: ${warning}
109609
+ `).join("");
109610
+ }
108803
109611
  function formatBoard(columns) {
108804
109612
  const lines = [];
108805
109613
  for (const column of columns) {
@@ -108848,7 +109656,7 @@ function formatWarnings(warnings) {
108848
109656
  // src/help.ts
108849
109657
  function commandHelp(topic) {
108850
109658
  if (!isCommandName(topic)) {
108851
- return fail(`Unknown help topic: ${topic}
109659
+ return fail2(`Unknown help topic: ${topic}
108852
109660
 
108853
109661
  Run \`mikan help\` to see available commands.`);
108854
109662
  }
@@ -108868,6 +109676,7 @@ Commands:
108868
109676
  update Update Issue title, labels, or body
108869
109677
  move Move an Issue to another Status
108870
109678
  append Append Markdown to an Issue section
109679
+ github Create or push GitHub Mirrors
108871
109680
  tui Open the read-only board
108872
109681
  watch Run the polling watcher
108873
109682
  mcp Start the stdio MCP server
@@ -108958,6 +109767,24 @@ Options:
108958
109767
  -b, --body <body> Markdown to append
108959
109768
  -s, --source <source> Source name for timestamped entries
108960
109769
  -h, --help Show this help
109770
+ `;
109771
+ case "github":
109772
+ return `Create or push one-way GitHub Mirrors.
109773
+
109774
+ Usage:
109775
+ mikan github mirror <issue-id>
109776
+ mikan github push <issue-id>
109777
+ mikan github push --all
109778
+
109779
+ Options:
109780
+ --all With push: update every Issue that already has github_issue
109781
+ -h, --help Show this help
109782
+
109783
+ Notes:
109784
+ Configure github.repo in .mikan/config.yaml first.
109785
+ GitHub Mirror uses the gh CLI; install gh and run gh auth login.
109786
+ mirror creates a GitHub Issue when github_issue is absent and updates it when present.
109787
+ push requires an existing github_issue; push --all never creates new GitHub Issues.
108961
109788
  `;
108962
109789
  case "tui":
108963
109790
  return `Open the read-only board.
@@ -108987,8 +109814,13 @@ Usage:
108987
109814
  mikan watch [options]
108988
109815
 
108989
109816
  Options:
108990
- -q, --quiet Suppress watch log output
109817
+ -q, --quiet Suppress watch log output except GitHub Mirror failures
109818
+ --github-push Push changed Issues that already have github_issue
108991
109819
  -h, --help Show this help
109820
+
109821
+ Notes:
109822
+ GitHub Mirror auto-push also runs when github.auto_push_mirrors is true.
109823
+ It only pushes existing mirrors and never creates GitHub Issues.
108992
109824
  `;
108993
109825
  case "mcp":
108994
109826
  return `Start the stdio MCP server, register it with an agent, or print its manifest.
@@ -109075,7 +109907,7 @@ async function runCli(argv = process.argv.slice(2), options = {}) {
109075
109907
  return topic ? commandHelp(topic) : ok2(helpText());
109076
109908
  }
109077
109909
  if (!isCommandName(command)) {
109078
- return fail(`Unknown command: ${command}
109910
+ return fail2(`Unknown command: ${command}
109079
109911
 
109080
109912
  Run \`mikan help\` to see available commands.`);
109081
109913
  }
@@ -109083,7 +109915,7 @@ Run \`mikan help\` to see available commands.`);
109083
109915
  return commandHelp(command);
109084
109916
  const parsed = parseArgs(argv.slice(1), command);
109085
109917
  if (!parsed.ok) {
109086
- return fail(`${parsed.error}
109918
+ return fail2(`${parsed.error}
109087
109919
 
109088
109920
  Run \`mikan help ${command}\` for usage.`);
109089
109921
  }
@@ -109103,6 +109935,8 @@ Run \`mikan help ${command}\` for usage.`);
109103
109935
  return runMove(cwd, parsed.value, options);
109104
109936
  case "append":
109105
109937
  return runAppend(cwd, parsed.value, options);
109938
+ case "github":
109939
+ return runGithub(cwd, parsed.value, options);
109106
109940
  case "mcp":
109107
109941
  return runMcp(cwd, parsed.value, options);
109108
109942
  case "skills":
@@ -109110,7 +109944,7 @@ Run \`mikan help ${command}\` for usage.`);
109110
109944
  case "tui": {
109111
109945
  const columns = parseTuiColumnsOption(parsed.value.flags.get("columns")?.at(-1));
109112
109946
  if (!columns.ok) {
109113
- return fail(`${columns.error}
109947
+ return fail2(`${columns.error}
109114
109948
 
109115
109949
  Run \`mikan help tui\` for usage.`);
109116
109950
  }
@@ -109118,12 +109952,12 @@ Run \`mikan help tui\` for usage.`);
109118
109952
  `);
109119
109953
  }
109120
109954
  case "watch":
109121
- return runWatch(cwd, parsed.value);
109955
+ return await runWatch(cwd, parsed.value, options);
109122
109956
  default:
109123
109957
  return ok2(helpText());
109124
109958
  }
109125
109959
  } catch (error51) {
109126
- return fail(error51 instanceof Error ? error51.message : String(error51));
109960
+ return fail2(error51 instanceof Error ? error51.message : String(error51));
109127
109961
  }
109128
109962
  }
109129
109963
  async function main(argv = process.argv.slice(2)) {
@@ -109147,19 +109981,19 @@ async function runInteractiveCommand(argv = process.argv.slice(2), options = {})
109147
109981
  if (argv[0] === "tui") {
109148
109982
  const parsed = parseArgs(argv.slice(1), "tui");
109149
109983
  if (!parsed.ok) {
109150
- return fail(`${parsed.error}
109984
+ return fail2(`${parsed.error}
109151
109985
 
109152
109986
  Run \`mikan help tui\` for usage.`);
109153
109987
  }
109154
109988
  const columns = parseTuiColumnsOption(parsed.value.flags.get("columns")?.at(-1));
109155
109989
  if (!columns.ok) {
109156
- return fail(`${columns.error}
109990
+ return fail2(`${columns.error}
109157
109991
 
109158
109992
  Run \`mikan help tui\` for usage.`);
109159
109993
  }
109160
109994
  const loaded = loadProjectConfig(cwd);
109161
109995
  if (!loaded.ok)
109162
- return fail(loaded.error.message);
109996
+ return fail2(loaded.error.message);
109163
109997
  await (options.launchTui ?? ((launchOptions) => launchTui({ cwd, columns: launchOptions.columns })))({
109164
109998
  columns: columns.value
109165
109999
  });
@@ -109168,12 +110002,13 @@ Run \`mikan help tui\` for usage.`);
109168
110002
  if (argv[0] === "watch") {
109169
110003
  const parsed = parseArgs(argv.slice(1), "watch");
109170
110004
  if (!parsed.ok) {
109171
- return fail(`${parsed.error}
110005
+ return fail2(`${parsed.error}
109172
110006
 
109173
110007
  Run \`mikan help watch\` for usage.`);
109174
110008
  }
109175
110009
  const quiet = parsed.value.flags.has("quiet");
109176
- (options.launchWatch ?? (() => watchProject({ cwd, quiet })))();
110010
+ const githubPush = parsed.value.flags.has("github-push");
110011
+ (options.launchWatch ?? (() => watchProject({ cwd, quiet, githubPush })))();
109177
110012
  return ok2("");
109178
110013
  }
109179
110014
  }