@saadnvd1/agent-os 0.3.836 → 0.3.845
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/fresh-start/route.test.ts +33 -0
- package/app/api/fresh-start/route.ts +3 -0
- package/app/api/health/route.ts +4 -2
- package/components/Devices/DeviceRow.tsx +83 -69
- package/components/Devices/PasskeysSection.test.ts +89 -0
- package/components/Devices/PasskeysSection.tsx +36 -26
- package/components/Health/HealthPanel.tsx +41 -16
- package/components/Merge/GlobalMergeSection.tsx +2 -5
- package/components/Merge/MergeSettingsFields.tsx +39 -77
- package/components/Merge/ProjectMergeSection.tsx +2 -6
- package/components/Merge/WorktreeSweepSection.tsx +40 -14
- package/components/Models/AgentRoleCard.tsx +61 -66
- package/components/Models/AgentRolesSection.tsx +5 -8
- package/components/Models/ModelsSection.tsx +7 -18
- package/components/Models/PriceInput.tsx +59 -0
- package/components/PhoneNotify/PhoneNotifyForm.tsx +37 -58
- package/components/SessionList/GroupShelves.tsx +8 -3
- package/components/SessionList/OrchestratorPinRow.tsx +2 -2
- package/components/SessionList/RowParts.tsx +39 -35
- package/components/SessionList/RowRename.test.ts +86 -17
- package/components/SessionList/RowShell.tsx +2 -5
- package/components/SessionList/SessionRow.tsx +0 -1
- package/components/Settings/AppWideLimits.tsx +61 -0
- package/components/Settings/ContextSection.tsx +96 -0
- package/components/Settings/ExperimentsSection.test.ts +9 -7
- package/components/Settings/ExperimentsSection.tsx +22 -23
- package/components/Settings/InlineConfirm.tsx +51 -0
- package/components/Settings/OwnerNameRow.tsx +10 -40
- package/components/Settings/PickerSetting.tsx +59 -0
- package/components/Settings/SettingRow.tsx +168 -0
- package/components/Settings/SettingsDialog.test.ts +1 -0
- package/components/Settings/SettingsDialog.tsx +47 -2
- package/components/Settings/settings-fields.test.ts +103 -0
- package/components/Settings/settings-fields.tsx +428 -0
- package/components/Shares/SharedLinksPanel.tsx +62 -53
- package/components/Workspaces/HqFolderForm.tsx +22 -53
- package/components/Workspaces/McpServersForm.tsx +21 -28
- package/components/Workspaces/ProjectTiersForm.tsx +28 -13
- package/components/Workspaces/RuleEditor.tsx +86 -0
- package/components/Workspaces/RulesForm.test.ts +154 -0
- package/components/Workspaces/RulesForm.tsx +116 -117
- package/components/Workspaces/WorkspaceModeForm.tsx +3 -3
- package/components/Workspaces/WorkspaceModelsForm.tsx +36 -36
- package/components/Workspaces/WorkspacePanel.tsx +73 -0
- package/components/Workspaces/WorkspacePicker.tsx +44 -0
- package/components/Workspaces/WorkspaceSettings.test.ts +153 -0
- package/components/Workspaces/WorkspaceSettings.tsx +63 -52
- package/components/Workspaces/useSettingsWorkspace.ts +47 -0
- package/content/whats-new.json +40 -0
- package/data/fresh-start/index.ts +1 -1
- package/data/workspaces/index.ts +9 -0
- package/hooks/useAutoSave.test.ts +116 -0
- package/hooks/useAutoSave.ts +98 -0
- package/lib/away/deploy.ts +34 -7
- package/lib/away/window-limits.ts +3 -1
- package/lib/chat/refresh.ts +10 -6
- package/lib/chat/stall-limits.ts +3 -1
- package/lib/models/plan-fresh.ts +61 -0
- package/lib/models/plan-step.ts +40 -24
- package/lib/orchestrator/scope.ts +10 -0
- package/lib/settings/defaults.ts +27 -0
- package/lib/settings/parse.ts +17 -0
- package/lib/settings-url.ts +1 -0
- package/lib/updates/banner.ts +2 -0
- package/lib/updates/run.ts +9 -0
- package/lib/updates/view.ts +28 -6
- package/lib/worktree-deps/paths.ts +9 -4
- package/lib/worktree-sweep/limits.ts +3 -0
- package/lib/worktree-sweep/settings.ts +4 -2
- package/lib/worktrees.ts +3 -0
- package/package.json +1 -1
- package/scripts/autodeploy +11 -0
- package/scripts/autodeploy.test.ts +30 -0
- package/scripts/lib/update-verify.mjs +11 -0
- package/scripts/update-run.mjs +29 -0
- package/scripts/update-run.test.ts +62 -4
- package/components/Away/AwayWindowForm.tsx +0 -91
- package/components/Workspaces/FreshStartForm.tsx +0 -177
- package/components/Workspaces/StallForm.tsx +0 -101
- package/components/Workspaces/TaskLimitForm.tsx +0 -84
- package/components/Workspaces/fresh-start.ts +0 -19
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useState } from "react";
|
|
4
|
-
import { toast } from "sonner";
|
|
5
|
-
import { Button } from "@/components/ui/button";
|
|
6
|
-
import { Input } from "@/components/ui/input";
|
|
7
|
-
import { Switch } from "@/components/ui/switch";
|
|
8
|
-
import { useStallQuery, useUpdateStall } from "@/data/stall";
|
|
9
|
-
import {
|
|
10
|
-
DEFAULT_STALL_MINUTES,
|
|
11
|
-
MAX_STALL_MINUTES,
|
|
12
|
-
MIN_STALL_MINUTES,
|
|
13
|
-
} from "@/lib/chat/stall-limits";
|
|
14
|
-
|
|
15
|
-
// How long a turn may produce nothing before it's flagged stalled and the
|
|
16
|
-
// workspace's orchestrator is told: app-wide.
|
|
17
|
-
export function StallForm() {
|
|
18
|
-
const { data, isPending, isError, error } = useStallQuery();
|
|
19
|
-
if (isPending)
|
|
20
|
-
return <div className="bg-muted/40 h-24 animate-pulse rounded-lg" />;
|
|
21
|
-
if (isError)
|
|
22
|
-
return <p className="text-destructive text-sm">{error.message}</p>;
|
|
23
|
-
return <Form key={data.minutes} saved={data.minutes} />;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function Form({ saved }: { saved: number }) {
|
|
27
|
-
const update = useUpdateStall();
|
|
28
|
-
const [on, setOn] = useState(saved > 0);
|
|
29
|
-
const [text, setText] = useState(
|
|
30
|
-
String(saved > 0 ? saved : DEFAULT_STALL_MINUTES)
|
|
31
|
-
);
|
|
32
|
-
const n = Number(text);
|
|
33
|
-
const valid =
|
|
34
|
-
Number.isInteger(n) && n >= MIN_STALL_MINUTES && n <= MAX_STALL_MINUTES;
|
|
35
|
-
const minutes = on ? n : 0;
|
|
36
|
-
const error =
|
|
37
|
-
on && !valid
|
|
38
|
-
? `Between ${MIN_STALL_MINUTES} and ${MAX_STALL_MINUTES} minutes`
|
|
39
|
-
: null;
|
|
40
|
-
const dirty = !error && minutes !== saved;
|
|
41
|
-
|
|
42
|
-
return (
|
|
43
|
-
<form
|
|
44
|
-
onSubmit={(e) => {
|
|
45
|
-
e.preventDefault();
|
|
46
|
-
if (error) return;
|
|
47
|
-
update.mutate(minutes, {
|
|
48
|
-
onSuccess: () => toast.success("Stall alert saved"),
|
|
49
|
-
onError: (err) => toast.error(err.message),
|
|
50
|
-
});
|
|
51
|
-
}}
|
|
52
|
-
className="bg-muted/40 space-y-3 rounded-lg px-3 py-3"
|
|
53
|
-
>
|
|
54
|
-
<h3 className="text-sm font-medium">Stalled turns</h3>
|
|
55
|
-
<p className="text-muted-foreground text-sm">
|
|
56
|
-
A turn that produces nothing for this long (no text, tool call or
|
|
57
|
-
result) shows as stalled, and the workspace's orchestrator is told
|
|
58
|
-
once. A long command that is still printing, or a background command the
|
|
59
|
-
agent is waiting on, isn't a stall.
|
|
60
|
-
</p>
|
|
61
|
-
<label className="flex min-h-11 items-center justify-between gap-3 text-sm md:min-h-9">
|
|
62
|
-
Flag stalled turns
|
|
63
|
-
<Switch
|
|
64
|
-
checked={on}
|
|
65
|
-
onCheckedChange={setOn}
|
|
66
|
-
aria-label="Flag stalled turns"
|
|
67
|
-
/>
|
|
68
|
-
</label>
|
|
69
|
-
{on && (
|
|
70
|
-
<label className="flex items-center justify-between gap-3 text-sm">
|
|
71
|
-
<span className="text-muted-foreground">After</span>
|
|
72
|
-
<span className="flex items-center gap-2">
|
|
73
|
-
<Input
|
|
74
|
-
type="number"
|
|
75
|
-
inputMode="numeric"
|
|
76
|
-
min={MIN_STALL_MINUTES}
|
|
77
|
-
max={MAX_STALL_MINUTES}
|
|
78
|
-
value={text}
|
|
79
|
-
onChange={(e) => setText(e.target.value)}
|
|
80
|
-
aria-label="Stall threshold, minutes"
|
|
81
|
-
aria-invalid={!!error}
|
|
82
|
-
className="h-11 w-24 text-base sm:h-9 md:text-sm"
|
|
83
|
-
/>
|
|
84
|
-
<span className="text-muted-foreground">minutes</span>
|
|
85
|
-
</span>
|
|
86
|
-
</label>
|
|
87
|
-
)}
|
|
88
|
-
{error && <p className="text-destructive text-xs">{error}</p>}
|
|
89
|
-
<div className="flex justify-end">
|
|
90
|
-
<Button
|
|
91
|
-
type="submit"
|
|
92
|
-
size="sm"
|
|
93
|
-
className="h-11 sm:h-8"
|
|
94
|
-
disabled={!!error || !dirty || update.isPending}
|
|
95
|
-
>
|
|
96
|
-
Save
|
|
97
|
-
</Button>
|
|
98
|
-
</div>
|
|
99
|
-
</form>
|
|
100
|
-
);
|
|
101
|
-
}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useState } from "react";
|
|
4
|
-
import { toast } from "sonner";
|
|
5
|
-
import { Button } from "@/components/ui/button";
|
|
6
|
-
import { Input } from "@/components/ui/input";
|
|
7
|
-
import { Switch } from "@/components/ui/switch";
|
|
8
|
-
import type { Workspace } from "@/lib/db";
|
|
9
|
-
import { useUpdateWorkspace } from "@/data/workspaces";
|
|
10
|
-
import { parseTaskLimit } from "./task-limit";
|
|
11
|
-
|
|
12
|
-
// How many tasks the workspace runs at once. Off by default; over the limit
|
|
13
|
-
// a new task is queued and starts by itself when one finishes.
|
|
14
|
-
export function TaskLimitForm({ workspace }: { workspace: Workspace }) {
|
|
15
|
-
const update = useUpdateWorkspace();
|
|
16
|
-
const current = workspace.max_running_tasks;
|
|
17
|
-
const [on, setOn] = useState(current !== null);
|
|
18
|
-
const [text, setText] = useState(String(current ?? 3));
|
|
19
|
-
const parsed = parseTaskLimit(on, text);
|
|
20
|
-
const dirty = !("error" in parsed) && parsed.limit !== current;
|
|
21
|
-
|
|
22
|
-
return (
|
|
23
|
-
<form
|
|
24
|
-
onSubmit={(e) => {
|
|
25
|
-
e.preventDefault();
|
|
26
|
-
if ("error" in parsed) return;
|
|
27
|
-
update.mutate(
|
|
28
|
-
{ id: workspace.id, maxRunningTasks: parsed.limit },
|
|
29
|
-
{
|
|
30
|
-
onSuccess: () =>
|
|
31
|
-
toast.success(
|
|
32
|
-
parsed.limit
|
|
33
|
-
? `Up to ${parsed.limit} tasks run at once`
|
|
34
|
-
: "No running task limit"
|
|
35
|
-
),
|
|
36
|
-
onError: (error) => toast.error(error.message),
|
|
37
|
-
}
|
|
38
|
-
);
|
|
39
|
-
}}
|
|
40
|
-
className="space-y-4"
|
|
41
|
-
>
|
|
42
|
-
<label className="flex min-h-11 items-center justify-between gap-3 text-sm md:min-h-9">
|
|
43
|
-
Limit running tasks
|
|
44
|
-
<Switch
|
|
45
|
-
checked={on}
|
|
46
|
-
onCheckedChange={setOn}
|
|
47
|
-
aria-label="Limit running tasks"
|
|
48
|
-
/>
|
|
49
|
-
</label>
|
|
50
|
-
{on && (
|
|
51
|
-
<label className="flex items-center justify-between gap-3 text-sm">
|
|
52
|
-
<span>At most</span>
|
|
53
|
-
<span className="flex items-center gap-2">
|
|
54
|
-
<Input
|
|
55
|
-
type="number"
|
|
56
|
-
inputMode="numeric"
|
|
57
|
-
min={1}
|
|
58
|
-
step={1}
|
|
59
|
-
value={text}
|
|
60
|
-
onChange={(e) => setText(e.target.value)}
|
|
61
|
-
aria-label="Running task limit"
|
|
62
|
-
aria-invalid={"error" in parsed}
|
|
63
|
-
className="h-11 w-20 text-base sm:h-9 md:text-sm"
|
|
64
|
-
/>
|
|
65
|
-
<span className="text-muted-foreground">at a time</span>
|
|
66
|
-
</span>
|
|
67
|
-
</label>
|
|
68
|
-
)}
|
|
69
|
-
{"error" in parsed && (
|
|
70
|
-
<p className="text-destructive text-xs">{parsed.error}</p>
|
|
71
|
-
)}
|
|
72
|
-
<div className="flex justify-end">
|
|
73
|
-
<Button
|
|
74
|
-
type="submit"
|
|
75
|
-
size="sm"
|
|
76
|
-
className="h-11 sm:h-8"
|
|
77
|
-
disabled={"error" in parsed || !dirty || update.isPending}
|
|
78
|
-
>
|
|
79
|
-
Save
|
|
80
|
-
</Button>
|
|
81
|
-
</div>
|
|
82
|
-
</form>
|
|
83
|
-
);
|
|
84
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
MAX_REFRESH_TOKENS,
|
|
3
|
-
MIN_REFRESH_TOKENS,
|
|
4
|
-
} from "@/lib/chat/refresh-limits";
|
|
5
|
-
|
|
6
|
-
// A threshold's input, in thousands of tokens: off is 0; on takes a whole
|
|
7
|
-
// number in the range the server holds (lib/chat/refresh).
|
|
8
|
-
export function parseFreshStart(
|
|
9
|
-
on: boolean,
|
|
10
|
-
text: string
|
|
11
|
-
): { tokens: number } | { error: string } {
|
|
12
|
-
if (!on) return { tokens: 0 };
|
|
13
|
-
const k = Number(text.trim());
|
|
14
|
-
const min = MIN_REFRESH_TOKENS / 1000;
|
|
15
|
-
const max = MAX_REFRESH_TOKENS / 1000;
|
|
16
|
-
if (!text.trim() || !Number.isInteger(k) || k < min || k > max)
|
|
17
|
-
return { error: `A whole number from ${min} to ${max}` };
|
|
18
|
-
return { tokens: k * 1000 };
|
|
19
|
-
}
|