@modootoday/pmcp 0.5.1 → 0.7.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/dist/http.js CHANGED
@@ -1,7 +1,13 @@
1
+ import {
2
+ DEFAULT_MODEL_ID,
3
+ encodeEntries,
4
+ loadEmbedder
5
+ } from "./chunk-NI2OLZPA.js";
6
+ import "./chunk-ZLELYZHL.js";
1
7
  import {
2
8
  createSkillServer,
3
9
  readCatalog
4
- } from "./chunk-76UKXVUE.js";
10
+ } from "./chunk-QHFORYIN.js";
5
11
 
6
12
  // src/http.ts
7
13
  import {
@@ -17,6 +23,25 @@ function createSkillHttpHandler(options) {
17
23
  let all = load(options);
18
24
  const tiersFor = options.tiersFor ?? (() => DEFAULT_TIERS);
19
25
  const handlers = /* @__PURE__ */ new Map();
26
+ let embedder;
27
+ let encoded = /* @__PURE__ */ new Map();
28
+ let vectors;
29
+ const semantic = options.semantic;
30
+ const encode = async () => {
31
+ if (!semantic) return "lexical";
32
+ try {
33
+ embedder ??= semantic.embedder ?? await loadEmbedder(semantic.modelId, semantic) ?? void 0;
34
+ if (!embedder)
35
+ throw new Error("@huggingface/transformers is not installed");
36
+ encoded = await encodeEntries(embedder, all, encoded);
37
+ vectors = new Map([...encoded].map(([name, v]) => [name, v.vector]));
38
+ return "semantic";
39
+ } catch (error) {
40
+ semantic.onError?.(error);
41
+ return "lexical";
42
+ }
43
+ };
44
+ let ready = encode();
20
45
  const handlerFor = (tiers) => {
21
46
  const key = [...tiers].sort().join(",");
22
47
  const cached = handlers.get(key);
@@ -24,6 +49,7 @@ function createSkillHttpHandler(options) {
24
49
  const handler = createMcpHandler(
25
50
  () => createSkillServer({
26
51
  ...options,
52
+ ...embedder && vectors ? { embedder, vectors } : {},
27
53
  loadCatalog: () => visibleTo(all, tiers)
28
54
  })
29
55
  );
@@ -54,12 +80,17 @@ function createSkillHttpHandler(options) {
54
80
  reload() {
55
81
  all = load(options);
56
82
  handlers.clear();
57
- }
83
+ vectors = void 0;
84
+ ready = encode();
85
+ },
86
+ ready: () => ready
58
87
  };
59
88
  }
60
89
  export {
90
+ DEFAULT_MODEL_ID,
61
91
  DEFAULT_TIERS,
62
92
  createSkillHttpHandler,
93
+ loadEmbedder,
63
94
  visibleTo
64
95
  };
65
96
  //# sourceMappingURL=http.js.map
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { I as IntentCache, S as SkillServerOptions, a as SkillTools } from './server-Dm71qZgM.js';
2
- export { C as CATALOG_PAGE_MAX, b as CATALOG_PAGE_SIZE, c as CallResponse, d as CatalogItem, e as CatalogResponse, D as DEFAULT_FIND_LIMIT, f as DESCRIBE_FILE_LIMIT, E as Embedder, F as FindOptions, g as FindResult, h as IntentCacheStats, K as KindFilter, M as Match, R as READ_BUDGET_BYTES, i as Ranking, j as ReadResult, k as SkillFilters, l as cosine, m as createSkillTools, n as find, o as lexicalScore, p as normaliseIntent } from './server-Dm71qZgM.js';
1
+ import { I as IntentCache, S as SkillServerOptions, a as SkillTools } from './server-wpYiAJ2n.js';
2
+ export { C as CATALOG_PAGE_MAX, b as CATALOG_PAGE_SIZE, c as CallResponse, d as CatalogItem, e as CatalogResponse, D as DEFAULT_FIND_LIMIT, f as DESCRIBE_FILE_LIMIT, E as Embedder, F as FindOptions, g as FindResult, h as IntentCacheStats, K as KindFilter, M as Match, R as READ_BUDGET_BYTES, i as Ranking, j as ReadResult, k as SkillFilters, l as cosine, m as createSkillTools, n as find, o as lexicalScore, p as normaliseIntent } from './server-wpYiAJ2n.js';
3
3
  import { S as SkillEntry } from './catalog-5v7jrGwP.js';
4
4
  export { a as ASSET_KINDS, A as AssetKind, C as CatalogOptions, M as MAX_SKILL_DEPTH, b as SKIPPED_DIRS, d as displayPath, k as kindOf, r as readBody, c as readCatalog, e as readFrontmatter, w as withoutBody } from './catalog-5v7jrGwP.js';
5
5
  import { McpServer } from '@modelcontextprotocol/server';
@@ -99,6 +99,131 @@ declare function findConfig(start: string): string | null;
99
99
  */
100
100
  declare function readConfig(path: string): ProjectConfig;
101
101
 
102
+ /** What the projector writes. A path is unique across a plan and is the lock key. */
103
+ type Output = {
104
+ readonly kind: "link";
105
+ readonly path: string;
106
+ readonly target: string;
107
+ } | {
108
+ readonly kind: "file";
109
+ readonly path: string;
110
+ readonly content: string;
111
+ }
112
+ /** One key inside a JSON file other content shares. path = file#a.b */
113
+ | {
114
+ readonly kind: "json";
115
+ readonly path: string;
116
+ readonly file: string;
117
+ readonly key: readonly string[];
118
+ readonly value: unknown;
119
+ }
120
+ /** A marked block inside a text file other content shares. path = file#pmcp */
121
+ | {
122
+ readonly kind: "block";
123
+ readonly path: string;
124
+ readonly file: string;
125
+ readonly content: string;
126
+ };
127
+
128
+ /**
129
+ * The projector's reading of pmcp.toml: which tools to write for, and the
130
+ * per-asset settings that do not belong in the cross-tool sources under .agents/.
131
+ */
132
+
133
+ declare const TOOLS: readonly ["claude", "codex", "gemini", "grok", "antigravity"];
134
+ type Tool = (typeof TOOLS)[number];
135
+ type Invocation = "any" | "user";
136
+ interface PackageRulesSpec {
137
+ /** Path of the rule file inside each package, e.g. `.agent/rules/PACKAGE.RULE.md`. */
138
+ readonly file: string;
139
+ /** Subdirectory of `.claude/rules` the links go in. */
140
+ readonly dir: string;
141
+ /** Leading path segments dropped when a link name is derived. */
142
+ readonly strip: readonly string[];
143
+ }
144
+ interface McpServerSpec {
145
+ readonly command: string;
146
+ readonly args: readonly string[];
147
+ readonly env: Readonly<Record<string, string>>;
148
+ /** Tools the server should expose where a host can narrow them. */
149
+ readonly tools?: readonly string[];
150
+ }
151
+ interface ProjectSpec {
152
+ readonly root: string;
153
+ readonly tools: ReadonlySet<Tool>;
154
+ readonly skills: Readonly<Record<string, {
155
+ invocation: Invocation;
156
+ }>>;
157
+ readonly agents: Readonly<Record<string, Partial<Record<Tool, Record<string, unknown>>>>>;
158
+ readonly packageRules: PackageRulesSpec | null;
159
+ readonly mcp: Readonly<Record<string, McpServerSpec>>;
160
+ }
161
+ declare function readSpec(config: ProjectConfig): ProjectSpec;
162
+
163
+ /**
164
+ * Every output the sources imply, read from disk but written nowhere. Sources:
165
+ * .agents/skills, .agents/agents, .agents/rules, package rule files, and pmcp.toml.
166
+ */
167
+
168
+ declare function plan(spec: ProjectSpec, owned?: ReadonlyMap<string, string>): Output[];
169
+
170
+ /**
171
+ * Writes or checks a plan. The lock (pmcp.lock) records what this wrote, so a
172
+ * source removed later takes its outputs with it, and a file someone else wrote
173
+ * is never overwritten.
174
+ */
175
+
176
+ declare const LOCK_FILE = "pmcp.lock";
177
+ interface ProjectResult {
178
+ /** 0 done or clean, 2 check found problems, 3 refused to overwrite. */
179
+ readonly code: 0 | 2 | 3;
180
+ readonly problems: readonly string[];
181
+ readonly outputs: number;
182
+ readonly pruned: number;
183
+ }
184
+ /** paths: globs whose fixed prefix holds no tracked file: a rule that loads nowhere. */
185
+ declare function deadGlobs(root: string, outputs: readonly Output[]): string[];
186
+ declare function project(spec: ProjectSpec, options: {
187
+ readonly check: boolean;
188
+ }): ProjectResult;
189
+
190
+ /**
191
+ * Asks each tool what it loads, through its own listing commands only: no
192
+ * model is called. A tool whose CLI is not installed is skipped, not failed.
193
+ */
194
+
195
+ interface RunResult {
196
+ /** The executable was not found. */
197
+ readonly missing: boolean;
198
+ readonly status: number | null;
199
+ readonly stdout: string;
200
+ }
201
+ type Runner = (command: string, args: readonly string[], cwd: string) => RunResult;
202
+ type Status = "ok" | "fail" | "skip";
203
+ interface Finding {
204
+ readonly tool: Tool | "project";
205
+ readonly check: string;
206
+ readonly status: Status;
207
+ readonly detail?: string;
208
+ }
209
+ interface DoctorOptions {
210
+ readonly run: Runner;
211
+ readonly home: string;
212
+ readonly only?: ReadonlySet<Tool>;
213
+ }
214
+ declare function doctor(spec: ProjectSpec, options: DoctorOptions): Finding[];
215
+
216
+ /**
217
+ * Links each package's path-scoped rule file into .claude/rules/<dir>/. One level
218
+ * down because Grok Build loads every top-level .claude/rules/*.md unscoped.
219
+ * Names already in use are kept, so moving the links renames nothing.
220
+ */
221
+
222
+ declare class ProjectError extends Error {
223
+ constructor(message: string);
224
+ }
225
+ declare function deriveName(dir: string, strip: readonly string[]): string;
226
+
102
227
  /**
103
228
  * The five tools, spoken over MCP.
104
229
  *
@@ -156,4 +281,4 @@ declare function extensionEntry(entry: SkillEntry): SkillExtensionEntry | null;
156
281
  */
157
282
  declare function registerSkillsExtension(server: McpServer, skills: () => readonly SkillEntry[]): void;
158
283
 
159
- export { CONFIG_FILE, type CatalogSection, ConfigError, DEFAULT_INTENT_CACHE_LIMIT, IntentCache, type IntentCacheOptions, type MetadataValue, type ProjectConfig, type Rejection, SERVER_NAME, SKILLS_EXTENSION, SkillEntry, type SkillExtensionEntry, type SkillResource, SkillServerOptions, SkillTools, assetRoot, createSkillServer, extensionEntry, findConfig, openIntentCache, readConfig, readFrontmatterText, readMarketplace, readMetadata, registerSkillTools, registerSkillsExtension, skillUri };
284
+ export { CONFIG_FILE, type CatalogSection, ConfigError, DEFAULT_INTENT_CACHE_LIMIT, type Finding, IntentCache, type IntentCacheOptions, LOCK_FILE, type McpServerSpec, type MetadataValue, type Output, type PackageRulesSpec, type ProjectConfig, ProjectError, type ProjectResult, type ProjectSpec, type Rejection, type Runner, SERVER_NAME, SKILLS_EXTENSION, SkillEntry, type SkillExtensionEntry, type SkillResource, SkillServerOptions, SkillTools, TOOLS, type Tool, assetRoot, createSkillServer, deadGlobs, deriveName, doctor, extensionEntry, findConfig, openIntentCache, plan, project, readConfig, readFrontmatterText, readMarketplace, readMetadata, readSpec, registerSkillTools, registerSkillsExtension, skillUri };
package/dist/index.js CHANGED
@@ -1,11 +1,22 @@
1
1
  import {
2
2
  CONFIG_FILE,
3
3
  ConfigError,
4
- DEFAULT_INTENT_CACHE_LIMIT,
4
+ LOCK_FILE,
5
+ ProjectError,
6
+ TOOLS,
7
+ deadGlobs,
8
+ deriveName,
9
+ doctor,
5
10
  findConfig,
6
- openIntentCache,
7
- readConfig
8
- } from "./chunk-XTLANVRL.js";
11
+ plan,
12
+ project,
13
+ readConfig,
14
+ readSpec
15
+ } from "./chunk-GNJSZCRH.js";
16
+ import {
17
+ DEFAULT_INTENT_CACHE_LIMIT,
18
+ openIntentCache
19
+ } from "./chunk-ZLELYZHL.js";
9
20
  import {
10
21
  ASSET_KINDS,
11
22
  CATALOG_PAGE_MAX,
@@ -37,7 +48,7 @@ import {
37
48
  registerSkillsExtension,
38
49
  skillUri,
39
50
  withoutBody
40
- } from "./chunk-76UKXVUE.js";
51
+ } from "./chunk-QHFORYIN.js";
41
52
  export {
42
53
  ASSET_KINDS,
43
54
  CATALOG_PAGE_MAX,
@@ -47,16 +58,22 @@ export {
47
58
  DEFAULT_FIND_LIMIT,
48
59
  DEFAULT_INTENT_CACHE_LIMIT,
49
60
  DESCRIBE_FILE_LIMIT,
61
+ LOCK_FILE,
50
62
  MAX_SKILL_DEPTH,
63
+ ProjectError,
51
64
  READ_BUDGET_BYTES,
52
65
  SERVER_NAME,
53
66
  SKILLS_EXTENSION,
54
67
  SKIPPED_DIRS,
68
+ TOOLS,
55
69
  assetRoot,
56
70
  cosine,
57
71
  createSkillServer,
58
72
  createSkillTools,
73
+ deadGlobs,
74
+ deriveName,
59
75
  displayPath,
76
+ doctor,
60
77
  extensionEntry,
61
78
  find,
62
79
  findConfig,
@@ -64,6 +81,8 @@ export {
64
81
  lexicalScore,
65
82
  normaliseIntent,
66
83
  openIntentCache,
84
+ plan,
85
+ project,
67
86
  readBody,
68
87
  readCatalog,
69
88
  readConfig,
@@ -71,6 +90,7 @@ export {
71
90
  readFrontmatterText,
72
91
  readMarketplace,
73
92
  readMetadata,
93
+ readSpec,
74
94
  registerSkillTools,
75
95
  registerSkillsExtension,
76
96
  skillUri,
@@ -56,7 +56,10 @@ interface FindResult {
56
56
  interface Embedder {
57
57
  readonly modelId: string;
58
58
  readonly dims: number;
59
+ /** Encodes an intent, the query side. */
59
60
  embed(text: string): Promise<Float32Array>;
61
+ /** Encodes a description, for models that write the two sides differently. */
62
+ embedPassage?(text: string): Promise<Float32Array>;
60
63
  }
61
64
  interface FindOptions {
62
65
  readonly entries: readonly SkillEntry[];
package/dist/stdio.js CHANGED
@@ -3,8 +3,8 @@ import {
3
3
  main,
4
4
  resolveRoots,
5
5
  serve
6
- } from "./chunk-ICHBC5FM.js";
7
- import "./chunk-76UKXVUE.js";
6
+ } from "./chunk-POJOFL4L.js";
7
+ import "./chunk-QHFORYIN.js";
8
8
  export {
9
9
  main,
10
10
  resolveRoots,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modootoday/pmcp",
3
- "version": "0.5.1",
3
+ "version": "0.7.0",
4
4
  "license": "Elastic-2.0",
5
5
  "author": "modootoday",
6
6
  "description": "An MCP server that finds the skills your installed packages already ship. Reads SKILL.md out of node_modules by shape rather than by path, so it sees the skills, .agent, .claude, .gemini and .codex conventions alike, and keeps session startup flat as the number of installed skills grows.",