sparkecoder 0.1.131 → 0.1.133

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 (155) hide show
  1. package/dist/agent/index.d.ts +3 -3
  2. package/dist/cli.js +348 -92
  3. package/dist/cli.js.map +1 -1
  4. package/dist/db/index.d.ts +2 -2
  5. package/dist/{index-BM99kjgq.d.ts → index-Bc0p0VPE.d.ts} +96 -96
  6. package/dist/index.d.ts +5 -5
  7. package/dist/index.js +292 -36
  8. package/dist/index.js.map +1 -1
  9. package/dist/{schema-Dz-wABVY.d.ts → schema-BSz4MzhJ.d.ts} +3 -3
  10. package/dist/{search-CVVfuBPZ.d.ts → search-DOzC4ojH.d.ts} +4 -4
  11. package/dist/server/index.js +292 -36
  12. package/dist/server/index.js.map +1 -1
  13. package/dist/tools/index.d.ts +3 -3
  14. package/package.json +1 -1
  15. package/web/.next/BUILD_ID +1 -1
  16. package/web/.next/standalone/web/.next/BUILD_ID +1 -1
  17. package/web/.next/standalone/web/.next/app-path-routes-manifest.json +1 -0
  18. package/web/.next/standalone/web/.next/build-manifest.json +2 -2
  19. package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
  20. package/web/.next/standalone/web/.next/routes-manifest.json +8 -0
  21. package/web/.next/standalone/web/.next/server/app/(main)/agents/page_client-reference-manifest.js +1 -1
  22. package/web/.next/standalone/web/.next/server/app/(main)/page_client-reference-manifest.js +1 -1
  23. package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page_client-reference-manifest.js +1 -1
  24. package/web/.next/standalone/web/.next/server/app/(main)/settings/page_client-reference-manifest.js +1 -1
  25. package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
  26. package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
  27. package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  28. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  29. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  30. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  31. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  32. package/web/.next/standalone/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  33. package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
  34. package/web/.next/standalone/web/.next/server/app/_not-found.rsc +2 -2
  35. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  36. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  37. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  38. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  39. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  40. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  41. package/web/.next/standalone/web/.next/server/app/agents.html +1 -1
  42. package/web/.next/standalone/web/.next/server/app/agents.rsc +4 -4
  43. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +2 -2
  44. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents.segment.rsc +1 -1
  45. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p.segment.rsc +2 -2
  46. package/web/.next/standalone/web/.next/server/app/agents.segments/_full.segment.rsc +4 -4
  47. package/web/.next/standalone/web/.next/server/app/agents.segments/_head.segment.rsc +1 -1
  48. package/web/.next/standalone/web/.next/server/app/agents.segments/_index.segment.rsc +2 -2
  49. package/web/.next/standalone/web/.next/server/app/agents.segments/_tree.segment.rsc +1 -1
  50. package/web/.next/standalone/web/.next/server/app/api/config/route.js +2 -1
  51. package/web/.next/standalone/web/.next/server/app/api/config/route.js.nft.json +1 -1
  52. package/web/.next/standalone/web/.next/server/app/api/health/route.js +2 -1
  53. package/web/.next/standalone/web/.next/server/app/api/health/route.js.nft.json +1 -1
  54. package/web/.next/standalone/web/.next/server/app/apple-icon.png/route.js +2 -1
  55. package/web/.next/standalone/web/.next/server/app/apple-icon.png/route.js.nft.json +1 -1
  56. package/web/.next/standalone/web/.next/server/app/docs/installation/page_client-reference-manifest.js +1 -1
  57. package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
  58. package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +3 -3
  59. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +3 -3
  60. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
  61. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +2 -2
  62. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
  63. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +2 -2
  64. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
  65. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +2 -2
  66. package/web/.next/standalone/web/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  67. package/web/.next/standalone/web/.next/server/app/docs/skills/page_client-reference-manifest.js +1 -1
  68. package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
  69. package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +3 -3
  70. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +3 -3
  71. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
  72. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +2 -2
  73. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
  74. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
  75. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
  76. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +2 -2
  77. package/web/.next/standalone/web/.next/server/app/docs/tools/page_client-reference-manifest.js +1 -1
  78. package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
  79. package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +3 -3
  80. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +3 -3
  81. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
  82. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +2 -2
  83. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
  84. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +2 -2
  85. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
  86. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +2 -2
  87. package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
  88. package/web/.next/standalone/web/.next/server/app/docs.rsc +3 -3
  89. package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +3 -3
  90. package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
  91. package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +2 -2
  92. package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
  93. package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +2 -2
  94. package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +2 -2
  95. package/web/.next/standalone/web/.next/server/app/favicon.ico/route.js +2 -1
  96. package/web/.next/standalone/web/.next/server/app/favicon.ico/route.js.nft.json +1 -1
  97. package/web/.next/standalone/web/.next/server/app/icon.png/route.js +2 -1
  98. package/web/.next/standalone/web/.next/server/app/icon.png/route.js.nft.json +1 -1
  99. package/web/.next/standalone/web/.next/server/app/index.html +1 -1
  100. package/web/.next/standalone/web/.next/server/app/index.rsc +4 -4
  101. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +2 -2
  102. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +2 -2
  103. package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +4 -4
  104. package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  105. package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +2 -2
  106. package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  107. package/web/.next/standalone/web/.next/server/app/opengraph-image.png/route.js +2 -1
  108. package/web/.next/standalone/web/.next/server/app/opengraph-image.png/route.js.nft.json +1 -1
  109. package/web/.next/standalone/web/.next/server/app/settings.html +1 -1
  110. package/web/.next/standalone/web/.next/server/app/settings.rsc +4 -4
  111. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings/__PAGE__.segment.rsc +2 -2
  112. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings.segment.rsc +1 -1
  113. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p.segment.rsc +2 -2
  114. package/web/.next/standalone/web/.next/server/app/settings.segments/_full.segment.rsc +4 -4
  115. package/web/.next/standalone/web/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  116. package/web/.next/standalone/web/.next/server/app/settings.segments/_index.segment.rsc +2 -2
  117. package/web/.next/standalone/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  118. package/web/.next/standalone/web/.next/server/app/sfapi/[...path]/route/app-paths-manifest.json +3 -0
  119. package/web/.next/standalone/web/.next/server/app/sfapi/[...path]/route/build-manifest.json +11 -0
  120. package/web/.next/standalone/web/.next/server/app/sfapi/[...path]/route/server-reference-manifest.json +4 -0
  121. package/web/.next/standalone/web/.next/server/app/sfapi/[...path]/route.js +6 -0
  122. package/web/.next/standalone/web/.next/server/app/sfapi/[...path]/route.js.map +5 -0
  123. package/web/.next/standalone/web/.next/server/app/sfapi/[...path]/route.js.nft.json +1 -0
  124. package/web/.next/standalone/web/.next/server/app/sfapi/[...path]/route_client-reference-manifest.js +2 -0
  125. package/web/.next/standalone/web/.next/server/app/twitter-image.png/route.js +2 -1
  126. package/web/.next/standalone/web/.next/server/app/twitter-image.png/route.js.nft.json +1 -1
  127. package/web/.next/standalone/web/.next/server/app-paths-manifest.json +1 -0
  128. package/web/.next/standalone/web/.next/server/chunks/2374f_next_bb86da32._.js +17 -0
  129. package/web/.next/standalone/web/.next/server/chunks/[root-of-the-server]__24426eb4._.js +7 -0
  130. package/web/.next/standalone/web/.next/server/chunks/[root-of-the-server]__912d97d3._.js +3 -0
  131. package/web/.next/standalone/web/.next/server/chunks/web__next-internal_server_app_sfapi_[___path]_route_actions_36c4ef97.js +3 -0
  132. package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
  133. package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
  134. package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
  135. package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
  136. package/web/.next/standalone/web/.next/static/chunks/7a7abb7146d0a913.js +1 -0
  137. package/web/.next/standalone/web/.next/static/static/chunks/7a7abb7146d0a913.js +1 -0
  138. package/web/.next/standalone/web/package-lock.json +12 -12
  139. package/web/.next/standalone/web/runtime-config.json +2 -1
  140. package/web/.next/standalone/web/src/app/sfapi/[...path]/route.ts +100 -0
  141. package/web/.next/standalone/web/src/lib/config.ts +23 -7
  142. package/web/.next/static/chunks/7a7abb7146d0a913.js +1 -0
  143. package/web/.next/standalone/web/.next/server/chunks/[root-of-the-server]__6aefd356._.js +0 -21
  144. package/web/.next/standalone/web/.next/static/chunks/5aece72c38f86fbd.js +0 -1
  145. package/web/.next/standalone/web/.next/static/static/chunks/5aece72c38f86fbd.js +0 -1
  146. package/web/.next/static/chunks/5aece72c38f86fbd.js +0 -1
  147. /package/web/.next/standalone/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_buildManifest.js +0 -0
  148. /package/web/.next/standalone/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_clientMiddlewareManifest.json +0 -0
  149. /package/web/.next/standalone/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_ssgManifest.js +0 -0
  150. /package/web/.next/standalone/web/.next/static/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_buildManifest.js +0 -0
  151. /package/web/.next/standalone/web/.next/static/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_clientMiddlewareManifest.json +0 -0
  152. /package/web/.next/standalone/web/.next/static/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_ssgManifest.js +0 -0
  153. /package/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_buildManifest.js +0 -0
  154. /package/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_clientMiddlewareManifest.json +0 -0
  155. /package/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_ssgManifest.js +0 -0
