kennel 0.2.23 → 0.2.25

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 (94) hide show
  1. package/dist/cli/dispatch.js +4 -52
  2. package/dist/cli/plugin.d.ts +1 -0
  3. package/dist/cli/plugin.js +103 -0
  4. package/dist/cli/usage.js +3 -1
  5. package/dist/core/api-client.js +1 -2
  6. package/dist/core/command.js +1 -1
  7. package/dist/core/core-folders.js +6 -2
  8. package/dist/core/runtime.js +30 -4657
  9. package/dist/mcp/install-page.d.ts +1 -1
  10. package/dist/mcp/install-page.js +419 -4
  11. package/dist/package/preview.js +229 -4774
  12. package/dist/plugins/external.d.ts +32 -0
  13. package/dist/plugins/external.js +60 -1
  14. package/dist/plugins/skills.d.ts +30 -0
  15. package/dist/plugins/skills.js +175 -0
  16. package/dist/site/folder-icons.d.ts +0 -7
  17. package/dist/site/folder-icons.js +3 -21
  18. package/dist/site/hot-viewer.js +1 -1
  19. package/dist/site/kinds.d.ts +1 -1
  20. package/dist/site/kinds.js +2 -59
  21. package/package.json +5 -5
  22. package/schemas/config.schema.json +30 -0
  23. package/web/assets/{abnfDiagram-VRR7QNED-aRemVX7f.js → abnfDiagram-VRR7QNED-CIyEzNaJ.js} +1 -1
  24. package/web/assets/{arc-BpDsnNTf.js → arc-Dba3y3eW.js} +1 -1
  25. package/web/assets/{architectureDiagram-ZJ3FMSHR-DNXHQddP.js → architectureDiagram-ZJ3FMSHR-DjFjO3tR.js} +1 -1
  26. package/web/assets/ask-tray-PMT6VVXN-ButKBzsY.js +23 -0
  27. package/web/assets/{blockDiagram-677ZJIJ3-CF4H4upo.js → blockDiagram-677ZJIJ3-C8ZQgtnK.js} +1 -1
  28. package/web/assets/{c4Diagram-LMCZKHZV-BPWUnjtx.js → c4Diagram-LMCZKHZV-DhWn2tZm.js} +1 -1
  29. package/web/assets/channel-BuqSObVl.js +1 -0
  30. package/web/assets/{chunk-2Q5K7J3B-DGsa7uv7.js → chunk-2Q5K7J3B-BEkPxYAB.js} +1 -1
  31. package/web/assets/{chunk-32BRIVSS-BRfic3W2.js → chunk-32BRIVSS-BZ0ofM9m.js} +1 -1
  32. package/web/assets/{chunk-5VM5RSS4-L2h7hliu.js → chunk-5VM5RSS4-CTgBiom0.js} +1 -1
  33. package/web/assets/{chunk-EX3LRPZG-BPgD_fgx.js → chunk-EX3LRPZG-B7lDJEfz.js} +1 -1
  34. package/web/assets/{chunk-JWPE2WC7-CckCaqu_.js → chunk-JWPE2WC7-DotlQGla.js} +1 -1
  35. package/web/assets/{chunk-MOJQB5TN-zyGgx-VW.js → chunk-MOJQB5TN-BSlB5ICN.js} +1 -1
  36. package/web/assets/{chunk-RYQCIY6F-Drzpg5IG.js → chunk-RYQCIY6F-BbDvgRvj.js} +1 -1
  37. package/web/assets/{chunk-V7JOEXUC-Di4ESKz-.js → chunk-V7JOEXUC-CqC2yHBO.js} +1 -1
  38. package/web/assets/{chunk-VR4S4FIN-C5lQtDI1.js → chunk-VR4S4FIN-18aLOCVw.js} +1 -1
  39. package/web/assets/{chunk-XXDRQBXY-Cell0ft2.js → chunk-XXDRQBXY-uulB67ep.js} +1 -1
  40. package/web/assets/classDiagram-OUVF2IWQ-xfk1LZB_.js +1 -0
  41. package/web/assets/classDiagram-v2-EOCWNBFH-xfk1LZB_.js +1 -0
  42. package/web/assets/{cose-bilkent-JH36ORCC-CiKtOFxl.js → cose-bilkent-JH36ORCC-C8yqL7ml.js} +1 -1
  43. package/web/assets/{cynefin-VYW2F7L2-B75MWf5b.js → cynefin-VYW2F7L2-D-wd85t1.js} +1 -1
  44. package/web/assets/{cynefinDiagram-TSTJHNR4-BmNVkSWW.js → cynefinDiagram-TSTJHNR4-rrV6rLov.js} +1 -1
  45. package/web/assets/{dagre-VKFMJZFB-BcM1Wqu5.js → dagre-VKFMJZFB-BxwiLhMr.js} +1 -1
  46. package/web/assets/{diagram-FQU43EPY-BiBWrxa8.js → diagram-FQU43EPY-8sr7lcj4.js} +1 -1
  47. package/web/assets/{diagram-G47NLZAW-Cfxukr7T.js → diagram-G47NLZAW-BQIU_Mie.js} +1 -1
  48. package/web/assets/{diagram-NH7WQ7WH-C83VkBYW.js → diagram-NH7WQ7WH-Bt-xVbVq.js} +1 -1
  49. package/web/assets/{diagram-OA4YK3LP-Oj0uj6CX.js → diagram-OA4YK3LP-p-i-3cps.js} +1 -1
  50. package/web/assets/{diagram-WEI45ONY-DhbL0nvt.js → diagram-WEI45ONY-E6t6-_mU.js} +1 -1
  51. package/web/assets/{ebnfDiagram-CCIWWBDH-D4JYp1UC.js → ebnfDiagram-CCIWWBDH-DCszfyU3.js} +1 -1
  52. package/web/assets/{entity-search-page-G6QEQNXT-UKzUU5id.js → entity-search-page-G6QEQNXT-D6cvoqrF.js} +1 -1
  53. package/web/assets/{erDiagram-Q63AITRT-C-oyRt9s.js → erDiagram-Q63AITRT-C4gBewIM.js} +1 -1
  54. package/web/assets/{flowDiagram-23GEKE2U-0Tplj9FK.js → flowDiagram-23GEKE2U-BEyFAV-g.js} +1 -1
  55. package/web/assets/{ganttDiagram-NO4QXBWP-wgh2e0B_.js → ganttDiagram-NO4QXBWP-Bat5BF2x.js} +1 -1
  56. package/web/assets/{gitGraphDiagram-IHSO6WYX-D6z9qDXa.js → gitGraphDiagram-IHSO6WYX-CGZs8b5E.js} +1 -1
  57. package/web/assets/index-DmJQJIC1.js +451 -0
  58. package/web/assets/{index-BGwTWQMJ.css → index-tpV2etC4.css} +1 -1
  59. package/web/assets/{infoDiagram-FWYZ7A6U-D3o7el5X.js → infoDiagram-FWYZ7A6U-Cglwuazb.js} +1 -1
  60. package/web/assets/{ishikawaDiagram-FXEZZL3T-CM0QyWYH.js → ishikawaDiagram-FXEZZL3T-C95-Gz9z.js} +1 -1
  61. package/web/assets/{journeyDiagram-5HDEW3XC-fmIoh0h6.js → journeyDiagram-5HDEW3XC-C055Trr6.js} +1 -1
  62. package/web/assets/{kanban-definition-HUTT4EX6-aEtqsiWf.js → kanban-definition-HUTT4EX6-CznSv3_t.js} +1 -1
  63. package/web/assets/{linear-aJ-2UZO5.js → linear-CnWGyi6E.js} +1 -1
  64. package/web/assets/{linked-session-header-M7WY6IGF-CltMJZiX.js → linked-session-header-M7WY6IGF-BFioq_q7.js} +1 -1
  65. package/web/assets/{mermaid.core-CL9g6xVu.js → mermaid.core-BIJiZKob.js} +4 -4
  66. package/web/assets/{mindmap-definition-LN4V7U3C-CtQo0XrW.js → mindmap-definition-LN4V7U3C-k97sTi1e.js} +1 -1
  67. package/web/assets/{pegDiagram-2B236MQR-ecu1L_3A.js → pegDiagram-2B236MQR-C-4ETzyd.js} +1 -1
  68. package/web/assets/{pieDiagram-ENE6RG2P-CdCKg3Cn.js → pieDiagram-ENE6RG2P-CH8gYIx3.js} +1 -1
  69. package/web/assets/{plugin-host-modules-Dz_BPJRS.js → plugin-host-modules-BI0aGGBk.js} +2 -2
  70. package/web/assets/{project-search-dialog-HJFGW4DG-CKtXc-UP.js → project-search-dialog-HJFGW4DG-DC6mBFkm.js} +1 -1
  71. package/web/assets/{project-search-page-NKQEBGPF-CMzuYEeM.js → project-search-page-NKQEBGPF-B0OxN-l5.js} +1 -1
  72. package/web/assets/{quadrantDiagram-ABIIQ3AL-Bt8r5TlW.js → quadrantDiagram-ABIIQ3AL-BFV2fyQY.js} +1 -1
  73. package/web/assets/{railroadDiagram-RFXS5EU6-DrWDVEVi.js → railroadDiagram-RFXS5EU6-Dxj8XtW1.js} +1 -1
  74. package/web/assets/{requirementDiagram-TGXJPOKE-Ewjwpo6V.js → requirementDiagram-TGXJPOKE-Drb3A2JL.js} +1 -1
  75. package/web/assets/{sankeyDiagram-HTMAVEWB-CJCMHuzX.js → sankeyDiagram-HTMAVEWB-DP7Lyg91.js} +1 -1
  76. package/web/assets/{selection-popup-532EHNCZ-py5aCy1E.js → selection-popup-532EHNCZ-C8EBNgOw.js} +1 -1
  77. package/web/assets/{sequenceDiagram-DBY2YBRQ-Chj-4L6Q.js → sequenceDiagram-DBY2YBRQ-6qzKd9e_.js} +1 -1
  78. package/web/assets/{sizeCapture-X5ZJPWSS-BguWhDIF.js → sizeCapture-X5ZJPWSS-DhCU_-w6.js} +1 -1
  79. package/web/assets/{stateDiagram-2N3HPSRC-BWisWMpK.js → stateDiagram-2N3HPSRC-C_BN15Uj.js} +1 -1
  80. package/web/assets/{stateDiagram-v2-6OUMAXLB-AiBXToz-.js → stateDiagram-v2-6OUMAXLB-DtNCoZjH.js} +1 -1
  81. package/web/assets/{swimlanes-5IMT3BWC-CxVQ97_C.js → swimlanes-5IMT3BWC-CW-FMmDB.js} +2 -2
  82. package/web/assets/swimlanesDiagram-G3AALYLV-Cak69Ty7.js +8 -0
  83. package/web/assets/{timeline-definition-FHXFAJF6-CCbI0InF.js → timeline-definition-FHXFAJF6-VX8Kq-Hg.js} +1 -1
  84. package/web/assets/{vennDiagram-L72KCM5P-mA5yKpJj.js → vennDiagram-L72KCM5P-DU3qCuRJ.js} +1 -1
  85. package/web/assets/{wardleyDiagram-EHGQE667-1Epw2EsU.js → wardleyDiagram-EHGQE667-CAA7wYyD.js} +1 -1
  86. package/web/assets/{xychartDiagram-FW5EYKEG-DM1CMD-p.js → xychartDiagram-FW5EYKEG-B-GbIjdQ.js} +1 -1
  87. package/web/index.html +2 -2
  88. package/README.md +0 -317
  89. package/web/assets/ask-tray-PMT6VVXN-HMPARq3A.js +0 -23
  90. package/web/assets/channel-CEZ4sDYU.js +0 -1
  91. package/web/assets/classDiagram-OUVF2IWQ-CjxqMQn2.js +0 -1
  92. package/web/assets/classDiagram-v2-EOCWNBFH-CjxqMQn2.js +0 -1
  93. package/web/assets/index-D_Fcgs3V.js +0 -451
  94. package/web/assets/swimlanesDiagram-G3AALYLV-DliPmGmf.js +0 -8
