@serviceme/devtools-core 2.0.0 → 2.0.2

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.
Files changed (82) hide show
  1. package/dist/auth-Bzss8zOv.mjs +995 -0
  2. package/dist/auth-Bzss8zOv.mjs.map +1 -0
  3. package/dist/auth-DXam3c4S.js +1078 -0
  4. package/dist/auth-DXam3c4S.js.map +1 -0
  5. package/dist/auth.d.mts +2 -2
  6. package/dist/auth.d.ts +2 -2
  7. package/dist/auth.js +14 -1029
  8. package/dist/auth.mjs +2 -991
  9. package/dist/device-CDDcwDY6.mjs +758 -0
  10. package/dist/device-CDDcwDY6.mjs.map +1 -0
  11. package/dist/device-DuAYH8bk.js +839 -0
  12. package/dist/device-DuAYH8bk.js.map +1 -0
  13. package/dist/device.d.mts +2 -455
  14. package/dist/device.d.ts +2 -455
  15. package/dist/device.js +15 -728
  16. package/dist/device.mjs +2 -679
  17. package/dist/index-2rX86yMq.d.mts +331 -0
  18. package/dist/index-BI11AfMH.d.mts +377 -0
  19. package/dist/index-BI11AfMH.d.ts +377 -0
  20. package/dist/index-CoA6y0MP.d.mts +498 -0
  21. package/dist/index-CoA6y0MP.d.ts +498 -0
  22. package/dist/index-DaW7IYA-.d.mts +185 -0
  23. package/dist/index-DaW7IYA-.d.ts +185 -0
  24. package/dist/index-Dp6FwWKh.d.ts +331 -0
  25. package/dist/index.d.mts +2340 -2101
  26. package/dist/index.d.ts +2340 -2101
  27. package/dist/index.js +8117 -10538
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.mjs +7895 -10318
  30. package/dist/index.mjs.map +1 -1
  31. package/dist/rolldown-runtime-VH7oDXx4.js +28 -0
  32. package/dist/skill-linker.d.mts +82 -81
  33. package/dist/skill-linker.d.ts +82 -81
  34. package/dist/skill-linker.js +359 -402
  35. package/dist/skill-linker.js.map +1 -1
  36. package/dist/skill-linker.mjs +345 -357
  37. package/dist/skill-linker.mjs.map +1 -1
  38. package/dist/skill-store-Bym2yinU.mjs +388 -0
  39. package/dist/skill-store-Bym2yinU.mjs.map +1 -0
  40. package/dist/skill-store-CJdYyyxu.js +408 -0
  41. package/dist/skill-store-CJdYyyxu.js.map +1 -0
  42. package/dist/skill-store.d.mts +41 -42
  43. package/dist/skill-store.d.ts +41 -42
  44. package/dist/skill-store.js +5 -338
  45. package/dist/skill-store.mjs +2 -301
  46. package/dist/submit-Cg7wSa3x.mjs +84 -0
  47. package/dist/submit-Cg7wSa3x.mjs.map +1 -0
  48. package/dist/submit-CltE6YOZ.js +98 -0
  49. package/dist/submit-CltE6YOZ.js.map +1 -0
  50. package/dist/submit.d.mts +2 -3
  51. package/dist/submit.d.ts +2 -3
  52. package/dist/submit.js +4 -166
  53. package/dist/submit.mjs +2 -130
  54. package/dist/toolbox-CbfxpNg-.mjs +540 -0
  55. package/dist/toolbox-CbfxpNg-.mjs.map +1 -0
  56. package/dist/toolbox-CxnOr-FY.js +614 -0
  57. package/dist/toolbox-CxnOr-FY.js.map +1 -0
  58. package/dist/toolbox.d.mts +2 -244
  59. package/dist/toolbox.d.ts +2 -244
  60. package/dist/toolbox.js +14 -584
  61. package/dist/toolbox.mjs +2 -536
  62. package/dist/{types-B9gk3dXH.d.ts → types-BCV3IedE.d.mts} +25 -23
  63. package/dist/{types-B9gk3dXH.d.mts → types-BCV3IedE.d.ts} +25 -23
  64. package/dist/userHome-BquDeFVE.js +526 -0
  65. package/dist/userHome-BquDeFVE.js.map +1 -0
  66. package/dist/userHome-CcnAQPG1.mjs +212 -0
  67. package/dist/userHome-CcnAQPG1.mjs.map +1 -0
  68. package/package.json +10 -10
  69. package/dist/auth.js.map +0 -1
  70. package/dist/auth.mjs.map +0 -1
  71. package/dist/device.js.map +0 -1
  72. package/dist/device.mjs.map +0 -1
  73. package/dist/index-BMk4tqIT.d.mts +0 -328
  74. package/dist/index-CymN0x9Z.d.ts +0 -328
  75. package/dist/index-PD135hlB.d.mts +0 -626
  76. package/dist/index-PD135hlB.d.ts +0 -626
  77. package/dist/skill-store.js.map +0 -1
  78. package/dist/skill-store.mjs.map +0 -1
  79. package/dist/submit.js.map +0 -1
  80. package/dist/submit.mjs.map +0 -1
  81. package/dist/toolbox.js.map +0 -1
  82. package/dist/toolbox.mjs.map +0 -1