package/dist/index.js CHANGED
@@ -649,12 +649,12 @@ function loadConfig(configPath, workingDirectory) {
649
649
  ]
650
650
  };
651
651
  const DEFAULT_REMOTE_URL = "https://agent-remote-server.sparkecode.com";
652
- const remoteUrl = process.env.SPARKECODER_REMOTE_URL || config.remoteServer?.url || DEFAULT_REMOTE_URL;
652
+ const remoteUrl2 = process.env.SPARKECODER_REMOTE_URL || config.remoteServer?.url || DEFAULT_REMOTE_URL;
653
653
  const remoteAuthKey = process.env.SPARKECODER_AUTH_KEY || config.remoteServer?.authKey || loadStoredAuthKey();
654
654
  const resolvedRemoteServer = {
655
- url: remoteUrl,
655
+ url: remoteUrl2,
656
656
  authKey: remoteAuthKey,
657
- isConfigured: !!remoteUrl && !!remoteAuthKey
657
+ isConfigured: !!remoteUrl2 && !!remoteAuthKey
658
658
  };
659
659
  const resolved = {
660
660
  ...config,
@@ -4910,11 +4910,11 @@ async function getRepoNamespace(workingDirectory, configuredNamespace) {
4910
4910
  if (configuredNamespace) {
4911
4911
  return configuredNamespace;
4912
4912
  }
4913
- const remoteUrl = getGitRemoteUrl(workingDirectory);
4914
- if (!remoteUrl) {
4913
+ const remoteUrl2 = getGitRemoteUrl(workingDirectory);
4914
+ if (!remoteUrl2) {
4915
4915
  return null;
4916
4916
  }
4917
- const parsed = parseGitRemoteUrl(remoteUrl);
4917
+ const parsed = parseGitRemoteUrl(remoteUrl2);
4918
4918
  if (!parsed) {
4919
4919
  return null;
4920
4920
  }
@@ -8362,6 +8362,29 @@ var init_persistence = __esm({
8362
8362
  });
8363
8363
 
8364
8364
  // src/integrations/slack/client.ts
8365
+ var client_exports = {};
8366
+ __export(client_exports, {
8367
+ LOADING_REACTION: () => LOADING_REACTION,
8368
+ RESULT_REACTIONS: () => RESULT_REACTIONS,
8369
+ addLoadingReaction: () => addLoadingReaction,
8370
+ addResultReaction: () => addResultReaction,
8371
+ botParticipatedInThread: () => botParticipatedInThread,
8372
+ ensureSlackSelfIdentity: () => ensureSlackSelfIdentity,
8373
+ getCachedSlackSelfIdentity: () => getCachedSlackSelfIdentity,
8374
+ getDefaultOrchestratorName: () => getDefaultOrchestratorName,
8375
+ getSlackAdapter: () => getSlackAdapter,
8376
+ getSlackAllowlistPolicy: () => getSlackAllowlistPolicy,
8377
+ getSlackBotToken: () => getSlackBotToken,
8378
+ getSlackDeniedReplyPolicy: () => getSlackDeniedReplyPolicy,
8379
+ getSlackSigningSecret: () => getSlackSigningSecret,
8380
+ isSlackConfigured: () => isSlackConfigured,
8381
+ normalizeSlackMentions: () => normalizeSlackMentions,
8382
+ noteBotPostedInThread: () => noteBotPostedInThread,
8383
+ postThreadMessage: () => postThreadMessage,
8384
+ removeLoadingReaction: () => removeLoadingReaction,
8385
+ resolveSlackUserInfo: () => resolveSlackUserInfo,
8386
+ resolveSlackUserName: () => resolveSlackUserName
8387
+ });
8365
8388
  function slackBackoffMs(attempt) {
8366
8389
  const expo = SLACK_BACKOFF_BASE_MS * 2 ** attempt;
8367
8390
  const jitter = Math.floor(Math.random() * SLACK_BACKOFF_BASE_MS);
@@ -11678,11 +11701,11 @@ ${p.text}` : p.text;
11678
11701
  const { isRemoteConfigured: isRemoteConfigured2, storageQueries: storageQueries2 } = await Promise.resolve().then(() => (init_remote(), remote_exports));
11679
11702
  if (!isRemoteConfigured2()) return [];
11680
11703
  const { readFile: readFile13 } = await import("fs/promises");
11681
- const { join: join19, basename: basename7 } = await import("path");
11704
+ const { join: join20, basename: basename7 } = await import("path");
11682
11705
  const urls = [];
11683
11706
  for (const filePath of filePaths) {
11684
11707
  try {
11685
- const fullPath = filePath.startsWith("/") ? filePath : join19(this.session.workingDirectory, filePath);
11708
+ const fullPath = filePath.startsWith("/") ? filePath : join20(this.session.workingDirectory, filePath);
11686
11709
  const fileName = basename7(fullPath);
11687
11710
  const ext = fileName.split(".").pop()?.toLowerCase() || "";
11688
11711
  const mimeMap = {
@@ -12053,6 +12076,233 @@ var init_ensure_orchestrator = __esm({
12053
12076
  }
12054
12077
  });
12055
12078
 
12079
+ // src/orchestrator/self-update.ts
12080
+ var self_update_exports = {};
12081
+ __export(self_update_exports, {
12082
+ __test: () => __test,
12083
+ startSelfUpdater: () => startSelfUpdater,
12084
+ stopSelfUpdater: () => stopSelfUpdater
12085
+ });
12086
+ import { spawn as spawn2, execFile } from "child_process";
12087
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync7, mkdirSync as mkdirSync10 } from "fs";
12088
+ import { dirname as dirname10, join as join18 } from "path";
12089
+ import { fileURLToPath as fileURLToPath4 } from "url";
12090
+ function currentVersion2() {
12091
+ const here = dirname10(fileURLToPath4(import.meta.url));
12092
+ const candidates = [
12093
+ join18(here, "..", "..", "package.json"),
12094
+ join18(here, "..", "package.json"),
12095
+ join18(process.cwd(), "package.json")
12096
+ ];
12097
+ for (const p of candidates) {
12098
+ try {
12099
+ const pkg = JSON.parse(readFileSync11(p, "utf8"));
12100
+ if (pkg.name === "sparkecoder" && pkg.version) return pkg.version;
12101
+ } catch {
12102
+ }
12103
+ }
12104
+ return "0.0.0";
12105
+ }
12106
+ function isLikelyGlobalInstall() {
12107
+ const here = dirname10(fileURLToPath4(import.meta.url));
12108
+ return here.includes("/node_modules/sparkecoder/") || here.includes("\\node_modules\\sparkecoder\\");
12109
+ }
12110
+ function isEnabled() {
12111
+ if (process.env.SPARKECODER_AUTO_UPDATE === "false" || process.env.SPARKECODER_AUTO_UPDATE === "0") return false;
12112
+ try {
12113
+ const cfg = getConfig();
12114
+ if (cfg?.autoUpdate?.enabled === false) return false;
12115
+ } catch {
12116
+ }
12117
+ return true;
12118
+ }
12119
+ function remoteUrl() {
12120
+ try {
12121
+ const cfg = getConfig();
12122
+ const url = cfg?.remoteServer?.url;
12123
+ return typeof url === "string" && url.length > 0 ? url.replace(/\/+$/, "") : null;
12124
+ } catch {
12125
+ return null;
12126
+ }
12127
+ }
12128
+ function intervalMs() {
12129
+ try {
12130
+ const h = getConfig()?.autoUpdate?.intervalHours;
12131
+ if (typeof h === "number" && h > 0) return h * 60 * 6e4;
12132
+ } catch {
12133
+ }
12134
+ return DEFAULT_INTERVAL_HOURS * 60 * 6e4;
12135
+ }
12136
+ function semverGt(a, b) {
12137
+ const parse = (v) => v.split("-")[0].split(".").map((n) => parseInt(n, 10) || 0);
12138
+ const pa = parse(a);
12139
+ const pb = parse(b);
12140
+ for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
12141
+ const x = pa[i] ?? 0;
12142
+ const y = pb[i] ?? 0;
12143
+ if (x > y) return true;
12144
+ if (x < y) return false;
12145
+ }
12146
+ return false;
12147
+ }
12148
+ function statePath() {
12149
+ try {
12150
+ return join18(getAppDataDirectory(), "self-update-state.json");
12151
+ } catch {
12152
+ return null;
12153
+ }
12154
+ }
12155
+ function readState() {
12156
+ const p = statePath();
12157
+ if (!p) return {};
12158
+ try {
12159
+ return JSON.parse(readFileSync11(p, "utf8"));
12160
+ } catch {
12161
+ return {};
12162
+ }
12163
+ }
12164
+ function writeState(s) {
12165
+ const p = statePath();
12166
+ if (!p) return;
12167
+ try {
12168
+ mkdirSync10(dirname10(p), { recursive: true });
12169
+ writeFileSync7(p, JSON.stringify(s));
12170
+ } catch {
12171
+ }
12172
+ }
12173
+ function attemptedRecently(target, now) {
12174
+ const s = readState();
12175
+ return s.lastTarget === target && typeof s.lastAttemptAt === "number" && now - s.lastAttemptAt < RETRY_COOLDOWN_MS;
12176
+ }
12177
+ function latestPublishedVersion() {
12178
+ return new Promise((resolve13) => {
12179
+ execFile("npm", ["view", "sparkecoder", "version"], { timeout: 3e4 }, (err, stdout) => {
12180
+ if (err) {
12181
+ resolve13(null);
12182
+ return;
12183
+ }
12184
+ const v = String(stdout).trim();
12185
+ resolve13(/^\d+\.\d+\.\d+/.test(v) ? v : null);
12186
+ });
12187
+ });
12188
+ }
12189
+ function runInstaller(url) {
12190
+ const secret = process.env.SPARKECODER_SETUP_SECRET || process.env.SPARKECODER_TUNNEL_SECRET || "";
12191
+ const query = secret ? `?secret=${encodeURIComponent(secret)}` : "";
12192
+ const oneLiner = `bash -c "$(curl -fsSL '${url}/install.sh${query}')" >/tmp/sparkecoder-selfupdate.log 2>&1`;
12193
+ const child = spawn2("bash", ["-lc", oneLiner], {
12194
+ detached: true,
12195
+ stdio: "ignore"
12196
+ });
12197
+ child.unref();
12198
+ }
12199
+ async function checkAndUpdate() {
12200
+ if (upgrading || !isEnabled()) return;
12201
+ const url = remoteUrl();
12202
+ if (!url) return;
12203
+ const latest = await latestPublishedVersion();
12204
+ if (!latest) return;
12205
+ const current = currentVersion2();
12206
+ if (!semverGt(latest, current)) return;
12207
+ const now = Date.now();
12208
+ if (attemptedRecently(latest, now)) {
12209
+ console.log(`[self-update] v${latest} already attempted recently; skipping until cooldown elapses`);
12210
+ return;
12211
+ }
12212
+ upgrading = true;
12213
+ const announced = await announceUpdate(latest);
12214
+ const delay = announced ? ANNOUNCE_GRACE_MS : 0;
12215
+ if (announced) {
12216
+ console.log(`[self-update] announced v${latest} in Slack; updating in ${Math.round(delay / 6e4)}m`);
12217
+ }
12218
+ const t = setTimeout(() => doInstall(latest, url, current), delay);
12219
+ if (typeof t.unref === "function") t.unref();
12220
+ }
12221
+ function doInstall(latest, url, current) {
12222
+ const prev = readState();
12223
+ writeState({
12224
+ lastTarget: latest,
12225
+ lastAttemptAt: Date.now(),
12226
+ attempts: prev.lastTarget === latest ? (prev.attempts ?? 0) + 1 : 1
12227
+ });
12228
+ console.log(`[self-update] newer version available: v${current} \u2192 v${latest}; re-running installer`);
12229
+ try {
12230
+ runInstaller(url);
12231
+ } catch (err) {
12232
+ upgrading = false;
12233
+ console.warn("[self-update] failed to launch installer:", err?.message || err);
12234
+ }
12235
+ }
12236
+ async function findOrchestratorId() {
12237
+ try {
12238
+ const { sessionQueries: sessionQueries2 } = await Promise.resolve().then(() => (init_db(), db_exports));
12239
+ const all = await sessionQueries2.list(500, 0);
12240
+ const orch = all.find((s) => s?.config?.role === "orchestrator");
12241
+ return orch?.id ?? null;
12242
+ } catch {
12243
+ return null;
12244
+ }
12245
+ }
12246
+ async function announceUpdate(target) {
12247
+ try {
12248
+ const { isSlackConfigured: isSlackConfigured2 } = await Promise.resolve().then(() => (init_client3(), client_exports));
12249
+ if (!isSlackConfigured2()) return false;
12250
+ const orchId = await findOrchestratorId();
12251
+ if (!orchId) return false;
12252
+ const { pushToInbox: pushToInbox2 } = await Promise.resolve().then(() => (init_inbox(), inbox_exports));
12253
+ pushToInbox2(orchId, {
12254
+ ref: { channel: "system", kind: "worker.completed", workerId: "self-update", workerName: "self-update" },
12255
+ 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.`,
12256
+ wake: "now",
12257
+ enqueuedAt: /* @__PURE__ */ new Date()
12258
+ });
12259
+ return true;
12260
+ } catch {
12261
+ return false;
12262
+ }
12263
+ }
12264
+ function startSelfUpdater() {
12265
+ if (started) return;
12266
+ started = true;
12267
+ if (!isEnabled()) {
12268
+ console.log("[self-update] disabled");
12269
+ return;
12270
+ }
12271
+ if (!isLikelyGlobalInstall()) {
12272
+ console.log("[self-update] skipped (not a global install)");
12273
+ return;
12274
+ }
12275
+ const kickoff = setTimeout(() => {
12276
+ void checkAndUpdate();
12277
+ timer = setInterval(() => {
12278
+ void checkAndUpdate();
12279
+ }, intervalMs());
12280
+ if (typeof timer.unref === "function") timer.unref();
12281
+ }, INITIAL_DELAY_MS);
12282
+ if (typeof kickoff.unref === "function") kickoff.unref();
12283
+ }
12284
+ function stopSelfUpdater() {
12285
+ if (timer) {
12286
+ clearInterval(timer);
12287
+ timer = null;
12288
+ }
12289
+ }
12290
+ var INITIAL_DELAY_MS, DEFAULT_INTERVAL_HOURS, ANNOUNCE_GRACE_MS, RETRY_COOLDOWN_MS, timer, started, upgrading, __test;
12291
+ var init_self_update = __esm({
12292
+ "src/orchestrator/self-update.ts"() {
12293
+ "use strict";
12294
+ init_config();
12295
+ INITIAL_DELAY_MS = 5 * 6e4;
12296
+ DEFAULT_INTERVAL_HOURS = 6;
12297
+ ANNOUNCE_GRACE_MS = 5 * 6e4;
12298
+ RETRY_COOLDOWN_MS = 24 * 60 * 6e4;
12299
+ timer = null;
12300
+ started = false;
12301
+ upgrading = false;
12302
+ __test = { currentVersion: currentVersion2, semverGt, isLikelyGlobalInstall };
12303
+ }
12304
+ });
12305
+
12056
12306
  // src/tasks/scheduler.ts
