@saadnvd1/agent-os 0.3.684 → 0.3.691
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/app/api/dev-servers/detect/route.ts +1 -2
- package/app/api/projects/[id]/dev-servers/[dsId]/route.ts +2 -4
- package/app/page.tsx +1 -2
- package/components/Artifacts/ArtifactsPanel.tsx +1 -1
- package/components/FileExplorer/FileTabs.tsx +1 -1
- package/components/Pane/DesktopTabBar.tsx +2 -2
- package/components/QuickSwitcher.tsx +24 -21
- package/components/SessionList/SessionRowMenu.tsx +0 -1
- package/components/Settings/ExperimentsSection.test.ts +7 -1
- package/components/Settings/NoApprovalsSection.test.ts +7 -1
- package/components/Terminal/TerminalToolbar.tsx +1 -1
- package/components/Terminal/VirtualKeyboard.tsx +1 -1
- package/components/WorkerCard.tsx +1 -7
- package/components/Workspaces/WorkspaceNameDialog.tsx +5 -3
- package/components/a/AButton.tsx +1 -6
- package/components/a/AIconButton.tsx +1 -5
- package/contexts/PaneContext.tsx +1 -6
- package/data/lumifyhub/index.ts +2 -4
- package/hooks/useDirectoryBrowser.ts +5 -4
- package/hooks/useDrawerAnimation.ts +11 -14
- package/hooks/useFileDrop.ts +2 -6
- package/hooks/useKeybarVisibility.ts +10 -29
- package/hooks/useSidebarPinned.ts +7 -23
- package/hooks/useSpeechRecognition.ts +19 -5
- package/hooks/useStoredFlag.ts +47 -0
- package/hooks/useViewport.ts +11 -17
- package/lib/approvals/no-approvals.ts +1 -7
- package/lib/artifacts/store.ts +1 -2
- package/lib/away/report.ts +1 -2
- package/lib/away/run.ts +1 -2
- package/lib/away/state.ts +1 -2
- package/lib/bookmarks/store.ts +1 -2
- package/lib/bus/delivery.ts +1 -2
- package/lib/bus/index.ts +1 -2
- package/lib/chat/compact-context.ts +1 -2
- package/lib/chat/stop.ts +1 -2
- package/lib/chat/worker/host.ts +1 -1
- package/lib/code-health/reports.ts +1 -2
- package/lib/db/lumifyhub.ts +2 -4
- package/lib/db/schedules-move.ts +1 -2
- package/lib/db/session-parts/tasks.ts +1 -2
- package/lib/db/stacks.ts +3 -9
- package/lib/db/types.ts +1 -7
- package/lib/doctor/checks.ts +7 -9
- package/lib/done/archive.ts +1 -2
- package/lib/experiments/meter.ts +1 -7
- package/lib/health/env/classes.ts +0 -2
- package/lib/health/env/recordHit.ts +1 -2
- package/lib/health/spin.ts +1 -4
- package/lib/health/store.ts +1 -2
- package/lib/hosts/index.ts +1 -2
- package/lib/hosts/peer-sync.ts +2 -4
- package/lib/hosts/remote-api.ts +1 -2
- package/lib/lumifyhub/types.ts +2 -8
- package/lib/notify/index.ts +1 -2
- package/lib/notify/push/index.ts +2 -7
- package/lib/orchestrator/external-pr.ts +1 -2
- package/lib/orchestrator/gates.ts +1 -6
- package/lib/orchestrator/needs-you-items.ts +16 -20
- package/lib/orchestrator/pr-wake.ts +1 -2
- package/lib/orchestrator/rebase.ts +1 -2
- package/lib/orchestrator/review.ts +1 -2
- package/lib/orchestrator/usage.ts +1 -2
- package/lib/plans/claim.ts +1 -2
- package/lib/plans/features.ts +4 -11
- package/lib/plans/release.ts +2 -4
- package/lib/ports.ts +1 -2
- package/lib/program-status/records.ts +1 -1
- package/lib/project-config/database.ts +1 -2
- package/lib/projects.ts +1 -2
- package/lib/recipes/settle.ts +2 -4
- package/lib/recipes/store.ts +2 -4
- package/lib/schedules/store.ts +2 -4
- package/lib/search/conversations/backfill.ts +2 -4
- package/lib/security/auth.ts +1 -2
- package/lib/security/passkeys.ts +1 -2
- package/lib/security/presence.ts +1 -7
- package/lib/session-artifacts/types.ts +1 -8
- package/lib/session-audit/transcript.ts +1 -3
- package/lib/session-logs/index.ts +1 -2
- package/lib/sessions/launch.ts +1 -2
- package/lib/share/snapshot.ts +1 -7
- package/lib/share/store.ts +1 -2
- package/lib/sidebar/orchestrator-row.ts +1 -6
- package/lib/sidebar/row-menu.ts +1 -2
- package/lib/sidebar/shelves.ts +1 -6
- package/lib/simulator/index.ts +1 -2
- package/lib/simulator/lease.ts +1 -5
- package/lib/stacks/index.ts +1 -1
- package/lib/stacks/plan.ts +1 -1
- package/lib/stacks/restack.ts +1 -2
- package/lib/stacks/tick.ts +1 -2
- package/lib/status/socket.ts +1 -2
- package/lib/tasks/contract/authorize.ts +1 -2
- package/lib/tasks/contract/plan.ts +1 -2
- package/lib/tasks/contract/sync.ts +1 -2
- package/lib/tasks/holds.ts +1 -5
- package/lib/tasks/index.ts +1 -2
- package/lib/tasks/loop-types.ts +1 -6
- package/lib/tasks/move-guard.ts +1 -2
- package/lib/tasks/move.ts +1 -2
- package/lib/tasks/moved-away.ts +1 -2
- package/lib/tasks/pause-hold.ts +1 -2
- package/lib/tasks/pause.ts +3 -6
- package/lib/tasks/pr-activity.ts +1 -3
- package/lib/tasks/queue-rows.ts +2 -4
- package/lib/tasks/queue-types.ts +1 -5
- package/lib/tasks/queue.ts +1 -2
- package/lib/tasks/refresh-base.ts +1 -2
- package/lib/tasks/start.ts +2 -4
- package/lib/tasks/starter.ts +1 -2
- package/lib/tasks/state.ts +1 -6
- package/lib/theme-config.ts +1 -8
- package/lib/updates/banner.ts +1 -6
- package/lib/updates/run.ts +1 -2
- package/lib/usage/aggregate.ts +1 -1
- package/lib/usage/nightly.ts +1 -2
- package/lib/usage/rate-limits.ts +1 -2
- package/lib/usage/turns.ts +1 -2
- package/lib/usage/windows.ts +5 -7
- package/lib/workspaces.ts +1 -2
- package/lib/worktree-sweep/databases.ts +0 -1
- package/package.json +3 -3
package/lib/recipes/store.ts
CHANGED
|
@@ -26,8 +26,7 @@ export const toRun = (r: RunRow): RecipeRun => ({
|
|
|
26
26
|
|
|
27
27
|
export function getRecipe(id: string): Recipe | null {
|
|
28
28
|
const row = db.prepare(`SELECT * FROM recipes WHERE id = ?`).get(id) as
|
|
29
|
-
|
|
|
30
|
-
| undefined;
|
|
29
|
+
RecipeRow | undefined;
|
|
31
30
|
return row ? toRecipe(row) : null;
|
|
32
31
|
}
|
|
33
32
|
|
|
@@ -285,8 +284,7 @@ export function lastRevisionId(recipeId: string): number | null {
|
|
|
285
284
|
|
|
286
285
|
export function getRun(id: number): RecipeRun | null {
|
|
287
286
|
const row = db.prepare(`SELECT * FROM recipe_runs WHERE id = ?`).get(id) as
|
|
288
|
-
|
|
|
289
|
-
| undefined;
|
|
287
|
+
RunRow | undefined;
|
|
290
288
|
return row ? toRun(row) : null;
|
|
291
289
|
}
|
|
292
290
|
|
package/lib/schedules/store.ts
CHANGED
|
@@ -138,8 +138,7 @@ export function finishOneOff(id: string, now = Date.now()): boolean {
|
|
|
138
138
|
|
|
139
139
|
export function getSchedule(id: string): Schedule | null {
|
|
140
140
|
const row = db.prepare(`SELECT * FROM schedules WHERE id = ?`).get(id) as
|
|
141
|
-
|
|
|
142
|
-
| undefined;
|
|
141
|
+
Row | undefined;
|
|
143
142
|
return row ? toSchedule(row) : null;
|
|
144
143
|
}
|
|
145
144
|
|
|
@@ -164,8 +163,7 @@ export function findSchedule(ref: string): Schedule {
|
|
|
164
163
|
export function getSessionRow(id: string): Session | null {
|
|
165
164
|
return (
|
|
166
165
|
(db.prepare(`SELECT * FROM session_rows WHERE id = ?`).get(id) as
|
|
167
|
-
|
|
|
168
|
-
| undefined) ?? null
|
|
166
|
+
Session | undefined) ?? null
|
|
169
167
|
);
|
|
170
168
|
}
|
|
171
169
|
|
|
@@ -13,8 +13,7 @@ interface State {
|
|
|
13
13
|
|
|
14
14
|
const stateOf = (db: Database.Database): State | undefined =>
|
|
15
15
|
db.prepare(`SELECT * FROM chat_search_state WHERE id = 1`).get() as
|
|
16
|
-
|
|
|
17
|
-
| undefined;
|
|
16
|
+
State | undefined;
|
|
18
17
|
|
|
19
18
|
// Starts the index over: the stored version is not this build's.
|
|
20
19
|
function reset(db: Database.Database): void {
|
|
@@ -68,8 +67,7 @@ export function backfillStep(db: Database.Database, batch = BATCH): boolean {
|
|
|
68
67
|
for (const r of rows) {
|
|
69
68
|
if (!r.text) continue;
|
|
70
69
|
const have = key.get(r.session_id, r.item_id) as
|
|
71
|
-
|
|
72
|
-
| undefined;
|
|
70
|
+
{ id: number } | undefined;
|
|
73
71
|
if (have) del.run(have.id);
|
|
74
72
|
else mk.run(r.session_id, r.item_id);
|
|
75
73
|
const id = (key.get(r.session_id, r.item_id) as { id: number }).id;
|
package/lib/security/auth.ts
CHANGED
|
@@ -20,8 +20,7 @@ export const REMOTE_HEADER = "x-agentos-remote";
|
|
|
20
20
|
export type Trust = "loopback" | "tailnet" | "device" | "open";
|
|
21
21
|
|
|
22
22
|
export type AuthResult =
|
|
23
|
-
|
|
24
|
-
| { ok: false };
|
|
23
|
+
{ ok: true; via: Trust; deviceId?: string } | { ok: false };
|
|
25
24
|
|
|
26
25
|
export interface AuthRequest {
|
|
27
26
|
url?: string;
|
package/lib/security/passkeys.ts
CHANGED
|
@@ -54,8 +54,7 @@ export function activePasskeyCount(): number {
|
|
|
54
54
|
export function getPasskey(id: string): PasskeyRow | null {
|
|
55
55
|
return (
|
|
56
56
|
(getDb().prepare(`SELECT * FROM passkeys WHERE id = ?`).get(id) as
|
|
57
|
-
|
|
|
58
|
-
| undefined) ?? null
|
|
57
|
+
PasskeyRow | undefined) ?? null
|
|
59
58
|
);
|
|
60
59
|
}
|
|
61
60
|
|
package/lib/security/presence.ts
CHANGED
|
@@ -147,13 +147,7 @@ const transportsOf = (k: PasskeyRow) =>
|
|
|
147
147
|
? (JSON.parse(k.transports) as AuthenticatorTransport[])
|
|
148
148
|
: undefined;
|
|
149
149
|
type AuthenticatorTransport =
|
|
150
|
-
| "
|
|
151
|
-
| "cable"
|
|
152
|
-
| "hybrid"
|
|
153
|
-
| "internal"
|
|
154
|
-
| "nfc"
|
|
155
|
-
| "smart-card"
|
|
156
|
-
| "usb";
|
|
150
|
+
"ble" | "cable" | "hybrid" | "internal" | "nfc" | "smart-card" | "usb";
|
|
157
151
|
|
|
158
152
|
// Options for an assertion on this host, or null when it has no passkey.
|
|
159
153
|
export async function assertionOptions(
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
// What a session produced, as the Artifacts view lists it. Client-safe.
|
|
2
2
|
|
|
3
3
|
export type ArtifactKind =
|
|
4
|
-
| "
|
|
5
|
-
| "file"
|
|
6
|
-
| "page"
|
|
7
|
-
| "image"
|
|
8
|
-
| "log"
|
|
9
|
-
| "pr"
|
|
10
|
-
| "run"
|
|
11
|
-
| "session-log";
|
|
4
|
+
"plan" | "file" | "page" | "image" | "log" | "pr" | "run" | "session-log";
|
|
12
5
|
|
|
13
6
|
// live: there to open. kept: its worktree went, a copy was kept. in-pr:
|
|
14
7
|
// committed, so the PR has it. gone: nothing left to open. outside: there,
|
|
@@ -121,8 +121,7 @@ export async function writeLog(
|
|
|
121
121
|
opts: CaptureOpts & { plan?: string | null } = {}
|
|
122
122
|
): Promise<boolean> {
|
|
123
123
|
const row = db.prepare(`SELECT * FROM session_rows WHERE id = ?`).get(id) as
|
|
124
|
-
|
|
|
125
|
-
| undefined;
|
|
124
|
+
Session | undefined;
|
|
126
125
|
const existing = getLog(id);
|
|
127
126
|
if (!eligible(row) || (existing && !opts.rewrite)) return false;
|
|
128
127
|
const info = opts.noGh
|
package/lib/sessions/launch.ts
CHANGED
|
@@ -340,7 +340,6 @@ async function launch(input: LaunchInput, id: string): Promise<Launched> {
|
|
|
340
340
|
|
|
341
341
|
function sessionName(id: string): string | null {
|
|
342
342
|
const row = db.prepare(`SELECT name FROM sessions WHERE id = ?`).get(id) as
|
|
343
|
-
|
|
344
|
-
| undefined;
|
|
343
|
+
{ name: string } | undefined;
|
|
345
344
|
return row?.name ?? null;
|
|
346
345
|
}
|
package/lib/share/snapshot.ts
CHANGED
|
@@ -17,13 +17,7 @@ import {
|
|
|
17
17
|
} from "./redact";
|
|
18
18
|
|
|
19
19
|
export type SnapshotType =
|
|
20
|
-
| "
|
|
21
|
-
| "assistant"
|
|
22
|
-
| "plan"
|
|
23
|
-
| "error"
|
|
24
|
-
| "divider"
|
|
25
|
-
| "artifact"
|
|
26
|
-
| "detail";
|
|
20
|
+
"user" | "assistant" | "plan" | "error" | "divider" | "artifact" | "detail";
|
|
27
21
|
|
|
28
22
|
export interface SnapshotItem {
|
|
29
23
|
id: string;
|
package/lib/share/store.ts
CHANGED
|
@@ -28,8 +28,7 @@ export function listSharedLinks(): SharedLink[] {
|
|
|
28
28
|
|
|
29
29
|
export function getSharedLink(id: string): SharedLink | undefined {
|
|
30
30
|
return db.prepare(`SELECT * FROM shared_links WHERE id = ?`).get(id) as
|
|
31
|
-
|
|
|
32
|
-
| undefined;
|
|
31
|
+
SharedLink | undefined;
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
export function markRevoked(id: string): void {
|
|
@@ -12,12 +12,7 @@ export interface OrchestratorRowCounts {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export type OrchestratorState =
|
|
15
|
-
| "
|
|
16
|
-
| "Failed"
|
|
17
|
-
| "Working"
|
|
18
|
-
| "Replied"
|
|
19
|
-
| "Waiting"
|
|
20
|
-
| "Idle";
|
|
15
|
+
"Paused" | "Failed" | "Working" | "Replied" | "Waiting" | "Idle";
|
|
21
16
|
|
|
22
17
|
const plural = (n: number, one: string) => `${n} ${one}${n === 1 ? "" : "s"}`;
|
|
23
18
|
|
package/lib/sidebar/row-menu.ts
CHANGED
|
@@ -38,8 +38,7 @@ export type RowMenuItem =
|
|
|
38
38
|
export type RowMenuGroup = "open" | "share" | "restart" | "move" | "automate";
|
|
39
39
|
|
|
40
40
|
export type RowMenuEntry =
|
|
41
|
-
| RowMenuItem
|
|
42
|
-
| { group: RowMenuGroup; items: RowMenuItem[] };
|
|
41
|
+
RowMenuItem | { group: RowMenuGroup; items: RowMenuItem[] };
|
|
43
42
|
|
|
44
43
|
export interface RowMenuInput {
|
|
45
44
|
session: Pick<
|
package/lib/sidebar/shelves.ts
CHANGED
|
@@ -8,12 +8,7 @@ import { isFinished, type TaskState } from "@/lib/tasks/state";
|
|
|
8
8
|
|
|
9
9
|
// Why a session is blocked on you.
|
|
10
10
|
export type SessionNeed =
|
|
11
|
-
| "
|
|
12
|
-
| "answer"
|
|
13
|
-
| "signin"
|
|
14
|
-
| "input"
|
|
15
|
-
| "unsent"
|
|
16
|
-
| "failed";
|
|
11
|
+
"approve" | "answer" | "signin" | "input" | "unsent" | "failed";
|
|
17
12
|
|
|
18
13
|
export const NEED_LABEL: Record<SessionNeed, string> = {
|
|
19
14
|
approve: "Approve",
|
package/lib/simulator/index.ts
CHANGED
|
@@ -71,8 +71,7 @@ export { shutTaskSimulators, shutFinishedTaskSimulators } from "./task-devices";
|
|
|
71
71
|
|
|
72
72
|
const session = (id: string) =>
|
|
73
73
|
db.prepare(`SELECT * FROM session_rows WHERE id = ?`).get(id) as
|
|
74
|
-
|
|
|
75
|
-
| undefined;
|
|
74
|
+
Session | undefined;
|
|
76
75
|
|
|
77
76
|
function declared(sessionId: string): {
|
|
78
77
|
config: NonNullable<ProjectConfig["simulator"]>;
|
package/lib/simulator/lease.ts
CHANGED
|
@@ -8,11 +8,7 @@ import { db } from "../db";
|
|
|
8
8
|
import { baseName, deviceNameFor, ownsDevice, type SimDevice } from "./simctl";
|
|
9
9
|
|
|
10
10
|
export type LeaseState =
|
|
11
|
-
| "
|
|
12
|
-
| "starting"
|
|
13
|
-
| "ready"
|
|
14
|
-
| "failed"
|
|
15
|
-
| "shutdown";
|
|
11
|
+
"creating" | "starting" | "ready" | "failed" | "shutdown";
|
|
16
12
|
|
|
17
13
|
export interface Lease {
|
|
18
14
|
session_id: string;
|
package/lib/stacks/index.ts
CHANGED
|
@@ -107,7 +107,7 @@ export function retryItem(stackId: string, itemId: string): StackView {
|
|
|
107
107
|
}
|
|
108
108
|
const items = q.items(db, stackId);
|
|
109
109
|
const reset = new Set([item.id]);
|
|
110
|
-
for (let grew = true; grew;
|
|
110
|
+
for (let grew = true; grew;) {
|
|
111
111
|
grew = false;
|
|
112
112
|
for (const i of items) {
|
|
113
113
|
if (reset.has(i.id) || i.status !== "held" || i.held_outside) continue;
|
package/lib/stacks/plan.ts
CHANGED
|
@@ -132,7 +132,7 @@ export function planStack(cards: PlanCard[]): PlanItem[] {
|
|
|
132
132
|
: best;
|
|
133
133
|
});
|
|
134
134
|
const chain = new Set<string>();
|
|
135
|
-
for (let node: string | null = parent; node;
|
|
135
|
+
for (let node: string | null = parent; node;) {
|
|
136
136
|
chain.add(node);
|
|
137
137
|
node = items.get(node)!.parent;
|
|
138
138
|
}
|
package/lib/stacks/restack.ts
CHANGED
|
@@ -110,8 +110,7 @@ const defaults: RestackDeps = {
|
|
|
110
110
|
const sessionOf = (id: string | null) =>
|
|
111
111
|
id
|
|
112
112
|
? ((db.prepare(`SELECT * FROM session_rows WHERE id = ?`).get(id) as
|
|
113
|
-
|
|
|
114
|
-
| undefined) ?? null)
|
|
113
|
+
Session | undefined) ?? null)
|
|
115
114
|
: null;
|
|
116
115
|
|
|
117
116
|
const LIVE = new Set(["running", "pr"]);
|
package/lib/stacks/tick.ts
CHANGED
|
@@ -40,8 +40,7 @@ const LIVE = new Set(["running", "pr"]);
|
|
|
40
40
|
|
|
41
41
|
const sessionOf = (id: string) =>
|
|
42
42
|
db.prepare(`SELECT * FROM session_rows WHERE id = ?`).get(id) as
|
|
43
|
-
|
|
|
44
|
-
| undefined;
|
|
43
|
+
Session | undefined;
|
|
45
44
|
|
|
46
45
|
async function refreshItem(item: StackItemRow): Promise<void> {
|
|
47
46
|
if (!item.session_id || !LIVE.has(item.status)) return;
|
package/lib/status/socket.ts
CHANGED
|
@@ -78,7 +78,6 @@ export function sessionFolder(sessionId: string): string | null {
|
|
|
78
78
|
`SELECT worktree_path, working_directory FROM sessions WHERE id = ?`
|
|
79
79
|
)
|
|
80
80
|
.get(sessionId) as
|
|
81
|
-
|
|
82
|
-
| undefined;
|
|
81
|
+
{ worktree_path: string | null; working_directory: string } | undefined;
|
|
83
82
|
return s ? s.worktree_path || s.working_directory : null;
|
|
84
83
|
}
|
|
@@ -69,8 +69,7 @@ export async function taskRoute(
|
|
|
69
69
|
const refused = refuse(request, id, rule);
|
|
70
70
|
if (refused) return refused;
|
|
71
71
|
const task = db.prepare(`SELECT * FROM session_rows WHERE id = ?`).get(id) as
|
|
72
|
-
|
|
|
73
|
-
| undefined;
|
|
72
|
+
Session | undefined;
|
|
74
73
|
if (!task)
|
|
75
74
|
return NextResponse.json({ error: "No such task" }, { status: 404 });
|
|
76
75
|
try {
|
|
@@ -41,8 +41,7 @@ export { remotePlanPath };
|
|
|
41
41
|
|
|
42
42
|
const getSession = (id: string) =>
|
|
43
43
|
db.prepare(`SELECT * FROM session_rows WHERE id = ?`).get(id) as
|
|
44
|
-
|
|
|
45
|
-
| undefined;
|
|
44
|
+
Session | undefined;
|
|
46
45
|
|
|
47
46
|
async function readCopy(id: string): Promise<string | null> {
|
|
48
47
|
try {
|
|
@@ -33,8 +33,7 @@ const FINISHED: Record<string, TaskStatus> = {
|
|
|
33
33
|
|
|
34
34
|
const getSession = (id: string) =>
|
|
35
35
|
db.prepare(`SELECT * FROM session_rows WHERE id = ?`).get(id) as
|
|
36
|
-
|
|
|
37
|
-
| undefined;
|
|
36
|
+
Session | undefined;
|
|
38
37
|
|
|
39
38
|
// The plan-written line a held task stored on its machine (plan-step.ts),
|
|
40
39
|
// once per distinct plan: the mirror keeps the last one it told about.
|
package/lib/tasks/holds.ts
CHANGED
|
@@ -56,11 +56,7 @@ export interface MachineView {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
export type MachineCode =
|
|
59
|
-
| "
|
|
60
|
-
| "load_red"
|
|
61
|
-
| "load_amber"
|
|
62
|
-
| "heavy"
|
|
63
|
-
| "spacing";
|
|
59
|
+
"needs" | "load_red" | "load_amber" | "heavy" | "spacing";
|
|
64
60
|
|
|
65
61
|
// A reason a task isn't starting. `code` is also what a queue row stores and
|
|
66
62
|
// the client reads. A hold that rests on a machine says which one, and when
|
package/lib/tasks/index.ts
CHANGED
|
@@ -447,8 +447,7 @@ export async function shellOnly(tmuxName: string): Promise<boolean> {
|
|
|
447
447
|
|
|
448
448
|
// A chat's turn as its worker says: "unknown" when it can't be reached.
|
|
449
449
|
type ChatTurn =
|
|
450
|
-
|
|
451
|
-
| "unknown";
|
|
450
|
+
NonNullable<Awaited<ReturnType<typeof chatStateNow>>> | "unknown";
|
|
452
451
|
|
|
453
452
|
// A chat between turns waits on the next message, as a terminal at its
|
|
454
453
|
// prompt does. One whose worker can't be reached counts as busy.
|
package/lib/tasks/loop-types.ts
CHANGED
|
@@ -100,12 +100,7 @@ export interface TaskDiffPatch {
|
|
|
100
100
|
// -- Checks and the review verdict ----------------------------------------
|
|
101
101
|
|
|
102
102
|
export type CheckState =
|
|
103
|
-
| "
|
|
104
|
-
| "fail"
|
|
105
|
-
| "pending"
|
|
106
|
-
| "skipped"
|
|
107
|
-
| "cancelled"
|
|
108
|
-
| "neutral";
|
|
103
|
+
"pass" | "fail" | "pending" | "skipped" | "cancelled" | "neutral";
|
|
109
104
|
|
|
110
105
|
export interface TaskCheck {
|
|
111
106
|
name: string;
|
package/lib/tasks/move-guard.ts
CHANGED
|
@@ -52,8 +52,7 @@ export function moveRefusal(session: Session): string | null {
|
|
|
52
52
|
FROM session_rows s WHERE id = ?`
|
|
53
53
|
)
|
|
54
54
|
.get(session.id) as
|
|
55
|
-
|
|
56
|
-
| undefined;
|
|
55
|
+
{ lh_card_id: string | null; stacked: number } | undefined;
|
|
57
56
|
if (row?.lh_card_id) return "Card tasks run on this machine only for now";
|
|
58
57
|
if (row?.stacked) return "Stacked tasks run on this machine only for now";
|
|
59
58
|
return null;
|
package/lib/tasks/move.ts
CHANGED
|
@@ -127,8 +127,7 @@ function orchestratorOf(
|
|
|
127
127
|
const by = starterOrchestrator(session.started_by);
|
|
128
128
|
if (!by) return undefined;
|
|
129
129
|
const o = db.prepare(`SELECT name FROM sessions WHERE id = ?`).get(by) as
|
|
130
|
-
|
|
131
|
-
| undefined;
|
|
130
|
+
{ name: string } | undefined;
|
|
132
131
|
return o ? { id: by, name: o.name } : undefined;
|
|
133
132
|
}
|
|
134
133
|
|
package/lib/tasks/moved-away.ts
CHANGED
|
@@ -14,8 +14,7 @@ import { archiveSession } from "../done/archive";
|
|
|
14
14
|
|
|
15
15
|
export async function cleanUpMovedAway(id: string): Promise<WorktreeFate> {
|
|
16
16
|
const s = db.prepare(`SELECT * FROM session_rows WHERE id = ?`).get(id) as
|
|
17
|
-
|
|
|
18
|
-
| undefined;
|
|
17
|
+
Session | undefined;
|
|
19
18
|
if (!s || s.task_status !== "moved" || !s.held_by_device)
|
|
20
19
|
return { action: "none" };
|
|
21
20
|
await endSessionAgent(s).catch((err) =>
|
package/lib/tasks/pause-hold.ts
CHANGED
|
@@ -16,8 +16,7 @@ export function pauseHoldOf(sessionId: string): PauseHold | null {
|
|
|
16
16
|
WHERE id = ? AND pause_state IN ('pausing', 'paused') AND pause_id IS NOT NULL`
|
|
17
17
|
)
|
|
18
18
|
.get(sessionId) as
|
|
19
|
-
|
|
20
|
-
| undefined;
|
|
19
|
+
{ pause_id: number; paused_until: string | null } | undefined;
|
|
21
20
|
return row ? { pauseId: row.pause_id, until: row.paused_until } : null;
|
|
22
21
|
}
|
|
23
22
|
|
package/lib/tasks/pause.ts
CHANGED
|
@@ -74,13 +74,11 @@ const nudge = () =>
|
|
|
74
74
|
|
|
75
75
|
const sessionOf = (id: string) =>
|
|
76
76
|
db.prepare(`SELECT * FROM session_rows WHERE id = ?`).get(id) as
|
|
77
|
-
|
|
|
78
|
-
| undefined;
|
|
77
|
+
Session | undefined;
|
|
79
78
|
|
|
80
79
|
const pauseRow = (id: number) =>
|
|
81
80
|
db.prepare(`SELECT * FROM task_pauses WHERE id = ?`).get(id) as
|
|
82
|
-
|
|
|
83
|
-
| undefined;
|
|
81
|
+
TaskPause | undefined;
|
|
84
82
|
|
|
85
83
|
// SQLite's datetime('now') is UTC without a zone.
|
|
86
84
|
const ms = (v: string | null | undefined) =>
|
|
@@ -400,8 +398,7 @@ export function setPauseNote(sessionId: string, note: string | null): void {
|
|
|
400
398
|
}
|
|
401
399
|
|
|
402
400
|
export type ResumeOutcome =
|
|
403
|
-
|
|
404
|
-
| { outcome: "held"; note: string };
|
|
401
|
+
{ outcome: "resumed" | "cancelled" } | { outcome: "held"; note: string };
|
|
405
402
|
|
|
406
403
|
// A deliberate Resume, by a person or the orchestrator: starts at once, past
|
|
407
404
|
// the slot limit, like Start now. A machine in the red still holds it: it is
|
package/lib/tasks/pr-activity.ts
CHANGED
|
@@ -59,9 +59,7 @@ export async function fingerprints(
|
|
|
59
59
|
);
|
|
60
60
|
for (const n of prs) {
|
|
61
61
|
const pr = res.data?.repository?.[`p${n}`] as
|
|
62
|
-
|
|
63
|
-
| null
|
|
64
|
-
| undefined;
|
|
62
|
+
{ createdAt: string; reviews: Last; comments: Last } | null | undefined;
|
|
65
63
|
if (!pr) continue;
|
|
66
64
|
const part = (l: Last) => `${l.totalCount}:${l.nodes[0]?.id ?? ""}`;
|
|
67
65
|
out.set(n, {
|
package/lib/tasks/queue-rows.ts
CHANGED
|
@@ -14,13 +14,11 @@ export const IN_FLIGHT = ["running", "moving"];
|
|
|
14
14
|
|
|
15
15
|
export const row = (id: string) =>
|
|
16
16
|
db.prepare(`SELECT * FROM task_queue WHERE id = ?`).get(id) as
|
|
17
|
-
|
|
|
18
|
-
| undefined;
|
|
17
|
+
QueueRow | undefined;
|
|
19
18
|
|
|
20
19
|
export const sessionOf = (id: string) =>
|
|
21
20
|
db.prepare(`SELECT * FROM session_rows WHERE id = ?`).get(id) as
|
|
22
|
-
|
|
|
23
|
-
| undefined;
|
|
21
|
+
Session | undefined;
|
|
24
22
|
|
|
25
23
|
export function patch(id: string, fields: Partial<QueueRow>): void {
|
|
26
24
|
const keys = Object.keys(fields);
|
package/lib/tasks/queue-types.ts
CHANGED
|
@@ -6,11 +6,7 @@ import type { Priority, WaitCode } from "./schedule-types";
|
|
|
6
6
|
import type { StartVia } from "./starter";
|
|
7
7
|
|
|
8
8
|
export type QueueStatus =
|
|
9
|
-
| "
|
|
10
|
-
| "starting"
|
|
11
|
-
| "started"
|
|
12
|
-
| "failed"
|
|
13
|
-
| "removed";
|
|
9
|
+
"queued" | "starting" | "started" | "failed" | "removed";
|
|
14
10
|
|
|
15
11
|
export interface QueueRow {
|
|
16
12
|
id: string;
|
package/lib/tasks/queue.ts
CHANGED
|
@@ -313,8 +313,7 @@ export function moveQueued(id: string, by: -1 | 1): void {
|
|
|
313
313
|
ORDER BY q.position ${by < 0 ? "DESC" : "ASC"} LIMIT 1`
|
|
314
314
|
)
|
|
315
315
|
.get({ position: r.position, ws: workspaceId, project: r.project_id }) as
|
|
316
|
-
|
|
|
317
|
-
| undefined;
|
|
316
|
+
QueueRow | undefined;
|
|
318
317
|
if (!other) return;
|
|
319
318
|
patch(r.id, { position: other.position });
|
|
320
319
|
patch(other.id, { position: r.position });
|
|
@@ -16,8 +16,7 @@ import { restackBranch, outputOf, type Runner } from "../stacks/git";
|
|
|
16
16
|
import { run } from "./gh";
|
|
17
17
|
|
|
18
18
|
export type RefreshResult =
|
|
19
|
-
|
|
20
|
-
| { moved: true; how: "reset" | "rebase" };
|
|
19
|
+
{ moved: false; note?: string } | { moved: true; how: "reset" | "rebase" };
|
|
21
20
|
|
|
22
21
|
export interface RefreshTarget {
|
|
23
22
|
name: string;
|
package/lib/tasks/start.ts
CHANGED
|
@@ -60,8 +60,7 @@ export function launchHold(sessionId: string): string | null {
|
|
|
60
60
|
LIMIT 1`
|
|
61
61
|
)
|
|
62
62
|
.get(sessionId, sessionId, sessionId) as
|
|
63
|
-
|
|
64
|
-
| undefined;
|
|
63
|
+
{ workspace_id: string } | undefined;
|
|
65
64
|
if (!row) return null;
|
|
66
65
|
if (isPaused(row.workspace_id)) return "the orchestrator is paused by Saad";
|
|
67
66
|
const window = brakesEnabled() ? windowRefusal(readUsage()) : null;
|
|
@@ -135,8 +134,7 @@ export async function finishTaskStart(
|
|
|
135
134
|
const now = db
|
|
136
135
|
.prepare(`SELECT task_status, archived_at FROM session_rows WHERE id = ?`)
|
|
137
136
|
.get(sessionId) as
|
|
138
|
-
|
|
139
|
-
| undefined;
|
|
137
|
+
{ task_status: string | null; archived_at: string | null } | undefined;
|
|
140
138
|
if (now?.task_status !== "running" || now.archived_at)
|
|
141
139
|
return done({
|
|
142
140
|
status: "failed",
|
package/lib/tasks/starter.ts
CHANGED
|
@@ -102,8 +102,7 @@ export function orchestratorOf(startedBy: string | null | undefined) {
|
|
|
102
102
|
const row = db
|
|
103
103
|
.prepare(`SELECT role, started_by FROM sessions WHERE id = ?`)
|
|
104
104
|
.get(id) as
|
|
105
|
-
|
|
106
|
-
| undefined;
|
|
105
|
+
{ role: string | null; started_by: string | null } | undefined;
|
|
107
106
|
if (!row) return null;
|
|
108
107
|
if (row.role === "orchestrator") return id;
|
|
109
108
|
id = row.started_by;
|
package/lib/tasks/state.ts
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import type { AttributionKind } from "./code-review";
|
|
2
2
|
|
|
3
3
|
export type TaskStatus =
|
|
4
|
-
| "
|
|
5
|
-
| "merged"
|
|
6
|
-
| "dropped"
|
|
7
|
-
| "done"
|
|
8
|
-
| "moving"
|
|
9
|
-
| "moved";
|
|
4
|
+
"running" | "merged" | "dropped" | "done" | "moving" | "moved";
|
|
10
5
|
|
|
11
6
|
export type ChecksVerdict = "pass" | "fail" | "pending" | "none";
|
|
12
7
|
|
package/lib/theme-config.ts
CHANGED
|
@@ -30,14 +30,7 @@ export type DarkThemeVariant =
|
|
|
30
30
|
| "ocean"
|
|
31
31
|
| "mocha";
|
|
32
32
|
export type LightThemeVariant =
|
|
33
|
-
| "
|
|
34
|
-
| "warm"
|
|
35
|
-
| "cool"
|
|
36
|
-
| "soft"
|
|
37
|
-
| "rose"
|
|
38
|
-
| "lavender"
|
|
39
|
-
| "mint"
|
|
40
|
-
| "peach";
|
|
33
|
+
"default" | "warm" | "cool" | "soft" | "rose" | "lavender" | "mint" | "peach";
|
|
41
34
|
export type Theme =
|
|
42
35
|
| "light"
|
|
43
36
|
| `light-${LightThemeVariant}`
|
package/lib/updates/banner.ts
CHANGED
|
@@ -68,12 +68,7 @@ export interface UpdateView {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
export type BannerState =
|
|
71
|
-
| "
|
|
72
|
-
| "available"
|
|
73
|
-
| "pending"
|
|
74
|
-
| "running"
|
|
75
|
-
| "failed"
|
|
76
|
-
| "built";
|
|
71
|
+
"hidden" | "available" | "pending" | "running" | "failed" | "built";
|
|
77
72
|
|
|
78
73
|
export const DISMISSED_VERSION_KEY = "agentos.update.dismissed";
|
|
79
74
|
export const DISMISSED_RUN_KEY = "agentos.update.dismissedRun";
|
package/lib/updates/run.ts
CHANGED
|
@@ -264,8 +264,7 @@ export async function preflight(
|
|
|
264
264
|
// ── starting ─────────────────────────────────────────────────────────────
|
|
265
265
|
|
|
266
266
|
export type StartResult =
|
|
267
|
-
|
|
268
|
-
| ({ ok: false } & Refusal);
|
|
267
|
+
{ ok: true; pending: boolean } | ({ ok: false } & Refusal);
|
|
269
268
|
|
|
270
269
|
/** Takes the right to start, atomically, so two requests can't both run. */
|
|
271
270
|
function claimStart(deps: Pick<RunDeps, "stateFile" | "now">): boolean {
|
package/lib/usage/aggregate.ts
CHANGED
|
@@ -76,7 +76,7 @@ export function aggregateUsage(
|
|
|
76
76
|
const since = rangeStart(range, now);
|
|
77
77
|
const total = acc();
|
|
78
78
|
const days = new Map<string, Acc>();
|
|
79
|
-
for (let t = since; t <= now;
|
|
79
|
+
for (let t = since; t <= now;) {
|
|
80
80
|
days.set(dayKey(t), acc());
|
|
81
81
|
const next = new Date(t);
|
|
82
82
|
next.setDate(next.getDate() + 1);
|
package/lib/usage/nightly.ts
CHANGED
|
@@ -45,8 +45,7 @@ const addDays = (day: string, n: number) =>
|
|
|
45
45
|
|
|
46
46
|
function setting(key: string): string | null {
|
|
47
47
|
const r = db.prepare(`SELECT value FROM settings WHERE key = ?`).get(key) as
|
|
48
|
-
|
|
49
|
-
| undefined;
|
|
48
|
+
{ value: string } | undefined;
|
|
50
49
|
return r?.value ?? null;
|
|
51
50
|
}
|
|
52
51
|
|
package/lib/usage/rate-limits.ts
CHANGED
|
@@ -160,8 +160,7 @@ export function lastReading(
|
|
|
160
160
|
WHERE window = ? AND at <= ? ORDER BY at DESC, id DESC LIMIT 1`
|
|
161
161
|
)
|
|
162
162
|
.get(window, before) as
|
|
163
|
-
|
|
164
|
-
| undefined;
|
|
163
|
+
{ at: number; utilization: number; resets_at: number | null } | undefined;
|
|
165
164
|
return r
|
|
166
165
|
? { at: r.at, utilization: r.utilization, resetsAt: r.resets_at }
|
|
167
166
|
: null;
|
package/lib/usage/turns.ts
CHANGED
|
@@ -111,8 +111,7 @@ export function recordCompaction(
|
|
|
111
111
|
const current = db
|
|
112
112
|
.prepare(`SELECT name, workspace_id FROM sessions WHERE id = ?`)
|
|
113
113
|
.get(session.id) as
|
|
114
|
-
|
|
115
|
-
| undefined;
|
|
114
|
+
{ name: string; workspace_id: string | null } | undefined;
|
|
116
115
|
db.prepare(
|
|
117
116
|
`INSERT INTO chat_compactions (session_id, session_name, workspace_id, at, trigger, phase, before_tokens, after_tokens)
|
|
118
117
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
|