package/dist/toolbox.mjs CHANGED
@@ -1,536 +1,2 @@
1
- // src/toolbox/sort.ts
2
- function lastUsedTimestamp(tool) {
3
- if (!tool.lastUsedAt) return 0;
4
- const ms = Date.parse(tool.lastUsedAt);
5
- return Number.isFinite(ms) ? ms : 0;
6
- }
7
- function sortByRecentFirst(tools) {
8
- return [...tools].sort((a, b) => {
9
- const tsA = lastUsedTimestamp(a);
10
- const tsB = lastUsedTimestamp(b);
11
- if (tsA !== tsB) return tsB - tsA;
12
- const orderA = a.order ?? Number.MAX_SAFE_INTEGER;
13
- const orderB = b.order ?? Number.MAX_SAFE_INTEGER;
14
- if (orderA !== orderB) return orderA - orderB;
15
- return a.id.localeCompare(b.id);
16
- });
17
- }
18
- function sortByUserOrder(tools) {
19
- return [...tools].sort((a, b) => {
20
- const orderA = a.order ?? Number.MAX_SAFE_INTEGER;
21
- const orderB = b.order ?? Number.MAX_SAFE_INTEGER;
22
- if (orderA !== orderB) return orderA - orderB;
23
- return a.id.localeCompare(b.id);
24
- });
25
- }
26
- function mergeWithDefaults(defaults, userTools) {
27
- const defaultIds = new Set(defaults.map((d) => d.id));
28
- const uniqueUserTools = userTools.filter((t) => !defaultIds.has(t.id));
29
- return sortByUserOrder([...defaults, ...uniqueUserTools]);
30
- }
31
- function reindexOrder(tools, newOrderIds) {
32
- const orderMap = /* @__PURE__ */ new Map();
33
- for (const [index, id] of newOrderIds.entries()) {
34
- orderMap.set(id, index);
35
- }
36
- for (const tool of tools) {
37
- const next = orderMap.get(tool.id);
38
- if (next !== void 0) tool.order = next;
39
- }
40
- return tools;
41
- }
42
- function touchLastUsedAt(tools, id, when = /* @__PURE__ */ new Date()) {
43
- return tools.map((tool) => tool.id === id ? { ...tool, lastUsedAt: when.toISOString() } : tool);
44
- }
45
-
46
- // src/toolbox/ToolboxStore.ts
47
- import * as fsp from "fs/promises";
48
- import * as path2 from "path";
49
- import { setTimeout as delay } from "timers/promises";
50
-
51
- // src/paths/userHome.ts
52
- import * as os from "os";
53
- import * as path from "path";
54
- var SERVICEME_DIR_NAME = ".serviceme";
55
- var SERVICEME_HOME_ENV = "SERVICEME_HOME";
56
- var activeOverrides = {};
57
- function resolveHomeDir() {
58
- const injected = activeOverrides.homeDir;
59
- if (injected !== void 0) {
60
- return injected;
61
- }
62
- return os.homedir();
63
- }
64
- function resolveServicemeHomeEnv() {
65
- const injected = activeOverrides.servicemeHomeEnv;
66
- if (injected !== void 0) {
67
- return injected.length > 0 ? injected : void 0;
68
- }
69
- const envValue = process.env[SERVICEME_HOME_ENV];
70
- return envValue && envValue.length > 0 ? envValue : void 0;
71
- }
72
- function getServicemeHome() {
73
- const override = resolveServicemeHomeEnv();
74
- if (override !== void 0) {
75
- return path.resolve(override);
76
- }
77
- return path.join(resolveHomeDir(), SERVICEME_DIR_NAME);
78
- }
79
- var TOOLBOX_JSON_FILENAME = "toolbox.json";
80
- function getToolboxJsonPath() {
81
- return path.join(getServicemeHome(), TOOLBOX_JSON_FILENAME);
82
- }
83
-
84
- // src/toolbox/types.ts
85
- var TOOLBOX_JSON_SCHEMA_VERSION = 1;
86
- var BUILTIN_DEFAULT_TOOLS = [
87
- {
88
- id: "builtin-docs",
89
- name: "SERVICEME Docs",
90
- description: "Official documentation portal",
91
- icon: "book",
92
- url: "https://docs.medalsoft.com/serviceme"
93
- },
94
- {
95
- id: "builtin-issues",
96
- name: "Issue Tracker",
97
- description: "Report bugs and feature requests",
98
- icon: "bug",
99
- url: "https://github.com/medalsoftchina/ms-devtools-vscode/issues"
100
- },
101
- {
102
- id: "builtin-changelog",
103
- name: "Changelog",
104
- description: "Release notes for every published version",
105
- icon: "history",
106
- url: "https://github.com/medalsoftchina/ms-devtools-vscode/releases"
107
- }
108
- ];
109
-
110
- // src/toolbox/ToolboxStore.ts
111
- var FILE_MODE = 384;
112
- var LOCK_DIR_MODE = 448;
113
- var DEFAULT_LOCK_TIMEOUT_MS = 5e3;
114
- var DEFAULT_LOCK_RETRY_MS = 25;
115
- var LOCK_STALE_GRACE_MS = 200;
116
- var TMP_SUFFIX = ".tmp";
117
- var WORKSPACE_TOOLBOX_RELATIVE_PATH = path2.join(".github", ".serviceme-toolbox.json");
118
- var LEGACY_WORKSPACE_TOOLBOX_FILENAME = ".ms-devtools-toolbox.json";
119
- async function migrateLegacyWorkspaceToolboxFile(filePath) {
120
- if (!filePath) return;
121
- const legacyPath = path2.join(path2.dirname(filePath), LEGACY_WORKSPACE_TOOLBOX_FILENAME);
122
- if (legacyPath === filePath) return;
123
- try {
124
- await fsp.access(filePath);
125
- return;
126
- } catch {
127
- }
128
- try {
129
- await fsp.rename(legacyPath, filePath);
130
- } catch {
131
- }
132
- }
133
- var FsToolboxFileBackend = class {
134
- constructor() {
135
- this.maxBackupCount = 5;
136
- }
137
- async exists(filePath) {
138
- try {
139
- await fsp.access(filePath);
140
- return true;
141
- } catch {
142
- return false;
143
- }
144
- }
145
- async read(filePath) {
146
- let buf;
147
- try {
148
- buf = await fsp.readFile(filePath, "utf8");
149
- } catch (err) {
150
- if (isNodeError(err) && err.code === "ENOENT") return null;
151
- throw err;
152
- }
153
- try {
154
- const parsed = JSON.parse(buf);
155
- return coercePersistedToolbox(parsed);
156
- } catch {
157
- await this.backupCorruptedFile(filePath);
158
- return null;
159
- }
160
- }
161
- async backupCorruptedFile(filePath) {
162
- try {
163
- const backupPath = `${filePath}.corrupted.${Date.now()}.bak`;
164
- await fsp.copyFile(filePath, backupPath);
165
- await this.purgeExcessBackups(filePath);
166
- } catch {
167
- }
168
- }
169
- async purgeExcessBackups(filePath) {
170
- const dir = path2.dirname(filePath);
171
- const base = path2.basename(filePath);
172
- let entries;
173
- try {
174
- entries = await fsp.readdir(dir);
175
- } catch {
176
- return;
177
- }
178
- const backups = entries.filter((n) => n.startsWith(base) && n.endsWith(".bak")).map((n) => ({ name: n, filePath: path2.join(dir, n) })).sort((a, b) => {
179
- return a.name.localeCompare(b.name);
180
- });
181
- const excess = backups.length - this.maxBackupCount;
182
- if (excess <= 0) return;
183
- await Promise.all(
184
- backups.slice(0, excess).map((b) => fsp.rm(b.filePath).catch(() => void 0))
185
- );
186
- }
187
- async write(filePath, payload) {
188
- await fsp.mkdir(path2.dirname(filePath), { recursive: true });
189
- const tmpPath = `${filePath}${TMP_SUFFIX}`;
190
- const bytes = Buffer.from(JSON.stringify(payload, null, " "), "utf8");
191
- await fsp.rm(tmpPath, { force: true });
192
- const handle = await fsp.open(tmpPath, "w", FILE_MODE);
193
- try {
194
- await handle.writeFile(bytes);
195
- await handle.sync();
196
- } finally {
197
- await handle.close();
198
- }
199
- await fsp.rename(tmpPath, filePath);
200
- await fsp.chmod(filePath, FILE_MODE).catch(() => void 0);
201
- }
202
- };
203
- function coercePersistedToolbox(parsed) {
204
- if (typeof parsed !== "object" || parsed === null) {
205
- throw new Error("toolbox.json: top-level must be an object");
206
- }
207
- const obj = parsed;
208
- const version = obj.version;
209
- if (version !== TOOLBOX_JSON_SCHEMA_VERSION) {
210
- throw new Error(`toolbox.json: unsupported schema version ${String(version)}`);
211
- }
212
- if (!Array.isArray(obj.tools)) {
213
- throw new Error("toolbox.json: 'tools' must be an array");
214
- }
215
- return { version, tools: obj.tools };
216
- }
217
- function isNodeError(value) {
218
- return value instanceof Error && typeof value.code === "string";
219
- }
220
- function isProcessAlive(pid) {
221
- try {
222
- process.kill(pid, 0);
223
- return true;
224
- } catch {
225
- return false;
226
- }
227
- }
228
- var ToolboxFileLock = class {
229
- constructor(filePath, timeoutMs, retryMs) {
230
- this.acquired = false;
231
- this.dirPath = `${filePath}.lock`;
232
- this.pidFilePath = path2.join(this.dirPath, "pid");
233
- this.timeoutMs = timeoutMs;
234
- this.retryMs = retryMs;
235
- }
236
- async acquire() {
237
- const start = Date.now();
238
- while (true) {
239
- try {
240
- await fsp.mkdir(this.dirPath, { mode: LOCK_DIR_MODE });
241
- await fsp.writeFile(this.pidFilePath, String(process.pid), "utf8").catch(() => void 0);
242
- this.acquired = true;
243
- return;
244
- } catch (err) {
245
- if (!isNodeError(err) || err.code !== "EEXIST") throw err;
246
- const stale = await this.isStaleLock();
247
- if (stale) {
248
- await fsp.rm(this.dirPath, { recursive: true, force: true });
249
- continue;
250
- }
251
- if (Date.now() - start >= this.timeoutMs) {
252
- throw new Error(`ToolboxStore lock acquisition timed out for ${this.dirPath}`);
253
- }
254
- await delay(this.retryMs);
255
- }
256
- }
257
- }
258
- async isStaleLock() {
259
- let pidStr;
260
- try {
261
- pidStr = await fsp.readFile(this.pidFilePath, "utf8");
262
- } catch {
263
- try {
264
- const stat2 = await fsp.stat(this.dirPath);
265
- return Date.now() - stat2.mtimeMs > LOCK_STALE_GRACE_MS;
266
- } catch {
267
- return false;
268
- }
269
- }
270
- const pid = Number.parseInt(pidStr.trim(), 10);
271
- if (!Number.isFinite(pid) || pid <= 0) return true;
272
- return !isProcessAlive(pid);
273
- }
274
- async release() {
275
- if (!this.acquired) return;
276
- this.acquired = false;
277
- await fsp.rm(this.dirPath, { recursive: true, force: true });
278
- }
279
- };
280
- function defaultWorkspacePath() {
281
- if (process.env.SERVICEME_NO_WORKSPACE_TOOLBOX === "1") return null;
282
- return path2.join(process.cwd(), WORKSPACE_TOOLBOX_RELATIVE_PATH);
283
- }
284
- var ToolboxStore = class {
285
- constructor(opts = {}) {
286
- this.userFilePath = opts.userFilePath ?? getToolboxJsonPath();
287
- this.resolveWorkspacePath = opts.resolveWorkspacePath ?? defaultWorkspacePath;
288
- this.defaults = opts.defaultTools ?? BUILTIN_DEFAULT_TOOLS;
289
- this.hooks = opts.hooks ?? {};
290
- this.backend = opts.backend ?? new FsToolboxFileBackend();
291
- this.lockTimeoutMs = opts.lockTimeoutMs ?? DEFAULT_LOCK_TIMEOUT_MS;
292
- this.lockRetryMs = opts.lockRetryMs ?? DEFAULT_LOCK_RETRY_MS;
293
- }
294
- /** Read a scope; returns the resolved toolbox (with defaults merged when empty). */
295
- async read(scope) {
296
- const filePath = this.filePathFor(scope);
297
- if (scope === "workspace") {
298
- await migrateLegacyWorkspaceToolboxFile(filePath);
299
- }
300
- const stored = filePath ? await this.backend.read(filePath) : null;
301
- const storedTools = stored?.tools ?? [];
302
- const defaults = this.defaults.map((seed, index) => toDefaultTool(seed, index));
303
- const merged = mergeWithDefaults(defaults, storedTools);
304
- const userOnly = storedTools.filter((t) => !this.defaults.some((d) => d.id === t.id));
305
- void userOnly;
306
- return { scope, tools: merged };
307
- }
308
- /**
309
- * Atomic write under a file lock. Replaces the entire `tools` array
310
- * with the provided snapshot.
311
- */
312
- async write(scope, tools) {
313
- const filePath = this.filePathFor(scope);
314
- if (!filePath) {
315
- throw new Error(`Cannot write toolbox scope '${scope}': file path is unavailable`);
316
- }
317
- if (scope === "workspace") {
318
- await migrateLegacyWorkspaceToolboxFile(filePath);
319
- }
320
- const payload = {
321
- version: TOOLBOX_JSON_SCHEMA_VERSION,
322
- tools: sortByUserOrder([...tools])
323
- };
324
- await this.hooks.beforeWrite?.(scope, payload);
325
- const lock = new ToolboxFileLock(filePath, this.lockTimeoutMs, this.lockRetryMs);
326
- await lock.acquire();
327
- try {
328
- await this.backend.write(filePath, payload);
329
- } finally {
330
- await lock.release();
331
- }
332
- await this.hooks.afterWrite?.(scope, payload);
333
- }
334
- /**
335
- * Read-modify-write under the file lock. The mutator receives the
336
- * current user-only list (defaults not included) and returns the
337
- * replacement list. Throwing inside the mutator aborts the write.
338
- */
339
- async mutate(scope, mutator) {
340
- const filePath = this.filePathFor(scope);
341
- if (!filePath) {
342
- throw new Error(`Cannot mutate toolbox scope '${scope}': file path is unavailable`);
343
- }
344
- if (scope === "workspace") {
345
- await migrateLegacyWorkspaceToolboxFile(filePath);
346
- }
347
- const lock = new ToolboxFileLock(filePath, this.lockTimeoutMs, this.lockRetryMs);
348
- await lock.acquire();
349
- try {
350
- const stored = await this.backend.read(filePath);
351
- const storedTools = stored?.tools ?? [];
352
- const defaultIds = new Set(this.defaults.map((d) => d.id));
353
- const userTools = storedTools.filter((t) => !defaultIds.has(t.id));
354
- const next = await mutator(userTools);
355
- const payload = {
356
- version: TOOLBOX_JSON_SCHEMA_VERSION,
357
- tools: sortByUserOrder([...next])
358
- };
359
- await this.hooks.beforeWrite?.(scope, payload);
360
- await this.backend.write(filePath, payload);
361
- await this.hooks.afterWrite?.(scope, payload);
362
- return next;
363
- } finally {
364
- await lock.release();
365
- }
366
- }
367
- /** Wipe a scope entirely (used by `toolbox.remove --all` extensions). */
368
- async clear(scope) {
369
- const filePath = this.filePathFor(scope);
370
- if (!filePath) return;
371
- await fsp.rm(filePath, { force: true });
372
- }
373
- /** Test seam — resolve the user-scope file path. */
374
- getUserFilePath() {
375
- return this.userFilePath;
376
- }
377
- /** Test seam — resolve the workspace-scope file path (or null when disabled). */
378
- getWorkspaceFilePath() {
379
- return this.resolveWorkspacePath();
380
- }
381
- filePathFor(scope) {
382
- return scope === "user" ? this.userFilePath : this.resolveWorkspacePath();
383
- }
384
- };
385
- function toDefaultTool(seed, order) {
386
- return {
387
- id: seed.id,
388
- name: seed.name,
389
- description: seed.description,
390
- icon: seed.icon,
391
- url: seed.url,
392
- isDefault: true,
393
- order,
394
- scope: "user"
395
- };
396
- }
397
-
398
- // src/toolbox/ToolboxCore.ts
399
- var DefaultToolImmutableError = class extends Error {
400
- constructor(toolId) {
401
- super(`Cannot remove default toolbox entry: ${toolId}`);
402
- this.toolId = toolId;
403
- this.name = "DefaultToolImmutableError";
404
- }
405
- };
406
- var ToolboxCore = class {
407
- constructor(opts = {}) {
408
- this.store = opts.store ?? new ToolboxStore();
409
- this.defaults = opts.defaultTools ?? BUILTIN_DEFAULT_TOOLS;
410
- this.listSort = opts.listSort ?? sortByUserOrder;
411
- }
412
- /** List all tools in a scope. Built-in defaults are merged in. */
413
- async list(scope = "user") {
414
- const resolved = await this.store.read(scope);
415
- return {
416
- scope,
417
- tools: this.listSort(resolved.tools)
418
- };
419
- }
420
- /**
421
- * Append a new tool to the requested scope. Default tools are
422
- * rejected (they are seeds, not user entries).
423
- */
424
- async add(tool, scope = "user") {
425
- if (this.isDefaultId(tool.id)) {
426
- throw new DefaultToolImmutableError(tool.id);
427
- }
428
- const next = await this.store.mutate(scope, async (current) => {
429
- const filtered = current.filter((t) => t.id !== tool.id);
430
- return [
431
- ...filtered,
432
- {
433
- ...tool,
434
- scope,
435
- isDefault: false,
436
- order: tool.order ?? filtered.length
437
- }
438
- ];
439
- });
440
- return { scope, tools: next };
441
- }
442
- /**
443
- * Remove a tool by id. Returns `success: false` when the id is a
444
- * built-in default (idempotent, never throws on missing entries).
445
- */
446
- async remove(id, scope = "user") {
447
- if (this.isDefaultId(id)) {
448
- throw new DefaultToolImmutableError(id);
449
- }
450
- const removed = await this.store.mutate(
451
- scope,
452
- async (current) => current.filter((t) => t.id !== id)
453
- );
454
- return { scope, toolId: id, success: !removed.some((t) => t.id === id) };
455
- }
456
- /**
457
- * Patch a tool by id. Default tools can only have their `order`
458
- * updated; other patches are silently ignored for default entries
459
- * (callers can compare before/after to detect the ignore).
460
- */
461
- async update(id, patch, scope = "user") {
462
- const isDefault = this.isDefaultId(id);
463
- const next = await this.store.mutate(scope, async (current) => {
464
- if (isDefault) {
465
- return current;
466
- }
467
- return current.map(
468
- (tool) => tool.id === id ? { ...tool, ...patch, scope, isDefault: false } : tool
469
- );
470
- });
471
- return { scope, tools: next };
472
- }
473
- /**
474
- * Stamp `lastUsedAt` on the targeted tool. This is the "recently
475
- * used" hook the Extension's webview uses when a user clicks a
476
- * toolbox entry.
477
- */
478
- async recordUsage(id, scope = "user", when = /* @__PURE__ */ new Date()) {
479
- if (this.isDefaultId(id)) {
480
- const seed = this.defaults.find((d) => d.id === id);
481
- if (!seed) return null;
482
- return { ...seed, scope, isDefault: true, order: 0, lastUsedAt: when.toISOString() };
483
- }
484
- let updated = null;
485
- await this.store.mutate(scope, async (current) => {
486
- const next = touchLastUsedAt(current, id, when);
487
- updated = next.find((t) => t.id === id) ?? null;
488
- return next;
489
- });
490
- return updated;
491
- }
492
- /**
493
- * Combined view: user + workspace scopes merged, sorted by recent
494
- * usage. Workspace tools overlay user tools (workspace entries win
495
- * on `id` collision).
496
- */
497
- async listMerged() {
498
- const [user, workspace] = await Promise.all([
499
- this.store.read("user"),
500
- this.store.read("workspace")
501
- ]);
502
- const seen = /* @__PURE__ */ new Set();
503
- const merged = [];
504
- for (const tool of workspace.tools) {
505
- seen.add(tool.id);
506
- merged.push({ ...tool, scope: "workspace" });
507
- }
508
- for (const tool of user.tools) {
509
- if (seen.has(tool.id)) continue;
510
- merged.push({ ...tool, scope: "user" });
511
- }
512
- return { scope: "user", tools: sortByRecentFirst(merged) };
513
- }
514
- /** Expose the underlying store (CLI / Bridge use it for path-level access). */
515
- getStore() {
516
- return this.store;
517
- }
518
- isDefaultId(id) {
519
- return this.defaults.some((d) => d.id === id);
520
- }
521
- };
522
- export {
523
- BUILTIN_DEFAULT_TOOLS,
524
- DefaultToolImmutableError,
525
- FsToolboxFileBackend,
526
- TOOLBOX_JSON_SCHEMA_VERSION,
527
- ToolboxCore,
528
- ToolboxStore,
529
- WORKSPACE_TOOLBOX_RELATIVE_PATH,
530
- mergeWithDefaults,
531
- reindexOrder,
532
- sortByRecentFirst,
533
- sortByUserOrder,
534
- touchLastUsedAt
535
- };
536
- //# sourceMappingURL=toolbox.mjs.map
1
+ import { a as WORKSPACE_TOOLBOX_RELATIVE_PATH, c as mergeWithDefaults, d as sortByUserOrder, f as touchLastUsedAt, i as ToolboxStore, l as reindexOrder, n as ToolboxCore, o as BUILTIN_DEFAULT_TOOLS, r as FsToolboxFileBackend, s as TOOLBOX_JSON_SCHEMA_VERSION, t as DefaultToolImmutableError, u as sortByRecentFirst } from "./toolbox-CbfxpNg-.mjs";
2
+ export { BUILTIN_DEFAULT_TOOLS, DefaultToolImmutableError, FsToolboxFileBackend, TOOLBOX_JSON_SCHEMA_VERSION, ToolboxCore, ToolboxStore, WORKSPACE_TOOLBOX_RELATIVE_PATH, mergeWithDefaults, reindexOrder, sortByRecentFirst, sortByUserOrder, touchLastUsedAt };
@@ -1,3 +1,4 @@
1
+ //#region src/skill-store/types.d.ts
1
2
  /**
2
3
  * Skill & Agent v2 — SkillStore Types
3
4
  *
@@ -27,36 +28,37 @@
27
28
  type SkillKind = "skill" | "agent";
28
29
  /** Top-level summary of a discovered skill/agent entry. */
