@saadnvd1/agent-os 0.3.550 → 0.3.552

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.
Files changed (36) hide show
  1. package/README.md +1 -0
  2. package/app/api/approvals/hook/route.ts +34 -0
  3. package/app/api/approvals/route.ts +52 -0
  4. package/app/api/devices/network/route.ts +2 -2
  5. package/app/api/sessions/[id]/summarize/route.ts +2 -1
  6. package/app/page.tsx +11 -2
  7. package/components/Approvals/NoApprovalsBadge.tsx +22 -0
  8. package/components/Chat/AccessPicker.tsx +13 -1
  9. package/components/SessionList/SidebarHeader.tsx +2 -0
  10. package/components/Settings/NoApprovalsSection.test.ts +115 -0
  11. package/components/Settings/NoApprovalsSection.tsx +103 -0
  12. package/components/Settings/SettingsDialog.test.ts +3 -0
  13. package/components/Settings/SettingsDialog.tsx +9 -0
  14. package/data/approvals/index.ts +56 -0
  15. package/lib/approvals/enable.ts +64 -0
  16. package/lib/approvals/no-approvals.ts +119 -0
  17. package/lib/chat/events.ts +2 -0
  18. package/lib/chat/settings.ts +17 -2
  19. package/lib/chat/worker/host.ts +49 -4
  20. package/lib/db/migrations.ts +18 -0
  21. package/lib/done/index.ts +3 -0
  22. package/lib/models/plan-step.ts +36 -7
  23. package/lib/needs-you.ts +3 -1
  24. package/lib/orchestrator/asks.ts +42 -5
  25. package/lib/orchestrator/brakes.ts +11 -0
  26. package/lib/orchestrator/brief.ts +7 -1
  27. package/lib/orchestrator/merge-approvals.ts +10 -1
  28. package/lib/orchestrator/presence-binding.ts +3 -0
  29. package/lib/orchestrator/review.ts +12 -1
  30. package/lib/orchestrator/signoff.ts +15 -1
  31. package/lib/security/network-state.ts +2 -2
  32. package/lib/security/presence.ts +1 -0
  33. package/lib/settings-url.ts +1 -0
  34. package/lib/sidebar/shelves.ts +3 -0
  35. package/package.json +1 -1
  36. package/scripts/claude-status-hook.sh +25 -1
@@ -2,7 +2,7 @@ import { tailscaleStatus, type TailscaleState } from "@/lib/tailscale";
2
2
  import { networkSetting, networkSettingLocked } from "./network-settings";
3
3
  import { reachableAt, type Reach } from "./reach";
4
4
  import { connectStatus, type ConnectStatus } from "@/lib/connect/serve";
5
- import { mergeApprovalsOn } from "@/lib/orchestrator/merge-approvals";
5
+ import { mergeApprovalsSetting } from "@/lib/orchestrator/merge-approvals";
6
6
 
7
7
  export interface NetworkState {
8
8
  lan: { on: boolean; locked: boolean };
@@ -24,7 +24,7 @@ export async function networkState(): Promise<NetworkState> {
24
24
  tailscale: await tailscaleStatus(),
25
25
  reach: await reachableAt(),
26
26
  connect: connectStatus(),
27
- mergeApprovals: { on: mergeApprovalsOn(), locked: false },
27
+ mergeApprovals: { on: mergeApprovalsSetting(), locked: false },
28
28
  };
29
29
  }
30
30
 
@@ -42,6 +42,7 @@ export type PresencePurpose =
42
42
  | "enroll"
43
43
  | "revoke"
44
44
  | "approvals-off"
45
+ | "no-approvals-on"
45
46
  | "rules";
46
47
 
47
48
  export class PresenceError extends Error {
@@ -6,6 +6,7 @@ export const SETTINGS_PARAM = "settings";
6
6
 
7
7
  export const SETTINGS_SECTIONS = [
8
8
  "merging",
9
+ "approvals",
9
10
  "workspaces",
10
11
  "models",
11
12
  "devices",
@@ -107,6 +107,9 @@ export function needOf(
107
107
  ): SessionNeed | null {
108
108
  const live = status?.need ?? null;
109
109
  if (live === "approve" || live === "answer" || live === "signin") return live;
110
+ // Finished work has no agent left to wait on you: text typed or queued
111
+ // for one that's been stopped is stale, not a reason to need you.
112
+ if (task && isFinished(task)) return null;
110
113
  return (
111
114
  taskNeed(task) ??
112
115
  live ??
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saadnvd1/agent-os",
3
- "version": "0.3.550",
3
+ "version": "0.3.552",
4
4
  "description": "Self-hosted web UI for managing Claude Code sessions",
5
5
  "bin": {
6
6
  "agent-os": "scripts/agent-os"
@@ -82,6 +82,25 @@ EOF
82
82
  case "$out" in '{"hookSpecificOutput"'*) printf '%s\n' "$out" ;; esac
83
83
  }
84
84
 
85
+ # No approvals mode: AgentOS answers a permission request with Claude's own
86
+ # allow decision, and says nothing when the mode is off. Prints the decision
87
+ # and returns 0 only when it was given.
88
+ autoallow() {
89
+ where="${AGENTOS_URL:-http://127.0.0.1:3011}/api/approvals/hook?session=$AGENTOS_SESSION_ID"
90
+ auth=
91
+ [ -z "$AGENTOS_TOKEN" ] ||
92
+ auth="header = \"Authorization: Bearer $AGENTOS_TOKEN\""
93
+ out=$(printf '%s' "$input" | curl -s --max-time 2 -K /dev/fd/3 \
94
+ -H 'Content-Type: application/json' --data-binary @- "$where" 2>/dev/null 3<<EOF
95
+ $auth
96
+ EOF
97
+ )
98
+ case "$out" in
99
+ '{"hookSpecificOutput"'*) printf '%s\n' "$out"; return 0 ;;
100
+ esac
101
+ return 1
102
+ }
103
+
85
104
  # Commands that take down every session on the machine, the agent's own
86
105
  # included. Inside tmux, $TMUX names the real server and wins over
87
106
  # TMUX_TMPDIR, so `tmux kill-server` there kills it; only an explicit -S or -L
@@ -126,7 +145,12 @@ case "$event" in
126
145
  esac
127
146
  ;;
128
147
  # Claude asks permission for its own questions too: still a question.
129
- PermissionRequest) asking ;;
148
+ PermissionRequest)
149
+ case "$(field tool_name)" in
150
+ AskUserQuestion) asking ;;
151
+ *) autoallow && report "state=working" || asking ;;
152
+ esac
153
+ ;;
130
154
  Notification)
131
155
  message=$(field message)
132
156
  # PermissionRequest already said which tool; older Claude Code versions