sparkecoder 0.1.131 → 0.1.132

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 (120) hide show
  1. package/dist/cli.js +348 -92
  2. package/dist/cli.js.map +1 -1
  3. package/dist/index.js +292 -36
  4. package/dist/index.js.map +1 -1
  5. package/dist/server/index.js +292 -36
  6. package/dist/server/index.js.map +1 -1
  7. package/package.json +1 -1
  8. package/web/.next/BUILD_ID +1 -1
  9. package/web/.next/standalone/web/.next/BUILD_ID +1 -1
  10. package/web/.next/standalone/web/.next/build-manifest.json +2 -2
  11. package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
  12. package/web/.next/standalone/web/.next/server/app/(main)/agents/page_client-reference-manifest.js +1 -1
  13. package/web/.next/standalone/web/.next/server/app/(main)/page_client-reference-manifest.js +1 -1
  14. package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page_client-reference-manifest.js +1 -1
  15. package/web/.next/standalone/web/.next/server/app/(main)/settings/page_client-reference-manifest.js +1 -1
  16. package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
  17. package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
  18. package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  19. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  20. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  21. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  22. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  23. package/web/.next/standalone/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  24. package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
  25. package/web/.next/standalone/web/.next/server/app/_not-found.rsc +2 -2
  26. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  27. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  28. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  29. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  30. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  31. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  32. package/web/.next/standalone/web/.next/server/app/agents.html +1 -1
  33. package/web/.next/standalone/web/.next/server/app/agents.rsc +4 -4
  34. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +2 -2
  35. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents.segment.rsc +1 -1
  36. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p.segment.rsc +2 -2
  37. package/web/.next/standalone/web/.next/server/app/agents.segments/_full.segment.rsc +4 -4
  38. package/web/.next/standalone/web/.next/server/app/agents.segments/_head.segment.rsc +1 -1
  39. package/web/.next/standalone/web/.next/server/app/agents.segments/_index.segment.rsc +2 -2
  40. package/web/.next/standalone/web/.next/server/app/agents.segments/_tree.segment.rsc +1 -1
  41. package/web/.next/standalone/web/.next/server/app/api/config/route.js.nft.json +1 -1
  42. package/web/.next/standalone/web/.next/server/app/api/health/route.js.nft.json +1 -1
  43. package/web/.next/standalone/web/.next/server/app/docs/installation/page_client-reference-manifest.js +1 -1
  44. package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
  45. package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +3 -3
  46. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +3 -3
  47. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
  48. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +2 -2
  49. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
  50. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +2 -2
  51. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
  52. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +2 -2
  53. package/web/.next/standalone/web/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  54. package/web/.next/standalone/web/.next/server/app/docs/skills/page_client-reference-manifest.js +1 -1
  55. package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
  56. package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +3 -3
  57. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +3 -3
  58. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
  59. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +2 -2
  60. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
  61. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
  62. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
  63. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +2 -2
  64. package/web/.next/standalone/web/.next/server/app/docs/tools/page_client-reference-manifest.js +1 -1
  65. package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
  66. package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +3 -3
  67. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +3 -3
  68. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
  69. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +2 -2
  70. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
  71. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +2 -2
  72. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
  73. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +2 -2
  74. package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
  75. package/web/.next/standalone/web/.next/server/app/docs.rsc +3 -3
  76. package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +3 -3
  77. package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
  78. package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +2 -2
  79. package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
  80. package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +2 -2
  81. package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +2 -2
  82. package/web/.next/standalone/web/.next/server/app/index.html +1 -1
  83. package/web/.next/standalone/web/.next/server/app/index.rsc +4 -4
  84. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +2 -2
  85. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +2 -2
  86. package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +4 -4
  87. package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  88. package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +2 -2
  89. package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  90. package/web/.next/standalone/web/.next/server/app/settings.html +1 -1
  91. package/web/.next/standalone/web/.next/server/app/settings.rsc +4 -4
  92. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings/__PAGE__.segment.rsc +2 -2
  93. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings.segment.rsc +1 -1
  94. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p.segment.rsc +2 -2
  95. package/web/.next/standalone/web/.next/server/app/settings.segments/_full.segment.rsc +4 -4
  96. package/web/.next/standalone/web/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  97. package/web/.next/standalone/web/.next/server/app/settings.segments/_index.segment.rsc +2 -2
  98. package/web/.next/standalone/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  99. package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
  100. package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
  101. package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
  102. package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
  103. package/web/.next/standalone/web/.next/static/chunks/185f69f6478ba713.js +1 -0
  104. package/web/.next/standalone/web/.next/static/static/chunks/185f69f6478ba713.js +1 -0
  105. package/web/.next/standalone/web/runtime-config.json +2 -1
  106. package/web/.next/standalone/web/src/app/__sfapi/[...path]/route.ts +96 -0
  107. package/web/.next/standalone/web/src/lib/config.ts +22 -7
  108. package/web/.next/static/chunks/185f69f6478ba713.js +1 -0
  109. package/web/.next/standalone/web/.next/static/chunks/5aece72c38f86fbd.js +0 -1
  110. package/web/.next/standalone/web/.next/static/static/chunks/5aece72c38f86fbd.js +0 -1
  111. package/web/.next/static/chunks/5aece72c38f86fbd.js +0 -1
  112. /package/web/.next/standalone/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → WaAcu3X3K00MDvfn1ik7H}/_buildManifest.js +0 -0
  113. /package/web/.next/standalone/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → WaAcu3X3K00MDvfn1ik7H}/_clientMiddlewareManifest.json +0 -0
  114. /package/web/.next/standalone/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → WaAcu3X3K00MDvfn1ik7H}/_ssgManifest.js +0 -0
  115. /package/web/.next/standalone/web/.next/static/static/{KQbunVSU5tNoYBl7TnhLn → WaAcu3X3K00MDvfn1ik7H}/_buildManifest.js +0 -0
  116. /package/web/.next/standalone/web/.next/static/static/{KQbunVSU5tNoYBl7TnhLn → WaAcu3X3K00MDvfn1ik7H}/_clientMiddlewareManifest.json +0 -0
  117. /package/web/.next/standalone/web/.next/static/static/{KQbunVSU5tNoYBl7TnhLn → WaAcu3X3K00MDvfn1ik7H}/_ssgManifest.js +0 -0
  118. /package/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → WaAcu3X3K00MDvfn1ik7H}/_buildManifest.js +0 -0
  119. /package/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → WaAcu3X3K00MDvfn1ik7H}/_clientMiddlewareManifest.json +0 -0
  120. /package/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → WaAcu3X3K00MDvfn1ik7H}/_ssgManifest.js +0 -0
package/dist/cli.js CHANGED
@@ -1163,12 +1163,12 @@ function loadConfig(configPath, workingDirectory) {
1163
1163
  ]
1164
1164
  };
1165
1165
  const DEFAULT_REMOTE_URL = "https://agent-remote-server.sparkecode.com";