29
30
  interface SkillEntry {
30
- /** Repository the entry was found in. */
31
- repoId: string;
32
- /** Skill or agent name (the directory name under the repo). */
33
- name: string;
34
- kind: SkillKind;
35
- /** Absolute path to the SKILL.md / AGENT.md file. */
36
- manifestPath: string;
37
- /** Absolute path to the directory containing the entry's files. */
38
- dir: string;
39
- /** Parsed frontmatter (best-effort; raw key/value map). */
40
- frontmatter: Record<string, unknown>;
41
- /** ISO timestamp of the manifest file's mtime. */
42
- modifiedAt: string;
31
+ /** Repository the entry was found in. */
32
+ repoId: string;
33
+ /** Skill or agent name (the directory name under the repo). */
34
+ name: string;
35
+ kind: SkillKind;
36
+ /** Absolute path to the SKILL.md / AGENT.md file. */
37
+ manifestPath: string;
38
+ /** Absolute path to the directory containing the entry's files. */
39
+ dir: string;
40
+ /** Parsed frontmatter (best-effort; raw key/value map). */
41
+ frontmatter: Record<string, unknown>;
42
+ /** ISO timestamp of the manifest file's mtime. */
43
+ modifiedAt: string;
43
44
  }
44
45
  /** Full detail of an entry: summary + all the files inside the dir. */
