sisyphi 1.2.16 → 1.2.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/README.md +3 -3
  2. package/dist/cli.js +202 -63
  3. package/dist/cli.js.map +1 -1
  4. package/dist/daemon.js +87 -4
  5. package/dist/daemon.js.map +1 -1
  6. package/dist/templates/agent-plugin/agents/CLAUDE.md +1 -1
  7. package/dist/templates/agent-plugin/agents/operator.md +9 -1
  8. package/dist/templates/agent-plugin/agents/review/compliance.md +4 -0
  9. package/dist/templates/agent-plugin/agents/review/efficiency.md +4 -0
  10. package/dist/templates/agent-plugin/agents/review/quality.md +4 -0
  11. package/dist/templates/agent-plugin/agents/review/reuse.md +4 -0
  12. package/dist/templates/agent-plugin/agents/review/security.md +4 -0
  13. package/dist/templates/agent-plugin/agents/review/tests.md +4 -0
  14. package/dist/templates/agent-plugin/agents/review.md +8 -6
  15. package/dist/templates/orchestrator-base.md +2 -0
  16. package/dist/templates/orchestrator-validation.md +10 -0
  17. package/package.json +1 -1
  18. package/templates/agent-plugin/agents/CLAUDE.md +1 -1
  19. package/templates/agent-plugin/agents/operator.md +9 -1
  20. package/templates/agent-plugin/agents/review/compliance.md +4 -0
  21. package/templates/agent-plugin/agents/review/efficiency.md +4 -0
  22. package/templates/agent-plugin/agents/review/quality.md +4 -0
  23. package/templates/agent-plugin/agents/review/reuse.md +4 -0
  24. package/templates/agent-plugin/agents/review/security.md +4 -0
  25. package/templates/agent-plugin/agents/review/tests.md +4 -0
  26. package/templates/agent-plugin/agents/review.md +8 -6
  27. package/templates/orchestrator-base.md +2 -0
  28. package/templates/orchestrator-validation.md +10 -0
package/dist/daemon.js CHANGED
@@ -10865,7 +10865,7 @@ init_paths();
10865
10865
  init_config();
10866
10866
  init_server();
10867
10867
  init_orphan_sweep();
10868
- import { mkdirSync as mkdirSync15, readFileSync as readFileSync29, writeFileSync as writeFileSync17, unlinkSync as unlinkSync6, existsSync as existsSync32 } from "fs";
10868
+ import { mkdirSync as mkdirSync15, readFileSync as readFileSync30, writeFileSync as writeFileSync17, unlinkSync as unlinkSync6, existsSync as existsSync33 } from "fs";
10869
10869
  import { execSync as execSync8 } from "child_process";
10870
10870
  import { setTimeout as sleep } from "timers/promises";
10871
10871
  import { Command } from "commander";
@@ -11840,6 +11840,88 @@ function stopLogRotator() {
11840
11840
  }
11841
11841
  }
11842
11842
 
