sisyphi 1.1.30 → 1.1.32
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/deploy/shared/cloud-init.yaml.tpl +3 -0
- package/dist/cli.js +39 -22
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js.map +1 -1
- package/dist/deploy/shared/cloud-init.yaml.tpl +3 -0
- package/dist/tui.js.map +1 -1
- package/package.json +1 -1
|
@@ -96,6 +96,9 @@ runcmd:
|
|
|
96
96
|
# 6. Sisyphus install (root → /usr/bin/sisyphusd symlink).
|
|
97
97
|
- npm i -g sisyphi@${sisyphus_version}
|
|
98
98
|
|
|
99
|
+
# 6b. Claude Code CLI (sisyphus drives it for agent sessions).
|
|
100
|
+
- npm i -g @anthropic-ai/claude-code
|
|
101
|
+
|
|
99
102
|
# 7. Daemon as systemd user service.
|
|
100
103
|
- sudo -u sisyphus XDG_RUNTIME_DIR=/run/user/$(id -u sisyphus) systemctl --user daemon-reload
|
|
101
104
|
- sudo -u sisyphus XDG_RUNTIME_DIR=/run/user/$(id -u sisyphus) systemctl --user enable --now sisyphusd
|
package/dist/cli.js
CHANGED
|
@@ -2320,6 +2320,11 @@ function getTmuxSessionInfo() {
|
|
|
2320
2320
|
function shellQuote(s) {
|
|
2321
2321
|
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
2322
2322
|
}
|
|
2323
|
+
function shellQuoteHomePath(path) {
|
|
2324
|
+
if (path === "~") return "~";
|
|
2325
|
+
if (path.startsWith("~/")) return `~/${shellQuote(path.slice(2))}`;
|
|
2326
|
+
return shellQuote(path);
|
|
2327
|
+
}
|
|
2323
2328
|
function validateRepoName(repo) {
|
|
2324
2329
|
return !repo.includes("/") && !repo.includes("\\") && !repo.includes("..");
|
|
2325
2330
|
}
|
|
@@ -10296,7 +10301,7 @@ function ensureGroveInstalled(provider) {
|
|
|
10296
10301
|
}
|
|
10297
10302
|
}
|
|
10298
10303
|
function ensureGroveRegistered(provider, repo, instancePath) {
|
|
10299
|
-
const cmd = `grove register --update --name ${shellQuote(repo)} ${
|
|
10304
|
+
const cmd = `grove register --update --name ${shellQuote(repo)} ${shellQuoteHomePath(instancePath)}`;
|
|
10300
10305
|
const result = runOnBox(provider, cmd);
|
|
10301
10306
|
if (result.exitCode !== 0) {
|
|
10302
10307
|
throw new Error(`Failed to register grove project ${repo}: ${result.stderr || result.stdout}`);
|
|
@@ -10319,13 +10324,8 @@ function captureGit(args2) {
|
|
|
10319
10324
|
}
|
|
10320
10325
|
function inferRepoName() {
|
|
10321
10326
|
const { stdout, ok } = captureGit(["rev-parse", "--show-toplevel"]);
|
|
10322
|
-
if (
|
|
10323
|
-
|
|
10324
|
-
}
|
|
10325
|
-
if (!stdout) {
|
|
10326
|
-
throw new Error("git rev-parse returned empty toplevel.");
|
|
10327
|
-
}
|
|
10328
|
-
return basename6(stdout);
|
|
10327
|
+
if (ok && stdout) return basename6(stdout);
|
|
10328
|
+
return basename6(process.cwd());
|
|
10329
10329
|
}
|
|
10330
10330
|
function getOriginUrl() {
|
|
10331
10331
|
const { stdout, ok } = captureGit(["remote", "get-url", "origin"]);
|
|
@@ -10334,10 +10334,8 @@ function getOriginUrl() {
|
|
|
10334
10334
|
}
|
|
10335
10335
|
function getRepoToplevel() {
|
|
10336
10336
|
const { stdout, ok } = captureGit(["rev-parse", "--show-toplevel"]);
|
|
10337
|
-
if (
|
|
10338
|
-
|
|
10339
|
-
}
|
|
10340
|
-
return stdout;
|
|
10337
|
+
if (ok && stdout) return stdout;
|
|
10338
|
+
return process.cwd();
|
|
10341
10339
|
}
|
|
10342
10340
|
var DEFAULT_EXCLUDES = [
|
|
10343
10341
|
".sisyphus/",
|
|
@@ -10389,7 +10387,7 @@ function packageManagerInstallCmd(pm) {
|
|
|
10389
10387
|
init_paths();
|
|
10390
10388
|
function readSidecar(provider, repo) {
|
|
10391
10389
|
const path = boxCloudSidecarPath(repo);
|
|
10392
|
-
const result = runOnBox(provider, `cat ${
|
|
10390
|
+
const result = runOnBox(provider, `cat ${shellQuoteHomePath(path)} 2>/dev/null`);
|
|
10393
10391
|
if (result.exitCode !== 0 || !result.stdout.trim()) return null;
|
|
10394
10392
|
try {
|
|
10395
10393
|
const parsed = JSON.parse(result.stdout);
|
|
@@ -10403,8 +10401,8 @@ function writeSidecar(provider, repo, data) {
|
|
|
10403
10401
|
const path = boxCloudSidecarPath(repo);
|
|
10404
10402
|
const json = JSON.stringify(data, null, 2);
|
|
10405
10403
|
const cmd = [
|
|
10406
|
-
`mkdir -p ${
|
|
10407
|
-
`cat > ${
|
|
10404
|
+
`mkdir -p ${shellQuoteHomePath(dir)}`,
|
|
10405
|
+
`cat > ${shellQuoteHomePath(path)} <<'SISYPHUS_CLOUD_SIDECAR_EOF'`,
|
|
10408
10406
|
json,
|
|
10409
10407
|
"SISYPHUS_CLOUD_SIDECAR_EOF"
|
|
10410
10408
|
].join("\n");
|
|
@@ -10431,7 +10429,9 @@ Pass --name <slug> to disambiguate, or --fresh to overwrite.`
|
|
|
10431
10429
|
}
|
|
10432
10430
|
if (opts.fresh) {
|
|
10433
10431
|
if (!localOrigin) {
|
|
10434
|
-
throw new Error(
|
|
10432
|
+
throw new Error(
|
|
10433
|
+
"--fresh requires an `origin` remote on the local repo. Not available when running from a non-git parent dir."
|
|
10434
|
+
);
|
|
10435
10435
|
}
|
|
10436
10436
|
if (!opts.yes) {
|
|
10437
10437
|
console.log(`This will wipe ~/projects/${repo} on the box and re-clone from ${localOrigin}.`);
|
|
@@ -10443,14 +10443,14 @@ Pass --name <slug> to disambiguate, or --fresh to overwrite.`
|
|
|
10443
10443
|
}
|
|
10444
10444
|
console.log(`\u2192 wiping ${remoteDir} and cloning ${localOrigin} on box...`);
|
|
10445
10445
|
const cloneCmd = [
|
|
10446
|
-
`rm -rf ${
|
|
10447
|
-
`mkdir -p ${
|
|
10448
|
-
`git clone ${shellQuote(localOrigin)} ${
|
|
10446
|
+
`rm -rf ${shellQuoteHomePath(remoteDir)}`,
|
|
10447
|
+
`mkdir -p ${shellQuoteHomePath("~/projects")}`,
|
|
10448
|
+
`git clone ${shellQuote(localOrigin)} ${shellQuoteHomePath(remoteDir)}`
|
|
10449
10449
|
].join(" && ");
|
|
10450
10450
|
const code = await runOnBoxStreaming(provider, cloneCmd);
|
|
10451
10451
|
if (code !== 0) throw new Error(`fresh clone failed (exit ${code})`);
|
|
10452
10452
|
} else {
|
|
10453
|
-
const mkdir = runOnBox(provider, `mkdir -p ${
|
|
10453
|
+
const mkdir = runOnBox(provider, `mkdir -p ${shellQuoteHomePath(remoteDir)}`);
|
|
10454
10454
|
if (mkdir.exitCode !== 0) {
|
|
10455
10455
|
throw new Error(`Failed to mkdir on box: ${mkdir.stderr}`);
|
|
10456
10456
|
}
|
|
@@ -10488,7 +10488,7 @@ async function cloudInstall(provider, repo) {
|
|
|
10488
10488
|
return;
|
|
10489
10489
|
}
|
|
10490
10490
|
console.log(`\u2192 ${pm} install in ${remoteDir} on box...`);
|
|
10491
|
-
const remoteCmd = `cd ${
|
|
10491
|
+
const remoteCmd = `cd ${shellQuoteHomePath(remoteDir)} && ${cmd}`;
|
|
10492
10492
|
const code = await runOnBoxStreaming(provider, remoteCmd);
|
|
10493
10493
|
if (code !== 0) throw new Error(`${pm} install failed (exit ${code})`);
|
|
10494
10494
|
const existing = readSidecar(provider, repo);
|
|
@@ -10504,7 +10504,7 @@ async function cloudInstall(provider, repo) {
|
|
|
10504
10504
|
}
|
|
10505
10505
|
async function cloudSession(provider, repo) {
|
|
10506
10506
|
const remoteDir = boxRepoPath(repo);
|
|
10507
|
-
const cmd = `sis admin home-init ${shellQuote(repo)} ${
|
|
10507
|
+
const cmd = `sis admin home-init ${shellQuote(repo)} ${shellQuoteHomePath(remoteDir)}`;
|
|
10508
10508
|
console.log(`\u2192 initializing tmux home session "${repo}" on box...`);
|
|
10509
10509
|
const result = runOnBox(provider, cmd);
|
|
10510
10510
|
if (result.exitCode !== 0) {
|
|
@@ -10528,6 +10528,19 @@ Use a fresh terminal, or run from outside tmux:
|
|
|
10528
10528
|
});
|
|
10529
10529
|
child.on("exit", (code) => process.exit(code === null ? 1 : code));
|
|
10530
10530
|
}
|
|
10531
|
+
function cloudClaudeLogin(provider) {
|
|
10532
|
+
const target = effectiveSshTarget(provider);
|
|
10533
|
+
const remote = [
|
|
10534
|
+
"command -v claude >/dev/null 2>&1",
|
|
10535
|
+
"|| sudo npm i -g @anthropic-ai/claude-code",
|
|
10536
|
+
"&& claude auth login"
|
|
10537
|
+
].join(" ");
|
|
10538
|
+
const child = spawn4("ssh", ["-t", target, remote], {
|
|
10539
|
+
stdio: "inherit",
|
|
10540
|
+
env: EXEC_ENV
|
|
10541
|
+
});
|
|
10542
|
+
child.on("exit", (code) => process.exit(code === null ? 1 : code));
|
|
10543
|
+
}
|
|
10531
10544
|
async function cloudStart(provider, repo, opts) {
|
|
10532
10545
|
await cloudSync(provider, repo, { fresh: opts.fresh, yes: opts.yes });
|
|
10533
10546
|
await cloudInstall(provider, repo);
|
|
@@ -10610,6 +10623,10 @@ function registerCloud(program2) {
|
|
|
10610
10623
|
const { provider, repo } = resolve11(raw);
|
|
10611
10624
|
await cloudStart(provider, repo, { fresh: raw.fresh === true, yes: raw.yes === true });
|
|
10612
10625
|
});
|
|
10626
|
+
cloud.command("claude-login").description("Run `claude auth login` on the box (device-code flow; paste the URL into your local browser).").option("--provider <name>", "Cloud provider.").action((raw) => {
|
|
10627
|
+
const provider = pickProvider(raw.provider);
|
|
10628
|
+
cloudClaudeLogin(provider);
|
|
10629
|
+
});
|
|
10613
10630
|
cloud.command("status").description("Print box-side status for this repo (planted, session running, last sync/install).").option("--name <repo>", "Override the repo name.").option("--provider <name>", "Cloud provider.").action((raw) => {
|
|
10614
10631
|
const { provider, repo } = resolve11(raw);
|
|
10615
10632
|
cloudStatus(provider, repo);
|