1166
- const remoteUrl = process.env.SPARKECODER_REMOTE_URL || config.remoteServer?.url || DEFAULT_REMOTE_URL;
1166
+ const remoteUrl2 = process.env.SPARKECODER_REMOTE_URL || config.remoteServer?.url || DEFAULT_REMOTE_URL;
1167
1167
  const remoteAuthKey = process.env.SPARKECODER_AUTH_KEY || config.remoteServer?.authKey || loadStoredAuthKey();
1168
1168
  const resolvedRemoteServer = {
1169
- url: remoteUrl,
1169
+ url: remoteUrl2,
1170
1170
  authKey: remoteAuthKey,
1171
- isConfigured: !!remoteUrl && !!remoteAuthKey
1171
+ isConfigured: !!remoteUrl2 && !!remoteAuthKey
1172
1172
  };
1173
1173
  const resolved = {
1174
1174
  ...config,
@@ -4894,11 +4894,11 @@ async function getRepoNamespace(workingDirectory, configuredNamespace) {
4894
4894
  if (configuredNamespace) {
4895
4895
  return configuredNamespace;
4896
4896
  }
4897
- const remoteUrl = getGitRemoteUrl(workingDirectory);
4898
- if (!remoteUrl) {
4897
+ const remoteUrl2 = getGitRemoteUrl(workingDirectory);
4898
+ if (!remoteUrl2) {
4899
4899
  return null;
4900
4900
  }
4901
- const parsed = parseGitRemoteUrl(remoteUrl);
4901
+ const parsed = parseGitRemoteUrl(remoteUrl2);
4902
4902
  if (!parsed) {
4903
4903
  return null;
4904
4904
  }
@@ -5497,7 +5497,7 @@ function isPathExcluded(relativePath, exclude) {
5497
5497
  }
5498
5498
  async function walkDirectory(dir, include, exclude, baseDir) {
5499
5499
  const { readdirSync: readdirSync4 } = await import("fs");
5500
- const { join: join20, relative: relative10 } = await import("path");
5500
+ const { join: join21, relative: relative10 } = await import("path");
5501
5501
  const files = [];
5502
5502
  function walk(currentDir) {
5503
5503
  let entries;
@@ -5507,7 +5507,7 @@ async function walkDirectory(dir, include, exclude, baseDir) {
5507
5507
  return;
5508
5508
  }
5509
5509
  for (const entry2 of entries) {
5510
- const fullPath = join20(currentDir, entry2.name);
5510
+ const fullPath = join21(currentDir, entry2.name);
5511
5511
  const relativePath = relative10(baseDir, fullPath);
5512
5512
  if (isPathExcluded(relativePath, exclude)) {
5513
5513
  continue;
@@ -9088,6 +9088,29 @@ var init_persistence = __esm({
9088
9088
  });
9089
9089
 
9090
9090
  // src/integrations/slack/client.ts
9091
+ var client_exports = {};
9092
+ __export(client_exports, {
9093
+ LOADING_REACTION: () => LOADING_REACTION,
9094
+ RESULT_REACTIONS: () => RESULT_REACTIONS,
9095
+ addLoadingReaction: () => addLoadingReaction,
9096
+ addResultReaction: () => addResultReaction,
9097
+ botParticipatedInThread: () => botParticipatedInThread,
9098
+ ensureSlackSelfIdentity: () => ensureSlackSelfIdentity,
9099
+ getCachedSlackSelfIdentity: () => getCachedSlackSelfIdentity,
9100
+ getDefaultOrchestratorName: () => getDefaultOrchestratorName,
9101
+ getSlackAdapter: () => getSlackAdapter,
9102
+ getSlackAllowlistPolicy: () => getSlackAllowlistPolicy,
9103
+ getSlackBotToken: () => getSlackBotToken,
9104
+ getSlackDeniedReplyPolicy: () => getSlackDeniedReplyPolicy,
9105
+ getSlackSigningSecret: () => getSlackSigningSecret,
9106
+ isSlackConfigured: () => isSlackConfigured,
9107
+ normalizeSlackMentions: () => normalizeSlackMentions,
9108
+ noteBotPostedInThread: () => noteBotPostedInThread,
9109
+ postThreadMessage: () => postThreadMessage,
9110
+ removeLoadingReaction: () => removeLoadingReaction,
9111
+ resolveSlackUserInfo: () => resolveSlackUserInfo,
9112
+ resolveSlackUserName: () => resolveSlackUserName
9113
+ });
9091
9114
  function slackBackoffMs(attempt) {
9092
9115
  const expo = SLACK_BACKOFF_BASE_MS * 2 ** attempt;
9093
9116
  const jitter = Math.floor(Math.random() * SLACK_BACKOFF_BASE_MS);
@@ -12404,11 +12427,11 @@ ${p.text}` : p.text;
12404
12427
  const { isRemoteConfigured: isRemoteConfigured2, storageQueries: storageQueries2 } = await Promise.resolve().then(() => (init_remote(), remote_exports));
12405
12428
  if (!isRemoteConfigured2()) return [];
12406
12429
  const { readFile: readFile13 } = await import("fs/promises");
12407
- const { join: join20, basename: basename7 } = await import("path");
12430
+ const { join: join21, basename: basename7 } = await import("path");
12408
12431
  const urls = [];
12409
12432
  for (const filePath of filePaths) {
12410
12433
  try {
12411
- const fullPath = filePath.startsWith("/") ? filePath : join20(this.session.workingDirectory, filePath);
12434
+ const fullPath = filePath.startsWith("/") ? filePath : join21(this.session.workingDirectory, filePath);
12412
12435
  const fileName = basename7(fullPath);
12413
12436
  const ext = fileName.split(".").pop()?.toLowerCase() || "";
12414
12437
  const mimeMap = {
@@ -12779,6 +12802,233 @@ var init_ensure_orchestrator = __esm({
12779
12802
  }
12780
12803
  });
12781
12804
 
12805
+ // src/orchestrator/self-update.ts
12806
+ var self_update_exports = {};
12807
+ __export(self_update_exports, {
12808
+ __test: () => __test,
12809
+ startSelfUpdater: () => startSelfUpdater,
12810
+ stopSelfUpdater: () => stopSelfUpdater
12811
+ });
12812
+ import { spawn as spawn2, execFile } from "child_process";
12813
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync7, mkdirSync as mkdirSync10 } from "fs";
12814
+ import { dirname as dirname10, join as join18 } from "path";
12815
+ import { fileURLToPath as fileURLToPath4 } from "url";
12816
+ function currentVersion2() {
12817
+ const here = dirname10(fileURLToPath4(import.meta.url));
12818
+ const candidates = [
12819
+ join18(here, "..", "..", "package.json"),
12820
+ join18(here, "..", "package.json"),
12821
+ join18(process.cwd(), "package.json")
12822
+ ];
12823
+ for (const p of candidates) {
12824
+ try {
12825
+ const pkg = JSON.parse(readFileSync11(p, "utf8"));
12826
+ if (pkg.name === "sparkecoder" && pkg.version) return pkg.version;
12827
+ } catch {
12828
+ }
12829
+ }
12830
+ return "0.0.0";
12831
+ }
12832
+ function isLikelyGlobalInstall() {
12833
+ const here = dirname10(fileURLToPath4(import.meta.url));
12834
+ return here.includes("/node_modules/sparkecoder/") || here.includes("\\node_modules\\sparkecoder\\");
12835
+ }
12836
+ function isEnabled() {
12837
+ if (process.env.SPARKECODER_AUTO_UPDATE === "false" || process.env.SPARKECODER_AUTO_UPDATE === "0") return false;
12838
+ try {
12839
+ const cfg = getConfig();
12840
+ if (cfg?.autoUpdate?.enabled === false) return false;
12841
+ } catch {
12842
+ }
12843
+ return true;
12844
+ }
12845
+ function remoteUrl() {
12846
+ try {
12847
+ const cfg = getConfig();
12848
+ const url = cfg?.remoteServer?.url;
12849
+ return typeof url === "string" && url.length > 0 ? url.replace(/\/+$/, "") : null;
12850
+ } catch {
12851
+ return null;
12852
+ }
12853
+ }
12854
+ function intervalMs() {
12855
+ try {
12856
+ const h = getConfig()?.autoUpdate?.intervalHours;
12857
+ if (typeof h === "number" && h > 0) return h * 60 * 6e4;
12858
+ } catch {
12859
+ }
12860
+ return DEFAULT_INTERVAL_HOURS * 60 * 6e4;
12861
+ }
12862
+ function semverGt(a, b) {
12863
+ const parse = (v) => v.split("-")[0].split(".").map((n) => parseInt(n, 10) || 0);
12864
+ const pa = parse(a);
12865
+ const pb = parse(b);
12866
+ for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
12867
+ const x = pa[i] ?? 0;
12868
+ const y = pb[i] ?? 0;
12869
+ if (x > y) return true;
12870
+ if (x < y) return false;
12871
+ }
12872
+ return false;
12873
+ }
12874
+ function statePath() {
12875
+ try {
12876
+ return join18(getAppDataDirectory(), "self-update-state.json");
12877
+ } catch {
12878
+ return null;
12879
+ }
12880
+ }
12881
+ function readState() {
12882
+ const p = statePath();
12883
+ if (!p) return {};
12884
+ try {
12885
+ return JSON.parse(readFileSync11(p, "utf8"));
12886
+ } catch {
12887
+ return {};
12888
+ }
12889
+ }
12890
+ function writeState(s) {
12891
+ const p = statePath();
12892
+ if (!p) return;
12893
+ try {
12894
+ mkdirSync10(dirname10(p), { recursive: true });
12895
+ writeFileSync7(p, JSON.stringify(s));
12896
+ } catch {
12897
+ }
12898
+ }
12899
+ function attemptedRecently(target, now) {
12900
+ const s = readState();
12901
+ return s.lastTarget === target && typeof s.lastAttemptAt === "number" && now - s.lastAttemptAt < RETRY_COOLDOWN_MS;
12902
+ }
12903
+ function latestPublishedVersion() {
12904
+ return new Promise((resolve14) => {
12905
+ execFile("npm", ["view", "sparkecoder", "version"], { timeout: 3e4 }, (err, stdout) => {
12906
+ if (err) {
12907
+ resolve14(null);
12908
+ return;
12909
+ }
12910
+ const v = String(stdout).trim();
12911
+ resolve14(/^\d+\.\d+\.\d+/.test(v) ? v : null);
12912
+ });
12913
+ });
12914
+ }
12915
+ function runInstaller(url) {
12916
+ const secret = process.env.SPARKECODER_SETUP_SECRET || process.env.SPARKECODER_TUNNEL_SECRET || "";
12917
+ const query = secret ? `?secret=${encodeURIComponent(secret)}` : "";
12918
+ const oneLiner = `bash -c "$(curl -fsSL '${url}/install.sh${query}')" >/tmp/sparkecoder-selfupdate.log 2>&1`;
12919
+ const child = spawn2("bash", ["-lc", oneLiner], {
12920
+ detached: true,
12921
+ stdio: "ignore"
12922
+ });
12923
+ child.unref();
12924
+ }
12925
+ async function checkAndUpdate() {
12926
+ if (upgrading || !isEnabled()) return;
12927
+ const url = remoteUrl();
12928
+ if (!url) return;
12929
+ const latest = await latestPublishedVersion();
12930
+ if (!latest) return;
12931
+ const current = currentVersion2();
12932
+ if (!semverGt(latest, current)) return;
12933
+ const now = Date.now();
12934
+ if (attemptedRecently(latest, now)) {
12935
+ console.log(`[self-update] v${latest} already attempted recently; skipping until cooldown elapses`);
12936
+ return;
12937
+ }
12938
+ upgrading = true;
12939
+ const announced = await announceUpdate(latest);
12940
+ const delay = announced ? ANNOUNCE_GRACE_MS : 0;
12941
+ if (announced) {
12942
+ console.log(`[self-update] announced v${latest} in Slack; updating in ${Math.round(delay / 6e4)}m`);
12943
+ }
12944
+ const t = setTimeout(() => doInstall(latest, url, current), delay);
12945
+ if (typeof t.unref === "function") t.unref();
12946
+ }
12947
+ function doInstall(latest, url, current) {
12948
+ const prev = readState();
12949
+ writeState({
12950
+ lastTarget: latest,
12951
+ lastAttemptAt: Date.now(),
12952
+ attempts: prev.lastTarget === latest ? (prev.attempts ?? 0) + 1 : 1
12953
+ });
12954
+ console.log(`[self-update] newer version available: v${current} \u2192 v${latest}; re-running installer`);
12955
+ try {
12956
+ runInstaller(url);
12957
+ } catch (err) {
12958
+ upgrading = false;
12959
+ console.warn("[self-update] failed to launch installer:", err?.message || err);
12960
+ }
12961
+ }
12962
+ async function findOrchestratorId() {
12963
+ try {
12964
+ const { sessionQueries: sessionQueries2 } = await Promise.resolve().then(() => (init_db(), db_exports));
12965
+ const all = await sessionQueries2.list(500, 0);
12966
+ const orch = all.find((s) => s?.config?.role === "orchestrator");
12967
+ return orch?.id ?? null;
12968
+ } catch {
12969
+ return null;
12970
+ }
12971
+ }
12972
+ async function announceUpdate(target) {
12973
+ try {
12974
+ const { isSlackConfigured: isSlackConfigured2 } = await Promise.resolve().then(() => (init_client3(), client_exports));
12975
+ if (!isSlackConfigured2()) return false;
12976
+ const orchId = await findOrchestratorId();
12977
+ if (!orchId) return false;
12978
+ const { pushToInbox: pushToInbox2 } = await Promise.resolve().then(() => (init_inbox(), inbox_exports));
12979
+ pushToInbox2(orchId, {
12980
+ ref: { channel: "system", kind: "worker.completed", workerId: "self-update", workerName: "self-update" },
12981
+ content: `[SYSTEM self-update] A software update to v${target} will begin in about 5 minutes and the service will restart briefly (expect ~1\u20132 minutes of downtime). Send a short Slack heads-up to whoever you normally talk to / the bot owner that you'll be offline for a quick update, then carry on. Use the messenger tool to deliver it. If you genuinely don't know who to tell, post in the most relevant channel you've recently been active in; if Slack isn't reachable, skip silently \u2014 the update will proceed regardless.`,
12982
+ wake: "now",
12983
+ enqueuedAt: /* @__PURE__ */ new Date()
12984
+ });
12985
+ return true;
12986
+ } catch {
12987
+ return false;
12988
+ }
12989
+ }
12990
+ function startSelfUpdater() {
12991
+ if (started) return;
12992
+ started = true;
12993
+ if (!isEnabled()) {
12994
+ console.log("[self-update] disabled");
12995
+ return;
12996
+ }
12997
+ if (!isLikelyGlobalInstall()) {
12998
+ console.log("[self-update] skipped (not a global install)");
12999
+ return;
13000
+ }
13001
+ const kickoff = setTimeout(() => {
13002
+ void checkAndUpdate();
13003
+ timer = setInterval(() => {
13004
+ void checkAndUpdate();
13005
+ }, intervalMs());
13006
+ if (typeof timer.unref === "function") timer.unref();
13007
+ }, INITIAL_DELAY_MS);
13008
+ if (typeof kickoff.unref === "function") kickoff.unref();
13009
+ }
13010
+ function stopSelfUpdater() {
13011
+ if (timer) {
13012
+ clearInterval(timer);
13013
+ timer = null;
13014
+ }
13015
+ }
13016
+ var INITIAL_DELAY_MS, DEFAULT_INTERVAL_HOURS, ANNOUNCE_GRACE_MS, RETRY_COOLDOWN_MS, timer, started, upgrading, __test;
13017
+ var init_self_update = __esm({
13018
+ "src/orchestrator/self-update.ts"() {
13019
+ "use strict";
13020
+ init_config();
13021
+ INITIAL_DELAY_MS = 5 * 6e4;
13022
+ DEFAULT_INTERVAL_HOURS = 6;
13023
+ ANNOUNCE_GRACE_MS = 5 * 6e4;
13024
+ RETRY_COOLDOWN_MS = 24 * 60 * 6e4;
13025
+ timer = null;
13026
+ started = false;
13027
+ upgrading = false;
13028
+ __test = { currentVersion: currentVersion2, semverGt, isLikelyGlobalInstall };
13029
+ }
13030
+ });
13031
+
12782
13032
  // src/tasks/scheduler.ts
12783
13033
  var scheduler_exports = {};
12784
13034
  __export(scheduler_exports, {
@@ -13081,8 +13331,8 @@ import chalk from "chalk";
13081
13331
  import ora from "ora";
13082
13332
  import "dotenv/config";
13083
13333
  import { createInterface } from "readline";
13084
- import { dirname as dirname11 } from "path";
13085
- import { fileURLToPath as fileURLToPath5 } from "url";
13334
+ import { dirname as dirname12 } from "path";
13335
+ import { fileURLToPath as fileURLToPath6 } from "url";
13086
13336
 
13087
13337
  // src/server/index.ts
13088
13338
  import "dotenv/config";
@@ -13090,11 +13340,11 @@ import { Hono as Hono10 } from "hono";
13090
13340
  import { serve } from "@hono/node-server";
13091
13341
  import { cors } from "hono/cors";
13092
13342
  import { logger } from "hono/logger";
13093
- import { existsSync as existsSync22, mkdirSync as mkdirSync10, writeFileSync as writeFileSync7 } from "fs";
13094
- import { resolve as resolve12, dirname as dirname10, join as join18 } from "path";
13095
- import { spawn as spawn2 } from "child_process";
13343
+ import { existsSync as existsSync22, mkdirSync as mkdirSync11, writeFileSync as writeFileSync8 } from "fs";
13344
+ import { resolve as resolve12, dirname as dirname11, join as join19 } from "path";
13345
+ import { spawn as spawn3 } from "child_process";
13096
13346
  import { createServer as createNetServer } from "net";
13097
- import { fileURLToPath as fileURLToPath4 } from "url";
13347
+ import { fileURLToPath as fileURLToPath5 } from "url";
13098
13348
 
13099
13349
  // src/server/routes/sessions.ts
13100
13350
  init_db();
@@ -17573,13 +17823,13 @@ var DEFAULT_WEB_PORT = 6969;
17573
17823
  var WEB_PORT_SEQUENCE = [6969, 6970, 6971, 6972, 6973, 6974, 6975, 6976, 6977, 6978];
17574
17824
  function getWebDirectory() {
17575
17825
  try {
17576
- const currentDir = dirname10(fileURLToPath4(import.meta.url));
17826
+ const currentDir = dirname11(fileURLToPath5(import.meta.url));
17577
17827
  const webDir = resolve12(currentDir, "..", "web");
17578
- if (existsSync22(webDir) && existsSync22(join18(webDir, "package.json"))) {
17828
+ if (existsSync22(webDir) && existsSync22(join19(webDir, "package.json"))) {
17579
17829
  return webDir;
17580
17830
  }
17581
17831
  const altWebDir = resolve12(currentDir, "..", "..", "web");
17582
- if (existsSync22(altWebDir) && existsSync22(join18(altWebDir, "package.json"))) {
17832
+ if (existsSync22(altWebDir) && existsSync22(join19(altWebDir, "package.json"))) {
17583
17833
  return altWebDir;
17584
17834
  }
17585
17835
  return null;
@@ -17637,20 +17887,20 @@ async function findWebPort(preferredPort) {
17637
17887
  return { port: preferredPort, alreadyRunning: false };
17638
17888
  }
17639
17889
  function hasProductionBuild(webDir) {
17640
- const buildIdPath = join18(webDir, ".next", "BUILD_ID");
17890
+ const buildIdPath = join19(webDir, ".next", "BUILD_ID");
17641
17891
  return existsSync22(buildIdPath);
17642
17892
  }
17643
17893
  function hasSourceFiles(webDir) {
17644
- const appDir = join18(webDir, "src", "app");
17645
- const pagesDir = join18(webDir, "src", "pages");
17646
- const rootAppDir = join18(webDir, "app");
17647
- const rootPagesDir = join18(webDir, "pages");
17894
+ const appDir = join19(webDir, "src", "app");
17895
+ const pagesDir = join19(webDir, "src", "pages");
17896
+ const rootAppDir = join19(webDir, "app");
17897
+ const rootPagesDir = join19(webDir, "pages");
17648
17898
  return existsSync22(appDir) || existsSync22(pagesDir) || existsSync22(rootAppDir) || existsSync22(rootPagesDir);
17649
17899
  }
17650
17900
  function getStandaloneServerPath(webDir) {
17651
17901
  const possiblePaths2 = [
17652
- join18(webDir, ".next", "standalone", "server.js"),
17653
- join18(webDir, ".next", "standalone", "web", "server.js")
17902
+ join19(webDir, ".next", "standalone", "server.js"),
17903
+ join19(webDir, ".next", "standalone", "web", "server.js")
17654
17904
  ];
17655
17905
  for (const serverPath of possiblePaths2) {
17656
17906
  if (existsSync22(serverPath)) {
@@ -17661,7 +17911,7 @@ function getStandaloneServerPath(webDir) {
17661
17911
  }
17662
17912
  function runCommand(command, args, cwd, env) {
17663
17913
  return new Promise((resolve14) => {
17664
- const child = spawn2(command, args, {
17914
+ const child = spawn3(command, args, {
17665
17915
  cwd,
17666
17916
  stdio: ["ignore", "pipe", "pipe"],
17667
17917
  env,
@@ -17693,15 +17943,15 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false, pu
17693
17943
  if (!quiet) console.log(` \u2713 Web UI already running at http://localhost:${actualPort}`);
17694
17944
  return { process: null, port: actualPort };
17695
17945
  }
17696
- const usePnpm = existsSync22(join18(webDir, "pnpm-lock.yaml"));
17697
- const useNpm = !usePnpm && existsSync22(join18(webDir, "package-lock.json"));
17946
+ const usePnpm = existsSync22(join19(webDir, "pnpm-lock.yaml"));
17947
+ const useNpm = !usePnpm && existsSync22(join19(webDir, "package-lock.json"));
17698
17948
  const pkgManager = usePnpm ? "pnpm" : useNpm ? "npm" : "npx";
17699
17949
  const { NODE_OPTIONS, TSX_TSCONFIG_PATH, ...cleanEnv } = process.env;
17700
17950
  const apiUrl = publicUrl || `http://127.0.0.1:${apiPort}`;
17701
- const runtimeConfig = { apiBaseUrl: apiUrl };
17702
- const runtimeConfigPath = join18(webDir, "runtime-config.json");
17951
+ const runtimeConfig = { apiBaseUrl: apiUrl, localApiBaseUrl: `http://127.0.0.1:${apiPort}` };
17952
+ const runtimeConfigPath = join19(webDir, "runtime-config.json");
17703
17953
  try {
17704
- writeFileSync7(runtimeConfigPath, JSON.stringify(runtimeConfig, null, 2));
17954
+ writeFileSync8(runtimeConfigPath, JSON.stringify(runtimeConfig, null, 2));
17705
17955
  if (!quiet) console.log(` \u{1F4DD} Runtime config written to ${runtimeConfigPath}`);
17706
17956
  } catch (err) {
17707
17957
  if (!quiet) console.warn(` \u26A0 Could not write runtime config: ${err}`);
@@ -17721,7 +17971,7 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false, pu
17721
17971
  if (standaloneServerPath) {
17722
17972
  command = "node";
17723
17973
  args = ["server.js"];
17724
- cwd = dirname10(standaloneServerPath);
17974
+ cwd = dirname11(standaloneServerPath);
17725
17975
  webEnv.PORT = String(actualPort);
17726
17976
  webEnv.HOSTNAME = "0.0.0.0";
17727
17977
  if (!quiet) console.log(" \u{1F4E6} Starting Web UI from standalone build...");
@@ -17751,7 +18001,7 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false, pu
17751
18001
  }
17752
18002
  return { process: null, port: actualPort };
17753
18003
  }
17754
- const child = spawn2(command, args, {
18004
+ const child = spawn3(command, args, {
17755
18005
  cwd,
17756
18006
  stdio: ["ignore", "pipe", "pipe"],
17757
18007
  env: webEnv,
@@ -17759,12 +18009,12 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false, pu
17759
18009
  shell: true
17760
18010
  });
17761
18011
  const startupTimeout = 3e4;
17762
- let started = false;
18012
+ let started2 = false;
17763
18013
  let exited = false;
17764
18014
  let exitCode = null;
17765
18015
  const startedPromise = new Promise((resolve14) => {
17766
18016
  const timeout = setTimeout(() => {
17767
- if (!started && !exited) {
18017
+ if (!started2 && !exited) {
17768
18018
  resolve14(false);
17769
18019
  }
17770
18020
  }, startupTimeout);
@@ -17776,8 +18026,8 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false, pu
17776
18026
  console.log(` Web UI: ${line}`);
17777
18027
  }
17778
18028
  }
17779
- if (!started && (output.includes("Ready") || output.includes("started") || output.includes("localhost"))) {
17780
- started = true;
18029
+ if (!started2 && (output.includes("Ready") || output.includes("started") || output.includes("localhost"))) {
18030
+ started2 = true;
17781
18031
  clearTimeout(timeout);
17782
18032
  resolve14(true);
17783
18033
  }
@@ -17796,7 +18046,7 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false, pu
17796
18046
  child.on("exit", (code) => {
17797
18047
  exited = true;
17798
18048
  exitCode = code;
17799
- if (!started) {
18049
+ if (!started2) {
17800
18050
  clearTimeout(timeout);
17801
18051
  resolve14(false);
17802
18052
  }
@@ -17916,7 +18166,7 @@ async function startServer(options = {}) {
17916
18166
  config.resolvedWorkingDirectory = options.workingDirectory;
17917
18167
  }
17918
18168
  if (!existsSync22(config.resolvedWorkingDirectory)) {
17919
- mkdirSync10(config.resolvedWorkingDirectory, { recursive: true });
18169
+ mkdirSync11(config.resolvedWorkingDirectory, { recursive: true });
17920
18170
  if (!options.quiet) console.log(`\u{1F4C1} Created agent workspace: ${config.resolvedWorkingDirectory}`);
17921
18171
  }
17922
18172
  if (!config.resolvedRemoteServer.url) {
@@ -17952,6 +18202,12 @@ async function startServer(options = {}) {
17952
18202
  } catch (err) {
17953
18203
  if (!options.quiet) console.warn(`[daemon] start skipped: ${err.message}`);
17954
18204
  }
18205
+ try {
18206
+ const { startSelfUpdater: startSelfUpdater2 } = await Promise.resolve().then(() => (init_self_update(), self_update_exports));
18207
+ startSelfUpdater2();
18208
+ } catch (err) {
18209
+ if (!options.quiet) console.warn(`[self-update] start skipped: ${err.message}`);
18210
+ }
17955
18211
  try {
17956
18212
  const { startScheduler: startScheduler2 } = await Promise.resolve().then(() => (init_scheduler(), scheduler_exports));
17957
18213
  startScheduler2({ quiet: options.quiet });
@@ -18476,18 +18732,18 @@ function generateOpenAPISpec() {
18476
18732
  init_config();
18477
18733
  init_semantic();
18478
18734
  init_db();
18479
- import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync8, readFileSync as readFileSync11, existsSync as existsSync23, statSync as statSync4, unlinkSync as unlinkSync3 } from "fs";
18480
- import { resolve as resolve13, join as join19 } from "path";
18735
+ import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync9, readFileSync as readFileSync12, existsSync as existsSync23, statSync as statSync4, unlinkSync as unlinkSync3 } from "fs";
18736
+ import { resolve as resolve13, join as join20 } from "path";
18481
18737
  function getCliVersion() {
18482
- const here = dirname11(fileURLToPath5(import.meta.url));
18738
+ const here = dirname12(fileURLToPath6(import.meta.url));
18483
18739
  const candidates = [
18484
- join19(here, "..", "package.json"),
18485
- join19(here, "..", "..", "package.json"),
18486
- join19(process.cwd(), "package.json")
18740
+ join20(here, "..", "package.json"),
18741
+ join20(here, "..", "..", "package.json"),
18742
+ join20(process.cwd(), "package.json")
18487
18743
  ];
18488
18744
  for (const p of candidates) {
18489
18745
  try {
18490
- const pkg = JSON.parse(readFileSync11(p, "utf8"));
18746
+ const pkg = JSON.parse(readFileSync12(p, "utf8"));
18491
18747
  if (pkg.name === "sparkecoder" && pkg.version) return pkg.version;
18492
18748
  } catch {
18493
18749
  }
@@ -19135,7 +19391,7 @@ program.command("task").description("Run an autonomous task that completes witho
19135
19391
  try {
19136
19392
  const schemaStr = options.schema;
19137
19393
  if (existsSync23(schemaStr)) {
19138
- outputSchema = JSON.parse(readFileSync11(schemaStr, "utf-8"));
19394
+ outputSchema = JSON.parse(readFileSync12(schemaStr, "utf-8"));
19139
19395
  } else {
19140
19396
  outputSchema = JSON.parse(schemaStr);
19141
19397
  }
@@ -19155,7 +19411,7 @@ program.command("task").description("Run an autonomous task that completes witho
19155
19411
  if (options.name) body.name = options.name;
19156
19412
  if (options.parentTask) body.parentTaskId = options.parentTask;
19157
19413
  const parseJsonArrayOption = (raw, label) => {
19158
- const text = existsSync23(raw) ? readFileSync11(raw, "utf-8") : raw;
19414
+ const text = existsSync23(raw) ? readFileSync12(raw, "utf-8") : raw;
19159
19415
  const parsed = JSON.parse(text);
19160
19416
  if (!Array.isArray(parsed)) {
19161
19417
  throw new Error(`${label} must be a JSON array`);
@@ -19226,7 +19482,7 @@ program.command("init").description("Create a sparkecoder.config.json file").opt
19226
19482
  let configLocation;
19227
19483
  if (options.global) {
19228
19484
  const appDataDir = ensureAppDataDirectory();
19229
- configPath = join19(appDataDir, "sparkecoder.config.json");
19485
+ configPath = join20(appDataDir, "sparkecoder.config.json");
19230
19486
  configLocation = "global";
19231
19487
  } else {
19232
19488
  configPath = resolve13(process.cwd(), "sparkecoder.config.json");
@@ -19238,7 +19494,7 @@ program.command("init").description("Create a sparkecoder.config.json file").opt
19238
19494
  return;
19239
19495
  }
19240
19496
  const config = createDefaultConfig();
19241
- writeFileSync8(configPath, JSON.stringify(config, null, 2));
19497
+ writeFileSync9(configPath, JSON.stringify(config, null, 2));
19242
19498
  console.log(chalk.green(`\u2713 Created ${configLocation} config`));
19243
19499
  console.log(chalk.dim(` ${configPath}`));
19244
19500
  console.log(chalk.dim("Set AI_GATEWAY_API_KEY and run sparkecoder to start"));
@@ -19257,11 +19513,11 @@ program.command("slack-setup").description("Interactively configure Slack integr
19257
19513
  console.error(chalk.red("Both bot token and signing secret are required."));
19258
19514
  process.exit(1);
19259
19515
  }
19260
- const configPath = options.global ? join19(ensureAppDataDirectory(), "sparkecoder.config.json") : resolve13(process.cwd(), "sparkecoder.config.json");
19516
+ const configPath = options.global ? join20(ensureAppDataDirectory(), "sparkecoder.config.json") : resolve13(process.cwd(), "sparkecoder.config.json");
19261
19517
  let existing = {};
19262
19518
  if (existsSync23(configPath)) {
19263
19519
  try {
19264
- existing = JSON.parse(readFileSync11(configPath, "utf-8"));
19520
+ existing = JSON.parse(readFileSync12(configPath, "utf-8"));
19265
19521
  } catch {
19266
19522
  }
19267
19523
  } else {
@@ -19273,7 +19529,7 @@ program.command("slack-setup").description("Interactively configure Slack integr
19273
19529
  signingSecret,
19274
19530
  defaultOrchestratorName: existing.slack?.defaultOrchestratorName ?? "orchestrator"
19275
19531
  };
19276
- writeFileSync8(configPath, JSON.stringify(existing, null, 2));
19532
+ writeFileSync9(configPath, JSON.stringify(existing, null, 2));
19277
19533
  console.log(chalk.green(`
19278
19534
  \u2713 Slack configured`));
19279
19535
  console.log(chalk.dim(` ${configPath}`));
@@ -19341,15 +19597,15 @@ program.command("cloudflared-setup").description("Auto-detect cloudflared + set
19341
19597
  if (options.remote) {
19342
19598
  try {
19343
19599
  let config = loadConfig(options.config, process.cwd());
19344
- let remoteUrl = config.resolvedRemoteServer.url;
19345
- if (!remoteUrl) {
19600
+ let remoteUrl2 = config.resolvedRemoteServer.url;
19601
+ if (!remoteUrl2) {
19346
19602
  console.log(chalk.red("No remoteServer.url configured. Run `sparkecoder login` (or set remoteServer.url in your config) first."));
19347
19603
  process.exitCode = 1;
19348
19604
  return;
19349
19605
  }
19350
19606
  let authKey3 = config.resolvedRemoteServer.authKey;
19351
19607
  if (!authKey3) {
19352
- authKey3 = await ensureRemoteAuthKey(remoteUrl);
19608
+ authKey3 = await ensureRemoteAuthKey(remoteUrl2);
19353
19609
  }
19354
19610
  const setupSecret = options.setupSecret || process.env.SPARKECODER_SETUP_SECRET || process.env.SPARKECODER_TUNNEL_SECRET;
19355
19611
  const hostname = options.hostname;
@@ -19363,7 +19619,7 @@ program.command("cloudflared-setup").description("Auto-detect cloudflared + set
19363
19619
  name: tunnelName
19364
19620
  };
19365
19621
  if (hostname) reqBody.hostname = hostname;
19366
- const res = await fetch(`${remoteUrl.replace(/\/$/, "")}${path}`, {
19622
+ const res = await fetch(`${remoteUrl2.replace(/\/$/, "")}${path}`, {
19367
19623
  method: "POST",
19368
19624
  headers: {
19369
19625
  "Content-Type": "application/json",
@@ -19539,8 +19795,8 @@ program.command("cloudflared-setup").description("Auto-detect cloudflared + set
19539
19795
  }
19540
19796
  const verOut = run("cloudflared", ["--version"]).stdout?.toString().split("\n")[0] || "installed";
19541
19797
  console.log(chalk.green("\u2713"), "cloudflared:", chalk.dim(verOut));
19542
- const cfDir = join19(homedir2(), ".cloudflared");
19543
- const certPath = join19(cfDir, "cert.pem");
19798
+ const cfDir = join20(homedir2(), ".cloudflared");
19799
+ const certPath = join20(cfDir, "cert.pem");
19544
19800
  if (!existsSync23(certPath)) {
19545
19801
  console.log(chalk.yellow("No Cloudflare login cert found."));
19546
19802
  if (await confirm("Run `cloudflared tunnel login` now (opens a browser)?", true)) {
@@ -19585,7 +19841,7 @@ program.command("cloudflared-setup").description("Auto-detect cloudflared + set
19585
19841
  return;
19586
19842
  }
19587
19843
  }
19588
- const credsFile = tunnel.credentials_file || join19(cfDir, `${tunnel.id}.json`);
19844
+ const credsFile = tunnel.credentials_file || join20(cfDir, `${tunnel.id}.json`);
19589
19845
  if (!existsSync23(credsFile)) {
19590
19846
  console.log(chalk.yellow(`Credentials file not found at ${credsFile}. The tunnel may still work via cert.pem.`));
19591
19847
  }
@@ -19609,7 +19865,7 @@ program.command("cloudflared-setup").description("Auto-detect cloudflared + set
19609
19865
  console.log(chalk.yellow("DNS route warning:"), err.trim().split("\n").slice(-2).join(" "));
19610
19866
  }
19611
19867
  }
19612
- const configPath = join19(cfDir, "config.yml");
19868
+ const configPath = join20(cfDir, "config.yml");
19613
19869
  const configBody = `tunnel: ${tunnel.id}
19614
19870
  credentials-file: ${credsFile}
19615
19871
  ingress:
@@ -19621,13 +19877,13 @@ ingress:
19621
19877
  `;
19622
19878
  let wroteConfig = false;
19623
19879
  if (existsSync23(configPath)) {
19624
- const existing = readFileSync11(configPath, "utf8");
19880
+ const existing = readFileSync12(configPath, "utf8");
19625
19881
  if (existing.trim() === configBody.trim()) {
19626
19882
  console.log(chalk.green("\u2713"), `config.yml already up to date: ${configPath}`);
19627
19883
  wroteConfig = true;
19628
19884
  } else if (await confirm(`A different ${configPath} exists. Overwrite (a backup will be saved)?`, false)) {
19629
19885
  copyFileSync(configPath, `${configPath}.bak.${Date.now()}`);
19630
- writeFileSync8(configPath, configBody);
19886
+ writeFileSync9(configPath, configBody);
19631
19887
  console.log(chalk.green("\u2713"), `wrote ${configPath} (previous saved as .bak.*)`);
19632
19888
  wroteConfig = true;
19633
19889
  } else {
@@ -19635,7 +19891,7 @@ ingress:
19635
19891
  console.log(chalk.cyan(configBody));
19636
19892
  }
19637
19893
  } else {
19638
- writeFileSync8(configPath, configBody);
19894
+ writeFileSync9(configPath, configBody);
19639
19895
  console.log(chalk.green("\u2713"), `wrote ${configPath}`);
19640
19896
  wroteConfig = true;
19641
19897
  }
@@ -19738,8 +19994,8 @@ program.command("index").description("Index repository for semantic search").opt
19738
19994
  try {
19739
19995
  const workingDir = options.workingDir ? resolve13(options.workingDir) : process.cwd();
19740
19996
  let config = loadConfig(options.config, workingDir);
19741
- const remoteUrl = config.resolvedRemoteServer.url;
19742
- if (!remoteUrl) {
19997
+ const remoteUrl2 = config.resolvedRemoteServer.url;
19998
+ if (!remoteUrl2) {
19743
19999
  console.error(chalk.red("Error: Remote server not configured"));
19744
20000
  console.log(chalk.dim("Set REMOTE_SERVER_URL environment variable or remoteServer.url in config"));
19745
20001
  process.exit(1);
@@ -19747,7 +20003,7 @@ program.command("index").description("Index repository for semantic search").opt
19747
20003
  let authKey3 = config.resolvedRemoteServer.authKey;
19748
20004
  if (!authKey3) {
19749
20005
  console.log(chalk.dim("Registering with remote server..."));
19750
- authKey3 = await ensureRemoteAuthKey(remoteUrl);
20006
+ authKey3 = await ensureRemoteAuthKey(remoteUrl2);
19751
20007
  config = loadConfig(options.config, workingDir);
19752
20008
  authKey3 = config.resolvedRemoteServer.authKey || authKey3;
19753
20009
  }
@@ -19756,7 +20012,7 @@ program.command("index").description("Index repository for semantic search").opt
19756
20012
  console.log(chalk.dim("Set SPARKECODER_AUTH_KEY or run sparkecoder to register with the remote server"));
19757
20013
  process.exit(1);
19758
20014
  }
19759
- initDatabase({ url: remoteUrl, authKey: authKey3 });
20015
+ initDatabase({ url: remoteUrl2, authKey: authKey3 });
19760
20016
  if (!isGitRepository(workingDir)) {
19761
20017
  console.error(chalk.red("Error: Not a git repository"));
19762
20018
  console.log(chalk.dim("Semantic indexing requires a git repository with a remote configured."));
@@ -19872,20 +20128,20 @@ program.command("search").description("Search indexed repository using semantic
19872
20128
  try {
19873
20129
  const workingDir = options.workingDir ? resolve13(options.workingDir) : process.cwd();
19874
20130
  const config = loadConfig(options.config, workingDir);
19875
- const remoteUrl = config.resolvedRemoteServer.url;
19876
- if (!remoteUrl) {
20131
+ const remoteUrl2 = config.resolvedRemoteServer.url;
20132
+ if (!remoteUrl2) {
19877
20133
  console.error(chalk.red("Error: Remote server not configured"));
19878
20134
  process.exit(1);
19879
20135
  }
19880
20136
  let authKey3 = config.resolvedRemoteServer.authKey;
19881
20137
  if (!authKey3) {
19882
- authKey3 = await ensureRemoteAuthKey(remoteUrl);
20138
+ authKey3 = await ensureRemoteAuthKey(remoteUrl2);
19883
20139
  }
19884
20140
  if (!authKey3) {
19885
20141
  console.error(chalk.red("Error: Remote auth key not available"));
19886
20142
  process.exit(1);
19887
20143
  }
19888
- initDatabase({ url: remoteUrl, authKey: authKey3 });
20144
+ initDatabase({ url: remoteUrl2, authKey: authKey3 });
19889
20145
  const namespace = await getRepoNamespace(workingDir, config.resolvedVectorGateway.namespace);
19890
20146
  if (!namespace) {
19891
20147
  console.error(chalk.red("Error: Could not determine repository namespace"));
@@ -20127,17 +20383,17 @@ program.command("request-permissions").description("Open System Settings to the
20127
20383
  let shellEscape2 = function(str) {
20128
20384
  return `'${str.replace(/'/g, "'\\''")}'`;
20129
20385
  }, stateFilePath = function() {
20130
- return join19(ensureAppDataDirectory(), "recordings.json");
20131
- }, readState = function() {
20386
+ return join20(ensureAppDataDirectory(), "recordings.json");
20387
+ }, readState2 = function() {
20132
20388
  const p = stateFilePath();
20133
20389
  if (!existsSync23(p)) return [];
20134
20390
  try {
20135
- return JSON.parse(readFileSync11(p, "utf-8"));
20391
+ return JSON.parse(readFileSync12(p, "utf-8"));
20136
20392
  } catch {
20137
20393
  return [];
20138
20394
  }
20139
- }, writeState = function(rows) {
20140
- writeFileSync8(stateFilePath(), JSON.stringify(rows, null, 2), { mode: 384 });
20395
+ }, writeState2 = function(rows) {
20396
+ writeFileSync9(stateFilePath(), JSON.stringify(rows, null, 2), { mode: 384 });
20141
20397
  }, isAlive = function(pid) {
20142
20398
  try {
20143
20399
  process.kill(pid, 0);
@@ -20148,7 +20404,7 @@ program.command("request-permissions").description("Open System Settings to the
20148
20404
  }, pruneDead = function(rows) {
20149
20405
  return rows.filter((r) => isAlive(r.pid));
20150
20406
  };
20151
- shellEscape3 = shellEscape2, stateFilePath2 = stateFilePath, readState2 = readState, writeState2 = writeState, isAlive2 = isAlive, pruneDead2 = pruneDead;
20407
+ shellEscape3 = shellEscape2, stateFilePath2 = stateFilePath, readState3 = readState2, writeState3 = writeState2, isAlive2 = isAlive, pruneDead2 = pruneDead;
20152
20408
  async function stopRecorderPid(pid) {
20153
20409
  if (!isAlive(pid)) return;
20154
20410
  try {
@@ -20210,12 +20466,12 @@ program.command("request-permissions").description("Open System Settings to the
20210
20466
  const record = program.command("record").description("Start/stop screen recordings");
20211
20467
  record.command("start").description("Start a screen recording (returns id, path, pid as JSON)").option("--name <slug>", "Optional human-readable label for the recording").option("--dir <path>", "Output directory (default: ~/recordings)").action(async (opts) => {
20212
20468
  const { homedir: homedir2, platform: osPlatform } = await import("os");
20213
- const outDir = opts.dir ? resolve13(opts.dir.replace(/^~/, homedir2())) : join19(homedir2(), "recordings");
20214
- mkdirSync11(outDir, { recursive: true });
20469
+ const outDir = opts.dir ? resolve13(opts.dir.replace(/^~/, homedir2())) : join20(homedir2(), "recordings");
20470
+ mkdirSync12(outDir, { recursive: true });
20215
20471
  const id = `rec-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;
20216
20472
  const ext = "mp4";
20217
20473
  const filename = `${id}${opts.name ? `-${String(opts.name).replace(/[^a-z0-9-]+/gi, "-").toLowerCase()}` : ""}.${ext}`;
20218
- const path = join19(outDir, filename);
20474
+ const path = join20(outDir, filename);
20219
20475
  let cmd;
20220
20476
  let args;
20221
20477
  let capturePath;
@@ -20297,13 +20553,13 @@ program.command("request-permissions").description("Open System Settings to the
20297
20553
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
20298
20554
  platform: osPlatform()
20299
20555
  };
20300
- const rows = pruneDead(readState());
20556
+ const rows = pruneDead(readState2());
20301
20557
  rows.push(row);
20302
- writeState(rows);
20558
+ writeState2(rows);
20303
20559
  console.log(JSON.stringify({ id, path, pid: child.pid, platform: osPlatform() }));
20304
20560
  });
20305
20561
  record.command("stop <id>").description("Stop a recording started by `sparkecoder record start`").action(async (id) => {
20306
- const rows = readState();
20562
+ const rows = readState2();
20307
20563
  const row = rows.find((r) => r.id === id);
20308
20564
  if (!row) {
20309
20565
  console.error(JSON.stringify({ error: `No recording found with id ${id}` }));
@@ -20311,7 +20567,7 @@ program.command("request-permissions").description("Open System Settings to the
20311
20567
  }
20312
20568
  const startedAt = new Date(row.startedAt).getTime();
20313
20569
  const { path: finalPath, ok, sizeMb, warning } = await finalizeRecording(row);
20314
- writeState(rows.filter((r) => r.id !== id));
20570
+ writeState2(rows.filter((r) => r.id !== id));
20315
20571
  console.log(JSON.stringify({
20316
20572
  id,
20317
20573
  path: finalPath,
@@ -20322,25 +20578,25 @@ program.command("request-permissions").description("Open System Settings to the
20322
20578
  }));
20323
20579
  });
20324
20580
  record.command("list").description("List active recordings").action(() => {
20325
- const rows = pruneDead(readState());
20326
- writeState(rows);
20581
+ const rows = pruneDead(readState2());
20582
+ writeState2(rows);
20327
20583
  console.log(JSON.stringify(rows, null, 2));
20328
20584
  });
20329
20585
  record.command("stop-all").description("Stop every active recording").action(async () => {
20330
- const rows = readState();
20586
+ const rows = readState2();
20331
20587
  const stopped = [];
20332
20588
  for (const r of rows) {
20333
20589
  const { path: finalPath, ok, warning } = await finalizeRecording(r);
20334
20590
  stopped.push({ id: r.id, path: finalPath, ok, ...warning ? { warning } : {} });
20335
20591
  }
20336
- writeState([]);
20592
+ writeState2([]);
20337
20593
  console.log(JSON.stringify({ stopped }));
20338
20594
  });
20339
20595
  }
20340
20596
  var shellEscape3;
20341
20597
  var stateFilePath2;
20342
- var readState2;
20343
- var writeState2;
20598
+ var readState3;
20599
+ var writeState3;
20344
20600
  var isAlive2;
20345
20601
  var pruneDead2;
20346
20602
  program.parse();