@serviceme/devtools-core 2.0.2 → 2.0.4

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 (56) hide show
  1. package/dist/{device-CDDcwDY6.mjs → device-BVcUUQ9t.mjs} +54 -19
  2. package/dist/device-BVcUUQ9t.mjs.map +1 -0
  3. package/dist/device-DCo0rgUt.mjs +793 -0
  4. package/dist/device-DCo0rgUt.mjs.map +1 -0
  5. package/dist/{device-DuAYH8bk.js → device-ihxrFR-w.js} +52 -17
  6. package/dist/device-ihxrFR-w.js.map +1 -0
  7. package/dist/device-uFAQxlNt.js +874 -0
  8. package/dist/device-uFAQxlNt.js.map +1 -0
  9. package/dist/device-yWpY_Zds.js +874 -0
  10. package/dist/device-yWpY_Zds.js.map +1 -0
  11. package/dist/device.d.mts +1 -1
  12. package/dist/device.d.ts +1 -1
  13. package/dist/device.js +1 -1
  14. package/dist/device.mjs +1 -1
  15. package/dist/{index-BI11AfMH.d.ts → index-DGXYp8J5.d.mts} +30 -15
  16. package/dist/{index-BI11AfMH.d.mts → index-DGXYp8J5.d.ts} +30 -15
  17. package/dist/index.d.mts +13 -82
  18. package/dist/index.d.ts +13 -82
  19. package/dist/index.js +72 -138
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +74 -135
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/skill-linker.js +1 -1
  24. package/dist/skill-linker.mjs +1 -1
  25. package/dist/{submit-Cg7wSa3x.mjs → submit-6zQPPrOJ.mjs} +2 -2
  26. package/dist/{submit-Cg7wSa3x.mjs.map → submit-6zQPPrOJ.mjs.map} +1 -1
  27. package/dist/submit-BTdbGEAd.mjs +84 -0
  28. package/dist/submit-BTdbGEAd.mjs.map +1 -0
  29. package/dist/submit-CW9schoc.js +98 -0
  30. package/dist/submit-CW9schoc.js.map +1 -0
  31. package/dist/submit-Dy0KTHzm.js +98 -0
  32. package/dist/submit-Dy0KTHzm.js.map +1 -0
  33. package/dist/submit.js +1 -1
  34. package/dist/submit.mjs +1 -1
  35. package/dist/toolbox-BV7vLGXZ.js +614 -0
  36. package/dist/toolbox-BV7vLGXZ.js.map +1 -0
  37. package/dist/{toolbox-CbfxpNg-.mjs → toolbox-BxgnUyDU.mjs} +2 -2
  38. package/dist/{toolbox-CbfxpNg-.mjs.map → toolbox-BxgnUyDU.mjs.map} +1 -1
  39. package/dist/toolbox-GSWMRdts.js +614 -0
  40. package/dist/toolbox-GSWMRdts.js.map +1 -0
  41. package/dist/toolbox-UG4dA2TI.mjs +540 -0
  42. package/dist/toolbox-UG4dA2TI.mjs.map +1 -0
  43. package/dist/toolbox.js +1 -1
  44. package/dist/toolbox.mjs +1 -1
  45. package/dist/userHome-B97jBm5O.mjs +196 -0
  46. package/dist/userHome-B97jBm5O.mjs.map +1 -0
  47. package/dist/userHome-Baz205B7.js +498 -0
  48. package/dist/userHome-Baz205B7.js.map +1 -0
  49. package/dist/userHome-CLlsXCvW.js +518 -0
  50. package/dist/userHome-CLlsXCvW.js.map +1 -0
  51. package/dist/{userHome-CcnAQPG1.mjs → userHome-DOMLiHy7.mjs} +2 -4
  52. package/dist/userHome-DOMLiHy7.mjs.map +1 -0
  53. package/package.json +2 -2
  54. package/dist/device-CDDcwDY6.mjs.map +0 -1
  55. package/dist/device-DuAYH8bk.js.map +0 -1
  56. package/dist/userHome-CcnAQPG1.mjs.map +0 -1
