@kodax-ai/kodax 0.7.95 → 0.7.96-alpha.2

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 (163) hide show
  1. package/CHANGELOG.md +178 -1
  2. package/LICENSE +158 -158
  3. package/README.md +149 -24
  4. package/README_CN.md +117 -24
  5. package/config-templates/config.example.jsonc +2 -1
  6. package/config-templates/integrations/a2a.example.jsonc +91 -91
  7. package/config-templates/integrations/extensions.example.jsonc +7 -7
  8. package/config-templates/integrations/mcp.example.jsonc +16 -16
  9. package/dist/builtin/code-review/SKILL.md +82 -82
  10. package/dist/builtin/git-workflow/SKILL.md +84 -84
  11. package/dist/builtin/skill-creator/SKILL.md +127 -127
  12. package/dist/builtin/skill-creator/agents/analyzer.md +12 -12
  13. package/dist/builtin/skill-creator/agents/comparator.md +13 -13
  14. package/dist/builtin/skill-creator/agents/grader.md +13 -13
  15. package/dist/builtin/skill-creator/references/schemas.md +227 -227
  16. package/dist/builtin/skill-creator/scripts/aggregate-benchmark.d.ts +46 -46
  17. package/dist/builtin/skill-creator/scripts/aggregate-benchmark.js +208 -208
  18. package/dist/builtin/skill-creator/scripts/analyze-benchmark.d.ts +46 -46
  19. package/dist/builtin/skill-creator/scripts/analyze-benchmark.js +286 -286
  20. package/dist/builtin/skill-creator/scripts/compare-runs.d.ts +62 -62
  21. package/dist/builtin/skill-creator/scripts/compare-runs.js +330 -330
  22. package/dist/builtin/skill-creator/scripts/generate-review.d.ts +33 -33
  23. package/dist/builtin/skill-creator/scripts/generate-review.js +414 -414
  24. package/dist/builtin/skill-creator/scripts/grade-evals.d.ts +73 -73
  25. package/dist/builtin/skill-creator/scripts/grade-evals.js +402 -402
  26. package/dist/builtin/skill-creator/scripts/improve-description.d.ts +23 -23
  27. package/dist/builtin/skill-creator/scripts/improve-description.js +160 -160
  28. package/dist/builtin/skill-creator/scripts/init-skill.d.ts +14 -14
  29. package/dist/builtin/skill-creator/scripts/init-skill.js +155 -155
  30. package/dist/builtin/skill-creator/scripts/install-skill.d.ts +29 -29
  31. package/dist/builtin/skill-creator/scripts/install-skill.js +173 -173
  32. package/dist/builtin/skill-creator/scripts/package-skill.d.ts +38 -38
  33. package/dist/builtin/skill-creator/scripts/package-skill.js +121 -121
  34. package/dist/builtin/skill-creator/scripts/quick-validate.d.ts +8 -8
  35. package/dist/builtin/skill-creator/scripts/quick-validate.js +163 -163
  36. package/dist/builtin/skill-creator/scripts/run-eval.d.ts +66 -66
  37. package/dist/builtin/skill-creator/scripts/run-eval.js +353 -353
  38. package/dist/builtin/skill-creator/scripts/run-loop.d.ts +49 -49
  39. package/dist/builtin/skill-creator/scripts/run-loop.js +242 -242
  40. package/dist/builtin/skill-creator/scripts/run-trigger-eval.d.ts +58 -58
  41. package/dist/builtin/skill-creator/scripts/run-trigger-eval.js +224 -224
  42. package/dist/builtin/tdd/SKILL.md +56 -56
  43. package/dist/chunks/agent-4FABF6WK.js +2 -0
  44. package/dist/chunks/argument-completer-72VHB2VL.js +2 -0
  45. package/dist/chunks/{chunk-7JXA3533.js → chunk-4OIQZWA5.js} +223 -226
  46. package/dist/chunks/{chunk-BNVSKIAB.js → chunk-6BVF3HZ7.js} +136 -136
  47. package/dist/chunks/chunk-7JZZIFZH.js +501 -0
  48. package/dist/chunks/chunk-AC7Z2OIY.js +2 -0
  49. package/dist/chunks/{chunk-JS452J2F.js → chunk-C4KYZAFU.js} +2 -2
  50. package/dist/chunks/chunk-CHUPIWIF.js +251 -0
  51. package/dist/chunks/{chunk-C4DTUKTR.js → chunk-GYUU7XLH.js} +5 -4
  52. package/dist/chunks/{chunk-OK4AXDC5.js → chunk-HAX55GOQ.js} +1 -1
  53. package/dist/chunks/chunk-JKTJCGO2.js +418 -0
  54. package/dist/chunks/{chunk-O743AJ5V.js → chunk-LQYETRFK.js} +171 -175
  55. package/dist/chunks/{chunk-2PEDBGKN.js → chunk-LTUZTQ6W.js} +1 -1
  56. package/dist/chunks/chunk-LYWDUSKO.js +2 -0
  57. package/dist/chunks/chunk-NGH6T4FD.js +92 -0
  58. package/dist/chunks/{chunk-SRIJX5ZP.js → chunk-NVRWCSA5.js} +1 -1
  59. package/dist/chunks/chunk-O4DS7RIQ.js +384 -0
  60. package/dist/chunks/chunk-ORXU6OWZ.js +2 -0
  61. package/dist/chunks/chunk-POTW3O65.js +124 -0
  62. package/dist/chunks/{chunk-2TM3W3GK.js → chunk-RIQSS56Y.js} +1 -1
  63. package/dist/chunks/chunk-U27XKEN5.js +407 -0
  64. package/dist/chunks/{chunk-6ABQJUK6.js → chunk-XUX6OUCA.js} +2 -2
  65. package/dist/chunks/{client-JDOS3YJR.js → client-4C456K4O.js} +1 -1
  66. package/dist/chunks/compaction-config-3VQRDFF4.js +2 -0
  67. package/dist/chunks/{construction-bootstrap-YCWHHUYO.js → construction-bootstrap-AHN7EDGG.js} +1 -1
  68. package/dist/chunks/dist-BCBQXAGI.js +2 -0
  69. package/dist/chunks/dist-QK2YDWU6.js +2 -0
  70. package/dist/chunks/host-VIHV7ADG.js +2 -0
  71. package/dist/chunks/run-manager-NBVMU3KV.js +2 -0
  72. package/dist/chunks/utils-MEJZ2IGI.js +2 -0
  73. package/dist/index.d.ts +22 -21
  74. package/dist/index.js +7 -7
  75. package/dist/kodax_bootstrap.js +26 -26
  76. package/dist/kodax_cli.js +1905 -1882
  77. package/dist/native/darwin-arm64/LICENSE-APACHE.txt +13 -0
  78. package/dist/native/darwin-arm64/kodax-text-transaction.node +0 -0
  79. package/dist/native/darwin-arm64/manifest.json +16 -0
  80. package/dist/native/darwin-x64/LICENSE-APACHE.txt +13 -0
  81. package/dist/native/darwin-x64/kodax-text-transaction.node +0 -0
  82. package/dist/native/darwin-x64/manifest.json +16 -0
  83. package/dist/native/linux-arm64/LICENSE-APACHE.txt +13 -0
  84. package/dist/native/linux-arm64/kodax-text-transaction.node +0 -0
  85. package/dist/native/linux-arm64/manifest.json +16 -0
  86. package/dist/native/linux-x64/LICENSE-APACHE.txt +13 -0
  87. package/dist/native/linux-x64/kodax-text-transaction.node +0 -0
  88. package/dist/native/linux-x64/manifest.json +16 -0
  89. package/dist/native/win32-x64/LICENSE-APACHE.txt +13 -0
  90. package/dist/native/win32-x64/NOTICE-windows-sandbox.txt +8 -0
  91. package/dist/native/win32-x64/kodax-windows-sandbox.exe +0 -0
  92. package/dist/native/win32-x64/kodax-windows-text-transaction.node +0 -0
  93. package/dist/native/win32-x64/manifest.json +30 -0
  94. package/dist/provider-capabilities.json +108 -2
  95. package/dist/runtime-worker.js +1745 -1727
  96. package/dist/sandbox-network-broker.js +1715 -0
  97. package/dist/sdk-a2a.d.ts +13 -12
  98. package/dist/sdk-a2a.js +1 -1
  99. package/dist/sdk-agent.d.ts +27 -18
  100. package/dist/sdk-agent.js +1 -1
  101. package/dist/sdk-coding.d.ts +107 -58
  102. package/dist/sdk-coding.js +1 -1
  103. package/dist/sdk-experimental-memory.d.ts +4 -4
  104. package/dist/sdk-experimental-memory.js +1 -1
  105. package/dist/sdk-llm.d.ts +9 -10
  106. package/dist/sdk-llm.js +1 -1
  107. package/dist/sdk-mcp.js +1 -1
  108. package/dist/sdk-media.d.ts +1 -1
  109. package/dist/sdk-media.js +1 -1
  110. package/dist/sdk-repl.d.ts +25 -17
  111. package/dist/sdk-repl.js +1 -1
  112. package/dist/sdk-runtime.d.ts +41 -17
  113. package/dist/sdk-runtime.js +1 -1
  114. package/dist/sdk-sandbox.d.ts +17 -3
  115. package/dist/sdk-sandbox.js +1 -1
  116. package/dist/sdk-session.d.ts +8 -7
  117. package/dist/sdk-session.js +1 -1
  118. package/dist/sdk-skills.js +1 -1
  119. package/dist/semantic-worker.js +61 -61
  120. package/dist/types-chunks/{base.d-vopO1rml.d.ts → base.d-COo8E2dk.d.ts} +18 -27
  121. package/dist/types-chunks/{bash-prefix-extractor.d-B2rxNI4L.d.ts → bash-prefix-extractor.d-DQOlA8cy.d.ts} +72 -52
  122. package/dist/types-chunks/{capability-learning.d-CE1tm29C.d.ts → capability-learning.d-lRPgA3Or.d.ts} +1 -1
  123. package/dist/types-chunks/{capsule.d-Y7QRS4J2.d.ts → capsule.d-0zxsgXg_.d.ts} +3 -3
  124. package/dist/types-chunks/{controller.d-BR-UVeUR.d.ts → controller.d-BTtyIIC1.d.ts} +1 -1
  125. package/dist/types-chunks/{controller.d-C5noq5-w.d.ts → controller.d-C7tXUcXo.d.ts} +2 -2
  126. package/dist/types-chunks/{guardrail.d-DqHD-61O.d.ts → guardrail.d-DKTyEHJa.d.ts} +5 -5
  127. package/dist/types-chunks/{history-retrieval.d-CKU8zmt_.d.ts → history-retrieval.d-CHnL99S7.d.ts} +2 -2
  128. package/dist/types-chunks/{public-api.d-D7fXaWW8.d.ts → public-api.d-Dx3L3W4Z.d.ts} +7 -4
  129. package/dist/types-chunks/{repl.d-BYDb14s6.d.ts → repl.d-mO01olIa.d.ts} +5 -5
  130. package/dist/types-chunks/{resolver.d-CwHUwbdE.d.ts → resolver.d-DlXPjeyx.d.ts} +38 -6
  131. package/dist/types-chunks/{review-inbox.d-BSgFewyj.d.ts → review-inbox.d-WDSe1nze.d.ts} +1 -1
  132. package/dist/types-chunks/{run-manager.d-BVJSntpS.d.ts → run-manager.d-DENbbzgR.d.ts} +1 -1
  133. package/dist/types-chunks/{sdk-session-CqEG84oP.d.ts → sdk-session-DYHGXXH4.d.ts} +3 -3
  134. package/dist/types-chunks/{shell-command-sets.d-DqaaBwhU.d.ts → shell-command-sets.d-CjFqS4dp.d.ts} +1 -1
  135. package/dist/types-chunks/{side-query.d-iH0P9ASy.d.ts → side-query.d-j8A3sFv_.d.ts} +2 -2
  136. package/dist/types-chunks/{types.d-rUOjXych.d.ts → types.d-BbZjR0Wr.d.ts} +1 -1
  137. package/dist/types-chunks/{types.d-CaTXAW_Q.d.ts → types.d-BkTIKdH6.d.ts} +2 -2
  138. package/dist/types-chunks/{types.d-C5xQEFcj.d.ts → types.d-DncLrpu_.d.ts} +4 -4
  139. package/dist/types-chunks/{types.d-CK9A9rpP.d.ts → types.d-Xy0f3x4i.d.ts} +9 -0
  140. package/dist/types-chunks/{utils.d-CWUyLiXo.d.ts → utils.d-CnxefMos.d.ts} +6 -6
  141. package/package.json +10 -3
  142. package/public_docs/README.md +130 -0
  143. package/public_docs/configuration/sandbox.md +289 -0
  144. package/public_docs/sdk/embedder-guide.md +6674 -0
  145. package/scripts/kodax-bin.cjs +28 -28
  146. package/scripts/production-env.cjs +25 -25
  147. package/dist/chunks/agent-XXZMXKKA.js +0 -2
  148. package/dist/chunks/argument-completer-KCYDGTQW.js +0 -2
  149. package/dist/chunks/chunk-77PNP27P.js +0 -92
  150. package/dist/chunks/chunk-7QBWHCIZ.js +0 -2
  151. package/dist/chunks/chunk-BHE66SP3.js +0 -123
  152. package/dist/chunks/chunk-BR2OSB2I.js +0 -722
  153. package/dist/chunks/chunk-DSMONSVB.js +0 -407
  154. package/dist/chunks/chunk-Q5VRWSKG.js +0 -418
  155. package/dist/chunks/chunk-XWRPOGJN.js +0 -4
  156. package/dist/chunks/chunk-Y5VIQBT6.js +0 -383
  157. package/dist/chunks/compaction-config-EGS4577X.js +0 -2
  158. package/dist/chunks/dist-ITTXQHRJ.js +0 -2
  159. package/dist/chunks/dist-KFYN3OKD.js +0 -2
  160. package/dist/chunks/host-VAYADIPW.js +0 -2
  161. package/dist/chunks/run-manager-52IJZMZJ.js +0 -2
  162. package/dist/chunks/utils-P7PBSL3R.js +0 -2
  163. package/dist/sandbox-workspace-session.js +0 -1705
