dsh-pstack 0.0.0-stage → 0.2.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 +22 -0
- package/README.md +133 -2
- package/assets/agents/comment-sicko.md +32 -0
- package/assets/agents/poteto-agent.md +8 -0
- package/assets/docs/guide/01-setup.md +64 -0
- package/assets/docs/guide/02-poteto-mode.md +139 -0
- package/assets/docs/guide/03-understand.md +79 -0
- package/assets/docs/guide/04-design.md +133 -0
- package/assets/docs/guide/05-build-and-clean.md +83 -0
- package/assets/docs/guide/06-verify-and-ship.md +152 -0
- package/assets/docs/guide/07-overnight.md +120 -0
- package/assets/docs/guide/08-principles.md +72 -0
- package/assets/docs/guide/09-make-it-yours.md +96 -0
- package/assets/docs/guide/10-recipes-and-pitfalls.md +180 -0
- package/assets/docs/guide/README.md +38 -0
- package/assets/docs/guide/images/design.jpg +0 -0
- package/assets/docs/guide/images/overnight.jpg +0 -0
- package/assets/docs/guide/images/recipes.jpg +0 -0
- package/assets/docs/guide/images/router.jpg +0 -0
- package/assets/docs/guide/images/understanding.jpg +0 -0
- package/assets/docs/guide/images/verification.jpg +0 -0
- package/assets/docs/harness/dsh.md +60 -0
- package/assets/docs/pstack-models.example.md +54 -0
- package/assets/skills/architect/SKILL.md +81 -0
- package/assets/skills/architect/references/design-red-flags.md +57 -0
- package/assets/skills/architect/references/rationale-template.md +35 -0
- package/assets/skills/architect/references/runner-prompt.md +20 -0
- package/assets/skills/arena/SKILL.md +50 -0
- package/assets/skills/automate-me/SKILL.md +106 -0
- package/assets/skills/benchmark-checklist/SKILL.md +39 -0
- package/assets/skills/blast-radius/SKILL.md +52 -0
- package/assets/skills/bro/SKILL.md +7 -0
- package/assets/skills/correct/SKILL.md +32 -0
- package/assets/skills/create-formal-verification-skill/SKILL.md +43 -0
- package/assets/skills/create-verification-skill/SKILL.md +46 -0
- package/assets/skills/create-verification-skill/references/feature-map-example/README.md +47 -0
- package/assets/skills/create-verification-skill/references/feature-map-example/create-note.md +39 -0
- package/assets/skills/create-verification-skill/references/feature-map-example/search.md +45 -0
- package/assets/skills/figure-it-out/SKILL.md +54 -0
- package/assets/skills/how/SKILL.md +38 -0
- package/assets/skills/how/references/explainer-prompt.md +55 -0
- package/assets/skills/how/references/explorer-prompt.md +35 -0
- package/assets/skills/in-your-own-words/SKILL.md +7 -0
- package/assets/skills/interrogate/SKILL.md +71 -0
- package/assets/skills/interrogate/references/code-quality-review.md +47 -0
- package/assets/skills/interrogate/references/lead-judgment.md +39 -0
- package/assets/skills/interrogate/references/reviewer-prompt.md +62 -0
- package/assets/skills/interrogate/references/rubric.md +77 -0
- package/assets/skills/ketchup/SKILL.md +45 -0
- package/assets/skills/maintain-formal-verification-skill/SKILL.md +60 -0
- package/assets/skills/maintain-verification-skill/SKILL.md +41 -0
- package/assets/skills/no-comments/SKILL.md +26 -0
- package/assets/skills/poteto-help/SKILL.md +162 -0
- package/assets/skills/poteto-help/references/prompting.md +51 -0
- package/assets/skills/poteto-help/references/recipes.md +51 -0
- package/assets/skills/poteto-mode/SKILL.md +151 -0
- package/assets/skills/poteto-mode/playbooks/authoring-a-skill.md +12 -0
- package/assets/skills/poteto-mode/playbooks/autonomous-run.md +15 -0
- package/assets/skills/poteto-mode/playbooks/autopilot-full.md +25 -0
- package/assets/skills/poteto-mode/playbooks/autopilot-stack.md +12 -0
- package/assets/skills/poteto-mode/playbooks/babysit.md +23 -0
- package/assets/skills/poteto-mode/playbooks/bug-fix.md +15 -0
- package/assets/skills/poteto-mode/playbooks/eval.md +25 -0
- package/assets/skills/poteto-mode/playbooks/feature.md +21 -0
- package/assets/skills/poteto-mode/playbooks/hillclimb.md +21 -0
- package/assets/skills/poteto-mode/playbooks/investigation.md +14 -0
- package/assets/skills/poteto-mode/playbooks/multi-phase-plan.md +155 -0
- package/assets/skills/poteto-mode/playbooks/opening-a-pr.md +34 -0
- package/assets/skills/poteto-mode/playbooks/orchestrate.md +112 -0
- package/assets/skills/poteto-mode/playbooks/pause-safely.md +10 -0
- package/assets/skills/poteto-mode/playbooks/perf-issue.md +25 -0
- package/assets/skills/poteto-mode/playbooks/prototype.md +14 -0
- package/assets/skills/poteto-mode/playbooks/refactoring.md +16 -0
- package/assets/skills/poteto-mode/playbooks/runtime-forensics.md +11 -0
- package/assets/skills/poteto-mode/playbooks/session-pickup.md +11 -0
- package/assets/skills/poteto-mode/playbooks/shipping.md +12 -0
- package/assets/skills/poteto-mode/playbooks/trace-forensics.md +14 -0
- package/assets/skills/poteto-mode/playbooks/visual-parity.md +11 -0
- package/assets/skills/poteto-mode/playbooks/worktree-cleanup.md +20 -0
- package/assets/skills/poteto-mode/references/bugbot-triage.md +142 -0
- package/assets/skills/poteto-mode/scripts/check-plan.mjs +220 -0
- package/assets/skills/poteto-mode/scripts/check-plan.test.mjs +343 -0
- package/assets/skills/poteto-mode/scripts/orch/orch.mjs +4282 -0
- package/assets/skills/poteto-mode/scripts/orch/orch.test.mjs +2042 -0
- package/assets/skills/poteto-mode/scripts/watch-pr/cli.test.mjs +5101 -0
- package/assets/skills/poteto-mode/scripts/watch-pr/github.test.mjs +1177 -0
- package/assets/skills/poteto-mode/scripts/watch-pr/policy.test.mjs +1441 -0
- package/assets/skills/poteto-mode/scripts/watch-pr/watch-pr.mjs +4601 -0
- package/assets/skills/poteto-mode/scripts/worktree-audit.mjs +675 -0
- package/assets/skills/principle-attack-the-premise/SKILL.md +21 -0
- package/assets/skills/principle-boundary-discipline/SKILL.md +34 -0
- package/assets/skills/principle-build-the-lever/SKILL.md +23 -0
- package/assets/skills/principle-encode-lessons-in-structure/SKILL.md +11 -0
- package/assets/skills/principle-exhaust-the-design-space/SKILL.md +9 -0
- package/assets/skills/principle-experience-first/SKILL.md +19 -0
- package/assets/skills/principle-explain-the-number/SKILL.md +17 -0
- package/assets/skills/principle-fix-root-causes/SKILL.md +21 -0
- package/assets/skills/principle-foundational-thinking/SKILL.md +21 -0
- package/assets/skills/principle-guard-the-context-window/SKILL.md +12 -0
- package/assets/skills/principle-laziness-protocol/SKILL.md +10 -0
- package/assets/skills/principle-make-operations-idempotent/SKILL.md +22 -0
- package/assets/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +14 -0
- package/assets/skills/principle-minimize-reader-load/SKILL.md +18 -0
- package/assets/skills/principle-model-the-domain/SKILL.md +24 -0
- package/assets/skills/principle-never-block-on-the-human/SKILL.md +15 -0
- package/assets/skills/principle-outcome-oriented-execution/SKILL.md +21 -0
- package/assets/skills/principle-prove-it-works/SKILL.md +24 -0
- package/assets/skills/principle-redesign-from-first-principles/SKILL.md +16 -0
- package/assets/skills/principle-separate-before-serializing-shared-state/SKILL.md +16 -0
- package/assets/skills/principle-sequence-verifiable-units/SKILL.md +17 -0
- package/assets/skills/principle-subtract-before-you-add/SKILL.md +18 -0
- package/assets/skills/principle-test-behavior-not-implementation/SKILL.md +20 -0
- package/assets/skills/principle-type-system-discipline/SKILL.md +13 -0
- package/assets/skills/recall/SKILL.md +37 -0
- package/assets/skills/reflect/SKILL.md +69 -0
- package/assets/skills/reflect/references/divergent-reviewer.md +38 -0
- package/assets/skills/reflect/references/judgment-reviewer.md +37 -0
- package/assets/skills/reflect/references/synthesizer.md +56 -0
- package/assets/skills/reflect/references/tooling-reviewer.md +48 -0
- package/assets/skills/setup-pstack/SKILL.md +67 -0
- package/assets/skills/sharpen/SKILL.md +16 -0
- package/assets/skills/show-me-your-work/SKILL.md +84 -0
- package/assets/skills/show-me-your-work/references/decision-log-template.tsv +1 -0
- package/assets/skills/show-me-your-work/scripts/log.mjs +108 -0
- package/assets/skills/swarm/SKILL.md +43 -0
- package/assets/skills/tdd/SKILL.md +42 -0
- package/assets/skills/teach/SKILL.md +23 -0
- package/assets/skills/technical-writing/SKILL.md +108 -0
- package/assets/skills/typescript-best-practices/SKILL.md +34 -0
- package/assets/skills/typescript-best-practices/references/patterns.md +328 -0
- package/assets/skills/unslop/SKILL.md +62 -0
- package/assets/skills/why/SKILL.md +100 -0
- package/assets/skills/why/references/epistemics.md +71 -0
- package/assets/skills/why/references/investigator-prompt.md +84 -0
- package/assets/skills/why/references/source-playbook.md +17 -0
- package/assets/skills/why/references/sources/code-archaeology.md +51 -0
- package/assets/skills/why/references/sources/databricks.md +70 -0
- package/assets/skills/why/references/sources/datadog.md +97 -0
- package/assets/skills/why/references/sources/incident-postmortem.md +5 -0
- package/assets/skills/why/references/sources/linear.md +48 -0
- package/assets/skills/why/references/sources/notion.md +55 -0
- package/assets/skills/why/references/sources/sentry.md +66 -0
- package/assets/skills/why/references/sources/slack.md +17 -0
- package/assets/skills/why/references/synthesizer-prompt.md +129 -0
- package/cordis.patch.yml +39 -0
- package/dist/frontmatter-BQX3ekwP.mjs +229 -0
- package/dist/frontmatter-BQX3ekwP.mjs.map +1 -0
- package/dist/history.d.mts +429 -0
- package/dist/history.mjs +1129 -0
- package/dist/history.mjs.map +1 -0
- package/dist/host-contract-o47JH_r8.d.mts +527 -0
- package/dist/index.d.mts +278 -0
- package/dist/index.mjs +272 -0
- package/dist/index.mjs.map +1 -0
- package/dist/paths-D_JlVmBk.mjs +42 -0
- package/dist/paths-D_JlVmBk.mjs.map +1 -0
- package/dist/script.d.mts +193 -0
- package/dist/script.mjs +782 -0
- package/dist/script.mjs.map +1 -0
- package/dist/subagent.d.mts +336 -0
- package/dist/subagent.mjs +1402 -0
- package/dist/subagent.mjs.map +1 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +106 -3
- package/static/icon.png +0 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
//#region src/provider.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* The bundled pstack skill provider: one provider over the 55 generated skills
|
|
4
|
+
* that ship inside this package.
|
|
5
|
+
*
|
|
6
|
+
* The provider contract below mirrors `@deepseek-ai/dsh-skill` 0.2.1-rc.3, which
|
|
7
|
+
* was read through the host Inspect provider (`Service.listService` with
|
|
8
|
+
* `service: "skills"`) and the installed type declarations. It is restated here
|
|
9
|
+
* as a structural contract instead of imported so the plugin keeps zero runtime
|
|
10
|
+
* imports from the host packages: a workspace-directory bundle is linked from
|
|
11
|
+
* its checkout, where `@deepseek-ai/*` is not resolvable.
|
|
12
|
+
*
|
|
13
|
+
* Design constraints this module enforces, from the port design document §8.1:
|
|
14
|
+
*
|
|
15
|
+
* - The catalog is built once from the package assets and never watched. A
|
|
16
|
+
* package update is the refresh boundary.
|
|
17
|
+
* - A malformed bundled skill fails the whole index instead of disappearing
|
|
18
|
+
* from the catalog, so a broken asset is a startup error rather than a skill
|
|
19
|
+
* users silently cannot see.
|
|
20
|
+
* - `get()` only accepts a locator this provider produced. Directory names are
|
|
21
|
+
* never joined from caller input.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Standard precedence rank for packaged skill providers, re-exported by
|
|
25
|
+
* `@deepseek-ai/dsh-skill` as `BUNDLED_SKILL_RANK`. Restated to keep the package
|
|
26
|
+
* dependency-free; a mismatch only changes which provider wins a name collision.
|
|
27
|
+
*/
|
|
28
|
+
export declare const BUNDLED_SKILL_RANK = 600;
|
|
29
|
+
/** Default provider name used when the row does not override it. */
|
|
30
|
+
export declare const DEFAULT_PROVIDER_NAME = "pstack";
|
|
31
|
+
/** Origin bucket for a skill contribution. */
|
|
32
|
+
type SkillSource = "project-dsh" | "project-agents" | "runtime" | "user-dsh" | "user-agents" | "custom" | "bundled" | (string & {});
|
|
33
|
+
/** Optional provider-specific base used by loaded skill bodies to resolve relative resources. */
|
|
34
|
+
type SkillResourceBase = {
|
|
35
|
+
readonly kind: "directory";
|
|
36
|
+
readonly path: string;
|
|
37
|
+
} | {
|
|
38
|
+
readonly kind: "url";
|
|
39
|
+
readonly url: string;
|
|
40
|
+
} | {
|
|
41
|
+
readonly kind: "opaque";
|
|
42
|
+
readonly description: string;
|
|
43
|
+
};
|
|
44
|
+
/** Invocation controls shared by skill discovery consumers. */
|
|
45
|
+
interface SkillInvocationPolicy {
|
|
46
|
+
/** Whether model-facing catalogs and loaders include this skill. */
|
|
47
|
+
readonly modelInvocable: boolean;
|
|
48
|
+
/** Whether human-facing command catalogs and loaders include this skill. */
|
|
49
|
+
readonly userInvocable: boolean;
|
|
50
|
+
}
|
|
51
|
+
/** Invocation-neutral skill metadata returned by `ctx.skills.list()`. */
|
|
52
|
+
interface SkillSummary {
|
|
53
|
+
/** Absolute instruction file path. */
|
|
54
|
+
readonly path?: string;
|
|
55
|
+
/** Kebab-case identifier used to address the skill. */
|
|
56
|
+
readonly name: string;
|
|
57
|
+
/** Short routing description shown by discovery consumers. */
|
|
58
|
+
readonly description: string;
|
|
59
|
+
/** Optional extra routing guidance. */
|
|
60
|
+
readonly whenToUse?: string;
|
|
61
|
+
/** Resolved model and user invocation controls. */
|
|
62
|
+
readonly invocation: SkillInvocationPolicy;
|
|
63
|
+
/** Discovery source that produced this skill. */
|
|
64
|
+
readonly source: SkillSource;
|
|
65
|
+
/** Provider that owns this skill body. */
|
|
66
|
+
readonly provider: string;
|
|
67
|
+
/** Provider-specific base for relative resources. */
|
|
68
|
+
readonly resourceBase?: SkillResourceBase;
|
|
69
|
+
}
|
|
70
|
+
/** Provider catalog entry used by the registry to merge and later load skills. */
|
|
71
|
+
interface SkillCandidate extends SkillSummary {
|
|
72
|
+
/** Lower ranks win duplicate skill names. */
|
|
73
|
+
readonly rank: number;
|
|
74
|
+
/** Opaque provider-owned handle passed back to `provider.get()`. */
|
|
75
|
+
readonly locator: unknown;
|
|
76
|
+
/** Parsed optional metadata object from provider-specific skill frontmatter. */
|
|
77
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
78
|
+
}
|
|
79
|
+
/** Complete parsed skill definition, including the body loaded by `ctx.skills.get()`. */
|
|
80
|
+
interface SkillDefinition extends SkillSummary {
|
|
81
|
+
/** Markdown instruction body after frontmatter removal. */
|
|
82
|
+
readonly content: string;
|
|
83
|
+
/** Parsed optional metadata object from frontmatter. */
|
|
84
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
85
|
+
}
|
|
86
|
+
/** Caller context used for cwd-sensitive and abortable provider work. */
|
|
87
|
+
interface SkillLookupOptions {
|
|
88
|
+
/** Workspace selector for the current lookup. */
|
|
89
|
+
readonly cwd?: string | undefined;
|
|
90
|
+
/** Abort discovery or loading work for the current caller. */
|
|
91
|
+
readonly signal?: AbortSignal | undefined;
|
|
92
|
+
}
|
|
93
|
+
/** Registration-scoped lifecycle capability handed to a provider factory. */
|
|
94
|
+
interface SkillProviderControl {
|
|
95
|
+
/** Aborts when registration fails or the exact provider registration is disposed. */
|
|
96
|
+
readonly signal: AbortSignal;
|
|
97
|
+
/** Invalidate completed catalogs and notify consumers. */
|
|
98
|
+
readonly invalidate: () => void;
|
|
99
|
+
}
|
|
100
|
+
/** Provider interface for one source of skills. */
|
|
101
|
+
interface SkillProvider {
|
|
102
|
+
/** Unique provider name in the `ctx.skills` registry. */
|
|
103
|
+
readonly name: string;
|
|
104
|
+
/** List available skill candidates for the current lookup context. */
|
|
105
|
+
readonly list: (options: SkillLookupOptions) => Promise<readonly SkillCandidate[]>;
|
|
106
|
+
/** Load a complete skill body for a previously listed candidate. */
|
|
107
|
+
readonly get: (candidate: SkillCandidate, options: SkillLookupOptions) => Promise<SkillDefinition | undefined>;
|
|
108
|
+
}
|
|
109
|
+
/** One validated on-disk bundled skill. */
|
|
110
|
+
interface BundledSkill {
|
|
111
|
+
readonly name: string;
|
|
112
|
+
readonly description: string;
|
|
113
|
+
readonly whenToUse?: string;
|
|
114
|
+
readonly invocation: SkillInvocationPolicy;
|
|
115
|
+
/** Absolute skill directory; the candidate resource base. */
|
|
116
|
+
readonly directory: string;
|
|
117
|
+
/** Absolute `SKILL.md` path. */
|
|
118
|
+
readonly instructionFile: string;
|
|
119
|
+
}
|
|
120
|
+
/** Validated skills keyed by their absolute directory. */
|
|
121
|
+
type BundledSkillIndex = ReadonlyMap<string, BundledSkill>;
|
|
122
|
+
/** Raised when a bundled asset violates the provider contract. */
|
|
123
|
+
export declare class BundledSkillError extends Error {
|
|
124
|
+
constructor(message: string);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Read and validate every bundled skill below one directory.
|
|
128
|
+
*
|
|
129
|
+
* This is the startup check: it runs before the provider registers, so a missing
|
|
130
|
+
* `SKILL.md`, an invalid frontmatter block, or a name that disagrees with its
|
|
131
|
+
* directory fails plugin activation with a path-qualified message instead of
|
|
132
|
+
* dropping a skill from the catalog.
|
|
133
|
+
*
|
|
134
|
+
* @param skillsRoot - absolute path of the directory holding the skill directories.
|
|
135
|
+
* @returns validated skills keyed by absolute skill directory, sorted by name.
|
|
136
|
+
* @throws {BundledSkillError} when the tree or any skill in it is malformed.
|
|
137
|
+
*/
|
|
138
|
+
export declare function loadBundledSkillIndex(skillsRoot: string): BundledSkillIndex;
|
|
139
|
+
/**
|
|
140
|
+
* Build the provider over an already validated index.
|
|
141
|
+
*
|
|
142
|
+
* @param index - result of {@link loadBundledSkillIndex}.
|
|
143
|
+
* @param providerName - registry name for this provider.
|
|
144
|
+
* @returns a read-only provider whose catalog never changes until the package does.
|
|
145
|
+
*/
|
|
146
|
+
export declare function createPstackSkillProvider(index: BundledSkillIndex, providerName?: string): SkillProvider;
|
|
147
|
+
/**
|
|
148
|
+
* Load the index and build the provider in one step, failing on a malformed tree.
|
|
149
|
+
*
|
|
150
|
+
* `apply()` uses this exact function, so the startup failure path and the
|
|
151
|
+
* provider used in tests are the same code.
|
|
152
|
+
*
|
|
153
|
+
* @param skillsRoot - absolute path of the bundled skill root.
|
|
154
|
+
* @param providerName - registry name for this provider.
|
|
155
|
+
* @returns the provider over the validated index.
|
|
156
|
+
*/
|
|
157
|
+
export declare function createPstackSkillProviderFromRoot(skillsRoot: string, providerName?: string): SkillProvider;
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region src/paths.d.ts
|
|
160
|
+
/**
|
|
161
|
+
* Package-internal resource locations.
|
|
162
|
+
*
|
|
163
|
+
* The provider reads generated assets in place instead of copying them into a
|
|
164
|
+
* user-visible skills directory, so every path here is resolved from this
|
|
165
|
+
* module's own location. The modules run from `src/` in a checkout and from the
|
|
166
|
+
* bundled `dist/index.mjs` in an installed package; both sit one directory below
|
|
167
|
+
* the package root, so the same expression holds in both cases.
|
|
168
|
+
*/
|
|
169
|
+
/** Absolute path of the package root: the repository in a checkout, the install directory after packing. */
|
|
170
|
+
export declare const PACKAGE_ROOT: string;
|
|
171
|
+
/** Absolute path of the generated, committed assets directory. */
|
|
172
|
+
export declare const ASSETS_ROOT: string;
|
|
173
|
+
/** Absolute path of the directory holding the 55 bundled skill directories. */
|
|
174
|
+
export declare const SKILLS_ROOT: string;
|
|
175
|
+
/** Absolute path of the generated harness mapping document. */
|
|
176
|
+
export declare const HARNESS_DOC_PATH: string;
|
|
177
|
+
//#endregion
|
|
178
|
+
//#region src/frontmatter.d.ts
|
|
179
|
+
/**
|
|
180
|
+
* Frontmatter parsing for pstack skills and agents.
|
|
181
|
+
*
|
|
182
|
+
* This is a deliberately small YAML subset, not YAML. It reads the shapes the
|
|
183
|
+
* upstream files use: plain scalars, single and double quotes, folded (`>` and
|
|
184
|
+
* `>-`) and literal (`|` and `|-`) blocks, comments, and blank lines. Nesting
|
|
185
|
+
* and multi-document streams are rejected rather than half-supported.
|
|
186
|
+
*/
|
|
187
|
+
export interface Frontmatter {
|
|
188
|
+
readonly data: Readonly<Record<string, string>>;
|
|
189
|
+
readonly body: string;
|
|
190
|
+
}
|
|
191
|
+
export interface SkillFrontmatter {
|
|
192
|
+
readonly name: string;
|
|
193
|
+
readonly description: string;
|
|
194
|
+
readonly disableModelInvocation: boolean;
|
|
195
|
+
readonly userInvocable: boolean;
|
|
196
|
+
readonly whenToUse?: string;
|
|
197
|
+
}
|
|
198
|
+
export interface AgentFrontmatter {
|
|
199
|
+
readonly name: string;
|
|
200
|
+
readonly description: string;
|
|
201
|
+
}
|
|
202
|
+
export interface DroppedFrontmatterField {
|
|
203
|
+
readonly file: string;
|
|
204
|
+
readonly field: string;
|
|
205
|
+
readonly value: string;
|
|
206
|
+
}
|
|
207
|
+
export declare const SKILL_CONSUMED_FIELDS: readonly ["name", "description", "disable-model-invocation", "user-invocable", "whenToUse"];
|
|
208
|
+
export declare const SKILL_DROPPED_FIELDS: readonly ["icon", "color", "paths"];
|
|
209
|
+
export declare const AGENT_CONSUMED_FIELDS: readonly ["name", "description"];
|
|
210
|
+
export declare const AGENT_DROPPED_FIELDS: readonly ["is_background"];
|
|
211
|
+
export declare const MAX_SKILL_NAME_LENGTH = 64;
|
|
212
|
+
export declare class FrontmatterError extends Error {
|
|
213
|
+
constructor(message: string);
|
|
214
|
+
}
|
|
215
|
+
export declare function parseFrontmatter(source: string): Frontmatter;
|
|
216
|
+
export declare function validateSkillFrontmatter(data: Readonly<Record<string, string>>, source: string): SkillFrontmatter;
|
|
217
|
+
export declare function validateAgentFrontmatter(data: Readonly<Record<string, string>>, source: string): AgentFrontmatter;
|
|
218
|
+
export declare function serializeSkillFrontmatter(data: SkillFrontmatter): string;
|
|
219
|
+
export declare function serializeAgentFrontmatter(data: AgentFrontmatter): string;
|
|
220
|
+
export declare function skillDroppedFields(data: Readonly<Record<string, string>>, source: string): readonly DroppedFrontmatterField[];
|
|
221
|
+
export declare function agentDroppedFields(data: Readonly<Record<string, string>>, source: string): readonly DroppedFrontmatterField[];
|
|
222
|
+
//#endregion
|
|
223
|
+
//#region src/index.d.ts
|
|
224
|
+
/** Plugin name used by Loader diagnostics for this row. */
|
|
225
|
+
export declare const name = "pstack";
|
|
226
|
+
/** The provider needs the skill registry and nothing else. */
|
|
227
|
+
export declare const inject: string[];
|
|
228
|
+
/** Row configuration. Every field is optional; an omitted `config` is valid. */
|
|
229
|
+
export interface PstackConfig {
|
|
230
|
+
/** Registry name for the provider; change it when two rows must coexist. */
|
|
231
|
+
readonly providerName?: string;
|
|
232
|
+
}
|
|
233
|
+
interface StandardSchemaIssue {
|
|
234
|
+
readonly message: string;
|
|
235
|
+
readonly path?: readonly (string | number)[];
|
|
236
|
+
}
|
|
237
|
+
type StandardSchemaResult = {
|
|
238
|
+
readonly value: PstackConfig;
|
|
239
|
+
readonly issues?: undefined;
|
|
240
|
+
} | {
|
|
241
|
+
readonly issues: readonly StandardSchemaIssue[];
|
|
242
|
+
};
|
|
243
|
+
/**
|
|
244
|
+
* Minimal Standard Schema validator for this plugin's row config.
|
|
245
|
+
*
|
|
246
|
+
* Cordis validates `apply()`'s second argument with `Config["~standard"]` and
|
|
247
|
+
* substitutes the returned `value`, so an omitted row `config` resolves to the
|
|
248
|
+
* documented defaults without a schemastery dependency.
|
|
249
|
+
*/
|
|
250
|
+
export declare const Config: {
|
|
251
|
+
"~standard": {
|
|
252
|
+
version: number;
|
|
253
|
+
vendor: string;
|
|
254
|
+
validate(value: unknown): StandardSchemaResult;
|
|
255
|
+
};
|
|
256
|
+
};
|
|
257
|
+
/** The slice of the Cordis context this plugin requires. */
|
|
258
|
+
export interface PstackSkillHost {
|
|
259
|
+
readonly skills: {
|
|
260
|
+
registerProvider(create: (control: SkillProviderControl) => SkillProvider): () => void;
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Register the bundled pstack skill provider.
|
|
265
|
+
*
|
|
266
|
+
* The bundled tree is validated before the provider registers, so a malformed
|
|
267
|
+
* `SKILL.md` fails plugin activation with a path-qualified error instead of
|
|
268
|
+
* removing one skill from the catalog. Nothing is copied out of the package and
|
|
269
|
+
* nothing is watched: reinstalling the package is the refresh boundary.
|
|
270
|
+
*
|
|
271
|
+
* @param ctx - host context carrying the skill registry.
|
|
272
|
+
* @param config - validated row config.
|
|
273
|
+
* @throws {import("./provider.ts").BundledSkillError} when the bundled tree is malformed.
|
|
274
|
+
*/
|
|
275
|
+
export declare function apply(ctx: PstackSkillHost, config?: PstackConfig): void;
|
|
276
|
+
//#endregion
|
|
277
|
+
export type { BundledSkill, BundledSkillIndex, SkillCandidate, SkillDefinition, SkillInvocationPolicy, SkillLookupOptions, SkillProvider, SkillProviderControl, SkillResourceBase, SkillSource, SkillSummary };
|
|
278
|
+
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { a as SKILLS_ROOT, n as HARNESS_DOC_PATH, r as PACKAGE_ROOT, t as ASSETS_ROOT } from "./paths-D_JlVmBk.mjs";
|
|
2
|
+
import { a as SKILL_CONSUMED_FIELDS, c as parseFrontmatter, d as skillDroppedFields, f as validateAgentFrontmatter, i as MAX_SKILL_NAME_LENGTH, l as serializeAgentFrontmatter, n as AGENT_DROPPED_FIELDS, o as SKILL_DROPPED_FIELDS, p as validateSkillFrontmatter, r as FrontmatterError, s as agentDroppedFields, t as AGENT_CONSUMED_FIELDS, u as serializeSkillFrontmatter } from "./frontmatter-BQX3ekwP.mjs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { readFileSync, readdirSync } from "node:fs";
|
|
5
|
+
//#region src/provider.ts
|
|
6
|
+
/**
|
|
7
|
+
* The bundled pstack skill provider: one provider over the 55 generated skills
|
|
8
|
+
* that ship inside this package.
|
|
9
|
+
*
|
|
10
|
+
* The provider contract below mirrors `@deepseek-ai/dsh-skill` 0.2.1-rc.3, which
|
|
11
|
+
* was read through the host Inspect provider (`Service.listService` with
|
|
12
|
+
* `service: "skills"`) and the installed type declarations. It is restated here
|
|
13
|
+
* as a structural contract instead of imported so the plugin keeps zero runtime
|
|
14
|
+
* imports from the host packages: a workspace-directory bundle is linked from
|
|
15
|
+
* its checkout, where `@deepseek-ai/*` is not resolvable.
|
|
16
|
+
*
|
|
17
|
+
* Design constraints this module enforces, from the port design document §8.1:
|
|
18
|
+
*
|
|
19
|
+
* - The catalog is built once from the package assets and never watched. A
|
|
20
|
+
* package update is the refresh boundary.
|
|
21
|
+
* - A malformed bundled skill fails the whole index instead of disappearing
|
|
22
|
+
* from the catalog, so a broken asset is a startup error rather than a skill
|
|
23
|
+
* users silently cannot see.
|
|
24
|
+
* - `get()` only accepts a locator this provider produced. Directory names are
|
|
25
|
+
* never joined from caller input.
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Standard precedence rank for packaged skill providers, re-exported by
|
|
29
|
+
* `@deepseek-ai/dsh-skill` as `BUNDLED_SKILL_RANK`. Restated to keep the package
|
|
30
|
+
* dependency-free; a mismatch only changes which provider wins a name collision.
|
|
31
|
+
*/
|
|
32
|
+
const BUNDLED_SKILL_RANK = 600;
|
|
33
|
+
/** Default provider name used when the row does not override it. */
|
|
34
|
+
const DEFAULT_PROVIDER_NAME = "pstack";
|
|
35
|
+
/** Raised when a bundled asset violates the provider contract. */
|
|
36
|
+
var BundledSkillError = class extends Error {
|
|
37
|
+
constructor(message) {
|
|
38
|
+
super(message);
|
|
39
|
+
this.name = "BundledSkillError";
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Read and validate every bundled skill below one directory.
|
|
44
|
+
*
|
|
45
|
+
* This is the startup check: it runs before the provider registers, so a missing
|
|
46
|
+
* `SKILL.md`, an invalid frontmatter block, or a name that disagrees with its
|
|
47
|
+
* directory fails plugin activation with a path-qualified message instead of
|
|
48
|
+
* dropping a skill from the catalog.
|
|
49
|
+
*
|
|
50
|
+
* @param skillsRoot - absolute path of the directory holding the skill directories.
|
|
51
|
+
* @returns validated skills keyed by absolute skill directory, sorted by name.
|
|
52
|
+
* @throws {BundledSkillError} when the tree or any skill in it is malformed.
|
|
53
|
+
*/
|
|
54
|
+
function loadBundledSkillIndex(skillsRoot) {
|
|
55
|
+
let entries;
|
|
56
|
+
try {
|
|
57
|
+
entries = readdirSync(skillsRoot, { withFileTypes: true });
|
|
58
|
+
} catch (error) {
|
|
59
|
+
throw new BundledSkillError(`bundled skills: cannot read "${skillsRoot}": ${messageOf(error)}`);
|
|
60
|
+
}
|
|
61
|
+
const index = /* @__PURE__ */ new Map();
|
|
62
|
+
for (const entry of entries.sort((left, right) => left.name < right.name ? -1 : 1)) {
|
|
63
|
+
const directory = join(skillsRoot, entry.name);
|
|
64
|
+
if (!entry.isDirectory()) throw new BundledSkillError(`bundled skills: "${directory}" is not a skill directory; remove it or add a SKILL.md`);
|
|
65
|
+
const instructionFile = join(directory, "SKILL.md");
|
|
66
|
+
const frontmatter = readSkillFrontmatter(readSkillFile(instructionFile), instructionFile);
|
|
67
|
+
if (frontmatter.name !== entry.name) throw new BundledSkillError(`${instructionFile}: skill name "${frontmatter.name}" does not match its directory "${entry.name}"`);
|
|
68
|
+
index.set(directory, {
|
|
69
|
+
name: frontmatter.name,
|
|
70
|
+
description: frontmatter.description,
|
|
71
|
+
...frontmatter.whenToUse === void 0 ? {} : { whenToUse: frontmatter.whenToUse },
|
|
72
|
+
invocation: {
|
|
73
|
+
modelInvocable: !frontmatter.disableModelInvocation,
|
|
74
|
+
userInvocable: frontmatter.userInvocable
|
|
75
|
+
},
|
|
76
|
+
directory,
|
|
77
|
+
instructionFile
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
if (index.size === 0) throw new BundledSkillError(`bundled skills: no skill directories under "${skillsRoot}"`);
|
|
81
|
+
return index;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Build the provider over an already validated index.
|
|
85
|
+
*
|
|
86
|
+
* @param index - result of {@link loadBundledSkillIndex}.
|
|
87
|
+
* @param providerName - registry name for this provider.
|
|
88
|
+
* @returns a read-only provider whose catalog never changes until the package does.
|
|
89
|
+
*/
|
|
90
|
+
function createPstackSkillProvider(index, providerName = DEFAULT_PROVIDER_NAME) {
|
|
91
|
+
const ordered = [...index.values()].sort((left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0);
|
|
92
|
+
return {
|
|
93
|
+
name: providerName,
|
|
94
|
+
async list(options) {
|
|
95
|
+
throwIfAborted(options?.signal);
|
|
96
|
+
return ordered.map((skill) => ({
|
|
97
|
+
name: skill.name,
|
|
98
|
+
description: skill.description,
|
|
99
|
+
...skill.whenToUse === void 0 ? {} : { whenToUse: skill.whenToUse },
|
|
100
|
+
invocation: skill.invocation,
|
|
101
|
+
source: "bundled",
|
|
102
|
+
provider: providerName,
|
|
103
|
+
rank: 600,
|
|
104
|
+
locator: {
|
|
105
|
+
kind: "bundled-skill",
|
|
106
|
+
directory: skill.directory,
|
|
107
|
+
instructionFile: skill.instructionFile
|
|
108
|
+
},
|
|
109
|
+
path: skill.instructionFile,
|
|
110
|
+
resourceBase: {
|
|
111
|
+
kind: "directory",
|
|
112
|
+
path: skill.directory
|
|
113
|
+
}
|
|
114
|
+
}));
|
|
115
|
+
},
|
|
116
|
+
async get(candidate, options) {
|
|
117
|
+
const locator = asBundledSkillLocator(candidate.locator);
|
|
118
|
+
if (locator === void 0) return void 0;
|
|
119
|
+
const skill = index.get(locator.directory);
|
|
120
|
+
if (skill === void 0 || skill.instructionFile !== locator.instructionFile || skill.name !== candidate.name) return;
|
|
121
|
+
throwIfAborted(options?.signal);
|
|
122
|
+
const text = readOptionalSkillFile(skill.instructionFile);
|
|
123
|
+
if (text === void 0) return void 0;
|
|
124
|
+
const { body } = parseFrontmatter(text);
|
|
125
|
+
return {
|
|
126
|
+
name: skill.name,
|
|
127
|
+
description: skill.description,
|
|
128
|
+
...skill.whenToUse === void 0 ? {} : { whenToUse: skill.whenToUse },
|
|
129
|
+
invocation: skill.invocation,
|
|
130
|
+
source: "bundled",
|
|
131
|
+
provider: providerName,
|
|
132
|
+
path: skill.instructionFile,
|
|
133
|
+
resourceBase: {
|
|
134
|
+
kind: "directory",
|
|
135
|
+
path: skill.directory
|
|
136
|
+
},
|
|
137
|
+
content: body
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Load the index and build the provider in one step, failing on a malformed tree.
|
|
144
|
+
*
|
|
145
|
+
* `apply()` uses this exact function, so the startup failure path and the
|
|
146
|
+
* provider used in tests are the same code.
|
|
147
|
+
*
|
|
148
|
+
* @param skillsRoot - absolute path of the bundled skill root.
|
|
149
|
+
* @param providerName - registry name for this provider.
|
|
150
|
+
* @returns the provider over the validated index.
|
|
151
|
+
*/
|
|
152
|
+
function createPstackSkillProviderFromRoot(skillsRoot, providerName = DEFAULT_PROVIDER_NAME) {
|
|
153
|
+
return createPstackSkillProvider(loadBundledSkillIndex(skillsRoot), providerName);
|
|
154
|
+
}
|
|
155
|
+
function asBundledSkillLocator(locator) {
|
|
156
|
+
if (typeof locator !== "object" || locator === null) return void 0;
|
|
157
|
+
const candidate = locator;
|
|
158
|
+
if (candidate.kind !== "bundled-skill") return void 0;
|
|
159
|
+
if (typeof candidate.directory !== "string") return void 0;
|
|
160
|
+
if (typeof candidate.instructionFile !== "string") return void 0;
|
|
161
|
+
return {
|
|
162
|
+
kind: "bundled-skill",
|
|
163
|
+
directory: candidate.directory,
|
|
164
|
+
instructionFile: candidate.instructionFile
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
function readSkillFile(instructionFile) {
|
|
168
|
+
try {
|
|
169
|
+
return readFileSync(instructionFile, "utf8");
|
|
170
|
+
} catch (error) {
|
|
171
|
+
throw new BundledSkillError(`bundled skills: cannot read "${instructionFile}": ${messageOf(error)}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/** Parse and validate one skill header, reporting failures as bundled-asset errors. */
|
|
175
|
+
function readSkillFrontmatter(text, instructionFile) {
|
|
176
|
+
try {
|
|
177
|
+
const { data } = parseFrontmatter(text);
|
|
178
|
+
return validateSkillFrontmatter(data, instructionFile);
|
|
179
|
+
} catch (error) {
|
|
180
|
+
const message = messageOf(error);
|
|
181
|
+
throw new BundledSkillError(message.includes(instructionFile) ? message : `${instructionFile}: ${message}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function readOptionalSkillFile(instructionFile) {
|
|
185
|
+
try {
|
|
186
|
+
return readFileSync(instructionFile, "utf8");
|
|
187
|
+
} catch (error) {
|
|
188
|
+
if (errorCode(error) === "ENOENT") return void 0;
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function throwIfAborted(signal) {
|
|
193
|
+
if (signal?.aborted !== true) return;
|
|
194
|
+
throw signal.reason ?? /* @__PURE__ */ new Error("skill provider work was aborted");
|
|
195
|
+
}
|
|
196
|
+
function errorCode(error) {
|
|
197
|
+
if (typeof error !== "object" || error === null) return void 0;
|
|
198
|
+
const code = error.code;
|
|
199
|
+
return typeof code === "string" ? code : void 0;
|
|
200
|
+
}
|
|
201
|
+
function messageOf(error) {
|
|
202
|
+
return error instanceof Error ? error.message : String(error);
|
|
203
|
+
}
|
|
204
|
+
//#endregion
|
|
205
|
+
//#region src/index.ts
|
|
206
|
+
/**
|
|
207
|
+
* dsh-pstack Host entry.
|
|
208
|
+
*
|
|
209
|
+
* Unit 2 ships one minimal capability: a single `ctx.skills` provider over the
|
|
210
|
+
* generated assets in this package. Delegation, restricted history, roles, and
|
|
211
|
+
* the worktree integration are later units and are deliberately absent here.
|
|
212
|
+
*
|
|
213
|
+
* The provider contract types live in `./provider.ts` and are structural copies
|
|
214
|
+
* of the `@deepseek-ai/dsh-skill` 0.2.1-rc.3 declarations, so this module imports
|
|
215
|
+
* nothing from the host packages at runtime.
|
|
216
|
+
*/
|
|
217
|
+
/** Plugin name used by Loader diagnostics for this row. */
|
|
218
|
+
const name = "pstack";
|
|
219
|
+
/** The provider needs the skill registry and nothing else. */
|
|
220
|
+
const inject = ["skills"];
|
|
221
|
+
/**
|
|
222
|
+
* Minimal Standard Schema validator for this plugin's row config.
|
|
223
|
+
*
|
|
224
|
+
* Cordis validates `apply()`'s second argument with `Config["~standard"]` and
|
|
225
|
+
* substitutes the returned `value`, so an omitted row `config` resolves to the
|
|
226
|
+
* documented defaults without a schemastery dependency.
|
|
227
|
+
*/
|
|
228
|
+
const Config = { "~standard": {
|
|
229
|
+
version: 1,
|
|
230
|
+
vendor: "dsh-pstack",
|
|
231
|
+
validate(value) {
|
|
232
|
+
if (value === void 0 || value === null) return { value: { providerName: DEFAULT_PROVIDER_NAME } };
|
|
233
|
+
if (typeof value !== "object" || Array.isArray(value)) return { issues: [{ message: "config must be a mapping" }] };
|
|
234
|
+
const issues = [];
|
|
235
|
+
const record = value;
|
|
236
|
+
for (const key of Object.keys(record)) if (key !== "providerName") issues.push({
|
|
237
|
+
message: `unknown field "${key}"`,
|
|
238
|
+
path: [key]
|
|
239
|
+
});
|
|
240
|
+
const providerName = record["providerName"];
|
|
241
|
+
if (providerName === void 0) return issues.length > 0 ? { issues } : { value: { providerName: DEFAULT_PROVIDER_NAME } };
|
|
242
|
+
if (typeof providerName !== "string" || providerName.trim() === "") {
|
|
243
|
+
issues.push({
|
|
244
|
+
message: "providerName must be a non-empty string",
|
|
245
|
+
path: ["providerName"]
|
|
246
|
+
});
|
|
247
|
+
return { issues };
|
|
248
|
+
}
|
|
249
|
+
return issues.length > 0 ? { issues } : { value: { providerName } };
|
|
250
|
+
}
|
|
251
|
+
} };
|
|
252
|
+
/**
|
|
253
|
+
* Register the bundled pstack skill provider.
|
|
254
|
+
*
|
|
255
|
+
* The bundled tree is validated before the provider registers, so a malformed
|
|
256
|
+
* `SKILL.md` fails plugin activation with a path-qualified error instead of
|
|
257
|
+
* removing one skill from the catalog. Nothing is copied out of the package and
|
|
258
|
+
* nothing is watched: reinstalling the package is the refresh boundary.
|
|
259
|
+
*
|
|
260
|
+
* @param ctx - host context carrying the skill registry.
|
|
261
|
+
* @param config - validated row config.
|
|
262
|
+
* @throws {import("./provider.ts").BundledSkillError} when the bundled tree is malformed.
|
|
263
|
+
*/
|
|
264
|
+
function apply(ctx, config = {}) {
|
|
265
|
+
const providerName = config.providerName ?? "pstack";
|
|
266
|
+
const index = loadBundledSkillIndex(SKILLS_ROOT);
|
|
267
|
+
ctx.skills.registerProvider((_control) => createPstackSkillProvider(index, providerName));
|
|
268
|
+
}
|
|
269
|
+
//#endregion
|
|
270
|
+
export { AGENT_CONSUMED_FIELDS, AGENT_DROPPED_FIELDS, ASSETS_ROOT, BUNDLED_SKILL_RANK, BundledSkillError, Config, DEFAULT_PROVIDER_NAME, FrontmatterError, HARNESS_DOC_PATH, MAX_SKILL_NAME_LENGTH, PACKAGE_ROOT, SKILLS_ROOT, SKILL_CONSUMED_FIELDS, SKILL_DROPPED_FIELDS, agentDroppedFields, apply, createPstackSkillProvider, createPstackSkillProviderFromRoot, inject, loadBundledSkillIndex, name, parseFrontmatter, serializeAgentFrontmatter, serializeSkillFrontmatter, skillDroppedFields, validateAgentFrontmatter, validateSkillFrontmatter };
|
|
271
|
+
|
|
272
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/provider.ts","../src/index.ts"],"sourcesContent":["/**\n * The bundled pstack skill provider: one provider over the 55 generated skills\n * that ship inside this package.\n *\n * The provider contract below mirrors `@deepseek-ai/dsh-skill` 0.2.1-rc.3, which\n * was read through the host Inspect provider (`Service.listService` with\n * `service: \"skills\"`) and the installed type declarations. It is restated here\n * as a structural contract instead of imported so the plugin keeps zero runtime\n * imports from the host packages: a workspace-directory bundle is linked from\n * its checkout, where `@deepseek-ai/*` is not resolvable.\n *\n * Design constraints this module enforces, from the port design document §8.1:\n *\n * - The catalog is built once from the package assets and never watched. A\n * package update is the refresh boundary.\n * - A malformed bundled skill fails the whole index instead of disappearing\n * from the catalog, so a broken asset is a startup error rather than a skill\n * users silently cannot see.\n * - `get()` only accepts a locator this provider produced. Directory names are\n * never joined from caller input.\n */\n\nimport { readFileSync, readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport { parseFrontmatter, validateSkillFrontmatter } from \"./frontmatter.ts\";\n\n/**\n * Standard precedence rank for packaged skill providers, re-exported by\n * `@deepseek-ai/dsh-skill` as `BUNDLED_SKILL_RANK`. Restated to keep the package\n * dependency-free; a mismatch only changes which provider wins a name collision.\n */\nexport const BUNDLED_SKILL_RANK = 600;\n\n/** Default provider name used when the row does not override it. */\nexport const DEFAULT_PROVIDER_NAME = \"pstack\";\n\n/** Origin bucket for a skill contribution. */\nexport type SkillSource =\n | \"project-dsh\"\n | \"project-agents\"\n | \"runtime\"\n | \"user-dsh\"\n | \"user-agents\"\n | \"custom\"\n | \"bundled\"\n | (string & {});\n\n/** Optional provider-specific base used by loaded skill bodies to resolve relative resources. */\nexport type SkillResourceBase =\n | { readonly kind: \"directory\"; readonly path: string }\n | { readonly kind: \"url\"; readonly url: string }\n | { readonly kind: \"opaque\"; readonly description: string };\n\n/** Invocation controls shared by skill discovery consumers. */\nexport interface SkillInvocationPolicy {\n /** Whether model-facing catalogs and loaders include this skill. */\n readonly modelInvocable: boolean;\n /** Whether human-facing command catalogs and loaders include this skill. */\n readonly userInvocable: boolean;\n}\n\n/** Invocation-neutral skill metadata returned by `ctx.skills.list()`. */\nexport interface SkillSummary {\n /** Absolute instruction file path. */\n readonly path?: string;\n /** Kebab-case identifier used to address the skill. */\n readonly name: string;\n /** Short routing description shown by discovery consumers. */\n readonly description: string;\n /** Optional extra routing guidance. */\n readonly whenToUse?: string;\n /** Resolved model and user invocation controls. */\n readonly invocation: SkillInvocationPolicy;\n /** Discovery source that produced this skill. */\n readonly source: SkillSource;\n /** Provider that owns this skill body. */\n readonly provider: string;\n /** Provider-specific base for relative resources. */\n readonly resourceBase?: SkillResourceBase;\n}\n\n/** Provider catalog entry used by the registry to merge and later load skills. */\nexport interface SkillCandidate extends SkillSummary {\n /** Lower ranks win duplicate skill names. */\n readonly rank: number;\n /** Opaque provider-owned handle passed back to `provider.get()`. */\n readonly locator: unknown;\n /** Parsed optional metadata object from provider-specific skill frontmatter. */\n readonly metadata?: Readonly<Record<string, unknown>>;\n}\n\n/** Complete parsed skill definition, including the body loaded by `ctx.skills.get()`. */\nexport interface SkillDefinition extends SkillSummary {\n /** Markdown instruction body after frontmatter removal. */\n readonly content: string;\n /** Parsed optional metadata object from frontmatter. */\n readonly metadata?: Readonly<Record<string, unknown>>;\n}\n\n/** Caller context used for cwd-sensitive and abortable provider work. */\nexport interface SkillLookupOptions {\n /** Workspace selector for the current lookup. */\n readonly cwd?: string | undefined;\n /** Abort discovery or loading work for the current caller. */\n readonly signal?: AbortSignal | undefined;\n}\n\n/** Registration-scoped lifecycle capability handed to a provider factory. */\nexport interface SkillProviderControl {\n /** Aborts when registration fails or the exact provider registration is disposed. */\n readonly signal: AbortSignal;\n /** Invalidate completed catalogs and notify consumers. */\n readonly invalidate: () => void;\n}\n\n/** Provider interface for one source of skills. */\nexport interface SkillProvider {\n /** Unique provider name in the `ctx.skills` registry. */\n readonly name: string;\n /** List available skill candidates for the current lookup context. */\n readonly list: (options: SkillLookupOptions) => Promise<readonly SkillCandidate[]>;\n /** Load a complete skill body for a previously listed candidate. */\n readonly get: (\n candidate: SkillCandidate,\n options: SkillLookupOptions,\n ) => Promise<SkillDefinition | undefined>;\n}\n\n/** Opaque handle this provider hands back to itself; never derived from caller input. */\ninterface BundledSkillLocator {\n readonly kind: \"bundled-skill\";\n /** Absolute skill directory that also serves as the resource base. */\n readonly directory: string;\n /** Absolute `SKILL.md` path read by `get()`. */\n readonly instructionFile: string;\n}\n\n/** One validated on-disk bundled skill. */\nexport interface BundledSkill {\n readonly name: string;\n readonly description: string;\n readonly whenToUse?: string;\n readonly invocation: SkillInvocationPolicy;\n /** Absolute skill directory; the candidate resource base. */\n readonly directory: string;\n /** Absolute `SKILL.md` path. */\n readonly instructionFile: string;\n}\n\n/** Validated skills keyed by their absolute directory. */\nexport type BundledSkillIndex = ReadonlyMap<string, BundledSkill>;\n\n/** Raised when a bundled asset violates the provider contract. */\nexport class BundledSkillError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"BundledSkillError\";\n }\n}\n\n/**\n * Read and validate every bundled skill below one directory.\n *\n * This is the startup check: it runs before the provider registers, so a missing\n * `SKILL.md`, an invalid frontmatter block, or a name that disagrees with its\n * directory fails plugin activation with a path-qualified message instead of\n * dropping a skill from the catalog.\n *\n * @param skillsRoot - absolute path of the directory holding the skill directories.\n * @returns validated skills keyed by absolute skill directory, sorted by name.\n * @throws {BundledSkillError} when the tree or any skill in it is malformed.\n */\nexport function loadBundledSkillIndex(skillsRoot: string): BundledSkillIndex {\n let entries;\n try {\n entries = readdirSync(skillsRoot, { withFileTypes: true });\n } catch (error) {\n throw new BundledSkillError(\n `bundled skills: cannot read \"${skillsRoot}\": ${messageOf(error)}`,\n );\n }\n\n const index = new Map<string, BundledSkill>();\n\n for (const entry of entries.sort((left, right) => (left.name < right.name ? -1 : 1))) {\n const directory = join(skillsRoot, entry.name);\n if (!entry.isDirectory()) {\n throw new BundledSkillError(\n `bundled skills: \"${directory}\" is not a skill directory; remove it or add a SKILL.md`,\n );\n }\n\n const instructionFile = join(directory, \"SKILL.md\");\n const text = readSkillFile(instructionFile);\n const frontmatter = readSkillFrontmatter(text, instructionFile);\n\n if (frontmatter.name !== entry.name) {\n throw new BundledSkillError(\n `${instructionFile}: skill name \"${frontmatter.name}\" does not match its directory \"${entry.name}\"`,\n );\n }\n\n index.set(directory, {\n name: frontmatter.name,\n description: frontmatter.description,\n ...(frontmatter.whenToUse === undefined ? {} : { whenToUse: frontmatter.whenToUse }),\n invocation: {\n modelInvocable: !frontmatter.disableModelInvocation,\n userInvocable: frontmatter.userInvocable,\n },\n directory,\n instructionFile,\n });\n }\n\n if (index.size === 0) {\n throw new BundledSkillError(`bundled skills: no skill directories under \"${skillsRoot}\"`);\n }\n\n return index;\n}\n\n/**\n * Build the provider over an already validated index.\n *\n * @param index - result of {@link loadBundledSkillIndex}.\n * @param providerName - registry name for this provider.\n * @returns a read-only provider whose catalog never changes until the package does.\n */\nexport function createPstackSkillProvider(\n index: BundledSkillIndex,\n providerName: string = DEFAULT_PROVIDER_NAME,\n): SkillProvider {\n const ordered = [...index.values()].sort((left, right) =>\n left.name < right.name ? -1 : left.name > right.name ? 1 : 0,\n );\n\n return {\n name: providerName,\n\n async list(options) {\n throwIfAborted(options?.signal);\n return ordered.map(\n (skill): SkillCandidate => ({\n name: skill.name,\n description: skill.description,\n ...(skill.whenToUse === undefined ? {} : { whenToUse: skill.whenToUse }),\n invocation: skill.invocation,\n source: \"bundled\",\n provider: providerName,\n rank: BUNDLED_SKILL_RANK,\n locator: {\n kind: \"bundled-skill\",\n directory: skill.directory,\n instructionFile: skill.instructionFile,\n } satisfies BundledSkillLocator,\n path: skill.instructionFile,\n resourceBase: { kind: \"directory\", path: skill.directory },\n }),\n );\n },\n\n async get(candidate, options) {\n const locator = asBundledSkillLocator(candidate.locator);\n if (locator === undefined) return undefined;\n\n const skill = index.get(locator.directory);\n if (\n skill === undefined ||\n skill.instructionFile !== locator.instructionFile ||\n skill.name !== candidate.name\n ) {\n return undefined;\n }\n\n throwIfAborted(options?.signal);\n\n const text = readOptionalSkillFile(skill.instructionFile);\n if (text === undefined) return undefined;\n const { body } = parseFrontmatter(text);\n\n return {\n name: skill.name,\n description: skill.description,\n ...(skill.whenToUse === undefined ? {} : { whenToUse: skill.whenToUse }),\n invocation: skill.invocation,\n source: \"bundled\",\n provider: providerName,\n path: skill.instructionFile,\n resourceBase: { kind: \"directory\", path: skill.directory },\n content: body,\n };\n },\n };\n}\n\n/**\n * Load the index and build the provider in one step, failing on a malformed tree.\n *\n * `apply()` uses this exact function, so the startup failure path and the\n * provider used in tests are the same code.\n *\n * @param skillsRoot - absolute path of the bundled skill root.\n * @param providerName - registry name for this provider.\n * @returns the provider over the validated index.\n */\nexport function createPstackSkillProviderFromRoot(\n skillsRoot: string,\n providerName: string = DEFAULT_PROVIDER_NAME,\n): SkillProvider {\n return createPstackSkillProvider(loadBundledSkillIndex(skillsRoot), providerName);\n}\n\nfunction asBundledSkillLocator(locator: unknown): BundledSkillLocator | undefined {\n if (typeof locator !== \"object\" || locator === null) return undefined;\n const candidate = locator as Partial<BundledSkillLocator>;\n if (candidate.kind !== \"bundled-skill\") return undefined;\n if (typeof candidate.directory !== \"string\") return undefined;\n if (typeof candidate.instructionFile !== \"string\") return undefined;\n return {\n kind: \"bundled-skill\",\n directory: candidate.directory,\n instructionFile: candidate.instructionFile,\n };\n}\n\nfunction readSkillFile(instructionFile: string): string {\n try {\n return readFileSync(instructionFile, \"utf8\");\n } catch (error) {\n throw new BundledSkillError(\n `bundled skills: cannot read \"${instructionFile}\": ${messageOf(error)}`,\n );\n }\n}\n\n/** Parse and validate one skill header, reporting failures as bundled-asset errors. */\nfunction readSkillFrontmatter(\n text: string,\n instructionFile: string,\n): ReturnType<typeof validateSkillFrontmatter> {\n try {\n const { data } = parseFrontmatter(text);\n return validateSkillFrontmatter(data, instructionFile);\n } catch (error) {\n const message = messageOf(error);\n throw new BundledSkillError(\n message.includes(instructionFile) ? message : `${instructionFile}: ${message}`,\n );\n }\n}\n\nfunction readOptionalSkillFile(instructionFile: string): string | undefined {\n try {\n return readFileSync(instructionFile, \"utf8\");\n } catch (error) {\n if (errorCode(error) === \"ENOENT\") return undefined;\n throw error;\n }\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted !== true) return;\n throw signal.reason ?? new Error(\"skill provider work was aborted\");\n}\n\nfunction errorCode(error: unknown): string | undefined {\n if (typeof error !== \"object\" || error === null) return undefined;\n const code = (error as { code?: unknown }).code;\n return typeof code === \"string\" ? code : undefined;\n}\n\nfunction messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","/**\n * dsh-pstack Host entry.\n *\n * Unit 2 ships one minimal capability: a single `ctx.skills` provider over the\n * generated assets in this package. Delegation, restricted history, roles, and\n * the worktree integration are later units and are deliberately absent here.\n *\n * The provider contract types live in `./provider.ts` and are structural copies\n * of the `@deepseek-ai/dsh-skill` 0.2.1-rc.3 declarations, so this module imports\n * nothing from the host packages at runtime.\n */\n\nimport { SKILLS_ROOT } from \"./paths.ts\";\nimport {\n DEFAULT_PROVIDER_NAME,\n createPstackSkillProvider,\n loadBundledSkillIndex,\n} from \"./provider.ts\";\nimport type { SkillProvider, SkillProviderControl } from \"./provider.ts\";\n\n/** Plugin name used by Loader diagnostics for this row. */\nexport const name = \"pstack\";\n\n/** The provider needs the skill registry and nothing else. */\nexport const inject = [\"skills\"];\n\n/** Row configuration. Every field is optional; an omitted `config` is valid. */\nexport interface PstackConfig {\n /** Registry name for the provider; change it when two rows must coexist. */\n readonly providerName?: string;\n}\n\ninterface StandardSchemaIssue {\n readonly message: string;\n readonly path?: readonly (string | number)[];\n}\n\ntype StandardSchemaResult =\n | { readonly value: PstackConfig; readonly issues?: undefined }\n | { readonly issues: readonly StandardSchemaIssue[] };\n\n/**\n * Minimal Standard Schema validator for this plugin's row config.\n *\n * Cordis validates `apply()`'s second argument with `Config[\"~standard\"]` and\n * substitutes the returned `value`, so an omitted row `config` resolves to the\n * documented defaults without a schemastery dependency.\n */\nexport const Config = {\n \"~standard\": {\n version: 1,\n vendor: \"dsh-pstack\",\n validate(value: unknown): StandardSchemaResult {\n if (value === undefined || value === null) {\n return { value: { providerName: DEFAULT_PROVIDER_NAME } };\n }\n if (typeof value !== \"object\" || Array.isArray(value)) {\n return { issues: [{ message: \"config must be a mapping\" }] };\n }\n\n const issues: StandardSchemaIssue[] = [];\n const record = value as Record<string, unknown>;\n for (const key of Object.keys(record)) {\n if (key !== \"providerName\") issues.push({ message: `unknown field \"${key}\"`, path: [key] });\n }\n\n const providerName = record[\"providerName\"];\n if (providerName === undefined) {\n return issues.length > 0\n ? { issues }\n : { value: { providerName: DEFAULT_PROVIDER_NAME } };\n }\n if (typeof providerName !== \"string\" || providerName.trim() === \"\") {\n issues.push({ message: \"providerName must be a non-empty string\", path: [\"providerName\"] });\n return { issues };\n }\n\n return issues.length > 0 ? { issues } : { value: { providerName } };\n },\n },\n};\n\n/** The slice of the Cordis context this plugin requires. */\nexport interface PstackSkillHost {\n readonly skills: {\n registerProvider(create: (control: SkillProviderControl) => SkillProvider): () => void;\n };\n}\n\n/**\n * Register the bundled pstack skill provider.\n *\n * The bundled tree is validated before the provider registers, so a malformed\n * `SKILL.md` fails plugin activation with a path-qualified error instead of\n * removing one skill from the catalog. Nothing is copied out of the package and\n * nothing is watched: reinstalling the package is the refresh boundary.\n *\n * @param ctx - host context carrying the skill registry.\n * @param config - validated row config.\n * @throws {import(\"./provider.ts\").BundledSkillError} when the bundled tree is malformed.\n */\nexport function apply(ctx: PstackSkillHost, config: PstackConfig = {}): void {\n const providerName = config.providerName ?? DEFAULT_PROVIDER_NAME;\n const index = loadBundledSkillIndex(SKILLS_ROOT);\n ctx.skills.registerProvider((_control) => createPstackSkillProvider(index, providerName));\n}\n\nexport { ASSETS_ROOT, HARNESS_DOC_PATH, PACKAGE_ROOT, SKILLS_ROOT } from \"./paths.ts\";\nexport {\n BUNDLED_SKILL_RANK,\n BundledSkillError,\n DEFAULT_PROVIDER_NAME,\n createPstackSkillProvider,\n createPstackSkillProviderFromRoot,\n loadBundledSkillIndex,\n} from \"./provider.ts\";\nexport type {\n BundledSkill,\n BundledSkillIndex,\n SkillCandidate,\n SkillDefinition,\n SkillInvocationPolicy,\n SkillLookupOptions,\n SkillProvider,\n SkillProviderControl,\n SkillResourceBase,\n SkillSource,\n SkillSummary,\n} from \"./provider.ts\";\nexport * from \"./frontmatter.ts\";\n"],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { dirname, join, resolve } from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
//#region src/paths.ts
|
|
4
|
+
/**
|
|
5
|
+
* Package-internal resource locations.
|
|
6
|
+
*
|
|
7
|
+
* The provider reads generated assets in place instead of copying them into a
|
|
8
|
+
* user-visible skills directory, so every path here is resolved from this
|
|
9
|
+
* module's own location. The modules run from `src/` in a checkout and from the
|
|
10
|
+
* bundled `dist/index.mjs` in an installed package; both sit one directory below
|
|
11
|
+
* the package root, so the same expression holds in both cases.
|
|
12
|
+
*/
|
|
13
|
+
/** Absolute path of the package root: the repository in a checkout, the install directory after packing. */
|
|
14
|
+
const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
15
|
+
/** Absolute path of the generated, committed assets directory. */
|
|
16
|
+
const ASSETS_ROOT = join(PACKAGE_ROOT, "assets");
|
|
17
|
+
/** Absolute path of the directory holding the 55 bundled skill directories. */
|
|
18
|
+
const SKILLS_ROOT = join(ASSETS_ROOT, "skills");
|
|
19
|
+
/** Absolute path of the directory holding the generated agent preambles. */
|
|
20
|
+
const AGENTS_ROOT = join(ASSETS_ROOT, "agents");
|
|
21
|
+
/**
|
|
22
|
+
* Absolute path of the `poteto-mode` instructions.
|
|
23
|
+
*
|
|
24
|
+
* `pstack_subagent` injects this path into a `poteto-agent` child's prompt, so the
|
|
25
|
+
* child reads the playbook from where it actually is instead of searching a Cursor
|
|
26
|
+
* plugin install for the highest version.
|
|
27
|
+
*/
|
|
28
|
+
const POTETO_MODE_SKILL_PATH = join(SKILLS_ROOT, "poteto-mode", "SKILL.md");
|
|
29
|
+
/** Absolute path of the generated harness mapping document. */
|
|
30
|
+
const HARNESS_DOC_PATH = join(ASSETS_ROOT, "docs", "harness", "dsh.md");
|
|
31
|
+
/**
|
|
32
|
+
* Absolute path of one agent preamble.
|
|
33
|
+
*
|
|
34
|
+
* Returns `undefined` for `general`, which is a plain child and gets no preamble.
|
|
35
|
+
*/
|
|
36
|
+
function agentPreamblePath(agent) {
|
|
37
|
+
return agent === "general" ? void 0 : join(AGENTS_ROOT, `${agent}.md`);
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { SKILLS_ROOT as a, POTETO_MODE_SKILL_PATH as i, HARNESS_DOC_PATH as n, agentPreamblePath as o, PACKAGE_ROOT as r, ASSETS_ROOT as t };
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=paths-D_JlVmBk.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths-D_JlVmBk.mjs","names":[],"sources":["../src/paths.ts"],"sourcesContent":["/**\n * Package-internal resource locations.\n *\n * The provider reads generated assets in place instead of copying them into a\n * user-visible skills directory, so every path here is resolved from this\n * module's own location. The modules run from `src/` in a checkout and from the\n * bundled `dist/index.mjs` in an installed package; both sit one directory below\n * the package root, so the same expression holds in both cases.\n */\n\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/** Absolute path of the package root: the repository in a checkout, the install directory after packing. */\nexport const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), \"..\");\n\n/** Absolute path of the generated, committed assets directory. */\nexport const ASSETS_ROOT = join(PACKAGE_ROOT, \"assets\");\n\n/** Absolute path of the directory holding the 55 bundled skill directories. */\nexport const SKILLS_ROOT = join(ASSETS_ROOT, \"skills\");\n\n/** Absolute path of the directory holding the generated agent preambles. */\nexport const AGENTS_ROOT = join(ASSETS_ROOT, \"agents\");\n\n/**\n * Absolute path of the `poteto-mode` instructions.\n *\n * `pstack_subagent` injects this path into a `poteto-agent` child's prompt, so the\n * child reads the playbook from where it actually is instead of searching a Cursor\n * plugin install for the highest version.\n */\nexport const POTETO_MODE_SKILL_PATH = join(SKILLS_ROOT, \"poteto-mode\", \"SKILL.md\");\n\n/** Absolute path of the generated harness mapping document. */\nexport const HARNESS_DOC_PATH = join(ASSETS_ROOT, \"docs\", \"harness\", \"dsh.md\");\n\n/**\n * Absolute path of one agent preamble.\n *\n * Returns `undefined` for `general`, which is a plain child and gets no preamble.\n */\nexport function agentPreamblePath(agent: string): string | undefined {\n return agent === \"general\" ? undefined : join(AGENTS_ROOT, `${agent}.md`);\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,MAAa,eAAe,QAAQ,QAAQ,cAAc,YAAY,GAAG,CAAC,GAAG,IAAI;;AAGjF,MAAa,cAAc,KAAK,cAAc,QAAQ;;AAGtD,MAAa,cAAc,KAAK,aAAa,QAAQ;;AAGrD,MAAa,cAAc,KAAK,aAAa,QAAQ;;;;;;;;AASrD,MAAa,yBAAyB,KAAK,aAAa,eAAe,UAAU;;AAGjF,MAAa,mBAAmB,KAAK,aAAa,QAAQ,WAAW,QAAQ;;;;;;AAO7E,SAAgB,kBAAkB,OAAmC;CACnE,OAAO,UAAU,YAAY,KAAA,IAAY,KAAK,aAAa,GAAG,MAAM,IAAI;AAC1E"}
|