45
46
  interface SkillDetail extends SkillEntry {
46
- files: SkillFile[];
47
+ files: SkillFile[];
47
48
  }
48
49
  /** A single file inside a skill / agent directory. */
49
50
  interface SkillFile {
50
- /** Path relative to the entry's directory. */
51
- path: string;
52
- /** UTF-8 content. */
53
- content: string;
51
+ /** Path relative to the entry's directory. */
52
+ path: string;
53
+ /** UTF-8 content. */
54
+ content: string;
54
55
  }
55
56
  /** Sentinel error for store lookups that miss. */
56
57
  declare class SkillNotFoundError extends Error {
57
- readonly repoId: string;
58
- readonly skillName: string;
59
- constructor(repoId: string, skillName: string);
58
+ readonly repoId: string;
59
+ readonly skillName: string;
60
+ constructor(repoId: string, skillName: string);
60
61
  }
61
-
62
- export { type SkillEntry as S, type SkillDetail as a, type SkillFile as b, type SkillKind as c, SkillNotFoundError as d };
62
+ //#endregion
63
+ export { SkillNotFoundError as a, SkillKind as i, SkillEntry as n, SkillFile as r, SkillDetail as t };
64
+ //# sourceMappingURL=types-BCV3IedE.d.mts.map
@@ -1,3 +1,4 @@
1
+ //#region src/skill-store/types.d.ts
1
2
  /**
2
3
  * Skill & Agent v2 — SkillStore Types
3
4
  *
@@ -27,36 +28,37 @@
27
28
  type SkillKind = "skill" | "agent";
28
29
  /** Top-level summary of a discovered skill/agent entry. */
