@saadnvd1/agent-os 0.3.513 → 0.3.516

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.
@@ -1,7 +1,6 @@
1
1
  // A task's PR stage for the sidebar, from state AgentOS already holds: the
2
2
  // PR as the last poll saw it, the stored review and CI checks, escalations,
3
3
  // asks and the armed flag. Nothing here asks GitHub.
4
- import { db, type Session } from "../db";
5
4
  import { cachedPR, storedPR } from "../tasks/session";
6
5
  import { derivePrStage } from "../tasks/pr-stage";
7
6
  import { getCheck } from "../orchestrator/checks";
@@ -9,30 +8,23 @@ import { holdingEscalations } from "../orchestrator/gates";
9
8
  import { openBySubject, workSubject } from "../orchestrator/asks";
10
9
  import { ciSettleLeft } from "../orchestrator/task-state";
11
10
  import { knownCommitTime } from "../orchestrator/facts";
11
+ import { prMemo, type Pass } from "./incremental";
12
12
  import type { SessionStatusResponse } from "./collect";
13
13
 
14
- type TaskRow = Session & { workspace_id: string };
15
-
16
14
  export function addPrStages(
17
- statuses: Record<string, SessionStatusResponse>
15
+ statuses: Record<string, SessionStatusResponse>,
16
+ pass: Pass
18
17
  ): void {
19
- const tasks = db
20
- .prepare(
21
- `SELECT s.*, p.workspace_id FROM sessions s
22
- JOIN projects p ON p.id = s.project_id
23
- WHERE s.task_status = 'running' AND s.pr_number IS NOT NULL
24
- AND s.archived_at IS NULL`
25
- )
26
- .all() as TaskRow[];
27
- for (const t of tasks) {
18
+ for (const t of pass.rows.values()) {
19
+ if (t.task_status !== "running" || !t.pr_number || !t.project_id) continue;
28
20
  const status = statuses[t.id];
29
- if (!status) continue;
30
- try {
31
- const pr = cachedPR(t.id) ?? storedPR(t);
32
- const head = pr?.head;
33
- const stage = derivePrStage({
34
- pr,
35
- settleIn:
21
+ if (!status || t.project_workspace_id === null) continue;
22
+ const workspaceId = t.project_workspace_id;
23
+ const stage = prMemo(pass, t.id, () => {
24
+ try {
25
+ const pr = cachedPR(t.id) ?? storedPR(t);
26
+ const head = pr?.head;
27
+ const settleIn =
36
28
  pr?.checks === "pass" && head
37
29
  ? ciSettleLeft({
38
30
  taskId: t.id,
@@ -40,16 +32,27 @@ export function addPrStages(
40
32
  checkCount: pr.checkCount ?? 0,
41
33
  committedAt: knownCommitTime(head),
42
34
  })
43
- : 0,
44
- review: head ? (getCheck(t.id, head, "review")?.status ?? null) : null,
45
- held:
46
- holdingEscalations(t.id).length > 0 ||
47
- !!openBySubject(t.workspace_id, workSubject(t.id)),
48
- armed: !!t.merge_armed_at,
49
- });
50
- if (stage) status.prStage = stage;
51
- } catch (error) {
52
- console.error(`[status] PR stage of ${t.id.slice(0, 8)}:`, error);
53
- }
35
+ : 0;
36
+ return {
37
+ value: derivePrStage({
38
+ pr,
39
+ settleIn,
40
+ review: head
41
+ ? (getCheck(t.id, head, "review")?.status ?? null)
42
+ : null,
43
+ held:
44
+ holdingEscalations(t.id).length > 0 ||
45
+ !!openBySubject(workspaceId, workSubject(t.id)),
46
+ armed: !!t.merge_armed_at,
47
+ }),
48
+ // Counting down to the end of the settle wait: time moves it.
49
+ keep: settleIn <= 0,
50
+ };
51
+ } catch (error) {
52
+ console.error(`[status] PR stage of ${t.id.slice(0, 8)}:`, error);
53
+ return { value: null, keep: false };
54
+ }
55
+ });
56
+ if (stage) status.prStage = stage;
54
57
  }
55
58
  }
@@ -18,6 +18,7 @@ import { lookupPR } from "./pr-poll";
18
18
  import { captureMergedTask } from "../session-logs";
19
19
  import { notifyStatusChanged } from "../status/hub";
20
20
  import type { TaskPR } from "./state";
21
+ import { markStatusDirty } from "../status/dirty";
21
22
 
22
23
  export const expandHome = (p: string) => p.replace(/^~/, os.homedir());
23
24
 
@@ -190,6 +191,7 @@ export async function prFor(
190
191
  if (renamed && !refused) moveBranch(session, renamed);
191
192
  const before = prCache.get(session.id)?.pr;
192
193
  prCache.set(session.id, { at: Date.now(), pr });
194
+ markStatusDirty(session.id);
193
195
  // A PR whose stage inputs moved is news for the sidebar's badge.
194
196
  if (prSignature(before) !== prSignature(pr)) notifyStatusChanged();
195
197
  if (pr) {
@@ -279,4 +281,5 @@ export function storedPR(s: Session): TaskPR | null {
279
281
 
280
282
  export function forgetPR(sessionId: string): void {
281
283
  prCache.delete(sessionId);
284
+ markStatusDirty(sessionId);
282
285
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saadnvd1/agent-os",
3
- "version": "0.3.513",
3
+ "version": "0.3.516",
4
4
  "description": "Self-hosted web UI for managing Claude Code sessions",
5
5
  "bin": {
6
6
  "agent-os": "scripts/agent-os"
package/server.ts CHANGED
@@ -318,6 +318,7 @@ app.prepare().then(async () => {
318
318
  const connect = demo
319
319
  ? { hostname: () => null }
320
320
  : startConnect({ onRequest, onUpgrade }, port);
321
+ policy.machineHost = () => connect.hostname();
321
322
  // HTTPS on the tailnet (its own port) for passkeys and other secure-origin APIs.
322
323
  if (
323
324
  !demo &&