12057
12307
  var scheduler_exports = {};
12058
12308
  __export(scheduler_exports, {
@@ -12139,11 +12389,11 @@ import { Hono as Hono10 } from "hono";
12139
12389
  import { serve } from "@hono/node-server";
12140
12390
  import { cors } from "hono/cors";
12141
12391
  import { logger } from "hono/logger";
12142
- import { existsSync as existsSync22, mkdirSync as mkdirSync10, writeFileSync as writeFileSync7 } from "fs";
12143
- import { resolve as resolve12, dirname as dirname10, join as join18 } from "path";
12144
- import { spawn as spawn2 } from "child_process";
12392
+ import { existsSync as existsSync22, mkdirSync as mkdirSync11, writeFileSync as writeFileSync8 } from "fs";
12393
+ import { resolve as resolve12, dirname as dirname11, join as join19 } from "path";
12394
+ import { spawn as spawn3 } from "child_process";
12145
12395
  import { createServer as createNetServer } from "net";
12146
- import { fileURLToPath as fileURLToPath4 } from "url";
12396
+ import { fileURLToPath as fileURLToPath5 } from "url";
12147
12397
 
12148
12398
  // src/server/routes/sessions.ts
12149
12399
  init_db();
@@ -16526,13 +16776,13 @@ var DEFAULT_WEB_PORT = 6969;
16526
16776
  var WEB_PORT_SEQUENCE = [6969, 6970, 6971, 6972, 6973, 6974, 6975, 6976, 6977, 6978];
16527
16777
  function getWebDirectory() {
16528
16778
  try {
16529
- const currentDir = dirname10(fileURLToPath4(import.meta.url));
16779
+ const currentDir = dirname11(fileURLToPath5(import.meta.url));
16530
16780
  const webDir = resolve12(currentDir, "..", "web");
16531
- if (existsSync22(webDir) && existsSync22(join18(webDir, "package.json"))) {
16781
+ if (existsSync22(webDir) && existsSync22(join19(webDir, "package.json"))) {
16532
16782
  return webDir;
16533
16783
  }
16534
16784
  const altWebDir = resolve12(currentDir, "..", "..", "web");
16535
- if (existsSync22(altWebDir) && existsSync22(join18(altWebDir, "package.json"))) {
16785
+ if (existsSync22(altWebDir) && existsSync22(join19(altWebDir, "package.json"))) {
16536
16786
  return altWebDir;
16537
16787
  }
16538
16788
  return null;
@@ -16590,20 +16840,20 @@ async function findWebPort(preferredPort) {
16590
16840
  return { port: preferredPort, alreadyRunning: false };
16591
16841
  }
16592
16842
  function hasProductionBuild(webDir) {
16593
- const buildIdPath = join18(webDir, ".next", "BUILD_ID");
16843
+ const buildIdPath = join19(webDir, ".next", "BUILD_ID");
16594
16844
  return existsSync22(buildIdPath);
16595
16845
  }
16596
16846
  function hasSourceFiles(webDir) {
16597
- const appDir = join18(webDir, "src", "app");
16598
- const pagesDir = join18(webDir, "src", "pages");
16599
- const rootAppDir = join18(webDir, "app");
16600
- const rootPagesDir = join18(webDir, "pages");
16847
+ const appDir = join19(webDir, "src", "app");
16848
+ const pagesDir = join19(webDir, "src", "pages");
16849
+ const rootAppDir = join19(webDir, "app");
16850
+ const rootPagesDir = join19(webDir, "pages");
16601
16851
  return existsSync22(appDir) || existsSync22(pagesDir) || existsSync22(rootAppDir) || existsSync22(rootPagesDir);
16602
16852
  }
16603
16853
  function getStandaloneServerPath(webDir) {
16604
16854
  const possiblePaths2 = [
16605
- join18(webDir, ".next", "standalone", "server.js"),
16606
- join18(webDir, ".next", "standalone", "web", "server.js")
16855
+ join19(webDir, ".next", "standalone", "server.js"),
16856
+ join19(webDir, ".next", "standalone", "web", "server.js")
16607
16857
  ];
16608
16858
  for (const serverPath of possiblePaths2) {
16609
16859
  if (existsSync22(serverPath)) {
@@ -16614,7 +16864,7 @@ function getStandaloneServerPath(webDir) {
16614
16864
  }
16615
16865
  function runCommand(command, args, cwd, env) {
16616
16866
  return new Promise((resolve13) => {
16617
- const child = spawn2(command, args, {
16867
+ const child = spawn3(command, args, {
16618
16868
  cwd,
16619
16869
  stdio: ["ignore", "pipe", "pipe"],
16620
16870
  env,
@@ -16646,15 +16896,15 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false, pu
16646
16896
  if (!quiet) console.log(` \u2713 Web UI already running at http://localhost:${actualPort}`);
16647
16897
  return { process: null, port: actualPort };
16648
16898
  }
16649
- const usePnpm = existsSync22(join18(webDir, "pnpm-lock.yaml"));
16650
- const useNpm = !usePnpm && existsSync22(join18(webDir, "package-lock.json"));
16899
+ const usePnpm = existsSync22(join19(webDir, "pnpm-lock.yaml"));
16900
+ const useNpm = !usePnpm && existsSync22(join19(webDir, "package-lock.json"));
16651
16901
  const pkgManager = usePnpm ? "pnpm" : useNpm ? "npm" : "npx";
16652
16902
  const { NODE_OPTIONS, TSX_TSCONFIG_PATH, ...cleanEnv } = process.env;
16653
16903
  const apiUrl = publicUrl || `http://127.0.0.1:${apiPort}`;
16654
- const runtimeConfig = { apiBaseUrl: apiUrl };
16655
- const runtimeConfigPath = join18(webDir, "runtime-config.json");
16904
+ const runtimeConfig = { apiBaseUrl: apiUrl, localApiBaseUrl: `http://127.0.0.1:${apiPort}` };
16905
+ const runtimeConfigPath = join19(webDir, "runtime-config.json");
16656
16906
  try {
16657
- writeFileSync7(runtimeConfigPath, JSON.stringify(runtimeConfig, null, 2));
16907
+ writeFileSync8(runtimeConfigPath, JSON.stringify(runtimeConfig, null, 2));
16658
16908
  if (!quiet) console.log(` \u{1F4DD} Runtime config written to ${runtimeConfigPath}`);
16659
16909
  } catch (err) {
16660
16910
  if (!quiet) console.warn(` \u26A0 Could not write runtime config: ${err}`);
@@ -16674,7 +16924,7 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false, pu
16674
16924
  if (standaloneServerPath) {
16675
16925
  command = "node";
16676
16926
  args = ["server.js"];
16677
- cwd = dirname10(standaloneServerPath);
16927
+ cwd = dirname11(standaloneServerPath);
16678
16928
  webEnv.PORT = String(actualPort);
16679
16929
  webEnv.HOSTNAME = "0.0.0.0";
16680
16930
  if (!quiet) console.log(" \u{1F4E6} Starting Web UI from standalone build...");
@@ -16704,7 +16954,7 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false, pu
16704
16954
  }
16705
16955
  return { process: null, port: actualPort };
16706
16956
  }
16707
- const child = spawn2(command, args, {
16957
+ const child = spawn3(command, args, {
16708
16958
  cwd,
16709
16959
  stdio: ["ignore", "pipe", "pipe"],
16710
16960
  env: webEnv,
@@ -16712,12 +16962,12 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false, pu
16712
16962
  shell: true
16713
16963
  });
16714
16964
  const startupTimeout = 3e4;
16715
- let started = false;
16965
+ let started2 = false;
16716
16966
  let exited = false;
16717
16967
  let exitCode = null;
16718
16968
  const startedPromise = new Promise((resolve13) => {
16719
16969
  const timeout = setTimeout(() => {
16720
- if (!started && !exited) {
16970
+ if (!started2 && !exited) {
16721
16971
  resolve13(false);
16722
16972
  }
16723
16973
  }, startupTimeout);
@@ -16729,8 +16979,8 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false, pu
16729
16979
  console.log(` Web UI: ${line}`);
16730
16980
  }
16731
16981
  }
16732
- if (!started && (output.includes("Ready") || output.includes("started") || output.includes("localhost"))) {
16733
- started = true;
16982
+ if (!started2 && (output.includes("Ready") || output.includes("started") || output.includes("localhost"))) {
16983
+ started2 = true;
16734
16984
  clearTimeout(timeout);
16735
16985
  resolve13(true);
16736
16986
  }
@@ -16749,7 +16999,7 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false, pu
16749
16999
  child.on("exit", (code) => {
16750
17000
  exited = true;
16751
17001
  exitCode = code;
16752
- if (!started) {
17002
+ if (!started2) {
16753
17003
  clearTimeout(timeout);
16754
17004
  resolve13(false);
16755
17005
  }
@@ -16869,7 +17119,7 @@ async function startServer(options = {}) {
16869
17119
  config.resolvedWorkingDirectory = options.workingDirectory;
16870
17120
  }
16871
17121
  if (!existsSync22(config.resolvedWorkingDirectory)) {
16872
- mkdirSync10(config.resolvedWorkingDirectory, { recursive: true });
17122
+ mkdirSync11(config.resolvedWorkingDirectory, { recursive: true });
16873
17123
  if (!options.quiet) console.log(`\u{1F4C1} Created agent workspace: ${config.resolvedWorkingDirectory}`);
16874
17124
  }
16875
17125
  if (!config.resolvedRemoteServer.url) {
@@ -16905,6 +17155,12 @@ async function startServer(options = {}) {
16905
17155
  } catch (err) {
16906
17156
  if (!options.quiet) console.warn(`[daemon] start skipped: ${err.message}`);
16907
17157
  }
17158
+ try {
17159
+ const { startSelfUpdater: startSelfUpdater2 } = await Promise.resolve().then(() => (init_self_update(), self_update_exports));
17160
+ startSelfUpdater2();
17161
+ } catch (err) {
17162
+ if (!options.quiet) console.warn(`[self-update] start skipped: ${err.message}`);
17163
+ }
16908
17164
  try {
16909
17165
  const { startScheduler: startScheduler2 } = await Promise.resolve().then(() => (init_scheduler(), scheduler_exports));
16910
17166
  startScheduler2({ quiet: options.quiet });