29
30
  interface SkillEntry {
30
- /** Repository the entry was found in. */
31
- repoId: string;
32
- /** Skill or agent name (the directory name under the repo). */
33
- name: string;
34
- kind: SkillKind;
35
- /** Absolute path to the SKILL.md / AGENT.md file. */
36
- manifestPath: string;
37
- /** Absolute path to the directory containing the entry's files. */
38
- dir: string;
39
- /** Parsed frontmatter (best-effort; raw key/value map). */
40
- frontmatter: Record<string, unknown>;
41
- /** ISO timestamp of the manifest file's mtime. */
42
- modifiedAt: string;
31
+ /** Repository the entry was found in. */
32
+ repoId: string;
33
+ /** Skill or agent name (the directory name under the repo). */
34
+ name: string;
35
+ kind: SkillKind;
36
+ /** Absolute path to the SKILL.md / AGENT.md file. */
37
+ manifestPath: string;
38
+ /** Absolute path to the directory containing the entry's files. */
39
+ dir: string;
40
+ /** Parsed frontmatter (best-effort; raw key/value map). */
41
+ frontmatter: Record<string, unknown>;
42
+ /** ISO timestamp of the manifest file's mtime. */
43
+ modifiedAt: string;
43
44
  }
44
45
  /** Full detail of an entry: summary + all the files inside the dir. */
45
46
  interface SkillDetail extends SkillEntry {
46
- files: SkillFile[];
47
+ files: SkillFile[];
47
48
  }
48
49
  /** A single file inside a skill / agent directory. */
49
50
  interface SkillFile {
50
- /** Path relative to the entry's directory. */
51
- path: string;
52
- /** UTF-8 content. */
53
- content: string;
51
+ /** Path relative to the entry's directory. */
52
+ path: string;
53
+ /** UTF-8 content. */
54
+ content: string;
54
55
  }
55
56
  /** Sentinel error for store lookups that miss. */
56
57
  declare class SkillNotFoundError extends Error {
57
- readonly repoId: string;
58
- readonly skillName: string;
59
- constructor(repoId: string, skillName: string);
58
+ readonly repoId: string;
59
+ readonly skillName: string;
60
+ constructor(repoId: string, skillName: string);
60
61
  }
61
-
62
- export { type SkillEntry as S, type SkillDetail as a, type SkillFile as b, type SkillKind as c, SkillNotFoundError as d };
62
+ //#endregion
63
+ export { SkillNotFoundError as a, SkillKind as i, SkillEntry as n, SkillFile as r, SkillDetail as t };
64
+ //# sourceMappingURL=types-BCV3IedE.d.ts.map