@modootoday/pmcp 0.13.1 → 0.14.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/.agents/plugins/marketplace.json +1157 -0
- package/.claude-plugin/marketplace.json +825 -0
- package/.claude-plugin/plugin.json +9 -0
- package/.mcp.json +9 -0
- package/README.md +48 -3
- package/dist/cli.js +1345 -741
- package/dist/{config-CJ43_oBS.d.ts → config-BkSpjUG6.d.ts} +1 -0
- package/dist/{embed-BBhv3y5x.d.ts → embed-CVCEz2FH.d.ts} +1 -1
- package/dist/http.d.ts +3 -3
- package/dist/http.js +216 -112
- package/dist/index.d.ts +7 -14
- package/dist/index.js +382 -262
- package/dist/mailbox/index.d.ts +1 -1
- package/dist/mailbox/index.js +18 -2
- package/dist/{server-CwWcRjqz.d.ts → server-DAcT89iv.d.ts} +1 -1
- package/dist/stdio.d.ts +1 -1
- package/dist/stdio.js +229 -121
- package/dist/tui-worker.js +18 -2
- package/docs/catalog.json +5422 -0
- package/docs/manual-library-skills.md +74 -0
- package/docs/skills.md +46 -0
- package/gemini-extension.json +11 -0
- package/mcp.json +10 -0
- package/package.json +22 -5
- package/plugin.json +10 -0
- package/plugins/agent-base-9/.claude-plugin/plugin.json +9 -0
- package/plugins/agent-base-9/LICENSE +93 -0
- package/plugins/agent-base-9/NOTICE +51 -0
- package/plugins/agent-base-9/gemini-extension.json +1 -0
- package/plugins/agent-base-9/plugin.json +10 -0
- package/plugins/agent-base-9/skills/agent-base/SKILL.md +118 -0
- package/plugins/ajv-formats-3/.claude-plugin/plugin.json +9 -0
- package/plugins/ajv-formats-3/LICENSE +93 -0
- package/plugins/ajv-formats-3/NOTICE +51 -0
- package/plugins/ajv-formats-3/gemini-extension.json +1 -0
- package/plugins/ajv-formats-3/plugin.json +10 -0
- package/plugins/ajv-formats-3/skills/ajv-formats/SKILL.md +178 -0
- package/plugins/allure-js-commons-3/.claude-plugin/plugin.json +9 -0
- package/plugins/allure-js-commons-3/LICENSE +93 -0
- package/plugins/allure-js-commons-3/NOTICE +51 -0
- package/plugins/allure-js-commons-3/gemini-extension.json +1 -0
- package/plugins/allure-js-commons-3/plugin.json +10 -0
- package/plugins/allure-js-commons-3/skills/allure-js-commons/SKILL.md +173 -0
- package/plugins/ansi-escapes-7/.claude-plugin/plugin.json +9 -0
- package/plugins/ansi-escapes-7/LICENSE +93 -0
- package/plugins/ansi-escapes-7/NOTICE +51 -0
- package/plugins/ansi-escapes-7/gemini-extension.json +1 -0
- package/plugins/ansi-escapes-7/plugin.json +10 -0
- package/plugins/ansi-escapes-7/skills/ansi-escapes/SKILL.md +189 -0
- package/plugins/ansi-styles-7/.claude-plugin/plugin.json +9 -0
- package/plugins/ansi-styles-7/LICENSE +93 -0
- package/plugins/ansi-styles-7/NOTICE +51 -0
- package/plugins/ansi-styles-7/gemini-extension.json +1 -0
- package/plugins/ansi-styles-7/plugin.json +10 -0
- package/plugins/ansi-styles-7/skills/ansi-styles/SKILL.md +161 -0
- package/plugins/app-builder-lib-26/.claude-plugin/plugin.json +9 -0
- package/plugins/app-builder-lib-26/LICENSE +93 -0
- package/plugins/app-builder-lib-26/NOTICE +51 -0
- package/plugins/app-builder-lib-26/gemini-extension.json +1 -0
- package/plugins/app-builder-lib-26/plugin.json +10 -0
- package/plugins/app-builder-lib-26/skills/app-builder-lib/SKILL.md +84 -0
- package/plugins/autoprefixer-10/.claude-plugin/plugin.json +9 -0
- package/plugins/autoprefixer-10/LICENSE +93 -0
- package/plugins/autoprefixer-10/NOTICE +51 -0
- package/plugins/autoprefixer-10/gemini-extension.json +1 -0
- package/plugins/autoprefixer-10/plugin.json +10 -0
- package/plugins/autoprefixer-10/skills/autoprefixer/SKILL.md +141 -0
- package/plugins/babel-plugin-transform-typescript-8/.claude-plugin/plugin.json +9 -0
- package/plugins/babel-plugin-transform-typescript-8/LICENSE +93 -0
- package/plugins/babel-plugin-transform-typescript-8/NOTICE +51 -0
- package/plugins/babel-plugin-transform-typescript-8/gemini-extension.json +1 -0
- package/plugins/babel-plugin-transform-typescript-8/plugin.json +10 -0
- package/plugins/babel-plugin-transform-typescript-8/skills/babel-plugin-transform-typescript/SKILL.md +135 -0
- package/plugins/bcryptjs-2/.claude-plugin/plugin.json +9 -0
- package/plugins/bcryptjs-2/LICENSE +93 -0
- package/plugins/bcryptjs-2/NOTICE +51 -0
- package/plugins/bcryptjs-2/gemini-extension.json +1 -0
- package/plugins/bcryptjs-2/plugin.json +10 -0
- package/plugins/bcryptjs-2/skills/bcryptjs/SKILL.md +78 -0
- package/plugins/bullmq-5/.claude-plugin/plugin.json +9 -0
- package/plugins/bullmq-5/LICENSE +93 -0
- package/plugins/bullmq-5/NOTICE +51 -0
- package/plugins/bullmq-5/gemini-extension.json +1 -0
- package/plugins/bullmq-5/plugin.json +10 -0
- package/plugins/bullmq-5/skills/bullmq/SKILL.md +59 -0
- package/plugins/bun-types-1/.claude-plugin/plugin.json +9 -0
- package/plugins/bun-types-1/LICENSE +93 -0
- package/plugins/bun-types-1/NOTICE +51 -0
- package/plugins/bun-types-1/gemini-extension.json +1 -0
- package/plugins/bun-types-1/plugin.json +10 -0
- package/plugins/bun-types-1/skills/bun-types/SKILL.md +119 -0
- package/plugins/chai-6/.claude-plugin/plugin.json +9 -0
- package/plugins/chai-6/LICENSE +93 -0
- package/plugins/chai-6/NOTICE +51 -0
- package/plugins/chai-6/gemini-extension.json +1 -0
- package/plugins/chai-6/plugin.json +10 -0
- package/plugins/chai-6/skills/chai/SKILL.md +160 -0
- package/plugins/chalk-6/.claude-plugin/plugin.json +9 -0
- package/plugins/chalk-6/LICENSE +93 -0
- package/plugins/chalk-6/NOTICE +51 -0
- package/plugins/chalk-6/gemini-extension.json +1 -0
- package/plugins/chalk-6/plugin.json +10 -0
- package/plugins/chalk-6/skills/chalk/SKILL.md +167 -0
- package/plugins/cli-cursor-5/.claude-plugin/plugin.json +9 -0
- package/plugins/cli-cursor-5/LICENSE +93 -0
- package/plugins/cli-cursor-5/NOTICE +51 -0
- package/plugins/cli-cursor-5/gemini-extension.json +1 -0
- package/plugins/cli-cursor-5/plugin.json +10 -0
- package/plugins/cli-cursor-5/skills/cli-cursor/SKILL.md +117 -0
- package/plugins/cli-spinners-3/.claude-plugin/plugin.json +9 -0
- package/plugins/cli-spinners-3/LICENSE +93 -0
- package/plugins/cli-spinners-3/NOTICE +51 -0
- package/plugins/cli-spinners-3/gemini-extension.json +1 -0
- package/plugins/cli-spinners-3/plugin.json +10 -0
- package/plugins/cli-spinners-3/skills/cli-spinners/SKILL.md +101 -0
- package/plugins/clickhouse-client-1/.claude-plugin/plugin.json +9 -0
- package/plugins/clickhouse-client-1/LICENSE +93 -0
- package/plugins/clickhouse-client-1/NOTICE +51 -0
- package/plugins/clickhouse-client-1/gemini-extension.json +1 -0
- package/plugins/clickhouse-client-1/plugin.json +10 -0
- package/plugins/clickhouse-client-1/skills/clickhouse-client/SKILL.md +54 -0
- package/plugins/clickhouse-client-web-1/.claude-plugin/plugin.json +9 -0
- package/plugins/clickhouse-client-web-1/LICENSE +93 -0
- package/plugins/clickhouse-client-web-1/NOTICE +51 -0
- package/plugins/clickhouse-client-web-1/gemini-extension.json +1 -0
- package/plugins/clickhouse-client-web-1/plugin.json +10 -0
- package/plugins/clickhouse-client-web-1/skills/clickhouse-client-web/SKILL.md +52 -0
- package/plugins/cliui-9/.claude-plugin/plugin.json +9 -0
- package/plugins/cliui-9/LICENSE +93 -0
- package/plugins/cliui-9/NOTICE +51 -0
- package/plugins/cliui-9/gemini-extension.json +1 -0
- package/plugins/cliui-9/plugin.json +10 -0
- package/plugins/cliui-9/skills/cliui/SKILL.md +163 -0
- package/plugins/cloudflare-workers-types-4/.claude-plugin/plugin.json +9 -0
- package/plugins/cloudflare-workers-types-4/LICENSE +93 -0
- package/plugins/cloudflare-workers-types-4/NOTICE +51 -0
- package/plugins/cloudflare-workers-types-4/gemini-extension.json +1 -0
- package/plugins/cloudflare-workers-types-4/plugin.json +10 -0
- package/plugins/cloudflare-workers-types-4/skills/cloudflare-workers-types/SKILL.md +63 -0
- package/plugins/commander-15/.claude-plugin/plugin.json +9 -0
- package/plugins/commander-15/LICENSE +93 -0
- package/plugins/commander-15/NOTICE +51 -0
- package/plugins/commander-15/gemini-extension.json +1 -0
- package/plugins/commander-15/plugin.json +10 -0
- package/plugins/commander-15/skills/commander/SKILL.md +204 -0
- package/plugins/content-type-3/.claude-plugin/plugin.json +9 -0
- package/plugins/content-type-3/LICENSE +93 -0
- package/plugins/content-type-3/NOTICE +51 -0
- package/plugins/content-type-3/gemini-extension.json +1 -0
- package/plugins/content-type-3/plugin.json +10 -0
- package/plugins/content-type-3/skills/content-type/SKILL.md +126 -0
- package/plugins/croner-10/.claude-plugin/plugin.json +9 -0
- package/plugins/croner-10/LICENSE +93 -0
- package/plugins/croner-10/NOTICE +51 -0
- package/plugins/croner-10/gemini-extension.json +1 -0
- package/plugins/croner-10/plugin.json +10 -0
- package/plugins/croner-10/skills/croner/SKILL.md +182 -0
- package/plugins/css-tree-3/.claude-plugin/plugin.json +9 -0
- package/plugins/css-tree-3/LICENSE +93 -0
- package/plugins/css-tree-3/NOTICE +51 -0
- package/plugins/css-tree-3/gemini-extension.json +1 -0
- package/plugins/css-tree-3/plugin.json +10 -0
- package/plugins/css-tree-3/skills/css-tree/SKILL.md +165 -0
- package/plugins/data-urls-7/.claude-plugin/plugin.json +9 -0
- package/plugins/data-urls-7/LICENSE +93 -0
- package/plugins/data-urls-7/NOTICE +51 -0
- package/plugins/data-urls-7/gemini-extension.json +1 -0
- package/plugins/data-urls-7/plugin.json +10 -0
- package/plugins/data-urls-7/skills/data-urls/SKILL.md +136 -0
- package/plugins/deep-eql-5/.claude-plugin/plugin.json +9 -0
- package/plugins/deep-eql-5/LICENSE +93 -0
- package/plugins/deep-eql-5/NOTICE +51 -0
- package/plugins/deep-eql-5/gemini-extension.json +1 -0
- package/plugins/deep-eql-5/plugin.json +10 -0
- package/plugins/deep-eql-5/skills/deep-eql/SKILL.md +130 -0
- package/plugins/dexie-4/.claude-plugin/plugin.json +9 -0
- package/plugins/dexie-4/LICENSE +93 -0
- package/plugins/dexie-4/NOTICE +51 -0
- package/plugins/dexie-4/gemini-extension.json +1 -0
- package/plugins/dexie-4/plugin.json +10 -0
- package/plugins/dexie-4/skills/dexie/SKILL.md +192 -0
- package/plugins/emittery-2/.claude-plugin/plugin.json +9 -0
- package/plugins/emittery-2/LICENSE +93 -0
- package/plugins/emittery-2/NOTICE +51 -0
- package/plugins/emittery-2/gemini-extension.json +1 -0
- package/plugins/emittery-2/plugin.json +10 -0
- package/plugins/emittery-2/skills/emittery/SKILL.md +234 -0
- package/plugins/eslint-10/.claude-plugin/plugin.json +9 -0
- package/plugins/eslint-10/LICENSE +93 -0
- package/plugins/eslint-10/NOTICE +51 -0
- package/plugins/eslint-10/gemini-extension.json +1 -0
- package/plugins/eslint-10/plugin.json +10 -0
- package/plugins/eslint-10/skills/eslint/SKILL.md +77 -0
- package/plugins/eslint-9/.claude-plugin/plugin.json +9 -0
- package/plugins/eslint-9/LICENSE +93 -0
- package/plugins/eslint-9/NOTICE +51 -0
- package/plugins/eslint-9/gemini-extension.json +1 -0
- package/plugins/eslint-9/plugin.json +10 -0
- package/plugins/eslint-9/skills/eslint/SKILL.md +93 -0
- package/plugins/eslint-plugin-react-hooks-7/.claude-plugin/plugin.json +9 -0
- package/plugins/eslint-plugin-react-hooks-7/LICENSE +93 -0
- package/plugins/eslint-plugin-react-hooks-7/NOTICE +51 -0
- package/plugins/eslint-plugin-react-hooks-7/gemini-extension.json +1 -0
- package/plugins/eslint-plugin-react-hooks-7/plugin.json +10 -0
- package/plugins/eslint-plugin-react-hooks-7/skills/eslint-plugin-react-hooks/SKILL.md +173 -0
- package/plugins/eslint-plugin-testing-library-7/.claude-plugin/plugin.json +9 -0
- package/plugins/eslint-plugin-testing-library-7/LICENSE +93 -0
- package/plugins/eslint-plugin-testing-library-7/NOTICE +51 -0
- package/plugins/eslint-plugin-testing-library-7/gemini-extension.json +1 -0
- package/plugins/eslint-plugin-testing-library-7/plugin.json +10 -0
- package/plugins/eslint-plugin-testing-library-7/skills/eslint-plugin-testing-library/SKILL.md +193 -0
- package/plugins/expect-type-1/.claude-plugin/plugin.json +9 -0
- package/plugins/expect-type-1/LICENSE +93 -0
- package/plugins/expect-type-1/NOTICE +51 -0
- package/plugins/expect-type-1/gemini-extension.json +1 -0
- package/plugins/expect-type-1/plugin.json +10 -0
- package/plugins/expect-type-1/skills/expect-type/SKILL.md +165 -0
- package/plugins/express-5/.claude-plugin/plugin.json +9 -0
- package/plugins/express-5/LICENSE +93 -0
- package/plugins/express-5/NOTICE +51 -0
- package/plugins/express-5/gemini-extension.json +1 -0
- package/plugins/express-5/plugin.json +10 -0
- package/plugins/express-5/skills/express/SKILL.md +179 -0
- package/plugins/fake-indexeddb-6/.claude-plugin/plugin.json +9 -0
- package/plugins/fake-indexeddb-6/LICENSE +93 -0
- package/plugins/fake-indexeddb-6/NOTICE +51 -0
- package/plugins/fake-indexeddb-6/gemini-extension.json +1 -0
- package/plugins/fake-indexeddb-6/plugin.json +10 -0
- package/plugins/fake-indexeddb-6/skills/fake-indexeddb/SKILL.md +147 -0
- package/plugins/fast-check-4/.claude-plugin/plugin.json +9 -0
- package/plugins/fast-check-4/LICENSE +93 -0
- package/plugins/fast-check-4/NOTICE +51 -0
- package/plugins/fast-check-4/gemini-extension.json +1 -0
- package/plugins/fast-check-4/plugin.json +10 -0
- package/plugins/fast-check-4/skills/fast-check/SKILL.md +168 -0
- package/plugins/figures-6/.claude-plugin/plugin.json +9 -0
- package/plugins/figures-6/LICENSE +93 -0
- package/plugins/figures-6/NOTICE +51 -0
- package/plugins/figures-6/gemini-extension.json +1 -0
- package/plugins/figures-6/plugin.json +10 -0
- package/plugins/figures-6/skills/figures/SKILL.md +99 -0
- package/plugins/firebase-12/.claude-plugin/plugin.json +9 -0
- package/plugins/firebase-12/LICENSE +93 -0
- package/plugins/firebase-12/NOTICE +51 -0
- package/plugins/firebase-12/gemini-extension.json +1 -0
- package/plugins/firebase-12/plugin.json +10 -0
- package/plugins/firebase-12/skills/firebase/SKILL.md +161 -0
- package/plugins/firebase-admin-14/.claude-plugin/plugin.json +9 -0
- package/plugins/firebase-admin-14/LICENSE +93 -0
- package/plugins/firebase-admin-14/NOTICE +51 -0
- package/plugins/firebase-admin-14/gemini-extension.json +1 -0
- package/plugins/firebase-admin-14/plugin.json +10 -0
- package/plugins/firebase-admin-14/skills/firebase-admin/SKILL.md +155 -0
- package/plugins/get-uri-8/.claude-plugin/plugin.json +9 -0
- package/plugins/get-uri-8/LICENSE +93 -0
- package/plugins/get-uri-8/NOTICE +51 -0
- package/plugins/get-uri-8/gemini-extension.json +1 -0
- package/plugins/get-uri-8/plugin.json +10 -0
- package/plugins/get-uri-8/skills/get-uri/SKILL.md +112 -0
- package/plugins/google-uuid-1/.claude-plugin/plugin.json +9 -0
- package/plugins/google-uuid-1/LICENSE +93 -0
- package/plugins/google-uuid-1/NOTICE +51 -0
- package/plugins/google-uuid-1/gemini-extension.json +1 -0
- package/plugins/google-uuid-1/plugin.json +10 -0
- package/plugins/google-uuid-1/skills/google-uuid/SKILL.md +70 -0
- package/plugins/graphql-16/.claude-plugin/plugin.json +9 -0
- package/plugins/graphql-16/LICENSE +93 -0
- package/plugins/graphql-16/NOTICE +51 -0
- package/plugins/graphql-16/gemini-extension.json +1 -0
- package/plugins/graphql-16/plugin.json +10 -0
- package/plugins/graphql-16/skills/graphql/SKILL.md +56 -0
- package/plugins/graphql-17/.claude-plugin/plugin.json +9 -0
- package/plugins/graphql-17/LICENSE +93 -0
- package/plugins/graphql-17/NOTICE +51 -0
- package/plugins/graphql-17/gemini-extension.json +1 -0
- package/plugins/graphql-17/plugin.json +10 -0
- package/plugins/graphql-17/skills/graphql/SKILL.md +159 -0
- package/plugins/graphql-yoga-5/.claude-plugin/plugin.json +9 -0
- package/plugins/graphql-yoga-5/LICENSE +93 -0
- package/plugins/graphql-yoga-5/NOTICE +51 -0
- package/plugins/graphql-yoga-5/gemini-extension.json +1 -0
- package/plugins/graphql-yoga-5/plugin.json +10 -0
- package/plugins/graphql-yoga-5/skills/graphql-yoga/SKILL.md +68 -0
- package/plugins/happy-dom-20/.claude-plugin/plugin.json +9 -0
- package/plugins/happy-dom-20/LICENSE +93 -0
- package/plugins/happy-dom-20/NOTICE +51 -0
- package/plugins/happy-dom-20/gemini-extension.json +1 -0
- package/plugins/happy-dom-20/plugin.json +10 -0
- package/plugins/happy-dom-20/skills/happy-dom/SKILL.md +172 -0
- package/plugins/hono-4/.claude-plugin/plugin.json +9 -0
- package/plugins/hono-4/LICENSE +93 -0
- package/plugins/hono-4/NOTICE +51 -0
- package/plugins/hono-4/gemini-extension.json +1 -0
- package/plugins/hono-4/plugin.json +10 -0
- package/plugins/hono-4/skills/hono/SKILL.md +203 -0
- package/plugins/http-proxy-agent-9/.claude-plugin/plugin.json +9 -0
- package/plugins/http-proxy-agent-9/LICENSE +93 -0
- package/plugins/http-proxy-agent-9/NOTICE +51 -0
- package/plugins/http-proxy-agent-9/gemini-extension.json +1 -0
- package/plugins/http-proxy-agent-9/plugin.json +10 -0
- package/plugins/http-proxy-agent-9/skills/http-proxy-agent/SKILL.md +142 -0
- package/plugins/human-signals-8/.claude-plugin/plugin.json +9 -0
- package/plugins/human-signals-8/LICENSE +93 -0
- package/plugins/human-signals-8/NOTICE +51 -0
- package/plugins/human-signals-8/gemini-extension.json +1 -0
- package/plugins/human-signals-8/plugin.json +10 -0
- package/plugins/human-signals-8/skills/human-signals/SKILL.md +81 -0
- package/plugins/inquirer-14/.claude-plugin/plugin.json +9 -0
- package/plugins/inquirer-14/LICENSE +93 -0
- package/plugins/inquirer-14/NOTICE +51 -0
- package/plugins/inquirer-14/gemini-extension.json +1 -0
- package/plugins/inquirer-14/plugin.json +10 -0
- package/plugins/inquirer-14/skills/inquirer/SKILL.md +152 -0
- package/plugins/ioredis-5/.claude-plugin/plugin.json +9 -0
- package/plugins/ioredis-5/LICENSE +93 -0
- package/plugins/ioredis-5/NOTICE +51 -0
- package/plugins/ioredis-5/gemini-extension.json +1 -0
- package/plugins/ioredis-5/plugin.json +10 -0
- package/plugins/ioredis-5/skills/ioredis/SKILL.md +63 -0
- package/plugins/ioredis-6/.claude-plugin/plugin.json +9 -0
- package/plugins/ioredis-6/LICENSE +93 -0
- package/plugins/ioredis-6/NOTICE +51 -0
- package/plugins/ioredis-6/gemini-extension.json +1 -0
- package/plugins/ioredis-6/plugin.json +10 -0
- package/plugins/ioredis-6/skills/ioredis/SKILL.md +204 -0
- package/plugins/ip-address-10/.claude-plugin/plugin.json +9 -0
- package/plugins/ip-address-10/LICENSE +93 -0
- package/plugins/ip-address-10/NOTICE +51 -0
- package/plugins/ip-address-10/gemini-extension.json +1 -0
- package/plugins/ip-address-10/plugin.json +10 -0
- package/plugins/ip-address-10/skills/ip-address/SKILL.md +184 -0
- package/plugins/jackspeak-4/.claude-plugin/plugin.json +9 -0
- package/plugins/jackspeak-4/LICENSE +93 -0
- package/plugins/jackspeak-4/NOTICE +51 -0
- package/plugins/jackspeak-4/gemini-extension.json +1 -0
- package/plugins/jackspeak-4/plugin.json +10 -0
- package/plugins/jackspeak-4/skills/jackspeak/SKILL.md +162 -0
- package/plugins/jake-12/.claude-plugin/plugin.json +9 -0
- package/plugins/jake-12/LICENSE +93 -0
- package/plugins/jake-12/NOTICE +51 -0
- package/plugins/jake-12/gemini-extension.json +1 -0
- package/plugins/jake-12/plugin.json +10 -0
- package/plugins/jake-12/skills/jake/SKILL.md +182 -0
- package/plugins/jasmine-core-7/.claude-plugin/plugin.json +9 -0
- package/plugins/jasmine-core-7/LICENSE +93 -0
- package/plugins/jasmine-core-7/NOTICE +51 -0
- package/plugins/jasmine-core-7/gemini-extension.json +1 -0
- package/plugins/jasmine-core-7/plugin.json +10 -0
- package/plugins/jasmine-core-7/skills/jasmine-core/SKILL.md +173 -0
- package/plugins/jest-cli-30/.claude-plugin/plugin.json +9 -0
- package/plugins/jest-cli-30/LICENSE +93 -0
- package/plugins/jest-cli-30/NOTICE +51 -0
- package/plugins/jest-cli-30/gemini-extension.json +1 -0
- package/plugins/jest-cli-30/plugin.json +10 -0
- package/plugins/jest-cli-30/skills/jest-cli/SKILL.md +121 -0
- package/plugins/jest-extended-7/.claude-plugin/plugin.json +9 -0
- package/plugins/jest-extended-7/LICENSE +93 -0
- package/plugins/jest-extended-7/NOTICE +51 -0
- package/plugins/jest-extended-7/gemini-extension.json +1 -0
- package/plugins/jest-extended-7/plugin.json +10 -0
- package/plugins/jest-extended-7/skills/jest-extended/SKILL.md +125 -0
- package/plugins/jsdom-30/.claude-plugin/plugin.json +9 -0
- package/plugins/jsdom-30/LICENSE +93 -0
- package/plugins/jsdom-30/NOTICE +51 -0
- package/plugins/jsdom-30/gemini-extension.json +1 -0
- package/plugins/jsdom-30/plugin.json +10 -0
- package/plugins/jsdom-30/skills/jsdom/SKILL.md +64 -0
- package/plugins/level-supports-6/.claude-plugin/plugin.json +9 -0
- package/plugins/level-supports-6/LICENSE +93 -0
- package/plugins/level-supports-6/NOTICE +51 -0
- package/plugins/level-supports-6/gemini-extension.json +1 -0
- package/plugins/level-supports-6/plugin.json +10 -0
- package/plugins/level-supports-6/skills/level-supports/SKILL.md +178 -0
- package/plugins/lowdb-7/.claude-plugin/plugin.json +9 -0
- package/plugins/lowdb-7/LICENSE +93 -0
- package/plugins/lowdb-7/NOTICE +51 -0
- package/plugins/lowdb-7/gemini-extension.json +1 -0
- package/plugins/lowdb-7/plugin.json +10 -0
- package/plugins/lowdb-7/skills/lowdb/SKILL.md +163 -0
- package/plugins/make-fetch-happen-16/.claude-plugin/plugin.json +9 -0
- package/plugins/make-fetch-happen-16/LICENSE +93 -0
- package/plugins/make-fetch-happen-16/NOTICE +51 -0
- package/plugins/make-fetch-happen-16/gemini-extension.json +1 -0
- package/plugins/make-fetch-happen-16/plugin.json +10 -0
- package/plugins/make-fetch-happen-16/skills/make-fetch-happen/SKILL.md +171 -0
- package/plugins/mdx-bundler-10/.claude-plugin/plugin.json +9 -0
- package/plugins/mdx-bundler-10/LICENSE +93 -0
- package/plugins/mdx-bundler-10/NOTICE +51 -0
- package/plugins/mdx-bundler-10/gemini-extension.json +1 -0
- package/plugins/mdx-bundler-10/plugin.json +10 -0
- package/plugins/mdx-bundler-10/skills/mdx-bundler/SKILL.md +133 -0
- package/plugins/mocha-12/.claude-plugin/plugin.json +9 -0
- package/plugins/mocha-12/LICENSE +93 -0
- package/plugins/mocha-12/NOTICE +51 -0
- package/plugins/mocha-12/gemini-extension.json +1 -0
- package/plugins/mocha-12/plugin.json +10 -0
- package/plugins/mocha-12/skills/mocha/SKILL.md +157 -0
- package/plugins/modelcontextprotocol-client-2/.claude-plugin/plugin.json +9 -0
- package/plugins/modelcontextprotocol-client-2/LICENSE +93 -0
- package/plugins/modelcontextprotocol-client-2/NOTICE +51 -0
- package/plugins/modelcontextprotocol-client-2/gemini-extension.json +1 -0
- package/plugins/modelcontextprotocol-client-2/plugin.json +10 -0
- package/plugins/modelcontextprotocol-client-2/skills/modelcontextprotocol-client/SKILL.md +86 -0
- package/plugins/modelcontextprotocol-sdk-1/.claude-plugin/plugin.json +9 -0
- package/plugins/modelcontextprotocol-sdk-1/LICENSE +93 -0
- package/plugins/modelcontextprotocol-sdk-1/NOTICE +51 -0
- package/plugins/modelcontextprotocol-sdk-1/gemini-extension.json +1 -0
- package/plugins/modelcontextprotocol-sdk-1/plugin.json +10 -0
- package/plugins/modelcontextprotocol-sdk-1/skills/modelcontextprotocol-sdk/SKILL.md +80 -0
- package/plugins/modelcontextprotocol-server-2/.claude-plugin/plugin.json +9 -0
- package/plugins/modelcontextprotocol-server-2/LICENSE +93 -0
- package/plugins/modelcontextprotocol-server-2/NOTICE +51 -0
- package/plugins/modelcontextprotocol-server-2/gemini-extension.json +1 -0
- package/plugins/modelcontextprotocol-server-2/plugin.json +10 -0
- package/plugins/modelcontextprotocol-server-2/skills/modelcontextprotocol-server/SKILL.md +80 -0
- package/plugins/msw-2/.claude-plugin/plugin.json +9 -0
- package/plugins/msw-2/LICENSE +93 -0
- package/plugins/msw-2/NOTICE +51 -0
- package/plugins/msw-2/gemini-extension.json +1 -0
- package/plugins/msw-2/plugin.json +10 -0
- package/plugins/msw-2/skills/msw/SKILL.md +182 -0
- package/plugins/negotiator-1/.claude-plugin/plugin.json +9 -0
- package/plugins/negotiator-1/LICENSE +93 -0
- package/plugins/negotiator-1/NOTICE +51 -0
- package/plugins/negotiator-1/gemini-extension.json +1 -0
- package/plugins/negotiator-1/plugin.json +10 -0
- package/plugins/negotiator-1/skills/negotiator/SKILL.md +180 -0
- package/plugins/npm-run-path-6/.claude-plugin/plugin.json +9 -0
- package/plugins/npm-run-path-6/LICENSE +93 -0
- package/plugins/npm-run-path-6/NOTICE +51 -0
- package/plugins/npm-run-path-6/gemini-extension.json +1 -0
- package/plugins/npm-run-path-6/plugin.json +10 -0
- package/plugins/npm-run-path-6/skills/npm-run-path/SKILL.md +137 -0
- package/plugins/nyc-18/.claude-plugin/plugin.json +9 -0
- package/plugins/nyc-18/LICENSE +93 -0
- package/plugins/nyc-18/NOTICE +51 -0
- package/plugins/nyc-18/gemini-extension.json +1 -0
- package/plugins/nyc-18/plugin.json +10 -0
- package/plugins/nyc-18/skills/nyc/SKILL.md +152 -0
- package/plugins/ow-3/.claude-plugin/plugin.json +9 -0
- package/plugins/ow-3/LICENSE +93 -0
- package/plugins/ow-3/NOTICE +51 -0
- package/plugins/ow-3/gemini-extension.json +1 -0
- package/plugins/ow-3/plugin.json +10 -0
- package/plugins/ow-3/skills/ow/SKILL.md +159 -0
- package/plugins/pac-proxy-agent-9/.claude-plugin/plugin.json +9 -0
- package/plugins/pac-proxy-agent-9/LICENSE +93 -0
- package/plugins/pac-proxy-agent-9/NOTICE +51 -0
- package/plugins/pac-proxy-agent-9/gemini-extension.json +1 -0
- package/plugins/pac-proxy-agent-9/plugin.json +10 -0
- package/plugins/pac-proxy-agent-9/skills/pac-proxy-agent/SKILL.md +111 -0
- package/plugins/pgsql-ast-parser-12/.claude-plugin/plugin.json +9 -0
- package/plugins/pgsql-ast-parser-12/LICENSE +93 -0
- package/plugins/pgsql-ast-parser-12/NOTICE +51 -0
- package/plugins/pgsql-ast-parser-12/gemini-extension.json +1 -0
- package/plugins/pgsql-ast-parser-12/plugin.json +10 -0
- package/plugins/pgsql-ast-parser-12/skills/pgsql-ast-parser/SKILL.md +136 -0
- package/plugins/playwright-test-1/.claude-plugin/plugin.json +9 -0
- package/plugins/playwright-test-1/LICENSE +93 -0
- package/plugins/playwright-test-1/NOTICE +51 -0
- package/plugins/playwright-test-1/gemini-extension.json +1 -0
- package/plugins/playwright-test-1/plugin.json +10 -0
- package/plugins/playwright-test-1/skills/playwright-test/SKILL.md +222 -0
- package/plugins/pmcp/.claude-plugin/plugin.json +9 -0
- package/plugins/pmcp/.mcp.json +9 -0
- package/plugins/pmcp/LICENSE +93 -0
- package/plugins/pmcp/NOTICE +51 -0
- package/plugins/pmcp/gemini-extension.json +11 -0
- package/plugins/pmcp/mcp.json +10 -0
- package/plugins/pmcp/plugin.json +10 -0
- package/plugins/pmcp/skills/package-skill-catalog/SKILL.md +54 -0
- package/plugins/pothos-core-4/.claude-plugin/plugin.json +9 -0
- package/plugins/pothos-core-4/LICENSE +93 -0
- package/plugins/pothos-core-4/NOTICE +51 -0
- package/plugins/pothos-core-4/gemini-extension.json +1 -0
- package/plugins/pothos-core-4/plugin.json +10 -0
- package/plugins/pothos-core-4/skills/pothos-core/SKILL.md +68 -0
- package/plugins/prettier-3/.claude-plugin/plugin.json +9 -0
- package/plugins/prettier-3/LICENSE +93 -0
- package/plugins/prettier-3/NOTICE +51 -0
- package/plugins/prettier-3/gemini-extension.json +1 -0
- package/plugins/prettier-3/plugin.json +10 -0
- package/plugins/prettier-3/skills/prettier/SKILL.md +69 -0
- package/plugins/protobufjs-8/.claude-plugin/plugin.json +9 -0
- package/plugins/protobufjs-8/LICENSE +93 -0
- package/plugins/protobufjs-8/NOTICE +51 -0
- package/plugins/protobufjs-8/gemini-extension.json +1 -0
- package/plugins/protobufjs-8/plugin.json +10 -0
- package/plugins/protobufjs-8/skills/protobufjs/SKILL.md +128 -0
- package/plugins/proxy-agent-8/.claude-plugin/plugin.json +9 -0
- package/plugins/proxy-agent-8/LICENSE +93 -0
- package/plugins/proxy-agent-8/NOTICE +51 -0
- package/plugins/proxy-agent-8/gemini-extension.json +1 -0
- package/plugins/proxy-agent-8/plugin.json +10 -0
- package/plugins/proxy-agent-8/skills/proxy-agent/SKILL.md +120 -0
- package/plugins/pydantic-2/.claude-plugin/plugin.json +9 -0
- package/plugins/pydantic-2/LICENSE +93 -0
- package/plugins/pydantic-2/NOTICE +51 -0
- package/plugins/pydantic-2/gemini-extension.json +1 -0
- package/plugins/pydantic-2/plugin.json +10 -0
- package/plugins/pydantic-2/skills/pydantic/SKILL.md +74 -0
- package/plugins/react-19/.claude-plugin/plugin.json +9 -0
- package/plugins/react-19/LICENSE +93 -0
- package/plugins/react-19/NOTICE +51 -0
- package/plugins/react-19/gemini-extension.json +1 -0
- package/plugins/react-19/plugin.json +10 -0
- package/plugins/react-19/skills/react/SKILL.md +150 -0
- package/plugins/react-dom-19/.claude-plugin/plugin.json +9 -0
- package/plugins/react-dom-19/LICENSE +93 -0
- package/plugins/react-dom-19/NOTICE +51 -0
- package/plugins/react-dom-19/gemini-extension.json +1 -0
- package/plugins/react-dom-19/plugin.json +10 -0
- package/plugins/react-dom-19/skills/react-dom/SKILL.md +178 -0
- package/plugins/react-icons-5/.claude-plugin/plugin.json +9 -0
- package/plugins/react-icons-5/LICENSE +93 -0
- package/plugins/react-icons-5/NOTICE +51 -0
- package/plugins/react-icons-5/gemini-extension.json +1 -0
- package/plugins/react-icons-5/plugin.json +10 -0
- package/plugins/react-icons-5/skills/react-icons/SKILL.md +194 -0
- package/plugins/react-is-19/.claude-plugin/plugin.json +9 -0
- package/plugins/react-is-19/LICENSE +93 -0
- package/plugins/react-is-19/NOTICE +51 -0
- package/plugins/react-is-19/gemini-extension.json +1 -0
- package/plugins/react-is-19/plugin.json +10 -0
- package/plugins/react-is-19/skills/react-is/SKILL.md +131 -0
- package/plugins/react-markdown-10/.claude-plugin/plugin.json +9 -0
- package/plugins/react-markdown-10/LICENSE +93 -0
- package/plugins/react-markdown-10/NOTICE +51 -0
- package/plugins/react-markdown-10/gemini-extension.json +1 -0
- package/plugins/react-markdown-10/plugin.json +10 -0
- package/plugins/react-markdown-10/skills/react-markdown/SKILL.md +163 -0
- package/plugins/react-router-8/.claude-plugin/plugin.json +9 -0
- package/plugins/react-router-8/LICENSE +93 -0
- package/plugins/react-router-8/NOTICE +51 -0
- package/plugins/react-router-8/gemini-extension.json +1 -0
- package/plugins/react-router-8/plugin.json +10 -0
- package/plugins/react-router-8/skills/react-router/SKILL.md +115 -0
- package/plugins/release-it-21/.claude-plugin/plugin.json +9 -0
- package/plugins/release-it-21/LICENSE +93 -0
- package/plugins/release-it-21/NOTICE +51 -0
- package/plugins/release-it-21/gemini-extension.json +1 -0
- package/plugins/release-it-21/plugin.json +10 -0
- package/plugins/release-it-21/skills/release-it/SKILL.md +202 -0
- package/plugins/reselect-5/.claude-plugin/plugin.json +9 -0
- package/plugins/reselect-5/LICENSE +93 -0
- package/plugins/reselect-5/NOTICE +51 -0
- package/plugins/reselect-5/gemini-extension.json +1 -0
- package/plugins/reselect-5/plugin.json +10 -0
- package/plugins/reselect-5/skills/reselect/SKILL.md +215 -0
- package/plugins/responselike-4/.claude-plugin/plugin.json +9 -0
- package/plugins/responselike-4/LICENSE +93 -0
- package/plugins/responselike-4/NOTICE +51 -0
- package/plugins/responselike-4/gemini-extension.json +1 -0
- package/plugins/responselike-4/plugin.json +10 -0
- package/plugins/responselike-4/skills/responselike/SKILL.md +173 -0
- package/plugins/rolldown-1/.claude-plugin/plugin.json +9 -0
- package/plugins/rolldown-1/LICENSE +93 -0
- package/plugins/rolldown-1/NOTICE +51 -0
- package/plugins/rolldown-1/gemini-extension.json +1 -0
- package/plugins/rolldown-1/plugin.json +10 -0
- package/plugins/rolldown-1/skills/rolldown/SKILL.md +182 -0
- package/plugins/semver-7/.claude-plugin/plugin.json +9 -0
- package/plugins/semver-7/LICENSE +93 -0
- package/plugins/semver-7/NOTICE +51 -0
- package/plugins/semver-7/gemini-extension.json +1 -0
- package/plugins/semver-7/plugin.json +10 -0
- package/plugins/semver-7/skills/semver/SKILL.md +55 -0
- package/plugins/serde-json-1/.claude-plugin/plugin.json +9 -0
- package/plugins/serde-json-1/LICENSE +93 -0
- package/plugins/serde-json-1/NOTICE +51 -0
- package/plugins/serde-json-1/gemini-extension.json +1 -0
- package/plugins/serde-json-1/plugin.json +10 -0
- package/plugins/serde-json-1/skills/serde-json/SKILL.md +68 -0
- package/plugins/sinon-22/.claude-plugin/plugin.json +9 -0
- package/plugins/sinon-22/LICENSE +93 -0
- package/plugins/sinon-22/NOTICE +51 -0
- package/plugins/sinon-22/gemini-extension.json +1 -0
- package/plugins/sinon-22/plugin.json +10 -0
- package/plugins/sinon-22/skills/sinon/SKILL.md +215 -0
- package/plugins/slice-ansi-9/.claude-plugin/plugin.json +9 -0
- package/plugins/slice-ansi-9/LICENSE +93 -0
- package/plugins/slice-ansi-9/NOTICE +51 -0
- package/plugins/slice-ansi-9/gemini-extension.json +1 -0
- package/plugins/slice-ansi-9/plugin.json +10 -0
- package/plugins/slice-ansi-9/skills/slice-ansi/SKILL.md +111 -0
- package/plugins/smol-toml-1/.claude-plugin/plugin.json +9 -0
- package/plugins/smol-toml-1/LICENSE +93 -0
- package/plugins/smol-toml-1/NOTICE +51 -0
- package/plugins/smol-toml-1/gemini-extension.json +1 -0
- package/plugins/smol-toml-1/plugin.json +10 -0
- package/plugins/smol-toml-1/skills/smol-toml/SKILL.md +63 -0
- package/plugins/socks-proxy-agent-10/.claude-plugin/plugin.json +9 -0
- package/plugins/socks-proxy-agent-10/LICENSE +93 -0
- package/plugins/socks-proxy-agent-10/NOTICE +51 -0
- package/plugins/socks-proxy-agent-10/gemini-extension.json +1 -0
- package/plugins/socks-proxy-agent-10/plugin.json +10 -0
- package/plugins/socks-proxy-agent-10/skills/socks-proxy-agent/SKILL.md +172 -0
- package/plugins/string-width-8/.claude-plugin/plugin.json +9 -0
- package/plugins/string-width-8/LICENSE +93 -0
- package/plugins/string-width-8/NOTICE +51 -0
- package/plugins/string-width-8/gemini-extension.json +1 -0
- package/plugins/string-width-8/plugin.json +10 -0
- package/plugins/string-width-8/skills/string-width/SKILL.md +101 -0
- package/plugins/superstruct-2/.claude-plugin/plugin.json +9 -0
- package/plugins/superstruct-2/LICENSE +93 -0
- package/plugins/superstruct-2/NOTICE +51 -0
- package/plugins/superstruct-2/gemini-extension.json +1 -0
- package/plugins/superstruct-2/plugin.json +10 -0
- package/plugins/superstruct-2/skills/superstruct/SKILL.md +170 -0
- package/plugins/supports-color-11/.claude-plugin/plugin.json +9 -0
- package/plugins/supports-color-11/LICENSE +93 -0
- package/plugins/supports-color-11/NOTICE +51 -0
- package/plugins/supports-color-11/gemini-extension.json +1 -0
- package/plugins/supports-color-11/plugin.json +10 -0
- package/plugins/supports-color-11/skills/supports-color/SKILL.md +115 -0
- package/plugins/tailwindcss-3/.claude-plugin/plugin.json +9 -0
- package/plugins/tailwindcss-3/LICENSE +93 -0
- package/plugins/tailwindcss-3/NOTICE +51 -0
- package/plugins/tailwindcss-3/gemini-extension.json +1 -0
- package/plugins/tailwindcss-3/plugin.json +10 -0
- package/plugins/tailwindcss-3/skills/tailwindcss/SKILL.md +72 -0
- package/plugins/tailwindcss-4/.claude-plugin/plugin.json +9 -0
- package/plugins/tailwindcss-4/LICENSE +93 -0
- package/plugins/tailwindcss-4/NOTICE +51 -0
- package/plugins/tailwindcss-4/gemini-extension.json +1 -0
- package/plugins/tailwindcss-4/plugin.json +10 -0
- package/plugins/tailwindcss-4/skills/tailwindcss/SKILL.md +82 -0
- package/plugins/tanstack-react-router-1/.claude-plugin/plugin.json +9 -0
- package/plugins/tanstack-react-router-1/LICENSE +93 -0
- package/plugins/tanstack-react-router-1/NOTICE +51 -0
- package/plugins/tanstack-react-router-1/gemini-extension.json +1 -0
- package/plugins/tanstack-react-router-1/plugin.json +10 -0
- package/plugins/tanstack-react-router-1/skills/tanstack-react-router/SKILL.md +96 -0
- package/plugins/tedious-20/.claude-plugin/plugin.json +9 -0
- package/plugins/tedious-20/LICENSE +93 -0
- package/plugins/tedious-20/NOTICE +51 -0
- package/plugins/tedious-20/gemini-extension.json +1 -0
- package/plugins/tedious-20/plugin.json +10 -0
- package/plugins/tedious-20/skills/tedious/SKILL.md +174 -0
- package/plugins/testing-library-react-16/.claude-plugin/plugin.json +9 -0
- package/plugins/testing-library-react-16/LICENSE +93 -0
- package/plugins/testing-library-react-16/NOTICE +51 -0
- package/plugins/testing-library-react-16/gemini-extension.json +1 -0
- package/plugins/testing-library-react-16/plugin.json +10 -0
- package/plugins/testing-library-react-16/skills/testing-library-react/SKILL.md +92 -0
- package/plugins/tinyspy-4/.claude-plugin/plugin.json +9 -0
- package/plugins/tinyspy-4/LICENSE +93 -0
- package/plugins/tinyspy-4/NOTICE +51 -0
- package/plugins/tinyspy-4/gemini-extension.json +1 -0
- package/plugins/tinyspy-4/plugin.json +10 -0
- package/plugins/tinyspy-4/skills/tinyspy/SKILL.md +158 -0
- package/plugins/tldts-7/.claude-plugin/plugin.json +9 -0
- package/plugins/tldts-7/LICENSE +93 -0
- package/plugins/tldts-7/NOTICE +51 -0
- package/plugins/tldts-7/gemini-extension.json +1 -0
- package/plugins/tldts-7/plugin.json +10 -0
- package/plugins/tldts-7/skills/tldts/SKILL.md +120 -0
- package/plugins/ts-morph-28/.claude-plugin/plugin.json +9 -0
- package/plugins/ts-morph-28/LICENSE +93 -0
- package/plugins/ts-morph-28/NOTICE +51 -0
- package/plugins/ts-morph-28/gemini-extension.json +1 -0
- package/plugins/ts-morph-28/plugin.json +10 -0
- package/plugins/ts-morph-28/skills/ts-morph/SKILL.md +219 -0
- package/plugins/tsup-8/.claude-plugin/plugin.json +9 -0
- package/plugins/tsup-8/LICENSE +93 -0
- package/plugins/tsup-8/NOTICE +51 -0
- package/plugins/tsup-8/gemini-extension.json +1 -0
- package/plugins/tsup-8/plugin.json +10 -0
- package/plugins/tsup-8/skills/tsup/SKILL.md +97 -0
- package/plugins/tsx-4/.claude-plugin/plugin.json +9 -0
- package/plugins/tsx-4/LICENSE +93 -0
- package/plugins/tsx-4/NOTICE +51 -0
- package/plugins/tsx-4/gemini-extension.json +1 -0
- package/plugins/tsx-4/plugin.json +10 -0
- package/plugins/tsx-4/skills/tsx/SKILL.md +159 -0
- package/plugins/type-fest-5/.claude-plugin/plugin.json +9 -0
- package/plugins/type-fest-5/LICENSE +93 -0
- package/plugins/type-fest-5/NOTICE +51 -0
- package/plugins/type-fest-5/gemini-extension.json +1 -0
- package/plugins/type-fest-5/plugin.json +10 -0
- package/plugins/type-fest-5/skills/type-fest/SKILL.md +132 -0
- package/plugins/typescript-5/.claude-plugin/plugin.json +9 -0
- package/plugins/typescript-5/LICENSE +93 -0
- package/plugins/typescript-5/NOTICE +51 -0
- package/plugins/typescript-5/gemini-extension.json +1 -0
- package/plugins/typescript-5/plugin.json +10 -0
- package/plugins/typescript-5/skills/typescript/SKILL.md +107 -0
- package/plugins/typescript-eslint-8/.claude-plugin/plugin.json +9 -0
- package/plugins/typescript-eslint-8/LICENSE +93 -0
- package/plugins/typescript-eslint-8/NOTICE +51 -0
- package/plugins/typescript-eslint-8/gemini-extension.json +1 -0
- package/plugins/typescript-eslint-8/plugin.json +10 -0
- package/plugins/typescript-eslint-8/skills/typescript-eslint/SKILL.md +179 -0
- package/plugins/typescript-eslint-eslint-plugin-8/.claude-plugin/plugin.json +9 -0
- package/plugins/typescript-eslint-eslint-plugin-8/LICENSE +93 -0
- package/plugins/typescript-eslint-eslint-plugin-8/NOTICE +51 -0
- package/plugins/typescript-eslint-eslint-plugin-8/gemini-extension.json +1 -0
- package/plugins/typescript-eslint-eslint-plugin-8/plugin.json +10 -0
- package/plugins/typescript-eslint-eslint-plugin-8/skills/typescript-eslint-eslint-plugin/SKILL.md +158 -0
- package/plugins/typescript-eslint-estree-8/.claude-plugin/plugin.json +9 -0
- package/plugins/typescript-eslint-estree-8/LICENSE +93 -0
- package/plugins/typescript-eslint-estree-8/NOTICE +51 -0
- package/plugins/typescript-eslint-estree-8/gemini-extension.json +1 -0
- package/plugins/typescript-eslint-estree-8/plugin.json +10 -0
- package/plugins/typescript-eslint-estree-8/skills/typescript-eslint-estree/SKILL.md +125 -0
- package/plugins/typescript-eslint-parser-8/.claude-plugin/plugin.json +9 -0
- package/plugins/typescript-eslint-parser-8/LICENSE +93 -0
- package/plugins/typescript-eslint-parser-8/NOTICE +51 -0
- package/plugins/typescript-eslint-parser-8/gemini-extension.json +1 -0
- package/plugins/typescript-eslint-parser-8/plugin.json +10 -0
- package/plugins/typescript-eslint-parser-8/skills/typescript-eslint-parser/SKILL.md +141 -0
- package/plugins/typescript-eslint-types-8/.claude-plugin/plugin.json +9 -0
- package/plugins/typescript-eslint-types-8/LICENSE +93 -0
- package/plugins/typescript-eslint-types-8/NOTICE +51 -0
- package/plugins/typescript-eslint-types-8/gemini-extension.json +1 -0
- package/plugins/typescript-eslint-types-8/plugin.json +10 -0
- package/plugins/typescript-eslint-types-8/skills/typescript-eslint-types/SKILL.md +117 -0
- package/plugins/typescript-eslint-utils-8/.claude-plugin/plugin.json +9 -0
- package/plugins/typescript-eslint-utils-8/LICENSE +93 -0
- package/plugins/typescript-eslint-utils-8/NOTICE +51 -0
- package/plugins/typescript-eslint-utils-8/gemini-extension.json +1 -0
- package/plugins/typescript-eslint-utils-8/plugin.json +10 -0
- package/plugins/typescript-eslint-utils-8/skills/typescript-eslint-utils/SKILL.md +195 -0
- package/plugins/typescript-eslint-visitor-keys-8/.claude-plugin/plugin.json +9 -0
- package/plugins/typescript-eslint-visitor-keys-8/LICENSE +93 -0
- package/plugins/typescript-eslint-visitor-keys-8/NOTICE +51 -0
- package/plugins/typescript-eslint-visitor-keys-8/gemini-extension.json +1 -0
- package/plugins/typescript-eslint-visitor-keys-8/plugin.json +10 -0
- package/plugins/typescript-eslint-visitor-keys-8/skills/typescript-eslint-visitor-keys/SKILL.md +116 -0
- package/plugins/valibot-1/.claude-plugin/plugin.json +9 -0
- package/plugins/valibot-1/LICENSE +93 -0
- package/plugins/valibot-1/NOTICE +51 -0
- package/plugins/valibot-1/gemini-extension.json +1 -0
- package/plugins/valibot-1/plugin.json +10 -0
- package/plugins/valibot-1/skills/valibot/SKILL.md +190 -0
- package/plugins/vite-7/.claude-plugin/plugin.json +9 -0
- package/plugins/vite-7/LICENSE +93 -0
- package/plugins/vite-7/NOTICE +51 -0
- package/plugins/vite-7/gemini-extension.json +1 -0
- package/plugins/vite-7/plugin.json +10 -0
- package/plugins/vite-7/skills/vite/SKILL.md +111 -0
- package/plugins/vite-8/.claude-plugin/plugin.json +9 -0
- package/plugins/vite-8/LICENSE +93 -0
- package/plugins/vite-8/NOTICE +51 -0
- package/plugins/vite-8/gemini-extension.json +1 -0
- package/plugins/vite-8/plugin.json +10 -0
- package/plugins/vite-8/skills/vite/SKILL.md +267 -0
- package/plugins/vitejs-plugin-react-5/.claude-plugin/plugin.json +9 -0
- package/plugins/vitejs-plugin-react-5/LICENSE +93 -0
- package/plugins/vitejs-plugin-react-5/NOTICE +51 -0
- package/plugins/vitejs-plugin-react-5/gemini-extension.json +1 -0
- package/plugins/vitejs-plugin-react-5/plugin.json +10 -0
- package/plugins/vitejs-plugin-react-5/skills/vitejs-plugin-react/SKILL.md +67 -0
- package/plugins/vitejs-plugin-react-6/.claude-plugin/plugin.json +9 -0
- package/plugins/vitejs-plugin-react-6/LICENSE +93 -0
- package/plugins/vitejs-plugin-react-6/NOTICE +51 -0
- package/plugins/vitejs-plugin-react-6/gemini-extension.json +1 -0
- package/plugins/vitejs-plugin-react-6/plugin.json +10 -0
- package/plugins/vitejs-plugin-react-6/skills/vitejs-plugin-react/SKILL.md +232 -0
- package/plugins/vitest-4/.claude-plugin/plugin.json +9 -0
- package/plugins/vitest-4/LICENSE +93 -0
- package/plugins/vitest-4/NOTICE +51 -0
- package/plugins/vitest-4/gemini-extension.json +1 -0
- package/plugins/vitest-4/plugin.json +10 -0
- package/plugins/vitest-4/skills/vitest/SKILL.md +127 -0
- package/plugins/vitest-5/.claude-plugin/plugin.json +9 -0
- package/plugins/vitest-5/LICENSE +93 -0
- package/plugins/vitest-5/NOTICE +51 -0
- package/plugins/vitest-5/gemini-extension.json +1 -0
- package/plugins/vitest-5/plugin.json +10 -0
- package/plugins/vitest-5/skills/vitest/SKILL.md +186 -0
- package/plugins/whatwg-mimetype-5/.claude-plugin/plugin.json +9 -0
- package/plugins/whatwg-mimetype-5/LICENSE +93 -0
- package/plugins/whatwg-mimetype-5/NOTICE +51 -0
- package/plugins/whatwg-mimetype-5/gemini-extension.json +1 -0
- package/plugins/whatwg-mimetype-5/plugin.json +10 -0
- package/plugins/whatwg-mimetype-5/skills/whatwg-mimetype/SKILL.md +150 -0
- package/plugins/wrangler-4/.claude-plugin/plugin.json +9 -0
- package/plugins/wrangler-4/LICENSE +93 -0
- package/plugins/wrangler-4/NOTICE +51 -0
- package/plugins/wrangler-4/gemini-extension.json +1 -0
- package/plugins/wrangler-4/plugin.json +10 -0
- package/plugins/wrangler-4/skills/wrangler/SKILL.md +87 -0
- package/plugins/wrap-ansi-10/.claude-plugin/plugin.json +9 -0
- package/plugins/wrap-ansi-10/LICENSE +93 -0
- package/plugins/wrap-ansi-10/NOTICE +51 -0
- package/plugins/wrap-ansi-10/gemini-extension.json +1 -0
- package/plugins/wrap-ansi-10/plugin.json +10 -0
- package/plugins/wrap-ansi-10/skills/wrap-ansi/SKILL.md +119 -0
- package/plugins/yaml-2/.claude-plugin/plugin.json +9 -0
- package/plugins/yaml-2/LICENSE +93 -0
- package/plugins/yaml-2/NOTICE +51 -0
- package/plugins/yaml-2/gemini-extension.json +1 -0
- package/plugins/yaml-2/plugin.json +10 -0
- package/plugins/yaml-2/skills/yaml/SKILL.md +56 -0
- package/plugins/yargs-18/.claude-plugin/plugin.json +9 -0
- package/plugins/yargs-18/LICENSE +93 -0
- package/plugins/yargs-18/NOTICE +51 -0
- package/plugins/yargs-18/gemini-extension.json +1 -0
- package/plugins/yargs-18/plugin.json +10 -0
- package/plugins/yargs-18/skills/yargs/SKILL.md +175 -0
- package/plugins/yargs-parser-22/.claude-plugin/plugin.json +9 -0
- package/plugins/yargs-parser-22/LICENSE +93 -0
- package/plugins/yargs-parser-22/NOTICE +51 -0
- package/plugins/yargs-parser-22/gemini-extension.json +1 -0
- package/plugins/yargs-parser-22/plugin.json +10 -0
- package/plugins/yargs-parser-22/skills/yargs-parser/SKILL.md +179 -0
- package/plugins/yeoman-environment-7/.claude-plugin/plugin.json +9 -0
- package/plugins/yeoman-environment-7/LICENSE +93 -0
- package/plugins/yeoman-environment-7/NOTICE +51 -0
- package/plugins/yeoman-environment-7/gemini-extension.json +1 -0
- package/plugins/yeoman-environment-7/plugin.json +10 -0
- package/plugins/yeoman-environment-7/skills/yeoman-environment/SKILL.md +136 -0
- package/plugins/z-schema-12/.claude-plugin/plugin.json +9 -0
- package/plugins/z-schema-12/LICENSE +93 -0
- package/plugins/z-schema-12/NOTICE +51 -0
- package/plugins/z-schema-12/gemini-extension.json +1 -0
- package/plugins/z-schema-12/plugin.json +10 -0
- package/plugins/z-schema-12/skills/z-schema/SKILL.md +179 -0
- package/plugins/zod-schema-validation-3/.claude-plugin/plugin.json +9 -0
- package/plugins/zod-schema-validation-3/LICENSE +93 -0
- package/plugins/zod-schema-validation-3/NOTICE +51 -0
- package/plugins/zod-schema-validation-3/gemini-extension.json +1 -0
- package/plugins/zod-schema-validation-3/plugin.json +10 -0
- package/plugins/zod-schema-validation-3/skills/zod-schema-validation/SKILL.md +188 -0
- package/plugins/zod-schema-validation-4/.claude-plugin/plugin.json +9 -0
- package/plugins/zod-schema-validation-4/LICENSE +93 -0
- package/plugins/zod-schema-validation-4/NOTICE +51 -0
- package/plugins/zod-schema-validation-4/gemini-extension.json +1 -0
- package/plugins/zod-schema-validation-4/plugin.json +10 -0
- package/plugins/zod-schema-validation-4/skills/zod-schema-validation/SKILL.md +181 -0
- package/plugins/zod-validation-error-5/.claude-plugin/plugin.json +9 -0
- package/plugins/zod-validation-error-5/LICENSE +93 -0
- package/plugins/zod-validation-error-5/NOTICE +51 -0
- package/plugins/zod-validation-error-5/gemini-extension.json +1 -0
- package/plugins/zod-validation-error-5/plugin.json +10 -0
- package/plugins/zod-validation-error-5/skills/zod-validation-error/SKILL.md +212 -0
- package/plugins/zustand-5/.claude-plugin/plugin.json +9 -0
- package/plugins/zustand-5/LICENSE +93 -0
- package/plugins/zustand-5/NOTICE +51 -0
- package/plugins/zustand-5/gemini-extension.json +1 -0
- package/plugins/zustand-5/plugin.json +10 -0
- package/plugins/zustand-5/skills/zustand/SKILL.md +128 -0
- package/skills/package-skill-catalog/SKILL.md +37 -222
package/dist/index.js
CHANGED
|
@@ -137,8 +137,8 @@ async function openIntentCache(options) {
|
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
// src/catalog.ts
|
|
140
|
-
import { existsSync as
|
|
141
|
-
import { basename as basename2, dirname as dirname2, isAbsolute, join as
|
|
140
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3, readdirSync as readdirSync2 } from "fs";
|
|
141
|
+
import { basename as basename2, dirname as dirname2, isAbsolute as isAbsolute2, join as join3, relative as relative2 } from "path";
|
|
142
142
|
|
|
143
143
|
// src/frontmatter.ts
|
|
144
144
|
import { parse } from "yaml";
|
|
@@ -260,8 +260,122 @@ function specProblems(front, directory) {
|
|
|
260
260
|
}
|
|
261
261
|
|
|
262
262
|
// src/marketplace.ts
|
|
263
|
-
import { existsSync, readFileSync, readdirSync } from "fs";
|
|
264
|
-
import { basename, dirname, join, resolve } from "path";
|
|
263
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync } from "fs";
|
|
264
|
+
import { basename, dirname, join as join2, resolve as resolve2 } from "path";
|
|
265
|
+
|
|
266
|
+
// src/marketplace/local.ts
|
|
267
|
+
import { existsSync, readFileSync, realpathSync, statSync } from "fs";
|
|
268
|
+
import { isAbsolute, join, relative, resolve, sep } from "path";
|
|
269
|
+
function object(value) {
|
|
270
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
271
|
+
}
|
|
272
|
+
function containedPath(root, path) {
|
|
273
|
+
const result = resolve(root, path);
|
|
274
|
+
const lexical = relative(resolve(root), result);
|
|
275
|
+
if (isAbsolute(lexical) || lexical === ".." || lexical.startsWith(`..${sep}`))
|
|
276
|
+
throw new Error("Path leaves the plugin root");
|
|
277
|
+
const physical = relative(realpathSync(root), realpathSync(result));
|
|
278
|
+
if (isAbsolute(physical) || physical === ".." || physical.startsWith(`..${sep}`))
|
|
279
|
+
throw new Error("Path leaves the plugin root through a symlink");
|
|
280
|
+
return result;
|
|
281
|
+
}
|
|
282
|
+
function pluginManifest(directory) {
|
|
283
|
+
for (const path of [
|
|
284
|
+
".claude-plugin/plugin.json",
|
|
285
|
+
"plugin.json",
|
|
286
|
+
".codex-plugin/plugin.json",
|
|
287
|
+
".grok-plugin/plugin.json"
|
|
288
|
+
]) {
|
|
289
|
+
if (!existsSync(join(directory, path))) continue;
|
|
290
|
+
const value = JSON.parse(
|
|
291
|
+
readFileSync(containedPath(directory, path), "utf8")
|
|
292
|
+
);
|
|
293
|
+
if (!object(value)) throw new Error("Plugin manifest must be an object");
|
|
294
|
+
return value;
|
|
295
|
+
}
|
|
296
|
+
return {};
|
|
297
|
+
}
|
|
298
|
+
function localSource(value) {
|
|
299
|
+
if (typeof value === "string") return value;
|
|
300
|
+
if (object(value) && value.source === "local" && typeof value.path === "string")
|
|
301
|
+
return value.path;
|
|
302
|
+
throw new Error(
|
|
303
|
+
"Only installed local plugin sources can be read; use the native installer for remote sources"
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
function readLocalMarketplace(directory, onReject) {
|
|
307
|
+
const filename = [
|
|
308
|
+
".claude-plugin/marketplace.json",
|
|
309
|
+
".agents/plugins/marketplace.json",
|
|
310
|
+
".grok-plugin/marketplace.json"
|
|
311
|
+
].find((path2) => existsSync(join(directory, path2)));
|
|
312
|
+
if (!filename) {
|
|
313
|
+
onReject?.({
|
|
314
|
+
path: directory,
|
|
315
|
+
reason: "No supported native marketplace.json found"
|
|
316
|
+
});
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
const path = join(directory, filename);
|
|
320
|
+
let manifest2;
|
|
321
|
+
try {
|
|
322
|
+
manifest2 = JSON.parse(
|
|
323
|
+
readFileSync(containedPath(directory, filename), "utf8")
|
|
324
|
+
);
|
|
325
|
+
} catch {
|
|
326
|
+
onReject?.({
|
|
327
|
+
path,
|
|
328
|
+
reason: "marketplace.json is not valid JSON or is outside its root"
|
|
329
|
+
});
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
if (!object(manifest2) || !Array.isArray(manifest2.plugins)) {
|
|
333
|
+
onReject?.({ path, reason: "marketplace.json requires a plugins array" });
|
|
334
|
+
return null;
|
|
335
|
+
}
|
|
336
|
+
const name = typeof manifest2.name === "string" ? manifest2.name : "marketplace";
|
|
337
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/u.test(name)) {
|
|
338
|
+
onReject?.({ path, reason: "Invalid marketplace name" });
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
const plugins = [];
|
|
342
|
+
const seen = /* @__PURE__ */ new Set();
|
|
343
|
+
for (const item of manifest2.plugins) {
|
|
344
|
+
try {
|
|
345
|
+
if (!object(item) || typeof item.name !== "string" || !/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/u.test(item.name))
|
|
346
|
+
throw new Error("Invalid plugin name");
|
|
347
|
+
if (seen.has(item.name)) throw new Error("Duplicate plugin name");
|
|
348
|
+
const source = localSource(item.source);
|
|
349
|
+
if (!source.startsWith("./") || source.split(/[\\/]/u).includes(".."))
|
|
350
|
+
throw new Error("Local plugin source must be a contained ./ path");
|
|
351
|
+
const pluginDirectory = containedPath(directory, source);
|
|
352
|
+
if (!statSync(pluginDirectory).isDirectory())
|
|
353
|
+
throw new Error("Plugin source must be a directory");
|
|
354
|
+
const metadata2 = pluginManifest(pluginDirectory);
|
|
355
|
+
if (metadata2.name !== void 0 && metadata2.name !== item.name)
|
|
356
|
+
throw new Error("Plugin manifest name differs from marketplace entry");
|
|
357
|
+
seen.add(item.name);
|
|
358
|
+
plugins.push({
|
|
359
|
+
name: item.name,
|
|
360
|
+
directory: pluginDirectory,
|
|
361
|
+
manifest: metadata2
|
|
362
|
+
});
|
|
363
|
+
} catch (error) {
|
|
364
|
+
onReject?.({
|
|
365
|
+
path,
|
|
366
|
+
reason: error instanceof Error ? error.message : "Invalid plugin source"
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
const metadata = object(manifest2.metadata) ? manifest2.metadata : {};
|
|
371
|
+
return {
|
|
372
|
+
name,
|
|
373
|
+
plugins,
|
|
374
|
+
...typeof metadata.tier === "string" ? { tier: metadata.tier } : {}
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// src/marketplace.ts
|
|
265
379
|
function readMetadata(source) {
|
|
266
380
|
return metadataOf(frontmatterObject(source));
|
|
267
381
|
}
|
|
@@ -274,16 +388,27 @@ var asList = (value) => {
|
|
|
274
388
|
if (typeof value === "string") return [value];
|
|
275
389
|
return Array.isArray(value) ? value : [];
|
|
276
390
|
};
|
|
277
|
-
function readJson(path) {
|
|
391
|
+
function readJson(path, root) {
|
|
278
392
|
try {
|
|
279
|
-
const parsed = JSON.parse(
|
|
393
|
+
const parsed = JSON.parse(
|
|
394
|
+
readFileSync2(containedPath(root, path), "utf8")
|
|
395
|
+
);
|
|
280
396
|
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
281
397
|
} catch {
|
|
282
398
|
return null;
|
|
283
399
|
}
|
|
284
400
|
}
|
|
285
401
|
function markdownEntry(context, path, fallbackSlug, shape) {
|
|
286
|
-
|
|
402
|
+
let source;
|
|
403
|
+
try {
|
|
404
|
+
source = readFileSync2(containedPath(context.pluginDir, path), "utf8");
|
|
405
|
+
} catch {
|
|
406
|
+
context.onReject?.({
|
|
407
|
+
path,
|
|
408
|
+
reason: "Asset is unreadable or outside the plugin root"
|
|
409
|
+
});
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
287
412
|
const front = readFrontmatter(source);
|
|
288
413
|
const description = front["description"] ?? "";
|
|
289
414
|
if (description === "") {
|
|
@@ -315,25 +440,25 @@ function markdownEntry(context, path, fallbackSlug, shape) {
|
|
|
315
440
|
};
|
|
316
441
|
}
|
|
317
442
|
function skillEntries(context) {
|
|
318
|
-
const dir =
|
|
319
|
-
if (!
|
|
443
|
+
const dir = join2(context.pluginDir, "skills");
|
|
444
|
+
if (!existsSync2(dir)) return [];
|
|
320
445
|
const found = [];
|
|
321
446
|
for (const child of readdirSync(dir, { withFileTypes: true })) {
|
|
322
447
|
if (!child.isDirectory()) continue;
|
|
323
|
-
const path =
|
|
324
|
-
if (!
|
|
448
|
+
const path = join2(dir, child.name, "SKILL.md");
|
|
449
|
+
if (!existsSync2(path)) continue;
|
|
325
450
|
const entry = markdownEntry(context, path, child.name, {});
|
|
326
451
|
if (entry) found.push(entry);
|
|
327
452
|
}
|
|
328
453
|
return found;
|
|
329
454
|
}
|
|
330
455
|
function commandEntries(context) {
|
|
331
|
-
const dir =
|
|
332
|
-
if (!
|
|
456
|
+
const dir = join2(context.pluginDir, "commands");
|
|
457
|
+
if (!existsSync2(dir)) return [];
|
|
333
458
|
const found = [];
|
|
334
459
|
for (const child of readdirSync(dir, { withFileTypes: true })) {
|
|
335
460
|
if (!child.isFile() || !child.name.endsWith(".md")) continue;
|
|
336
|
-
const path =
|
|
461
|
+
const path = join2(dir, child.name);
|
|
337
462
|
const entry = markdownEntry(context, path, basename(child.name, ".md"), {
|
|
338
463
|
root: path
|
|
339
464
|
});
|
|
@@ -342,22 +467,22 @@ function commandEntries(context) {
|
|
|
342
467
|
return found;
|
|
343
468
|
}
|
|
344
469
|
function agentEntries(context) {
|
|
345
|
-
const dir =
|
|
346
|
-
if (!
|
|
470
|
+
const dir = join2(context.pluginDir, "agents");
|
|
471
|
+
if (!existsSync2(dir)) return [];
|
|
347
472
|
const found = [];
|
|
348
473
|
for (const child of readdirSync(dir, { withFileTypes: true })) {
|
|
349
474
|
let entry = null;
|
|
350
475
|
if (child.isFile() && child.name.endsWith(".md")) {
|
|
351
|
-
const path =
|
|
476
|
+
const path = join2(dir, child.name);
|
|
352
477
|
entry = markdownEntry(context, path, basename(child.name, ".md"), {
|
|
353
478
|
kind: "agent",
|
|
354
479
|
root: path,
|
|
355
480
|
namespace: "agents"
|
|
356
481
|
});
|
|
357
|
-
} else if (child.isDirectory() &&
|
|
482
|
+
} else if (child.isDirectory() && existsSync2(join2(dir, child.name, "agent.md"))) {
|
|
358
483
|
entry = markdownEntry(
|
|
359
484
|
context,
|
|
360
|
-
|
|
485
|
+
join2(dir, child.name, "agent.md"),
|
|
361
486
|
child.name,
|
|
362
487
|
{
|
|
363
488
|
kind: "agent",
|
|
@@ -371,9 +496,9 @@ function agentEntries(context) {
|
|
|
371
496
|
}
|
|
372
497
|
function hookEntries(context, manifest2) {
|
|
373
498
|
const declared = typeof manifest2.hooks === "string" ? manifest2.hooks : void 0;
|
|
374
|
-
const path =
|
|
375
|
-
if (!
|
|
376
|
-
const hooks = readJson(path);
|
|
499
|
+
const path = resolve2(context.pluginDir, declared ?? "hooks/hooks.json");
|
|
500
|
+
if (!existsSync2(path)) return [];
|
|
501
|
+
const hooks = readJson(path, context.pluginDir);
|
|
377
502
|
if (hooks === null) {
|
|
378
503
|
context.onReject?.({ path, reason: "hooks.json is not a JSON object" });
|
|
379
504
|
return [];
|
|
@@ -399,9 +524,12 @@ function hookEntries(context, manifest2) {
|
|
|
399
524
|
];
|
|
400
525
|
}
|
|
401
526
|
function mcpEntries(context) {
|
|
402
|
-
const
|
|
403
|
-
|
|
404
|
-
|
|
527
|
+
const filename = [".mcp.json", "mcp.json", "mcp_config.json"].find(
|
|
528
|
+
(name) => existsSync2(join2(context.pluginDir, name))
|
|
529
|
+
);
|
|
530
|
+
if (!filename) return [];
|
|
531
|
+
const path = join2(context.pluginDir, filename);
|
|
532
|
+
const config = readJson(path, context.pluginDir);
|
|
405
533
|
const servers = config?.["mcpServers"];
|
|
406
534
|
if (servers === null || typeof servers !== "object" || Array.isArray(servers)) {
|
|
407
535
|
context.onReject?.({ path, reason: ".mcp.json has no mcpServers object" });
|
|
@@ -420,48 +548,24 @@ function mcpEntries(context) {
|
|
|
420
548
|
}));
|
|
421
549
|
}
|
|
422
550
|
function readMarketplace(dir, onReject) {
|
|
423
|
-
const
|
|
424
|
-
if (!
|
|
425
|
-
onReject?.({
|
|
426
|
-
path: dir,
|
|
427
|
-
reason: "no .claude-plugin/marketplace.json here"
|
|
428
|
-
});
|
|
429
|
-
return [];
|
|
430
|
-
}
|
|
431
|
-
let manifest2;
|
|
432
|
-
try {
|
|
433
|
-
manifest2 = JSON.parse(
|
|
434
|
-
readFileSync(manifestPath, "utf8")
|
|
435
|
-
);
|
|
436
|
-
} catch {
|
|
437
|
-
onReject?.({
|
|
438
|
-
path: manifestPath,
|
|
439
|
-
reason: "marketplace.json is not valid JSON"
|
|
440
|
-
});
|
|
441
|
-
return [];
|
|
442
|
-
}
|
|
443
|
-
const marketplace = manifest2.name ?? "marketplace";
|
|
551
|
+
const marketplace = readLocalMarketplace(dir, onReject);
|
|
552
|
+
if (!marketplace) return [];
|
|
444
553
|
const found = [];
|
|
445
|
-
for (const plugin of
|
|
446
|
-
|
|
447
|
-
const pluginDir = resolve(dir, plugin.source);
|
|
448
|
-
if (!existsSync(pluginDir)) continue;
|
|
449
|
-
const pluginManifest = readJson(
|
|
450
|
-
join(pluginDir, ".claude-plugin", "plugin.json")
|
|
451
|
-
) ?? {};
|
|
554
|
+
for (const plugin of marketplace.plugins) {
|
|
555
|
+
const pluginManifest2 = plugin.manifest;
|
|
452
556
|
const context = {
|
|
453
|
-
marketplace,
|
|
557
|
+
marketplace: marketplace.name,
|
|
454
558
|
plugin: plugin.name,
|
|
455
|
-
pluginDir,
|
|
456
|
-
pluginDescription: typeof
|
|
457
|
-
tier:
|
|
559
|
+
pluginDir: plugin.directory,
|
|
560
|
+
pluginDescription: typeof pluginManifest2.description === "string" ? pluginManifest2.description : void 0,
|
|
561
|
+
tier: marketplace.tier,
|
|
458
562
|
onReject
|
|
459
563
|
};
|
|
460
564
|
found.push(
|
|
461
565
|
...skillEntries(context),
|
|
462
566
|
...commandEntries(context),
|
|
463
567
|
...agentEntries(context),
|
|
464
|
-
...hookEntries(context,
|
|
568
|
+
...hookEntries(context, pluginManifest2),
|
|
465
569
|
...mcpEntries(context)
|
|
466
570
|
);
|
|
467
571
|
}
|
|
@@ -503,29 +607,29 @@ function skillFiles(packageDir) {
|
|
|
503
607
|
}
|
|
504
608
|
for (const entry of entries) {
|
|
505
609
|
if (entry.isFile()) {
|
|
506
|
-
if (entry.name === "SKILL.md") found.push(
|
|
610
|
+
if (entry.name === "SKILL.md") found.push(join3(dir, entry.name));
|
|
507
611
|
continue;
|
|
508
612
|
}
|
|
509
613
|
if (!entry.isDirectory()) continue;
|
|
510
614
|
if (SKIPPED_DIRS.has(entry.name)) continue;
|
|
511
615
|
if (depth + 1 <= MAX_SKILL_DEPTH)
|
|
512
|
-
stack.push([
|
|
616
|
+
stack.push([join3(dir, entry.name), depth + 1]);
|
|
513
617
|
}
|
|
514
618
|
}
|
|
515
619
|
return found.sort();
|
|
516
620
|
}
|
|
517
621
|
function packageDirs(root) {
|
|
518
|
-
if (!
|
|
622
|
+
if (!existsSync3(root)) return [];
|
|
519
623
|
const found = [];
|
|
520
624
|
for (const entry of readdirSync2(root, { withFileTypes: true })) {
|
|
521
625
|
if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
|
|
522
626
|
if (entry.name === ".bin" || entry.name === ".cache") continue;
|
|
523
|
-
const path =
|
|
627
|
+
const path = join3(root, entry.name);
|
|
524
628
|
if (entry.name.startsWith("@")) {
|
|
525
|
-
if (!
|
|
629
|
+
if (!existsSync3(path)) continue;
|
|
526
630
|
for (const scoped of readdirSync2(path, { withFileTypes: true })) {
|
|
527
631
|
if (scoped.isDirectory() || scoped.isSymbolicLink()) {
|
|
528
|
-
found.push(
|
|
632
|
+
found.push(join3(path, scoped.name));
|
|
529
633
|
}
|
|
530
634
|
}
|
|
531
635
|
continue;
|
|
@@ -537,7 +641,7 @@ function packageDirs(root) {
|
|
|
537
641
|
function readManifest(dir) {
|
|
538
642
|
try {
|
|
539
643
|
const parsed = JSON.parse(
|
|
540
|
-
|
|
644
|
+
readFileSync3(join3(dir, "package.json"), "utf8")
|
|
541
645
|
);
|
|
542
646
|
return parsed !== null && typeof parsed === "object" ? parsed : null;
|
|
543
647
|
} catch {
|
|
@@ -571,8 +675,8 @@ function globDirs(base, pattern) {
|
|
|
571
675
|
}
|
|
572
676
|
const segment = segments[index];
|
|
573
677
|
if (!segment.includes("*")) {
|
|
574
|
-
const next =
|
|
575
|
-
if (
|
|
678
|
+
const next = join3(dir, segment);
|
|
679
|
+
if (existsSync3(next)) walk(next, index + 1);
|
|
576
680
|
return;
|
|
577
681
|
}
|
|
578
682
|
let entries;
|
|
@@ -584,12 +688,12 @@ function globDirs(base, pattern) {
|
|
|
584
688
|
const children = entries.filter((e) => e.isDirectory() || e.isSymbolicLink()).filter((e) => !SKIPPED_DIRS.has(e.name));
|
|
585
689
|
if (segment === "**") {
|
|
586
690
|
walk(dir, index + 1);
|
|
587
|
-
for (const child of children) walk(
|
|
691
|
+
for (const child of children) walk(join3(dir, child.name), index);
|
|
588
692
|
return;
|
|
589
693
|
}
|
|
590
694
|
const matcher = segmentMatcher(segment);
|
|
591
695
|
for (const child of children) {
|
|
592
|
-
if (matcher.test(child.name)) walk(
|
|
696
|
+
if (matcher.test(child.name)) walk(join3(dir, child.name), index + 1);
|
|
593
697
|
}
|
|
594
698
|
};
|
|
595
699
|
walk(base, 0);
|
|
@@ -614,7 +718,7 @@ function workspacePackageDirs(root) {
|
|
|
614
718
|
}
|
|
615
719
|
}
|
|
616
720
|
}
|
|
617
|
-
const members = [...included].filter((m) => !excluded.has(m) &&
|
|
721
|
+
const members = [...included].filter((m) => !excluded.has(m) && existsSync3(join3(m, "package.json"))).sort();
|
|
618
722
|
for (const member of members) expand(member);
|
|
619
723
|
ordered.push(dir);
|
|
620
724
|
};
|
|
@@ -631,9 +735,9 @@ function nameOf(dir, named2) {
|
|
|
631
735
|
}
|
|
632
736
|
function expandRootGlob(dir) {
|
|
633
737
|
if (!dir.includes("*")) return [dir];
|
|
634
|
-
const absolute =
|
|
738
|
+
const absolute = isAbsolute2(dir);
|
|
635
739
|
const base = absolute ? "/" : ".";
|
|
636
|
-
return globDirs(base, dir).filter((d) =>
|
|
740
|
+
return globDirs(base, dir).filter((d) => existsSync3(join3(d, "package.json"))).sort();
|
|
637
741
|
}
|
|
638
742
|
function readCatalog(options) {
|
|
639
743
|
const scopes = options.scopes ?? [];
|
|
@@ -657,7 +761,7 @@ function readCatalog(options) {
|
|
|
657
761
|
seenPaths.add(path);
|
|
658
762
|
let source;
|
|
659
763
|
try {
|
|
660
|
-
source =
|
|
764
|
+
source = readFileSync3(path, "utf8");
|
|
661
765
|
} catch {
|
|
662
766
|
continue;
|
|
663
767
|
}
|
|
@@ -701,7 +805,7 @@ function readCatalog(options) {
|
|
|
701
805
|
}
|
|
702
806
|
seen.add(entry.name);
|
|
703
807
|
if (kindOf(entry) === "skill" && basename2(entry.path) === "SKILL.md") {
|
|
704
|
-
const parsed = frontmatterObject(
|
|
808
|
+
const parsed = frontmatterObject(readFileSync3(entry.path, "utf8"));
|
|
705
809
|
for (const problem of specProblems(
|
|
706
810
|
parsed,
|
|
707
811
|
basename2(dirname2(entry.path))
|
|
@@ -721,7 +825,7 @@ function withoutBody({
|
|
|
721
825
|
return rest;
|
|
722
826
|
}
|
|
723
827
|
function displayPath(root, entry) {
|
|
724
|
-
return
|
|
828
|
+
return relative2(root, entry.path).replaceAll("\\", "/");
|
|
725
829
|
}
|
|
726
830
|
|
|
727
831
|
// src/find.ts
|
|
@@ -811,10 +915,10 @@ function rank(matches2, limit) {
|
|
|
811
915
|
}
|
|
812
916
|
|
|
813
917
|
// src/search.ts
|
|
814
|
-
import { existsSync as
|
|
918
|
+
import { existsSync as existsSync4 } from "fs";
|
|
815
919
|
|
|
816
920
|
// src/embed.ts
|
|
817
|
-
import { resolve as
|
|
921
|
+
import { resolve as resolve3 } from "path";
|
|
818
922
|
|
|
819
923
|
// src/encoder.ts
|
|
820
924
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -1000,7 +1104,7 @@ async function loadEmbedder(modelId, options = {}) {
|
|
|
1000
1104
|
const cache = options.cacheDir ?? module.env?.cacheDir;
|
|
1001
1105
|
if (typeof cache !== "string")
|
|
1002
1106
|
throw new Error("Provide modelPath or cacheDir for an offline encoder");
|
|
1003
|
-
source =
|
|
1107
|
+
source = resolve3(
|
|
1004
1108
|
cache,
|
|
1005
1109
|
selected.modelId,
|
|
1006
1110
|
selected.revision === "main" ? "." : selected.revision
|
|
@@ -1147,7 +1251,7 @@ async function prepareSearch(catalog, options) {
|
|
|
1147
1251
|
reason,
|
|
1148
1252
|
options: {}
|
|
1149
1253
|
});
|
|
1150
|
-
if (!
|
|
1254
|
+
if (!existsSync4(options.indexPath)) return lexical("index_missing");
|
|
1151
1255
|
let store;
|
|
1152
1256
|
try {
|
|
1153
1257
|
store = await openEntryVectors(options.indexPath, { readOnly: true });
|
|
@@ -1234,8 +1338,8 @@ function detectRuntime(server, ctx) {
|
|
|
1234
1338
|
}
|
|
1235
1339
|
|
|
1236
1340
|
// src/config.ts
|
|
1237
|
-
import { existsSync as
|
|
1238
|
-
import { dirname as dirname3, join as
|
|
1341
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
|
|
1342
|
+
import { dirname as dirname3, join as join4, resolve as resolve4 } from "path";
|
|
1239
1343
|
import { parse as parse2 } from "smol-toml";
|
|
1240
1344
|
var CONFIG_FILE = "pmcp.toml";
|
|
1241
1345
|
function embeddingSection(path, dir, value) {
|
|
@@ -1303,8 +1407,8 @@ function embeddingSection(path, dir, value) {
|
|
|
1303
1407
|
revision: string("revision"),
|
|
1304
1408
|
encoder,
|
|
1305
1409
|
enabled: section.enabled,
|
|
1306
|
-
modelPath: modelPath === void 0 ? void 0 :
|
|
1307
|
-
cacheDir: cacheDir === void 0 ? void 0 :
|
|
1410
|
+
modelPath: modelPath === void 0 ? void 0 : resolve4(dir, modelPath),
|
|
1411
|
+
cacheDir: cacheDir === void 0 ? void 0 : resolve4(dir, cacheDir)
|
|
1308
1412
|
};
|
|
1309
1413
|
try {
|
|
1310
1414
|
resolveEncoder(result.modelId, result);
|
|
@@ -1323,12 +1427,16 @@ var ConfigError = class extends Error {
|
|
|
1323
1427
|
}
|
|
1324
1428
|
};
|
|
1325
1429
|
var PATH_KEYS = ["roots", "workspaces", "packages", "marketplaces"];
|
|
1326
|
-
var CATALOG_KEYS = /* @__PURE__ */ new Set([
|
|
1430
|
+
var CATALOG_KEYS = /* @__PURE__ */ new Set([
|
|
1431
|
+
...PATH_KEYS,
|
|
1432
|
+
"scopes",
|
|
1433
|
+
"builtin"
|
|
1434
|
+
]);
|
|
1327
1435
|
function findConfig(start) {
|
|
1328
|
-
let dir =
|
|
1436
|
+
let dir = resolve4(start);
|
|
1329
1437
|
for (; ; ) {
|
|
1330
|
-
const candidate =
|
|
1331
|
-
if (
|
|
1438
|
+
const candidate = join4(dir, CONFIG_FILE);
|
|
1439
|
+
if (existsSync5(candidate)) return candidate;
|
|
1332
1440
|
const parent = dirname3(dir);
|
|
1333
1441
|
if (parent === dir) return null;
|
|
1334
1442
|
dir = parent;
|
|
@@ -1341,11 +1449,11 @@ function stringList(path, key, value) {
|
|
|
1341
1449
|
return value;
|
|
1342
1450
|
}
|
|
1343
1451
|
function readConfig(path) {
|
|
1344
|
-
const absolute =
|
|
1452
|
+
const absolute = resolve4(path);
|
|
1345
1453
|
const dir = dirname3(absolute);
|
|
1346
1454
|
let raw;
|
|
1347
1455
|
try {
|
|
1348
|
-
raw = parse2(
|
|
1456
|
+
raw = parse2(readFileSync4(absolute, "utf8"));
|
|
1349
1457
|
} catch (error) {
|
|
1350
1458
|
const reason = error instanceof Error ? error.message : "unreadable";
|
|
1351
1459
|
throw new ConfigError(absolute, reason.split("\n")[0] ?? reason);
|
|
@@ -1363,10 +1471,22 @@ function readConfig(path) {
|
|
|
1363
1471
|
if (!CATALOG_KEYS.has(key)) {
|
|
1364
1472
|
throw new ConfigError(absolute, `unknown key [catalog] ${key}`);
|
|
1365
1473
|
}
|
|
1474
|
+
if (key === "builtin") {
|
|
1475
|
+
if (typeof value !== "boolean")
|
|
1476
|
+
throw new ConfigError(absolute, "[catalog] builtin must be a boolean");
|
|
1477
|
+
catalog[key] = value;
|
|
1478
|
+
continue;
|
|
1479
|
+
}
|
|
1366
1480
|
const list2 = stringList(absolute, key, value);
|
|
1367
|
-
catalog[key] = key === "scopes" ? list2 : list2.map((p) =>
|
|
1481
|
+
catalog[key] = key === "scopes" ? list2 : list2.map((p) => resolve4(dir, p));
|
|
1368
1482
|
}
|
|
1369
|
-
return {
|
|
1483
|
+
return {
|
|
1484
|
+
path: absolute,
|
|
1485
|
+
dir,
|
|
1486
|
+
catalog,
|
|
1487
|
+
raw,
|
|
1488
|
+
...configured
|
|
1489
|
+
};
|
|
1370
1490
|
}
|
|
1371
1491
|
|
|
1372
1492
|
// src/project/mcp-spec.ts
|
|
@@ -1390,7 +1510,7 @@ var KEYS = /* @__PURE__ */ new Set([
|
|
|
1390
1510
|
function fail(path, where, detail) {
|
|
1391
1511
|
throw new ConfigError(path, `${where} ${detail}`);
|
|
1392
1512
|
}
|
|
1393
|
-
function
|
|
1513
|
+
function object2(path, where, value) {
|
|
1394
1514
|
if (value === void 0) {
|
|
1395
1515
|
return {};
|
|
1396
1516
|
}
|
|
@@ -1413,7 +1533,7 @@ function list(path, where, value, unique = true) {
|
|
|
1413
1533
|
}
|
|
1414
1534
|
function mapping(path, where, value) {
|
|
1415
1535
|
const result = {};
|
|
1416
|
-
for (const [key, item] of Object.entries(
|
|
1536
|
+
for (const [key, item] of Object.entries(object2(path, where, value))) {
|
|
1417
1537
|
if (typeof item !== "string") {
|
|
1418
1538
|
fail(path, where, "values must be strings");
|
|
1419
1539
|
}
|
|
@@ -1431,14 +1551,14 @@ function nativeOptions(path, where, value) {
|
|
|
1431
1551
|
};
|
|
1432
1552
|
const result = {};
|
|
1433
1553
|
for (const [tool, raw] of Object.entries(
|
|
1434
|
-
|
|
1554
|
+
object2(path, `${where} native`, value)
|
|
1435
1555
|
)) {
|
|
1436
1556
|
if (!TOOLS.includes(tool)) {
|
|
1437
1557
|
fail(path, where, `unknown native target ${tool}`);
|
|
1438
1558
|
}
|
|
1439
1559
|
const values = {};
|
|
1440
1560
|
for (const [key, item] of Object.entries(
|
|
1441
|
-
|
|
1561
|
+
object2(path, `${where} native.${tool}`, raw)
|
|
1442
1562
|
)) {
|
|
1443
1563
|
if (!fields[tool].includes(key) || typeof item !== "number" || !Number.isFinite(item) || item <= 0) {
|
|
1444
1564
|
fail(path, where, `unsupported native option ${tool}.${key}`);
|
|
@@ -1452,12 +1572,12 @@ function nativeOptions(path, where, value) {
|
|
|
1452
1572
|
function environmentSources(path, where, value) {
|
|
1453
1573
|
const result = {};
|
|
1454
1574
|
for (const [key, raw] of Object.entries(
|
|
1455
|
-
|
|
1575
|
+
object2(path, `${where} env_from`, value)
|
|
1456
1576
|
)) {
|
|
1457
1577
|
if (!ENV_NAME.test(key) || key === "PROJECT_ROOT") {
|
|
1458
1578
|
fail(path, where, "invalid environment source name");
|
|
1459
1579
|
}
|
|
1460
|
-
const source =
|
|
1580
|
+
const source = object2(path, `${where} env_from.${key}`, raw);
|
|
1461
1581
|
if (Object.keys(source).some((name) => name !== "file" && name !== "pointer")) {
|
|
1462
1582
|
fail(path, where, "environment sources accept only file and pointer");
|
|
1463
1583
|
}
|
|
@@ -1470,12 +1590,12 @@ function environmentSources(path, where, value) {
|
|
|
1470
1590
|
}
|
|
1471
1591
|
function readMcp(path, value) {
|
|
1472
1592
|
const servers = {};
|
|
1473
|
-
for (const [alias, raw] of Object.entries(
|
|
1593
|
+
for (const [alias, raw] of Object.entries(object2(path, "[mcp]", value))) {
|
|
1474
1594
|
const where = `[mcp.${alias}]`;
|
|
1475
1595
|
if (!/^[a-z0-9][a-z0-9-]*$/u.test(alias)) {
|
|
1476
1596
|
fail(path, where, "use lowercase, digits and -");
|
|
1477
1597
|
}
|
|
1478
|
-
const entry =
|
|
1598
|
+
const entry = object2(path, where, raw);
|
|
1479
1599
|
for (const key of Object.keys(entry)) {
|
|
1480
1600
|
if (!KEYS.has(key)) {
|
|
1481
1601
|
fail(path, where, `unknown field ${key}`);
|
|
@@ -1606,8 +1726,8 @@ function readMcp(path, value) {
|
|
|
1606
1726
|
// src/project/hook-adapter.ts
|
|
1607
1727
|
import { spawnSync } from "child_process";
|
|
1608
1728
|
import { createHash as createHash3 } from "crypto";
|
|
1609
|
-
import { existsSync as
|
|
1610
|
-
import { dirname as dirname4, isAbsolute as
|
|
1729
|
+
import { existsSync as existsSync6, readFileSync as readFileSync5, realpathSync as realpathSync2, statSync as statSync2 } from "fs";
|
|
1730
|
+
import { dirname as dirname4, isAbsolute as isAbsolute3, relative as relative3, resolve as resolve5 } from "path";
|
|
1611
1731
|
var denied = () => ({
|
|
1612
1732
|
decision: "deny",
|
|
1613
1733
|
reason: "Shell guard failed validation or execution"
|
|
@@ -1617,22 +1737,22 @@ function guardPath(root, command) {
|
|
|
1617
1737
|
if (!script?.startsWith(".agents/guards/")) {
|
|
1618
1738
|
throw new Error("Hook command must execute a script under .agents/guards/");
|
|
1619
1739
|
}
|
|
1620
|
-
const absolute =
|
|
1621
|
-
const base =
|
|
1622
|
-
const inside =
|
|
1623
|
-
if (
|
|
1740
|
+
const absolute = resolve5(root, script);
|
|
1741
|
+
const base = resolve5(root, ".agents/guards");
|
|
1742
|
+
const inside = relative3(base, absolute);
|
|
1743
|
+
if (isAbsolute3(inside) || inside === ".." || inside.startsWith("../") || inside.startsWith("..\\")) {
|
|
1624
1744
|
throw new Error("Hook guard must stay under .agents/guards/");
|
|
1625
1745
|
}
|
|
1626
|
-
if (!
|
|
1746
|
+
if (!existsSync6(absolute) || !statSync2(absolute).isFile()) {
|
|
1627
1747
|
throw new Error("Hook guard script must exist");
|
|
1628
1748
|
}
|
|
1629
|
-
const actual =
|
|
1630
|
-
if (
|
|
1749
|
+
const actual = relative3(base, realpathSync2(absolute));
|
|
1750
|
+
if (isAbsolute3(actual) || actual === ".." || actual.startsWith("../") || actual.startsWith("..\\")) {
|
|
1631
1751
|
throw new Error("Hook guard cannot resolve outside .agents/guards/");
|
|
1632
1752
|
}
|
|
1633
1753
|
return absolute;
|
|
1634
1754
|
}
|
|
1635
|
-
function
|
|
1755
|
+
function object3(value) {
|
|
1636
1756
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
1637
1757
|
return {};
|
|
1638
1758
|
}
|
|
@@ -1656,9 +1776,9 @@ function scalar(value) {
|
|
|
1656
1776
|
}
|
|
1657
1777
|
function evaluateShellHook(root, policy, tool, payload) {
|
|
1658
1778
|
try {
|
|
1659
|
-
const value =
|
|
1660
|
-
const call =
|
|
1661
|
-
const input = tool === "antigravity" ?
|
|
1779
|
+
const value = object3(payload);
|
|
1780
|
+
const call = object3(value["toolCall"]);
|
|
1781
|
+
const input = tool === "antigravity" ? object3(call["args"]) : object3(value["tool_input"]);
|
|
1662
1782
|
const name = tool === "antigravity" ? call["name"] : value["tool_name"];
|
|
1663
1783
|
const shellNames = {
|
|
1664
1784
|
codex: ["Bash", "exec_command", "shell", "shell_command"],
|
|
@@ -1706,7 +1826,7 @@ function evaluateShellHook(root, policy, tool, payload) {
|
|
|
1706
1826
|
if (result.status !== 0 || result.error) {
|
|
1707
1827
|
return denied();
|
|
1708
1828
|
}
|
|
1709
|
-
const response =
|
|
1829
|
+
const response = object3(JSON.parse(result.stdout));
|
|
1710
1830
|
if (Object.keys(response).some(
|
|
1711
1831
|
(key) => !["decision", "reason"].includes(key)
|
|
1712
1832
|
) || !["allow", "deny"].includes(String(response["decision"])) || response["reason"] !== void 0 && typeof response["reason"] !== "string") {
|
|
@@ -1744,8 +1864,8 @@ async function main() {
|
|
|
1744
1864
|
if (!file) {
|
|
1745
1865
|
throw new Error("Missing hook policy");
|
|
1746
1866
|
}
|
|
1747
|
-
const bytes =
|
|
1748
|
-
const adapter =
|
|
1867
|
+
const bytes = readFileSync5(file);
|
|
1868
|
+
const adapter = readFileSync5(process.argv[1]);
|
|
1749
1869
|
const actual = createHash3("sha256").update(adapter).update(bytes).digest("hex");
|
|
1750
1870
|
if (actual !== integrity) {
|
|
1751
1871
|
throw new Error("Hook integrity mismatch");
|
|
@@ -1764,8 +1884,8 @@ async function main() {
|
|
|
1764
1884
|
}
|
|
1765
1885
|
chunks.push(bytes2);
|
|
1766
1886
|
}
|
|
1767
|
-
const root =
|
|
1768
|
-
const guardSha256 = createHash3("sha256").update(
|
|
1887
|
+
const root = resolve5(dirname4(file), "../..");
|
|
1888
|
+
const guardSha256 = createHash3("sha256").update(readFileSync5(guardPath(root, policy.command))).digest("hex");
|
|
1769
1889
|
if (policy.contractVersion !== 1 || guardSha256 !== policy.guardSha256) {
|
|
1770
1890
|
throw new Error(
|
|
1771
1891
|
"Hook guard source changed; reproject and review native trust"
|
|
@@ -1958,8 +2078,8 @@ function readSpec(config) {
|
|
|
1958
2078
|
}
|
|
1959
2079
|
|
|
1960
2080
|
// src/project/plan.ts
|
|
1961
|
-
import { existsSync as
|
|
1962
|
-
import { join as
|
|
2081
|
+
import { existsSync as existsSync9, readFileSync as readFileSync7, readdirSync as readdirSync4 } from "fs";
|
|
2082
|
+
import { join as join7 } from "path";
|
|
1963
2083
|
|
|
1964
2084
|
// src/project/frontmatter.ts
|
|
1965
2085
|
import { parse as parse3 } from "yaml";
|
|
@@ -1967,8 +2087,8 @@ function splitFrontmatter(source) {
|
|
|
1967
2087
|
const match = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/u.exec(source);
|
|
1968
2088
|
if (!match) return { meta: {}, body: source };
|
|
1969
2089
|
const meta = parse3(match[1] ?? "");
|
|
1970
|
-
const
|
|
1971
|
-
return { meta:
|
|
2090
|
+
const object5 = meta !== null && typeof meta === "object" && !Array.isArray(meta) ? meta : {};
|
|
2091
|
+
return { meta: object5, body: match[2] ?? "" };
|
|
1972
2092
|
}
|
|
1973
2093
|
function scalar2(value) {
|
|
1974
2094
|
if (typeof value === "string") return value;
|
|
@@ -2011,8 +2131,8 @@ function splitKeyed(path) {
|
|
|
2011
2131
|
|
|
2012
2132
|
// src/project/package-rules.ts
|
|
2013
2133
|
import { execFileSync } from "child_process";
|
|
2014
|
-
import { existsSync as
|
|
2015
|
-
import { dirname as dirname5, join as
|
|
2134
|
+
import { existsSync as existsSync7, lstatSync, readdirSync as readdirSync3, readlinkSync } from "fs";
|
|
2135
|
+
import { dirname as dirname5, join as join5, posix } from "path";
|
|
2016
2136
|
var ProjectError = class extends Error {
|
|
2017
2137
|
constructor(message) {
|
|
2018
2138
|
super(message);
|
|
@@ -2057,11 +2177,11 @@ function linkTarget(abs) {
|
|
|
2057
2177
|
}
|
|
2058
2178
|
function legacyLinks(root) {
|
|
2059
2179
|
const found = /* @__PURE__ */ new Map();
|
|
2060
|
-
const dir =
|
|
2061
|
-
if (!
|
|
2180
|
+
const dir = join5(root, RULES_DIR);
|
|
2181
|
+
if (!existsSync7(dir)) return found;
|
|
2062
2182
|
for (const entry of readdirSync3(dir).sort()) {
|
|
2063
2183
|
if (!entry.endsWith(".md")) continue;
|
|
2064
|
-
const target = linkTarget(
|
|
2184
|
+
const target = linkTarget(join5(dir, entry));
|
|
2065
2185
|
if (target === null || !target.startsWith("../../")) continue;
|
|
2066
2186
|
found.set(entry.slice(0, -3), target.slice("../../".length));
|
|
2067
2187
|
}
|
|
@@ -2106,7 +2226,7 @@ function packageRuleOutputs(root, spec, owned) {
|
|
|
2106
2226
|
}
|
|
2107
2227
|
|
|
2108
2228
|
// src/project/mcp.ts
|
|
2109
|
-
import { isAbsolute as
|
|
2229
|
+
import { isAbsolute as isAbsolute4, relative as relative4 } from "path";
|
|
2110
2230
|
var runtimeByTool = {
|
|
2111
2231
|
claude: "claude-code",
|
|
2112
2232
|
codex: "codex-cli",
|
|
@@ -2257,12 +2377,12 @@ function nativeEntry(spec, alias, server, tool) {
|
|
|
2257
2377
|
}
|
|
2258
2378
|
let started;
|
|
2259
2379
|
if (Object.keys(server.envFrom ?? {}).length > 0) {
|
|
2260
|
-
const entry =
|
|
2380
|
+
const entry = relative4(spec.root, process.argv[1] ?? "");
|
|
2261
2381
|
const driverEnv = {};
|
|
2262
2382
|
if (server.mailbox) {
|
|
2263
2383
|
driverEnv["PMCP_MAILBOX_RUNTIME"] = runtimeByTool[tool];
|
|
2264
2384
|
}
|
|
2265
|
-
if (!
|
|
2385
|
+
if (!isAbsolute4(entry) && !entry.startsWith("..")) {
|
|
2266
2386
|
started = launch({
|
|
2267
2387
|
command: "node",
|
|
2268
2388
|
args: [`${ROOT_VAR}/${entry}`, "project", "exec-mcp", alias],
|
|
@@ -2371,8 +2491,8 @@ function mcpOutputs(spec) {
|
|
|
2371
2491
|
|
|
2372
2492
|
// src/project/hooks.ts
|
|
2373
2493
|
import { createHash as createHash4 } from "crypto";
|
|
2374
|
-
import { existsSync as
|
|
2375
|
-
import { join as
|
|
2494
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
|
|
2495
|
+
import { join as join6 } from "path";
|
|
2376
2496
|
import { fileURLToPath } from "url";
|
|
2377
2497
|
var HOOK_DIRECTORY = ".agents/pmcp-hooks";
|
|
2378
2498
|
var ADAPTER = `${HOOK_DIRECTORY}/adapter.mjs`;
|
|
@@ -2393,7 +2513,7 @@ var native = {
|
|
|
2393
2513
|
matcher: "run_command"
|
|
2394
2514
|
}
|
|
2395
2515
|
};
|
|
2396
|
-
function
|
|
2516
|
+
function object4(value) {
|
|
2397
2517
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
2398
2518
|
throw new ProjectError(
|
|
2399
2519
|
"Native hook configuration must be an object; contents are redacted"
|
|
@@ -2402,20 +2522,20 @@ function object3(value) {
|
|
|
2402
2522
|
return value;
|
|
2403
2523
|
}
|
|
2404
2524
|
function groups(root, file, key) {
|
|
2405
|
-
const absolute =
|
|
2406
|
-
if (!
|
|
2525
|
+
const absolute = join6(root, file);
|
|
2526
|
+
if (!existsSync8(absolute)) {
|
|
2407
2527
|
return [];
|
|
2408
2528
|
}
|
|
2409
2529
|
let value;
|
|
2410
2530
|
try {
|
|
2411
|
-
value = JSON.parse(
|
|
2531
|
+
value = JSON.parse(readFileSync6(absolute, "utf8"));
|
|
2412
2532
|
} catch {
|
|
2413
2533
|
throw new ProjectError(
|
|
2414
2534
|
"Cannot parse native hook configuration; contents are redacted"
|
|
2415
2535
|
);
|
|
2416
2536
|
}
|
|
2417
2537
|
for (const part of key) {
|
|
2418
|
-
value =
|
|
2538
|
+
value = object4(value)[part];
|
|
2419
2539
|
if (value === void 0) {
|
|
2420
2540
|
return [];
|
|
2421
2541
|
}
|
|
@@ -2432,15 +2552,15 @@ function adapterSource() {
|
|
|
2432
2552
|
const sourceBuild = fileURLToPath(
|
|
2433
2553
|
new URL("../../dist/project/hook-adapter.js", import.meta.url)
|
|
2434
2554
|
);
|
|
2435
|
-
const file =
|
|
2436
|
-
if (!
|
|
2555
|
+
const file = existsSync8(published) ? published : sourceBuild;
|
|
2556
|
+
if (!existsSync8(file)) {
|
|
2437
2557
|
throw new ProjectError("Build pmcp before projecting shell hook adapters");
|
|
2438
2558
|
}
|
|
2439
|
-
return
|
|
2559
|
+
return readFileSync6(file, "utf8");
|
|
2440
2560
|
}
|
|
2441
2561
|
function hookOutputs(spec) {
|
|
2442
|
-
const lockFile =
|
|
2443
|
-
const lock =
|
|
2562
|
+
const lockFile = join6(spec.root, "pmcp.lock");
|
|
2563
|
+
const lock = existsSync8(lockFile) ? JSON.parse(readFileSync6(lockFile, "utf8")) : {};
|
|
2444
2564
|
const previous = new Map(
|
|
2445
2565
|
(lock.outputs ?? []).filter((entry) => entry.managed !== void 0).map((entry) => [entry.path, entry.managed])
|
|
2446
2566
|
);
|
|
@@ -2457,7 +2577,7 @@ function hookOutputs(spec) {
|
|
|
2457
2577
|
outputs.push({ kind: "file", path: ADAPTER, content: adapter });
|
|
2458
2578
|
for (const hook of selected) {
|
|
2459
2579
|
const policyFile = `${HOOK_DIRECTORY}/${hook.name}.json`;
|
|
2460
|
-
const guardSha256 = createHash4("sha256").update(
|
|
2580
|
+
const guardSha256 = createHash4("sha256").update(readFileSync6(guardPath(spec.root, hook.command))).digest("hex");
|
|
2461
2581
|
const policy = `${JSON.stringify({ ...hook, contractVersion: 1, guardSha256 }, null, 2)}
|
|
2462
2582
|
`;
|
|
2463
2583
|
outputs.push({ kind: "file", path: policyFile, content: policy });
|
|
@@ -2527,20 +2647,20 @@ var AGENT_FIELDS = {
|
|
|
2527
2647
|
};
|
|
2528
2648
|
var SETTINGS = ".claude/settings.json";
|
|
2529
2649
|
function listDirs(dir) {
|
|
2530
|
-
if (!
|
|
2650
|
+
if (!existsSync9(dir)) return [];
|
|
2531
2651
|
return readdirSync4(dir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name).sort();
|
|
2532
2652
|
}
|
|
2533
2653
|
var tomlString = (value) => JSON.stringify(typeof value === "string" ? value : String(value ?? ""));
|
|
2534
2654
|
function skillNames(root) {
|
|
2535
|
-
const dir =
|
|
2655
|
+
const dir = join7(root, ".agents/skills");
|
|
2536
2656
|
return listDirs(dir).filter(
|
|
2537
|
-
(name) =>
|
|
2657
|
+
(name) => existsSync9(join7(dir, name, "SKILL.md"))
|
|
2538
2658
|
);
|
|
2539
2659
|
}
|
|
2540
2660
|
function agentNames(root) {
|
|
2541
|
-
const dir =
|
|
2661
|
+
const dir = join7(root, ".agents/agents");
|
|
2542
2662
|
return listDirs(dir).filter(
|
|
2543
|
-
(name) =>
|
|
2663
|
+
(name) => existsSync9(join7(dir, name, "agent.md"))
|
|
2544
2664
|
);
|
|
2545
2665
|
}
|
|
2546
2666
|
function skillOutputs(spec) {
|
|
@@ -2574,13 +2694,13 @@ policy:
|
|
|
2574
2694
|
}
|
|
2575
2695
|
function ruleOutputs(spec) {
|
|
2576
2696
|
if (!spec.tools.has("claude")) return [];
|
|
2577
|
-
const dir =
|
|
2578
|
-
if (!
|
|
2697
|
+
const dir = join7(spec.root, ".agents/rules");
|
|
2698
|
+
if (!existsSync9(dir)) return [];
|
|
2579
2699
|
const outputs = [];
|
|
2580
2700
|
for (const file of readdirSync4(dir).filter((f) => f.endsWith(".md")).sort()) {
|
|
2581
2701
|
const rel = `.agents/rules/${file}`;
|
|
2582
2702
|
const { meta, body } = splitFrontmatter(
|
|
2583
|
-
|
|
2703
|
+
readFileSync7(join7(spec.root, rel), "utf8")
|
|
2584
2704
|
);
|
|
2585
2705
|
const globs = [meta["globs"] ?? []].flat().filter((g) => typeof g === "string" && g !== "");
|
|
2586
2706
|
const head = globs.length > 0 ? renderFrontmatter({ paths: globs }) : "";
|
|
@@ -2599,7 +2719,7 @@ function agentOutputs(spec) {
|
|
|
2599
2719
|
for (const name of agentNames(spec.root)) {
|
|
2600
2720
|
const rel = `.agents/agents/${name}/agent.md`;
|
|
2601
2721
|
const { meta, body } = splitFrontmatter(
|
|
2602
|
-
|
|
2722
|
+
readFileSync7(join7(spec.root, rel), "utf8")
|
|
2603
2723
|
);
|
|
2604
2724
|
const overrides = spec.agents[name] ?? {};
|
|
2605
2725
|
const note = `<!-- ${MARK} from ${rel} -->
|
|
@@ -2671,35 +2791,35 @@ function censusDirs(spec) {
|
|
|
2671
2791
|
// src/project/apply.ts
|
|
2672
2792
|
import { createHash as createHash6 } from "crypto";
|
|
2673
2793
|
import {
|
|
2674
|
-
existsSync as
|
|
2794
|
+
existsSync as existsSync11,
|
|
2675
2795
|
lstatSync as lstatSync3,
|
|
2676
2796
|
mkdirSync as mkdirSync2,
|
|
2677
|
-
readFileSync as
|
|
2797
|
+
readFileSync as readFileSync9,
|
|
2678
2798
|
readdirSync as readdirSync5,
|
|
2679
2799
|
readlinkSync as readlinkSync2,
|
|
2680
2800
|
rmSync,
|
|
2681
2801
|
symlinkSync,
|
|
2682
2802
|
writeFileSync as writeFileSync2
|
|
2683
2803
|
} from "fs";
|
|
2684
|
-
import { dirname as dirname7, join as
|
|
2804
|
+
import { dirname as dirname7, join as join9, posix as posix2 } from "path";
|
|
2685
2805
|
import { parse as parse4 } from "smol-toml";
|
|
2686
2806
|
|
|
2687
2807
|
// src/project/backup.ts
|
|
2688
2808
|
import { createHash as createHash5 } from "crypto";
|
|
2689
2809
|
import {
|
|
2690
|
-
existsSync as
|
|
2810
|
+
existsSync as existsSync10,
|
|
2691
2811
|
lstatSync as lstatSync2,
|
|
2692
2812
|
mkdirSync,
|
|
2693
2813
|
mkdtempSync,
|
|
2694
|
-
readFileSync as
|
|
2814
|
+
readFileSync as readFileSync8,
|
|
2695
2815
|
writeFileSync
|
|
2696
2816
|
} from "fs";
|
|
2697
2817
|
import { homedir } from "os";
|
|
2698
|
-
import { dirname as dirname6, isAbsolute as
|
|
2818
|
+
import { dirname as dirname6, isAbsolute as isAbsolute5, join as join8, relative as relative5, resolve as resolve6 } from "path";
|
|
2699
2819
|
function backupFiles(root, paths) {
|
|
2700
|
-
const base =
|
|
2701
|
-
const inside =
|
|
2702
|
-
if (!
|
|
2820
|
+
const base = join8(homedir(), ".cache/pmcp/project-backups");
|
|
2821
|
+
const inside = relative5(resolve6(root), resolve6(base));
|
|
2822
|
+
if (!isAbsolute5(inside) && inside !== ".." && !inside.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`)) {
|
|
2703
2823
|
throw new ProjectError("Project backups must be outside the project");
|
|
2704
2824
|
}
|
|
2705
2825
|
mkdirSync(base, { recursive: true, mode: 448 });
|
|
@@ -2713,12 +2833,12 @@ function backupFiles(root, paths) {
|
|
|
2713
2833
|
);
|
|
2714
2834
|
}
|
|
2715
2835
|
const snapshots = [...new Set(paths)].map((path) => {
|
|
2716
|
-
const absolute =
|
|
2717
|
-
const within =
|
|
2718
|
-
if (
|
|
2836
|
+
const absolute = resolve6(root, path);
|
|
2837
|
+
const within = relative5(resolve6(root), absolute);
|
|
2838
|
+
if (isAbsolute5(within) || within === ".." || within.startsWith("../") || within.startsWith("..\\")) {
|
|
2719
2839
|
throw new ProjectError("Backup paths must stay inside the project");
|
|
2720
2840
|
}
|
|
2721
|
-
if (!
|
|
2841
|
+
if (!existsSync10(absolute)) {
|
|
2722
2842
|
return { path, contents: null };
|
|
2723
2843
|
}
|
|
2724
2844
|
const stat = lstatSync2(absolute);
|
|
@@ -2727,14 +2847,14 @@ function backupFiles(root, paths) {
|
|
|
2727
2847
|
`Refusing to back up a nonregular config file: ${path}`
|
|
2728
2848
|
);
|
|
2729
2849
|
}
|
|
2730
|
-
return { path, contents:
|
|
2850
|
+
return { path, contents: readFileSync8(absolute) };
|
|
2731
2851
|
});
|
|
2732
|
-
const destination = mkdtempSync(
|
|
2852
|
+
const destination = mkdtempSync(join8(base, "project-"));
|
|
2733
2853
|
const entries = snapshots.map(({ path, contents }) => {
|
|
2734
2854
|
if (contents === null) {
|
|
2735
2855
|
return { path, present: false };
|
|
2736
2856
|
}
|
|
2737
|
-
const output =
|
|
2857
|
+
const output = join8(destination, "files", path);
|
|
2738
2858
|
mkdirSync(dirname6(output), { recursive: true, mode: 448 });
|
|
2739
2859
|
writeFileSync(output, contents, { mode: 384 });
|
|
2740
2860
|
return {
|
|
@@ -2744,11 +2864,11 @@ function backupFiles(root, paths) {
|
|
|
2744
2864
|
};
|
|
2745
2865
|
});
|
|
2746
2866
|
writeFileSync(
|
|
2747
|
-
|
|
2867
|
+
join8(destination, "receipt.json"),
|
|
2748
2868
|
JSON.stringify(
|
|
2749
2869
|
{
|
|
2750
2870
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2751
|
-
projectRoot:
|
|
2871
|
+
projectRoot: resolve6(root),
|
|
2752
2872
|
entries
|
|
2753
2873
|
},
|
|
2754
2874
|
null,
|
|
@@ -2769,9 +2889,9 @@ var PREDECESSORS = [
|
|
|
2769
2889
|
];
|
|
2770
2890
|
var sha = (text) => createHash6("sha256").update(text).digest("hex");
|
|
2771
2891
|
function readLock(root) {
|
|
2772
|
-
const path =
|
|
2773
|
-
if (!
|
|
2774
|
-
const lock = JSON.parse(
|
|
2892
|
+
const path = join9(root, LOCK_FILE);
|
|
2893
|
+
if (!existsSync11(path)) return [];
|
|
2894
|
+
const lock = JSON.parse(readFileSync9(path, "utf8"));
|
|
2775
2895
|
return lock.outputs ?? [];
|
|
2776
2896
|
}
|
|
2777
2897
|
function linkOf(abs) {
|
|
@@ -2781,12 +2901,12 @@ function linkOf(abs) {
|
|
|
2781
2901
|
return null;
|
|
2782
2902
|
}
|
|
2783
2903
|
}
|
|
2784
|
-
var exists = (abs) =>
|
|
2904
|
+
var exists = (abs) => existsSync11(abs) || linkOf(abs) !== null;
|
|
2785
2905
|
function readJson2(abs) {
|
|
2786
|
-
if (!
|
|
2906
|
+
if (!existsSync11(abs)) return {};
|
|
2787
2907
|
let value;
|
|
2788
2908
|
try {
|
|
2789
|
-
value = JSON.parse(
|
|
2909
|
+
value = JSON.parse(readFileSync9(abs, "utf8"));
|
|
2790
2910
|
} catch {
|
|
2791
2911
|
throw new ProjectError(
|
|
2792
2912
|
"Cannot parse native JSON configuration; contents are redacted"
|
|
@@ -2794,16 +2914,16 @@ function readJson2(abs) {
|
|
|
2794
2914
|
}
|
|
2795
2915
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
2796
2916
|
}
|
|
2797
|
-
function getKey(
|
|
2798
|
-
let node =
|
|
2917
|
+
function getKey(object5, key) {
|
|
2918
|
+
let node = object5;
|
|
2799
2919
|
for (const part of key) {
|
|
2800
2920
|
if (node === null || typeof node !== "object") return void 0;
|
|
2801
2921
|
node = node[part];
|
|
2802
2922
|
}
|
|
2803
2923
|
return node;
|
|
2804
2924
|
}
|
|
2805
|
-
function setKey(
|
|
2806
|
-
let node =
|
|
2925
|
+
function setKey(object5, key, value) {
|
|
2926
|
+
let node = object5;
|
|
2807
2927
|
for (const part of key.slice(0, -1)) {
|
|
2808
2928
|
const next = node[part];
|
|
2809
2929
|
if (next === null || typeof next !== "object" || Array.isArray(next)) {
|
|
@@ -2813,17 +2933,17 @@ function setKey(object4, key, value) {
|
|
|
2813
2933
|
}
|
|
2814
2934
|
node[key[key.length - 1] ?? ""] = value;
|
|
2815
2935
|
}
|
|
2816
|
-
function deleteKey(
|
|
2936
|
+
function deleteKey(object5, key) {
|
|
2817
2937
|
const [head, ...rest] = key;
|
|
2818
|
-
if (head === void 0 || !(head in
|
|
2938
|
+
if (head === void 0 || !(head in object5)) return;
|
|
2819
2939
|
if (rest.length === 0) {
|
|
2820
|
-
delete
|
|
2940
|
+
delete object5[head];
|
|
2821
2941
|
return;
|
|
2822
2942
|
}
|
|
2823
|
-
const child =
|
|
2943
|
+
const child = object5[head];
|
|
2824
2944
|
if (child === null || typeof child !== "object") return;
|
|
2825
2945
|
deleteKey(child, rest);
|
|
2826
|
-
if (Object.keys(child).length === 0) delete
|
|
2946
|
+
if (Object.keys(child).length === 0) delete object5[head];
|
|
2827
2947
|
}
|
|
2828
2948
|
var same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
2829
2949
|
var block = (content) => `${BEGIN}
|
|
@@ -2838,19 +2958,19 @@ function withoutBlock(text) {
|
|
|
2838
2958
|
return `${text.slice(0, start).replace(/\n+$/u, "\n")}${after}`;
|
|
2839
2959
|
}
|
|
2840
2960
|
function present(root, output) {
|
|
2841
|
-
const abs =
|
|
2961
|
+
const abs = join9(root, "file" in output ? output.file : output.path);
|
|
2842
2962
|
switch (output.kind) {
|
|
2843
2963
|
case "link":
|
|
2844
2964
|
return linkOf(abs) === output.target;
|
|
2845
2965
|
case "file":
|
|
2846
|
-
return
|
|
2966
|
+
return existsSync11(abs) && linkOf(abs) === null && readFileSync9(abs, "utf8") === output.content;
|
|
2847
2967
|
case "json":
|
|
2848
2968
|
if (output.managed && Array.isArray(output.value) && output.value.length === 0) {
|
|
2849
2969
|
return getKey(readJson2(abs), output.key) === void 0;
|
|
2850
2970
|
}
|
|
2851
2971
|
return same(getKey(readJson2(abs), output.key), output.value);
|
|
2852
2972
|
case "block":
|
|
2853
|
-
return
|
|
2973
|
+
return existsSync11(abs) && readFileSync9(abs, "utf8").includes(block(output.content));
|
|
2854
2974
|
}
|
|
2855
2975
|
}
|
|
2856
2976
|
function replaceable(root, output, owned) {
|
|
@@ -2858,12 +2978,12 @@ function replaceable(root, output, owned) {
|
|
|
2858
2978
|
if (output.key[0] !== "mcpServers" || owned.has(output.path)) {
|
|
2859
2979
|
return true;
|
|
2860
2980
|
}
|
|
2861
|
-
const existing = getKey(readJson2(
|
|
2981
|
+
const existing = getKey(readJson2(join9(root, output.file)), output.key);
|
|
2862
2982
|
return existing === void 0 || same(existing, output.value);
|
|
2863
2983
|
}
|
|
2864
2984
|
if (output.kind === "block") {
|
|
2865
|
-
const absolute =
|
|
2866
|
-
const text2 =
|
|
2985
|
+
const absolute = join9(root, output.file);
|
|
2986
|
+
const text2 = existsSync11(absolute) ? readFileSync9(absolute, "utf8") : "";
|
|
2867
2987
|
const outside = parse4(withoutBlock(text2));
|
|
2868
2988
|
const proposed = parse4(output.content);
|
|
2869
2989
|
const existing = objectKeys(outside["mcp_servers"]);
|
|
@@ -2872,14 +2992,14 @@ function replaceable(root, output, owned) {
|
|
|
2872
2992
|
);
|
|
2873
2993
|
}
|
|
2874
2994
|
if (owned.has(output.path)) return true;
|
|
2875
|
-
const abs =
|
|
2995
|
+
const abs = join9(root, output.path);
|
|
2876
2996
|
if (!exists(abs)) return true;
|
|
2877
2997
|
const target = linkOf(abs);
|
|
2878
2998
|
if (target !== null) {
|
|
2879
2999
|
return output.kind === "link" && target === output.target;
|
|
2880
3000
|
}
|
|
2881
3001
|
if (lstatSync3(abs).isDirectory()) return false;
|
|
2882
|
-
const text =
|
|
3002
|
+
const text = readFileSync9(abs, "utf8");
|
|
2883
3003
|
if (output.kind === "file" && text === output.content) return true;
|
|
2884
3004
|
return PREDECESSORS.some((mark) => text.includes(mark));
|
|
2885
3005
|
}
|
|
@@ -2893,15 +3013,15 @@ function undeclared(spec, outputs) {
|
|
|
2893
3013
|
const declared = new Set(outputs.map((o) => o.path));
|
|
2894
3014
|
const found = [];
|
|
2895
3015
|
for (const dir of censusDirs(spec)) {
|
|
2896
|
-
const abs =
|
|
2897
|
-
if (!
|
|
3016
|
+
const abs = join9(spec.root, dir);
|
|
3017
|
+
if (!existsSync11(abs)) continue;
|
|
2898
3018
|
for (const entry of readdirSync5(abs)) {
|
|
2899
3019
|
const path = `${dir}/${entry}`;
|
|
2900
3020
|
if (!declared.has(path)) found.push(path);
|
|
2901
3021
|
}
|
|
2902
3022
|
}
|
|
2903
|
-
const rules =
|
|
2904
|
-
if (spec.tools.has("grok") &&
|
|
3023
|
+
const rules = join9(spec.root, RULES_DIR);
|
|
3024
|
+
if (spec.tools.has("grok") && existsSync11(rules)) {
|
|
2905
3025
|
for (const entry of readdirSync5(rules, { withFileTypes: true })) {
|
|
2906
3026
|
if (entry.isDirectory()) continue;
|
|
2907
3027
|
found.push(`${RULES_DIR}/${entry.name}`);
|
|
@@ -2928,9 +3048,9 @@ function deadGlobs(root, outputs) {
|
|
|
2928
3048
|
if (rule.kind === "file") {
|
|
2929
3049
|
text = rule.content;
|
|
2930
3050
|
} else if (rule.kind === "link") {
|
|
2931
|
-
const abs =
|
|
2932
|
-
if (!
|
|
2933
|
-
text =
|
|
3051
|
+
const abs = join9(root, posix2.join(posix2.dirname(rule.path), rule.target));
|
|
3052
|
+
if (!existsSync11(abs)) continue;
|
|
3053
|
+
text = readFileSync9(abs, "utf8");
|
|
2934
3054
|
} else {
|
|
2935
3055
|
continue;
|
|
2936
3056
|
}
|
|
@@ -2980,7 +3100,7 @@ function project(spec, options) {
|
|
|
2980
3100
|
}
|
|
2981
3101
|
}
|
|
2982
3102
|
for (const path of jsonPaths) {
|
|
2983
|
-
readJson2(
|
|
3103
|
+
readJson2(join9(spec.root, path));
|
|
2984
3104
|
}
|
|
2985
3105
|
if (options.check) {
|
|
2986
3106
|
const problems = [
|
|
@@ -3042,7 +3162,7 @@ function project(spec, options) {
|
|
|
3042
3162
|
for (const output of outputs) {
|
|
3043
3163
|
if (output.kind !== "link" && output.kind !== "file") continue;
|
|
3044
3164
|
if (present(spec.root, output)) continue;
|
|
3045
|
-
const abs =
|
|
3165
|
+
const abs = join9(spec.root, output.path);
|
|
3046
3166
|
mkdirSync2(dirname7(abs), { recursive: true });
|
|
3047
3167
|
rmSync(abs, { force: true, recursive: true });
|
|
3048
3168
|
if (output.kind === "link") symlinkSync(output.target, abs);
|
|
@@ -3068,12 +3188,12 @@ function project(spec, options) {
|
|
|
3068
3188
|
group.drops.push(keyed.key);
|
|
3069
3189
|
jsonFiles.set(keyed.file, group);
|
|
3070
3190
|
} else {
|
|
3071
|
-
rmSync(
|
|
3191
|
+
rmSync(join9(spec.root, entry.path), { force: true, recursive: true });
|
|
3072
3192
|
}
|
|
3073
3193
|
pruned += 1;
|
|
3074
3194
|
}
|
|
3075
3195
|
for (const [file, { sets, drops }] of jsonFiles) {
|
|
3076
|
-
const abs =
|
|
3196
|
+
const abs = join9(spec.root, file);
|
|
3077
3197
|
const before = readJson2(abs);
|
|
3078
3198
|
const after = structuredClone(before);
|
|
3079
3199
|
for (const key of drops) deleteKey(after, key);
|
|
@@ -3088,18 +3208,18 @@ function project(spec, options) {
|
|
|
3088
3208
|
}
|
|
3089
3209
|
}
|
|
3090
3210
|
if (same(before, after)) continue;
|
|
3091
|
-
if (!
|
|
3211
|
+
if (!existsSync11(abs) && Object.keys(after).length === 0) continue;
|
|
3092
3212
|
mkdirSync2(dirname7(abs), { recursive: true });
|
|
3093
3213
|
writeFileSync2(abs, `${JSON.stringify(after, null, 2)}
|
|
3094
3214
|
`);
|
|
3095
3215
|
}
|
|
3096
3216
|
for (const [file, content] of blockFiles) {
|
|
3097
|
-
const abs =
|
|
3098
|
-
const before =
|
|
3217
|
+
const abs = join9(spec.root, file);
|
|
3218
|
+
const before = existsSync11(abs) ? readFileSync9(abs, "utf8") : "";
|
|
3099
3219
|
let after = withoutBlock(before);
|
|
3100
3220
|
if (content !== null) {
|
|
3101
|
-
const
|
|
3102
|
-
after = `${after}${
|
|
3221
|
+
const sep5 = after === "" || after.endsWith("\n\n") ? "" : after.endsWith("\n") ? "\n" : "\n\n";
|
|
3222
|
+
after = `${after}${sep5}${block(content)}`;
|
|
3103
3223
|
}
|
|
3104
3224
|
if (after === before) continue;
|
|
3105
3225
|
mkdirSync2(dirname7(abs), { recursive: true });
|
|
@@ -3114,15 +3234,15 @@ function project(spec, options) {
|
|
|
3114
3234
|
)
|
|
3115
3235
|
);
|
|
3116
3236
|
for (const [name, target] of legacyLinks(spec.root)) {
|
|
3117
|
-
const abs =
|
|
3118
|
-
const broken = !
|
|
3237
|
+
const abs = join9(spec.root, RULES_DIR, `${name}.md`);
|
|
3238
|
+
const broken = !existsSync11(abs);
|
|
3119
3239
|
if (!broken && !linkedDirs.has(posix2.dirname(target))) continue;
|
|
3120
3240
|
rmSync(abs, { force: true });
|
|
3121
3241
|
pruned += 1;
|
|
3122
3242
|
}
|
|
3123
3243
|
}
|
|
3124
3244
|
writeFileSync2(
|
|
3125
|
-
|
|
3245
|
+
join9(spec.root, LOCK_FILE),
|
|
3126
3246
|
`${JSON.stringify({ version: 1, outputs: outputs.filter((output) => output.kind !== "json" || output.managed === void 0 || output.managed.length > 0).map(lockEntry) }, null, 2)}
|
|
3127
3247
|
`
|
|
3128
3248
|
);
|
|
@@ -3137,8 +3257,8 @@ function project(spec, options) {
|
|
|
3137
3257
|
|
|
3138
3258
|
// src/project/doctor.ts
|
|
3139
3259
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
3140
|
-
import { existsSync as
|
|
3141
|
-
import { join as
|
|
3260
|
+
import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
|
|
3261
|
+
import { join as join10 } from "path";
|
|
3142
3262
|
import { parse as parse5 } from "smol-toml";
|
|
3143
3263
|
var missingFrom = (names, present2) => names.filter((name) => !present2(name));
|
|
3144
3264
|
function verdict(tool, check, missing) {
|
|
@@ -3200,10 +3320,10 @@ function claude(spec, o) {
|
|
|
3200
3320
|
}
|
|
3201
3321
|
function codex(spec, o) {
|
|
3202
3322
|
const findings = [];
|
|
3203
|
-
const config =
|
|
3323
|
+
const config = join10(o.home, ".codex/config.toml");
|
|
3204
3324
|
let trusted = false;
|
|
3205
|
-
if (
|
|
3206
|
-
const projects = parse5(
|
|
3325
|
+
if (existsSync12(config)) {
|
|
3326
|
+
const projects = parse5(readFileSync10(config, "utf8")).projects ?? {};
|
|
3207
3327
|
const root = spec.root.replace(/\/$/u, "");
|
|
3208
3328
|
trusted = projects[root]?.trust_level === "trusted" || projects[`${root}/`]?.trust_level === "trusted";
|
|
3209
3329
|
}
|
|
@@ -3329,8 +3449,8 @@ function grok(spec, o) {
|
|
|
3329
3449
|
}
|
|
3330
3450
|
function antigravity(spec, options) {
|
|
3331
3451
|
const foreign = agentNames(spec.root).filter((name) => {
|
|
3332
|
-
const text =
|
|
3333
|
-
|
|
3452
|
+
const text = readFileSync10(
|
|
3453
|
+
join10(spec.root, ".agents/agents", name, "agent.md"),
|
|
3334
3454
|
"utf8"
|
|
3335
3455
|
);
|
|
3336
3456
|
return splitFrontmatter(text).meta["tools"] !== void 0;
|
|
@@ -3350,7 +3470,7 @@ function antigravity(spec, options) {
|
|
|
3350
3470
|
if (serversForTool(spec, "antigravity").length > 0) {
|
|
3351
3471
|
const result = options.run(
|
|
3352
3472
|
"agy",
|
|
3353
|
-
["plugin", "validate",
|
|
3473
|
+
["plugin", "validate", join10(spec.root, ANTIGRAVITY_MCP_PLUGIN)],
|
|
3354
3474
|
spec.root
|
|
3355
3475
|
);
|
|
3356
3476
|
findings.push(
|
|
@@ -3381,11 +3501,11 @@ function doctor(spec, options) {
|
|
|
3381
3501
|
}
|
|
3382
3502
|
|
|
3383
3503
|
// src/server.ts
|
|
3384
|
-
import { readFileSync as
|
|
3504
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
3385
3505
|
|
|
3386
3506
|
// src/files/bundle.ts
|
|
3387
|
-
import { readFileSync as
|
|
3388
|
-
import { dirname as dirname8, join as
|
|
3507
|
+
import { readFileSync as readFileSync12, statSync as statSync4 } from "fs";
|
|
3508
|
+
import { dirname as dirname8, join as join12 } from "path";
|
|
3389
3509
|
|
|
3390
3510
|
// src/mime.ts
|
|
3391
3511
|
var TYPES = {
|
|
@@ -3492,8 +3612,8 @@ function classify(path, bytes) {
|
|
|
3492
3612
|
|
|
3493
3613
|
// src/files/list.ts
|
|
3494
3614
|
import { createHash as createHash7 } from "crypto";
|
|
3495
|
-
import { readFileSync as
|
|
3496
|
-
import { basename as basename4, join as
|
|
3615
|
+
import { readFileSync as readFileSync11, readdirSync as readdirSync6, statSync as statSync3 } from "fs";
|
|
3616
|
+
import { basename as basename4, join as join11, relative as relative6, sep as sep2 } from "path";
|
|
3497
3617
|
|
|
3498
3618
|
// src/files/redact.ts
|
|
3499
3619
|
import { basename as basename3 } from "path";
|
|
@@ -3530,11 +3650,11 @@ function servedBytes(path, raw) {
|
|
|
3530
3650
|
var FILE_LIST_LIMIT = 200;
|
|
3531
3651
|
var sha256 = (bytes) => createHash7("sha256").update(bytes).digest("hex");
|
|
3532
3652
|
function describe(path, full) {
|
|
3533
|
-
const bytes = servedBytes(full,
|
|
3653
|
+
const bytes = servedBytes(full, readFileSync11(full));
|
|
3534
3654
|
return { path, bytes: bytes.length, sha256: sha256(bytes) };
|
|
3535
3655
|
}
|
|
3536
3656
|
function listSkillFiles(root, limit = FILE_LIST_LIMIT) {
|
|
3537
|
-
if (
|
|
3657
|
+
if (statSync3(root).isFile()) {
|
|
3538
3658
|
return { files: [describe(basename4(root), root)], truncated: false };
|
|
3539
3659
|
}
|
|
3540
3660
|
const files = [];
|
|
@@ -3543,14 +3663,14 @@ function listSkillFiles(root, limit = FILE_LIST_LIMIT) {
|
|
|
3543
3663
|
const dir = stack.pop();
|
|
3544
3664
|
for (const entry of readdirSync6(dir, { withFileTypes: true })) {
|
|
3545
3665
|
if (entry.name === "node_modules" || entry.name === ".git") continue;
|
|
3546
|
-
const full =
|
|
3666
|
+
const full = join11(dir, entry.name);
|
|
3547
3667
|
if (entry.isDirectory()) {
|
|
3548
3668
|
stack.push(full);
|
|
3549
3669
|
continue;
|
|
3550
3670
|
}
|
|
3551
3671
|
if (!entry.isFile()) continue;
|
|
3552
3672
|
if (files.length >= limit) return { files, truncated: true };
|
|
3553
|
-
files.push(describe(
|
|
3673
|
+
files.push(describe(relative6(root, full).split(sep2).join("/"), full));
|
|
3554
3674
|
}
|
|
3555
3675
|
}
|
|
3556
3676
|
files.sort((a, b) => a.path.localeCompare(b.path));
|
|
@@ -3577,7 +3697,7 @@ function resolveSkillFileUri(uri, entries) {
|
|
|
3577
3697
|
// src/files/bundle.ts
|
|
3578
3698
|
function bundleSkill(entry) {
|
|
3579
3699
|
const root = assetRoot(entry);
|
|
3580
|
-
const base =
|
|
3700
|
+
const base = statSync4(root).isFile() ? dirname8(root) : root;
|
|
3581
3701
|
const listing2 = listSkillFiles(root);
|
|
3582
3702
|
return {
|
|
3583
3703
|
name: entry.name,
|
|
@@ -3585,40 +3705,40 @@ function bundleSkill(entry) {
|
|
|
3585
3705
|
files: listing2.files.map((file) => ({
|
|
3586
3706
|
...file,
|
|
3587
3707
|
uri: skillFileUri(entry, file.path),
|
|
3588
|
-
mimeType: classify(file.path,
|
|
3708
|
+
mimeType: classify(file.path, readFileSync12(join12(base, file.path))).mimeType
|
|
3589
3709
|
}))
|
|
3590
3710
|
};
|
|
3591
3711
|
}
|
|
3592
3712
|
|
|
3593
3713
|
// src/files/read.ts
|
|
3594
|
-
import { readFileSync as
|
|
3714
|
+
import { readFileSync as readFileSync13, statSync as statSync6 } from "fs";
|
|
3595
3715
|
|
|
3596
3716
|
// src/files/resolve.ts
|
|
3597
|
-
import { realpathSync as
|
|
3598
|
-
import { dirname as dirname9, isAbsolute as
|
|
3599
|
-
var ownFile = (entry) =>
|
|
3717
|
+
import { realpathSync as realpathSync3, statSync as statSync5 } from "fs";
|
|
3718
|
+
import { dirname as dirname9, isAbsolute as isAbsolute6, relative as relative7, resolve as resolve7, sep as sep3 } from "path";
|
|
3719
|
+
var ownFile = (entry) => relative7(assetRoot(entry), entry.path).split(sep3).join("/");
|
|
3600
3720
|
function resolveSkillFile(entry, wanted = ownFile(entry)) {
|
|
3601
|
-
if (
|
|
3721
|
+
if (isAbsolute6(wanted) || wanted.split(/[\\/]/u).includes("..")) {
|
|
3602
3722
|
return { ok: false, error: "path_outside_skill", detail: wanted };
|
|
3603
3723
|
}
|
|
3604
|
-
const scope =
|
|
3605
|
-
const single =
|
|
3724
|
+
const scope = realpathSync3(assetRoot(entry));
|
|
3725
|
+
const single = statSync5(scope).isFile();
|
|
3606
3726
|
const root = single ? dirname9(scope) : scope;
|
|
3607
3727
|
let target;
|
|
3608
3728
|
try {
|
|
3609
|
-
target =
|
|
3610
|
-
single && wanted === "" ? scope :
|
|
3729
|
+
target = realpathSync3(
|
|
3730
|
+
single && wanted === "" ? scope : resolve7(root, wanted)
|
|
3611
3731
|
);
|
|
3612
3732
|
} catch {
|
|
3613
3733
|
return { ok: false, error: "no_such_file", detail: wanted };
|
|
3614
3734
|
}
|
|
3615
|
-
const inside = single ? target === scope : target === root || target.startsWith(root +
|
|
3735
|
+
const inside = single ? target === scope : target === root || target.startsWith(root + sep3);
|
|
3616
3736
|
if (!inside)
|
|
3617
3737
|
return { ok: false, error: "path_outside_skill", detail: wanted };
|
|
3618
3738
|
return {
|
|
3619
3739
|
ok: true,
|
|
3620
3740
|
target,
|
|
3621
|
-
path:
|
|
3741
|
+
path: relative7(root, target).split(sep3).join("/")
|
|
3622
3742
|
};
|
|
3623
3743
|
}
|
|
3624
3744
|
|
|
@@ -3627,7 +3747,7 @@ var READ_BUDGET_BYTES = 256 * 1024;
|
|
|
3627
3747
|
function readSkillFile(entry, wanted, budget = READ_BUDGET_BYTES) {
|
|
3628
3748
|
const resolved = resolveSkillFile(entry, wanted);
|
|
3629
3749
|
if (!resolved.ok) return resolved;
|
|
3630
|
-
const size =
|
|
3750
|
+
const size = statSync6(resolved.target).size;
|
|
3631
3751
|
if (size > budget) {
|
|
3632
3752
|
return {
|
|
3633
3753
|
ok: false,
|
|
@@ -3635,7 +3755,7 @@ function readSkillFile(entry, wanted, budget = READ_BUDGET_BYTES) {
|
|
|
3635
3755
|
detail: `${size} bytes > ${budget}`
|
|
3636
3756
|
};
|
|
3637
3757
|
}
|
|
3638
|
-
const bytes = servedBytes(resolved.target,
|
|
3758
|
+
const bytes = servedBytes(resolved.target, readFileSync13(resolved.target));
|
|
3639
3759
|
const { kind: kind2, mimeType } = classify(resolved.path, bytes);
|
|
3640
3760
|
return {
|
|
3641
3761
|
ok: true,
|
|
@@ -3811,7 +3931,7 @@ function createSkillTools(options) {
|
|
|
3811
3931
|
describe(name) {
|
|
3812
3932
|
const entry = byName(name);
|
|
3813
3933
|
if (!entry) return null;
|
|
3814
|
-
const source =
|
|
3934
|
+
const source = readFileSync14(entry.path, "utf8");
|
|
3815
3935
|
const listing2 = listSkillFiles(assetRoot(entry));
|
|
3816
3936
|
return {
|
|
3817
3937
|
name: entry.name,
|
|
@@ -3848,7 +3968,7 @@ function createSkillTools(options) {
|
|
|
3848
3968
|
return {
|
|
3849
3969
|
name: entry.name,
|
|
3850
3970
|
body: readBody(
|
|
3851
|
-
servedBytes(entry.path,
|
|
3971
|
+
servedBytes(entry.path, readFileSync14(entry.path)).toString("utf8")
|
|
3852
3972
|
),
|
|
3853
3973
|
files: bundle.files.filter((file) => file.path !== own),
|
|
3854
3974
|
filesTruncated: bundle.truncated
|
|
@@ -3917,7 +4037,7 @@ function registerSkillPrompts(server, tools) {
|
|
|
3917
4037
|
}
|
|
3918
4038
|
|
|
3919
4039
|
// src/resources.ts
|
|
3920
|
-
import { statSync as
|
|
4040
|
+
import { statSync as statSync7 } from "fs";
|
|
3921
4041
|
import {
|
|
3922
4042
|
ResourceNotFoundError,
|
|
3923
4043
|
ResourceTemplate
|
|
@@ -3930,7 +4050,7 @@ function listing(entries) {
|
|
|
3930
4050
|
name: entry.name,
|
|
3931
4051
|
description: entry.description,
|
|
3932
4052
|
mimeType: "text/markdown",
|
|
3933
|
-
size:
|
|
4053
|
+
size: statSync7(entry.path).size
|
|
3934
4054
|
}));
|
|
3935
4055
|
}
|
|
3936
4056
|
function complete(value, entries) {
|
|
@@ -3968,17 +4088,17 @@ function registerSkillResources(server, skills) {
|
|
|
3968
4088
|
|
|
3969
4089
|
// src/extension/entry.ts
|
|
3970
4090
|
import { createHash as createHash8 } from "crypto";
|
|
3971
|
-
import { readFileSync as
|
|
3972
|
-
import { basename as basename5, dirname as dirname10, join as
|
|
4091
|
+
import { readFileSync as readFileSync15, readdirSync as readdirSync7, statSync as statSync8 } from "fs";
|
|
4092
|
+
import { basename as basename5, dirname as dirname10, join as join13, relative as relative8, sep as sep4 } from "path";
|
|
3973
4093
|
var MAX_RESOURCES = 512;
|
|
3974
4094
|
var MAX_SKILL_BYTES = 16 * 1024 * 1024;
|
|
3975
4095
|
var digests = /* @__PURE__ */ new Map();
|
|
3976
4096
|
function facts(path) {
|
|
3977
|
-
const stat =
|
|
4097
|
+
const stat = statSync8(path);
|
|
3978
4098
|
const key = `${stat.mtimeMs}:${stat.size}`;
|
|
3979
4099
|
const cached = digests.get(path);
|
|
3980
4100
|
if (cached?.key === key) return cached;
|
|
3981
|
-
const bytes = servedBytes(path,
|
|
4101
|
+
const bytes = servedBytes(path, readFileSync15(path));
|
|
3982
4102
|
const digest = `sha256:${createHash8("sha256").update(bytes).digest("hex")}`;
|
|
3983
4103
|
const fresh = { key, digest, size: bytes.length };
|
|
3984
4104
|
digests.set(path, fresh);
|
|
@@ -3991,7 +4111,7 @@ function filesUnder(root) {
|
|
|
3991
4111
|
const dir = stack.pop();
|
|
3992
4112
|
for (const entry of readdirSync7(dir, { withFileTypes: true })) {
|
|
3993
4113
|
if (entry.name === "node_modules" || entry.name === ".git") continue;
|
|
3994
|
-
const full =
|
|
4114
|
+
const full = join13(dir, entry.name);
|
|
3995
4115
|
if (entry.isDirectory()) stack.push(full);
|
|
3996
4116
|
else if (entry.isFile()) found.push(full);
|
|
3997
4117
|
if (found.length > MAX_RESOURCES) return null;
|
|
@@ -4002,7 +4122,7 @@ function filesUnder(root) {
|
|
|
4002
4122
|
function extensionEntry(entry) {
|
|
4003
4123
|
if (kindOf(entry) !== "skill" || basename5(entry.path) !== "SKILL.md")
|
|
4004
4124
|
return null;
|
|
4005
|
-
const frontmatter = frontmatterObject(
|
|
4125
|
+
const frontmatter = frontmatterObject(readFileSync15(entry.path, "utf8"));
|
|
4006
4126
|
const root = dirname10(entry.path);
|
|
4007
4127
|
if (specProblems(frontmatter, basename5(root)).length > 0) return null;
|
|
4008
4128
|
if (frontmatter?.["name"] !== entry.slug) return null;
|
|
@@ -4012,7 +4132,7 @@ function extensionEntry(entry) {
|
|
|
4012
4132
|
const resources = files.map((path) => {
|
|
4013
4133
|
const fact = facts(path);
|
|
4014
4134
|
total += fact.size;
|
|
4015
|
-
const file =
|
|
4135
|
+
const file = relative8(root, path).split(sep4).join("/");
|
|
4016
4136
|
return {
|
|
4017
4137
|
uri: skillFileUri(entry, file),
|
|
4018
4138
|
digest: fact.digest,
|
|
@@ -4497,7 +4617,7 @@ function registerMailboxTools(server, service) {
|
|
|
4497
4617
|
|
|
4498
4618
|
// src/mcp.ts
|
|
4499
4619
|
var SERVER_NAME = "pmcp";
|
|
4500
|
-
var SERVER_VERSION = "0.
|
|
4620
|
+
var SERVER_VERSION = "0.14.0";
|
|
4501
4621
|
function registerSkillTools(server, tools) {
|
|
4502
4622
|
registerCatalogTool(server, tools);
|
|
4503
4623
|
registerFindTool(server, tools);
|
|
@@ -4518,16 +4638,16 @@ function createSkillServer(options) {
|
|
|
4518
4638
|
}
|
|
4519
4639
|
|
|
4520
4640
|
// src/validate.ts
|
|
4521
|
-
import { existsSync as
|
|
4522
|
-
import { basename as basename6, join as
|
|
4641
|
+
import { existsSync as existsSync13, readFileSync as readFileSync16, statSync as statSync9 } from "fs";
|
|
4642
|
+
import { basename as basename6, join as join14, resolve as resolve8 } from "path";
|
|
4523
4643
|
function validateSkillDir(dir) {
|
|
4524
|
-
const root =
|
|
4525
|
-
const skillMd = basename6(root) === "SKILL.md" ? root :
|
|
4526
|
-
if (!
|
|
4644
|
+
const root = resolve8(dir);
|
|
4645
|
+
const skillMd = basename6(root) === "SKILL.md" ? root : join14(root, "SKILL.md");
|
|
4646
|
+
if (!existsSync13(skillMd) || !statSync9(skillMd).isFile()) {
|
|
4527
4647
|
return [{ path: root, reason: "no SKILL.md", level: "error" }];
|
|
4528
4648
|
}
|
|
4529
|
-
const front = frontmatterObject(
|
|
4530
|
-
const directory = basename6(skillMd === root ?
|
|
4649
|
+
const front = frontmatterObject(readFileSync16(skillMd, "utf8"));
|
|
4650
|
+
const directory = basename6(skillMd === root ? join14(root, "..") : root);
|
|
4531
4651
|
return specProblems(front, directory).map((reason) => ({
|
|
4532
4652
|
path: skillMd,
|
|
4533
4653
|
reason,
|