sparkecoder 0.1.118 → 0.1.119
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.js +1 -1
- package/dist/agent/index.js.map +1 -1
- package/dist/cli.js +74 -10
- package/dist/cli.js.map +1 -1
- package/dist/index.js +73 -9
- package/dist/index.js.map +1 -1
- package/dist/server/index.js +73 -9
- package/dist/server/index.js.map +1 -1
- package/dist/tools/index.js.map +1 -1
- 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/build-manifest.json +2 -2
- package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
- 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.html +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_tree.segment.rsc +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 +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +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 +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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 +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 +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.html +1 -1
- package/web/.next/standalone/web/.next/server/app/index.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.html +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings/__PAGE__.segment.rsc +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- 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/{T8x1J_CS0n9FaWBr5GhLe → Bt00m8W4k5F79ALhN700F}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{T8x1J_CS0n9FaWBr5GhLe → Bt00m8W4k5F79ALhN700F}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{T8x1J_CS0n9FaWBr5GhLe → Bt00m8W4k5F79ALhN700F}/_ssgManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{T8x1J_CS0n9FaWBr5GhLe → Bt00m8W4k5F79ALhN700F}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{T8x1J_CS0n9FaWBr5GhLe → Bt00m8W4k5F79ALhN700F}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/static/{T8x1J_CS0n9FaWBr5GhLe → Bt00m8W4k5F79ALhN700F}/_ssgManifest.js +0 -0
- /package/web/.next/static/{T8x1J_CS0n9FaWBr5GhLe → Bt00m8W4k5F79ALhN700F}/_buildManifest.js +0 -0
- /package/web/.next/static/{T8x1J_CS0n9FaWBr5GhLe → Bt00m8W4k5F79ALhN700F}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{T8x1J_CS0n9FaWBr5GhLe → Bt00m8W4k5F79ALhN700F}/_ssgManifest.js +0 -0
package/dist/index.js
CHANGED
|
@@ -646,7 +646,7 @@ function loadConfig(configPath, workingDirectory) {
|
|
|
646
646
|
...config,
|
|
647
647
|
server: {
|
|
648
648
|
port: config.server.port,
|
|
649
|
-
host: config.server.host ?? "
|
|
649
|
+
host: config.server.host ?? "0.0.0.0",
|
|
650
650
|
publicUrl: config.server.publicUrl
|
|
651
651
|
},
|
|
652
652
|
resolvedWorkingDirectory,
|
|
@@ -813,7 +813,7 @@ function createDefaultConfig() {
|
|
|
813
813
|
},
|
|
814
814
|
server: {
|
|
815
815
|
port: 3141,
|
|
816
|
-
host: "
|
|
816
|
+
host: "0.0.0.0"
|
|
817
817
|
},
|
|
818
818
|
databasePath: "./sparkecoder.db"
|
|
819
819
|
};
|
|
@@ -7822,6 +7822,44 @@ function getSlackSigningSecret() {
|
|
|
7822
7822
|
function getDefaultOrchestratorName() {
|
|
7823
7823
|
return readSlackConfig()?.defaultOrchestratorName ?? null;
|
|
7824
7824
|
}
|
|
7825
|
+
function getCachedSlackSelfIdentity() {
|
|
7826
|
+
const cfg = readSlackConfig();
|
|
7827
|
+
if (!cfg) return null;
|
|
7828
|
+
if (cachedSelf && cachedSelf.token === cfg.botToken) return cachedSelf.identity;
|
|
7829
|
+
return null;
|
|
7830
|
+
}
|
|
7831
|
+
async function ensureSlackSelfIdentity() {
|
|
7832
|
+
const cfg = readSlackConfig();
|
|
7833
|
+
if (!cfg) return null;
|
|
7834
|
+
if (cachedSelf && cachedSelf.token === cfg.botToken) return cachedSelf.identity;
|
|
7835
|
+
if (selfInflight) return selfInflight;
|
|
7836
|
+
selfInflight = (async () => {
|
|
7837
|
+
try {
|
|
7838
|
+
const res = await fetch("https://slack.com/api/auth.test", {
|
|
7839
|
+
method: "POST",
|
|
7840
|
+
headers: { Authorization: `Bearer ${cfg.botToken}` }
|
|
7841
|
+
});
|
|
7842
|
+
const data = await res.json().catch(() => ({}));
|
|
7843
|
+
if (!data?.ok) {
|
|
7844
|
+
console.warn(`[slack] auth.test failed: ${data?.error || `HTTP ${res.status}`}`);
|
|
7845
|
+
return null;
|
|
7846
|
+
}
|
|
7847
|
+
const identity = {
|
|
7848
|
+
botUserId: String(data.user_id || ""),
|
|
7849
|
+
botId: String(data.bot_id || ""),
|
|
7850
|
+
teamId: data.team_id ? String(data.team_id) : void 0
|
|
7851
|
+
};
|
|
7852
|
+
cachedSelf = { token: cfg.botToken, identity };
|
|
7853
|
+
return identity;
|
|
7854
|
+
} catch (err) {
|
|
7855
|
+
console.warn("[slack] auth.test error:", err?.message || err);
|
|
7856
|
+
return null;
|
|
7857
|
+
} finally {
|
|
7858
|
+
selfInflight = null;
|
|
7859
|
+
}
|
|
7860
|
+
})();
|
|
7861
|
+
return selfInflight;
|
|
7862
|
+
}
|
|
7825
7863
|
function getSlackAllowlistPolicy() {
|
|
7826
7864
|
try {
|
|
7827
7865
|
const cfg = getConfig();
|
|
@@ -7847,11 +7885,13 @@ function getSlackDeniedReplyPolicy() {
|
|
|
7847
7885
|
return { enabled: true, template: DEFAULT_DENIED_TEMPLATE };
|
|
7848
7886
|
}
|
|
7849
7887
|
}
|
|
7850
|
-
var DEFAULT_DENIED_TEMPLATE;
|
|
7888
|
+
var cachedSelf, selfInflight, DEFAULT_DENIED_TEMPLATE;
|
|
7851
7889
|
var init_client3 = __esm({
|
|
7852
7890
|
"src/integrations/slack/client.ts"() {
|
|
7853
7891
|
"use strict";
|
|
7854
7892
|
init_config();
|
|
7893
|
+
cachedSelf = null;
|
|
7894
|
+
selfInflight = null;
|
|
7855
7895
|
DEFAULT_DENIED_TEMPLATE = "Sorry, you don't have permission to use this bot. (Contact the bot owner if you think this is a mistake.)";
|
|
7856
7896
|
}
|
|
7857
7897
|
});
|
|
@@ -7869,9 +7909,19 @@ function isThreadOwned(channel, threadTs) {
|
|
|
7869
7909
|
function stripMention(text) {
|
|
7870
7910
|
return String(text || "").replace(/<@[^>]+>/g, "").trim();
|
|
7871
7911
|
}
|
|
7872
|
-
function
|
|
7912
|
+
function isSelfAuthored(event, self) {
|
|
7913
|
+
if (!self) return true;
|
|
7914
|
+
if (self.botId && event.bot_id && event.bot_id === self.botId) return true;
|
|
7915
|
+
if (self.botUserId && event.user && event.user === self.botUserId) return true;
|
|
7916
|
+
return false;
|
|
7917
|
+
}
|
|
7918
|
+
function slackEventToInboundResult(event, opts = {}) {
|
|
7873
7919
|
if (!event) return { event: null, dropReason: "empty_text" };
|
|
7874
|
-
|
|
7920
|
+
const self = opts.self ?? getCachedSlackSelfIdentity();
|
|
7921
|
+
const isBotAuthored = !!event.bot_id || event.type === "message" && event.subtype === "bot_message";
|
|
7922
|
+
if (isBotAuthored && isSelfAuthored(event, self)) {
|
|
7923
|
+
return { event: null, dropReason: "bot_message" };
|
|
7924
|
+
}
|
|
7875
7925
|
if (event.type === "message" && event.subtype && IGNORED_MESSAGE_SUBTYPES.has(event.subtype)) {
|
|
7876
7926
|
return { event: null, dropReason: "bot_message" };
|
|
7877
7927
|
}
|
|
@@ -7948,7 +7998,6 @@ var init_slack = __esm({
|
|
|
7948
7998
|
}
|
|
7949
7999
|
};
|
|
7950
8000
|
IGNORED_MESSAGE_SUBTYPES = /* @__PURE__ */ new Set([
|
|
7951
|
-
"bot_message",
|
|
7952
8001
|
"message_changed",
|
|
7953
8002
|
"message_deleted",
|
|
7954
8003
|
"channel_join",
|
|
@@ -13675,7 +13724,8 @@ slack.post("/events", async (c) => {
|
|
|
13675
13724
|
updateEvent(auditId, { status: "dropped", dropReason: "duplicate_delivery" });
|
|
13676
13725
|
return c.json({ ok: true });
|
|
13677
13726
|
}
|
|
13678
|
-
const
|
|
13727
|
+
const self = await ensureSlackSelfIdentity();
|
|
13728
|
+
const { event: inbound, dropReason } = slackEventToInboundResult(ev, { self });
|
|
13679
13729
|
if (inbound) {
|
|
13680
13730
|
const isThreadReply = ev.type === "message" && ev.channel_type !== "im" && typeof ev.thread_ts === "string" && ev.thread_ts !== ev.ts;
|
|
13681
13731
|
if (isThreadReply) {
|
|
@@ -14649,13 +14699,15 @@ async function startServer(options = {}) {
|
|
|
14649
14699
|
if (!options.quiet) console.warn(`[scheduler] start skipped: ${err.message}`);
|
|
14650
14700
|
}
|
|
14651
14701
|
const port = options.port || config.server.port;
|
|
14652
|
-
const
|
|
14702
|
+
const envHost = process.env.SPARKECODER_API_HOST || process.env.SPARKECODER_HOST;
|
|
14703
|
+
const host = envHost || options.host || config.server.host || "0.0.0.0";
|
|
14704
|
+
const hostSource = envHost ? process.env.SPARKECODER_API_HOST ? "env SPARKECODER_API_HOST" : "env SPARKECODER_HOST" : options.host ? "--host flag" : config.server.host ? "config.server.host" : "default";
|
|
14653
14705
|
const publicUrl = options.publicUrl || config.server.publicUrl;
|
|
14654
14706
|
const app = await createApp({ quiet: options.quiet });
|
|
14655
14707
|
if (!options.quiet) {
|
|
14656
14708
|
console.log(`
|
|
14657
14709
|
\u{1F680} SparkECoder API Server`);
|
|
14658
|
-
console.log(` \u2192
|
|
14710
|
+
console.log(` \u2192 Binding to ${host}:${port} (source: ${hostSource})`);
|
|
14659
14711
|
if (publicUrl) {
|
|
14660
14712
|
console.log(` \u2192 Public URL: ${publicUrl}`);
|
|
14661
14713
|
}
|
|
@@ -14664,10 +14716,22 @@ async function startServer(options = {}) {
|
|
|
14664
14716
|
console.log(` \u2192 OpenAPI spec: http://${host}:${port}/openapi.json
|
|
14665
14717
|
`);
|
|
14666
14718
|
}
|
|
14719
|
+
if (host === "127.0.0.1" || host === "localhost") {
|
|
14720
|
+
console.log(`[sparkecoder] \u26A0 API bound to ${host} only \u2014 not reachable from outside the machine.`);
|
|
14721
|
+
console.log(`[sparkecoder] For tunnels/reverse proxies (Modal/Fly/Docker), set --host 0.0.0.0 or SPARKECODER_API_HOST=0.0.0.0.`);
|
|
14722
|
+
}
|
|
14667
14723
|
serverInstance = serve({
|
|
14668
14724
|
fetch: app.fetch,
|
|
14669
14725
|
port,
|
|
14670
14726
|
hostname: host
|
|
14727
|
+
}, (info) => {
|
|
14728
|
+
const actual = `${info.address}:${info.port}`;
|
|
14729
|
+
const requested = `${host}:${port}`;
|
|
14730
|
+
if (info.address === "127.0.0.1" && host !== "127.0.0.1" && host !== "localhost") {
|
|
14731
|
+
console.warn(`[sparkecoder] \u2717 API listener bound to ${actual} but ${requested} was requested. External requests will be refused.`);
|
|
14732
|
+
} else {
|
|
14733
|
+
console.log(`[sparkecoder] \u2713 API listening on ${actual}`);
|
|
14734
|
+
}
|
|
14671
14735
|
});
|
|
14672
14736
|
let webPort;
|
|
14673
14737
|
let webStarted;
|