mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
db86d38ca4
* feat(skills): add the plannotator knowledge-layer skill with a CLI freshness guard A new model-invocable core skill (apps/skills/core/plannotator) that teaches an agent the whole CLI surface: decision guide, per-command reference with flags and exit codes, env vars, the external-annotations API, and a do-not list. The existing plannotator-* core skills stay lightweight action stubs. A freshness test (apps/hook/server/plannotator-skill-reference.test.ts) parses the skill's documented subcommands and flags and diffs them against cli.ts usage text plus the CLI arg-parsing sources, in both directions, so the reference cannot drift from the real CLI without failing the suite. Installers copy the single-sourced core body into ~/.claude/skills and ~/.agents/skills on all three platforms; uninstall removes it from both scopes. The skill ships model-invocable as a documented exception to the locked-by-default rule, asserted both ways in install.test.ts. * feat(marketing): serve the plannotator knowledge skill as /llms.txt Single-sourced at build time from apps/skills/core/plannotator/SKILL.md per the llmstxt.org spec (H1, blockquote, detail sections, Docs link list), so the CLI freshness guard transitively keeps llms.txt current. * fix(skills): reach every install path with the plannotator knowledge skill The knowledge skill reached Claude Code and ~/.agents but was missing from three install paths. Six fixes from the install-reach review of #1377. Kiro: the installer's Kiro leg copied only the two action skills, so Kiro users got launchers and no CLI reference. One copy line per installer, and "plannotator" joins uninstall.ts's KIRO_SKILLS. OpenCode npm: @plannotator/opencode's postinstall copied only commands/*.md. The package now ships the skill (copied at build time like the HTML assets, gitignored so the shipped copy cannot drift) and postinstall places it under ${XDG_CONFIG_HOME:-$HOME/.config}/opencode/skills/plannotator/, which is a path OpenCode really scans ({skill,skills}/**/SKILL.md under xdgConfig/ opencode). Uninstall sweeps it, skills only, so a user's own opencode/commands/plannotator.md stays out of scope. Pi npm: vendor.sh copies the skill to apps/pi-extension/skills/plannotator/ and package.json declares it under pi.skills, which Pi resolves relative to the package root. Neither vendored copy carries the // @generated header the .ts files use: a SKILL.md must open with its frontmatter on line 1. llms.txt: the endpoint resolved the skill through process.cwd(), which breaks under any invocation but --cwd apps/marketing. new URL(import.meta.url) does not fix it either, because Vite rewrites import.meta.url to the emitted SSR chunk's location. Inlined with Vite's ?raw, resolved by the bundler relative to the source file. Also drops the summary paragraph the required blockquote already carries; SKILL.md itself is unchanged. Uninstall: KNOWLEDGE_SKILLS is a separate list from CORE_SKILLS precisely so the bare name "plannotator" cannot leak into LEGACY_COMMAND_NAMES or STALE_CODEX_SKILLS and delete a user's own files. Nothing tested that; now a test proves the five installed scopes are removed and commands/plannotator.md (Claude and OpenCode) plus ~/.codex/skills/plannotator survive. Also cleanupStaleSkillLayout now knows KNOWLEDGE_SKILLS. Origins: oh-my-pi (#1373) was missing from SKILL.md's PLANNOTATOR_ORIGIN row. The guard now imports AGENT_CONFIG and asserts the row names every key and invents none, and its header comment is narrowed to what it actually proves: bidirectional for subcommands and origins, one-directional for flags. AI-assisted (Claude) under maintainer direction.
33 lines
1.5 KiB
TypeScript
33 lines
1.5 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import packageJson from "./package.json";
|
|
|
|
describe("OpenCode package entrypoints", () => {
|
|
test("keeps V1 on main and exposes V2 from the package root", () => {
|
|
expect(packageJson.main).toBe("dist/index.js");
|
|
// OpenCode 1 checks ./server before main, so that subpath must remain absent.
|
|
expect(packageJson.exports).toEqual({
|
|
".": "./dist/server.js",
|
|
});
|
|
});
|
|
|
|
test("ships the plannotator knowledge skill and installs it where OpenCode scans", () => {
|
|
// #1377 install reach: postinstall wrote only commands/*.md, so npm-plugin
|
|
// users never received the CLI reference. Three things have to line up or
|
|
// it silently stops shipping: the build must copy it into the package,
|
|
// `files` must include it, and postinstall must place it under the config
|
|
// dir OpenCode scans (`{skill,skills}/**/SKILL.md` under xdgConfig/opencode).
|
|
expect(packageJson.files).toContain("skills");
|
|
expect(packageJson.scripts["build:skill"]).toContain(
|
|
"cp -R ../skills/core/plannotator skills/plannotator",
|
|
);
|
|
// The build must actually run that step, not merely define it.
|
|
expect(packageJson.scripts.build).toContain("bun run build:skill");
|
|
expect(packageJson.scripts.postinstall).toContain(
|
|
"${XDG_CONFIG_HOME:-$HOME/.config}/opencode/skills/plannotator",
|
|
);
|
|
expect(packageJson.scripts.postinstall).toContain(
|
|
"./skills/plannotator/SKILL.md",
|
|
);
|
|
});
|
|
});
|