kennel 0.2.24 → 0.2.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/cli/dispatch.js +2 -2
  2. package/dist/cli/usage.js +7 -1
  3. package/dist/core/api-client.js +1 -2
  4. package/dist/core/command.js +1 -1
  5. package/dist/core/core-folders.js +6 -2
  6. package/dist/core/runtime.js +30 -4657
  7. package/dist/mcp/install-page.d.ts +1 -1
  8. package/dist/mcp/install-page.js +419 -4
  9. package/dist/package/preview.d.ts +4 -0
  10. package/dist/package/preview.js +790 -4990
  11. package/dist/site/hot-viewer.js +1 -1
  12. package/dist/site/kinds.d.ts +1 -1
  13. package/dist/site/kinds.js +2 -59
  14. package/dist/site/terminal.d.ts +9 -1
  15. package/dist/site/terminal.js +162 -20
  16. package/package.json +5 -5
  17. package/web/assets/{abnfDiagram-VRR7QNED-aRemVX7f.js → abnfDiagram-VRR7QNED-CIyEzNaJ.js} +1 -1
  18. package/web/assets/{arc-BpDsnNTf.js → arc-Dba3y3eW.js} +1 -1
  19. package/web/assets/{architectureDiagram-ZJ3FMSHR-DNXHQddP.js → architectureDiagram-ZJ3FMSHR-DjFjO3tR.js} +1 -1
  20. package/web/assets/ask-tray-PMT6VVXN-ButKBzsY.js +23 -0
  21. package/web/assets/{blockDiagram-677ZJIJ3-CF4H4upo.js → blockDiagram-677ZJIJ3-C8ZQgtnK.js} +1 -1
  22. package/web/assets/{c4Diagram-LMCZKHZV-BPWUnjtx.js → c4Diagram-LMCZKHZV-DhWn2tZm.js} +1 -1
  23. package/web/assets/channel-BuqSObVl.js +1 -0
  24. package/web/assets/{chunk-2Q5K7J3B-DGsa7uv7.js → chunk-2Q5K7J3B-BEkPxYAB.js} +1 -1
  25. package/web/assets/{chunk-32BRIVSS-BRfic3W2.js → chunk-32BRIVSS-BZ0ofM9m.js} +1 -1
  26. package/web/assets/{chunk-5VM5RSS4-L2h7hliu.js → chunk-5VM5RSS4-CTgBiom0.js} +1 -1
  27. package/web/assets/{chunk-EX3LRPZG-BPgD_fgx.js → chunk-EX3LRPZG-B7lDJEfz.js} +1 -1
  28. package/web/assets/{chunk-JWPE2WC7-CckCaqu_.js → chunk-JWPE2WC7-DotlQGla.js} +1 -1
  29. package/web/assets/{chunk-MOJQB5TN-zyGgx-VW.js → chunk-MOJQB5TN-BSlB5ICN.js} +1 -1
  30. package/web/assets/{chunk-RYQCIY6F-Drzpg5IG.js → chunk-RYQCIY6F-BbDvgRvj.js} +1 -1
  31. package/web/assets/{chunk-V7JOEXUC-Di4ESKz-.js → chunk-V7JOEXUC-CqC2yHBO.js} +1 -1
  32. package/web/assets/{chunk-VR4S4FIN-C5lQtDI1.js → chunk-VR4S4FIN-18aLOCVw.js} +1 -1
  33. package/web/assets/{chunk-XXDRQBXY-Cell0ft2.js → chunk-XXDRQBXY-uulB67ep.js} +1 -1
  34. package/web/assets/classDiagram-OUVF2IWQ-xfk1LZB_.js +1 -0
  35. package/web/assets/classDiagram-v2-EOCWNBFH-xfk1LZB_.js +1 -0
  36. package/web/assets/{cose-bilkent-JH36ORCC-CiKtOFxl.js → cose-bilkent-JH36ORCC-C8yqL7ml.js} +1 -1
  37. package/web/assets/{cynefin-VYW2F7L2-B75MWf5b.js → cynefin-VYW2F7L2-D-wd85t1.js} +1 -1
  38. package/web/assets/{cynefinDiagram-TSTJHNR4-BmNVkSWW.js → cynefinDiagram-TSTJHNR4-rrV6rLov.js} +1 -1
  39. package/web/assets/{dagre-VKFMJZFB-BcM1Wqu5.js → dagre-VKFMJZFB-BxwiLhMr.js} +1 -1
  40. package/web/assets/{diagram-FQU43EPY-BiBWrxa8.js → diagram-FQU43EPY-8sr7lcj4.js} +1 -1
  41. package/web/assets/{diagram-G47NLZAW-Cfxukr7T.js → diagram-G47NLZAW-BQIU_Mie.js} +1 -1
  42. package/web/assets/{diagram-NH7WQ7WH-C83VkBYW.js → diagram-NH7WQ7WH-Bt-xVbVq.js} +1 -1
  43. package/web/assets/{diagram-OA4YK3LP-Oj0uj6CX.js → diagram-OA4YK3LP-p-i-3cps.js} +1 -1
  44. package/web/assets/{diagram-WEI45ONY-DhbL0nvt.js → diagram-WEI45ONY-E6t6-_mU.js} +1 -1
  45. package/web/assets/{ebnfDiagram-CCIWWBDH-D4JYp1UC.js → ebnfDiagram-CCIWWBDH-DCszfyU3.js} +1 -1
  46. package/web/assets/{entity-search-page-G6QEQNXT-UKzUU5id.js → entity-search-page-G6QEQNXT-D6cvoqrF.js} +1 -1
  47. package/web/assets/{erDiagram-Q63AITRT-C-oyRt9s.js → erDiagram-Q63AITRT-C4gBewIM.js} +1 -1
  48. package/web/assets/{flowDiagram-23GEKE2U-0Tplj9FK.js → flowDiagram-23GEKE2U-BEyFAV-g.js} +1 -1
  49. package/web/assets/{ganttDiagram-NO4QXBWP-wgh2e0B_.js → ganttDiagram-NO4QXBWP-Bat5BF2x.js} +1 -1
  50. package/web/assets/{gitGraphDiagram-IHSO6WYX-D6z9qDXa.js → gitGraphDiagram-IHSO6WYX-CGZs8b5E.js} +1 -1
  51. package/web/assets/index-DmJQJIC1.js +451 -0
  52. package/web/assets/{index-BGwTWQMJ.css → index-tpV2etC4.css} +1 -1
  53. package/web/assets/{infoDiagram-FWYZ7A6U-D3o7el5X.js → infoDiagram-FWYZ7A6U-Cglwuazb.js} +1 -1
  54. package/web/assets/{ishikawaDiagram-FXEZZL3T-CM0QyWYH.js → ishikawaDiagram-FXEZZL3T-C95-Gz9z.js} +1 -1
  55. package/web/assets/{journeyDiagram-5HDEW3XC-fmIoh0h6.js → journeyDiagram-5HDEW3XC-C055Trr6.js} +1 -1
  56. package/web/assets/{kanban-definition-HUTT4EX6-aEtqsiWf.js → kanban-definition-HUTT4EX6-CznSv3_t.js} +1 -1
  57. package/web/assets/{linear-aJ-2UZO5.js → linear-CnWGyi6E.js} +1 -1
  58. package/web/assets/{linked-session-header-M7WY6IGF-CltMJZiX.js → linked-session-header-M7WY6IGF-BFioq_q7.js} +1 -1
  59. package/web/assets/{mermaid.core-CL9g6xVu.js → mermaid.core-BIJiZKob.js} +4 -4
  60. package/web/assets/{mindmap-definition-LN4V7U3C-CtQo0XrW.js → mindmap-definition-LN4V7U3C-k97sTi1e.js} +1 -1
  61. package/web/assets/{pegDiagram-2B236MQR-ecu1L_3A.js → pegDiagram-2B236MQR-C-4ETzyd.js} +1 -1
  62. package/web/assets/{pieDiagram-ENE6RG2P-CdCKg3Cn.js → pieDiagram-ENE6RG2P-CH8gYIx3.js} +1 -1
  63. package/web/assets/{plugin-host-modules-Dz_BPJRS.js → plugin-host-modules-BI0aGGBk.js} +2 -2
  64. package/web/assets/{project-search-dialog-HJFGW4DG-CKtXc-UP.js → project-search-dialog-HJFGW4DG-DC6mBFkm.js} +1 -1
  65. package/web/assets/{project-search-page-NKQEBGPF-CMzuYEeM.js → project-search-page-NKQEBGPF-B0OxN-l5.js} +1 -1
  66. package/web/assets/{quadrantDiagram-ABIIQ3AL-Bt8r5TlW.js → quadrantDiagram-ABIIQ3AL-BFV2fyQY.js} +1 -1
  67. package/web/assets/{railroadDiagram-RFXS5EU6-DrWDVEVi.js → railroadDiagram-RFXS5EU6-Dxj8XtW1.js} +1 -1
  68. package/web/assets/{requirementDiagram-TGXJPOKE-Ewjwpo6V.js → requirementDiagram-TGXJPOKE-Drb3A2JL.js} +1 -1
  69. package/web/assets/{sankeyDiagram-HTMAVEWB-CJCMHuzX.js → sankeyDiagram-HTMAVEWB-DP7Lyg91.js} +1 -1
  70. package/web/assets/{selection-popup-532EHNCZ-py5aCy1E.js → selection-popup-532EHNCZ-C8EBNgOw.js} +1 -1
  71. package/web/assets/{sequenceDiagram-DBY2YBRQ-Chj-4L6Q.js → sequenceDiagram-DBY2YBRQ-6qzKd9e_.js} +1 -1
  72. package/web/assets/{sizeCapture-X5ZJPWSS-BguWhDIF.js → sizeCapture-X5ZJPWSS-DhCU_-w6.js} +1 -1
  73. package/web/assets/{stateDiagram-2N3HPSRC-BWisWMpK.js → stateDiagram-2N3HPSRC-C_BN15Uj.js} +1 -1
  74. package/web/assets/{stateDiagram-v2-6OUMAXLB-AiBXToz-.js → stateDiagram-v2-6OUMAXLB-DtNCoZjH.js} +1 -1
  75. package/web/assets/{swimlanes-5IMT3BWC-CxVQ97_C.js → swimlanes-5IMT3BWC-CW-FMmDB.js} +2 -2
  76. package/web/assets/swimlanesDiagram-G3AALYLV-Cak69Ty7.js +8 -0
  77. package/web/assets/{timeline-definition-FHXFAJF6-CCbI0InF.js → timeline-definition-FHXFAJF6-VX8Kq-Hg.js} +1 -1
  78. package/web/assets/{vennDiagram-L72KCM5P-mA5yKpJj.js → vennDiagram-L72KCM5P-DU3qCuRJ.js} +1 -1
  79. package/web/assets/{wardleyDiagram-EHGQE667-1Epw2EsU.js → wardleyDiagram-EHGQE667-CAA7wYyD.js} +1 -1
  80. package/web/assets/{xychartDiagram-FW5EYKEG-DM1CMD-p.js → xychartDiagram-FW5EYKEG-B-GbIjdQ.js} +1 -1
  81. package/web/index.html +2 -2
  82. package/README.md +0 -317
  83. package/web/assets/ask-tray-PMT6VVXN-HMPARq3A.js +0 -23
  84. package/web/assets/channel-CEZ4sDYU.js +0 -1
  85. package/web/assets/classDiagram-OUVF2IWQ-CjxqMQn2.js +0 -1
  86. package/web/assets/classDiagram-v2-EOCWNBFH-CjxqMQn2.js +0 -1
  87. package/web/assets/index-D_Fcgs3V.js +0 -451
  88. package/web/assets/swimlanesDiagram-G3AALYLV-DliPmGmf.js +0 -8
