@plurnk/plurnk-skills 0.0.0-stage → 3.0.0

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/.env.defaults ADDED
@@ -0,0 +1,9 @@
1
+ # Standard Agent Skills: complete definitions, with independent enabledness.
2
+ # `_` in a key represents `-`; Unicode names work in .env or via `env 'KEY=value' command`.
3
+ # PLURNK_SKILLS_code_review={"name":"code-review","source":"/srv/skills/code-review"}
4
+ PLURNK_SKILLS_ENABLED=1
5
+ # PLURNK_SKILLS_code_review_ENABLED=0
6
+ # Any skill name: its definition, and its own _ENABLED control.
7
+ # PLURNK_SKILLS_<name>=<definition>
8
+ # Deadline for one skills source fetch (git ls-remote, git clone, tar, unzip), positive ms.
9
+ PLURNK_SKILLS_FETCH_TIMEOUT_MS=120000
package/README.md CHANGED
@@ -1,3 +1,12 @@
1
- # Temporary Holding Version
1
+ # Plurnk skills
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The daemon module for standard [Agent Skills](https://agentskills.io): discovery,
4
+ workspace definitions, live folders, fetched Git/archive copies, and `skill://` resources.
5
+ Included in the default Plurnk service installation; loaded through ordinary module discovery.
6
+
7
+ Configure sources and enabledness through [.env.defaults](./.env.defaults), standard skill
8
+ locations, or the `skills` family. The host composes Plurnk's own reference as an ordinary skill.
9
+
10
+ The format library is `@plurnk/plurnk-agent-skills`. This package owns workspace management,
11
+ not the file format. See [SPEC.md](./SPEC.md) for the contract and [docs/skills.md](./docs/skills.md)
12
+ for the model-facing reference.
package/SPEC.md ADDED
@@ -0,0 +1,170 @@
1
+ # Plurnk skills specification
2
+
3
+ ## Module
4
+
5
+ §skills-module **Skills load through ordinary daemon module discovery.**
6
+ The package registers its Functionality family and read-only resource tree during setup.
7
+ It opens no ingress and owns no producers to drain. Core supplies workspace paths, admitted
8
+ subprocess environment, operational storage, plugin components and host-composed reference trees
9
+ through published module seams. Invalid configuration leaves the family inspectable but unavailable
10
+ under {§configuration-repair-path}; the module reports it for offline validation too.
11
+
12
+ The durable namespace is `@plurnk/plurnk-skills`.
13
+
14
+ ## Workspace family
15
+
16
+ §skills-functionality **Agent Skills are one workspace Functionality family.**
17
+ The discovered skills module registers the `skills` family with the coordinator ({§functionality-coordinator});
18
+ its adapter owns protocol truth for standard Agent Skills and nothing else. A
19
+ definition is `SkillDefinition`: the standard skill `name`, its `source`, and
20
+ optional Git `ref`/resolved `commit` ({§skills-sources}). Only a host-provided
21
+ resource tree omits `source`. Source location is not mutation ownership: standard
22
+ project/global roots are read-only configuration inputs; live changes belong to
23
+ the workspace. Plurnk neither installs into nor deletes from those roots.
24
+
25
+ *Available definitions.* The filesystem is the only truth about installation:
26
+ every `<root>/<name>/SKILL.md` directory under the project, plurnk, then global
27
+ root is one service-origin definition, a nearer root shadowing a farther one and
28
+ all of them shadowing host-provided trees by name. Each filesystem definition
29
+ names its actual source directory. The workspace's durable state owns
30
+ enablement ({§functionality-state}); a disabled skill stays client-visible and
31
+ leaves no model-facing trace.
32
+
33
+ §skills-configuration **Skills use the shared definition cascade.**
34
+
35
+ | Layer, low to high | Definition source |
36
+ |---|---|
37
+ | Service | Host-provided trees |
38
+ | Standard locations | Global, plurnk, then project roots selected by {§agent-roots} |
39
+ | Cascading environment | `PLURNK_SKILLS_<name>={"name":"<name>","source":"…","ref"?:"…"}` replaces the complete definition |
40
+ | Live workspace | `skills (add)` creates a workspace definition through {§functionality-coordinator} |
41
+
42
+ `PLURNK_SKILLS_ENABLED` supplies default enabledness; `<name>_ENABLED` overrides
43
+ it independently ({§resource-environment}). The decoded environment alias must
44
+ equal the standard skill name, including digit-leading and Unicode names.
45
+ Blank definitions are invalid; controls may precede a definition. Environment
46
+ validation checks shape, names, remote URL rules, and Git-only `ref` without
47
+ fetching or opening a source; `commit` is service-recorded, not an input.
48
+
49
+ *Discovery is inert.* `source` is the family's one discovery input
50
+ ({§functionality-discover-advertisement}): `discover {source}` lists the standard
51
+ skills one source carries, each a candidate with `source` provenance and the exact
52
+ definition to add; it never installs, persists, or enables.
53
+
54
+ *Admission.* `add {alias, definition}` requires `alias = name` and a `source`;
55
+ the workspace definition may shadow a service skill of the same name. Relative
56
+ sources require a project root; absolute sources work in headless workspaces.
57
+ A local source is recorded as its absolute path.
58
+ A git source records the `commit` its `ref` names at admission, or its default
59
+ branch's when no `ref` is given; `ref` belongs to git sources, and a supplied
60
+ `commit` is refused because the service records it. The family's aliases use
61
+ the standard skill-name grammar ({§agent-skills-name}), including digit-leading
62
+ and Unicode names, rather than the coordinator's generic default.
63
+
64
+ *Preparation.* For each enabled alias the adapter selects the host-provided
65
+ tree or resolves the complete source definition ({§skills-sources}). Local
66
+ folders and their `SKILL.md` files remain live references, including supporting
67
+ resources and symlink retargeting. Git/archive sources are materialized only
68
+ inside {§module-workspace-directory}; different workspaces and complete source
69
+ definitions cannot reuse each other's materializations accidentally.
70
+ The first fetched Git/archive copy remains stable across enable, cooling, and
71
+ restart until the complete source definition changes. In particular, an
72
+ operator-configured symbolic Git ref is not an implicit update subscription.
73
+ Each admitted skill requires standard `name` and `description` frontmatter
74
+ with `name` matching its directory. A missing, uninstallable, or invalid skill
75
+ is `unavailable` with its exact Problem ({§problems-skills}) under the
76
+ coordinator's failure policy ({§functionality-model-mutation}); one bad skill
77
+ never fails the family.
78
+
79
+ Removal follows {§skills-remove}.
80
+
81
+ §skills-sources **A source is a git remote, a folder, or a file, read with standard tools.**
82
+ Fetching runs nothing it fetched. Materialized copies cannot contain references
83
+ outside their skill; live resources retain {§agent-skills-directory} containment.
84
+
85
+ | Source | How it is read |
86
+ |---|---|
87
+ | Git remote: a full `https://` or `ssh://` URL, or `user@host:path` | `git ls-remote` resolves the ref at admission; preparation shallow-clones it with hooks and submodules off, and a checkout at any other commit is 409 `source-moved` |
88
+ | Folder: absolute, `~/`, or relative to the project root | Live reference; standard directory/name matching applies |
89
+ | A file named `SKILL.md` | Live reference to its skill directory and supporting resources |
90
+ | A `.zip`, `.tar`, `.tgz`, `.tar.gz`, `.tar.bz2`, `.tar.xz`, or `.tar.zst` archive | Unpacked into private staging with `unzip` or `tar`; a lone top-level directory is the source's root |
91
+
92
+ Any other scheme, plain `http`, and an https URL carrying credentials are refused
93
+ with `source-invalid`: a recorded source is listed to every client. Git runs with the
94
+ operator's configuration, credentials, and SSH agent, never plurnk's secrets, and
95
+ never prompts; `PLURNK_SKILLS_FETCH_TIMEOUT_MS` bounds each fetch.
96
+
97
+ A source's skills are the directories holding a `SKILL.md`, found by walking
98
+ from its root without entering `.git` or a skill already found. A fetched skill at
99
+ the root is named by its frontmatter ({§agent-skills-name}); local references and
100
+ directories below the root use the standard folder rule. A source with `plugin.json` at its root is an
101
+ Agent Plugin and is refused with 422 `source-is-plugin`, so its skills keep the
102
+ plugin's identity. Materialization copies the named skill beside its workspace-owned destination
103
+ and renames it to `<root>/<name>`; a copy that holds a link out of the skill, or
104
+ anything but files, directories, and inward links, is refused with 422
105
+ `source-unsafe` and leaves nothing behind.
106
+
107
+ §skills-resources **A skill is a resource tree, not a rewritten document.**
108
+ The family exposes enabled, available {§agent-skills-tree} sources through
109
+ `skill://<name>/` using {§resource-tree-scheme}. The source owns its bytes; commons entries are demand-loaded
110
+ projections, not writable installations. Filesystem skills retain their original
111
+ directories; service-provided trees need no generated filesystem directory.
112
+ The authority is the name's WHATWG URI representation, including percent-encoding
113
+ for non-ASCII names. Installation names remain unchanged; a raw spelling and its
114
+ serialized URI address the same resource, not separate skill identities.
115
+
116
+ | Operation | Contract |
117
+ | --- | --- |
118
+ | Turn0 `FIND (skill://*/SKILL.md)` | One ordinary resource catalog: name, address, and standard frontmatter description via {§mimetype-summary}. No synthetic index, body injection, or execution. |
119
+ | `READ (skill://<name>/SKILL.md)` | Original frontmatter and Markdown, unchanged; relative links remain relative to the source layout. |
120
+ | `READ` / `FIND` below the authority | References, scripts, and assets retain their source paths and ordinary pattern, channel, byte, and multimodal semantics. Acquisition observes current source contents, including disappearance. |
121
+ | ```` ```runtime (skill://<name>/scripts/program.ext) ```` | Ordinary resource execution and proposal policy; preserve the native file and its siblings under {§exec-source-temporary}. Discovery and READ never execute scripts. |
122
+ | Model mutation | Read-only; no EDIT, SEND, or KILL of skill resources. Manage definitions and enablement through ```` ```skills ````. |
123
+ | Disable / unavailable / remove | Withdraw the authority from new resource access and discovery. Existing log receipts remain historical evidence. |
124
+ | WORK / FORK | Use the same workspace Functionality, not copied definitions or resource caches. |
125
+
126
+ Explicit skill URIs address these resources; bare operation paths still address
127
+ project files, with no implicit current-skill directory. Source resolution follows
128
+ {§agent-skills-directory}, including symlinked skill directories and containment of references.
129
+ An uninstalled Git skill is not manufactured by repository detection.
130
+
131
+ §skills-remove **`remove` forgets the workspace binding, not the source.**
132
+ It withdraws that definition and restores any inherited definition and enabledness
133
+ ({§functionality-coordinator}). External folders are never deleted. Fetched
134
+ materializations remain workspace-owned operational state, reusable only for the
135
+ same complete definition; they confer no availability without a definition.
136
+ Inherited definitions cannot be removed here; their enabledness can be overridden.
137
+
138
+ §skills-hotload **Skills placed out of band are admitted at the next turn** ({§functionality-hotload}). The
139
+ family keeps one signature of the discovered roots, configured definitions, source locations, and `SKILL.md` sources
140
+ per resident workspace, read before a publication loads the skills it describes. Turn admission
141
+ recomputes it under the workspace gate before packet assembly: a changed signature republishes the
142
+ family, and an unchanged one republishes only when the skills the coordinator would publish differ
143
+ from the published ones. A skill installed, edited or removed by any other tool is therefore
144
+ discoverable in the first subsequent model turn, while an unchanged set dispatches nothing. The model manages skills
145
+ only through the generated ```` ```skills ```` family
146
+ ({§functionality-model-projection}); it is never taught a package manager.
147
+
148
+ ## Problems
149
+
150
+ §problems-skills **Agent Skills source and setup Problems.** Shared coordination failures use
151
+ {§problems-functionality}. Placeholders below describe the failing source or definition.
152
+
153
+ | code | status | contract |
154
+ |---|---:|---|
155
+ | `definition-invalid` | 400 | The Agent Skill definition is invalid; a supplied commit must be a ref instead, and refs require Git sources. |
156
+ | `source-invalid` | 400 | '*source*' is not a valid git remote URL; an https source carries no credentials (git's credential helper supplies them); is not a source: a git remote is a full https or ssh URL; is relative, and this workspace has no project root to resolve it against; or is neither a folder, a SKILL.md, nor a zip or tar archive. |
157
+ | `source-missing` | 404 | No folder or file is at '*source*'. |
158
+ | `source-unreadable` | 422 | '*source*' cannot be read: *cause*; or '*path*' could not be unpacked: *reason*. |
159
+ | `source-unreachable` | 502 | git could not reach '*remote*', or fetch it (at '*ref*'): *reason*. |
160
+ | `ref-missing` | 404 | '*remote*' has no branch or tag '*ref*', or names no default branch. |
161
+ | `source-moved` | 409 | '*source*' *ref* now names *current*; this skill was added at *commit*. Recovery: Remove the skill and add it again to take the current commit. |
162
+ | `source-is-plugin` | 422 | '*source*' is an Agent Plugin, not a skill. |
163
+ | `source-unsafe` | 422 | '*path*' links outside its skill, or is neither a file, a directory, nor an inward link. |
164
+ | `skill-not-found` | 404 | '*source*' carries no Agent Skill named '*name*'. |
165
+ | `skill-ambiguous` | 409 | '*source*' carries *count* skills named '*name*'. |
166
+ | `alias-mismatch` | 400 | Alias '*alias*' must equal the skill name '*name*'. |
167
+ | `source-required` | 400 | Adding '*alias*' requires the source that provides it. |
168
+ | `install-failed` | 500 | Agent Skill '*name*' could not be placed under *root*: *cause*. |
169
+ | `skill-missing` | 404 | Agent Skill '*alias*' is not provided by this service. |
170
+ | `skill-invalid` | 422 | Agent Skill '*alias*' is not a valid standard skill: *cause*. |
@@ -0,0 +1,35 @@
1
+ import { type ProvidedSkillsSeam, type SkillTree } from "@plurnk/plurnk-agent-skills";
2
+ import { type FunctionalityCandidate, type FunctionalityDiscoverQuery, type JsonSchema, type SkillDefinition } from "@plurnk/plurnk-contracts";
3
+ import type { WorkspacePluginsSeam } from "@plurnk/plurnk-agent-plugins";
4
+ import type { FunctionalityDefinitionSource, FunctionalityFamilyHandle, FunctionalityPreparation, FunctionalityPrepared, FunctionalityServiceDefinition, WorkspaceCapabilityIdentity } from "@plurnk/plurnk-contracts";
5
+ import type { FunctionalityAdapter, FunctionalityDiscovery, ModuleSetupSeam } from "@plurnk/plurnk-modules";
6
+ export type SourceSeam = Pick<ModuleSetupSeam, "workspacePaths" | "workspaceStateDirectory" | "operatorEnvironment"> & WorkspacePluginsSeam & ProvidedSkillsSeam;
7
+ export declare const serviceSkills: (env?: NodeJS.ProcessEnv) => ReadonlyMap<string, SkillDefinition>;
8
+ export default class SkillsFunctionality implements FunctionalityAdapter {
9
+ #private;
10
+ readonly family = "skills";
11
+ readonly aliasPattern: RegExp;
12
+ readonly namespaceOwner = "@plurnk/plurnk-skills";
13
+ readonly summary = "Manage Agent Skills";
14
+ readonly definitionSchema: JsonSchema;
15
+ readonly example: {
16
+ alias: string;
17
+ definition: {
18
+ name: string;
19
+ source: string;
20
+ };
21
+ };
22
+ readonly docsDir: string;
23
+ readonly discovery: FunctionalityDiscovery;
24
+ constructor(seam: SourceSeam);
25
+ static validateConfiguration(): void;
26
+ attach(handle: FunctionalityFamilyHandle): void;
27
+ trees(workspaceId: number): ReadonlyMap<string, SkillTree>;
28
+ refreshIfChanged(identity: WorkspaceCapabilityIdentity): Promise<void>;
29
+ available(identity: WorkspaceCapabilityIdentity): Promise<readonly FunctionalityServiceDefinition[]>;
30
+ discover(query: FunctionalityDiscoverQuery, identity: WorkspaceCapabilityIdentity): Promise<readonly FunctionalityCandidate[]>;
31
+ admit(input: unknown, identity: WorkspaceCapabilityIdentity): Promise<FunctionalityDefinitionSource>;
32
+ prepare(preparation: FunctionalityPreparation): Promise<FunctionalityPrepared>;
33
+ teardown(_snapshot: unknown, identity: WorkspaceCapabilityIdentity): Promise<void>;
34
+ }
35
+ //# sourceMappingURL=Functionality.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Functionality.d.ts","sourceRoot":"","sources":["../src/Functionality.ts"],"names":[],"mappings":"AAMA,OAAO,EAAkB,KAAK,kBAAkB,EAAE,KAAK,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACtG,OAAO,EAGH,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EACf,KAAK,eAAe,EACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEzE,OAAO,KAAK,EACR,6BAA6B,EAC7B,yBAAyB,EAEzB,wBAAwB,EACxB,qBAAqB,EACrB,8BAA8B,EAC9B,2BAA2B,EAC9B,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,eAAe,EAAkB,MAAM,wBAAwB,CAAC;AAO5H,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE,gBAAgB,GAAG,yBAAyB,GAAG,qBAAqB,CAAC,GAC9G,oBAAoB,GAAG,kBAAkB,CAAC;AA+BhD,eAAO,MAAM,aAAa,SAAS,MAAM,CAAC,UAAU,KAAiB,WAAW,CAAC,MAAM,EAAE,eAAe,CAqBvG,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,mBAAoB,YAAW,oBAAoB;;IACpE,QAAQ,CAAC,MAAM,YAAiB;IAChC,QAAQ,CAAC,YAAY,SAAc;IACnC,QAAQ,CAAC,cAAc,2BAAgB;IACvC,QAAQ,CAAC,OAAO,yBAAyB;IACzC,QAAQ,CAAC,gBAAgB,EAAE,UAAU,CAAc;IACnD,QAAQ,CAAC,OAAO;QAAK,KAAK;QAAmB,UAAU;YAAI,IAAI;YAAmB,MAAM;;MAA4C;IACpI,QAAQ,CAAC,OAAO,SAAsC;IACtD,QAAQ,CAAC,SAAS,EAAE,sBAAsB,CAGxC;IAOF,YAAY,IAAI,EAAE,UAAU,EAG3B;IAGD,MAAM,CAAC,qBAAqB,IAAI,IAAI,CAGnC;IAED,MAAM,CAAC,MAAM,EAAE,yBAAyB,GAAG,IAAI,CAE9C;IAED,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAEzD;IA+EK,gBAAgB,CAAC,QAAQ,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAM3E;IAEK,SAAS,CAAC,QAAQ,EAAE,2BAA2B,GAAG,OAAO,CAAC,SAAS,8BAA8B,EAAE,CAAC,CAqBzG;IAEK,QAAQ,CAAC,KAAK,EAAE,0BAA0B,EAAE,QAAQ,EAAE,2BAA2B,GAAG,OAAO,CAAC,SAAS,sBAAsB,EAAE,CAAC,CAcnI;IAEK,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,2BAA2B,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAwBzG;IA6DK,OAAO,CAAC,WAAW,EAAE,wBAAwB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA4CnF;IAEK,QAAQ,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvF;CACJ"}
@@ -0,0 +1,357 @@
1
+ // {§skills-functionality} — standard Agent Skills as one workspace Functionality
2
+ // family. Configuration roots are inputs; live references and fetched sources
3
+ // belong to workspace definitions, never to an installation scope.
4
+ import { createHash } from "node:crypto";
5
+ import { readdir, readFile, realpath, stat } from "node:fs/promises";
6
+ import { join, resolve } from "node:path";
7
+ import { SkillDirectory } from "@plurnk/plurnk-agent-skills";
8
+ import { SKILL_NAME, Validator, } from "@plurnk/plurnk-contracts";
9
+ import { ConfigurationError, Knob, ResourceEnvironment } from "@plurnk/plurnk-meta";
10
+ import SkillSource from "./SkillSource.js";
11
+ import { SkillsActionError, actionError, messageOf } from "./problems.js";
12
+ const SKILLS_FAMILY = "skills";
13
+ const SKILLS_OWNER = "@plurnk/plurnk-skills";
14
+ const DEFINITION = { $ref: "https://schemas.plurnk.xyz/v0/SkillDefinition.json" };
15
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
16
+ const missing = (cause) => {
17
+ if (cause?.code === "ENOENT")
18
+ return false;
19
+ throw cause;
20
+ };
21
+ const isFile = (path) => stat(path).then((info) => info.isFile(), missing);
22
+ const environment = (env = process.env) => new ResourceEnvironment("PLURNK_SKILLS_", { controls: ["FETCH_TIMEOUT_MS"], settings: [], aliasPattern: SKILL_NAME }, env);
23
+ export const serviceSkills = (env = process.env) => {
24
+ const definitions = new Map();
25
+ for (const [alias, { key, value }] of environment(env).definitions) {
26
+ let definition;
27
+ try {
28
+ definition = Validator.assertSkillDefinition(JSON.parse(value));
29
+ }
30
+ catch (cause) {
31
+ throw new ConfigurationError(key, `${key} must contain a complete SkillDefinition.`, { cause });
32
+ }
33
+ if (definition.name !== alias)
34
+ throw new ConfigurationError(key, `${key}: the definition name must equal '${alias}'.`);
35
+ if (definition.source === undefined)
36
+ throw new ConfigurationError(key, `${key}: a configured skill requires a source.`);
37
+ if (definition.commit !== undefined)
38
+ throw new ConfigurationError(key, `${key}: commit is service-recorded; configure a Git ref instead.`);
39
+ try {
40
+ const remote = SkillSource.remote(definition.source);
41
+ if (definition.ref !== undefined && remote === null)
42
+ throw new Error("A ref names a branch or tag of a git source.");
43
+ }
44
+ catch (cause) {
45
+ throw new ConfigurationError(key, `${key}: invalid skill source or ref.`, { cause });
46
+ }
47
+ definitions.set(alias, definition);
48
+ }
49
+ return definitions;
50
+ };
51
+ export default class SkillsFunctionality {
52
+ family = SKILLS_FAMILY;
53
+ aliasPattern = SKILL_NAME;
54
+ namespaceOwner = SKILLS_OWNER;
55
+ summary = "Manage Agent Skills";
56
+ definitionSchema = DEFINITION;
57
+ example = { alias: "sql-formatter", definition: { name: "sql-formatter", source: "https://git.example/acme/skills.git" } };
58
+ docsDir = resolve(import.meta.dirname, "..");
59
+ discovery = {
60
+ inputs: ["source"],
61
+ details: "`source` lists the Agent Skills one source carries: a git remote as a full https or ssh URL, a folder, a lone SKILL.md, or a zip or tar archive. A candidate carries the exact definition to add.",
62
+ };
63
+ #seam;
64
+ #source;
65
+ #snapshots = new Map();
66
+ #handle = null;
67
+ constructor(seam) {
68
+ this.#seam = seam;
69
+ this.#source = new SkillSource(() => seam.operatorEnvironment());
70
+ }
71
+ // Reads the fetch deadline and the configured definitions without opening a source.
72
+ static validateConfiguration() {
73
+ Knob.integer("PLURNK_SKILLS_FETCH_TIMEOUT_MS", 1);
74
+ serviceSkills();
75
+ }
76
+ attach(handle) {
77
+ this.#handle = handle;
78
+ }
79
+ trees(workspaceId) {
80
+ return this.#snapshots.get(workspaceId)?.trees ?? new Map();
81
+ }
82
+ async #installedIn(scope, dir) {
83
+ let entries;
84
+ try {
85
+ entries = await readdir(dir, { withFileTypes: true });
86
+ }
87
+ catch (cause) {
88
+ if (cause.code === "ENOENT")
89
+ return [];
90
+ throw new Error(`read ${scope} Agent Skills directory ${dir} failed`, { cause });
91
+ }
92
+ const installed = [];
93
+ for (const entry of entries.filter((candidate) => candidate.isDirectory() || candidate.isSymbolicLink())) {
94
+ const file = join(dir, entry.name, "SKILL.md");
95
+ if (await isFile(file))
96
+ installed.push({ name: entry.name, dir: join(dir, entry.name), file });
97
+ }
98
+ return installed.toSorted((left, right) => left.name.localeCompare(right.name));
99
+ }
100
+ // {§agent-plugins-hosting} Standalone skills precede bundles within each host-ordered scope.
101
+ async #scan(workspaceId, { configurationRoots }) {
102
+ const union = new Map();
103
+ const { plugins } = await this.#seam.readWorkspacePlugins(workspaceId);
104
+ const scopes = new Set([...configurationRoots.map(({ scope }) => scope), ...plugins.map(({ scope }) => scope)]);
105
+ for (const scope of scopes) {
106
+ const root = configurationRoots.find((candidate) => candidate.scope === scope);
107
+ const standalone = root === undefined ? [] : await this.#installedIn(scope, join(root.directory, "skills"));
108
+ for (const installed of standalone) {
109
+ if (!union.has(installed.name))
110
+ union.set(installed.name, installed);
111
+ }
112
+ for (const plugin of plugins.filter((candidate) => candidate.scope === scope)) {
113
+ for (const skill of plugin.skills) {
114
+ const name = skill.document.name;
115
+ if (!union.has(name))
116
+ union.set(name, { name, kind: "plugin", dir: skill.directory, file: join(skill.directory, "SKILL.md") });
117
+ }
118
+ }
119
+ }
120
+ return union;
121
+ }
122
+ async #signature(workspaceId, paths, definitions) {
123
+ const hash = createHash("sha256");
124
+ hash.update((await this.#seam.readWorkspacePlugins(workspaceId)).signature);
125
+ for (const [name, tree] of await this.#seam.readProvidedSkills()) {
126
+ hash.update(JSON.stringify([name, "service", tree.document.source]));
127
+ }
128
+ for (const { scope, directory } of paths.configurationRoots) {
129
+ for (const installed of await this.#installedIn(scope, join(directory, "skills"))) {
130
+ const identity = await Promise.all([realpath(installed.dir), readFile(installed.file, "utf8")])
131
+ .catch((cause) => [messageOf(cause)]);
132
+ hash.update(JSON.stringify([installed.name, scope, ...identity]));
133
+ }
134
+ }
135
+ const settings = environment();
136
+ hash.update(JSON.stringify([...serviceSkills()]));
137
+ for (const [alias, raw] of definitions) {
138
+ const definition = raw;
139
+ hash.update(JSON.stringify([alias, definition, settings.enabled(alias)]));
140
+ if (definition.source === undefined)
141
+ continue;
142
+ try {
143
+ const located = await SkillSource.locate(definition.source, paths);
144
+ if (located.kind !== "folder" && located.kind !== "skill-file")
145
+ continue;
146
+ const opened = await this.#source.open(located);
147
+ try {
148
+ for (const found of opened.skills.filter(({ name }) => name === alias)) {
149
+ hash.update(JSON.stringify([await realpath(found.dir), await readFile(join(found.dir, "SKILL.md"), "utf8")]));
150
+ }
151
+ hash.update(JSON.stringify(opened.invalid));
152
+ }
153
+ finally {
154
+ await opened.close();
155
+ }
156
+ }
157
+ catch (cause) {
158
+ // The preparation reports the source failure; its fingerprint lets restoration trigger a retry.
159
+ hash.update(messageOf(cause));
160
+ }
161
+ }
162
+ return hash.digest("hex");
163
+ }
164
+ // {§skills-hotload} — skills placed, edited or deleted out of band are admitted before a turn
165
+ // assembles its packet. Changed content republishes; otherwise the coordinator republishes only
166
+ // when the skills it would publish differ from the published ones.
167
+ async refreshIfChanged(identity) {
168
+ const published = this.#snapshots.get(identity.workspaceId);
169
+ if (published === undefined)
170
+ return;
171
+ const current = await this.#signature(identity.workspaceId, await this.#seam.workspacePaths(identity.workspaceId), published.definitions);
172
+ if (this.#handle === null)
173
+ throw new Error("Skills Functionality is not attached to its coordinator handle.");
174
+ await this.#handle.refresh(identity, { gate: "none", ifChanged: current === published.signature });
175
+ }
176
+ async available(identity) {
177
+ SkillsFunctionality.validateConfiguration();
178
+ const installedSkills = await this.#scan(identity.workspaceId, await this.#seam.workspacePaths(identity.workspaceId));
179
+ const settings = environment();
180
+ const definitions = new Map();
181
+ for (const name of (await this.#seam.readProvidedSkills()).keys()) {
182
+ definitions.set(name, { alias: name, definition: { name }, enabled: settings.enabled(name) });
183
+ }
184
+ for (const { name, dir, file, kind } of installedSkills.values()) {
185
+ definitions.set(name, {
186
+ alias: name, definition: { name, source: dir }, enabled: settings.enabled(name),
187
+ provenance: { kind: kind ?? "file", source: file },
188
+ });
189
+ }
190
+ for (const [name, definition] of serviceSkills()) {
191
+ definitions.set(name, {
192
+ alias: name, definition, enabled: settings.enabled(name),
193
+ provenance: { kind: "environment", source: settings.definitions.get(name).key },
194
+ });
195
+ }
196
+ return [...definitions.values()];
197
+ }
198
+ async discover(query, identity) {
199
+ const source = query.source;
200
+ const located = await SkillSource.locate(source, await this.#seam.workspacePaths(identity.workspaceId));
201
+ const opened = await this.#source.open(located);
202
+ try {
203
+ return opened.skills.map((skill) => ({
204
+ alias: skill.name,
205
+ summary: skill.description,
206
+ definition: { name: skill.name, source },
207
+ provenance: { kind: "source", source },
208
+ }));
209
+ }
210
+ finally {
211
+ await opened.close();
212
+ }
213
+ }
214
+ async admit(input, identity) {
215
+ const params = isRecord(input) ? input : {};
216
+ let definition;
217
+ try {
218
+ definition = structuredClone(Validator.assertSkillDefinition(structuredClone(params.definition)));
219
+ }
220
+ catch (cause) {
221
+ throw actionError("definition-invalid", 400, "The Agent Skill definition is invalid.", { retryable: false }, cause);
222
+ }
223
+ const alias = typeof params.alias === "string" ? params.alias : definition.name;
224
+ if (alias !== definition.name) {
225
+ throw actionError("alias-mismatch", 400, `Alias '${alias}' must equal the skill name '${definition.name}'.`, { alias, name: definition.name, retryable: false });
226
+ }
227
+ if (definition.commit !== undefined) {
228
+ throw actionError("definition-invalid", 400, "The service records the commit a skill was added at; name a ref instead.", { alias, retryable: false });
229
+ }
230
+ if (definition.source === undefined) {
231
+ throw actionError("source-required", 400, `Adding '${alias}' requires the source that provides it.`, { alias, retryable: false });
232
+ }
233
+ const located = await SkillSource.locate(definition.source, await this.#seam.workspacePaths(identity.workspaceId));
234
+ if (located.kind !== "git") {
235
+ if (definition.ref !== undefined)
236
+ throw actionError("definition-invalid", 400, "A ref names a branch or tag of a git source.", { alias, retryable: false });
237
+ return { alias, definition: { ...definition, source: located.location } };
238
+ }
239
+ return { alias, definition: { ...definition, commit: await this.#source.resolveCommit(located.location, definition.ref) } };
240
+ }
241
+ // {§skills-sources} — complete source identity owns a reusable materialization within one workspace.
242
+ async #loadSource(definition, workspaceId, paths) {
243
+ const key = createHash("sha256").update(JSON.stringify([
244
+ definition.name, definition.source, definition.ref ?? null, definition.commit ?? null,
245
+ ])).digest("hex");
246
+ const root = join(await this.#seam.workspaceStateDirectory(workspaceId, SKILLS_OWNER), key);
247
+ const cached = join(root, definition.name);
248
+ if (await isFile(join(cached, "SKILL.md")))
249
+ return this.#loadDirectory(definition.name, cached);
250
+ const located = await SkillSource.locate(definition.source, paths);
251
+ const opened = await this.#source.open(located, {
252
+ ...(definition.ref === undefined ? {} : { ref: definition.ref }),
253
+ ...(definition.commit === undefined ? {} : { commit: definition.commit }),
254
+ });
255
+ try {
256
+ const matches = opened.skills.filter(({ name }) => name === definition.name);
257
+ if (matches.length > 1) {
258
+ throw actionError("skill-ambiguous", 409, `'${definition.source}' carries ${matches.length} skills named '${definition.name}'.`, {
259
+ name: definition.name, source: definition.source, retryable: false,
260
+ });
261
+ }
262
+ const match = matches[0];
263
+ if (match === undefined) {
264
+ const broken = opened.invalid.find(({ dir }) => dir.endsWith(`/${definition.name}`));
265
+ if (broken !== undefined) {
266
+ throw actionError("skill-invalid", 422, `Agent Skill '${definition.name}' in '${definition.source}' is not a valid standard skill: ${broken.reason}`, {
267
+ name: definition.name, source: definition.source, retryable: false,
268
+ });
269
+ }
270
+ throw actionError("skill-not-found", 404, `'${definition.source}' carries no Agent Skill named '${definition.name}'.`, {
271
+ name: definition.name, source: definition.source, retryable: false,
272
+ });
273
+ }
274
+ if (located.kind === "folder" || located.kind === "skill-file") {
275
+ await SkillSource.assertInward(match.dir);
276
+ return await this.#loadDirectory(definition.name, match.dir);
277
+ }
278
+ let dir;
279
+ try {
280
+ dir = await SkillSource.install(match, root);
281
+ }
282
+ catch (cause) {
283
+ if (cause instanceof SkillsActionError)
284
+ throw cause;
285
+ throw actionError("install-failed", 500, `Agent Skill '${definition.name}' could not be placed under ${root}: ${messageOf(cause)}`, {
286
+ name: definition.name, retryable: false,
287
+ }, cause);
288
+ }
289
+ return await this.#loadDirectory(definition.name, dir);
290
+ }
291
+ finally {
292
+ await opened.close();
293
+ }
294
+ }
295
+ async #loadDirectory(alias, dir) {
296
+ try {
297
+ return await SkillDirectory.load(dir);
298
+ }
299
+ catch (cause) {
300
+ throw actionError("skill-invalid", 422, `Agent Skill '${alias}' is not a valid standard skill: ${messageOf(cause)}`, { name: alias, path: join(dir, "SKILL.md"), retryable: false }, cause);
301
+ }
302
+ }
303
+ async prepare(preparation) {
304
+ const paths = await this.#seam.workspacePaths(preparation.workspaceId);
305
+ const definitions = new Map([...preparation.enabled].map(([alias, { definition }]) => [alias, definition]));
306
+ // Read before the skills it describes, so content changed while they load is seen as changed.
307
+ const signature = await this.#signature(preparation.workspaceId, paths, definitions);
308
+ const provided = await this.#seam.readProvidedSkills();
309
+ const previous = preparation.previous;
310
+ const carried = new Set(previous?.unavailable ?? []);
311
+ const outcomes = new Map();
312
+ const trees = new Map();
313
+ for (const [alias, raw] of definitions) {
314
+ preparation.progress(alias);
315
+ const definition = raw;
316
+ try {
317
+ const tree = definition.source === undefined ? provided.get(alias)
318
+ : await this.#loadSource(definition, preparation.workspaceId, paths);
319
+ if (tree === undefined)
320
+ throw actionError("skill-missing", 404, `Agent Skill '${alias}' is not provided by this service.`, { name: alias, retryable: false });
321
+ trees.set(new URL(`skill://${alias}/`).hostname, tree);
322
+ outcomes.set(alias, { state: "active", detail: {
323
+ ...(tree instanceof SkillDirectory ? { path: tree.directory } : {}),
324
+ description: tree.document.description,
325
+ } });
326
+ }
327
+ catch (cause) {
328
+ if (!(cause instanceof SkillsActionError))
329
+ throw cause;
330
+ const fresh = !carried.has(alias) || preparation.force === alias;
331
+ if (preparation.failure === "reject" && fresh)
332
+ throw cause;
333
+ if (fresh)
334
+ console.error(`Agent Skill '${alias}' unavailable: ${cause.problem.detail}`);
335
+ outcomes.set(alias, { state: "unavailable", problem: structuredClone(cause.problem) });
336
+ }
337
+ }
338
+ const snapshot = {
339
+ signature,
340
+ trees,
341
+ definitions,
342
+ unavailable: [...outcomes].filter(([, outcome]) => outcome.state === "unavailable").map(([alias]) => alias),
343
+ };
344
+ const { workspaceId } = preparation;
345
+ return {
346
+ documents: [],
347
+ outcomes,
348
+ snapshot,
349
+ commit: async () => { this.#snapshots.set(workspaceId, snapshot); },
350
+ abort: async () => { },
351
+ };
352
+ }
353
+ async teardown(_snapshot, identity) {
354
+ this.#snapshots.delete(identity.workspaceId);
355
+ }
356
+ }
357
+ //# sourceMappingURL=Functionality.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Functionality.js","sourceRoot":"","sources":["../src/Functionality.ts"],"names":[],"mappings":"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"}