skilld-harness 3.0.0-beta.1
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.
- package/LICENSE +21 -0
- package/README.md +58 -0
- package/dist/_chunks/skills.mjs +87 -0
- package/dist/_chunks/skills.mjs.map +1 -0
- package/dist/index.d.mts +122 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +1209 -0
- package/dist/index.mjs.map +1 -0
- package/dist/skills/generate-package-skill/SKILL.md +64 -0
- package/dist/skills/generate-package-skill/assets/harness-request.md +11 -0
- package/dist/skills/generate-project-skill/SKILL.md +62 -0
- package/dist/skills/generate-project-skill/assets/harness-request.md +11 -0
- package/dist/skills/harness-skills.json +5 -0
- package/dist/skills/review-skill/SKILL.md +28 -0
- package/dist/skills/review-skill/assets/harness-request.md +24 -0
- package/dist/skills/skilld/SKILL.md +67 -0
- package/dist/skills/skilld-maintained-skills.json +6 -0
- package/dist/skills.d.mts +14 -0
- package/dist/skills.d.mts.map +1 -0
- package/dist/skills.mjs +2 -0
- package/package.json +76 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026-present Harlan Wilton
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# skilld-harness
|
|
2
|
+
|
|
3
|
+
Run visible skilld-maintained Skills through an AI SDK Harness.
|
|
4
|
+
|
|
5
|
+
The package checks output limits, paths, file types, and Skill frontmatter.
|
|
6
|
+
It then promotes generated Skills with an atomic directory rename.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
pnpm add skilld-harness @ai-sdk/harness ws zod
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Use Node 22 or newer.
|
|
15
|
+
The sandbox must provide POSIX `sh`, `rm`, `mkdir`, and GNU `find`.
|
|
16
|
+
|
|
17
|
+
## Run a Skill
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { createSkillHarness } from 'skilld-harness'
|
|
21
|
+
|
|
22
|
+
const skillHarness = createSkillHarness({
|
|
23
|
+
harness,
|
|
24
|
+
sandbox,
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const result = await skillHarness.run({
|
|
28
|
+
_tag: 'ProjectSkill',
|
|
29
|
+
projectDir: process.cwd(),
|
|
30
|
+
destination: {
|
|
31
|
+
rootDir: '.skills',
|
|
32
|
+
name: 'my-project',
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Every run returns a tagged `Ok` or `Err` value.
|
|
38
|
+
An installed Skill can include cleanup warnings after promotion.
|
|
39
|
+
|
|
40
|
+
Pass `fetch` to `createSkillHarness` when the host owns HTTP access.
|
|
41
|
+
The default adapter uses the Node global fetch implementation.
|
|
42
|
+
|
|
43
|
+
## Visible Skills
|
|
44
|
+
|
|
45
|
+
Import `skilld-harness/skills` to load the published Skill instructions.
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import {
|
|
49
|
+
loadSkilldMaintainedSkill,
|
|
50
|
+
skilldMaintainedSkillNames,
|
|
51
|
+
} from 'skilld-harness/skills'
|
|
52
|
+
|
|
53
|
+
const names = await skilldMaintainedSkillNames()
|
|
54
|
+
const skill = await loadSkilldMaintainedSkill('generate-project-skill')
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The same Skill files remain usable directly through an Agent.
|
|
58
|
+
Direct runs remain user reviewed.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, isAbsolute, posix, relative, resolve, sep } from "node:path";
|
|
3
|
+
import { parseDocument } from "yaml";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
function isSkillName(value) {
|
|
6
|
+
return value.length >= 1 && value.length <= 64 && /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value);
|
|
7
|
+
}
|
|
8
|
+
function resolveWithin(root, candidate) {
|
|
9
|
+
const absoluteRoot = resolve(root);
|
|
10
|
+
const absoluteCandidate = resolve(root, candidate);
|
|
11
|
+
const fromRoot = relative(absoluteRoot, absoluteCandidate);
|
|
12
|
+
if (fromRoot === "" || !fromRoot.startsWith(`..${sep}`) && fromRoot !== ".." && !isAbsolute(fromRoot)) return absoluteCandidate;
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
function normalizeOutputPath(value) {
|
|
16
|
+
if (value.length === 0 || value.includes("\\") || value.includes("\0") || posix.isAbsolute(value)) return null;
|
|
17
|
+
const normalized = posix.normalize(value);
|
|
18
|
+
if (normalized === "." || normalized === ".." || normalized.startsWith("../") || normalized !== value) return null;
|
|
19
|
+
return normalized;
|
|
20
|
+
}
|
|
21
|
+
const skillRoots = [
|
|
22
|
+
resolve(dirname(fileURLToPath(import.meta.url)), "../skills"),
|
|
23
|
+
resolve(dirname(fileURLToPath(import.meta.url)), "skills"),
|
|
24
|
+
resolve(dirname(fileURLToPath(import.meta.url)), "../../../skills")
|
|
25
|
+
];
|
|
26
|
+
function parseManifest(source) {
|
|
27
|
+
const value = JSON.parse(source);
|
|
28
|
+
if (!Array.isArray(value) || value.some((name) => typeof name !== "string" || !isSkillName(name))) throw new Error("skilld-maintained Skill manifest is invalid.");
|
|
29
|
+
if (new Set(value).size !== value.length) throw new Error("skilld-maintained Skill manifest contains duplicate names.");
|
|
30
|
+
return Object.freeze([...value]);
|
|
31
|
+
}
|
|
32
|
+
async function locateFile(path) {
|
|
33
|
+
for (const root of skillRoots) {
|
|
34
|
+
const value = await readFile(resolve(root, path), "utf8").catch((error) => {
|
|
35
|
+
if (error.code === "ENOENT") return null;
|
|
36
|
+
throw error;
|
|
37
|
+
});
|
|
38
|
+
if (value !== null) return value;
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`skilld-maintained Skill file is missing: ${path}`);
|
|
41
|
+
}
|
|
42
|
+
function splitSkill(source) {
|
|
43
|
+
const match = source.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
|
|
44
|
+
if (!match) throw new Error("skilld-maintained Skill frontmatter is invalid.");
|
|
45
|
+
const document = parseDocument(match[1], { uniqueKeys: true });
|
|
46
|
+
if (document.errors.length > 0) throw new Error("skilld-maintained Skill frontmatter is invalid.");
|
|
47
|
+
const frontmatter = document.toJS();
|
|
48
|
+
if (!frontmatter || typeof frontmatter !== "object") throw new Error("skilld-maintained Skill frontmatter is invalid.");
|
|
49
|
+
const values = frontmatter;
|
|
50
|
+
if (typeof values.name !== "string" || typeof values.description !== "string") throw new Error("skilld-maintained Skill frontmatter is incomplete.");
|
|
51
|
+
return {
|
|
52
|
+
name: values.name,
|
|
53
|
+
description: values.description,
|
|
54
|
+
content: match[2]
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
async function harnessSkillNames() {
|
|
58
|
+
return parseManifest(await locateFile("harness-skills.json"));
|
|
59
|
+
}
|
|
60
|
+
async function skilldMaintainedSkillNames() {
|
|
61
|
+
return parseManifest(await locateFile("skilld-maintained-skills.json"));
|
|
62
|
+
}
|
|
63
|
+
async function loadSkilldMaintainedSkill(name) {
|
|
64
|
+
if (!(await skilldMaintainedSkillNames()).includes(name)) throw new Error(`Unknown skilld-maintained Skill: ${name}`);
|
|
65
|
+
const skill = splitSkill(await locateFile(`${name}/SKILL.md`));
|
|
66
|
+
if (skill.name !== name) throw new Error(`skilld-maintained Skill name does not match its directory: ${name}`);
|
|
67
|
+
if (!(await harnessSkillNames()).includes(name)) return skill;
|
|
68
|
+
const request = await locateFile(`${name}/assets/harness-request.md`);
|
|
69
|
+
return {
|
|
70
|
+
...skill,
|
|
71
|
+
files: [{
|
|
72
|
+
path: "assets/harness-request.md",
|
|
73
|
+
content: request
|
|
74
|
+
}]
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
const DEFAULT_OUTPUT_POLICY = Object.freeze({
|
|
78
|
+
maxSourceFiles: 2e3,
|
|
79
|
+
maxSourceFileBytes: 524288,
|
|
80
|
+
maxSourceBytes: 52428800,
|
|
81
|
+
maxOutputFiles: 64,
|
|
82
|
+
maxOutputFileBytes: 524288,
|
|
83
|
+
maxOutputBytes: 4194304
|
|
84
|
+
});
|
|
85
|
+
export { DEFAULT_OUTPUT_POLICY, harnessSkillNames, isSkillName, loadSkilldMaintainedSkill, normalizeOutputPath, resolveWithin, skilldMaintainedSkillNames };
|
|
86
|
+
|
|
87
|
+
//# sourceMappingURL=skills.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.mjs","names":[],"sources":["../../src/internal/paths.ts","../../src/skills.ts"],"sourcesContent":["import { isAbsolute, posix, relative, resolve, sep } from 'node:path'\n\nexport function isSkillName(value: string): boolean {\n return value.length >= 1\n && value.length <= 64\n && /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value)\n}\n\nexport function resolveWithin(root: string, candidate: string): string | null {\n const absoluteRoot = resolve(root)\n const absoluteCandidate = resolve(root, candidate)\n const fromRoot = relative(absoluteRoot, absoluteCandidate)\n if (fromRoot === '' || (!fromRoot.startsWith(`..${sep}`) && fromRoot !== '..' && !isAbsolute(fromRoot)))\n return absoluteCandidate\n return null\n}\n\nexport function normalizeOutputPath(value: string): string | null {\n if (value.length === 0 || value.includes('\\\\') || value.includes('\\0') || posix.isAbsolute(value))\n return null\n const normalized = posix.normalize(value)\n if (normalized === '.' || normalized === '..' || normalized.startsWith('../') || normalized !== value)\n return null\n return normalized\n}\n","import type { HarnessV1Skill } from '@ai-sdk/harness'\nimport { readFile } from 'node:fs/promises'\nimport { dirname, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { parseDocument } from 'yaml'\nimport { isSkillName } from './internal/paths.ts'\n\nconst skillRoots = [\n resolve(dirname(fileURLToPath(import.meta.url)), '../skills'),\n resolve(dirname(fileURLToPath(import.meta.url)), 'skills'),\n resolve(dirname(fileURLToPath(import.meta.url)), '../../../skills'),\n] as const\n\nfunction parseManifest(source: string): ReadonlyArray<string> {\n const value = JSON.parse(source) as unknown\n if (!Array.isArray(value) || value.some(name => typeof name !== 'string' || !isSkillName(name)))\n throw new Error('skilld-maintained Skill manifest is invalid.')\n if (new Set(value).size !== value.length)\n throw new Error('skilld-maintained Skill manifest contains duplicate names.')\n return Object.freeze([...value])\n}\n\nasync function locateFile(path: string): Promise<string> {\n for (const root of skillRoots) {\n const value = await readFile(resolve(root, path), 'utf8').catch((error) => {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT')\n return null\n throw error\n })\n if (value !== null)\n return value\n }\n throw new Error(`skilld-maintained Skill file is missing: ${path}`)\n}\n\nfunction splitSkill(source: string): { name: string, description: string, content: string } {\n const match = source.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n([\\s\\S]*)$/)\n if (!match)\n throw new Error('skilld-maintained Skill frontmatter is invalid.')\n\n const document = parseDocument(match[1]!, { uniqueKeys: true })\n if (document.errors.length > 0)\n throw new Error('skilld-maintained Skill frontmatter is invalid.')\n const frontmatter = document.toJS() as unknown\n if (!frontmatter || typeof frontmatter !== 'object')\n throw new Error('skilld-maintained Skill frontmatter is invalid.')\n\n const values = frontmatter as Record<string, unknown>\n if (typeof values.name !== 'string' || typeof values.description !== 'string')\n throw new Error('skilld-maintained Skill frontmatter is incomplete.')\n\n return { name: values.name, description: values.description, content: match[2]! }\n}\n\nexport async function harnessSkillNames(): Promise<ReadonlyArray<string>> {\n const source = await locateFile('harness-skills.json')\n return parseManifest(source)\n}\n\nexport async function skilldMaintainedSkillNames(): Promise<ReadonlyArray<string>> {\n const source = await locateFile('skilld-maintained-skills.json')\n return parseManifest(source)\n}\n\nexport async function loadSkilldMaintainedSkill(name: string): Promise<HarnessV1Skill> {\n const names = await skilldMaintainedSkillNames()\n if (!names.includes(name))\n throw new Error(`Unknown skilld-maintained Skill: ${name}`)\n\n const source = await locateFile(`${name}/SKILL.md`)\n const skill = splitSkill(source)\n if (skill.name !== name)\n throw new Error(`skilld-maintained Skill name does not match its directory: ${name}`)\n\n const harnessSkills = await harnessSkillNames()\n if (!harnessSkills.includes(name))\n return skill\n\n const request = await locateFile(`${name}/assets/harness-request.md`)\n return {\n ...skill,\n files: [{ path: 'assets/harness-request.md', content: request }],\n }\n}\n\nexport const DEFAULT_OUTPUT_POLICY = Object.freeze({\n maxSourceFiles: 2_000,\n maxSourceFileBytes: 512 * 1024,\n maxSourceBytes: 50 * 1024 * 1024,\n maxOutputFiles: 64,\n maxOutputFileBytes: 512 * 1024,\n maxOutputBytes: 4 * 1024 * 1024,\n})\n"],"mappings":";;;;AAEA,SAAgB,YAAY,OAAwB;CAClD,OAAO,MAAM,UAAU,KAClB,MAAM,UAAU,MAChB,6BAA6B,KAAK,KAAK;AAC9C;AAEA,SAAgB,cAAc,MAAc,WAAkC;CAC5E,MAAM,eAAe,QAAQ,IAAI;CACjC,MAAM,oBAAoB,QAAQ,MAAM,SAAS;CACjD,MAAM,WAAW,SAAS,cAAc,iBAAiB;CACzD,IAAI,aAAa,MAAO,CAAC,SAAS,WAAW,KAAK,KAAK,KAAK,aAAa,QAAQ,CAAC,WAAW,QAAQ,GACnG,OAAO;CACT,OAAO;AACT;AAEA,SAAgB,oBAAoB,OAA8B;CAChE,IAAI,MAAM,WAAW,KAAK,MAAM,SAAS,IAAI,KAAK,MAAM,SAAS,IAAI,KAAK,MAAM,WAAW,KAAK,GAC9F,OAAO;CACT,MAAM,aAAa,MAAM,UAAU,KAAK;CACxC,IAAI,eAAe,OAAO,eAAe,QAAQ,WAAW,WAAW,KAAK,KAAK,eAAe,OAC9F,OAAO;CACT,OAAO;AACT;ACjBA,MAAM,aAAa;CACjB,QAAQ,QAAQ,cAAc,YAAY,GAAG,CAAC,GAAG,WAAW;CAC5D,QAAQ,QAAQ,cAAc,YAAY,GAAG,CAAC,GAAG,QAAQ;CACzD,QAAQ,QAAQ,cAAc,YAAY,GAAG,CAAC,GAAG,iBAAiB;AACpE;AAEA,SAAS,cAAc,QAAuC;CAC5D,MAAM,QAAQ,KAAK,MAAM,MAAM;CAC/B,IAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAK,SAAQ,OAAO,SAAS,YAAY,CAAC,YAAY,IAAI,CAAC,GAC5F,MAAM,IAAI,MAAM,8CAA8C;CAChE,IAAI,IAAI,IAAI,KAAK,CAAC,CAAC,SAAS,MAAM,QAChC,MAAM,IAAI,MAAM,4DAA4D;CAC9E,OAAO,OAAO,OAAO,CAAC,GAAG,KAAK,CAAC;AACjC;AAEA,eAAe,WAAW,MAA+B;CACvD,KAAK,MAAM,QAAQ,YAAY;EAC7B,MAAM,QAAQ,MAAM,SAAS,QAAQ,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,OAAO,UAAU;GACzE,IAAK,MAAgC,SAAS,UAC5C,OAAO;GACT,MAAM;EACR,CAAC;EACD,IAAI,UAAU,MACZ,OAAO;CACX;CACA,MAAM,IAAI,MAAM,4CAA4C,MAAM;AACpE;AAEA,SAAS,WAAW,QAAwE;CAC1F,MAAM,QAAQ,OAAO,MAAM,4CAA4C;CACvE,IAAI,CAAC,OACH,MAAM,IAAI,MAAM,iDAAiD;CAEnE,MAAM,WAAW,cAAc,MAAM,IAAK,EAAE,YAAY,KAAK,CAAC;CAC9D,IAAI,SAAS,OAAO,SAAS,GAC3B,MAAM,IAAI,MAAM,iDAAiD;CACnE,MAAM,cAAc,SAAS,KAAK;CAClC,IAAI,CAAC,eAAe,OAAO,gBAAgB,UACzC,MAAM,IAAI,MAAM,iDAAiD;CAEnE,MAAM,SAAS;CACf,IAAI,OAAO,OAAO,SAAS,YAAY,OAAO,OAAO,gBAAgB,UACnE,MAAM,IAAI,MAAM,oDAAoD;CAEtE,OAAO;EAAE,MAAM,OAAO;EAAM,aAAa,OAAO;EAAa,SAAS,MAAM;CAAI;AAClF;AAEA,eAAsB,oBAAoD;CAExE,OAAO,cAAc,MADA,WAAW,qBAAqB,CAC1B;AAC7B;AAEA,eAAsB,6BAA6D;CAEjF,OAAO,cAAc,MADA,WAAW,+BAA+B,CACpC;AAC7B;AAEA,eAAsB,0BAA0B,MAAuC;CAErF,IAAI,EAAC,MADe,2BAA2B,EAAA,CACpC,SAAS,IAAI,GACtB,MAAM,IAAI,MAAM,oCAAoC,MAAM;CAG5D,MAAM,QAAQ,WAAW,MADJ,WAAW,GAAG,KAAK,UAAU,CACnB;CAC/B,IAAI,MAAM,SAAS,MACjB,MAAM,IAAI,MAAM,8DAA8D,MAAM;CAGtF,IAAI,EAAC,MADuB,kBAAkB,EAAA,CAC3B,SAAS,IAAI,GAC9B,OAAO;CAET,MAAM,UAAU,MAAM,WAAW,GAAG,KAAK,2BAA2B;CACpE,OAAO;EACL,GAAG;EACH,OAAO,CAAC;GAAE,MAAM;GAA6B,SAAS;EAAQ,CAAC;CACjE;AACF;AAEA,MAAa,wBAAwB,OAAO,OAAO;CACjD,gBAAgB;CAChB,oBAAoB;CACpB,gBAAgB;CAChB,gBAAgB;CAChB,oBAAoB;CACpB,gBAAgB;AAClB,CAAC"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { HarnessAgentSandboxConfig } from "@ai-sdk/harness/agent";
|
|
2
|
+
import { HarnessV1, HarnessV1SandboxProvider } from "@ai-sdk/harness";
|
|
3
|
+
interface SkillDestination {
|
|
4
|
+
readonly rootDir: string;
|
|
5
|
+
readonly name: string;
|
|
6
|
+
}
|
|
7
|
+
type PackageSource = {
|
|
8
|
+
readonly _tag: 'NpmPackage';
|
|
9
|
+
readonly spec: string;
|
|
10
|
+
} | {
|
|
11
|
+
readonly _tag: 'LocalPackage';
|
|
12
|
+
readonly rootDir: string;
|
|
13
|
+
readonly packageDir: string;
|
|
14
|
+
};
|
|
15
|
+
type SkillRun = {
|
|
16
|
+
readonly _tag: 'PackageSkill';
|
|
17
|
+
readonly source: PackageSource;
|
|
18
|
+
readonly destination: SkillDestination;
|
|
19
|
+
} | {
|
|
20
|
+
readonly _tag: 'ProjectSkill';
|
|
21
|
+
readonly projectDir: string;
|
|
22
|
+
readonly destination: SkillDestination;
|
|
23
|
+
} | {
|
|
24
|
+
readonly _tag: 'ReviewSkill';
|
|
25
|
+
readonly skillDir: string;
|
|
26
|
+
};
|
|
27
|
+
interface SkillOutputPolicy {
|
|
28
|
+
readonly maxSourceFiles: number;
|
|
29
|
+
readonly maxSourceFileBytes: number;
|
|
30
|
+
readonly maxSourceBytes: number;
|
|
31
|
+
readonly maxOutputFiles: number;
|
|
32
|
+
readonly maxOutputFileBytes: number;
|
|
33
|
+
readonly maxOutputBytes: number;
|
|
34
|
+
}
|
|
35
|
+
interface SkillRunOptions {
|
|
36
|
+
readonly signal?: AbortSignal;
|
|
37
|
+
}
|
|
38
|
+
interface SkillFile {
|
|
39
|
+
readonly path: string;
|
|
40
|
+
readonly bytes: number;
|
|
41
|
+
}
|
|
42
|
+
interface SourceAttempt {
|
|
43
|
+
readonly source: string;
|
|
44
|
+
readonly status: 'used' | 'skipped';
|
|
45
|
+
readonly reason?: string;
|
|
46
|
+
}
|
|
47
|
+
interface GeneratedSkill {
|
|
48
|
+
readonly _tag: 'GeneratedSkill';
|
|
49
|
+
readonly name: string;
|
|
50
|
+
readonly outputDir: string;
|
|
51
|
+
readonly files: ReadonlyArray<SkillFile>;
|
|
52
|
+
readonly sourceAttempts: ReadonlyArray<SourceAttempt>;
|
|
53
|
+
/** Cleanup problems after the new Skill reached its destination. */
|
|
54
|
+
readonly warnings: ReadonlyArray<string>;
|
|
55
|
+
}
|
|
56
|
+
interface SkillReviewFinding {
|
|
57
|
+
readonly level: 'error' | 'warning' | 'note';
|
|
58
|
+
readonly path: string;
|
|
59
|
+
readonly message: string;
|
|
60
|
+
readonly fix: string;
|
|
61
|
+
}
|
|
62
|
+
interface SkillReview {
|
|
63
|
+
readonly _tag: 'SkillReview';
|
|
64
|
+
readonly summary: string;
|
|
65
|
+
readonly findings: ReadonlyArray<SkillReviewFinding>;
|
|
66
|
+
}
|
|
67
|
+
type SkillRunError = {
|
|
68
|
+
readonly _tag: 'InvalidInput';
|
|
69
|
+
readonly message: string;
|
|
70
|
+
} | {
|
|
71
|
+
readonly _tag: 'SourceUnavailable';
|
|
72
|
+
readonly message: string;
|
|
73
|
+
readonly attempts: ReadonlyArray<SourceAttempt>;
|
|
74
|
+
readonly cause?: unknown;
|
|
75
|
+
} | {
|
|
76
|
+
readonly _tag: 'AgentFailed';
|
|
77
|
+
readonly message: string;
|
|
78
|
+
readonly cause?: unknown;
|
|
79
|
+
} | {
|
|
80
|
+
readonly _tag: 'InvalidSkill';
|
|
81
|
+
readonly message: string;
|
|
82
|
+
readonly issues: ReadonlyArray<string>;
|
|
83
|
+
} | {
|
|
84
|
+
readonly _tag: 'UnsafeOutputPath';
|
|
85
|
+
readonly message: string;
|
|
86
|
+
readonly path: string;
|
|
87
|
+
} | {
|
|
88
|
+
readonly _tag: 'OutputBusy';
|
|
89
|
+
readonly message: string;
|
|
90
|
+
readonly path: string;
|
|
91
|
+
} | {
|
|
92
|
+
readonly _tag: 'PromotionFailed';
|
|
93
|
+
readonly message: string;
|
|
94
|
+
readonly path: string;
|
|
95
|
+
readonly cause?: unknown;
|
|
96
|
+
} | {
|
|
97
|
+
readonly _tag: 'Cancelled';
|
|
98
|
+
readonly message: string;
|
|
99
|
+
};
|
|
100
|
+
type SkillRunResult = {
|
|
101
|
+
readonly _tag: 'Ok';
|
|
102
|
+
readonly value: GeneratedSkill | SkillReview;
|
|
103
|
+
} | {
|
|
104
|
+
readonly _tag: 'Err';
|
|
105
|
+
readonly error: SkillRunError;
|
|
106
|
+
};
|
|
107
|
+
interface SkillHarness {
|
|
108
|
+
readonly run: (input: SkillRun, options?: SkillRunOptions) => Promise<SkillRunResult>;
|
|
109
|
+
}
|
|
110
|
+
interface CreateSkillHarnessOptions {
|
|
111
|
+
readonly harness: HarnessV1;
|
|
112
|
+
/** The sandbox must provide POSIX sh, rm, mkdir, and GNU find. */
|
|
113
|
+
readonly sandbox: HarnessV1SandboxProvider;
|
|
114
|
+
/** onSession runs after the Harness writes its visible inputs. */
|
|
115
|
+
readonly sandboxConfig?: HarnessAgentSandboxConfig;
|
|
116
|
+
readonly outputPolicy?: Partial<SkillOutputPolicy>;
|
|
117
|
+
/** HTTP adapter for npm metadata and immutable source archives. */
|
|
118
|
+
readonly fetch?: (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
119
|
+
}
|
|
120
|
+
declare function createSkillHarness(options: CreateSkillHarnessOptions): SkillHarness;
|
|
121
|
+
export { type CreateSkillHarnessOptions, type GeneratedSkill, type PackageSource, type SkillDestination, type SkillFile, type SkillHarness, type SkillOutputPolicy, type SkillReview, type SkillReviewFinding, type SkillRun, type SkillRunError, type SkillRunOptions, type SkillRunResult, type SourceAttempt, createSkillHarness };
|
|
122
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/harness.ts"],"mappings":";;UAGiB;WACN;WACA;;KAGC;WAEC;WACA;;WAGA;WACA;WACA;;KAGD;WAEC;WACA,QAAQ;WACR,aAAa;;WAGb;WACA;WACA,aAAa;;WAGb;WACA;;UAGI;WACN;WACA;WACA;WACA;WACA;WACA;;UAGM;WACN,SAAS;;UAGH;WACN;WACA;;UAGM;WACN;WACA;WACA;;UAGM;WACN;WACA;WACA;WACA,OAAO,cAAc;WACrB,gBAAgB,cAAc;;WAE9B,UAAU;;UAGJ;WACN;WACA;WACA;WACA;;UAGM;WACN;WACA;WACA,UAAU,cAAc;;KAGvB;WACK;WAA+B;;WAEjC;WACA;WACA,UAAU,cAAc;WACxB;;WAEE;WAA8B;WAA0B;;WACxD;WAA+B;WAA0B,QAAQ;;WACjE;WAAmC;WAA0B;;WAC7D;WAA6B;WAA0B;;WACvD;WAAkC;WAA0B;WAAuB;;WACnF;WAA4B;;KAEjC;WACK;WAAqB,OAAO,iBAAiB;;WAC7C;WAAsB,OAAO;;UAE7B;WACN,MAAM,OAAO,UAAU,UAAU,oBAAoB,QAAQ;;UAGvD;WACN,SAAS;;WAET,SAAS;;WAET,gBAAgB;WAChB,eAAe,QAAQ;;WAEvB,SAAS,gBAAgB,MAAM,SAAS,OAAO,gBAAgB,QAAQ;;iBCkElE,mBAAmB,SAAS,4BAA4B"}
|