@@ -0,0 +1,518 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.js");
2
+ let node_path = require("node:path");
3
+ node_path = require_rolldown_runtime.__toESM(node_path);
4
+ let node_os = require("node:os");
5
+ node_os = require_rolldown_runtime.__toESM(node_os);
6
+ //#region src/paths/userHome.ts
7
+ /**
8
+ * SERVICEME user home directory helpers.
9
+ *
10
+ * All paths resolve under {@link getServicemeHome}, which is either the
11
+ * `SERVICEME_HOME` environment variable (when set and non-empty) or
12
+ * `$HOME/.serviceme` on POSIX / `%USERPROFILE%\.serviceme` on Windows.
13
+ *
14
+ * Tests inject `homeDir` and `servicemeHomeEnv` overrides via
15
+ * {@link setUserHomeOverrides} / {@link resetUserHomeOverrides} so they can
16
+ * exercise the path logic without touching the real user environment.
17
+ */
18
+ /** Layout constants — kept in one place so other modules can reuse them. */
19
+ const SERVICEME_DIR_NAME = ".serviceme";
20
+ const REPOS_SUBDIR = "repos";
21
+ const CACHE_SUBDIR = "cache";
22
+ const DRAFTS_SUBDIR = "drafts";
23
+ const SKILL_DRAFTS_SUBDIR = "skills";
24
+ const AGENT_DRAFTS_SUBDIR = "agents";
25
+ const REPOS_CONFIG_FILENAME = "repos.json";
26
+ const WORKSPACES_SUBDIR = "workspaces";
27
+ const WORKSPACE_CONTENT_STATE_FILENAME = "copilot-content-state.json";
28
+ /**
29
+ * Repo id regex — used to validate any `repoId` argument before it is joined
30
+ * into a filesystem path. Keeps path traversal attempts out and gives us a
31
+ * predictable on-disk shape.
32
+ */
33
+ const SAFE_REPO_ID_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/;
34
+ /** Environment variable that overrides the user-home root directory. */
35
+ const SERVICEME_HOME_ENV = "SERVICEME_HOME";
36
+ let activeOverrides = {};
37
+ function setUserHomeOverrides(overrides) {
38
+ activeOverrides = { ...overrides };
39
+ }
40
+ function resetUserHomeOverrides() {
41
+ activeOverrides = {};
42
+ }
43
+ function resolveHomeDir() {
44
+ const injected = activeOverrides.homeDir;
45
+ if (injected !== void 0) return injected;
46
+ return node_os.homedir();
47
+ }
48
+ function resolveServicemeHomeEnv() {
49
+ const injected = activeOverrides.servicemeHomeEnv;
50
+ if (injected !== void 0) return injected.length > 0 ? injected : void 0;
51
+ const envValue = process.env[SERVICEME_HOME_ENV];
52
+ return envValue && envValue.length > 0 ? envValue : void 0;
53
+ }
54
+ function resolvePlatform() {
55
+ return activeOverrides.platform ?? process.platform;
56
+ }
57
+ function assertSafeRepoId(repoId) {
58
+ if (typeof repoId !== "string" || repoId.length === 0 || !SAFE_REPO_ID_PATTERN.test(repoId)) throw new Error(`Invalid repo id: ${JSON.stringify(repoId)}. Must match ${SAFE_REPO_ID_PATTERN} (alphanumeric start, then alphanumerics / underscores / hyphens, ≤ 64 chars).`);
59
+ return repoId;
60
+ }
61
+ /**
62
+ * The raw OS home directory (`os.homedir()`), honoring test overrides
63
+ * ({@link setUserHomeOverrides}). Exported for callers that need a
64
+ * home-relative path *outside* of `~/.serviceme` — e.g. the
65
+ * `~/.agents/{skills,agents}` convention used by `SkillLinker` for
66
+ * user-scope links.
67
+ */
68
+ function getHomeDir() {
69
+ return resolveHomeDir();
70
+ }
71
+ /**
72
+ * Root directory for all SERVICEME user-level state. Resolves to
73
+ * `${SERVICEME_HOME}` when that env var is set, otherwise `${HOME}/.serviceme`
74
+ * (POSIX) or `%USERPROFILE%\.serviceme` (Windows via `os.homedir`).
75
+ */
76
+ function getServicemeHome() {
77
+ const override = resolveServicemeHomeEnv();
78
+ if (override !== void 0) return node_path.resolve(override);
79
+ return node_path.join(resolveHomeDir(), SERVICEME_DIR_NAME);
80
+ }
81
+ /** `$HOME/.serviceme/repos` (or `${SERVICEME_HOME}/repos`). */
82
+ function getReposDir() {
83
+ return node_path.join(getServicemeHome(), REPOS_SUBDIR);
84
+ }
85
+ /** `$HOME/.serviceme/repos/<repoId>` — validates `repoId` first. */
86
+ function getRepoDir(repoId) {
87
+ return node_path.join(getReposDir(), assertSafeRepoId(repoId));
88
+ }
89
+ /** `$HOME/.serviceme/cache` — generic per-user cache. */
90
+ function getCacheDir() {
91
+ return node_path.join(getServicemeHome(), CACHE_SUBDIR);
92
+ }
93
+ /** `$HOME/.serviceme/cache/<repoId>` — per-repo sync state lives here. */
94
+ function getRepoCacheDir(repoId) {
95
+ return node_path.join(getCacheDir(), assertSafeRepoId(repoId));
96
+ }
97
+ /** `$HOME/.serviceme/drafts` — local edits not yet pushed upstream. */
98
+ function getDraftsDir() {
99
+ return node_path.join(getServicemeHome(), DRAFTS_SUBDIR);
100
+ }
101
+ /** `$HOME/.serviceme/drafts/skills` — local skill drafts. */
102
+ function getSkillDraftsDir() {
103
+ return node_path.join(getDraftsDir(), SKILL_DRAFTS_SUBDIR);
104
+ }
105
+ /** `$HOME/.serviceme/drafts/agents` — local agent drafts. */
106
+ function getAgentDraftsDir() {
107
+ return node_path.join(getDraftsDir(), AGENT_DRAFTS_SUBDIR);
108
+ }
109
+ /**
110
+ * `$HOME/.serviceme/repos.json` — the single config entry point for repo
111
+ * metadata. Always under the resolved home root (i.e. follows
112
+ * `SERVICEME_HOME` overrides too).
113
+ */
114
+ function getReposConfigPath() {
115
+ return node_path.join(getServicemeHome(), REPOS_CONFIG_FILENAME);
116
+ }
117
+ /** `~/.serviceme/workspaces` — machine-local per-workspace state root. */
118
+ function getWorkspacesDir() {
119
+ return node_path.join(getServicemeHome(), WORKSPACES_SUBDIR);
120
+ }
121
+ /**
122
+ * Convenience helper for callers that need to switch behaviour on platform
123
+ * (e.g. `SkillLinker` chooses symlink vs junction). Exported mostly so tests
124
+ * can pin the value without touching `process.platform` directly.
125
+ */
126
+ function getHomePlatform() {
127
+ return resolvePlatform();
128
+ }
129
+ /** Layout constants for scheduled-tasks files. Kept here so other modules
130
+ * can reuse them and the names stay in sync with the design doc. */
131
+ const SCHEDULED_TASKS_CONFIG_FILENAME = "scheduled-tasks.json";
132
+ const SCHEDULED_TASKS_LOG_FILENAME = "scheduled-tasks-log.json";
133
+ const SCHEDULER_PID_FILENAME = "scheduler.pid";
134
+ const SCHEDULER_LOCK_FILENAME = "scheduler.lock";
135
+ const SCHEDULER_LOG_FILENAME = "scheduler.log";
136
+ const MIGRATION_FAILURES_FILENAME = "migration-failures.json";
137
+ const KNOWN_WORKSPACES_FILENAME = "known-workspaces.json";
138
+ /** `~/.serviceme/scheduled-tasks.json` — the global v2 task list. */
139
+ function getScheduledTasksConfigPath() {
140
+ return node_path.join(getServicemeHome(), SCHEDULED_TASKS_CONFIG_FILENAME);
141
+ }
142
+ /** `~/.serviceme/scheduled-tasks-log.json` — the global execution log (200 LRU). */
143
+ function getScheduledTasksLogPath() {
144
+ return node_path.join(getServicemeHome(), SCHEDULED_TASKS_LOG_FILENAME);
145
+ }
146
+ /** `~/.serviceme/scheduler.pid` — global daemon PID file. */
147
+ function getSchedulerPidPath() {
148
+ return node_path.join(getServicemeHome(), SCHEDULER_PID_FILENAME);
149
+ }
150
+ /** `~/.serviceme/scheduler.lock` — global daemon startup flock. */
151
+ function getSchedulerLockPath() {
152
+ return node_path.join(getServicemeHome(), SCHEDULER_LOCK_FILENAME);
153
+ }
154
+ /** `~/.serviceme/scheduler.log` — global daemon log (daemon lifecycle, not task execution). */
155
+ function getSchedulerLogPath() {
156
+ return node_path.join(getServicemeHome(), SCHEDULER_LOG_FILENAME);
157
+ }
158
+ /** `~/.serviceme/migration-failures.json` — diagnostics for failed v1→v2 imports. */
159
+ function getMigrationFailuresPath() {
160
+ return node_path.join(getServicemeHome(), MIGRATION_FAILURES_FILENAME);
161
+ }
162
+ /** `~/.serviceme/known-workspaces.json` — workspace list the extension has seen. */
163
+ function getKnownWorkspacesPath() {
164
+ return node_path.join(getServicemeHome(), KNOWN_WORKSPACES_FILENAME);
165
+ }
166
+ /**
167
+ * `~/.serviceme/server-proxy.json` — r7 BYOM Server Proxy toggle
168
+ * self-state. Written by the extension's `ProxyConfigService`, readable
169
+ * by the CLI / Server so they can decide whether to route traffic
170
+ * through the corporate proxy without booting VS Code.
171
+ *
172
+ * Lives under user-level `~/.serviceme/` (not under a workspace) because
173
+ * the toggle is a *user preference* — the same human enabling it on
174
+ * machine A should be able to rely on it on machine B after sync, not
175
+ * have it disappear when they switch repos.
176
+ */
177
+ function getServerProxyGlobalPath() {
178
+ return node_path.join(getServicemeHome(), SERVER_PROXY_GLOBAL_FILENAME);
179
+ }
180
+ /** Layout constants for the Phase 5 client-side state files. The server
181
+ * already has the corresponding routes (`/api/v1/auth/...`,
182
+ * `/api/v1/device/...`, etc.) — the client just needs the on-disk
183
+ * file paths + a first-run bootstrap so the auth/device/toolbox
184
+ * services can open + read them without a per-call existence check. */
185
+ const CREDENTIALS_CONFIG_FILENAME = "credentials.json";
186
+ const DEVICE_JSON_FILENAME = "device.json";
187
+ const TOOLBOX_JSON_FILENAME = "toolbox.json";
188
+ const MACHINE_ID_FILENAME = "machine-id";
189
+ const PROFILES_JSON_FILENAME = "profiles.json";
190
+ /** `~/.serviceme/credentials.json` — better-auth session tokens + refresh state (client-side cache). */
191
+ function getCredentialsConfigPath() {
192
+ return node_path.join(getServicemeHome(), CREDENTIALS_CONFIG_FILENAME);
193
+ }
194
+ /** `~/.serviceme/device.json` — device enrollment payload (id, public key fingerprint, claimed-by). */
195
+ function getDeviceJsonPath() {
196
+ return node_path.join(getServicemeHome(), DEVICE_JSON_FILENAME);
197
+ }
198
+ /** `~/.serviceme/toolbox.json` — local toolbox state (installed tool refs, per-user prefs). */
199
+ function getToolboxJsonPath() {
200
+ return node_path.join(getServicemeHome(), TOOLBOX_JSON_FILENAME);
201
+ }
202
+ /** `~/.serviceme/machine-id` — opaque stable per-install id (uuid v4 string, no JSON wrapper). */
203
+ function getMachineIdPath() {
204
+ return node_path.join(getServicemeHome(), MACHINE_ID_FILENAME);
205
+ }
206
+ /** `~/.serviceme/profiles.json` — cached projection of server-side profile rows; refresh on demand. */
207
+ function getProfilesJsonPath() {
208
+ return node_path.join(getServicemeHome(), PROFILES_JSON_FILENAME);
209
+ }
210
+ //#endregion
211
+ Object.defineProperty(exports, "AGENT_DRAFTS_SUBDIR", {
212
+ enumerable: true,
213
+ get: function() {
214
+ return AGENT_DRAFTS_SUBDIR;
215
+ }
216
+ });
217
+ Object.defineProperty(exports, "CACHE_SUBDIR", {
218
+ enumerable: true,
219
+ get: function() {
220
+ return CACHE_SUBDIR;
221
+ }
222
+ });
223
+ Object.defineProperty(exports, "CREDENTIALS_CONFIG_FILENAME", {
224
+ enumerable: true,
225
+ get: function() {
226
+ return CREDENTIALS_CONFIG_FILENAME;
227
+ }
228
+ });
229
+ Object.defineProperty(exports, "DEVICE_JSON_FILENAME", {
230
+ enumerable: true,
231
+ get: function() {
232
+ return DEVICE_JSON_FILENAME;
233
+ }
234
+ });
235
+ Object.defineProperty(exports, "DRAFTS_SUBDIR", {
236
+ enumerable: true,
237
+ get: function() {
238
+ return DRAFTS_SUBDIR;
239
+ }
240
+ });
241
+ Object.defineProperty(exports, "KNOWN_WORKSPACES_FILENAME", {
242
+ enumerable: true,
243
+ get: function() {
244
+ return KNOWN_WORKSPACES_FILENAME;
245
+ }
246
+ });
247
+ Object.defineProperty(exports, "MACHINE_ID_FILENAME", {
248
+ enumerable: true,
249
+ get: function() {
250
+ return MACHINE_ID_FILENAME;
251
+ }
252
+ });
253
+ Object.defineProperty(exports, "MIGRATION_FAILURES_FILENAME", {
254
+ enumerable: true,
255
+ get: function() {
256
+ return MIGRATION_FAILURES_FILENAME;
257
+ }
258
+ });
259
+ Object.defineProperty(exports, "PROFILES_JSON_FILENAME", {
260
+ enumerable: true,
261
+ get: function() {
262
+ return PROFILES_JSON_FILENAME;
263
+ }
264
+ });
265
+ Object.defineProperty(exports, "REPOS_CONFIG_FILENAME", {
266
+ enumerable: true,
267
+ get: function() {
268
+ return REPOS_CONFIG_FILENAME;
269
+ }
270
+ });
271
+ Object.defineProperty(exports, "REPOS_SUBDIR", {
272
+ enumerable: true,
273
+ get: function() {
274
+ return REPOS_SUBDIR;
275
+ }
276
+ });
277
+ Object.defineProperty(exports, "SAFE_REPO_ID_PATTERN", {
278
+ enumerable: true,
279
+ get: function() {
280
+ return SAFE_REPO_ID_PATTERN;
281
+ }
282
+ });
283
+ Object.defineProperty(exports, "SCHEDULED_TASKS_CONFIG_FILENAME", {
284
+ enumerable: true,
285
+ get: function() {
286
+ return SCHEDULED_TASKS_CONFIG_FILENAME;
287
+ }
288
+ });
289
+ Object.defineProperty(exports, "SCHEDULED_TASKS_LOG_FILENAME", {
290
+ enumerable: true,
291
+ get: function() {
292
+ return SCHEDULED_TASKS_LOG_FILENAME;
293
+ }
294
+ });
295
+ Object.defineProperty(exports, "SCHEDULER_LOCK_FILENAME", {
296
+ enumerable: true,
297
+ get: function() {
298
+ return SCHEDULER_LOCK_FILENAME;
299
+ }
300
+ });
301
+ Object.defineProperty(exports, "SCHEDULER_LOG_FILENAME", {
302
+ enumerable: true,
303
+ get: function() {
304
+ return SCHEDULER_LOG_FILENAME;
305
+ }
306
+ });
307
+ Object.defineProperty(exports, "SCHEDULER_PID_FILENAME", {
308
+ enumerable: true,
309
+ get: function() {
310
+ return SCHEDULER_PID_FILENAME;
311
+ }
312
+ });
313
+ Object.defineProperty(exports, "SERVICEME_DIR_NAME", {
314
+ enumerable: true,
315
+ get: function() {
316
+ return SERVICEME_DIR_NAME;
317
+ }
318
+ });
319
+ Object.defineProperty(exports, "SERVICEME_HOME_ENV", {
320
+ enumerable: true,
321
+ get: function() {
322
+ return SERVICEME_HOME_ENV;
323
+ }
324
+ });
325
+ Object.defineProperty(exports, "SKILL_DRAFTS_SUBDIR", {
326
+ enumerable: true,
327
+ get: function() {
328
+ return SKILL_DRAFTS_SUBDIR;
329
+ }
330
+ });
331
+ Object.defineProperty(exports, "TOOLBOX_JSON_FILENAME", {
332
+ enumerable: true,
333
+ get: function() {
334
+ return TOOLBOX_JSON_FILENAME;
335
+ }
336
+ });
337
+ Object.defineProperty(exports, "WORKSPACES_SUBDIR", {
338
+ enumerable: true,
339
+ get: function() {
340
+ return WORKSPACES_SUBDIR;
341
+ }
342
+ });
343
+ Object.defineProperty(exports, "WORKSPACE_CONTENT_STATE_FILENAME", {
344
+ enumerable: true,
345
+ get: function() {
346
+ return WORKSPACE_CONTENT_STATE_FILENAME;
347
+ }
348
+ });
349
+ Object.defineProperty(exports, "assertSafeRepoId", {
350
+ enumerable: true,
351
+ get: function() {
352
+ return assertSafeRepoId;
353
+ }
354
+ });
355
+ Object.defineProperty(exports, "getAgentDraftsDir", {
356
+ enumerable: true,
357
+ get: function() {
358
+ return getAgentDraftsDir;
359
+ }
360
+ });
361
+ Object.defineProperty(exports, "getCacheDir", {
362
+ enumerable: true,
363
+ get: function() {
364
+ return getCacheDir;
365
+ }
366
+ });
367
+ Object.defineProperty(exports, "getCredentialsConfigPath", {
368
+ enumerable: true,
369
+ get: function() {
370
+ return getCredentialsConfigPath;
371
+ }
372
+ });
373
+ Object.defineProperty(exports, "getDeviceJsonPath", {
374
+ enumerable: true,
375
+ get: function() {
376
+ return getDeviceJsonPath;
377
+ }
378
+ });
379
+ Object.defineProperty(exports, "getDraftsDir", {
380
+ enumerable: true,
381
+ get: function() {
382
+ return getDraftsDir;
383
+ }
384
+ });
385
+ Object.defineProperty(exports, "getHomeDir", {
386
+ enumerable: true,
387
+ get: function() {
388
+ return getHomeDir;
389
+ }
390
+ });
391
+ Object.defineProperty(exports, "getHomePlatform", {
392
+ enumerable: true,
393
+ get: function() {
394
+ return getHomePlatform;
395
+ }
396
+ });
397
+ Object.defineProperty(exports, "getKnownWorkspacesPath", {
398
+ enumerable: true,
399
+ get: function() {
400
+ return getKnownWorkspacesPath;
401
+ }
402
+ });
403
+ Object.defineProperty(exports, "getMachineIdPath", {
404
+ enumerable: true,
405
+ get: function() {
406
+ return getMachineIdPath;
407
+ }
408
+ });
409
+ Object.defineProperty(exports, "getMigrationFailuresPath", {
410
+ enumerable: true,
411
+ get: function() {
412
+ return getMigrationFailuresPath;
413
+ }
414
+ });
415
+ Object.defineProperty(exports, "getProfilesJsonPath", {
416
+ enumerable: true,
417
+ get: function() {
418
+ return getProfilesJsonPath;
419
+ }
420
+ });
421
+ Object.defineProperty(exports, "getRepoCacheDir", {
422
+ enumerable: true,
423
+ get: function() {
424
+ return getRepoCacheDir;
425
+ }
426
+ });
427
+ Object.defineProperty(exports, "getRepoDir", {
428
+ enumerable: true,
429
+ get: function() {
430
+ return getRepoDir;
431
+ }
432
+ });
433
+ Object.defineProperty(exports, "getReposConfigPath", {
434
+ enumerable: true,
435
+ get: function() {
436
+ return getReposConfigPath;
437
+ }
438
+ });
439
+ Object.defineProperty(exports, "getReposDir", {
440
+ enumerable: true,
441
+ get: function() {
442
+ return getReposDir;
443
+ }
444
+ });
445
+ Object.defineProperty(exports, "getScheduledTasksConfigPath", {
446
+ enumerable: true,
447
+ get: function() {
448
+ return getScheduledTasksConfigPath;
449
+ }
450
+ });
451
+ Object.defineProperty(exports, "getScheduledTasksLogPath", {
452
+ enumerable: true,
453
+ get: function() {
454
+ return getScheduledTasksLogPath;
455
+ }
456
+ });
457
+ Object.defineProperty(exports, "getSchedulerLockPath", {
458
+ enumerable: true,
459
+ get: function() {
460
+ return getSchedulerLockPath;
461
+ }
462
+ });
463
+ Object.defineProperty(exports, "getSchedulerLogPath", {
464
+ enumerable: true,
465
+ get: function() {
466
+ return getSchedulerLogPath;
467
+ }
468
+ });
469
+ Object.defineProperty(exports, "getSchedulerPidPath", {
470
+ enumerable: true,
471
+ get: function() {
472
+ return getSchedulerPidPath;
473
+ }
474
+ });
475
+ Object.defineProperty(exports, "getServerProxyGlobalPath", {
476
+ enumerable: true,
477
+ get: function() {
478
+ return getServerProxyGlobalPath;
479
+ }
480
+ });
481
+ Object.defineProperty(exports, "getServicemeHome", {
482
+ enumerable: true,
483
+ get: function() {
484
+ return getServicemeHome;
485
+ }
486
+ });
487
+ Object.defineProperty(exports, "getSkillDraftsDir", {
488
+ enumerable: true,
489
+ get: function() {
490
+ return getSkillDraftsDir;
491
+ }
492
+ });
493
+ Object.defineProperty(exports, "getToolboxJsonPath", {
494
+ enumerable: true,
495
+ get: function() {
496
+ return getToolboxJsonPath;
497
+ }
498
+ });
499
+ Object.defineProperty(exports, "getWorkspacesDir", {
500
+ enumerable: true,
501
+ get: function() {
502
+ return getWorkspacesDir;
503
+ }
504
+ });
505
+ Object.defineProperty(exports, "resetUserHomeOverrides", {
506
+ enumerable: true,
507
+ get: function() {
508
+ return resetUserHomeOverrides;
509
+ }
510
+ });
511
+ Object.defineProperty(exports, "setUserHomeOverrides", {
512
+ enumerable: true,
513
+ get: function() {
514
+ return setUserHomeOverrides;
515
+ }
516
+ });
517
+
518
+ //# sourceMappingURL=userHome-CLlsXCvW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"userHome-CLlsXCvW.js","names":["os","path"],"sources":["../src/paths/userHome.ts"],"sourcesContent":["import * as os from \"node:os\";\nimport * as path from \"node:path\";\n\n/**\n * SERVICEME user home directory helpers.\n *\n * All paths resolve under {@link getServicemeHome}, which is either the\n * `SERVICEME_HOME` environment variable (when set and non-empty) or\n * `$HOME/.serviceme` on POSIX / `%USERPROFILE%\\.serviceme` on Windows.\n *\n * Tests inject `homeDir` and `servicemeHomeEnv` overrides via\n * {@link setUserHomeOverrides} / {@link resetUserHomeOverrides} so they can\n * exercise the path logic without touching the real user environment.\n */\n\n/** Layout constants — kept in one place so other modules can reuse them. */\nexport const SERVICEME_DIR_NAME = \".serviceme\";\nexport const REPOS_SUBDIR = \"repos\";\nexport const CACHE_SUBDIR = \"cache\";\nexport const DRAFTS_SUBDIR = \"drafts\";\nexport const SKILL_DRAFTS_SUBDIR = \"skills\";\nexport const AGENT_DRAFTS_SUBDIR = \"agents\";\nexport const REPOS_CONFIG_FILENAME = \"repos.json\";\nexport const WORKSPACES_SUBDIR = \"workspaces\";\nexport const WORKSPACE_CONTENT_STATE_FILENAME = \"copilot-content-state.json\";\n\n/**\n * Repo id regex — used to validate any `repoId` argument before it is joined\n * into a filesystem path. Keeps path traversal attempts out and gives us a\n * predictable on-disk shape.\n */\nexport const SAFE_REPO_ID_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/;\n\n/** Environment variable that overrides the user-home root directory. */\nexport const SERVICEME_HOME_ENV = \"SERVICEME_HOME\";\n\n/**\n * Test seam: lets unit tests inject deterministic values for `os.homedir()`\n * and the `SERVICEME_HOME` env override without actually mutating\n * `process.env` (which would leak into other tests).\n */\ninterface UserHomeOverrides {\n\thomeDir?: string | undefined;\n\tservicemeHomeEnv?: string | undefined;\n\tplatform?: NodeJS.Platform | undefined;\n}\n\nlet activeOverrides: UserHomeOverrides = {};\n\nexport function setUserHomeOverrides(overrides: UserHomeOverrides): void {\n\tactiveOverrides = { ...overrides };\n}\n\nexport function resetUserHomeOverrides(): void {\n\tactiveOverrides = {};\n}\n\nfunction resolveHomeDir(): string {\n\tconst injected = activeOverrides.homeDir;\n\tif (injected !== undefined) {\n\t\treturn injected;\n\t}\n\treturn os.homedir();\n}\n\nfunction resolveServicemeHomeEnv(): string | undefined {\n\tconst injected = activeOverrides.servicemeHomeEnv;\n\tif (injected !== undefined) {\n\t\t// Treat empty string as \"not set\" — `process.env` always returns a string\n\t\t// but tests may deliberately pass \"\" to opt out.\n\t\treturn injected.length > 0 ? injected : undefined;\n\t}\n\tconst envValue = process.env[SERVICEME_HOME_ENV];\n\treturn envValue && envValue.length > 0 ? envValue : undefined;\n}\n\nfunction resolvePlatform(): NodeJS.Platform {\n\treturn activeOverrides.platform ?? process.platform;\n}\n\nexport function assertSafeRepoId(repoId: string): string {\n\tif (typeof repoId !== \"string\" || repoId.length === 0 || !SAFE_REPO_ID_PATTERN.test(repoId)) {\n\t\tthrow new Error(\n\t\t\t`Invalid repo id: ${JSON.stringify(repoId)}. ` +\n\t\t\t\t`Must match ${SAFE_REPO_ID_PATTERN} (alphanumeric start, then ` +\n\t\t\t\t`alphanumerics / underscores / hyphens, ≤ 64 chars).`\n\t\t);\n\t}\n\treturn repoId;\n}\n\n/**\n * The raw OS home directory (`os.homedir()`), honoring test overrides\n * ({@link setUserHomeOverrides}). Exported for callers that need a\n * home-relative path *outside* of `~/.serviceme` — e.g. the\n * `~/.agents/{skills,agents}` convention used by `SkillLinker` for\n * user-scope links.\n */\nexport function getHomeDir(): string {\n\treturn resolveHomeDir();\n}\n\n/**\n * Root directory for all SERVICEME user-level state. Resolves to\n * `${SERVICEME_HOME}` when that env var is set, otherwise `${HOME}/.serviceme`\n * (POSIX) or `%USERPROFILE%\\.serviceme` (Windows via `os.homedir`).\n */\nexport function getServicemeHome(): string {\n\tconst override = resolveServicemeHomeEnv();\n\tif (override !== undefined) {\n\t\treturn path.resolve(override);\n\t}\n\treturn path.join(resolveHomeDir(), SERVICEME_DIR_NAME);\n}\n\n/** `$HOME/.serviceme/repos` (or `${SERVICEME_HOME}/repos`). */\nexport function getReposDir(): string {\n\treturn path.join(getServicemeHome(), REPOS_SUBDIR);\n}\n\n/** `$HOME/.serviceme/repos/<repoId>` — validates `repoId` first. */\nexport function getRepoDir(repoId: string): string {\n\treturn path.join(getReposDir(), assertSafeRepoId(repoId));\n}\n\n/** `$HOME/.serviceme/cache` — generic per-user cache. */\nexport function getCacheDir(): string {\n\treturn path.join(getServicemeHome(), CACHE_SUBDIR);\n}\n\n/** `$HOME/.serviceme/cache/<repoId>` — per-repo sync state lives here. */\nexport function getRepoCacheDir(repoId: string): string {\n\treturn path.join(getCacheDir(), assertSafeRepoId(repoId));\n}\n\n/** `$HOME/.serviceme/drafts` — local edits not yet pushed upstream. */\nexport function getDraftsDir(): string {\n\treturn path.join(getServicemeHome(), DRAFTS_SUBDIR);\n}\n\n/** `$HOME/.serviceme/drafts/skills` — local skill drafts. */\nexport function getSkillDraftsDir(): string {\n\treturn path.join(getDraftsDir(), SKILL_DRAFTS_SUBDIR);\n}\n\n/** `$HOME/.serviceme/drafts/agents` — local agent drafts. */\nexport function getAgentDraftsDir(): string {\n\treturn path.join(getDraftsDir(), AGENT_DRAFTS_SUBDIR);\n}\n\n/**\n * `$HOME/.serviceme/repos.json` — the single config entry point for repo\n * metadata. Always under the resolved home root (i.e. follows\n * `SERVICEME_HOME` overrides too).\n */\nexport function getReposConfigPath(): string {\n\treturn path.join(getServicemeHome(), REPOS_CONFIG_FILENAME);\n}\n\n/** `~/.serviceme/workspaces` — machine-local per-workspace state root. */\nexport function getWorkspacesDir(): string {\n\treturn path.join(getServicemeHome(), WORKSPACES_SUBDIR);\n}\n\n/**\n * Convenience helper for callers that need to switch behaviour on platform\n * (e.g. `SkillLinker` chooses symlink vs junction). Exported mostly so tests\n * can pin the value without touching `process.platform` directly.\n */\nexport function getHomePlatform(): NodeJS.Platform {\n\treturn resolvePlatform();\n}\n\n// ─── Scheduled Tasks paths (added by M1.5.3) ───────────────────────────────\n\n/** Layout constants for scheduled-tasks files. Kept here so other modules\n * can reuse them and the names stay in sync with the design doc. */\nexport const SCHEDULED_TASKS_CONFIG_FILENAME = \"scheduled-tasks.json\";\nexport const SCHEDULED_TASKS_LOG_FILENAME = \"scheduled-tasks-log.json\";\nexport const SCHEDULER_PID_FILENAME = \"scheduler.pid\";\nexport const SCHEDULER_LOCK_FILENAME = \"scheduler.lock\";\nexport const SCHEDULER_LOG_FILENAME = \"scheduler.log\";\nexport const MIGRATION_FAILURES_FILENAME = \"migration-failures.json\";\nexport const KNOWN_WORKSPACES_FILENAME = \"known-workspaces.json\";\n\n/** `~/.serviceme/scheduled-tasks.json` — the global v2 task list. */\nexport function getScheduledTasksConfigPath(): string {\n\treturn path.join(getServicemeHome(), SCHEDULED_TASKS_CONFIG_FILENAME);\n}\n\n/** `~/.serviceme/scheduled-tasks-log.json` — the global execution log (200 LRU). */\nexport function getScheduledTasksLogPath(): string {\n\treturn path.join(getServicemeHome(), SCHEDULED_TASKS_LOG_FILENAME);\n}\n\n/** `~/.serviceme/scheduler.pid` — global daemon PID file. */\nexport function getSchedulerPidPath(): string {\n\treturn path.join(getServicemeHome(), SCHEDULER_PID_FILENAME);\n}\n\n/** `~/.serviceme/scheduler.lock` — global daemon startup flock. */\nexport function getSchedulerLockPath(): string {\n\treturn path.join(getServicemeHome(), SCHEDULER_LOCK_FILENAME);\n}\n\n/** `~/.serviceme/scheduler.log` — global daemon log (daemon lifecycle, not task execution). */\nexport function getSchedulerLogPath(): string {\n\treturn path.join(getServicemeHome(), SCHEDULER_LOG_FILENAME);\n}\n\n/** `~/.serviceme/migration-failures.json` — diagnostics for failed v1→v2 imports. */\nexport function getMigrationFailuresPath(): string {\n\treturn path.join(getServicemeHome(), MIGRATION_FAILURES_FILENAME);\n}\n\n/** `~/.serviceme/known-workspaces.json` — workspace list the extension has seen. */\nexport function getKnownWorkspacesPath(): string {\n\treturn path.join(getServicemeHome(), KNOWN_WORKSPACES_FILENAME);\n}\n\n// ─── r7 BYOM Server Proxy (rev.20) ─────────────────────────────────────────\n\n/**\n * `~/.serviceme/server-proxy.json` — r7 BYOM Server Proxy toggle\n * self-state. Written by the extension's `ProxyConfigService`, readable\n * by the CLI / Server so they can decide whether to route traffic\n * through the corporate proxy without booting VS Code.\n *\n * Lives under user-level `~/.serviceme/` (not under a workspace) because\n * the toggle is a *user preference* — the same human enabling it on\n * machine A should be able to rely on it on machine B after sync, not\n * have it disappear when they switch repos.\n */\nexport function getServerProxyGlobalPath(): string {\n\treturn path.join(getServicemeHome(), SERVER_PROXY_GLOBAL_FILENAME);\n}\n\n// ─── Phase 5 (auth + device + toolbox) placeholders (Spec §11.12) ────────\n\n/** Layout constants for the Phase 5 client-side state files. The server\n * already has the corresponding routes (`/api/v1/auth/...`,\n * `/api/v1/device/...`, etc.) — the client just needs the on-disk\n * file paths + a first-run bootstrap so the auth/device/toolbox\n * services can open + read them without a per-call existence check. */\nexport const CREDENTIALS_CONFIG_FILENAME = \"credentials.json\";\nexport const DEVICE_JSON_FILENAME = \"device.json\";\nexport const TOOLBOX_JSON_FILENAME = \"toolbox.json\";\nexport const MACHINE_ID_FILENAME = \"machine-id\";\nexport const PROFILES_JSON_FILENAME = \"profiles.json\";\n\n/** `~/.serviceme/credentials.json` — better-auth session tokens + refresh state (client-side cache). */\nexport function getCredentialsConfigPath(): string {\n\treturn path.join(getServicemeHome(), CREDENTIALS_CONFIG_FILENAME);\n}\n\n/** `~/.serviceme/device.json` — device enrollment payload (id, public key fingerprint, claimed-by). */\nexport function getDeviceJsonPath(): string {\n\treturn path.join(getServicemeHome(), DEVICE_JSON_FILENAME);\n}\n\n/** `~/.serviceme/toolbox.json` — local toolbox state (installed tool refs, per-user prefs). */\nexport function getToolboxJsonPath(): string {\n\treturn path.join(getServicemeHome(), TOOLBOX_JSON_FILENAME);\n}\n\n/** `~/.serviceme/machine-id` — opaque stable per-install id (uuid v4 string, no JSON wrapper). */\nexport function getMachineIdPath(): string {\n\treturn path.join(getServicemeHome(), MACHINE_ID_FILENAME);\n}\n\n/** `~/.serviceme/profiles.json` — cached projection of server-side profile rows; refresh on demand. */\nexport function getProfilesJsonPath(): string {\n\treturn path.join(getServicemeHome(), PROFILES_JSON_FILENAME);\n}\n"],"mappings":"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"}
@@ -22,8 +22,6 @@ const AGENT_DRAFTS_SUBDIR = "agents";
22
22
  const REPOS_CONFIG_FILENAME = "repos.json";