11843
+ // src/daemon/upload-backfill.ts
11844
+ init_paths();
11845
+ init_config();
11846
+ init_upload();
11847
+ init_version();
11848
+ init_state();
11849
+ init_uploader();
11850
+ import { existsSync as existsSync32, readdirSync as readdirSync14, readFileSync as readFileSync29 } from "fs";
11851
+ var backfillStarted = false;
11852
+ async function backfillUploads() {
11853
+ if (backfillStarted) return;
11854
+ backfillStarted = true;
11855
+ try {
11856
+ const config = loadConfig(process.cwd());
11857
+ if (!isUploadConfigured(config.upload)) return;
11858
+ const base = historyBaseDir();
11859
+ let dirs;
11860
+ try {
11861
+ dirs = readdirSync14(base);
11862
+ } catch {
11863
+ return;
11864
+ }
11865
+ const candidates = [];
11866
+ for (const sessionId of dirs) {
11867
+ let summary;
11868
+ try {
11869
+ summary = JSON.parse(readFileSync29(historySessionSummaryPath(sessionId), "utf-8"));
11870
+ } catch {
11871
+ continue;
11872
+ }
11873
+ if (summary.status !== "completed" || !summary.cwd) continue;
11874
+ candidates.push({ sessionId, cwd: summary.cwd, startedAt: new Date(summary.startedAt ?? 0).getTime() });
11875
+ }
11876
+ candidates.sort((a, b) => b.startedAt - a.startedAt);
11877
+ const sisyphusVersion = getSisyphusVersion();
11878
+ let uploaded = 0;
11879
+ let skipped = 0;
11880
+ let failed = 0;
11881
+ let unexportable = 0;
11882
+ for (const { sessionId, cwd } of candidates) {
11883
+ if (!existsSync32(statePath(cwd, sessionId))) {
11884
+ unexportable++;
11885
+ continue;
11886
+ }
11887
+ let session;
11888
+ try {
11889
+ session = getSession(cwd, sessionId);
11890
+ } catch {
11891
+ unexportable++;
11892
+ continue;
11893
+ }
11894
+ if (session.status !== "completed") continue;
11895
+ if (session.uploadStatus === "uploaded") {
11896
+ skipped++;
11897
+ continue;
11898
+ }
11899
+ try {
11900
+ await runSessionUploadAndPersist({
11901
+ sessionId,
11902
+ cwd,
11903
+ fullConfig: loadConfig(cwd),
11904
+ session,
11905
+ status: "completed",
11906
+ sisyphusVersion
11907
+ });
11908
+ const after = getSession(cwd, sessionId);
11909
+ if (after.uploadStatus === "uploaded") uploaded++;
11910
+ else failed++;
11911
+ } catch {
11912
+ failed++;
11913
+ }
11914
+ }
11915
+ if (uploaded || failed) {
11916
+ console.log(
11917
+ `[sisyphus] upload backfill: ${uploaded} uploaded, ${skipped} already up, ${failed} failed, ${unexportable} unexportable (of ${candidates.length} completed)`
11918
+ );
11919
+ }
11920
+ } catch (err) {
11921
+ console.warn("[sisyphus] upload backfill aborted:", err instanceof Error ? err.message : err);
11922
+ }
11923
+ }
11924
+
11843
11925
  // src/daemon/index.ts
11844
11926
  var nodeVersion = parseInt(process.versions.node.split(".")[0], 10);
11845
11927
  if (nodeVersion < 22) {
@@ -11852,7 +11934,7 @@ function ensureDirs() {
11852
11934
  function readPid() {
11853
11935
  const pidFile = daemonPidPath();
11854
11936
  try {
11855
- const pid = parseInt(readFileSync29(pidFile, "utf-8").trim(), 10);
11937
+ const pid = parseInt(readFileSync30(pidFile, "utf-8").trim(), 10);
11856
11938
  return pid && isProcessAlive(pid) ? pid : null;
11857
11939
  } catch {
11858
11940
  return null;
@@ -11915,10 +11997,10 @@ function stopDaemon() {
11915
11997
  }
11916
11998
  async function recoverOneSession(sessionId, cwd, tmuxIdSet, tmuxNameToId, panesByWindow) {
11917
11999
  const stateFile = statePath(cwd, sessionId);
11918
- if (!existsSync32(stateFile)) return false;
12000
+ if (!existsSync33(stateFile)) return false;
11919
12001
  let session;
11920
12002
  try {
11921
- session = JSON.parse(readFileSync29(stateFile, "utf-8"));
12003
+ session = JSON.parse(readFileSync30(stateFile, "utf-8"));
11922
12004
  } catch {
11923
12005
  console.error(`[sisyphus] Failed to read session state for ${sessionId}, skipping`);
11924
12006
  return false;
@@ -12080,6 +12162,7 @@ async function startDaemon() {
12080
12162
  await recoverSessions();
12081
12163
  await sweepOrphans();
12082
12164
  startHeartbeatScanner();
12165
+ void backfillUploads();
12083
12166
  const shutdown = async () => {
12084
12167
  console.log("[sisyphus] Shutting down...");
12085
12168
  stopLogRotator();