@@ -1,177 +1,177 @@
1
- #!/usr/bin/env node
2
-
3
- import { cp, mkdir, readFile, rm, stat, writeFile } from 'node:fs/promises';
4
- import path from 'node:path';
5
- import { fileURLToPath } from 'node:url';
6
- import { strFromU8, unzipSync } from 'fflate';
7
- import { validateSkillDirectory } from './quick-validate.js';
8
- import { getDefaultSkillsDir, parseSkillMarkdown, pathExists } from './utils.js';
9
-
10
- const PACKAGE_MANIFEST_PATH = '.kodax-package.json';
11
-
12
- function normalizeArchivePath(relativePath) {
13
- return relativePath.replace(/\\/g, '/').replace(/^\.?\//, '');
14
- }
15
-
16
- function assertSafeArchivePath(relativePath) {
17
- const normalized = normalizeArchivePath(relativePath);
18
- if (!normalized || normalized.startsWith('/') || normalized.includes('../')) {
19
- throw new Error(`Unsafe archive entry path: ${relativePath}`);
20
- }
21
- return normalized;
22
- }
23
-
24
- function isZipLike(filePath) {
25
- return /\.(skill|zip)$/i.test(filePath);
26
- }
27
-
28
- export function readSkillPackageBuffer(buffer) {
29
- const archive = unzipSync(buffer);
30
- const entries = Object.entries(archive).map(([relativePath, bytes]) => ({
31
- relativePath: assertSafeArchivePath(relativePath),
32
- bytes,
33
- }));
34
-
35
- const skillEntry = entries.find((entry) => entry.relativePath === 'SKILL.md');
36
- if (!skillEntry) {
37
- throw new Error('Archive is missing SKILL.md');
38
- }
39
-
40
- const parsedSkill = parseSkillMarkdown(strFromU8(skillEntry.bytes));
41
- const skillName = typeof parsedSkill.frontmatter.name === 'string'
42
- ? parsedSkill.frontmatter.name.trim()
43
- : '';
44
- const description = typeof parsedSkill.frontmatter.description === 'string'
45
- ? parsedSkill.frontmatter.description.trim()
46
- : '';
47
- if (!skillName || !description) {
48
- throw new Error('Archive SKILL.md is missing required frontmatter fields.');
49
- }
50
-
51
- const manifestEntry = entries.find((entry) => entry.relativePath === PACKAGE_MANIFEST_PATH);
52
- const manifest = manifestEntry
53
- ? JSON.parse(strFromU8(manifestEntry.bytes))
54
- : null;
55
-
56
- return {
57
- skillName,
58
- manifest,
59
- entries: entries.filter((entry) => entry.relativePath !== PACKAGE_MANIFEST_PATH),
60
- };
61
- }
62
-
63
- async function ensureInstallTarget(targetDir, force) {
64
- if (await pathExists(targetDir)) {
65
- if (!force) {
66
- throw new Error(`Target skill already exists: ${targetDir}`);
67
- }
68
- await rm(targetDir, { recursive: true, force: true });
69
- }
70
- await mkdir(targetDir, { recursive: true });
71
- }
72
-
73
- export async function installSkillArchive(archivePath, options = {}) {
74
- const skillsDir = path.resolve(options.skillsDir ?? getDefaultSkillsDir());
75
- const archive = readSkillPackageBuffer(await readFile(archivePath));
76
- const targetDir = path.join(skillsDir, archive.skillName);
77
- await ensureInstallTarget(targetDir, options.force === true);
78
-
79
- for (const entry of archive.entries) {
80
- const destination = path.join(targetDir, entry.relativePath);
81
- await mkdir(path.dirname(destination), { recursive: true });
82
- await writeFile(destination, entry.bytes);
83
- }
84
-
85
- return {
86
- skillName: archive.skillName,
87
- installedTo: targetDir,
88
- source: path.resolve(archivePath),
89
- manifest: archive.manifest,
90
- };
91
- }
92
-
93
- export async function installSkillDirectory(skillDir, options = {}) {
94
- const validation = await validateSkillDirectory(skillDir);
95
- if (!validation.valid) {
96
- throw new Error(`Cannot install invalid skill:\n- ${validation.errors.join('\n- ')}`);
97
- }
98
-
99
- const skillFilePath = path.join(skillDir, 'SKILL.md');
100
- const skill = parseSkillMarkdown(await readFile(skillFilePath, 'utf8'));
101
- const skillsDir = path.resolve(options.skillsDir ?? getDefaultSkillsDir());
102
- const targetDir = path.join(skillsDir, skill.frontmatter.name);
103
- if (await pathExists(targetDir)) {
104
- if (!options.force) {
105
- throw new Error(`Target skill already exists: ${targetDir}`);
106
- }
107
- await rm(targetDir, { recursive: true, force: true });
108
- }
109
- await mkdir(skillsDir, { recursive: true });
110
- await cp(skillDir, targetDir, { recursive: true });
111
-
112
- return {
113
- skillName: skill.frontmatter.name,
114
- installedTo: targetDir,
115
- source: path.resolve(skillDir),
116
- manifest: null,
117
- };
118
- }
119
-
120
- export async function installSkill(inputPath, options = {}) {
121
- const resolvedInput = path.resolve(inputPath);
122
- const inputStat = await stat(resolvedInput).catch(() => null);
123
- if (!inputStat) {
124
- throw new Error(`Input not found: ${resolvedInput}`);
125
- }
126
-
127
- if (inputStat.isDirectory()) {
128
- return installSkillDirectory(resolvedInput, options);
129
- }
130
-
131
- if (inputStat.isFile() && isZipLike(resolvedInput)) {
132
- return installSkillArchive(resolvedInput, options);
133
- }
134
-
135
- throw new Error('Input must be a skill directory or a .skill/.zip archive.');
136
- }
137
-
138
- function parseArgs(argv) {
139
- const args = {
140
- input: argv[2],
141
- skillsDir: undefined,
142
- force: false,
143
- };
144
-
145
- for (let index = 3; index < argv.length; index += 1) {
146
- const token = argv[index];
147
- if (token === '--dest' && argv[index + 1]) {
148
- args.skillsDir = argv[++index];
149
- } else if (token === '--force') {
150
- args.force = true;
151
- }
152
- }
153
-
154
- return args;
155
- }
156
-
1
+ #!/usr/bin/env node
2
+
3
+ import { cp, mkdir, readFile, rm, stat, writeFile } from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { strFromU8, unzipSync } from 'fflate';
7
+ import { validateSkillDirectory } from './quick-validate.js';
8
+ import { getDefaultSkillsDir, parseSkillMarkdown, pathExists } from './utils.js';
9
+
10
+ const PACKAGE_MANIFEST_PATH = '.kodax-package.json';
11
+
12
+ function normalizeArchivePath(relativePath) {
13
+ return relativePath.replace(/\\/g, '/').replace(/^\.?\//, '');
14
+ }
15
+
16
+ function assertSafeArchivePath(relativePath) {
17
+ const normalized = normalizeArchivePath(relativePath);
18
+ if (!normalized || normalized.startsWith('/') || normalized.includes('../')) {
19
+ throw new Error(`Unsafe archive entry path: ${relativePath}`);
20
+ }
21
+ return normalized;
22
+ }
23
+
24
+ function isZipLike(filePath) {
25
+ return /\.(skill|zip)$/i.test(filePath);
26
+ }
27
+
28
+ export function readSkillPackageBuffer(buffer) {
29
+ const archive = unzipSync(buffer);
30
+ const entries = Object.entries(archive).map(([relativePath, bytes]) => ({
31
+ relativePath: assertSafeArchivePath(relativePath),
32
+ bytes,
33
+ }));
34
+
35
+ const skillEntry = entries.find((entry) => entry.relativePath === 'SKILL.md');
36
+ if (!skillEntry) {
37
+ throw new Error('Archive is missing SKILL.md');
38
+ }
39
+
40
+ const parsedSkill = parseSkillMarkdown(strFromU8(skillEntry.bytes));
41
+ const skillName = typeof parsedSkill.frontmatter.name === 'string'
42
+ ? parsedSkill.frontmatter.name.trim()
43
+ : '';
44
+ const description = typeof parsedSkill.frontmatter.description === 'string'
45
+ ? parsedSkill.frontmatter.description.trim()
46
+ : '';
47
+ if (!skillName || !description) {
48
+ throw new Error('Archive SKILL.md is missing required frontmatter fields.');
49
+ }
50
+
51
+ const manifestEntry = entries.find((entry) => entry.relativePath === PACKAGE_MANIFEST_PATH);
52
+ const manifest = manifestEntry
53
+ ? JSON.parse(strFromU8(manifestEntry.bytes))
54
+ : null;
55
+
56
+ return {
57
+ skillName,
58
+ manifest,
59
+ entries: entries.filter((entry) => entry.relativePath !== PACKAGE_MANIFEST_PATH),
60
+ };
61
+ }
62
+
63
+ async function ensureInstallTarget(targetDir, force) {
64
+ if (await pathExists(targetDir)) {
65
+ if (!force) {
66
+ throw new Error(`Target skill already exists: ${targetDir}`);
67
+ }
68
+ await rm(targetDir, { recursive: true, force: true });
69
+ }
70
+ await mkdir(targetDir, { recursive: true });
71
+ }
72
+
73
+ export async function installSkillArchive(archivePath, options = {}) {
74
+ const skillsDir = path.resolve(options.skillsDir ?? getDefaultSkillsDir());
75
+ const archive = readSkillPackageBuffer(await readFile(archivePath));
76
+ const targetDir = path.join(skillsDir, archive.skillName);
77
+ await ensureInstallTarget(targetDir, options.force === true);
78
+
79
+ for (const entry of archive.entries) {
80
+ const destination = path.join(targetDir, entry.relativePath);
81
+ await mkdir(path.dirname(destination), { recursive: true });
82
+ await writeFile(destination, entry.bytes);
83
+ }
84
+
85
+ return {
86
+ skillName: archive.skillName,
87
+ installedTo: targetDir,
88
+ source: path.resolve(archivePath),
89
+ manifest: archive.manifest,
90
+ };
91
+ }
92
+
93
+ export async function installSkillDirectory(skillDir, options = {}) {
94
+ const validation = await validateSkillDirectory(skillDir);
95
+ if (!validation.valid) {
96
+ throw new Error(`Cannot install invalid skill:\n- ${validation.errors.join('\n- ')}`);
97
+ }
98
+
99
+ const skillFilePath = path.join(skillDir, 'SKILL.md');
100
+ const skill = parseSkillMarkdown(await readFile(skillFilePath, 'utf8'));
101
+ const skillsDir = path.resolve(options.skillsDir ?? getDefaultSkillsDir());
102
+ const targetDir = path.join(skillsDir, skill.frontmatter.name);
103
+ if (await pathExists(targetDir)) {
104
+ if (!options.force) {
105
+ throw new Error(`Target skill already exists: ${targetDir}`);
106
+ }
107
+ await rm(targetDir, { recursive: true, force: true });
108
+ }
109
+ await mkdir(skillsDir, { recursive: true });
110
+ await cp(skillDir, targetDir, { recursive: true });
111
+
112
+ return {
113
+ skillName: skill.frontmatter.name,
114
+ installedTo: targetDir,
115
+ source: path.resolve(skillDir),
116
+ manifest: null,
117
+ };
118
+ }
119
+
120
+ export async function installSkill(inputPath, options = {}) {
121
+ const resolvedInput = path.resolve(inputPath);
122
+ const inputStat = await stat(resolvedInput).catch(() => null);
123
+ if (!inputStat) {
124
+ throw new Error(`Input not found: ${resolvedInput}`);
125
+ }
126
+
127
+ if (inputStat.isDirectory()) {
128
+ return installSkillDirectory(resolvedInput, options);
129
+ }
130
+
131
+ if (inputStat.isFile() && isZipLike(resolvedInput)) {
132
+ return installSkillArchive(resolvedInput, options);
133
+ }
134
+
135
+ throw new Error('Input must be a skill directory or a .skill/.zip archive.');
136
+ }
137
+
138
+ function parseArgs(argv) {
139
+ const args = {
140
+ input: argv[2],
141
+ skillsDir: undefined,
142
+ force: false,
143
+ };
144
+
145
+ for (let index = 3; index < argv.length; index += 1) {
146
+ const token = argv[index];
147
+ if (token === '--dest' && argv[index + 1]) {
148
+ args.skillsDir = argv[++index];
149
+ } else if (token === '--force') {
150
+ args.force = true;
151
+ }
152
+ }
153
+
154
+ return args;
155
+ }
156
+
157
157
  export async function main(argv = process.argv) {
158
158
  const args = parseArgs(argv);
159
- if (!args.input) {
160
- console.error('Usage: node scripts/install-skill.js <skill-dir-or-archive> [--dest <skills-dir>] [--force]');
161
- process.exit(1);
162
- }
163
-
164
- const result = await installSkill(args.input, args);
165
- console.log(`Installed ${result.skillName} to ${result.installedTo}`);
166
- }
167
-
159
+ if (!args.input) {
160
+ console.error('Usage: node scripts/install-skill.js <skill-dir-or-archive> [--dest <skills-dir>] [--force]');
161
+ process.exit(1);
162
+ }
163
+
164
+ const result = await installSkill(args.input, args);
165
+ console.log(`Installed ${result.skillName} to ${result.installedTo}`);
166
+ }
167
+
168
168
  const isDirectRun = process.env.KODAX_MODULE_BUNDLE !== 'true'
169
169
  && process.argv[1]
170
- && fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
171
-
172
- if (isDirectRun) {
173
- main().catch((error) => {
174
- console.error(error instanceof Error ? error.message : String(error));
175
- process.exit(1);
176
- });
177
- }
170
+ && fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
171
+
172
+ if (isDirectRun) {
173
+ main().catch((error) => {
174
+ console.error(error instanceof Error ? error.message : String(error));
175
+ process.exit(1);
176
+ });
177
+ }
@@ -1,39 +1,39 @@
1
- export interface PackagedSkillFile {
2
- path: string;
3
- size: number;
4
- sha256: string;
5
- }
6
-
7
- export interface SkillPackageManifest {
8
- format: 'kodax-skill-package';
9
- version: 1;
10
- created_at: string;
11
- entrypoint: 'SKILL.md';
12
- skill: {
13
- name: string;
14
- description: string;
15
- compatibility: string | null;
16
- user_invocable: boolean;
17
- disable_model_invocation: boolean;
18
- };
19
- files: PackagedSkillFile[];
20
- note: string;
21
- }
22
-
23
- export function createPackageManifest(
24
- skill: { frontmatter: Record<string, unknown> },
25
- files: Array<{ relativePath: string; bytes: Uint8Array; sha256: string }>,
26
- options?: { createdAt?: string }
27
- ): SkillPackageManifest;
28
-
29
- export function buildSkillPackage(
30
- skillDir: string,
31
- options?: { createdAt?: string }
32
- ): Promise<{ manifest: SkillPackageManifest; bytes: Uint8Array }>;
33
-
34
- export function writeSkillPackage(
35
- skillDir: string,
36
- outputPath: string,
37
- options?: { createdAt?: string }
38
- ): Promise<{ manifest: SkillPackageManifest; bytes: Uint8Array; outputPath: string }>;
1
+ export interface PackagedSkillFile {
2
+ path: string;
3
+ size: number;
4
+ sha256: string;
5
+ }
6
+
7
+ export interface SkillPackageManifest {
8
+ format: 'kodax-skill-package';
9
+ version: 1;
10
+ created_at: string;
11
+ entrypoint: 'SKILL.md';
12
+ skill: {
13
+ name: string;
14
+ description: string;
15
+ compatibility: string | null;
16
+ user_invocable: boolean;
17
+ disable_model_invocation: boolean;
18
+ };
19
+ files: PackagedSkillFile[];
20
+ note: string;
21
+ }
22
+
23
+ export function createPackageManifest(
24
+ skill: { frontmatter: Record<string, unknown> },
25
+ files: Array<{ relativePath: string; bytes: Uint8Array; sha256: string }>,
26
+ options?: { createdAt?: string }
27
+ ): SkillPackageManifest;
28
+
29
+ export function buildSkillPackage(
30
+ skillDir: string,
31
+ options?: { createdAt?: string }
32
+ ): Promise<{ manifest: SkillPackageManifest; bytes: Uint8Array }>;
33
+
34
+ export function writeSkillPackage(
35
+ skillDir: string,
36
+ outputPath: string,
37
+ options?: { createdAt?: string }
38
+ ): Promise<{ manifest: SkillPackageManifest; bytes: Uint8Array; outputPath: string }>;
39
39
  export declare function main(argv?: string[]): Promise<void>;
@@ -1,125 +1,125 @@
1
- #!/usr/bin/env node
2
-
3
- import { readFile, writeFile } from 'node:fs/promises';
4
- import { createHash } from 'node:crypto';
5
- import path from 'node:path';
6
- import { fileURLToPath } from 'node:url';
7
- import { zipSync, strToU8 } from 'fflate';
8
- import { validateSkillDirectory } from './quick-validate.js';
9
- import { collectFiles, loadSkill } from './utils.js';
10
-
11
- const PACKAGE_MANIFEST_PATH = '.kodax-package.json';
12
-
13
- function toUint8Array(value) {
14
- return value instanceof Uint8Array ? value : new Uint8Array(value);
15
- }
16
-
17
- function sha256(buffer) {
18
- return createHash('sha256').update(buffer).digest('hex');
19
- }
20
-
21
- export function createPackageManifest(skill, files, options = {}) {
22
- return {
23
- format: 'kodax-skill-package',
24
- version: 1,
25
- created_at: options.createdAt ?? new Date().toISOString(),
26
- entrypoint: 'SKILL.md',
27
- skill: {
28
- name: skill.frontmatter.name,
29
- description: skill.frontmatter.description,
30
- compatibility: skill.frontmatter.compatibility ?? null,
31
- user_invocable: skill.frontmatter['user-invocable'] ?? true,
32
- disable_model_invocation: skill.frontmatter['disable-model-invocation'] ?? false,
33
- },
34
- files: files.map((file) => ({
35
- path: file.relativePath,
36
- size: file.bytes.length,
37
- sha256: file.sha256,
38
- })),
39
- note: 'This archive is a zip file with a .skill extension. Compatible agents can extract and install the included skill directory.',
40
- };
41
- }
42
-
43
- export async function buildSkillPackage(skillDir, options = {}) {
44
- const validation = await validateSkillDirectory(skillDir);
45
- if (!validation.valid) {
46
- throw new Error(`Cannot package invalid skill:\n- ${validation.errors.join('\n- ')}`);
47
- }
48
-
49
- const skill = await loadSkill(skillDir);
50
- const discoveredFiles = await collectFiles(skillDir);
51
- const files = [];
52
- for (const file of discoveredFiles) {
53
- if (file.relativePath.endsWith('.skill')) {
54
- continue;
55
- }
56
- const bytes = toUint8Array(await readFile(file.absolutePath));
57
- files.push({
58
- ...file,
59
- bytes,
60
- sha256: sha256(bytes),
61
- });
62
- }
63
-
64
- const manifest = createPackageManifest(skill, files, options);
65
- const archiveEntries = {
66
- [PACKAGE_MANIFEST_PATH]: strToU8(JSON.stringify(manifest, null, 2)),
67
- };
68
- for (const file of files) {
69
- archiveEntries[file.relativePath] = file.bytes;
70
- }
71
-
72
- return {
73
- manifest,
74
- bytes: zipSync(archiveEntries, { level: 6 }),
75
- };
76
- }
77
-
78
- export async function writeSkillPackage(skillDir, outputPath, options = {}) {
79
- const result = await buildSkillPackage(skillDir, options);
80
- await writeFile(outputPath, result.bytes);
81
- return {
82
- ...result,
83
- outputPath: path.resolve(outputPath),
84
- };
85
- }
86
-
87
- function parseArgs(argv) {
88
- const args = {
89
- skillDir: argv[2],
90
- output: undefined,
91
- };
92
-
93
- for (let index = 3; index < argv.length; index += 1) {
94
- const token = argv[index];
95
- if (token === '--output' && argv[index + 1]) {
96
- args.output = argv[++index];
97
- }
98
- }
99
-
100
- return args;
101
- }
102
-
1
+ #!/usr/bin/env node
2
+
3
+ import { readFile, writeFile } from 'node:fs/promises';
4
+ import { createHash } from 'node:crypto';
5
+ import path from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+ import { zipSync, strToU8 } from 'fflate';
8
+ import { validateSkillDirectory } from './quick-validate.js';
9
+ import { collectFiles, loadSkill } from './utils.js';
10
+
11
+ const PACKAGE_MANIFEST_PATH = '.kodax-package.json';
12
+
13
+ function toUint8Array(value) {
14
+ return value instanceof Uint8Array ? value : new Uint8Array(value);
15
+ }
16
+
17
+ function sha256(buffer) {
18
+ return createHash('sha256').update(buffer).digest('hex');
19
+ }
20
+
21
+ export function createPackageManifest(skill, files, options = {}) {
22
+ return {
23
+ format: 'kodax-skill-package',
24
+ version: 1,
25
+ created_at: options.createdAt ?? new Date().toISOString(),
26
+ entrypoint: 'SKILL.md',
27
+ skill: {
28
+ name: skill.frontmatter.name,
29
+ description: skill.frontmatter.description,
30
+ compatibility: skill.frontmatter.compatibility ?? null,
31
+ user_invocable: skill.frontmatter['user-invocable'] ?? true,
32
+ disable_model_invocation: skill.frontmatter['disable-model-invocation'] ?? false,
33
+ },
34
+ files: files.map((file) => ({
35
+ path: file.relativePath,
36
+ size: file.bytes.length,
37
+ sha256: file.sha256,
38
+ })),
39
+ note: 'This archive is a zip file with a .skill extension. Compatible agents can extract and install the included skill directory.',
40
+ };
41
+ }
42
+
43
+ export async function buildSkillPackage(skillDir, options = {}) {
44
+ const validation = await validateSkillDirectory(skillDir);
45
+ if (!validation.valid) {
46
+ throw new Error(`Cannot package invalid skill:\n- ${validation.errors.join('\n- ')}`);
47
+ }
48
+
49
+ const skill = await loadSkill(skillDir);
50
+ const discoveredFiles = await collectFiles(skillDir);
51
+ const files = [];
52
+ for (const file of discoveredFiles) {
53
+ if (file.relativePath.endsWith('.skill')) {
54
+ continue;
55
+ }
56
+ const bytes = toUint8Array(await readFile(file.absolutePath));
57
+ files.push({
58
+ ...file,
59
+ bytes,
60
+ sha256: sha256(bytes),
61
+ });
62
+ }
63
+
64
+ const manifest = createPackageManifest(skill, files, options);
65
+ const archiveEntries = {
66
+ [PACKAGE_MANIFEST_PATH]: strToU8(JSON.stringify(manifest, null, 2)),
67
+ };
68
+ for (const file of files) {
69
+ archiveEntries[file.relativePath] = file.bytes;
70
+ }
71
+
72
+ return {
73
+ manifest,
74
+ bytes: zipSync(archiveEntries, { level: 6 }),
75
+ };
76
+ }
77
+
78
+ export async function writeSkillPackage(skillDir, outputPath, options = {}) {
79
+ const result = await buildSkillPackage(skillDir, options);
80
+ await writeFile(outputPath, result.bytes);
81
+ return {
82
+ ...result,
83
+ outputPath: path.resolve(outputPath),
84
+ };
85
+ }
86
+
87
+ function parseArgs(argv) {
88
+ const args = {
89
+ skillDir: argv[2],
90
+ output: undefined,
91
+ };
92
+
93
+ for (let index = 3; index < argv.length; index += 1) {
94
+ const token = argv[index];
95
+ if (token === '--output' && argv[index + 1]) {
96
+ args.output = argv[++index];
97
+ }
98
+ }
99
+
100
+ return args;
101
+ }
102
+
103
103
  export async function main(argv = process.argv) {
104
104
  const args = parseArgs(argv);
105
- if (!args.skillDir) {
106
- console.error('Usage: node scripts/package-skill.js <skill-dir> [--output <file.skill>]');
107
- process.exit(1);
108
- }
109
-
110
- const skill = await loadSkill(args.skillDir);
111
- const outputPath = args.output ?? path.join(path.dirname(args.skillDir), `${skill.frontmatter.name}.skill`);
112
- const result = await writeSkillPackage(args.skillDir, outputPath);
113
- console.log(`Wrote ${result.outputPath}`);
114
- }
115
-
105
+ if (!args.skillDir) {
106
+ console.error('Usage: node scripts/package-skill.js <skill-dir> [--output <file.skill>]');
107
+ process.exit(1);
108
+ }
109
+
110
+ const skill = await loadSkill(args.skillDir);
111
+ const outputPath = args.output ?? path.join(path.dirname(args.skillDir), `${skill.frontmatter.name}.skill`);
112
+ const result = await writeSkillPackage(args.skillDir, outputPath);
113
+ console.log(`Wrote ${result.outputPath}`);
114
+ }
115
+
116
116
  const isDirectRun = process.env.KODAX_MODULE_BUNDLE !== 'true'
117
117
  && process.argv[1]
118
- && fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
119
-
120
- if (isDirectRun) {
121
- main().catch((error) => {
122
- console.error(error instanceof Error ? error.message : String(error));
123
- process.exit(1);
124
- });
125
- }
118
+ && fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
119
+
120
+ if (isDirectRun) {
121
+ main().catch((error) => {
122
+ console.error(error instanceof Error ? error.message : String(error));
123
+ process.exit(1);
124
+ });
125
+ }