@serviceme/devtools-core 0.4.2 → 0.4.3

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/index.js CHANGED
@@ -101,7 +101,6 @@ __export(src_exports, {
101
101
  SERVICEME_DIR_NAME: () => SERVICEME_DIR_NAME,
102
102
  SERVICEME_HOME_ENV: () => SERVICEME_HOME_ENV,
103
103
  SKILL_DRAFTS_SUBDIR: () => SKILL_DRAFTS_SUBDIR,
104
- SchedulerDaemon: () => SchedulerDaemon,
105
104
  SchedulerDaemonV2: () => SchedulerDaemonV2,
106
105
  ShellExecutor: () => ShellExecutor,
107
106
  SkillCatalogClient: () => SkillCatalogClient,
@@ -175,7 +174,6 @@ __export(src_exports, {
175
174
  isGitHubLocalEmail: () => isGitHubLocalEmail,
176
175
  isStreamingTaskExecutor: () => isStreamingTaskExecutor,
177
176
  isUserRepo: () => isUserRepo,
178
- matchesCron: () => matchesCron,
179
177
  mergeWithDefaults: () => mergeWithDefaults,
180
178
  migrateLegacyServerProxyEnabled: () => migrateLegacyServerProxyEnabled,
181
179
  migrateToGlobal: () => migrateToGlobal,
@@ -183,7 +181,6 @@ __export(src_exports, {
183
181
  narrowRepoConfig: () => narrowRepoConfig,
184
182
  noopLogger: () => noopLogger,
185
183
  parseAgentToolPermissions: () => parseAgentToolPermissions,
186
- parseIntervalMs: () => parseIntervalMs,
187
184
  randomInstallationId: () => randomInstallationId,
188
185
  readServerProxyGlobal: () => readServerProxyGlobal,
189
186
  reindexOrder: () => reindexOrder,
@@ -4927,7 +4924,7 @@ var PidManager = class {
4927
4924
  }
4928
4925
  };
4929
4926
 
4930
- // src/scheduled-tasks/daemon/SchedulerDaemon.ts
4927
+ // src/scheduled-tasks/daemon/SchedulerDaemonV2.ts
4931
4928
  var fs18 = __toESM(require("fs"));
4932
4929
  var os5 = __toESM(require("os"));
4933
4930
  var path19 = __toESM(require("path"));
@@ -5923,235 +5920,9 @@ var TaskLogManager = class {
5923
5920
  }
5924
5921
  };
5925
5922
 
5926
- // src/scheduled-tasks/daemon/SchedulerDaemon.ts
5923
+ // src/scheduled-tasks/daemon/SchedulerDaemonV2.ts
5927
5924
  var TICK_INTERVAL = 1e3;
5928
5925
  var MIN_SCHEDULE_INTERVAL = 1e3;
5929
- var SchedulerDaemon = class {
5930
- constructor(workspacePath, options = {}) {
5931
- this.tickTimer = null;
5932
- this.watcher = null;
5933
- this.running = false;
5934
- this.startTime = 0;
5935
- // Track last execution time and running state per task
5936
- this.lastRun = /* @__PURE__ */ new Map();
5937
- this.taskRunning = /* @__PURE__ */ new Set();
5938
- this.workspacePath = workspacePath;
5939
- const configDir = path19.join(workspacePath, ".serviceme");
5940
- this.configManager = new TaskConfigManager({
5941
- configPath: path19.join(configDir, "scheduled-tasks.json")
5942
- });
5943
- this.logManager = new TaskLogManager({
5944
- logPath: path19.join(configDir, "scheduled-tasks-log.json")
5945
- });
5946
- this.pidManager = new PidManager(workspacePath);
5947
- this.logger = new DaemonLogger(workspacePath);
5948
- this.getExecutor = options.getExecutor ?? getExecutor;
5949
- }
5950
- start() {
5951
- if (this.running) return;
5952
- this.running = true;
5953
- this.startTime = Date.now();
5954
- this.pidManager.writePid(process.pid);
5955
- const configPath = this.configManager.getConfigPath();
5956
- const logPath = this.logger.getLogPath();
5957
- this.logger.log("info", "=".repeat(60));
5958
- this.logger.log(
5959
- "info",
5960
- `Scheduler daemon started
5961
- PID: ${process.pid}
5962
- Node: ${process.version}
5963
- OS: ${os5.type()} ${os5.release()} (${process.arch})
5964
- Platform: ${process.platform}
5965
- Hostname: ${os5.hostname()}
5966
- User: ${os5.userInfo().username}
5967
- Workspace: ${this.workspacePath}
5968
- Config: ${configPath}
5969
- LogPath: ${logPath}
5970
- ExecPath: ${process.execPath}`
5971
- );
5972
- this.tickTimer = setInterval(() => this.tick(), TICK_INTERVAL);
5973
- this.setupConfigWatch();
5974
- process.on("SIGTERM", () => this.stop());
5975
- process.on("SIGINT", () => this.stop());
5976
- }
5977
- stop() {
5978
- if (!this.running) return;
5979
- this.running = false;
5980
- if (this.tickTimer) {
5981
- clearInterval(this.tickTimer);
5982
- this.tickTimer = null;
5983
- }
5984
- if (this.watcher) {
5985
- this.watcher.close();
5986
- this.watcher = null;
5987
- }
5988
- this.pidManager.removePid();
5989
- this.logger.log("info", "Scheduler daemon stopped");
5990
- process.exit(0);
5991
- }
5992
- setupConfigWatch() {
5993
- const configPath = this.configManager.getConfigPath();
5994
- const dir = configPath.substring(0, configPath.lastIndexOf("/"));
5995
- try {
5996
- if (fs18.existsSync(dir)) {
5997
- this.watcher = fs18.watch(dir, (_eventType, filename) => {
5998
- if (filename === "scheduled-tasks.json") {
5999
- this.logger.log("info", "Config file changed, reconciling...");
6000
- }
6001
- });
6002
- }
6003
- } catch {
6004
- this.logger.log("warn", "Could not watch config directory");
6005
- }
6006
- }
6007
- tick() {
6008
- const config = this.configManager.readConfig();
6009
- const now = Date.now();
6010
- for (const task of config.tasks) {
6011
- if (!task.enabled) continue;
6012
- if (this.taskRunning.has(task.id)) continue;
6013
- let lastExec = this.lastRun.get(task.id);
6014
- if (lastExec === void 0) {
6015
- this.lastRun.set(task.id, now);
6016
- lastExec = now;
6017
- }
6018
- if (this.shouldRun(task, lastExec, now)) {
6019
- this.executeTask(task, now);
6020
- }
6021
- }
6022
- }
6023
- shouldRun(task, lastExec, now) {
6024
- if (task.scheduleType === "interval") {
6025
- const intervalMs = parseIntervalMs(task.schedule);
6026
- if (intervalMs < MIN_SCHEDULE_INTERVAL) return false;
6027
- return now - lastExec >= intervalMs;
6028
- }
6029
- if (task.scheduleType === "cron") {
6030
- if (now - lastExec < 6e4) return false;
6031
- return matchesCron(task.schedule, new Date(now));
6032
- }
6033
- return false;
6034
- }
6035
- async executeTask(task, now) {
6036
- this.taskRunning.add(task.id);
6037
- this.lastRun.set(task.id, now);
6038
- const startedAt = new Date(now).toISOString();
6039
- const startMs = Date.now();
6040
- this.logger.log(
6041
- "info",
6042
- `Executing task: ${task.name} (${task.id})
6043
- type: ${task.taskType}
6044
- schedule: ${task.schedule} (${task.scheduleType})
6045
- enabled: ${task.enabled}`
6046
- );
6047
- try {
6048
- const executionPayload = resolveTaskExecutionPayload(
6049
- task.taskType,
6050
- task.payload,
6051
- this.workspacePath
6052
- );
6053
- validateTaskPayload(task.taskType, executionPayload);
6054
- const executor = this.getExecutor(task.taskType);
6055
- const result = await executor.execute(executionPayload);
6056
- const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
6057
- const durationMs = Date.now() - startMs;
6058
- this.logManager.appendLog({
6059
- taskId: task.id,
6060
- taskName: task.name,
6061
- startedAt,
6062
- finishedAt,
6063
- status: result.status === "running" ? "failure" : result.status,
6064
- output: result.output,
6065
- error: result.error
6066
- });
6067
- const outputBytes = result.output ? Buffer.byteLength(result.output) : 0;
6068
- this.logger.log(
6069
- "info",
6070
- `Task completed: ${task.name} (${task.id})
6071
- status: ${result.status}
6072
- duration: ${durationMs}ms
6073
- outputBytes: ${outputBytes}`
6074
- );
6075
- } catch (err) {
6076
- const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
6077
- const durationMs = Date.now() - startMs;
6078
- const message = err instanceof Error ? err.message : String(err);
6079
- this.logManager.appendLog({
6080
- taskId: task.id,
6081
- taskName: task.name,
6082
- startedAt,
6083
- finishedAt,
6084
- status: "failure",
6085
- error: message
6086
- });
6087
- this.logger.log(
6088
- "error",
6089
- `Task failed: ${task.name} (${task.id})
6090
- duration: ${durationMs}ms
6091
- error: ${message}`
6092
- );
6093
- } finally {
6094
- this.taskRunning.delete(task.id);
6095
- }
6096
- }
6097
- getStatus() {
6098
- const config = this.configManager.readConfig();
6099
- return {
6100
- running: this.running,
6101
- pid: process.pid,
6102
- uptimeSeconds: this.running ? Math.floor((Date.now() - this.startTime) / 1e3) : null,
6103
- tasksRegistered: config.tasks.length,
6104
- tasksEnabled: config.tasks.filter((t) => t.enabled).length,
6105
- workspacePath: this.workspacePath,
6106
- pidFile: this.pidManager.getPidPath()
6107
- };
6108
- }
6109
- };
6110
- function parseIntervalMs(schedule) {
6111
- const match = /^every\s+(\d+)\s*(s|sec|m|min|h|hr|d|day)s?$/i.exec(schedule);
6112
- if (!match) return 0;
6113
- const [, numStr, unit] = match;
6114
- const num = Number.parseInt(numStr ?? "0", 10);
6115
- switch (unit?.toLowerCase()) {
6116
- case "s":
6117
- case "sec":
6118
- return num * 1e3;
6119
- case "m":
6120
- case "min":
6121
- return num * 60 * 1e3;
6122
- case "h":
6123
- case "hr":
6124
- return num * 60 * 60 * 1e3;
6125
- case "d":
6126
- case "day":
6127
- return num * 24 * 60 * 60 * 1e3;
6128
- default:
6129
- return 0;
6130
- }
6131
- }
6132
- function matchesCron(expression, date) {
6133
- const parts = expression.trim().split(/\s+/);
6134
- if (parts.length < 5) return false;
6135
- const [minPart, hourPart, dayPart, monthPart, weekdayPart] = parts;
6136
- if (!minPart || !hourPart || !dayPart || !monthPart || !weekdayPart) return false;
6137
- return matchCronField(minPart, date.getMinutes()) && matchCronField(hourPart, date.getHours()) && matchCronField(dayPart, date.getDate()) && matchCronField(monthPart, date.getMonth() + 1) && matchCronField(weekdayPart, date.getDay());
6138
- }
6139
- function matchCronField(field, value) {
6140
- if (field === "*") return true;
6141
- if (field.startsWith("*/")) {
6142
- const step = Number.parseInt(field.slice(2), 10);
6143
- return step > 0 && value % step === 0;
6144
- }
6145
- const values = field.split(",");
6146
- return values.some((v) => Number.parseInt(v, 10) === value);
6147
- }
6148
-
6149
- // src/scheduled-tasks/daemon/SchedulerDaemonV2.ts
6150
- var fs19 = __toESM(require("fs"));
6151
- var os6 = __toESM(require("os"));
6152
- var path20 = __toESM(require("path"));
6153
- var TICK_INTERVAL2 = 1e3;
6154
- var MIN_SCHEDULE_INTERVAL2 = 1e3;
6155
5926
  var SCHEDULER_LOG_FILENAME2 = "scheduler.log";
6156
5927
  var SchedulerDaemonV2 = class {
6157
5928
  constructor(options = {}) {
@@ -6168,8 +5939,8 @@ var SchedulerDaemonV2 = class {
6168
5939
  this.configManager = options.configManager ?? new TaskConfigManager();
6169
5940
  this.logManager = options.logManager ?? new TaskLogManager();
6170
5941
  this.pidManager = options.pidManager ?? new PidManager("", { pidPath: getSchedulerPidPath() });
6171
- this.logger = options.logger ?? new DaemonLogger(os6.homedir(), {
6172
- logPath: path20.join(path20.dirname(this.pidManager.getPidPath()), SCHEDULER_LOG_FILENAME2)
5942
+ this.logger = options.logger ?? new DaemonLogger(os5.homedir(), {
5943
+ logPath: path19.join(path19.dirname(this.pidManager.getPidPath()), SCHEDULER_LOG_FILENAME2)
6173
5944
  });
6174
5945
  this.getExecutor = options.getExecutor ?? getExecutor;
6175
5946
  this.tryAcquireLock = options.tryAcquireLock ?? (() => true);
@@ -6199,12 +5970,12 @@ var SchedulerDaemonV2 = class {
6199
5970
  `SchedulerDaemonV2 started
6200
5971
  PID: ${process.pid}
6201
5972
  Node: ${process.version}
6202
- OS: ${os6.type()} ${os6.release()} (${process.arch})
5973
+ OS: ${os5.type()} ${os5.release()} (${process.arch})
6203
5974
  Config: ${this.configManager.getConfigPath()}
6204
5975
  LogPath: ${this.logger.getLogPath()}
6205
5976
  PidPath: ${this.pidManager.getPidPath()}`
6206
5977
  );
6207
- this.tickTimer = setInterval(() => this.tick(), TICK_INTERVAL2);
5978
+ this.tickTimer = setInterval(() => this.tick(), TICK_INTERVAL);
6208
5979
  process.on("SIGTERM", this.sigtermHandler);
6209
5980
  process.on("SIGINT", this.sigintHandler);
6210
5981
  }
@@ -6227,7 +5998,7 @@ var SchedulerDaemonV2 = class {
6227
5998
  const now = Date.now();
6228
5999
  for (const task of config.tasks) {
6229
6000
  if (!task.enabled) continue;
6230
- if (!fs19.existsSync(task.workspace.path)) {
6001
+ if (!fs18.existsSync(task.workspace.path)) {
6231
6002
  this.disableTaskForMissingWorkspace(task, config);
6232
6003
  continue;
6233
6004
  }
@@ -6267,13 +6038,13 @@ var SchedulerDaemonV2 = class {
6267
6038
  }
6268
6039
  shouldRun(task, lastExec, now) {
6269
6040
  if (task.scheduleType === "interval") {
6270
- const intervalMs = parseIntervalMs2(task.schedule);
6271
- if (intervalMs < MIN_SCHEDULE_INTERVAL2) return false;
6041
+ const intervalMs = parseIntervalMs(task.schedule);
6042
+ if (intervalMs < MIN_SCHEDULE_INTERVAL) return false;
6272
6043
  return now - lastExec >= intervalMs;
6273
6044
  }
6274
6045
  if (task.scheduleType === "cron") {
6275
6046
  if (now - lastExec < 6e4) return false;
6276
- return matchesCron2(task.schedule, new Date(now));
6047
+ return matchesCron(task.schedule, new Date(now));
6277
6048
  }
6278
6049
  return false;
6279
6050
  }
@@ -6344,7 +6115,7 @@ var SchedulerDaemonV2 = class {
6344
6115
  };
6345
6116
  }
6346
6117
  };
6347
- function parseIntervalMs2(schedule) {
6118
+ function parseIntervalMs(schedule) {
6348
6119
  const match = /^every\s+(\d+)\s*(s|sec|m|min|h|hr|d|day)s?$/i.exec(schedule);
6349
6120
  if (!match) return 0;
6350
6121
  const [, numStr, unit] = match;
@@ -6366,14 +6137,14 @@ function parseIntervalMs2(schedule) {
6366
6137
  return 0;
6367
6138
  }
6368
6139
  }
6369
- function matchesCron2(expression, date) {
6140
+ function matchesCron(expression, date) {
6370
6141
  const parts = expression.trim().split(/\s+/);
6371
6142
  if (parts.length < 5) return false;
6372
6143
  const [minPart, hourPart, dayPart, monthPart, weekdayPart] = parts;
6373
6144
  if (!minPart || !hourPart || !dayPart || !monthPart || !weekdayPart) return false;
6374
- return matchCronField2(minPart, date.getMinutes()) && matchCronField2(hourPart, date.getHours()) && matchCronField2(dayPart, date.getDate()) && matchCronField2(monthPart, date.getMonth() + 1) && matchCronField2(weekdayPart, date.getDay());
6145
+ return matchCronField(minPart, date.getMinutes()) && matchCronField(hourPart, date.getHours()) && matchCronField(dayPart, date.getDate()) && matchCronField(monthPart, date.getMonth() + 1) && matchCronField(weekdayPart, date.getDay());
6375
6146
  }
6376
- function matchCronField2(field, value) {
6147
+ function matchCronField(field, value) {
6377
6148
  if (field === "*") return true;
6378
6149
  if (field.startsWith("*/")) {
6379
6150
  const step = Number.parseInt(field.slice(2), 10);
@@ -6384,21 +6155,21 @@ function matchCronField2(field, value) {
6384
6155
  }
6385
6156
 
6386
6157
  // src/scheduled-tasks/migration/MigrateToGlobal.ts
6387
- var fs20 = __toESM(require("fs"));
6388
- var path21 = __toESM(require("path"));
6158
+ var fs19 = __toESM(require("fs"));
6159
+ var path20 = __toESM(require("path"));
6389
6160
  var import_devtools_protocol9 = require("@serviceme/devtools-protocol");
6390
6161
  var WORKSPACE_DIR = ".serviceme";
6391
6162
  var V1_FILENAME = "scheduled-tasks.json";
6392
6163
  function defaultProbe(workspacePath) {
6393
6164
  return {
6394
6165
  path: workspacePath,
6395
- name: path21.basename(workspacePath) || workspacePath
6166
+ name: path20.basename(workspacePath) || workspacePath
6396
6167
  };
6397
6168
  }
6398
6169
  function readV1Config(v1Path) {
6399
6170
  let raw;
6400
6171
  try {
6401
- raw = fs20.readFileSync(v1Path, "utf-8");
6172
+ raw = fs19.readFileSync(v1Path, "utf-8");
6402
6173
  } catch (err) {
6403
6174
  return {
6404
6175
  ok: false,
@@ -6421,27 +6192,27 @@ function readV1Config(v1Path) {
6421
6192
  }
6422
6193
  function safeDelete(filePath) {
6423
6194
  try {
6424
- fs20.unlinkSync(filePath);
6195
+ fs19.unlinkSync(filePath);
6425
6196
  } catch {
6426
6197
  }
6427
6198
  }
6428
6199
  function ensureDir(filePath) {
6429
- const dir = path21.dirname(filePath);
6430
- if (!fs20.existsSync(dir)) {
6431
- fs20.mkdirSync(dir, { recursive: true });
6200
+ const dir = path20.dirname(filePath);
6201
+ if (!fs19.existsSync(dir)) {
6202
+ fs19.mkdirSync(dir, { recursive: true });
6432
6203
  }
6433
6204
  }
6434
6205
  function readJsonFile(filePath) {
6435
- if (!fs20.existsSync(filePath)) return null;
6206
+ if (!fs19.existsSync(filePath)) return null;
6436
6207
  try {
6437
- return JSON.parse(fs20.readFileSync(filePath, "utf-8"));
6208
+ return JSON.parse(fs19.readFileSync(filePath, "utf-8"));
6438
6209
  } catch {
6439
6210
  return null;
6440
6211
  }
6441
6212
  }
6442
6213
  function writeJsonFile(filePath, data) {
6443
6214
  ensureDir(filePath);
6444
- fs20.writeFileSync(filePath, JSON.stringify(data, null, " "), "utf-8");
6215
+ fs19.writeFileSync(filePath, JSON.stringify(data, null, " "), "utf-8");
6445
6216
  }
6446
6217
  function disambiguateName(task, existingNames, workspaceName) {
6447
6218
  if (!existingNames.has(task.name)) {
@@ -6471,8 +6242,8 @@ async function migrateToGlobal(options) {
6471
6242
  const conflicts = [];
6472
6243
  const issues = [];
6473
6244
  for (const workspacePath of options.workspacePaths) {
6474
- const v1Path = path21.join(workspacePath, WORKSPACE_DIR, V1_FILENAME);
6475
- if (!fs20.existsSync(v1Path)) continue;
6245
+ const v1Path = path20.join(workspacePath, WORKSPACE_DIR, V1_FILENAME);
6246
+ if (!fs19.existsSync(v1Path)) continue;
6476
6247
  const v1 = readV1Config(v1Path);
6477
6248
  if (!v1.ok) {
6478
6249
  failures.push({
@@ -6514,8 +6285,8 @@ async function migrateToGlobal(options) {
6514
6285
  if (migrated > 0) {
6515
6286
  ensureDir(globalConfigPath);
6516
6287
  const tmp = `${globalConfigPath}.tmp`;
6517
- fs20.writeFileSync(tmp, JSON.stringify(baseConfig, null, " "), "utf-8");
6518
- fs20.renameSync(tmp, globalConfigPath);
6288
+ fs19.writeFileSync(tmp, JSON.stringify(baseConfig, null, " "), "utf-8");
6289
+ fs19.renameSync(tmp, globalConfigPath);
6519
6290
  }
6520
6291
  if (failures.length > priorFailures.length) {
6521
6292
  writeJsonFile(migrationFailuresPath, failures);
@@ -6532,8 +6303,8 @@ async function migrateToGlobal(options) {
6532
6303
 
6533
6304
  // src/scheduled-tasks/workspace-probe/WorkspaceProbe.ts
6534
6305
  var import_node_child_process5 = require("child_process");
6535
- var fs21 = __toESM(require("fs"));
6536
- var path22 = __toESM(require("path"));
6306
+ var fs20 = __toESM(require("fs"));
6307
+ var path21 = __toESM(require("path"));
6537
6308
  var DEFAULT_TIMEOUT_MS5 = 2e3;
6538
6309
  var GitTimeoutError = class extends Error {
6539
6310
  constructor() {
@@ -6596,8 +6367,8 @@ var WorkspaceProbe = class {
6596
6367
  }
6597
6368
  }
6598
6369
  async probe(workspacePath) {
6599
- const name = path22.basename(workspacePath) || workspacePath;
6600
- if (!workspacePath || !fs21.existsSync(workspacePath)) {
6370
+ const name = path21.basename(workspacePath) || workspacePath;
6371
+ if (!workspacePath || !fs20.existsSync(workspacePath)) {
6601
6372
  return {
6602
6373
  workspace: { path: workspacePath, name },
6603
6374
  error: "path-not-found"
@@ -6749,8 +6520,8 @@ var SkillReconciler = class {
6749
6520
  };
6750
6521
 
6751
6522
  // src/skills/SkillStore.ts
6752
- var fs22 = __toESM(require("fs/promises"));
6753
- var path23 = __toESM(require("path"));
6523
+ var fs21 = __toESM(require("fs/promises"));
6524
+ var path22 = __toESM(require("path"));
6754
6525
  var USER_SKILL_MARKER_FILE = ".serviceme-skill.json";
6755
6526
  var LEGACY_USER_SKILL_MARKER_FILE = ".ms-devtools-skill.json";
6756
6527
  var WORKSPACE_SKILLS_ROOT_RELATIVE = ".github/skills";
@@ -6766,7 +6537,7 @@ var SkillStore = class {
6766
6537
  constructor(options) {
6767
6538
  this.workspacePath = options.workspacePath;
6768
6539
  this.userSkillsRoot = options.userSkillsRoot;
6769
- this.fileSystem = options.fileSystem ?? fs22;
6540
+ this.fileSystem = options.fileSystem ?? fs21;
6770
6541
  }
6771
6542
  normalizeRemoteSkillId(remoteId) {
6772
6543
  if (remoteId.startsWith("official/")) {
@@ -6785,10 +6556,10 @@ var SkillStore = class {
6785
6556
  return WORKSPACE_SKILLS_MARKER_RELATIVE;
6786
6557
  }
6787
6558
  getUserSkillPath(skillId) {
6788
- return path23.join(this.userSkillsRoot, skillId);
6559
+ return path22.join(this.userSkillsRoot, skillId);
6789
6560
  }
6790
6561
  async listWorkspaceSkillIds() {
6791
- const skillsRootPath = path23.join(this.workspacePath, WORKSPACE_SKILLS_ROOT_RELATIVE);
6562
+ const skillsRootPath = path22.join(this.workspacePath, WORKSPACE_SKILLS_ROOT_RELATIVE);
6792
6563
  try {
6793
6564
  const entries = await this.fileSystem.readdir(skillsRootPath, {
6794
6565
  withFileTypes: true
@@ -6812,7 +6583,7 @@ var SkillStore = class {
6812
6583
  const targetDir = this.getUserSkillPath(skillId);
6813
6584
  await this.fileSystem.mkdir(targetDir, { recursive: true });
6814
6585
  await this.fileSystem.writeFile(
6815
- path23.join(targetDir, USER_SKILL_MARKER_FILE),
6586
+ path22.join(targetDir, USER_SKILL_MARKER_FILE),
6816
6587
  JSON.stringify({ skillId, installedBy: "serviceme" }, null, 2),
6817
6588
  "utf-8"
6818
6589
  );
@@ -6821,7 +6592,7 @@ var SkillStore = class {
6821
6592
  await this.migrateLegacyUserSkillMarker(skillId);
6822
6593
  try {
6823
6594
  const marker = await this.fileSystem.readFile(
6824
- path23.join(this.getUserSkillPath(skillId), USER_SKILL_MARKER_FILE),
6595
+ path22.join(this.getUserSkillPath(skillId), USER_SKILL_MARKER_FILE),
6825
6596
  "utf-8"
6826
6597
  );
6827
6598
  const parsed = JSON.parse(marker);
@@ -6838,8 +6609,8 @@ var SkillStore = class {
6838
6609
  */
6839
6610
  async migrateLegacyUserSkillMarker(skillId) {
6840
6611
  const targetDir = this.getUserSkillPath(skillId);
6841
- const newPath = path23.join(targetDir, USER_SKILL_MARKER_FILE);
6842
- const legacyPath = path23.join(targetDir, LEGACY_USER_SKILL_MARKER_FILE);
6612
+ const newPath = path22.join(targetDir, USER_SKILL_MARKER_FILE);
6613
+ const legacyPath = path22.join(targetDir, LEGACY_USER_SKILL_MARKER_FILE);
6843
6614
  try {
6844
6615
  await this.fileSystem.readFile(newPath, "utf-8");
6845
6616
  return;
@@ -6852,12 +6623,12 @@ var SkillStore = class {
6852
6623
  }
6853
6624
  }
6854
6625
  async writeSkillFiles(skillId, scope, files) {
6855
- const root = scope === "workspace" ? path23.join(this.workspacePath, WORKSPACE_SKILLS_ROOT_RELATIVE) : this.userSkillsRoot;
6856
- const targetDir = path23.join(root, skillId);
6626
+ const root = scope === "workspace" ? path22.join(this.workspacePath, WORKSPACE_SKILLS_ROOT_RELATIVE) : this.userSkillsRoot;
6627
+ const targetDir = path22.join(root, skillId);
6857
6628
  await this.fileSystem.mkdir(targetDir, { recursive: true });
6858
6629
  for (const file of files) {
6859
- const filePath = path23.join(targetDir, file.path);
6860
- await this.fileSystem.mkdir(path23.dirname(filePath), { recursive: true });
6630
+ const filePath = path22.join(targetDir, file.path);
6631
+ await this.fileSystem.mkdir(path22.dirname(filePath), { recursive: true });
6861
6632
  await this.fileSystem.writeFile(filePath, file.content, "utf-8");
6862
6633
  if (file.executable) {
6863
6634
  try {
@@ -6870,8 +6641,8 @@ var SkillStore = class {
6870
6641
  };
6871
6642
 
6872
6643
  // src/submit/index.ts
6873
- var fs23 = __toESM(require("fs/promises"));
6874
- var path24 = __toESM(require("path"));
6644
+ var fs22 = __toESM(require("fs/promises"));
6645
+ var path23 = __toESM(require("path"));
6875
6646
 
6876
6647
  // src/submit/types.ts
6877
6648
  var SubmitError = class extends Error {
@@ -6921,14 +6692,14 @@ var SubmitClient = class {
6921
6692
  throw new SubmitError(v.reason ?? "unknown", v.detail ?? "validation denied");
6922
6693
  }
6923
6694
  const localRepoPath = getRepoDir(repoId);
6924
- const targetDir = path24.join(localRepoPath, "skills", skillName);
6925
- await fs23.mkdir(targetDir, { recursive: true });
6695
+ const targetDir = path23.join(localRepoPath, "skills", skillName);
6696
+ await fs22.mkdir(targetDir, { recursive: true });
6926
6697
  for (const f of files) {
6927
- const full = path24.join(targetDir, f.path);
6928
- await fs23.mkdir(path24.dirname(full), { recursive: true });
6698
+ const full = path23.join(targetDir, f.path);
6699
+ await fs22.mkdir(path23.dirname(full), { recursive: true });
6929
6700
  const tmp = `${full}.${process.pid}.${Date.now()}.tmp`;
6930
- await fs23.writeFile(tmp, f.content, "utf8");
6931
- await fs23.rename(tmp, full);
6701
+ await fs22.writeFile(tmp, f.content, "utf8");
6702
+ await fs22.rename(tmp, full);
6932
6703
  }
6933
6704
  const commitMessage = `feat(skills): add ${skillName}`;
6934
6705
  const { commitSha } = await this.git.commit(localRepoPath, commitMessage);
@@ -6997,7 +6768,7 @@ function touchLastUsedAt(tools, id, when = /* @__PURE__ */ new Date()) {
6997
6768
 
6998
6769
  // src/toolbox/ToolboxStore.ts
6999
6770
  var fsp2 = __toESM(require("fs/promises"));
7000
- var path25 = __toESM(require("path"));
6771
+ var path24 = __toESM(require("path"));
7001
6772
  var import_promises4 = require("timers/promises");
7002
6773
 
7003
6774
  // src/toolbox/types.ts
@@ -7033,11 +6804,11 @@ var DEFAULT_LOCK_TIMEOUT_MS2 = 5e3;
7033
6804
  var DEFAULT_LOCK_RETRY_MS2 = 25;
7034
6805
  var LOCK_STALE_GRACE_MS2 = 200;
7035
6806
  var TMP_SUFFIX2 = ".tmp";
7036
- var WORKSPACE_TOOLBOX_RELATIVE_PATH = path25.join(".github", ".serviceme-toolbox.json");
6807
+ var WORKSPACE_TOOLBOX_RELATIVE_PATH = path24.join(".github", ".serviceme-toolbox.json");
7037
6808
  var LEGACY_WORKSPACE_TOOLBOX_FILENAME = ".ms-devtools-toolbox.json";
7038
6809
  async function migrateLegacyWorkspaceToolboxFile(filePath) {
7039
6810
  if (!filePath) return;
7040
- const legacyPath = path25.join(path25.dirname(filePath), LEGACY_WORKSPACE_TOOLBOX_FILENAME);
6811
+ const legacyPath = path24.join(path24.dirname(filePath), LEGACY_WORKSPACE_TOOLBOX_FILENAME);
7041
6812
  if (legacyPath === filePath) return;
7042
6813
  try {
7043
6814
  await fsp2.access(filePath);
@@ -7086,15 +6857,15 @@ var FsToolboxFileBackend = class {
7086
6857
  }
7087
6858
  }
7088
6859
  async purgeExcessBackups(filePath) {
7089
- const dir = path25.dirname(filePath);
7090
- const base = path25.basename(filePath);
6860
+ const dir = path24.dirname(filePath);
6861
+ const base = path24.basename(filePath);
7091
6862
  let entries;
7092
6863
  try {
7093
6864
  entries = await fsp2.readdir(dir);
7094
6865
  } catch {
7095
6866
  return;
7096
6867
  }
7097
- const backups = entries.filter((n) => n.startsWith(base) && n.endsWith(".bak")).map((n) => ({ name: n, filePath: path25.join(dir, n) })).sort((a, b) => {
6868
+ const backups = entries.filter((n) => n.startsWith(base) && n.endsWith(".bak")).map((n) => ({ name: n, filePath: path24.join(dir, n) })).sort((a, b) => {
7098
6869
  return a.name.localeCompare(b.name);
7099
6870
  });
7100
6871
  const excess = backups.length - this.maxBackupCount;
@@ -7104,7 +6875,7 @@ var FsToolboxFileBackend = class {
7104
6875
  );
7105
6876
  }
7106
6877
  async write(filePath, payload) {
7107
- await fsp2.mkdir(path25.dirname(filePath), { recursive: true });
6878
+ await fsp2.mkdir(path24.dirname(filePath), { recursive: true });
7108
6879
  const tmpPath = `${filePath}${TMP_SUFFIX2}`;
7109
6880
  const bytes = Buffer.from(JSON.stringify(payload, null, " "), "utf8");
7110
6881
  await fsp2.rm(tmpPath, { force: true });
@@ -7148,7 +6919,7 @@ var ToolboxFileLock = class {
7148
6919
  constructor(filePath, timeoutMs, retryMs) {
7149
6920
  this.acquired = false;
7150
6921
  this.dirPath = `${filePath}.lock`;
7151
- this.pidFilePath = path25.join(this.dirPath, "pid");
6922
+ this.pidFilePath = path24.join(this.dirPath, "pid");
7152
6923
  this.timeoutMs = timeoutMs;
7153
6924
  this.retryMs = retryMs;
7154
6925
  }
@@ -7198,7 +6969,7 @@ var ToolboxFileLock = class {
7198
6969
  };
7199
6970
  function defaultWorkspacePath() {
7200
6971
  if (process.env.SERVICEME_NO_WORKSPACE_TOOLBOX === "1") return null;
7201
- return path25.join(process.cwd(), WORKSPACE_TOOLBOX_RELATIVE_PATH);
6972
+ return path24.join(process.cwd(), WORKSPACE_TOOLBOX_RELATIVE_PATH);
7202
6973
  }
7203
6974
  var ToolboxStore = class {
7204
6975
  constructor(opts = {}) {
@@ -7511,7 +7282,6 @@ var ToolboxCore = class {
7511
7282
  SERVICEME_DIR_NAME,
7512
7283
  SERVICEME_HOME_ENV,
7513
7284
  SKILL_DRAFTS_SUBDIR,
7514
- SchedulerDaemon,
7515
7285
  SchedulerDaemonV2,
7516
7286
  ShellExecutor,
7517
7287
  SkillCatalogClient,
@@ -7585,7 +7355,6 @@ var ToolboxCore = class {
7585
7355
  isGitHubLocalEmail,
7586
7356
  isStreamingTaskExecutor,
7587
7357
  isUserRepo,
7588
- matchesCron,
7589
7358
  mergeWithDefaults,
7590
7359
  migrateLegacyServerProxyEnabled,
7591
7360
  migrateToGlobal,
@@ -7593,7 +7362,6 @@ var ToolboxCore = class {
7593
7362
  narrowRepoConfig,
7594
7363
  noopLogger,
7595
7364
  parseAgentToolPermissions,
7596
- parseIntervalMs,
7597
7365
  randomInstallationId,
7598
7366
  readServerProxyGlobal,
7599
7367
  reindexOrder,