@modootoday/pmcp 0.14.0 → 0.15.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
@@ -2294,7 +2294,7 @@ function registerMailboxTools(server, service) {
2294
2294
 
2295
2295
  // src/mcp.ts
2296
2296
  var SERVER_NAME = "pmcp";
2297
- var SERVER_VERSION = "0.14.0";
2297
+ var SERVER_VERSION = "0.15.0";
2298
2298
  function registerSkillTools(server, tools) {
2299
2299
  registerCatalogTool(server, tools);
2300
2300
  registerFindTool(server, tools);
package/dist/index.d.ts CHANGED
@@ -275,7 +275,7 @@ declare function resolveSkillFileUri(uri: string, entries: readonly SkillEntry[]
275
275
 
276
276
  /** Reported to the host on connect. */
277
277
  declare const SERVER_NAME = "pmcp";
278
- declare const SERVER_VERSION = "0.14.0";
278
+ declare const SERVER_VERSION = "0.15.0";
279
279
  /**
280
280
  * Registers the skill_* tools on a server.
281
281
  *
package/dist/index.js CHANGED
@@ -5,19 +5,19 @@ function normaliseIntent(intent) {
5
5
 
6
6
  // src/storage/sqlite.ts
7
7
  async function openSqlite(path, options = {}) {
8
- if (!process.versions.bun) {
9
- const name2 = "node:sqlite";
10
- const { DatabaseSync } = await import(name2);
11
- return { db: new DatabaseSync(path, options), provider: name2 };
8
+ const provider = process.versions.bun ? "bun:sqlite" : "node:sqlite";
9
+ const sqlite = await import(provider);
10
+ if (provider === "node:sqlite") {
11
+ const { DatabaseSync } = sqlite;
12
+ return { db: new DatabaseSync(path, options), provider };
12
13
  }
13
- const name = "bun:sqlite";
14
- const { Database } = await import(name);
14
+ const { Database } = sqlite;
15
15
  const native2 = new Database(path, {
16
16
  create: !options.readOnly,
17
17
  readonly: options.readOnly
18
18
  });
19
19
  return {
20
- provider: name,
20
+ provider,
21
21
  db: {
22
22
  exec: (sql) => native2.run(sql),
23
23
  prepare: (sql) => native2.query(sql),
@@ -1437,6 +1437,7 @@ function findConfig(start) {
1437
1437
  for (; ; ) {
1438
1438
  const candidate = join4(dir, CONFIG_FILE);
1439
1439
  if (existsSync5(candidate)) return candidate;
1440
+ if (existsSync5(join4(dir, ".git"))) return null;
1440
1441
  const parent = dirname3(dir);
1441
1442
  if (parent === dir) return null;
1442
1443
  dir = parent;
@@ -2792,16 +2793,14 @@ function censusDirs(spec) {
2792
2793
  import { createHash as createHash6 } from "crypto";
2793
2794
  import {
2794
2795
  existsSync as existsSync11,
2795
- lstatSync as lstatSync3,
2796
+ lstatSync as lstatSync4,
2796
2797
  mkdirSync as mkdirSync2,
2797
2798
  readFileSync as readFileSync9,
2798
2799
  readdirSync as readdirSync5,
2799
2800
  readlinkSync as readlinkSync2,
2800
- rmSync,
2801
- symlinkSync,
2802
- writeFileSync as writeFileSync2
2801
+ rmSync as rmSync2
2803
2802
  } from "fs";
2804
- import { dirname as dirname7, join as join9, posix as posix2 } from "path";
2803
+ import { dirname as dirname8, join as join9, posix as posix2 } from "path";
2805
2804
  import { parse as parse4 } from "smol-toml";
2806
2805
 
2807
2806
  // src/project/backup.ts
@@ -2879,6 +2878,67 @@ function backupFiles(root, paths) {
2879
2878
  return destination;
2880
2879
  }
2881
2880
 
2881
+ // src/project/write.ts
2882
+ import { randomUUID } from "crypto";
2883
+ import {
2884
+ closeSync,
2885
+ fchmodSync,
2886
+ fsyncSync,
2887
+ lstatSync as lstatSync3,
2888
+ openSync,
2889
+ renameSync,
2890
+ rmSync,
2891
+ symlinkSync,
2892
+ writeFileSync as writeFileSync2
2893
+ } from "fs";
2894
+ import { dirname as dirname7 } from "path";
2895
+ function fileMode(path) {
2896
+ try {
2897
+ const stat = lstatSync3(path);
2898
+ if (stat.isFile()) return stat.mode & 511;
2899
+ } catch (error) {
2900
+ if (error.code !== "ENOENT") throw error;
2901
+ }
2902
+ return 438 & ~process.umask();
2903
+ }
2904
+ function syncDirectory(path) {
2905
+ if (process.platform === "win32") return;
2906
+ const descriptor = openSync(dirname7(path), "r");
2907
+ try {
2908
+ fsyncSync(descriptor);
2909
+ } finally {
2910
+ closeSync(descriptor);
2911
+ }
2912
+ }
2913
+ function replaceFile(path, content) {
2914
+ const mode = fileMode(path);
2915
+ const temporary = `${path}.${randomUUID()}.new`;
2916
+ const descriptor = openSync(temporary, "wx", 384);
2917
+ try {
2918
+ try {
2919
+ writeFileSync2(descriptor, content);
2920
+ fchmodSync(descriptor, mode);
2921
+ fsyncSync(descriptor);
2922
+ } finally {
2923
+ closeSync(descriptor);
2924
+ }
2925
+ renameSync(temporary, path);
2926
+ syncDirectory(path);
2927
+ } finally {
2928
+ rmSync(temporary, { force: true });
2929
+ }
2930
+ }
2931
+ function replaceLink(path, target) {
2932
+ const temporary = `${path}.${randomUUID()}.new`;
2933
+ try {
2934
+ symlinkSync(target, temporary);
2935
+ renameSync(temporary, path);
2936
+ syncDirectory(path);
2937
+ } finally {
2938
+ rmSync(temporary, { force: true });
2939
+ }
2940
+ }
2941
+
2882
2942
  // src/project/apply.ts
2883
2943
  var LOCK_FILE = "pmcp.lock";
2884
2944
  var BEGIN = "# >>> pmcp project (edit pmcp.toml, not this block) >>>";
@@ -2896,7 +2956,7 @@ function readLock(root) {
2896
2956
  }
2897
2957
  function linkOf(abs) {
2898
2958
  try {
2899
- return lstatSync3(abs).isSymbolicLink() ? readlinkSync2(abs) : null;
2959
+ return lstatSync4(abs).isSymbolicLink() ? readlinkSync2(abs) : null;
2900
2960
  } catch {
2901
2961
  return null;
2902
2962
  }
@@ -2998,7 +3058,7 @@ function replaceable(root, output, owned) {
2998
3058
  if (target !== null) {
2999
3059
  return output.kind === "link" && target === output.target;
3000
3060
  }
3001
- if (lstatSync3(abs).isDirectory()) return false;
3061
+ if (lstatSync4(abs).isDirectory()) return false;
3002
3062
  const text = readFileSync9(abs, "utf8");
3003
3063
  if (output.kind === "file" && text === output.content) return true;
3004
3064
  return PREDECESSORS.some((mark) => text.includes(mark));
@@ -3163,10 +3223,12 @@ function project(spec, options) {
3163
3223
  if (output.kind !== "link" && output.kind !== "file") continue;
3164
3224
  if (present(spec.root, output)) continue;
3165
3225
  const abs = join9(spec.root, output.path);
3166
- mkdirSync2(dirname7(abs), { recursive: true });
3167
- rmSync(abs, { force: true, recursive: true });
3168
- if (output.kind === "link") symlinkSync(output.target, abs);
3169
- else writeFileSync2(abs, output.content);
3226
+ mkdirSync2(dirname8(abs), { recursive: true });
3227
+ if (output.kind === "link") {
3228
+ replaceLink(abs, output.target);
3229
+ continue;
3230
+ }
3231
+ replaceFile(abs, output.content);
3170
3232
  }
3171
3233
  let pruned = 0;
3172
3234
  const jsonFiles = /* @__PURE__ */ new Map();
@@ -3188,7 +3250,7 @@ function project(spec, options) {
3188
3250
  group.drops.push(keyed.key);
3189
3251
  jsonFiles.set(keyed.file, group);
3190
3252
  } else {
3191
- rmSync(join9(spec.root, entry.path), { force: true, recursive: true });
3253
+ rmSync2(join9(spec.root, entry.path), { force: true, recursive: true });
3192
3254
  }
3193
3255
  pruned += 1;
3194
3256
  }
@@ -3209,8 +3271,8 @@ function project(spec, options) {
3209
3271
  }
3210
3272
  if (same(before, after)) continue;
3211
3273
  if (!existsSync11(abs) && Object.keys(after).length === 0) continue;
3212
- mkdirSync2(dirname7(abs), { recursive: true });
3213
- writeFileSync2(abs, `${JSON.stringify(after, null, 2)}
3274
+ mkdirSync2(dirname8(abs), { recursive: true });
3275
+ replaceFile(abs, `${JSON.stringify(after, null, 2)}
3214
3276
  `);
3215
3277
  }
3216
3278
  for (const [file, content] of blockFiles) {
@@ -3222,8 +3284,8 @@ function project(spec, options) {
3222
3284
  after = `${after}${sep5}${block(content)}`;
3223
3285
  }
3224
3286
  if (after === before) continue;
3225
- mkdirSync2(dirname7(abs), { recursive: true });
3226
- writeFileSync2(abs, after);
3287
+ mkdirSync2(dirname8(abs), { recursive: true });
3288
+ replaceFile(abs, after);
3227
3289
  }
3228
3290
  if (spec.packageRules) {
3229
3291
  const linkedDirs = new Set(
@@ -3237,11 +3299,11 @@ function project(spec, options) {
3237
3299
  const abs = join9(spec.root, RULES_DIR, `${name}.md`);
3238
3300
  const broken = !existsSync11(abs);
3239
3301
  if (!broken && !linkedDirs.has(posix2.dirname(target))) continue;
3240
- rmSync(abs, { force: true });
3302
+ rmSync2(abs, { force: true });
3241
3303
  pruned += 1;
3242
3304
  }
3243
3305
  }
3244
- writeFileSync2(
3306
+ replaceFile(
3245
3307
  join9(spec.root, LOCK_FILE),
3246
3308
  `${JSON.stringify({ version: 1, outputs: outputs.filter((output) => output.kind !== "json" || output.managed === void 0 || output.managed.length > 0).map(lockEntry) }, null, 2)}
3247
3309
  `
@@ -3505,7 +3567,7 @@ import { readFileSync as readFileSync14 } from "fs";
3505
3567
 
3506
3568
  // src/files/bundle.ts
3507
3569
  import { readFileSync as readFileSync12, statSync as statSync4 } from "fs";
3508
- import { dirname as dirname8, join as join12 } from "path";
3570
+ import { dirname as dirname9, join as join12 } from "path";
3509
3571
 
3510
3572
  // src/mime.ts
3511
3573
  var TYPES = {
@@ -3697,7 +3759,7 @@ function resolveSkillFileUri(uri, entries) {
3697
3759
  // src/files/bundle.ts
3698
3760
  function bundleSkill(entry) {
3699
3761
  const root = assetRoot(entry);
3700
- const base = statSync4(root).isFile() ? dirname8(root) : root;
3762
+ const base = statSync4(root).isFile() ? dirname9(root) : root;
3701
3763
  const listing2 = listSkillFiles(root);
3702
3764
  return {
3703
3765
  name: entry.name,
@@ -3715,7 +3777,7 @@ import { readFileSync as readFileSync13, statSync as statSync6 } from "fs";
3715
3777
 
3716
3778
  // src/files/resolve.ts
3717
3779
  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";
3780
+ import { dirname as dirname10, isAbsolute as isAbsolute6, relative as relative7, resolve as resolve7, sep as sep3 } from "path";
3719
3781
  var ownFile = (entry) => relative7(assetRoot(entry), entry.path).split(sep3).join("/");
3720
3782
  function resolveSkillFile(entry, wanted = ownFile(entry)) {
3721
3783
  if (isAbsolute6(wanted) || wanted.split(/[\\/]/u).includes("..")) {
@@ -3723,7 +3785,7 @@ function resolveSkillFile(entry, wanted = ownFile(entry)) {
3723
3785
  }
3724
3786
  const scope = realpathSync3(assetRoot(entry));
3725
3787
  const single = statSync5(scope).isFile();
3726
- const root = single ? dirname9(scope) : scope;
3788
+ const root = single ? dirname10(scope) : scope;
3727
3789
  let target;
3728
3790
  try {
3729
3791
  target = realpathSync3(
@@ -4089,7 +4151,7 @@ function registerSkillResources(server, skills) {
4089
4151
  // src/extension/entry.ts
4090
4152
  import { createHash as createHash8 } from "crypto";
4091
4153
  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";
4154
+ import { basename as basename5, dirname as dirname11, join as join13, relative as relative8, sep as sep4 } from "path";
4093
4155
  var MAX_RESOURCES = 512;
4094
4156
  var MAX_SKILL_BYTES = 16 * 1024 * 1024;
4095
4157
  var digests = /* @__PURE__ */ new Map();
@@ -4123,7 +4185,7 @@ function extensionEntry(entry) {
4123
4185
  if (kindOf(entry) !== "skill" || basename5(entry.path) !== "SKILL.md")
4124
4186
  return null;
4125
4187
  const frontmatter = frontmatterObject(readFileSync15(entry.path, "utf8"));
4126
- const root = dirname10(entry.path);
4188
+ const root = dirname11(entry.path);
4127
4189
  if (specProblems(frontmatter, basename5(root)).length > 0) return null;
4128
4190
  if (frontmatter?.["name"] !== entry.slug) return null;
4129
4191
  const files = filesUnder(root);
@@ -4617,7 +4679,7 @@ function registerMailboxTools(server, service) {
4617
4679
 
4618
4680
  // src/mcp.ts
4619
4681
  var SERVER_NAME = "pmcp";
4620
- var SERVER_VERSION = "0.14.0";
4682
+ var SERVER_VERSION = "0.15.0";
4621
4683
  function registerSkillTools(server, tools) {
4622
4684
  registerCatalogTool(server, tools);
4623
4685
  registerFindTool(server, tools);
@@ -247,19 +247,19 @@ import { setTimeout as delay } from "timers/promises";
247
247
 
248
248
  // src/storage/sqlite.ts
249
249
  async function openSqlite(path, options = {}) {
250
- if (!process.versions.bun) {
251
- const name2 = "node:sqlite";
252
- const { DatabaseSync } = await import(name2);
253
- return { db: new DatabaseSync(path, options), provider: name2 };
250
+ const provider = process.versions.bun ? "bun:sqlite" : "node:sqlite";
251
+ const sqlite = await import(provider);
252
+ if (provider === "node:sqlite") {
253
+ const { DatabaseSync } = sqlite;
254
+ return { db: new DatabaseSync(path, options), provider };
254
255
  }
255
- const name = "bun:sqlite";
256
- const { Database } = await import(name);
256
+ const { Database } = sqlite;
257
257
  const native = new Database(path, {
258
258
  create: !options.readOnly,
259
259
  readonly: options.readOnly
260
260
  });
261
261
  return {
262
- provider: name,
262
+ provider,
263
263
  db: {
264
264
  exec: (sql) => native.run(sql),
265
265
  prepare: (sql) => native.query(sql),
package/dist/stdio.js CHANGED
@@ -1941,7 +1941,7 @@ function registerMailboxTools(server, service) {
1941
1941
 
1942
1942
  // src/mcp.ts
1943
1943
  var SERVER_NAME = "pmcp";
1944
- var SERVER_VERSION = "0.14.0";
1944
+ var SERVER_VERSION = "0.15.0";
1945
1945
  function registerSkillTools(server, tools) {
1946
1946
  registerCatalogTool(server, tools);
1947
1947
  registerFindTool(server, tools);
@@ -2238,19 +2238,19 @@ import { setTimeout as delay } from "timers/promises";
2238
2238
 
2239
2239
  // src/storage/sqlite.ts
2240
2240
  async function openSqlite(path, options = {}) {
2241
- if (!process.versions.bun) {
2242
- const name2 = "node:sqlite";
2243
- const { DatabaseSync } = await import(name2);
2244
- return { db: new DatabaseSync(path, options), provider: name2 };
2241
+ const provider = process.versions.bun ? "bun:sqlite" : "node:sqlite";
2242
+ const sqlite = await import(provider);
2243
+ if (provider === "node:sqlite") {
2244
+ const { DatabaseSync } = sqlite;
2245
+ return { db: new DatabaseSync(path, options), provider };
2245
2246
  }
2246
- const name = "bun:sqlite";
2247
- const { Database } = await import(name);
2247
+ const { Database } = sqlite;
2248
2248
  const native = new Database(path, {
2249
2249
  create: !options.readOnly,
2250
2250
  readonly: options.readOnly
2251
2251
  });
2252
2252
  return {
2253
- provider: name,
2253
+ provider,
2254
2254
  db: {
2255
2255
  exec: (sql) => native.run(sql),
2256
2256
  prepare: (sql) => native.query(sql),