@@ -201,7 +201,7 @@ export async function hotViewer(options) {
201
201
  env: {
202
202
  ...process.env,
203
203
  // Explicit remote bindings (--lan) switch the Vite plugins into
204
- // remote mode: realpath root scope, host actions disabled, ACP off.
204
+ // remote mode: realpath root scope, host actions disabled.
205
205
  // KENNEL_VIEWER_HOSTS tells the config which Host headers are legit
206
206
  // (DNS-rebinding guard; loopback is always allowed).
207
207
  KENNEL_VIEWER_ROOT: options.root,
@@ -1 +1 @@
1
- export * from "kennel-preview/kinds";
1
+ export { previewKind } from "kennel-api/shared/document-kinds";
@@ -1,4 +1,4 @@
1
- // packages/kinds/src/kinds.ts
1
+ // packages/api/src/shared/document-kinds.ts
2
2
  var previewTextKinds = new Set([
3
3
  "code",
4
4
  "eml",
@@ -7,9 +7,6 @@ var previewTextKinds = new Set([
7
7
  "table",
8
8
  "text"
9
9
  ]);
10
- function previewTextKind(kind) {
11
- return previewTextKinds.has(kind);
12
- }
13
10
  var codeExtensions = new Set([
14
11
  ".astro",
15
12
  ".bash",
@@ -100,60 +97,6 @@ function previewKind(path) {
100
97
  return "binary";
101
98
  return;
102
99
  }
103
- var rawMime = {
104
- ".avif": "image/avif",
105
- ".bmp": "image/bmp",
106
- ".gif": "image/gif",
107
- ".htm": "text/html; charset=utf-8",
108
- ".html": "text/html; charset=utf-8",
109
- ".ico": "image/x-icon",
110
- ".jpeg": "image/jpeg",
111
- ".jpg": "image/jpeg",
112
- ".pdf": "application/pdf",
113
- ".png": "image/png",
114
- ".svg": "image/svg+xml",
115
- ".webp": "image/webp"
116
- };
117
- function previewRawMime(path) {
118
- const extension = path.slice(path.lastIndexOf(".")).toLowerCase();
119
- const mime = rawMime[extension];
120
- if (mime)
121
- return mime;
122
- if (previewKind(path) === "code" || previewKind(path) === "table")
123
- return "text/plain; charset=utf-8";
124
- return;
125
- }
126
- var mediaMime = {
127
- ".aac": "audio/aac",
128
- ".avif": "image/avif",
129
- ".bmp": "image/bmp",
130
- ".flac": "audio/flac",
131
- ".gif": "image/gif",
132
- ".ico": "image/x-icon",
133
- ".jpeg": "image/jpeg",
134
- ".jpg": "image/jpeg",
135
- ".m4a": "audio/mp4",
136
- ".m4v": "video/mp4",
137
- ".mov": "video/quicktime",
138
- ".mp3": "audio/mpeg",
139
- ".mp4": "video/mp4",
140
- ".oga": "audio/ogg",
141
- ".ogg": "audio/ogg",
142
- ".ogv": "video/ogg",
143
- ".opus": "audio/opus",
144
- ".png": "image/png",
145
- ".wav": "audio/wav",
146
- ".webm": "video/webm",
147
- ".webp": "image/webp"
148
- };
149
- function mediaRawMime(path) {
150
- const extension = path.slice(path.lastIndexOf(".")).toLowerCase();
151
- return mediaMime[extension];
152
- }
153
100
  export {
154
- mediaRawMime,
155
- previewKind,
156
- previewRawMime,
157
- previewTextKind,
158
- previewTextKinds
101
+ previewKind
159
102
  };
@@ -1 +1,9 @@
1
- export { openPreview, previewTerminal } from "kennel-preview/terminal";
1
+ export { openPreview } from "kennel-preview/terminal";
2
+ export declare function previewTerminal(url: string, target: {
3
+ root: string;
4
+ target?: string;
5
+ }): {
6
+ close: () => void;
7
+ closed: Promise<void>;
8
+ interactive: boolean;
9
+ };
@@ -1,7 +1,7 @@
1
1
  // packages/preview/src/terminal.ts
2
- import { execFile } from "node:child_process";
2
+ import { execFile, execFileSync } from "node:child_process";
3
3
  import { basename } from "node:path";
4
- import { emitKeypressEvents } from "node:readline";
4
+ import { clearScreenDown, cursorTo, emitKeypressEvents } from "node:readline";
5
5
  function openPreview(url) {
6
6
  const command = process.platform === "darwin" ? "/usr/bin/open" : process.platform === "win32" ? "explorer.exe" : "xdg-open";
7
7
  execFile(command, [url], (error) => {
@@ -9,17 +9,40 @@ function openPreview(url) {
9
9
  console.error(`Could not open browser: ${error.message}`);
10
10
  });
11
11
  }
12
- function previewTerminal(url, target) {
12
+ function copyPreviewLink(url) {
13
+ const command = process.platform === "darwin" ? "/usr/bin/pbcopy" : process.platform === "win32" ? "clip" : process.env.WAYLAND_DISPLAY ? "wl-copy" : "xclip";
14
+ const args = command === "xclip" ? ["-selection", "clipboard"] : [];
15
+ return new Promise((done, fail) => {
16
+ const child = execFile(command, args, (error) => error ? fail(error) : done());
17
+ child.stdin?.on("error", fail);
18
+ child.stdin?.end(url);
19
+ });
20
+ }
21
+ var terminalText = (text) => text.replace(/[\u0000-\u001f\u007f-\u009f]/g, "");
22
+ function repositoryName(folder) {
23
+ try {
24
+ const root = execFileSync("git", ["-C", folder, "rev-parse", "--show-toplevel"], {
25
+ encoding: "utf8",
26
+ stdio: ["ignore", "pipe", "ignore"],
27
+ timeout: 1000
28
+ });
29
+ return terminalText(basename(root.trim()));
30
+ } catch {
31
+ return;
32
+ }
33
+ }
34
+ function previewTerminal(url, target, startShare) {
13
35
  url = new URL(url).href;
14
36
  const input = process.stdin;
15
37
  const output = process.stdout;
16
38
  const terminal = Boolean(output.isTTY && process.env.TERM !== "dumb");
17
39
  const interactive = terminal && Boolean(input.isTTY);
18
- const name = (basename(target.target ?? target.root) || target.root).replace(/[\u0000-\u001f\u007f-\u009f]/g, "");
19
- const label = `(open ${name})`;
40
+ const name = terminalText(basename(target.target ?? target.root) || target.root);
41
+ const title = terminalText(basename(target.root) || target.root);
42
+ const repository = interactive ? repositoryName(target.root) : undefined;
20
43
  const color = terminal && process.env.NO_COLOR === undefined && output.hasColors();
21
- const accent = (text) => color ? `\x1B[36m${text}\x1B[39m` : text;
22
- const link = terminal ? `\x1B]8;;${url}\x1B\\${accent(label)}\x1B]8;;\x1B\\` : `${label}
44
+ const accent = (text) => color ? `\x1B[32m${text}\x1B[39m` : text;
45
+ const link = (label) => terminal ? `\x1B]8;;${url}\x1B\\${accent(label)}\x1B]8;;\x1B\\` : `${label}
23
46
  ${url}`;
24
47
  const wasRaw = Boolean(input.isRaw);
25
48
  const wasFlowing = input.readableFlowing === true;
@@ -28,6 +51,74 @@ function previewTerminal(url, target) {
28
51
  resolveClosed = resolve;
29
52
  });
30
53
  let finished = false;
54
+ let busy = false;
55
+ let selected = 0;
56
+ let status = "";
57
+ let share;
58
+ const render = () => {
59
+ if (!interactive || finished)
60
+ return;
61
+ cursorTo(output, 0, 0);
62
+ clearScreenDown(output);
63
+ const width = Math.max(1, (output.columns || 80) - 5);
64
+ const fit = (text) => {
65
+ const characters = Array.from(terminalText(text));
66
+ return characters.length > width ? characters.slice(0, width - 1).join("") + "…" : characters.join("");
67
+ };
68
+ const count = Math.max(1, Math.min(8, (output.rows || 24) - 12));
69
+ const start = Math.max(0, Math.min(selected - Math.floor(count / 2), actions.length - count));
70
+ const choices = actions.slice(start, start + count).map((item, index) => {
71
+ const label = fit(item.shortcut ? `[${item.shortcut}] ${item.label}` : item.label);
72
+ return start + index === selected ? accent(` › ${label}`) : ` ${label}`;
73
+ });
74
+ output.write([
75
+ ` \x1B[1m${link(fit(title))}\x1B[22m`,
76
+ ...repository ? [` ${color ? "\x1B[2m" : ""}${fit(repository)}${color ? "\x1B[22m" : ""}`] : [],
77
+ ...target.target ? [` File: ${fit(name)}`] : [],
78
+ "",
79
+ ...choices,
80
+ "",
81
+ " ↑ ↓ to move · Enter to choose · Esc or Ctrl+C to exit",
82
+ ...actions.length > count ? [` ${selected + 1} / ${actions.length}`] : [],
83
+ ...status ? ["", ` ${status}`] : [],
84
+ ""
85
+ ].join(`
86
+ `));
87
+ };
88
+ const shareFolder = async () => {
89
+ status = "Preparing a password-protected Wi-Fi link…";
90
+ render();
91
+ try {
92
+ share ??= startShare();
93
+ let active;
94
+ try {
95
+ active = await share;
96
+ } catch (error) {
97
+ share = undefined;
98
+ throw error;
99
+ }
100
+ if (finished)
101
+ return;
102
+ status = `Wi-Fi link: ${active.url}
103
+ Username: ${active.username} · Password: ${active.password}
104
+ Password required. Send the password separately. Same Wi-Fi only.
105
+ Self-signed HTTPS (24 hours): expect a certificate warning.
106
+ Verify SHA-256 before trusting the certificate:
107
+ ${active.fingerprint}
108
+ Keep this command running. Ctrl+C stops sharing.`;
109
+ render();
110
+ try {
111
+ await copyPreviewLink(active.url);
112
+ status += `
113
+ Wi-Fi link copied to clipboard (without the password).`;
114
+ } catch (error) {
115
+ status += `
116
+ Could not copy link: ${terminalText(error instanceof Error ? error.message : String(error))}`;
117
+ }
118
+ } catch (error) {
119
+ status = `Could not share folder: ${terminalText(error instanceof Error ? error.message : String(error))}`;
120
+ }
121
+ };
31
122
  const close = () => {
32
123
  if (finished)
33
124
  return;
@@ -38,40 +129,91 @@ function previewTerminal(url, target) {
38
129
  if (interactive) {
39
130
  input.off("keypress", keypress);
40
131
  input.off("end", close);
132
+ output.off("resize", render);
133
+ output.write("\x1B[?25h\x1B[?1049l");
41
134
  input.setRawMode(wasRaw);
42
135
  if (!wasFlowing)
43
136
  input.pause();
44
137
  }
45
- resolveClosed();
138
+ if (share) {
139
+ share.then((active) => active.close()).catch((error) => {
140
+ console.error(` Wi-Fi share stopped: ${error instanceof Error ? error.message : error}`);
141
+ }).finally(() => resolveClosed());
142
+ } else
143
+ resolveClosed();
144
+ };
145
+ const actions = [
146
+ { label: "Open in browser", shortcut: "o", run: () => {
147
+ openPreview(url);
148
+ status = "Browser open requested.";
149
+ } },
150
+ { label: "Share to another device", shortcut: "s", run: shareFolder },
151
+ { label: "Exit", shortcut: "q", run: close }
152
+ ];
153
+ const activate = async () => {
154
+ busy = true;
155
+ try {
156
+ await actions[selected].run();
157
+ } catch (error) {
158
+ status = `Could not complete action: ${terminalText(error instanceof Error ? error.message : String(error))}`;
159
+ } finally {
160
+ busy = false;
161
+ render();
162
+ }
46
163
  };
47
164
  const keypress = (_text, key) => {
48
- if (key.ctrl && (key.name === "c" || key.name === "d"))
165
+ if (key.name === "escape" || key.ctrl && (key.name === "c" || key.name === "d")) {
49
166
  close();
50
- else if (key.name === "o" && !key.ctrl && !key.meta)
51
- openPreview(url);
167
+ return;
168
+ }
169
+ if (busy || finished)
170
+ return;
171
+ const shortcut = !key.ctrl && !key.meta ? actions.findIndex((item) => item.shortcut === key.name) : -1;
172
+ if (shortcut !== -1) {
173
+ selected = shortcut;
174
+ activate();
175
+ return;
176
+ }
177
+ if (key.name === "up")
178
+ selected = (selected - 1 + actions.length) % actions.length;
179
+ else if (key.name === "down")
180
+ selected = (selected + 1) % actions.length;
181
+ else if (key.name === "return") {
182
+ activate();
183
+ return;
184
+ } else
185
+ return;
186
+ render();
52
187
  };
53
188
  process.once("SIGINT", close);
54
189
  process.once("SIGTERM", close);
55
190
  process.once("exit", close);
56
191
  if (interactive) {
192
+ output.write("\x1B[?1049h\x1B[?25l");
193
+ output.on("resize", render);
57
194
  emitKeypressEvents(input);
58
195
  input.setRawMode(true);
59
196
  input.on("keypress", keypress);
60
197
  input.once("end", close);
61
198
  input.resume();
62
199
  }
63
- console.log(`
64
- ${link}
65
- `);
66
- if (interactive) {
67
- console.log(` shortcuts:
68
- ${accent("o")} - open in browser
69
- ctrl+c - exit
200
+ if (interactive)
201
+ render();
202
+ else
203
+ console.log(`
204
+ ${link(name)}
70
205
  `);
71
- }
72
206
  return { close, closed, interactive };
73
207
  }
208
+
209
+ // packages/cli/src/site/terminal.ts
210
+ function previewTerminal2(url, target) {
211
+ return previewTerminal(url, target, async () => {
212
+ const { startLanShare } = await import(new URL("../package/preview.js", import.meta.url).href);
213
+ return startLanShare(target);
214
+ });
215
+ }
74
216
  export {
75
217
  openPreview,
76
- previewTerminal
218
+ previewTerminal2 as previewTerminal
77
219
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kennel",
3
- "version": "0.2.24",
3
+ "version": "0.2.26",
4
4
  "description": "Open-source pop-up previews for AI output: markdown, HTML artifacts, email, images, code, tables, notes, and calendars, from the terminal or your agent session.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -49,7 +49,8 @@
49
49
  "scripts": {
50
50
  "build": "node scripts/build.mjs",
51
51
  "typecheck": "tsc -p tsconfig.json --noEmit",
52
- "check": "npm run build && node --check bin/kennel.mjs && node --check dist/main.js",
52
+ "check": "npm run build && node --check bin/kennel.mjs && node --check dist/main.js && npm run smoke",
53
+ "smoke": "node --input-type=module -e \"await import('./dist/mcp/generate.js')\"",
53
54
  "prepack": "node scripts/build.mjs",
54
55
  "pack:check": "bun pm pack --dry-run",
55
56
  "publish:public": "npm publish --access public --registry=https://registry.npmjs.org --@raggle-ai:registry=https://registry.npmjs.org",
@@ -65,12 +66,10 @@
65
66
  "date-fns": "^4.1.0",
66
67
  "effect": "^3.19.7",
67
68
  "esbuild": "^0.27.0",
68
- "kennel-knowledge": "https://registry.npmjs.org/%40raggle-ai%2fkennel-knowledge/-/kennel-knowledge-0.1.0.tgz",
69
69
  "kennel-mcp": "https://registry.npmjs.org/%40raggle-ai%2fkennel-mcp/-/kennel-mcp-0.1.8.tgz",
70
- "kennel-plugins": "0.1.10",
70
+ "kennel-plugins": "0.1.11",
71
71
  "koffi": "^3.3.1",
72
72
  "lucide-react": "^0.562.0",
73
- "pi-acp": "0.0.33",
74
73
  "radix-ui": "^1.6.7",
75
74
  "react": "19.1.0",
76
75
  "react-dom": "19.1.0",
@@ -84,6 +83,7 @@
84
83
  },
85
84
  "devDependencies": {
86
85
  "@types/node": "^22.13.4",
86
+ "kennel-api": "0.1.0",
87
87
  "kennel-preview": "0.1.0",
88
88
  "typescript": "^5.9.3"
89
89
  },
@@ -1 +1 @@
1
- import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-zyGgx-VW.js";import{p as f}from"./chunk-JWPE2WC7-CckCaqu_.js";import{_ as n,l as o}from"./mermaid.core-CL9g6xVu.js";import{b as c,M as d}from"./cynefin-VYW2F7L2-B75MWf5b.js";import"./index-D_Fcgs3V.js";import"./react-DELVxLrX.js";import"./markdown-BP-54rPU.js";import"./tanstack-CRaSxWtK.js";var v=c().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),m=t?parseInt(t,10):0,l=s?parseInt(s,10):1/0;return{min:m,max:l}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new d(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},C={parser:R,db:a,renderer:u,styles:p};export{C as diagram};
1
+ import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-BSlB5ICN.js";import{p as f}from"./chunk-JWPE2WC7-DotlQGla.js";import{_ as n,l as o}from"./mermaid.core-BIJiZKob.js";import{b as c,M as d}from"./cynefin-VYW2F7L2-D-wd85t1.js";import"./index-DmJQJIC1.js";import"./react-DELVxLrX.js";import"./markdown-BP-54rPU.js";import"./tanstack-CRaSxWtK.js";var v=c().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),m=t?parseInt(t,10):0,l=s?parseInt(s,10):1/0;return{min:m,max:l}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new d(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},C={parser:R,db:a,renderer:u,styles:p};export{C as diagram};
@@ -1 +1 @@
1
- import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as sn,ab as on,ac as fn}from"./mermaid.core-CL9g6xVu.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,z,a){var O=I-l,i=D-h,n=z-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function U(l,h,I,D,v,A,z){var a=l-I,O=h-D,i=(z?A:-A)/J(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,B=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*J(on(0,T*T*R-P*P)),Y=(P*g-m*S)/R,$=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=Y-B,e=$-t,r=w-B,C=p-t;return x*x+e*e>r*r+C*C&&(Y=w,$=p),{cx:Y,cy:$,x01:-n,y01:-d,x11:Y*(v/T-1),y11:$*(v/T-1)}}function hn(){var l=cn,h=yn,I=j(0),D=null,v=gn,A=dn,z=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,B=rn(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(B>tn-y)a.moveTo(s*F(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*F(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=B,S=B,Y=z.apply(this,arguments)/2,$=Y>y&&(D?+D.apply(this,arguments):J(u*u+s*s)),w=_(rn(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if($>y){var C=sn($/u*q(Y)),K=sn($/s*q(Y));(P-=C*2)>y?(C*=t?1:-1,R+=C,T-=C):(P=0,R=T=(f+c)/2),(S-=K*2)>y?(K*=t?1:-1,m+=K,g-=K):(S=0,m=g=(f+c)/2)}var G=s*F(m),H=s*q(m),L=u*F(T),M=u*q(T);if(w>y){var N=s*F(g),Q=s*q(g),V=u*F(R),W=u*q(R),E;if(B<an)if(E=pn(G,H,V,W,N,Q,L,M)){var X=G-E[0],Z=H-E[1],b=N-E[0],k=Q-E[1],nn=1/q(fn((X*b+Z*k)/(J(X*X+Z*Z)*J(b*b+k*k)))/2),en=J(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=U(V,W,G,H,s,x,t),r=U(N,Q,L,M,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(G,H),a.arc(0,0,s,m,g,!t)):a.moveTo(G,H),!(u>y)||!(P>y)?a.lineTo(L,M):p>y?(e=U(L,M,N,Q,u,-p,t),r=U(G,H,V,W,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[F(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:j(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:j(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:j(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:j(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:j(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:j(+n),i):A},i.padAngle=function(n){return arguments.length?(z=typeof n=="function"?n:j(+n),i):z},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
1
+ import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as sn,ab as on,ac as fn}from"./mermaid.core-BIJiZKob.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,z,a){var O=I-l,i=D-h,n=z-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function U(l,h,I,D,v,A,z){var a=l-I,O=h-D,i=(z?A:-A)/J(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,B=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*J(on(0,T*T*R-P*P)),Y=(P*g-m*S)/R,$=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=Y-B,e=$-t,r=w-B,C=p-t;return x*x+e*e>r*r+C*C&&(Y=w,$=p),{cx:Y,cy:$,x01:-n,y01:-d,x11:Y*(v/T-1),y11:$*(v/T-1)}}function hn(){var l=cn,h=yn,I=j(0),D=null,v=gn,A=dn,z=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,B=rn(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(B>tn-y)a.moveTo(s*F(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*F(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=B,S=B,Y=z.apply(this,arguments)/2,$=Y>y&&(D?+D.apply(this,arguments):J(u*u+s*s)),w=_(rn(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if($>y){var C=sn($/u*q(Y)),K=sn($/s*q(Y));(P-=C*2)>y?(C*=t?1:-1,R+=C,T-=C):(P=0,R=T=(f+c)/2),(S-=K*2)>y?(K*=t?1:-1,m+=K,g-=K):(S=0,m=g=(f+c)/2)}var G=s*F(m),H=s*q(m),L=u*F(T),M=u*q(T);if(w>y){var N=s*F(g),Q=s*q(g),V=u*F(R),W=u*q(R),E;if(B<an)if(E=pn(G,H,V,W,N,Q,L,M)){var X=G-E[0],Z=H-E[1],b=N-E[0],k=Q-E[1],nn=1/q(fn((X*b+Z*k)/(J(X*X+Z*Z)*J(b*b+k*k)))/2),en=J(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=U(V,W,G,H,s,x,t),r=U(N,Q,L,M,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(G,H),a.arc(0,0,s,m,g,!t)):a.moveTo(G,H),!(u>y)||!(P>y)?a.lineTo(L,M):p>y?(e=U(L,M,N,Q,u,-p,t),r=U(G,H,V,W,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[F(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:j(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:j(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:j(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:j(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:j(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:j(+n),i):A},i.padAngle=function(n){return arguments.length?(z=typeof n=="function"?n:j(+n),i):z},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};