autopilot-code 0.0.27 → 0.1.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/.autopilot/autopilot.json +2 -1
- package/dist/cli.js +2 -1
- package/package.json +1 -1
- package/scripts/postinstall.js +3 -1
- package/scripts/run_autopilot.py +87 -0
- package/templates/autopilot.json +2 -1
package/dist/cli.js
CHANGED
package/package.json
CHANGED
package/scripts/postinstall.js
CHANGED
|
@@ -14,7 +14,9 @@ if (process.env.CI || process.env.GITHUB_ACTIONS) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
// Skip if running in an autopilot worktree (prevents killing the running service)
|
|
17
|
-
|
|
17
|
+
// INIT_CWD is set by npm to the directory where npm install was run
|
|
18
|
+
const initCwd = process.env.INIT_CWD || process.cwd();
|
|
19
|
+
if (initCwd.includes('/tmp/autopilot-issue-') || process.env.AUTOPILOT_WORKTREE) {
|
|
18
20
|
console.log('Autopilot: skipping auto-install (running in worktree).');
|
|
19
21
|
process.exit(0);
|
|
20
22
|
}
|
package/scripts/run_autopilot.py
CHANGED
|
@@ -84,6 +84,7 @@ class RepoConfig:
|
|
|
84
84
|
conflict_resolution_max_attempts: int
|
|
85
85
|
auto_fix_checks: bool
|
|
86
86
|
auto_fix_checks_max_attempts: int
|
|
87
|
+
auto_update: bool
|
|
87
88
|
|
|
88
89
|
|
|
89
90
|
def load_config(repo_root: Path) -> RepoConfig | None:
|
|
@@ -132,6 +133,7 @@ def load_config(repo_root: Path) -> RepoConfig | None:
|
|
|
132
133
|
conflict_resolution_max_attempts=conflict_resolution_max_attempts,
|
|
133
134
|
auto_fix_checks=auto_fix_checks,
|
|
134
135
|
auto_fix_checks_max_attempts=auto_fix_checks_max_attempts,
|
|
136
|
+
auto_update=data.get("autoUpdate", False),
|
|
135
137
|
)
|
|
136
138
|
|
|
137
139
|
|
|
@@ -245,6 +247,68 @@ def write_state(repo_root: Path, state: dict[str, Any]) -> None:
|
|
|
245
247
|
p.write_text(json.dumps(state, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
|
246
248
|
|
|
247
249
|
|
|
250
|
+
def load_global_state() -> dict[str, Any]:
|
|
251
|
+
p = GLOBAL_STATE_FILE
|
|
252
|
+
if not p.exists():
|
|
253
|
+
GLOBAL_CONFIG_DIR.mkdir(parents=True, exist_ok=True)
|
|
254
|
+
return {}
|
|
255
|
+
try:
|
|
256
|
+
return json.loads(p.read_text(encoding="utf-8"))
|
|
257
|
+
except Exception:
|
|
258
|
+
return {}
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def write_global_state(state: dict[str, Any]) -> None:
|
|
262
|
+
GLOBAL_CONFIG_DIR.mkdir(parents=True, exist_ok=True)
|
|
263
|
+
GLOBAL_STATE_FILE.write_text(json.dumps(state, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def flag_autopilot_needs_update() -> None:
|
|
267
|
+
"""Flag that autopilot needs to update itself."""
|
|
268
|
+
state = load_global_state()
|
|
269
|
+
state["needsUpdate"] = True
|
|
270
|
+
write_global_state(state)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def check_autopilot_needs_update() -> bool:
|
|
274
|
+
"""Check if autopilot is flagged for update."""
|
|
275
|
+
state = load_global_state()
|
|
276
|
+
return state.get("needsUpdate", False)
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def clear_autopilot_update_flag() -> None:
|
|
280
|
+
"""Clear the update flag."""
|
|
281
|
+
state = load_global_state()
|
|
282
|
+
if "needsUpdate" in state:
|
|
283
|
+
del state["needsUpdate"]
|
|
284
|
+
write_global_state(state)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def is_autopilot_repo(repo: str) -> bool:
|
|
288
|
+
"""Check if the repo is the autopilot repository."""
|
|
289
|
+
return repo in ("bakkensoftware/autopilot", "anomalyco/autopilot")
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def update_autopilot() -> bool:
|
|
293
|
+
"""Update autopilot globally and restart service."""
|
|
294
|
+
print("[autopilot] Updating autopilot-code...", flush=True)
|
|
295
|
+
|
|
296
|
+
try:
|
|
297
|
+
sh(["npm", "install", "-g", "autopilot-code"], check=True)
|
|
298
|
+
print("[autopilot] Successfully installed updated autopilot-code", flush=True)
|
|
299
|
+
except Exception as e:
|
|
300
|
+
print(f"[autopilot] Failed to install autopilot-code: {e}", flush=True)
|
|
301
|
+
return False
|
|
302
|
+
|
|
303
|
+
try:
|
|
304
|
+
sh(["systemctl", "--user", "restart", "autopilot"], check=True)
|
|
305
|
+
print("[autopilot] Restarted autopilot service", flush=True)
|
|
306
|
+
return True
|
|
307
|
+
except Exception as e:
|
|
308
|
+
print(f"[autopilot] Failed to restart service: {e}", flush=True)
|
|
309
|
+
return False
|
|
310
|
+
|
|
311
|
+
|
|
248
312
|
def touch_heartbeat(cfg: RepoConfig, issue_number: int) -> None:
|
|
249
313
|
"""Update durable local heartbeat state for the repo.
|
|
250
314
|
|
|
@@ -585,6 +649,11 @@ def try_merge_pr(cfg: RepoConfig, issue_number: int, pr: dict[str, Any]) -> bool
|
|
|
585
649
|
"--add-label", cfg.label_done, "--remove-label", cfg.label_in_progress])
|
|
586
650
|
sh(["gh", "issue", "close", str(issue_number), "--repo", cfg.repo])
|
|
587
651
|
|
|
652
|
+
# Flag autopilot for update if we merged our own repo
|
|
653
|
+
if is_autopilot_repo(cfg.repo):
|
|
654
|
+
print(f"[{cfg.repo}] Merged PR to autopilot repo, flagging for self-update", flush=True)
|
|
655
|
+
flag_autopilot_needs_update()
|
|
656
|
+
|
|
588
657
|
return True
|
|
589
658
|
except Exception as e:
|
|
590
659
|
print(f"[{cfg.repo}] Failed to merge PR #{pr_number}: {e}", flush=True)
|
|
@@ -747,6 +816,24 @@ def run_cycle(
|
|
|
747
816
|
]
|
|
748
817
|
)
|
|
749
818
|
|
|
819
|
+
# Check if autopilot needs to update
|
|
820
|
+
if not dry_run and check_autopilot_needs_update():
|
|
821
|
+
print("[autopilot] Detected need for self-update", flush=True)
|
|
822
|
+
|
|
823
|
+
# Check if any repo has auto_update enabled
|
|
824
|
+
any_auto_update = any(cfg.auto_update for cfg in all_configs)
|
|
825
|
+
|
|
826
|
+
if any_auto_update:
|
|
827
|
+
print("[autopilot] Performing self-update...", flush=True)
|
|
828
|
+
if update_autopilot():
|
|
829
|
+
clear_autopilot_update_flag()
|
|
830
|
+
print("[autopilot] Self-update completed, service restarted", flush=True)
|
|
831
|
+
else:
|
|
832
|
+
print("[autopilot] Self-update failed, flag preserved for next cycle", flush=True)
|
|
833
|
+
else:
|
|
834
|
+
print("[autopilot] auto_update is disabled for all repos, skipping self-update", flush=True)
|
|
835
|
+
clear_autopilot_update_flag()
|
|
836
|
+
|
|
750
837
|
return claimed_count
|
|
751
838
|
|
|
752
839
|
|