@agentdeck/bridge 1.2.0 → 1.2.1
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/dist/apme/classifier.d.ts.map +1 -1
- package/dist/apme/classifier.js +18 -10
- package/dist/apme/classifier.js.map +1 -1
- package/dist/apme/claude-transcript-reader.d.ts +36 -0
- package/dist/apme/claude-transcript-reader.d.ts.map +1 -1
- package/dist/apme/claude-transcript-reader.js +78 -2
- package/dist/apme/claude-transcript-reader.js.map +1 -1
- package/dist/apme/collector.d.ts +109 -3
- package/dist/apme/collector.d.ts.map +1 -1
- package/dist/apme/collector.js +408 -44
- package/dist/apme/collector.js.map +1 -1
- package/dist/apme/dashboard-html.d.ts.map +1 -1
- package/dist/apme/dashboard-html.js +4 -2
- package/dist/apme/dashboard-html.js.map +1 -1
- package/dist/apme/graph.d.ts +1 -1
- package/dist/apme/graph.d.ts.map +1 -1
- package/dist/apme/graph.js +51 -1
- package/dist/apme/graph.js.map +1 -1
- package/dist/apme/http.d.ts.map +1 -1
- package/dist/apme/http.js +4 -0
- package/dist/apme/http.js.map +1 -1
- package/dist/apme/index.d.ts +4 -0
- package/dist/apme/index.d.ts.map +1 -1
- package/dist/apme/index.js +13 -1
- package/dist/apme/index.js.map +1 -1
- package/dist/apme/runner.d.ts +90 -0
- package/dist/apme/runner.d.ts.map +1 -1
- package/dist/apme/runner.js +524 -48
- package/dist/apme/runner.js.map +1 -1
- package/dist/apme/sample-to-timeline.d.ts.map +1 -1
- package/dist/apme/sample-to-timeline.js +5 -0
- package/dist/apme/sample-to-timeline.js.map +1 -1
- package/dist/apme/settings.d.ts +8 -0
- package/dist/apme/settings.d.ts.map +1 -1
- package/dist/apme/settings.js +4 -0
- package/dist/apme/settings.js.map +1 -1
- package/dist/apme/store.d.ts +77 -8
- package/dist/apme/store.d.ts.map +1 -1
- package/dist/apme/store.js +189 -17
- package/dist/apme/store.js.map +1 -1
- package/dist/apme/task-gradeability.d.ts +82 -0
- package/dist/apme/task-gradeability.d.ts.map +1 -0
- package/dist/apme/task-gradeability.js +126 -0
- package/dist/apme/task-gradeability.js.map +1 -0
- package/dist/awaiting-overlay.d.ts +13 -26
- package/dist/awaiting-overlay.d.ts.map +1 -1
- package/dist/awaiting-overlay.js +7 -40
- package/dist/awaiting-overlay.js.map +1 -1
- package/dist/claude-permission-rules.d.ts +20 -32
- package/dist/claude-permission-rules.d.ts.map +1 -1
- package/dist/claude-permission-rules.js +19 -102
- package/dist/claude-permission-rules.js.map +1 -1
- package/dist/claude-usage-recovery.d.ts +54 -0
- package/dist/claude-usage-recovery.d.ts.map +1 -0
- package/dist/claude-usage-recovery.js +200 -0
- package/dist/claude-usage-recovery.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +28 -8
- package/dist/cli.js.map +1 -1
- package/dist/codex-rollout-response.d.ts +43 -0
- package/dist/codex-rollout-response.d.ts.map +1 -1
- package/dist/codex-rollout-response.js +67 -0
- package/dist/codex-rollout-response.js.map +1 -1
- package/dist/coordination-evidence.d.ts +150 -0
- package/dist/coordination-evidence.d.ts.map +1 -0
- package/dist/coordination-evidence.js +455 -0
- package/dist/coordination-evidence.js.map +1 -0
- package/dist/daemon-server.d.ts.map +1 -1
- package/dist/daemon-server.js +329 -34
- package/dist/daemon-server.js.map +1 -1
- package/dist/daemon.js +1 -1
- package/dist/deferred-reply-read.d.ts +24 -0
- package/dist/deferred-reply-read.d.ts.map +1 -0
- package/dist/deferred-reply-read.js +42 -0
- package/dist/deferred-reply-read.js.map +1 -0
- package/dist/esp32-serial.d.ts +11 -0
- package/dist/esp32-serial.d.ts.map +1 -1
- package/dist/esp32-serial.js +57 -2
- package/dist/esp32-serial.js.map +1 -1
- package/dist/hook-codex-sessions.d.ts +9 -0
- package/dist/hook-codex-sessions.d.ts.map +1 -1
- package/dist/hook-codex-sessions.js +35 -2
- package/dist/hook-codex-sessions.js.map +1 -1
- package/dist/hook-opencode-sessions.d.ts +62 -0
- package/dist/hook-opencode-sessions.d.ts.map +1 -0
- package/dist/hook-opencode-sessions.js +180 -0
- package/dist/hook-opencode-sessions.js.map +1 -0
- package/dist/hook-response-source.d.ts +40 -0
- package/dist/hook-response-source.d.ts.map +1 -0
- package/dist/hook-response-source.js +31 -0
- package/dist/hook-response-source.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/native-dependency-diagnostics.d.ts +29 -0
- package/dist/native-dependency-diagnostics.d.ts.map +1 -0
- package/dist/native-dependency-diagnostics.js +95 -0
- package/dist/native-dependency-diagnostics.js.map +1 -0
- package/dist/observed-steering.d.ts +4 -4
- package/dist/observed-steering.d.ts.map +1 -1
- package/dist/observed-steering.js +28 -32
- package/dist/observed-steering.js.map +1 -1
- package/dist/openclaw-gateway-stability.d.ts +94 -0
- package/dist/openclaw-gateway-stability.d.ts.map +1 -0
- package/dist/openclaw-gateway-stability.js +176 -0
- package/dist/openclaw-gateway-stability.js.map +1 -0
- package/dist/passive-observer.d.ts +5 -0
- package/dist/passive-observer.d.ts.map +1 -1
- package/dist/passive-observer.js +6 -0
- package/dist/passive-observer.js.map +1 -1
- package/dist/review-runner.js +1 -1
- package/dist/subagent-timeline.d.ts +27 -0
- package/dist/subagent-timeline.d.ts.map +1 -1
- package/dist/subagent-timeline.js +52 -5
- package/dist/subagent-timeline.js.map +1 -1
- package/dist/usage-api.d.ts +3 -0
- package/dist/usage-api.d.ts.map +1 -1
- package/dist/usage-api.js +101 -36
- package/dist/usage-api.js.map +1 -1
- package/dist/usage-event.d.ts.map +1 -1
- package/dist/usage-event.js +2 -1
- package/dist/usage-event.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which closed tasks the judge may score at all.
|
|
3
|
+
*
|
|
4
|
+
* The task rollup judge used to run on anything that carried text, and "text"
|
|
5
|
+
* included the user's own prompts — so a task whose agent never answered was
|
|
6
|
+
* scored against silence, a task whose only turn ended in a usage-limit abort
|
|
7
|
+
* was scored on the abort notice ("Failed to send notifications due to
|
|
8
|
+
* repeated session limits", 0%), and a `hello` was scored as a failed
|
|
9
|
+
* planning task. Measured over one week (2026-09-03): 69 of 182 judged tasks
|
|
10
|
+
* held no agent reply, at a mean 0.59 that then ranked beside real work on
|
|
11
|
+
* the scorecard and floated to the top of the Work board's attention sort.
|
|
12
|
+
*
|
|
13
|
+
* A verdict about the agent's work needs the agent's work. This is the ONE
|
|
14
|
+
* place that says what counts, so the runner and the reaper's enqueue gate
|
|
15
|
+
* cannot drift apart. Reasons are surfaced on the task row rather than
|
|
16
|
+
* silently skipped — a task the judge declined must say why, or "unjudged"
|
|
17
|
+
* reads as a backlog.
|
|
18
|
+
*/
|
|
19
|
+
/** A task with no captured reply is still the agent's work when its tool
|
|
20
|
+
* trajectory says so: this many tool calls, or any file written. Headless
|
|
21
|
+
* and workflow agents (`claude -p`, subagents) routinely end on a Write or
|
|
22
|
+
* a Bash with no closing prose, and the judge reads their trajectory — the
|
|
23
|
+
* first cut of this rule declined 67 such tasks as "no reply" and withdrew
|
|
24
|
+
* verdicts that had been sound. */
|
|
25
|
+
export const WORK_EVIDENCE_MIN_TOOL_CALLS = 3;
|
|
26
|
+
/** Longest prompt AND longest reply, in characters, for a tool-less
|
|
27
|
+
* single-turn task to still count as a greeting rather than a task. Twelve
|
|
28
|
+
* covers "hello", "thanks", "안녕", "테스트" and stops short of the shortest
|
|
29
|
+
* real instruction seen ("add a feature", 13). */
|
|
30
|
+
export const TRIVIAL_PROMPT_MAX_CHARS = 12;
|
|
31
|
+
export const TRIVIAL_REPLY_MAX_CHARS = 200;
|
|
32
|
+
const CLIENT_ENDED = new Set(['aborted']);
|
|
33
|
+
function text(v) {
|
|
34
|
+
return typeof v === 'string' ? v.trim() : '';
|
|
35
|
+
}
|
|
36
|
+
function toolCalls(t) {
|
|
37
|
+
return typeof t.tool_calls === 'number' ? t.tool_calls : 0;
|
|
38
|
+
}
|
|
39
|
+
function filesTouched(t) {
|
|
40
|
+
const m = typeof t.files_modified === 'number' ? t.files_modified : 0;
|
|
41
|
+
const c = typeof t.files_created === 'number' ? t.files_created : 0;
|
|
42
|
+
return m + c;
|
|
43
|
+
}
|
|
44
|
+
/** `response_kind` as the collector tagged it, else derived from the row. */
|
|
45
|
+
function hasTextReply(t) {
|
|
46
|
+
const raw = t.efficiency_json;
|
|
47
|
+
if (typeof raw === 'string' && raw.length > 0) {
|
|
48
|
+
try {
|
|
49
|
+
const k = JSON.parse(raw).response_kind;
|
|
50
|
+
if (k === 'tool_only' || k === 'empty')
|
|
51
|
+
return false;
|
|
52
|
+
if (k === 'text')
|
|
53
|
+
return text(t.response).length > 0;
|
|
54
|
+
}
|
|
55
|
+
catch { /* fall through */ }
|
|
56
|
+
}
|
|
57
|
+
return text(t.response).length > 0;
|
|
58
|
+
}
|
|
59
|
+
export function taskGradeability(turns) {
|
|
60
|
+
if (turns.length === 0)
|
|
61
|
+
return { gradeable: false, reason: 'no_reply' };
|
|
62
|
+
const worked = turns.filter((t) => !CLIENT_ENDED.has(t.end_source));
|
|
63
|
+
if (worked.length === 0)
|
|
64
|
+
return { gradeable: false, reason: 'aborted_only' };
|
|
65
|
+
const replied = worked.filter(hasTextReply);
|
|
66
|
+
if (replied.length === 0) {
|
|
67
|
+
const tools = worked.reduce((n, t) => n + toolCalls(t), 0);
|
|
68
|
+
const files = worked.reduce((n, t) => n + filesTouched(t), 0);
|
|
69
|
+
if (tools < WORK_EVIDENCE_MIN_TOOL_CALLS && files === 0)
|
|
70
|
+
return { gradeable: false, reason: 'no_reply' };
|
|
71
|
+
}
|
|
72
|
+
if (worked.length === 1 &&
|
|
73
|
+
toolCalls(worked[0]) === 0 &&
|
|
74
|
+
text(worked[0].prompt).length <= TRIVIAL_PROMPT_MAX_CHARS &&
|
|
75
|
+
text(worked[0].response).length <= TRIVIAL_REPLY_MAX_CHARS) {
|
|
76
|
+
return { gradeable: false, reason: 'trivial' };
|
|
77
|
+
}
|
|
78
|
+
return { gradeable: true };
|
|
79
|
+
}
|
|
80
|
+
/** Withdraw every verdict in the window that the gradeability rule would not
|
|
81
|
+
* have allowed — the judge's own past output, re-read under the rule it now
|
|
82
|
+
* applies. Idempotent: a retracted row carries `notGradeable` and is not
|
|
83
|
+
* offered again. Returns how many were withdrawn, by reason. */
|
|
84
|
+
export function retractUngradeableVerdicts(store, sinceMs) {
|
|
85
|
+
const out = { no_reply: 0, aborted_only: 0, trivial: 0, readmitted: 0 };
|
|
86
|
+
for (const { id } of store.listJudgedTasks(sinceMs)) {
|
|
87
|
+
const g = taskGradeability(store.listTurnsForTask(id));
|
|
88
|
+
if (g.gradeable)
|
|
89
|
+
continue;
|
|
90
|
+
store.retractTaskVerdict(id, g.reason);
|
|
91
|
+
out[g.reason]++;
|
|
92
|
+
}
|
|
93
|
+
// The rule can also LOOSEN (it did once — see WORK_EVIDENCE_MIN_TOOL_CALLS):
|
|
94
|
+
// a task declined under the stricter reading goes back to the backlog.
|
|
95
|
+
for (const { id } of store.listDeclinedTasks(sinceMs)) {
|
|
96
|
+
if (!taskGradeability(store.listTurnsForTask(id)).gradeable)
|
|
97
|
+
continue;
|
|
98
|
+
store.readmitTask(id);
|
|
99
|
+
out.readmitted++;
|
|
100
|
+
}
|
|
101
|
+
return out;
|
|
102
|
+
}
|
|
103
|
+
/** What the Work board prints beside a task the judge declined. */
|
|
104
|
+
export const NOT_GRADEABLE_LABEL = {
|
|
105
|
+
no_reply: 'no reply captured',
|
|
106
|
+
aborted_only: 'ended by the client (limit / auth / API)',
|
|
107
|
+
trivial: 'trivial exchange',
|
|
108
|
+
};
|
|
109
|
+
/** The `notes_json` shape written for a declined task, so the row can say
|
|
110
|
+
* why. Kept separate from the judge's `{reasoning, done, missed}` shape. */
|
|
111
|
+
export function notGradeableNotes(reason) {
|
|
112
|
+
return JSON.stringify({ notGradeable: reason });
|
|
113
|
+
}
|
|
114
|
+
/** Read the reason back off a task row's `notes_json`, if that is what it holds. */
|
|
115
|
+
export function readNotGradeable(notesJson) {
|
|
116
|
+
if (typeof notesJson !== 'string' || notesJson.length === 0)
|
|
117
|
+
return null;
|
|
118
|
+
try {
|
|
119
|
+
const r = JSON.parse(notesJson).notGradeable;
|
|
120
|
+
return r === 'no_reply' || r === 'aborted_only' || r === 'trivial' ? r : null;
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=task-gradeability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-gradeability.js","sourceRoot":"","sources":["../../src/apme/task-gradeability.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,6 +30,12 @@ export interface AwaitingEntry {
|
|
|
30
30
|
kind: AwaitingKind;
|
|
31
31
|
state: 'awaiting_permission' | 'awaiting_option';
|
|
32
32
|
question: string;
|
|
33
|
+
/** Not subject to the transcript-recency drop in
|
|
34
|
+
* `applyAwaitingOverlayToObserved`. That drop is a Claude ESC heuristic
|
|
35
|
+
* (the transcript freezes while Claude waits); an agent whose record keeps
|
|
36
|
+
* moving during its wait (a Codex rollout) sets this and relies on its own
|
|
37
|
+
* hook clears + the TTL instead. */
|
|
38
|
+
sticky?: boolean;
|
|
33
39
|
/** Structured AskUserQuestion choices for the ACTIVE group. Pressable only
|
|
34
40
|
* when the daemon can deliver the answer (terminal injection or a held
|
|
35
41
|
* ask-gate) — otherwise devices direct the user back to the terminal. */
|
|
@@ -64,7 +70,9 @@ export interface AwaitingEntry {
|
|
|
64
70
|
requestId?: string;
|
|
65
71
|
updatedAt: number;
|
|
66
72
|
}
|
|
67
|
-
export declare function setAwaitingOverlay(sessionId: string, question: string, requestId?: string
|
|
73
|
+
export declare function setAwaitingOverlay(sessionId: string, question: string, requestId?: string, opts?: {
|
|
74
|
+
sticky?: boolean;
|
|
75
|
+
}): void;
|
|
68
76
|
/** Notification permission prompts arrive several seconds after
|
|
69
77
|
* AskUserQuestion's structured PreToolUse. Preserve an existing option
|
|
70
78
|
* interaction instead of downgrading it to generic permission copy. */
|
|
@@ -166,29 +174,8 @@ export declare function looksLikePermissionMessage(message: string): boolean;
|
|
|
166
174
|
* `DaemonServer.isPermissionNotification`.
|
|
167
175
|
*/
|
|
168
176
|
export declare function isPermissionNotification(notificationType: string | undefined, message: string): boolean;
|
|
169
|
-
/**
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
|
|
173
|
-
* Claude's PreToolUse hook fires for EVERY tool call regardless of mode or
|
|
174
|
-
* allowlist — even when Claude will auto-approve and never prompt the user.
|
|
175
|
-
* `permission_mode` is the session's global decision posture, so gate only in
|
|
176
|
-
* modes where Claude could still surface its own prompt; otherwise the device
|
|
177
|
-
* nags for a decision the agent never asked for (the reported false-attention
|
|
178
|
-
* bug). Mirrors the Swift `DaemonServer.shouldGate(permissionMode:tool:)`.
|
|
179
|
-
*
|
|
180
|
-
* - `bypassPermissions` / `dontAsk` → never prompts → don't gate
|
|
181
|
-
* - `auto` → policy engine auto-approves; its
|
|
182
|
-
* decisions live outside the settings allowlist files, so the rule
|
|
183
|
-
* predictor can't see them and every unlisted call would false-hold.
|
|
184
|
-
* The rare genuine prompt still surfaces via the Notification
|
|
185
|
-
* `permission_prompt` overlay → don't gate
|
|
186
|
-
* - `plan` → tools don't execute → don't gate
|
|
187
|
-
* - `acceptEdits` → edits auto-approved, Bash still prompts
|
|
188
|
-
* - `default` / unknown → Claude may prompt → gate
|
|
189
|
-
*
|
|
190
|
-
* Unknown/absent mode is treated as `default` (gate) to preserve behavior on
|
|
191
|
-
* older Claude versions that don't send the field.
|
|
192
|
-
*/
|
|
193
|
-
export declare function shouldGatePreToolUse(permissionMode: string | undefined, tool: string): boolean;
|
|
177
|
+
/** Mode gate for the PreToolUse device-approval hold — SSOT in
|
|
178
|
+
* @agentdeck/shared (generated into the Swift daemon). Re-exported here for
|
|
179
|
+
* the daemon's existing import path. */
|
|
180
|
+
export { shouldGatePreToolUse } from '@agentdeck/shared';
|
|
194
181
|
//# sourceMappingURL=awaiting-overlay.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"awaiting-overlay.d.ts","sourceRoot":"","sources":["../src/awaiting-overlay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGtD;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAC;AAEnD;;8CAE8C;AAC9C,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,qBAAqB,GAAG,iBAAiB,CAAC;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB;;8EAE0E;IAC1E,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B;;;;uFAImF;IACnF,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;wEAGoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;iFAC6E;IAC7E,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD;;;uEAGmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;+DAE2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AA4BD,wBAAgB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"awaiting-overlay.d.ts","sourceRoot":"","sources":["../src/awaiting-overlay.ts"],"names":[],"mappings":"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"}
|
package/dist/awaiting-overlay.js
CHANGED
|
@@ -21,7 +21,7 @@ const RESOLVED_ACTIVITY_MARGIN_MS = 1_000;
|
|
|
21
21
|
/** Cap question length at the source so every sessions_list broadcast stays small. */
|
|
22
22
|
const MAX_QUESTION_LEN = 120;
|
|
23
23
|
const overlay = new Map();
|
|
24
|
-
export function setAwaitingOverlay(sessionId, question, requestId) {
|
|
24
|
+
export function setAwaitingOverlay(sessionId, question, requestId, opts = {}) {
|
|
25
25
|
const trimmed = (question || '').replace(/\s+/g, ' ').trim().slice(0, MAX_QUESTION_LEN);
|
|
26
26
|
overlay.set(sessionId, {
|
|
27
27
|
kind: 'permission',
|
|
@@ -29,6 +29,7 @@ export function setAwaitingOverlay(sessionId, question, requestId) {
|
|
|
29
29
|
question: trimmed,
|
|
30
30
|
requestId,
|
|
31
31
|
updatedAt: Date.now(),
|
|
32
|
+
...(opts.sticky ? { sticky: true } : {}),
|
|
32
33
|
});
|
|
33
34
|
}
|
|
34
35
|
/** Notification permission prompts arrive several seconds after
|
|
@@ -218,6 +219,7 @@ export function applyAwaitingOverlayToObserved(sessions) {
|
|
|
218
219
|
// overlay was set → answered or ESC-dismissed. Drop it (no hook will).
|
|
219
220
|
if (ov.kind === 'permission' &&
|
|
220
221
|
!ov.requestId &&
|
|
222
|
+
!ov.sticky &&
|
|
221
223
|
typeof s.lastActivityAt === 'number' &&
|
|
222
224
|
s.lastActivityAt > ov.updatedAt + RESOLVED_ACTIVITY_MARGIN_MS) {
|
|
223
225
|
clearAwaitingOverlay(uuid);
|
|
@@ -288,43 +290,8 @@ export function isPermissionNotification(notificationType, message) {
|
|
|
288
290
|
}
|
|
289
291
|
return looksLikePermissionMessage(message);
|
|
290
292
|
}
|
|
291
|
-
/**
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
* session's `permission_mode`?
|
|
296
|
-
*
|
|
297
|
-
* Claude's PreToolUse hook fires for EVERY tool call regardless of mode or
|
|
298
|
-
* allowlist — even when Claude will auto-approve and never prompt the user.
|
|
299
|
-
* `permission_mode` is the session's global decision posture, so gate only in
|
|
300
|
-
* modes where Claude could still surface its own prompt; otherwise the device
|
|
301
|
-
* nags for a decision the agent never asked for (the reported false-attention
|
|
302
|
-
* bug). Mirrors the Swift `DaemonServer.shouldGate(permissionMode:tool:)`.
|
|
303
|
-
*
|
|
304
|
-
* - `bypassPermissions` / `dontAsk` → never prompts → don't gate
|
|
305
|
-
* - `auto` → policy engine auto-approves; its
|
|
306
|
-
* decisions live outside the settings allowlist files, so the rule
|
|
307
|
-
* predictor can't see them and every unlisted call would false-hold.
|
|
308
|
-
* The rare genuine prompt still surfaces via the Notification
|
|
309
|
-
* `permission_prompt` overlay → don't gate
|
|
310
|
-
* - `plan` → tools don't execute → don't gate
|
|
311
|
-
* - `acceptEdits` → edits auto-approved, Bash still prompts
|
|
312
|
-
* - `default` / unknown → Claude may prompt → gate
|
|
313
|
-
*
|
|
314
|
-
* Unknown/absent mode is treated as `default` (gate) to preserve behavior on
|
|
315
|
-
* older Claude versions that don't send the field.
|
|
316
|
-
*/
|
|
317
|
-
export function shouldGatePreToolUse(permissionMode, tool) {
|
|
318
|
-
switch ((permissionMode || 'default').trim()) {
|
|
319
|
-
case 'bypassPermissions':
|
|
320
|
-
case 'dontAsk':
|
|
321
|
-
case 'auto':
|
|
322
|
-
case 'plan':
|
|
323
|
-
return false;
|
|
324
|
-
case 'acceptEdits':
|
|
325
|
-
return !EDIT_FAMILY_TOOLS.has(tool);
|
|
326
|
-
default:
|
|
327
|
-
return true;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
293
|
+
/** Mode gate for the PreToolUse device-approval hold — SSOT in
|
|
294
|
+
* @agentdeck/shared (generated into the Swift daemon). Re-exported here for
|
|
295
|
+
* the daemon's existing import path. */
|
|
296
|
+
export { shouldGatePreToolUse } from '@agentdeck/shared';
|
|
330
297
|
//# sourceMappingURL=awaiting-overlay.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"awaiting-overlay.js","sourceRoot":"","sources":["../src/awaiting-overlay.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"awaiting-overlay.js","sourceRoot":"","sources":["../src/awaiting-overlay.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,35 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Loader half of the observed-session PreToolUse device-approval gate.
|
|
3
|
+
*
|
|
4
|
+
* The PREDICTION ("would Claude Code actually prompt for this call?") lives in
|
|
5
|
+
* `@agentdeck/shared` (`shared/src/claude-permission-rules.ts`), generated
|
|
6
|
+
* into the Swift daemon and pinned by shared/claude-permission-vectors.json.
|
|
7
|
+
* This module only reads the settings files Claude Code reads for a cwd and
|
|
8
|
+
* hands the merged rules to that predictor.
|
|
5
9
|
*
|
|
6
10
|
* HISTORY (why precision-first): the first PreToolUse gate held EVERY gated
|
|
7
11
|
* tool call, so tools Claude auto-approves (allowlist rules, acceptEdits,
|
|
8
12
|
* session "always allow") still popped Allow/Deny on devices — the reported
|
|
9
13
|
* false-attention bug that got the gate removed (DEVELOPMENT_LOG 2026-05).
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* Rule semantics mirror Claude Code `permissions.allow/deny/ask` entries:
|
|
17
|
-
* "Bash" → every Bash call
|
|
18
|
-
* "Bash(git status)" → exact command
|
|
19
|
-
* "Bash(git status:*)" → command prefix
|
|
20
|
-
* "Read(...)"/"WebFetch(domain:x)"/"mcp__srv__tool" → tool + spec
|
|
21
|
-
* Matching is deliberately asymmetric:
|
|
22
|
-
* - allow/deny rules match LOOSELY (tool-name match with any spec counts)
|
|
23
|
-
* because a loose match only suppresses a hold (safe direction).
|
|
24
|
-
* - ask rules match STRICTLY (tool-only, or exact/prefix Bash) because an
|
|
25
|
-
* ask match *causes* a hold and must not fire on a spec we can't parse.
|
|
14
|
+
* The reinstated gate only ever holds calls the shared predictor is CONFIDENT
|
|
15
|
+
* Claude will prompt for. Every uncertainty resolves to "don't hold": a
|
|
16
|
+
* missed hold just means the user answers in the terminal (the pre-gate
|
|
17
|
+
* status quo), while a false hold nags the user with a popup Claude never
|
|
18
|
+
* asked for AND stalls the agent for the whole hold timeout.
|
|
26
19
|
*/
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
deny: string[];
|
|
31
|
-
ask: string[];
|
|
32
|
-
}
|
|
20
|
+
import { type MergedPermissionRules, type PermissionRuleVerdict } from '@agentdeck/shared';
|
|
21
|
+
export type RuleVerdict = PermissionRuleVerdict;
|
|
22
|
+
type MergedRules = MergedPermissionRules;
|
|
33
23
|
export declare function isNeverPromptTool(tool: string): boolean;
|
|
34
24
|
export declare function isPromptProneTool(tool: string): boolean;
|
|
35
25
|
export declare function _setHomeOverrideForTests(path: string | null): void;
|
|
@@ -43,13 +33,11 @@ export declare function loadMergedPermissionRules(cwd: string | undefined): Merg
|
|
|
43
33
|
/** Test helper. */
|
|
44
34
|
export declare function _clearRulesCache(): void;
|
|
45
35
|
/**
|
|
46
|
-
* Predict Claude's permission-rule verdict for a tool call
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* 'none' → no rule matches: default behavior for the tool applies
|
|
51
|
-
* 'unknown' → settings unreadable: don't hold
|
|
36
|
+
* Predict Claude's permission-rule verdict for a tool call against the
|
|
37
|
+
* settings files that apply to `cwd`. See the shared predictor for the
|
|
38
|
+
* verdict semantics; `permissionMode` lets it apply the `acceptEdits`
|
|
39
|
+
* filesystem auto-approvals.
|
|
52
40
|
*/
|
|
53
|
-
export declare function evaluatePermissionRules(tool: string, toolInput: Record<string, unknown> | undefined, cwd: string | undefined): RuleVerdict;
|
|
41
|
+
export declare function evaluatePermissionRules(tool: string, toolInput: Record<string, unknown> | undefined, cwd: string | undefined, permissionMode?: string): RuleVerdict;
|
|
54
42
|
export {};
|
|
55
43
|
//# sourceMappingURL=claude-permission-rules.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-permission-rules.d.ts","sourceRoot":"","sources":["../src/claude-permission-rules.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"claude-permission-rules.d.ts","sourceRoot":"","sources":["../src/claude-permission-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EAIL,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC3B,MAAM,mBAAmB,CAAC;AAG3B,MAAM,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAChD,KAAK,WAAW,GAAG,qBAAqB,CAAC;AAEzC,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAYD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAGlE;AAiBD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,IAAI,CA+BrF;AAED,mBAAmB;AACnB,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC9C,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,cAAc,CAAC,EAAE,MAAM,GACtB,WAAW,CAGb"}
|
|
@@ -1,47 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Loader half of the observed-session PreToolUse device-approval gate.
|
|
3
|
+
*
|
|
4
|
+
* The PREDICTION ("would Claude Code actually prompt for this call?") lives in
|
|
5
|
+
* `@agentdeck/shared` (`shared/src/claude-permission-rules.ts`), generated
|
|
6
|
+
* into the Swift daemon and pinned by shared/claude-permission-vectors.json.
|
|
7
|
+
* This module only reads the settings files Claude Code reads for a cwd and
|
|
8
|
+
* hands the merged rules to that predictor.
|
|
5
9
|
*
|
|
6
10
|
* HISTORY (why precision-first): the first PreToolUse gate held EVERY gated
|
|
7
11
|
* tool call, so tools Claude auto-approves (allowlist rules, acceptEdits,
|
|
8
12
|
* session "always allow") still popped Allow/Deny on devices — the reported
|
|
9
13
|
* false-attention bug that got the gate removed (DEVELOPMENT_LOG 2026-05).
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* Rule semantics mirror Claude Code `permissions.allow/deny/ask` entries:
|
|
17
|
-
* "Bash" → every Bash call
|
|
18
|
-
* "Bash(git status)" → exact command
|
|
19
|
-
* "Bash(git status:*)" → command prefix
|
|
20
|
-
* "Read(...)"/"WebFetch(domain:x)"/"mcp__srv__tool" → tool + spec
|
|
21
|
-
* Matching is deliberately asymmetric:
|
|
22
|
-
* - allow/deny rules match LOOSELY (tool-name match with any spec counts)
|
|
23
|
-
* because a loose match only suppresses a hold (safe direction).
|
|
24
|
-
* - ask rules match STRICTLY (tool-only, or exact/prefix Bash) because an
|
|
25
|
-
* ask match *causes* a hold and must not fire on a spec we can't parse.
|
|
14
|
+
* The reinstated gate only ever holds calls the shared predictor is CONFIDENT
|
|
15
|
+
* Claude will prompt for. Every uncertainty resolves to "don't hold": a
|
|
16
|
+
* missed hold just means the user answers in the terminal (the pre-gate
|
|
17
|
+
* status quo), while a false hold nags the user with a popup Claude never
|
|
18
|
+
* asked for AND stalls the agent for the whole hold timeout.
|
|
26
19
|
*/
|
|
27
20
|
import { readFileSync, statSync } from 'fs';
|
|
28
21
|
import { join } from 'path';
|
|
29
22
|
import { homedir } from 'os';
|
|
23
|
+
import { evaluatePermissionRules as evaluateSharedRules, NEVER_PROMPT_TOOLS, PROMPT_PRONE_TOOLS, } from '@agentdeck/shared';
|
|
30
24
|
import { debug } from './logger.js';
|
|
31
|
-
/** Tools that never trigger a permission prompt — holding them can only ever
|
|
32
|
-
* be a false positive. Kept intentionally tight (unknown tools are excluded
|
|
33
|
-
* by the prompt-prone check below, not this list). */
|
|
34
|
-
const NEVER_PROMPT_TOOLS = new Set([
|
|
35
|
-
'Read', 'Glob', 'Grep', 'LS',
|
|
36
|
-
'TodoWrite', 'TodoRead', 'NotebookRead',
|
|
37
|
-
'Task', 'TaskOutput', 'BashOutput',
|
|
38
|
-
]);
|
|
39
|
-
/** Tools that DO prompt in default/auto permission mode unless allowlisted.
|
|
40
|
-
* Anything outside this set (including every mcp__* tool, whose per-server
|
|
41
|
-
* trust state we cannot see) is never held. */
|
|
42
|
-
const PROMPT_PRONE_TOOLS = new Set([
|
|
43
|
-
'Bash', 'Write', 'Edit', 'MultiEdit', 'NotebookEdit', 'WebFetch', 'WebSearch',
|
|
44
|
-
]);
|
|
45
25
|
export function isNeverPromptTool(tool) {
|
|
46
26
|
return NEVER_PROMPT_TOOLS.has(tool);
|
|
47
27
|
}
|
|
@@ -121,77 +101,14 @@ export function loadMergedPermissionRules(cwd) {
|
|
|
121
101
|
export function _clearRulesCache() {
|
|
122
102
|
rulesCache.clear();
|
|
123
103
|
}
|
|
124
|
-
function parseRule(rule) {
|
|
125
|
-
const m = /^([A-Za-z][A-Za-z0-9_]*)(?:\((.*)\))?$/.exec(rule.trim());
|
|
126
|
-
if (!m)
|
|
127
|
-
return null;
|
|
128
|
-
return { tool: m[1], spec: m[2] };
|
|
129
|
-
}
|
|
130
|
-
function bashSpecMatches(spec, command) {
|
|
131
|
-
if (spec === '*')
|
|
132
|
-
return true;
|
|
133
|
-
if (spec.endsWith(':*'))
|
|
134
|
-
return command.startsWith(spec.slice(0, -2));
|
|
135
|
-
return command === spec;
|
|
136
|
-
}
|
|
137
|
-
/** Loose match (allow/deny direction): a tool-name match with ANY spec counts,
|
|
138
|
-
* except Bash specs which we can compare precisely. */
|
|
139
|
-
function matchesLoose(rule, tool, command) {
|
|
140
|
-
if (rule.tool !== tool)
|
|
141
|
-
return false;
|
|
142
|
-
if (rule.spec === undefined)
|
|
143
|
-
return true;
|
|
144
|
-
if (tool === 'Bash') {
|
|
145
|
-
if (command === undefined)
|
|
146
|
-
return true; // malformed input — assume covered
|
|
147
|
-
return bashSpecMatches(rule.spec, command)
|
|
148
|
-
// Compound commands: Claude prompts unless every segment is allowed; we
|
|
149
|
-
// only need "might be auto-approved", so a prefix match on the first
|
|
150
|
-
// segment is enough to suppress the hold.
|
|
151
|
-
|| bashSpecMatches(rule.spec, command.split(/&&|\|\||;|\|/)[0]?.trim() ?? command);
|
|
152
|
-
}
|
|
153
|
-
// Non-Bash specs (paths, domains, globs): we don't replicate the matcher —
|
|
154
|
-
// any spec on the right tool MIGHT match, so treat it as covered.
|
|
155
|
-
return true;
|
|
156
|
-
}
|
|
157
|
-
/** Strict match (ask direction): only patterns we can evaluate exactly. */
|
|
158
|
-
function matchesStrict(rule, tool, command) {
|
|
159
|
-
if (rule.tool !== tool)
|
|
160
|
-
return false;
|
|
161
|
-
if (rule.spec === undefined)
|
|
162
|
-
return true;
|
|
163
|
-
if (tool === 'Bash' && command !== undefined)
|
|
164
|
-
return bashSpecMatches(rule.spec, command);
|
|
165
|
-
return false;
|
|
166
|
-
}
|
|
167
104
|
/**
|
|
168
|
-
* Predict Claude's permission-rule verdict for a tool call
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
* 'none' → no rule matches: default behavior for the tool applies
|
|
173
|
-
* 'unknown' → settings unreadable: don't hold
|
|
105
|
+
* Predict Claude's permission-rule verdict for a tool call against the
|
|
106
|
+
* settings files that apply to `cwd`. See the shared predictor for the
|
|
107
|
+
* verdict semantics; `permissionMode` lets it apply the `acceptEdits`
|
|
108
|
+
* filesystem auto-approvals.
|
|
174
109
|
*/
|
|
175
|
-
export function evaluatePermissionRules(tool, toolInput, cwd) {
|
|
176
|
-
const rules = loadMergedPermissionRules(cwd);
|
|
177
|
-
if (rules === null)
|
|
178
|
-
return 'unknown';
|
|
110
|
+
export function evaluatePermissionRules(tool, toolInput, cwd, permissionMode) {
|
|
179
111
|
const command = typeof toolInput?.command === 'string' ? toolInput.command : undefined;
|
|
180
|
-
|
|
181
|
-
const parsed = parseRule(r);
|
|
182
|
-
if (parsed && matchesLoose(parsed, tool, command))
|
|
183
|
-
return 'deny';
|
|
184
|
-
}
|
|
185
|
-
for (const r of rules.allow) {
|
|
186
|
-
const parsed = parseRule(r);
|
|
187
|
-
if (parsed && matchesLoose(parsed, tool, command))
|
|
188
|
-
return 'allow';
|
|
189
|
-
}
|
|
190
|
-
for (const r of rules.ask) {
|
|
191
|
-
const parsed = parseRule(r);
|
|
192
|
-
if (parsed && matchesStrict(parsed, tool, command))
|
|
193
|
-
return 'ask';
|
|
194
|
-
}
|
|
195
|
-
return 'none';
|
|
112
|
+
return evaluateSharedRules(tool, command, loadMergedPermissionRules(cwd), { permissionMode });
|
|
196
113
|
}
|
|
197
114
|
//# sourceMappingURL=claude-permission-rules.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-permission-rules.js","sourceRoot":"","sources":["../src/claude-permission-rules.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"claude-permission-rules.js","sourceRoot":"","sources":["../src/claude-permission-rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export declare const CLAUDE_USAGE_RECOVERY_FILE: string;
|
|
2
|
+
/** Claude owns the rotating refresh token and its interprocess lock. Never copy,
|
|
3
|
+
* rotate, or write those credentials ourselves. This bounded turn may consume a
|
|
4
|
+
* small amount of subscription quota; it carries no workspace or user content.
|
|
5
|
+
* --bare is NOT appropriate: that mode explicitly disables OAuth/keychain reads.
|
|
6
|
+
* An older CLI rejecting --safe-mode fails closed rather than loading hooks.
|
|
7
|
+
*/
|
|
8
|
+
export declare const CLAUDE_USAGE_RECOVERY_ARGS: string[];
|
|
9
|
+
/** Keep the recovery CLI on the same credential store as usage-api.ts.
|
|
10
|
+
* On macOS that reader targets the default Keychain service; a custom config
|
|
11
|
+
* directory can select a DIFFERENT Keychain namespace in Claude. Fail closed
|
|
12
|
+
* rather than spend quota or renew an unrelated account. On other platforms,
|
|
13
|
+
* resolve relative paths before the child changes cwd to the temporary folder.
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildClaudeUsageRecoveryEnv(source?: NodeJS.ProcessEnv, platform?: NodeJS.Platform, home?: string): NodeJS.ProcessEnv | null;
|
|
16
|
+
/** `execFile` runs one executable — it does not search PATHEXT and (since the
|
|
17
|
+
* Node 20.12/18.20 spawn hardening) will not run a `.cmd`/`.bat` shim without a
|
|
18
|
+
* shell. A bare `'claude'` was therefore ENOENT on every Windows install, and a
|
|
19
|
+
* LaunchAgent carries the installing shell's PATH, which may not contain the
|
|
20
|
+
* CLI at all — both surfaced only as a recurring generic failure line. Resolve
|
|
21
|
+
* the real file once so the unavailable case can SAY it is unavailable.
|
|
22
|
+
* Returns `{ shim: true }` for a Windows shell shim: shell-quoting a JSON
|
|
23
|
+
* argument through cmd.exe is a worse failure than declining, so recovery is
|
|
24
|
+
* skipped there and says so. */
|
|
25
|
+
export declare function resolveClaudeCli(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): {
|
|
26
|
+
path: string;
|
|
27
|
+
shim: boolean;
|
|
28
|
+
} | null;
|
|
29
|
+
export declare function runClaudeUsageRecovery(): Promise<void>;
|
|
30
|
+
/** Kill any in-flight recovery child. Called from the daemon's shutdown path;
|
|
31
|
+
* safe to call with none running. */
|
|
32
|
+
export declare function stopClaudeUsageRecoveryChildren(): void;
|
|
33
|
+
interface RecoveryRecord {
|
|
34
|
+
credentialHash: string;
|
|
35
|
+
attempts: number;
|
|
36
|
+
nextAttemptAt: number;
|
|
37
|
+
}
|
|
38
|
+
interface RecoveryDependencies {
|
|
39
|
+
now: () => number;
|
|
40
|
+
read: () => RecoveryRecord | null;
|
|
41
|
+
write: (record: RecoveryRecord) => void;
|
|
42
|
+
run: () => Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
/** Single daemon owner; persisted cooldown also survives daemon restart. */
|
|
45
|
+
export declare class ClaudeUsageRecovery {
|
|
46
|
+
private deps;
|
|
47
|
+
private pending;
|
|
48
|
+
private record;
|
|
49
|
+
constructor(deps: RecoveryDependencies);
|
|
50
|
+
recover(accessToken: string): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
export declare const claudeUsageRecovery: ClaudeUsageRecovery;
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=claude-usage-recovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-usage-recovery.d.ts","sourceRoot":"","sources":["../src/claude-usage-recovery.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,0BAA0B,QAAoD,CAAC;AAE5F;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,UAMtC,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,GAAE,MAAM,CAAC,UAAwB,EACvC,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,IAAI,SAAY,GACf,MAAM,CAAC,UAAU,GAAG,IAAI,CAe1B;AAED;;;;;;;;gCAQgC;AAChC,wBAAgB,gBAAgB,CAC9B,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAgBxC;AASD,wBAAgB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAqCtD;AAMD;sCACsC;AACtC,wBAAgB,+BAA+B,IAAI,IAAI,CAKtD;AAED,UAAU,cAAc;IAAG,cAAc,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE;AAC5F,UAAU,oBAAoB;IAC5B,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,cAAc,GAAG,IAAI,CAAC;IAClC,KAAK,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IACxC,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,4EAA4E;AAC5E,qBAAa,mBAAmB;IAGlB,OAAO,CAAC,IAAI;IAFxB,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,MAAM,CAA+B;gBACzB,IAAI,EAAE,oBAAoB;IAExC,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAclD;AAED,eAAO,MAAM,mBAAmB,qBAkB9B,CAAC"}
|