sproutkit-code 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +133 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -35355,21 +35355,21 @@ var require_cross_spawn = __commonJS({
|
|
|
35355
35355
|
var cp = require("child_process");
|
|
35356
35356
|
var parse = require_parse();
|
|
35357
35357
|
var enoent = require_enoent();
|
|
35358
|
-
function
|
|
35358
|
+
function spawn2(command, args, options) {
|
|
35359
35359
|
const parsed = parse(command, args, options);
|
|
35360
35360
|
const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
|
|
35361
35361
|
enoent.hookChildProcess(spawned, parsed);
|
|
35362
35362
|
return spawned;
|
|
35363
35363
|
}
|
|
35364
|
-
function
|
|
35364
|
+
function spawnSync3(command, args, options) {
|
|
35365
35365
|
const parsed = parse(command, args, options);
|
|
35366
35366
|
const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
|
|
35367
35367
|
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
35368
35368
|
return result;
|
|
35369
35369
|
}
|
|
35370
|
-
module2.exports =
|
|
35371
|
-
module2.exports.spawn =
|
|
35372
|
-
module2.exports.sync =
|
|
35370
|
+
module2.exports = spawn2;
|
|
35371
|
+
module2.exports.spawn = spawn2;
|
|
35372
|
+
module2.exports.sync = spawnSync3;
|
|
35373
35373
|
module2.exports._parse = parse;
|
|
35374
35374
|
module2.exports._enoent = enoent;
|
|
35375
35375
|
}
|
|
@@ -82456,7 +82456,7 @@ var require_package = __commonJS({
|
|
|
82456
82456
|
"package.json"(exports2, module2) {
|
|
82457
82457
|
module2.exports = {
|
|
82458
82458
|
name: "sproutkit-code",
|
|
82459
|
-
version: "0.
|
|
82459
|
+
version: "0.8.0",
|
|
82460
82460
|
description: "Sproutkit in your terminal \u2014 find leads, build sites, run outreach, all via chat.",
|
|
82461
82461
|
bin: {
|
|
82462
82462
|
sproutkit: "./dist/index.js"
|
|
@@ -83740,8 +83740,108 @@ async function cmdBuildAll(argv) {
|
|
|
83740
83740
|
});
|
|
83741
83741
|
}
|
|
83742
83742
|
|
|
83743
|
+
// src/claude-bridge.ts
|
|
83744
|
+
var import_child_process3 = require("child_process");
|
|
83745
|
+
function runClaudeTurn(args) {
|
|
83746
|
+
const { message, sessionId, write } = args;
|
|
83747
|
+
const timeoutMs = args.timeoutMs ?? 6e5;
|
|
83748
|
+
const cliArgs = [
|
|
83749
|
+
"-p",
|
|
83750
|
+
"--output-format",
|
|
83751
|
+
"stream-json",
|
|
83752
|
+
"--include-partial-messages",
|
|
83753
|
+
"--verbose",
|
|
83754
|
+
// required for stream_event emission
|
|
83755
|
+
// Let Claude drive the sproutkit CLI without hanging on a permission
|
|
83756
|
+
// prompt, but ONLY the sproutkit command — nothing else runs unattended.
|
|
83757
|
+
"--allowedTools",
|
|
83758
|
+
"Bash(sproutkit *)"
|
|
83759
|
+
];
|
|
83760
|
+
if (sessionId) cliArgs.push("--resume", sessionId);
|
|
83761
|
+
return new Promise((resolve) => {
|
|
83762
|
+
let child;
|
|
83763
|
+
try {
|
|
83764
|
+
child = (0, import_child_process3.spawn)(claudeBin(), cliArgs, { stdio: ["pipe", "pipe", "pipe"] });
|
|
83765
|
+
} catch (e) {
|
|
83766
|
+
resolve({ sessionId, ok: false, error: e.message });
|
|
83767
|
+
return;
|
|
83768
|
+
}
|
|
83769
|
+
let buf = "";
|
|
83770
|
+
let newSessionId = sessionId;
|
|
83771
|
+
let sawText = false;
|
|
83772
|
+
let settled = false;
|
|
83773
|
+
let stderr = "";
|
|
83774
|
+
const timer = setTimeout(() => {
|
|
83775
|
+
if (settled) return;
|
|
83776
|
+
settled = true;
|
|
83777
|
+
child.kill("SIGKILL");
|
|
83778
|
+
resolve({ sessionId: newSessionId, ok: false, error: `Timed out after ${Math.round(timeoutMs / 1e3)}s.` });
|
|
83779
|
+
}, timeoutMs);
|
|
83780
|
+
child.stdout.on("data", (d) => {
|
|
83781
|
+
buf += d.toString();
|
|
83782
|
+
let nl;
|
|
83783
|
+
while ((nl = buf.indexOf("\n")) >= 0) {
|
|
83784
|
+
const line = buf.slice(0, nl).trim();
|
|
83785
|
+
buf = buf.slice(nl + 1);
|
|
83786
|
+
if (!line) continue;
|
|
83787
|
+
let ev;
|
|
83788
|
+
try {
|
|
83789
|
+
ev = JSON.parse(line);
|
|
83790
|
+
} catch {
|
|
83791
|
+
continue;
|
|
83792
|
+
}
|
|
83793
|
+
if (ev.session_id) newSessionId = ev.session_id;
|
|
83794
|
+
if (ev.type === "stream_event" && ev.event?.delta?.type === "text_delta" && typeof ev.event.delta.text === "string") {
|
|
83795
|
+
sawText = true;
|
|
83796
|
+
write(ev.event.delta.text);
|
|
83797
|
+
}
|
|
83798
|
+
if (ev.type === "result" && !sawText && typeof ev.result === "string") {
|
|
83799
|
+
write(ev.result);
|
|
83800
|
+
}
|
|
83801
|
+
}
|
|
83802
|
+
});
|
|
83803
|
+
child.stderr.on("data", (d) => stderr += d.toString());
|
|
83804
|
+
child.on("error", (e) => {
|
|
83805
|
+
if (settled) return;
|
|
83806
|
+
settled = true;
|
|
83807
|
+
clearTimeout(timer);
|
|
83808
|
+
const msg = e.code === "ENOENT" ? `Claude Code CLI not found. Install it and run 'claude /login'.` : `Failed to run Claude Code: ${e.message}`;
|
|
83809
|
+
resolve({ sessionId: newSessionId, ok: false, error: msg });
|
|
83810
|
+
});
|
|
83811
|
+
child.on("close", (code) => {
|
|
83812
|
+
if (settled) return;
|
|
83813
|
+
settled = true;
|
|
83814
|
+
clearTimeout(timer);
|
|
83815
|
+
if (code !== 0 && !sawText) {
|
|
83816
|
+
resolve({
|
|
83817
|
+
sessionId: newSessionId,
|
|
83818
|
+
ok: false,
|
|
83819
|
+
error: stderr.trim() || `Claude Code exited with code ${code}.`
|
|
83820
|
+
});
|
|
83821
|
+
} else {
|
|
83822
|
+
resolve({ sessionId: newSessionId, ok: true });
|
|
83823
|
+
}
|
|
83824
|
+
});
|
|
83825
|
+
child.stdin.write(message);
|
|
83826
|
+
child.stdin.end();
|
|
83827
|
+
});
|
|
83828
|
+
}
|
|
83829
|
+
|
|
83743
83830
|
// src/index.ts
|
|
83831
|
+
var import_child_process4 = require("child_process");
|
|
83744
83832
|
process.env.SPROUTKIT_HEADLESS = "1";
|
|
83833
|
+
function claudePresent() {
|
|
83834
|
+
try {
|
|
83835
|
+
const bin = process.env.SPROUTKIT_CLAUDE_BIN || "claude";
|
|
83836
|
+
return (0, import_child_process4.spawnSync)(bin, ["--version"], { stdio: "ignore", timeout: 1e4 }).status === 0;
|
|
83837
|
+
} catch {
|
|
83838
|
+
return false;
|
|
83839
|
+
}
|
|
83840
|
+
}
|
|
83841
|
+
function useClaudeBridge() {
|
|
83842
|
+
if (getBackend() === "claude_code") return true;
|
|
83843
|
+
return claudePresent() && !getSetting("anthropic_key");
|
|
83844
|
+
}
|
|
83745
83845
|
async function main() {
|
|
83746
83846
|
const arg = process.argv[2];
|
|
83747
83847
|
initDatabase();
|
|
@@ -83831,23 +83931,47 @@ async function main() {
|
|
|
83831
83931
|
closeTty();
|
|
83832
83932
|
return;
|
|
83833
83933
|
}
|
|
83934
|
+
const bridged = useClaudeBridge();
|
|
83834
83935
|
const oneShot = process.argv.slice(2).join(" ").trim();
|
|
83835
83936
|
if (oneShot) {
|
|
83836
|
-
|
|
83937
|
+
if (bridged) {
|
|
83938
|
+
const r = await runClaudeTurn({ message: oneShot, sessionId: null, write: (t) => process.stdout.write(t) });
|
|
83939
|
+
say();
|
|
83940
|
+
if (!r.ok) say(c.red(` ${r.error ?? "Claude Code failed."}`));
|
|
83941
|
+
} else {
|
|
83942
|
+
await runTurn(oneShot);
|
|
83943
|
+
}
|
|
83837
83944
|
closeTty();
|
|
83838
83945
|
return;
|
|
83839
83946
|
}
|
|
83840
83947
|
await refreshIfStale(getSetting("anthropic_key")).catch(() => {
|
|
83841
83948
|
});
|
|
83842
83949
|
await notifyIfOutdated();
|
|
83843
|
-
|
|
83950
|
+
if (bridged && !skillInstalled()) {
|
|
83951
|
+
say(c.amber(" Tip: run 'sproutkit setup' to install the Sproutkit skill so Claude can find/build/book for you."));
|
|
83952
|
+
}
|
|
83953
|
+
say(
|
|
83954
|
+
bridged ? c.dim(" Talk to Sproutkit (powered by your Claude subscription). Type a request, or 'exit'.") : c.dim(" Chat with Sproutkit. Type a request, or 'exit' to quit.")
|
|
83955
|
+
);
|
|
83844
83956
|
say();
|
|
83957
|
+
let claudeSession = null;
|
|
83845
83958
|
while (true) {
|
|
83846
83959
|
const line = await ask(c.greenBold("sproutkit \u203A "));
|
|
83847
83960
|
if (!line) continue;
|
|
83848
83961
|
if (line === "exit" || line === "quit") break;
|
|
83849
83962
|
try {
|
|
83850
|
-
|
|
83963
|
+
if (bridged) {
|
|
83964
|
+
const r = await runClaudeTurn({
|
|
83965
|
+
message: line,
|
|
83966
|
+
sessionId: claudeSession,
|
|
83967
|
+
write: (t) => process.stdout.write(t)
|
|
83968
|
+
});
|
|
83969
|
+
say();
|
|
83970
|
+
if (r.sessionId) claudeSession = r.sessionId;
|
|
83971
|
+
if (!r.ok) say(c.red(` ${r.error ?? "Claude Code failed."}`));
|
|
83972
|
+
} else {
|
|
83973
|
+
await runTurn(line);
|
|
83974
|
+
}
|
|
83851
83975
|
} catch (e) {
|
|
83852
83976
|
say(c.red(` Error: ${e.message}`));
|
|
83853
83977
|
}
|