@@ -1,6 +1,4 @@
1
- import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
2
- import { dirname, resolve } from 'node:path';
3
- import { fileURLToPath } from 'node:url';
1
+ import { existsSync } from 'node:fs';
4
2
  import { usage } from './usage.js';
5
3
  export async function dispatch(argv) {
6
4
  const [, , command, ...args] = argv;
@@ -13,55 +11,9 @@ export async function dispatch(argv) {
13
11
  await viewer([]);
14
12
  return;
15
13
  }
16
- if (command === 'plugin' && args[0] === 'add') {
17
- const url = args[1];
18
- let directory;
19
- for (let index = 2; index < args.length; index += 1) {
20
- const arg = args[index];
21
- if (arg === '--path' || arg === '--directory') {
22
- directory = args[index + 1];
23
- if (!directory)
24
- throw new Error(`${arg} requires a plugin subdirectory`);
25
- index += 1;
26
- }
27
- else {
28
- throw new Error('Usage: kennel plugin add <git-repository-url-or-local-path> [--path <subdirectory>]');
29
- }
30
- }
31
- if (!url)
32
- throw new Error('Usage: kennel plugin add <git-repository-url-or-local-path> [--path <subdirectory>]');
33
- const { installExternalPlugin } = await import('../plugins/external.js');
34
- const plugin = await installExternalPlugin(url, { directory });
35
- const source = plugin.path ?? plugin.url;
36
- console.log(`Installed plugin ${plugin.id} from ${source} at ${plugin.commit}`);
37
- return;
38
- }
39
- if (command === 'plugin' && args[0] === 'new') {
40
- const id = args[1];
41
- if (!id || args.length > 2)
42
- throw new Error('Usage: kennel plugin new <id>');
43
- if (!/^[a-z][a-z0-9-]*$/u.test(id))
44
- throw new Error(`Invalid plugin id: ${id}`);
45
- const target = resolve(id);
46
- if (existsSync(target))
47
- throw new Error(`Refusing to overwrite existing path: ${target}`);
48
- const root = resolve(dirname(fileURLToPath(import.meta.url)), '../..');
49
- const template = resolve(root, 'templates/plugin');
50
- mkdirSync(target, { recursive: true });
51
- cpSync(template, target, { recursive: true });
52
- const replacePlaceholders = (folder) => {
53
- for (const name of readdirSync(folder)) {
54
- const path = resolve(folder, name);
55
- if (statSync(path).isDirectory()) {
56
- replacePlaceholders(path);
57
- continue;
58
- }
59
- const content = readFileSync(path, 'utf8').replaceAll('__PLUGIN_ID__', id);
60
- writeFileSync(path, content);
61
- }
62
- };
63
- replacePlaceholders(target);
64
- console.log(`Created Kennel plugin ${id} in ${target}`);
14
+ if (command === 'plugin') {
15
+ const { plugin } = await import('./plugin.js');
16
+ await plugin(args);
65
17
  return;
66
18
  }
67
19
  if (command === 'core') {
@@ -0,0 +1 @@
1
+ export declare function plugin(args: string[]): Promise<void>;
@@ -0,0 +1,103 @@
1
+ import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
2
+ import { dirname, resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ const USAGE = `Usage:
5
+ kennel plugin add <git-repository-url-or-local-path> [--path <subdirectory>] [--install-skill]
6
+ kennel plugin skill install <plugin-id> [--force]
7
+ kennel plugin list
8
+ kennel plugin new <id>`;
9
+ function usageError() {
10
+ throw new Error(USAGE);
11
+ }
12
+ async function installSkill(id, force) {
13
+ const { installPluginSkill } = await import('../plugins/external.js');
14
+ const skill = installPluginSkill(id, { force });
15
+ console.log(`Installed skill ${skill.name} at ${skill.path} (commit ${skill.commit})`);
16
+ for (const duplicate of skill.duplicates) {
17
+ console.warn(`Warning: another skill named ${skill.name} exists at ${duplicate}; Kennel did not change it.`);
18
+ }
19
+ }
20
+ export async function plugin(args) {
21
+ const [subcommand, ...rest] = args;
22
+ if (subcommand === 'new') {
23
+ const id = rest[0];
24
+ if (!id || rest.length > 1)
25
+ throw new Error('Usage: kennel plugin new <id>');
26
+ if (!/^[a-z][a-z0-9-]*$/u.test(id))
27
+ throw new Error(`Invalid plugin id: ${id}`);
28
+ const target = resolve(id);
29
+ if (existsSync(target))
30
+ throw new Error(`Refusing to overwrite existing path: ${target}`);
31
+ const root = resolve(dirname(fileURLToPath(import.meta.url)), '../..');
32
+ const template = resolve(root, 'templates/plugin');
33
+ mkdirSync(target, { recursive: true });
34
+ cpSync(template, target, { recursive: true });
35
+ const replacePlaceholders = (folder) => {
36
+ for (const name of readdirSync(folder)) {
37
+ const path = resolve(folder, name);
38
+ if (statSync(path).isDirectory()) {
39
+ replacePlaceholders(path);
40
+ continue;
41
+ }
42
+ const content = readFileSync(path, 'utf8').replaceAll('__PLUGIN_ID__', id);
43
+ writeFileSync(path, content);
44
+ }
45
+ };
46
+ replacePlaceholders(target);
47
+ console.log(`Created Kennel plugin ${id} in ${target}`);
48
+ return;
49
+ }
50
+ if (subcommand === 'add') {
51
+ const [url, ...flags] = rest;
52
+ let directory;
53
+ let withSkill = false;
54
+ for (let index = 0; index < flags.length; index += 1) {
55
+ const arg = flags[index];
56
+ if (arg === '--path' || arg === '--directory') {
57
+ directory = flags[index + 1];
58
+ if (!directory)
59
+ throw new Error(`${arg} requires a plugin subdirectory`);
60
+ index += 1;
61
+ }
62
+ else if (arg === '--install-skill') {
63
+ withSkill = true;
64
+ }
65
+ else {
66
+ usageError();
67
+ }
68
+ }
69
+ if (!url || url.startsWith('-'))
70
+ usageError();
71
+ const { installExternalPlugin } = await import('../plugins/external.js');
72
+ const entry = await installExternalPlugin(url, { directory });
73
+ console.log(`Installed plugin ${entry.id} from ${entry.path ?? entry.url} at ${entry.commit}`);
74
+ if (withSkill)
75
+ await installSkill(entry.id, false);
76
+ else if (entry.skill)
77
+ console.log(`Plugin declares skill ${entry.skill.name}; install it with \`kennel plugin skill install ${entry.id}\``);
78
+ return;
79
+ }
80
+ if (subcommand === 'skill' && rest[0] === 'install') {
81
+ const [, id, ...flags] = rest;
82
+ if (!id || id.startsWith('-') || flags.some((flag) => flag !== '--force'))
83
+ usageError();
84
+ await installSkill(id, flags.includes('--force'));
85
+ return;
86
+ }
87
+ if (subcommand === 'list' && rest.length === 0) {
88
+ const { listPluginStatus } = await import('../plugins/external.js');
89
+ const plugins = listPluginStatus();
90
+ if (plugins.length === 0) {
91
+ console.log('No external plugins installed.');
92
+ return;
93
+ }
94
+ for (const item of plugins) {
95
+ const skill = item.skill.name
96
+ ? `skill ${item.skill.name}: ${item.skill.state} (${item.skill.path})`
97
+ : 'skill: missing (none declared)';
98
+ console.log(`${item.id}\t${item.packageName}@${item.commit.slice(0, 12)}\t${skill}`);
99
+ }
100
+ return;
101
+ }
102
+ usageError();
103
+ }
package/dist/cli/usage.js CHANGED
@@ -2,7 +2,9 @@ export function usage() {
2
2
  console.log(`Usage:
3
3
  knl core [folder] [--host <host>] [--port <port>] [--api-only] [--web-root <dir>]
4
4
  kennel init [path] [--plugin <id>] [--force] [--list]
5
- kennel plugin add <git-repository-url-or-local-path> [--path <subdirectory>]
5
+ kennel plugin add <git-repository-url-or-local-path> [--path <subdirectory>] [--install-skill]
6
+ kennel plugin skill install <plugin-id> [--force]
7
+ kennel plugin list
6
8
  kennel plugin new <id>
7
9
  kennel core-folders [path] [--json]
8
10
  kennel [folder] [--host <host>] [--port <port>] [--lan|--tailscale]
@@ -5003,7 +5003,7 @@ var coreCollectionUiSchema = object({
5003
5003
  primaryField: string2(),
5004
5004
  secondaryField: string2().optional(),
5005
5005
  filters: array(string2()),
5006
- numericFilters: array(string2()),
5006
+ numericFilters: array(string2()).default([]),
5007
5007
  sort: array(coreCollectionSortSchema).optional()
5008
5008
  });
5009
5009
  var collectionSummarySchema = object({
@@ -5215,7 +5215,6 @@ var routes = {
5215
5215
  method: "get",
5216
5216
  query: emptyQuery,
5217
5217
  response: object({
5218
- acp: boolean2(),
5219
5218
  download: boolean2(),
5220
5219
  hostActions: _enum(["local", "none"]),
5221
5220
  local: boolean2(),
@@ -11,7 +11,7 @@ export async function core(args) {
11
11
  for (let index = 0; index < args.length; index++) {
12
12
  const arg = args[index];
13
13
  if (arg === "--help" || arg === "-h") {
14
- console.log("Usage: knl core [folder] [--port 5181] [--host 127.0.0.1] [--api-only] [--web-root dir]\nNon-loopback hosts restrict reads to folder and disable host actions/ACP.\n--web-root serves another host page (for example a desktop shell) instead of the web app.");
14
+ console.log("Usage: knl core [folder] [--port 5181] [--host 127.0.0.1] [--api-only] [--web-root dir]\nNon-loopback hosts restrict reads to folder and disable host actions.\n--web-root serves another host page (for example a desktop shell) instead of the web app.");
15
15
  return;
16
16
  }
17
17
  if (arg === "--api-only") {
@@ -20574,7 +20574,7 @@ var coreCollectionUiSchema = object({
20574
20574
  primaryField: string2(),
20575
20575
  secondaryField: string2().optional(),
20576
20576
  filters: array(string2()),
20577
- numericFilters: array(string2()),
20577
+ numericFilters: array(string2()).default([]),
20578
20578
  sort: array(coreCollectionSortSchema).optional()
20579
20579
  });
20580
20580
  var collectionSummarySchema = object({
@@ -20683,8 +20683,11 @@ import { BlockList, isIP } from "node:net";
20683
20683
  // packages/schemas/src/data/icon-image.ts
20684
20684
  import { constants } from "node:fs";
20685
20685
  import { open } from "node:fs/promises";
20686
- import sharp from "sharp";
20687
20686
  var maxIconBytes = 512 * 1024;
20687
+ var importRuntime = new Function("specifier", "return import(specifier)");
20688
+ async function loadSharp() {
20689
+ return (await importRuntime("sharp")).default;
20690
+ }
20688
20691
  async function readIconFile(path) {
20689
20692
  const file = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW).catch(() => {
20690
20693
  return;
@@ -20712,6 +20715,7 @@ async function normalizeIcon(data) {
20712
20715
  if (!data.length || data.length > maxIconBytes)
20713
20716
  return;
20714
20717
  try {
20718
+ const sharp = await loadSharp();
20715
20719
  const image = sharp(data, {
20716
20720
  limitInputPixels: 1024 * 1024,
20717
20721
  failOn: "warning"