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.
- package/dist/agent/index.d.ts +3 -3
- package/dist/cli.js +348 -92
- package/dist/cli.js.map +1 -1
- package/dist/db/index.d.ts +2 -2
- package/dist/{index-BM99kjgq.d.ts → index-Bc0p0VPE.d.ts} +96 -96
- package/dist/index.d.ts +5 -5
- package/dist/index.js +292 -36
- package/dist/index.js.map +1 -1
- package/dist/{schema-Dz-wABVY.d.ts → schema-BSz4MzhJ.d.ts} +3 -3
- package/dist/{search-CVVfuBPZ.d.ts → search-DOzC4ojH.d.ts} +4 -4
- package/dist/server/index.js +292 -36
- package/dist/server/index.js.map +1 -1
- package/dist/tools/index.d.ts +3 -3
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/app-path-routes-manifest.json +1 -0
- package/web/.next/standalone/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/web/.next/routes-manifest.json +8 -0
- package/web/.next/standalone/web/.next/server/app/(main)/agents/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/(main)/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/(main)/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.html +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.rsc +4 -4
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/agents.segments/_full.segment.rsc +4 -4
- package/web/.next/standalone/web/.next/server/app/agents.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/agents.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/api/config/route.js +2 -1
- package/web/.next/standalone/web/.next/server/app/api/config/route.js.nft.json +1 -1
- package/web/.next/standalone/web/.next/server/app/api/health/route.js +2 -1
- package/web/.next/standalone/web/.next/server/app/api/health/route.js.nft.json +1 -1
- package/web/.next/standalone/web/.next/server/app/apple-icon.png/route.js +2 -1
- package/web/.next/standalone/web/.next/server/app/apple-icon.png/route.js.nft.json +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/favicon.ico/route.js +2 -1
- package/web/.next/standalone/web/.next/server/app/favicon.ico/route.js.nft.json +1 -1
- package/web/.next/standalone/web/.next/server/app/icon.png/route.js +2 -1
- package/web/.next/standalone/web/.next/server/app/icon.png/route.js.nft.json +1 -1
- package/web/.next/standalone/web/.next/server/app/index.html +1 -1
- package/web/.next/standalone/web/.next/server/app/index.rsc +4 -4
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/opengraph-image.png/route.js +2 -1
- package/web/.next/standalone/web/.next/server/app/opengraph-image.png/route.js.nft.json +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.html +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.rsc +4 -4
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings/__PAGE__.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/settings.segments/_full.segment.rsc +4 -4
- package/web/.next/standalone/web/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/sfapi/[...path]/route/app-paths-manifest.json +3 -0
- package/web/.next/standalone/web/.next/server/app/sfapi/[...path]/route/build-manifest.json +11 -0
- package/web/.next/standalone/web/.next/server/app/sfapi/[...path]/route/server-reference-manifest.json +4 -0
- package/web/.next/standalone/web/.next/server/app/sfapi/[...path]/route.js +6 -0
- package/web/.next/standalone/web/.next/server/app/sfapi/[...path]/route.js.map +5 -0
- package/web/.next/standalone/web/.next/server/app/sfapi/[...path]/route.js.nft.json +1 -0
- package/web/.next/standalone/web/.next/server/app/sfapi/[...path]/route_client-reference-manifest.js +2 -0
- package/web/.next/standalone/web/.next/server/app/twitter-image.png/route.js +2 -1
- package/web/.next/standalone/web/.next/server/app/twitter-image.png/route.js.nft.json +1 -1
- package/web/.next/standalone/web/.next/server/app-paths-manifest.json +1 -0
- package/web/.next/standalone/web/.next/server/chunks/2374f_next_bb86da32._.js +17 -0
- package/web/.next/standalone/web/.next/server/chunks/[root-of-the-server]__24426eb4._.js +7 -0
- package/web/.next/standalone/web/.next/server/chunks/[root-of-the-server]__912d97d3._.js +3 -0
- package/web/.next/standalone/web/.next/server/chunks/web__next-internal_server_app_sfapi_[___path]_route_actions_36c4ef97.js +3 -0
- package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
- package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
- package/web/.next/standalone/web/.next/static/chunks/7a7abb7146d0a913.js +1 -0
- package/web/.next/standalone/web/.next/static/static/chunks/7a7abb7146d0a913.js +1 -0
- package/web/.next/standalone/web/package-lock.json +12 -12
- package/web/.next/standalone/web/runtime-config.json +2 -1
- package/web/.next/standalone/web/src/app/sfapi/[...path]/route.ts +100 -0
- package/web/.next/standalone/web/src/lib/config.ts +23 -7
- package/web/.next/static/chunks/7a7abb7146d0a913.js +1 -0
- package/web/.next/standalone/web/.next/server/chunks/[root-of-the-server]__6aefd356._.js +0 -21
- package/web/.next/standalone/web/.next/static/chunks/5aece72c38f86fbd.js +0 -1
- package/web/.next/standalone/web/.next/static/static/chunks/5aece72c38f86fbd.js +0 -1
- package/web/.next/static/chunks/5aece72c38f86fbd.js +0 -1
- /package/web/.next/standalone/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_ssgManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_ssgManifest.js +0 -0
- /package/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_buildManifest.js +0 -0
- /package/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{KQbunVSU5tNoYBl7TnhLn → Mvd2J29fa2_xre21byVay}/_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
|
|
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:
|
|
1169
|
+
url: remoteUrl2,
|
|
1170
1170
|
authKey: remoteAuthKey,
|
|
1171
|
-
isConfigured: !!
|
|
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
|
|
4898
|
-
if (!
|
|
4897
|
+
const remoteUrl2 = getGitRemoteUrl(workingDirectory);
|
|
4898
|
+
if (!remoteUrl2) {
|
|
4899
4899
|
return null;
|
|
4900
4900
|
}
|
|
4901
|
-
const parsed = parseGitRemoteUrl(
|
|
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:
|
|
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 =
|
|
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:
|
|
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 :
|
|
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
|
|
13085
|
-
import { fileURLToPath as
|
|
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
|
|
13094
|
-
import { resolve as resolve12, dirname as
|
|
13095
|
-
import { spawn as
|
|
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
|
|
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 =
|
|
17826
|
+
const currentDir = dirname11(fileURLToPath5(import.meta.url));
|
|
17577
17827
|
const webDir = resolve12(currentDir, "..", "web");
|
|
17578
|
-
if (existsSync22(webDir) && existsSync22(
|
|
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(
|
|
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 =
|
|
17890
|
+
const buildIdPath = join19(webDir, ".next", "BUILD_ID");
|
|
17641
17891
|
return existsSync22(buildIdPath);
|
|
17642
17892
|
}
|
|
17643
17893
|
function hasSourceFiles(webDir) {
|
|
17644
|
-
const appDir =
|
|
17645
|
-
const pagesDir =
|
|
17646
|
-
const rootAppDir =
|
|
17647
|
-
const rootPagesDir =
|
|
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
|
-
|
|
17653
|
-
|
|
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 =
|
|
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(
|
|
17697
|
-
const useNpm = !usePnpm && existsSync22(
|
|
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 =
|
|
17951
|
+
const runtimeConfig = { apiBaseUrl: apiUrl, localApiBaseUrl: `http://127.0.0.1:${apiPort}` };
|
|
17952
|
+
const runtimeConfigPath = join19(webDir, "runtime-config.json");
|
|
17703
17953
|
try {
|
|
17704
|
-
|
|
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 =
|
|
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 =
|
|
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
|
|
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 (!
|
|
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 (!
|
|
17780
|
-
|
|
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 (!
|
|
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
|
-
|
|
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
|
|
18480
|
-
import { resolve as resolve13, join as
|
|
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 =
|
|
18738
|
+
const here = dirname12(fileURLToPath6(import.meta.url));
|
|
18483
18739
|
const candidates = [
|
|
18484
|
-
|
|
18485
|
-
|
|
18486
|
-
|
|
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(
|
|
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(
|
|
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) ?
|
|
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 =
|
|
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
|
-
|
|
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 ?
|
|
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(
|
|
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
|
-
|
|
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
|
|
19345
|
-
if (!
|
|
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(
|
|
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(`${
|
|
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 =
|
|
19543
|
-
const certPath =
|
|
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 ||
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
19742
|
-
if (!
|
|
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(
|
|
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:
|
|
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
|
|
19876
|
-
if (!
|
|
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(
|
|
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:
|
|
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
|
|
20131
|
-
},
|
|
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(
|
|
20391
|
+
return JSON.parse(readFileSync12(p, "utf-8"));
|
|
20136
20392
|
} catch {
|
|
20137
20393
|
return [];
|
|
20138
20394
|
}
|
|
20139
|
-
},
|
|
20140
|
-
|
|
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,
|
|
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())) :
|
|
20214
|
-
|
|
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 =
|
|
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(
|
|
20556
|
+
const rows = pruneDead(readState2());
|
|
20301
20557
|
rows.push(row);
|
|
20302
|
-
|
|
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 =
|
|
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
|
-
|
|
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(
|
|
20326
|
-
|
|
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 =
|
|
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
|
-
|
|
20592
|
+
writeState2([]);
|
|
20337
20593
|
console.log(JSON.stringify({ stopped }));
|
|
20338
20594
|
});
|
|
20339
20595
|
}
|
|
20340
20596
|
var shellEscape3;
|
|
20341
20597
|
var stateFilePath2;
|
|
20342
|
-
var
|
|
20343
|
-
var
|
|
20598
|
+
var readState3;
|
|
20599
|
+
var writeState3;
|
|
20344
20600
|
var isAlive2;
|
|
20345
20601
|
var pruneDead2;
|
|
20346
20602
|
program.parse();
|