23
23
  const WORKSPACES_SUBDIR = "workspaces";
24
24
  const WORKSPACE_CONTENT_STATE_FILENAME = "copilot-content-state.json";
25
- /** rev.20 — r7 BYOM Server Proxy toggle self-state (read by ext + CLI + server). */
26
- const SERVER_PROXY_GLOBAL_FILENAME = "server-proxy.json";
27
25
  /**
28
26
  * Repo id regex — used to validate any `repoId` argument before it is joined
29
27
  * into a filesystem path. Keeps path traversal attempts out and gives us a
@@ -207,6 +205,6 @@ function getProfilesJsonPath() {
207
205
  return path.join(getServicemeHome(), PROFILES_JSON_FILENAME);
208
206
  }
209
207
  //#endregion
210
- export { getDraftsDir as A, getReposDir as B, WORKSPACES_SUBDIR as C, getCacheDir as D, getAgentDraftsDir as E, getMigrationFailuresPath as F, getSchedulerPidPath as G, getScheduledTasksLogPath as H, getProfilesJsonPath as I, getSkillDraftsDir as J, getServerProxyGlobalPath as K, getRepoCacheDir as L, getHomePlatform as M, getKnownWorkspacesPath as N, getCredentialsConfigPath as O, getMachineIdPath as P, setUserHomeOverrides as Q, getRepoDir as R, TOOLBOX_JSON_FILENAME as S, assertSafeRepoId as T, getSchedulerLockPath as U, getScheduledTasksConfigPath as V, getSchedulerLogPath as W, getWorkspacesDir as X, getToolboxJsonPath as Y, resetUserHomeOverrides as Z, SCHEDULER_PID_FILENAME as _, DRAFTS_SUBDIR as a, SERVICEME_HOME_ENV as b, MIGRATION_FAILURES_FILENAME as c, REPOS_SUBDIR as d, SAFE_REPO_ID_PATTERN as f, SCHEDULER_LOG_FILENAME as g, SCHEDULER_LOCK_FILENAME as h, DEVICE_JSON_FILENAME as i, getHomeDir as j, getDeviceJsonPath as k, PROFILES_JSON_FILENAME as l, SCHEDULED_TASKS_LOG_FILENAME as m, CACHE_SUBDIR as n, KNOWN_WORKSPACES_FILENAME as o, SCHEDULED_TASKS_CONFIG_FILENAME as p, getServicemeHome as q, CREDENTIALS_CONFIG_FILENAME as r, MACHINE_ID_FILENAME as s, AGENT_DRAFTS_SUBDIR as t, REPOS_CONFIG_FILENAME as u, SERVER_PROXY_GLOBAL_FILENAME as v, WORKSPACE_CONTENT_STATE_FILENAME as w, SKILL_DRAFTS_SUBDIR as x, SERVICEME_DIR_NAME as y, getReposConfigPath as z };
208
+ export { getHomeDir as A, getScheduledTasksConfigPath as B, WORKSPACE_CONTENT_STATE_FILENAME as C, getCredentialsConfigPath as D, getCacheDir as E, getProfilesJsonPath as F, getServerProxyGlobalPath as G, getSchedulerLockPath as H, getRepoCacheDir as I, getToolboxJsonPath as J, getServicemeHome as K, getRepoDir as L, getKnownWorkspacesPath as M, getMachineIdPath as N, getDeviceJsonPath as O, getMigrationFailuresPath as P, getReposConfigPath as R, WORKSPACES_SUBDIR as S, getAgentDraftsDir as T, getSchedulerLogPath as U, getScheduledTasksLogPath as V, getSchedulerPidPath as W, resetUserHomeOverrides as X, getWorkspacesDir as Y, setUserHomeOverrides as Z, SCHEDULER_PID_FILENAME as _, DRAFTS_SUBDIR as a, SKILL_DRAFTS_SUBDIR as b, MIGRATION_FAILURES_FILENAME as c, REPOS_SUBDIR as d, SAFE_REPO_ID_PATTERN as f, SCHEDULER_LOG_FILENAME as g, SCHEDULER_LOCK_FILENAME as h, DEVICE_JSON_FILENAME as i, getHomePlatform as j, getDraftsDir as k, PROFILES_JSON_FILENAME as l, SCHEDULED_TASKS_LOG_FILENAME as m, CACHE_SUBDIR as n, KNOWN_WORKSPACES_FILENAME as o, SCHEDULED_TASKS_CONFIG_FILENAME as p, getSkillDraftsDir as q, CREDENTIALS_CONFIG_FILENAME as r, MACHINE_ID_FILENAME as s, AGENT_DRAFTS_SUBDIR as t, REPOS_CONFIG_FILENAME as u, SERVICEME_DIR_NAME as v, assertSafeRepoId as w, TOOLBOX_JSON_FILENAME as x, SERVICEME_HOME_ENV as y, getReposDir as z };
211
209
 
212
- //# sourceMappingURL=userHome-CcnAQPG1.mjs.map
210
+ //# sourceMappingURL=userHome-DOMLiHy7.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"userHome-DOMLiHy7.mjs","names":[],"sources":["../src/paths/userHome.ts"],"sourcesContent":["import * as os from \"node:os\";\nimport * as path from \"node:path\";\n\n/**\n * SERVICEME user home directory helpers.\n *\n * All paths resolve under {@link getServicemeHome}, which is either the\n * `SERVICEME_HOME` environment variable (when set and non-empty) or\n * `$HOME/.serviceme` on POSIX / `%USERPROFILE%\\.serviceme` on Windows.\n *\n * Tests inject `homeDir` and `servicemeHomeEnv` overrides via\n * {@link setUserHomeOverrides} / {@link resetUserHomeOverrides} so they can\n * exercise the path logic without touching the real user environment.\n */\n\n/** Layout constants — kept in one place so other modules can reuse them. */\nexport const SERVICEME_DIR_NAME = \".serviceme\";\nexport const REPOS_SUBDIR = \"repos\";\nexport const CACHE_SUBDIR = \"cache\";\nexport const DRAFTS_SUBDIR = \"drafts\";\nexport const SKILL_DRAFTS_SUBDIR = \"skills\";\nexport const AGENT_DRAFTS_SUBDIR = \"agents\";\nexport const REPOS_CONFIG_FILENAME = \"repos.json\";\nexport const WORKSPACES_SUBDIR = \"workspaces\";\nexport const WORKSPACE_CONTENT_STATE_FILENAME = \"copilot-content-state.json\";\n\n/**\n * Repo id regex — used to validate any `repoId` argument before it is joined\n * into a filesystem path. Keeps path traversal attempts out and gives us a\n * predictable on-disk shape.\n */\nexport const SAFE_REPO_ID_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/;\n\n/** Environment variable that overrides the user-home root directory. */\nexport const SERVICEME_HOME_ENV = \"SERVICEME_HOME\";\n\n/**\n * Test seam: lets unit tests inject deterministic values for `os.homedir()`\n * and the `SERVICEME_HOME` env override without actually mutating\n * `process.env` (which would leak into other tests).\n */\ninterface UserHomeOverrides {\n\thomeDir?: string | undefined;\n\tservicemeHomeEnv?: string | undefined;\n\tplatform?: NodeJS.Platform | undefined;\n}\n\nlet activeOverrides: UserHomeOverrides = {};\n\nexport function setUserHomeOverrides(overrides: UserHomeOverrides): void {\n\tactiveOverrides = { ...overrides };\n}\n\nexport function resetUserHomeOverrides(): void {\n\tactiveOverrides = {};\n}\n\nfunction resolveHomeDir(): string {\n\tconst injected = activeOverrides.homeDir;\n\tif (injected !== undefined) {\n\t\treturn injected;\n\t}\n\treturn os.homedir();\n}\n\nfunction resolveServicemeHomeEnv(): string | undefined {\n\tconst injected = activeOverrides.servicemeHomeEnv;\n\tif (injected !== undefined) {\n\t\t// Treat empty string as \"not set\" — `process.env` always returns a string\n\t\t// but tests may deliberately pass \"\" to opt out.\n\t\treturn injected.length > 0 ? injected : undefined;\n\t}\n\tconst envValue = process.env[SERVICEME_HOME_ENV];\n\treturn envValue && envValue.length > 0 ? envValue : undefined;\n}\n\nfunction resolvePlatform(): NodeJS.Platform {\n\treturn activeOverrides.platform ?? process.platform;\n}\n\nexport function assertSafeRepoId(repoId: string): string {\n\tif (typeof repoId !== \"string\" || repoId.length === 0 || !SAFE_REPO_ID_PATTERN.test(repoId)) {\n\t\tthrow new Error(\n\t\t\t`Invalid repo id: ${JSON.stringify(repoId)}. ` +\n\t\t\t\t`Must match ${SAFE_REPO_ID_PATTERN} (alphanumeric start, then ` +\n\t\t\t\t`alphanumerics / underscores / hyphens, ≤ 64 chars).`\n\t\t);\n\t}\n\treturn repoId;\n}\n\n/**\n * The raw OS home directory (`os.homedir()`), honoring test overrides\n * ({@link setUserHomeOverrides}). Exported for callers that need a\n * home-relative path *outside* of `~/.serviceme` — e.g. the\n * `~/.agents/{skills,agents}` convention used by `SkillLinker` for\n * user-scope links.\n */\nexport function getHomeDir(): string {\n\treturn resolveHomeDir();\n}\n\n/**\n * Root directory for all SERVICEME user-level state. Resolves to\n * `${SERVICEME_HOME}` when that env var is set, otherwise `${HOME}/.serviceme`\n * (POSIX) or `%USERPROFILE%\\.serviceme` (Windows via `os.homedir`).\n */\nexport function getServicemeHome(): string {\n\tconst override = resolveServicemeHomeEnv();\n\tif (override !== undefined) {\n\t\treturn path.resolve(override);\n\t}\n\treturn path.join(resolveHomeDir(), SERVICEME_DIR_NAME);\n}\n\n/** `$HOME/.serviceme/repos` (or `${SERVICEME_HOME}/repos`). */\nexport function getReposDir(): string {\n\treturn path.join(getServicemeHome(), REPOS_SUBDIR);\n}\n\n/** `$HOME/.serviceme/repos/<repoId>` — validates `repoId` first. */\nexport function getRepoDir(repoId: string): string {\n\treturn path.join(getReposDir(), assertSafeRepoId(repoId));\n}\n\n/** `$HOME/.serviceme/cache` — generic per-user cache. */\nexport function getCacheDir(): string {\n\treturn path.join(getServicemeHome(), CACHE_SUBDIR);\n}\n\n/** `$HOME/.serviceme/cache/<repoId>` — per-repo sync state lives here. */\nexport function getRepoCacheDir(repoId: string): string {\n\treturn path.join(getCacheDir(), assertSafeRepoId(repoId));\n}\n\n/** `$HOME/.serviceme/drafts` — local edits not yet pushed upstream. */\nexport function getDraftsDir(): string {\n\treturn path.join(getServicemeHome(), DRAFTS_SUBDIR);\n}\n\n/** `$HOME/.serviceme/drafts/skills` — local skill drafts. */\nexport function getSkillDraftsDir(): string {\n\treturn path.join(getDraftsDir(), SKILL_DRAFTS_SUBDIR);\n}\n\n/** `$HOME/.serviceme/drafts/agents` — local agent drafts. */\nexport function getAgentDraftsDir(): string {\n\treturn path.join(getDraftsDir(), AGENT_DRAFTS_SUBDIR);\n}\n\n/**\n * `$HOME/.serviceme/repos.json` — the single config entry point for repo\n * metadata. Always under the resolved home root (i.e. follows\n * `SERVICEME_HOME` overrides too).\n */\nexport function getReposConfigPath(): string {\n\treturn path.join(getServicemeHome(), REPOS_CONFIG_FILENAME);\n}\n\n/** `~/.serviceme/workspaces` — machine-local per-workspace state root. */\nexport function getWorkspacesDir(): string {\n\treturn path.join(getServicemeHome(), WORKSPACES_SUBDIR);\n}\n\n/**\n * Convenience helper for callers that need to switch behaviour on platform\n * (e.g. `SkillLinker` chooses symlink vs junction). Exported mostly so tests\n * can pin the value without touching `process.platform` directly.\n */\nexport function getHomePlatform(): NodeJS.Platform {\n\treturn resolvePlatform();\n}\n\n// ─── Scheduled Tasks paths (added by M1.5.3) ───────────────────────────────\n\n/** Layout constants for scheduled-tasks files. Kept here so other modules\n * can reuse them and the names stay in sync with the design doc. */\nexport const SCHEDULED_TASKS_CONFIG_FILENAME = \"scheduled-tasks.json\";\nexport const SCHEDULED_TASKS_LOG_FILENAME = \"scheduled-tasks-log.json\";\nexport const SCHEDULER_PID_FILENAME = \"scheduler.pid\";\nexport const SCHEDULER_LOCK_FILENAME = \"scheduler.lock\";\nexport const SCHEDULER_LOG_FILENAME = \"scheduler.log\";\nexport const MIGRATION_FAILURES_FILENAME = \"migration-failures.json\";\nexport const KNOWN_WORKSPACES_FILENAME = \"known-workspaces.json\";\n\n/** `~/.serviceme/scheduled-tasks.json` — the global v2 task list. */\nexport function getScheduledTasksConfigPath(): string {\n\treturn path.join(getServicemeHome(), SCHEDULED_TASKS_CONFIG_FILENAME);\n}\n\n/** `~/.serviceme/scheduled-tasks-log.json` — the global execution log (200 LRU). */\nexport function getScheduledTasksLogPath(): string {\n\treturn path.join(getServicemeHome(), SCHEDULED_TASKS_LOG_FILENAME);\n}\n\n/** `~/.serviceme/scheduler.pid` — global daemon PID file. */\nexport function getSchedulerPidPath(): string {\n\treturn path.join(getServicemeHome(), SCHEDULER_PID_FILENAME);\n}\n\n/** `~/.serviceme/scheduler.lock` — global daemon startup flock. */\nexport function getSchedulerLockPath(): string {\n\treturn path.join(getServicemeHome(), SCHEDULER_LOCK_FILENAME);\n}\n\n/** `~/.serviceme/scheduler.log` — global daemon log (daemon lifecycle, not task execution). */\nexport function getSchedulerLogPath(): string {\n\treturn path.join(getServicemeHome(), SCHEDULER_LOG_FILENAME);\n}\n\n/** `~/.serviceme/migration-failures.json` — diagnostics for failed v1→v2 imports. */\nexport function getMigrationFailuresPath(): string {\n\treturn path.join(getServicemeHome(), MIGRATION_FAILURES_FILENAME);\n}\n\n/** `~/.serviceme/known-workspaces.json` — workspace list the extension has seen. */\nexport function getKnownWorkspacesPath(): string {\n\treturn path.join(getServicemeHome(), KNOWN_WORKSPACES_FILENAME);\n}\n\n// ─── r7 BYOM Server Proxy (rev.20) ─────────────────────────────────────────\n\n/**\n * `~/.serviceme/server-proxy.json` — r7 BYOM Server Proxy toggle\n * self-state. Written by the extension's `ProxyConfigService`, readable\n * by the CLI / Server so they can decide whether to route traffic\n * through the corporate proxy without booting VS Code.\n *\n * Lives under user-level `~/.serviceme/` (not under a workspace) because\n * the toggle is a *user preference* — the same human enabling it on\n * machine A should be able to rely on it on machine B after sync, not\n * have it disappear when they switch repos.\n */\nexport function getServerProxyGlobalPath(): string {\n\treturn path.join(getServicemeHome(), SERVER_PROXY_GLOBAL_FILENAME);\n}\n\n// ─── Phase 5 (auth + device + toolbox) placeholders (Spec §11.12) ────────\n\n/** Layout constants for the Phase 5 client-side state files. The server\n * already has the corresponding routes (`/api/v1/auth/...`,\n * `/api/v1/device/...`, etc.) — the client just needs the on-disk\n * file paths + a first-run bootstrap so the auth/device/toolbox\n * services can open + read them without a per-call existence check. */\nexport const CREDENTIALS_CONFIG_FILENAME = \"credentials.json\";\nexport const DEVICE_JSON_FILENAME = \"device.json\";\nexport const TOOLBOX_JSON_FILENAME = \"toolbox.json\";\nexport const MACHINE_ID_FILENAME = \"machine-id\";\nexport const PROFILES_JSON_FILENAME = \"profiles.json\";\n\n/** `~/.serviceme/credentials.json` — better-auth session tokens + refresh state (client-side cache). */\nexport function getCredentialsConfigPath(): string {\n\treturn path.join(getServicemeHome(), CREDENTIALS_CONFIG_FILENAME);\n}\n\n/** `~/.serviceme/device.json` — device enrollment payload (id, public key fingerprint, claimed-by). */\nexport function getDeviceJsonPath(): string {\n\treturn path.join(getServicemeHome(), DEVICE_JSON_FILENAME);\n}\n\n/** `~/.serviceme/toolbox.json` — local toolbox state (installed tool refs, per-user prefs). */\nexport function getToolboxJsonPath(): string {\n\treturn path.join(getServicemeHome(), TOOLBOX_JSON_FILENAME);\n}\n\n/** `~/.serviceme/machine-id` — opaque stable per-install id (uuid v4 string, no JSON wrapper). */\nexport function getMachineIdPath(): string {\n\treturn path.join(getServicemeHome(), MACHINE_ID_FILENAME);\n}\n\n/** `~/.serviceme/profiles.json` — cached projection of server-side profile rows; refresh on demand. */\nexport function getProfilesJsonPath(): string {\n\treturn path.join(getServicemeHome(), PROFILES_JSON_FILENAME);\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serviceme/devtools-core",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "Reusable Node.js core capabilities powering the SERVICEME CLI and integrations.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "repository": {
@@ -81,7 +81,7 @@
81
81
  "json5": "^2.2.3",
82
82
  "yauzl": "^3.2.0",
83
83
  "zod": "^4.5.4",
84
- "@serviceme/devtools-protocol": "2.0.2"
84
+ "@serviceme/devtools-protocol": "2.0.4"
85
85
  },
86
86
  "devDependencies": {
87
87
  "@types/node": "^24",