@proagentstore/cli 0.1.27 → 0.1.28
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.
|
@@ -122,10 +122,15 @@ export class CodingRuntime {
|
|
|
122
122
|
}
|
|
123
123
|
return { ok: true };
|
|
124
124
|
}
|
|
125
|
-
/**
|
|
125
|
+
/**
|
|
126
|
+
* Polled by the brain workflow: has the human resolved the handoff? Defaults to
|
|
127
|
+
* NOT resolved when there's no live entry — if the runner restarted mid-handoff
|
|
128
|
+
* we must NOT auto-resume (the brain would proceed without the value it was told
|
|
129
|
+
* to wait for); the workflow's poll loop times out safely instead.
|
|
130
|
+
*/
|
|
126
131
|
takeoverStatus(sessionId) {
|
|
127
132
|
const t = this.takeovers.get(sessionId);
|
|
128
|
-
return { resolved: t?.resolved ??
|
|
133
|
+
return { resolved: t?.resolved ?? false, value: t?.value };
|
|
129
134
|
}
|
|
130
135
|
endTakeover(sessionId) {
|
|
131
136
|
this.takeovers.delete(sessionId);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { execFileSync } from "node:child_process";
|
|
2
|
-
import { existsSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { existsSync, mkdirSync, rmSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
3
4
|
/**
|
|
4
5
|
* Low-level tmux primitives for the coding runtime.
|
|
5
6
|
*
|
|
@@ -98,13 +99,19 @@ export function sanitizeSessionName(label) {
|
|
|
98
99
|
* can surface it (a session can't start without its repo).
|
|
99
100
|
*/
|
|
100
101
|
export function ensureRepo(dir, opts = {}) {
|
|
101
|
-
|
|
102
|
+
// A real checkout (has .git) is reused as-is.
|
|
103
|
+
if (existsSync(join(dir, ".git")))
|
|
102
104
|
return dir;
|
|
103
105
|
if (!opts.cloneUrl) {
|
|
104
106
|
// No source to clone from — make the directory so tmux can cd into it.
|
|
105
|
-
|
|
107
|
+
if (!existsSync(dir))
|
|
108
|
+
mkdirSync(dir, { recursive: true });
|
|
106
109
|
return dir;
|
|
107
110
|
}
|
|
111
|
+
// A stale/empty/half-cloned dir (exists but no .git) would make `git clone`
|
|
112
|
+
// fail on a non-empty target — clear it first so the clone is clean.
|
|
113
|
+
if (existsSync(dir))
|
|
114
|
+
rmSync(dir, { recursive: true, force: true });
|
|
108
115
|
let url = opts.cloneUrl;
|
|
109
116
|
if (opts.token && /^https:\/\//.test(url)) {
|
|
110
117
|
url = url.replace(/^https:\/\//, `https://x-access-token:${opts.token}@`);
|
|
@@ -765,7 +765,10 @@ export class LocalRunner {
|
|
|
765
765
|
const task = this.store.getTask(taskId);
|
|
766
766
|
if (task) {
|
|
767
767
|
const success = outcome === "submitted" || outcome === "ready" || outcome === "expired";
|
|
768
|
-
|
|
768
|
+
// 'blocked' = the agent stopped and needs the USER (email verification, can't
|
|
769
|
+
// proceed truthfully) — it's needs-attention, not a failure, so keep it a
|
|
770
|
+
// distinct status (the console shows it as an active ticket, not buried).
|
|
771
|
+
task.status = outcome === "blocked" ? "blocked" : success ? "completed" : "failed";
|
|
769
772
|
task.output = { outcome, detail };
|
|
770
773
|
if (!success)
|
|
771
774
|
task.error = detail || outcome;
|