@te-river/opencode-team-mode 1.6.0 → 1.6.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/README.md +80 -15
- package/README.zh-CN.md +67 -18
- package/dist/host/note.d.ts +7 -0
- package/dist/host/note.d.ts.map +1 -0
- package/dist/host/note.js +28 -0
- package/dist/host/note.js.map +1 -0
- package/dist/host/v1.d.ts +14 -0
- package/dist/host/v1.d.ts.map +1 -0
- package/dist/host/v1.js +340 -0
- package/dist/host/v1.js.map +1 -0
- package/dist/host/v2-browser-gate.d.ts +45 -0
- package/dist/host/v2-browser-gate.d.ts.map +1 -0
- package/dist/host/v2-browser-gate.js +319 -0
- package/dist/host/v2-browser-gate.js.map +1 -0
- package/dist/host/v2-capabilities.d.ts +68 -0
- package/dist/host/v2-capabilities.d.ts.map +1 -0
- package/dist/host/v2-capabilities.js +146 -0
- package/dist/host/v2-capabilities.js.map +1 -0
- package/dist/host/v2-client.d.ts +53 -0
- package/dist/host/v2-client.d.ts.map +1 -0
- package/dist/host/v2-client.js +193 -0
- package/dist/host/v2-client.js.map +1 -0
- package/dist/host/v2-events.d.ts +56 -0
- package/dist/host/v2-events.d.ts.map +1 -0
- package/dist/host/v2-events.js +158 -0
- package/dist/host/v2-events.js.map +1 -0
- package/dist/host/v2-guard.d.ts +101 -0
- package/dist/host/v2-guard.d.ts.map +1 -0
- package/dist/host/v2-guard.js +199 -0
- package/dist/host/v2-guard.js.map +1 -0
- package/dist/host/v2-offload.d.ts +148 -0
- package/dist/host/v2-offload.d.ts.map +1 -0
- package/dist/host/v2-offload.js +288 -0
- package/dist/host/v2-offload.js.map +1 -0
- package/dist/host/v2-permissions.d.ts +123 -0
- package/dist/host/v2-permissions.d.ts.map +1 -0
- package/dist/host/v2-permissions.js +190 -0
- package/dist/host/v2-permissions.js.map +1 -0
- package/dist/host/v2-probe.d.ts +85 -0
- package/dist/host/v2-probe.d.ts.map +1 -0
- package/dist/host/v2-probe.js +268 -0
- package/dist/host/v2-probe.js.map +1 -0
- package/dist/host/v2-scope.d.ts +51 -0
- package/dist/host/v2-scope.d.ts.map +1 -0
- package/dist/host/v2-scope.js +58 -0
- package/dist/host/v2-scope.js.map +1 -0
- package/dist/host/v2-session-client.d.ts +74 -0
- package/dist/host/v2-session-client.d.ts.map +1 -0
- package/dist/host/v2-session-client.js +171 -0
- package/dist/host/v2-session-client.js.map +1 -0
- package/dist/host/v2-session.d.ts +85 -0
- package/dist/host/v2-session.d.ts.map +1 -0
- package/dist/host/v2-session.js +171 -0
- package/dist/host/v2-session.js.map +1 -0
- package/dist/host/v2-subagent.d.ts +157 -0
- package/dist/host/v2-subagent.d.ts.map +1 -0
- package/dist/host/v2-subagent.js +286 -0
- package/dist/host/v2-subagent.js.map +1 -0
- package/dist/host/v2-tool.d.ts +67 -0
- package/dist/host/v2-tool.d.ts.map +1 -0
- package/dist/host/v2-tool.js +209 -0
- package/dist/host/v2-tool.js.map +1 -0
- package/dist/host/v2-transcript.d.ts +73 -0
- package/dist/host/v2-transcript.d.ts.map +1 -0
- package/dist/host/v2-transcript.js +151 -0
- package/dist/host/v2-transcript.js.map +1 -0
- package/dist/host/v2-types.d.ts +229 -0
- package/dist/host/v2-types.d.ts.map +1 -0
- package/dist/host/v2-types.js +17 -0
- package/dist/host/v2-types.js.map +1 -0
- package/dist/host/v2.d.ts +42 -0
- package/dist/host/v2.d.ts.map +1 -0
- package/dist/host/v2.js +706 -0
- package/dist/host/v2.js.map +1 -0
- package/dist/index.d.ts +23 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -366
- package/dist/index.js.map +1 -1
- package/dist/prompts/lead.d.ts +1 -1
- package/dist/prompts/lead.d.ts.map +1 -1
- package/dist/prompts/lead.js +452 -426
- package/dist/prompts/lead.js.map +1 -1
- package/dist/prompts/shared.d.ts +2 -2
- package/dist/prompts/shared.d.ts.map +1 -1
- package/dist/prompts/shared.js +30 -10
- package/dist/prompts/shared.js.map +1 -1
- package/dist/prompts/specialists.d.ts +2 -2
- package/dist/prompts/specialists.d.ts.map +1 -1
- package/dist/prompts/specialists.js +7 -6
- package/dist/prompts/specialists.js.map +1 -1
- package/dist/task-offload.d.ts +16 -0
- package/dist/task-offload.d.ts.map +1 -1
- package/dist/task-offload.js +51 -0
- package/dist/task-offload.js.map +1 -1
- package/dist/tm/browser.d.ts.map +1 -1
- package/dist/tm/browser.js +41 -10
- package/dist/tm/browser.js.map +1 -1
- package/dist/tm/dispatch.d.ts +47 -0
- package/dist/tm/dispatch.d.ts.map +1 -1
- package/dist/tm/dispatch.js +230 -31
- package/dist/tm/dispatch.js.map +1 -1
- package/dist/tm/dupe-guard.d.ts +16 -3
- package/dist/tm/dupe-guard.d.ts.map +1 -1
- package/dist/tm/dupe-guard.js +27 -7
- package/dist/tm/dupe-guard.js.map +1 -1
- package/dist/tm/index.d.ts +40 -1
- package/dist/tm/index.d.ts.map +1 -1
- package/dist/tm/index.js +40 -11
- package/dist/tm/index.js.map +1 -1
- package/dist/tm/ledger.d.ts +114 -0
- package/dist/tm/ledger.d.ts.map +1 -0
- package/dist/tm/ledger.js +308 -0
- package/dist/tm/ledger.js.map +1 -0
- package/dist/tm/perm-ask.d.ts +1 -3
- package/dist/tm/perm-ask.d.ts.map +1 -1
- package/dist/tm/perm-ask.js +10 -1
- package/dist/tm/perm-ask.js.map +1 -1
- package/dist/tm/preview.d.ts +55 -0
- package/dist/tm/preview.d.ts.map +1 -1
- package/dist/tm/preview.js +225 -0
- package/dist/tm/preview.js.map +1 -1
- package/dist/tm/search.d.ts.map +1 -1
- package/dist/tm/search.js +40 -10
- package/dist/tm/search.js.map +1 -1
- package/dist/tm/serp-loop.d.ts +45 -0
- package/dist/tm/serp-loop.d.ts.map +1 -0
- package/dist/tm/serp-loop.js +80 -0
- package/dist/tm/serp-loop.js.map +1 -0
- package/dist/tm/stats.d.ts +10 -0
- package/dist/tm/stats.d.ts.map +1 -1
- package/dist/tm/stats.js +160 -0
- package/dist/tm/stats.js.map +1 -1
- package/dist/tm/webfetch.d.ts +4 -0
- package/dist/tm/webfetch.d.ts.map +1 -1
- package/dist/tm/webfetch.js +75 -8
- package/dist/tm/webfetch.js.map +1 -1
- package/docs/installation-v2.md +436 -0
- package/docs/installation.md +12 -0
- package/docs/research/agent-data-exchange.md +117 -0
- package/docs/research/browser-pane.md +89 -0
- package/docs/research/host-http-api.md +132 -0
- package/docs/research/host-subagent-injection.md +187 -0
- package/docs/research/plugin-loader-contract.md +261 -0
- package/docs/research/v2-builtin-tools.md +447 -0
- package/docs/v2-port-notes.md +315 -0
- package/index.js +7 -0
- package/package.json +64 -61
- package/scripts/gen-v2-config.mjs +304 -0
- package/scripts/lib/config-surgery.cjs +239 -0
- package/scripts/lib/fake-ctx.mjs +146 -0
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `tm_ledger` — the LEDGER rule's landing spot on a host that has no `todowrite`.
|
|
3
|
+
*
|
|
4
|
+
* The lead's prompt mandates it: every new ask becomes a list item BEFORE the
|
|
5
|
+
* work, an interruption is an insertion rather than a replacement, `blocked` is a
|
|
6
|
+
* state and not an exit, and after a compaction the list is re-read before
|
|
7
|
+
* anything else. On v1 that list is the host's own `todowrite`. On v2 a plugin
|
|
8
|
+
* cannot create that tool (`V2_ONLY_ACTIONS` names `todowrite` as a key with no
|
|
9
|
+
* v2 counterpart), so the mandate had no落点 — and the goal tripwire in `tm_join`
|
|
10
|
+
* had nothing to check, which it now says out loud (`goal_unchecked reason=no_seam`).
|
|
11
|
+
*
|
|
12
|
+
* This module is the other answer. Storage is `ctx.storage` — the host's own
|
|
13
|
+
* key/value domain, proven by a boot self-check that writes a marker and reads it
|
|
14
|
+
* back. That choice beats the alternative (a file under the run store), which is
|
|
15
|
+
* the user's work-in-progress sitting in a temp directory with no owner. Two facts
|
|
16
|
+
* from a live 2.0.16 probe (`docs/research/agent-data-exchange.md`) shape this file:
|
|
17
|
+
* · the domain is shared across sessions, agents AND projects — the only namespace
|
|
18
|
+
* is the plugin id — so the session id is part of the key and nothing may be
|
|
19
|
+
* written without one;
|
|
20
|
+
* · there is no TTL and no quota, so a list that only ever grows is a leak with a
|
|
21
|
+
* friendly name. That is why `LEDGER_MAX_ITEMS` refuses instead of promising a
|
|
22
|
+
* cleanup mechanism this host does not offer.
|
|
23
|
+
*
|
|
24
|
+
* The honesty rule this module exists to obey (product goal #6): a reply about
|
|
25
|
+
* the list says whether the list REACHED storage. An in-memory-only "已记录"
|
|
26
|
+
* would be exactly the unverified "done" the rest of this plugin treats as a bug.
|
|
27
|
+
*/
|
|
28
|
+
import { tmError, toToolResult } from "./result.js";
|
|
29
|
+
export const LEDGER_STATUSES = ["open", "doing", "done", "blocked"];
|
|
30
|
+
const KEY_PREFIX = "team-mode/ledger/";
|
|
31
|
+
/** `ctx.storage.get` answered with the raw value in one build and with
|
|
32
|
+
* `{value: …}` in another (the boot self-check accepts both), so the reader has
|
|
33
|
+
* to unwrap both rather than trusting either. */
|
|
34
|
+
function unwrapStored(raw) {
|
|
35
|
+
if (raw && typeof raw === "object" && "value" in raw) {
|
|
36
|
+
return raw.value;
|
|
37
|
+
}
|
|
38
|
+
return raw;
|
|
39
|
+
}
|
|
40
|
+
export function createStorageLedgerStore(storage) {
|
|
41
|
+
const st = storage;
|
|
42
|
+
const ok = !!st && typeof st.get === "function" && typeof st.set === "function";
|
|
43
|
+
let detail;
|
|
44
|
+
return {
|
|
45
|
+
kind: "ctx.storage",
|
|
46
|
+
available: () => ok,
|
|
47
|
+
detail: () => detail ?? "",
|
|
48
|
+
async load(sessionID) {
|
|
49
|
+
if (!ok)
|
|
50
|
+
throw new Error("这个宿主没有给 ctx.storage 的 get/set");
|
|
51
|
+
const raw = await st.get(KEY_PREFIX + sessionID);
|
|
52
|
+
return normalizeLedger(unwrapStored(raw));
|
|
53
|
+
},
|
|
54
|
+
async save(ledger) {
|
|
55
|
+
if (!ok)
|
|
56
|
+
throw new Error("这个宿主没有给 ctx.storage 的 get/set");
|
|
57
|
+
try {
|
|
58
|
+
await st.set(KEY_PREFIX + ledger.sessionID, ledger);
|
|
59
|
+
detail = undefined;
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
detail = String(err?.message ?? err).slice(0, 120);
|
|
63
|
+
throw err;
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** Defensive read: a value that is not a ledger is treated as absent rather than
|
|
69
|
+
* half-trusted, because a silently-mangled list is worse than an empty one —
|
|
70
|
+
* the lead would wrap up believing the work was accounted for. */
|
|
71
|
+
export function normalizeLedger(raw) {
|
|
72
|
+
if (!raw || typeof raw !== "object")
|
|
73
|
+
return null;
|
|
74
|
+
const o = raw;
|
|
75
|
+
if (!Array.isArray(o.items))
|
|
76
|
+
return null;
|
|
77
|
+
const items = [];
|
|
78
|
+
for (const it of o.items) {
|
|
79
|
+
if (!it || typeof it !== "object")
|
|
80
|
+
continue;
|
|
81
|
+
const e = it;
|
|
82
|
+
const text = typeof e.text === "string" ? e.text.trim() : "";
|
|
83
|
+
if (!text)
|
|
84
|
+
continue;
|
|
85
|
+
items.push({
|
|
86
|
+
id: Number.isFinite(Number(e.id)) ? Number(e.id) : items.length + 1,
|
|
87
|
+
text,
|
|
88
|
+
status: LEDGER_STATUSES.includes(String(e.status))
|
|
89
|
+
? String(e.status)
|
|
90
|
+
: "open",
|
|
91
|
+
at: Number.isFinite(Number(e.at)) ? Number(e.at) : Date.now(),
|
|
92
|
+
...(typeof e.note === "string" && e.note ? { note: e.note } : {}),
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
sessionID: String(o.sessionID ?? ""),
|
|
97
|
+
items,
|
|
98
|
+
updated: Number.isFinite(Number(o.updated)) ? Number(o.updated) : Date.now(),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/** The dedup key. The LEDGER rule says an interruption INSERTS, and the same ask
|
|
102
|
+
* arriving twice (a re-stated instruction, a screenshot of the same question)
|
|
103
|
+
* must not grow a second line the lead then has to close twice — so the key is
|
|
104
|
+
* the text with case/whitespace/trailing punctuation removed, which is the same
|
|
105
|
+
* "same question" notion tm_memory's dedupKey uses. */
|
|
106
|
+
export function ledgerDedupKey(text) {
|
|
107
|
+
return String(text ?? "")
|
|
108
|
+
.toLowerCase()
|
|
109
|
+
.replace(/[\s ]+/g, " ")
|
|
110
|
+
.replace(/[。..!!??;;::,,]+$/g, "")
|
|
111
|
+
.trim();
|
|
112
|
+
}
|
|
113
|
+
export function emptyLedger(sessionID) {
|
|
114
|
+
return { sessionID, items: [], updated: Date.now() };
|
|
115
|
+
}
|
|
116
|
+
/** `ctx.storage` never expires anything (measured), so the list needs a ceiling or
|
|
117
|
+
* it grows for the life of the install. Refusing is honest; silently truncating
|
|
118
|
+
* would be the overstated claim — the lead would believe its oldest asks were gone
|
|
119
|
+
* when they were only hidden. */
|
|
120
|
+
export const LEDGER_MAX_ITEMS_DEFAULT = 200;
|
|
121
|
+
export function ledgerMaxItems(env = process.env) {
|
|
122
|
+
const n = Number(String(env.TM_LEDGER_MAX_ITEMS ?? "").trim());
|
|
123
|
+
return Number.isFinite(n) && n >= 10 ? Math.floor(n) : LEDGER_MAX_ITEMS_DEFAULT;
|
|
124
|
+
}
|
|
125
|
+
/** A merge is reported, not hidden: the reply says "这条已经在清单上(#2)" so the
|
|
126
|
+
* lead learns the insertion was a repeat instead of wondering why the count did
|
|
127
|
+
* not move. */
|
|
128
|
+
export function addItem(ledger, text, now = Date.now()) {
|
|
129
|
+
const clean = String(text ?? "").replace(/[\s ]+/g, " ").trim().slice(0, 400);
|
|
130
|
+
const key = ledgerDedupKey(clean);
|
|
131
|
+
const existing = clean ? ledger.items.find((i) => ledgerDedupKey(i.text) === key) : undefined;
|
|
132
|
+
if (existing)
|
|
133
|
+
return { ledger, item: existing, merged: true };
|
|
134
|
+
const nextId = ledger.items.reduce((m, i) => Math.max(m, i.id), 0) + 1;
|
|
135
|
+
const item = { id: nextId, text: clean, status: "open", at: now };
|
|
136
|
+
return { ledger: { ...ledger, items: [...ledger.items, item], updated: now }, item, merged: false };
|
|
137
|
+
}
|
|
138
|
+
const MARKS = { open: "[ ]", doing: "[>]", done: "[x]", blocked: "[!]" };
|
|
139
|
+
export function openItems(ledger) {
|
|
140
|
+
return (ledger?.items ?? []).filter((i) => i.status !== "done");
|
|
141
|
+
}
|
|
142
|
+
/** Resolve `#4` / `4` / a substring, and refuse an ambiguous match by NAMING the
|
|
143
|
+
* candidates — a list tool that silently marks the wrong line destroys the one
|
|
144
|
+
* thing it is for. */
|
|
145
|
+
export function findItem(ledger, ref) {
|
|
146
|
+
const s = String(ref ?? "").trim().replace(/^#/, "");
|
|
147
|
+
if (!s)
|
|
148
|
+
return { candidates: ledger.items };
|
|
149
|
+
if (/^\d+$/.test(s)) {
|
|
150
|
+
const byId = ledger.items.find((i) => i.id === Number(s));
|
|
151
|
+
return byId ? { item: byId, candidates: [byId] } : { candidates: [] };
|
|
152
|
+
}
|
|
153
|
+
const key = ledgerDedupKey(s);
|
|
154
|
+
const hits = ledger.items.filter((i) => ledgerDedupKey(i.text).includes(key) || key.includes(ledgerDedupKey(i.text)));
|
|
155
|
+
return hits.length === 1 ? { item: hits[0], candidates: hits } : { candidates: hits };
|
|
156
|
+
}
|
|
157
|
+
export function markItem(ledger, ref, status, note, now = Date.now()) {
|
|
158
|
+
const { item, candidates } = findItem(ledger, ref);
|
|
159
|
+
if (!item) {
|
|
160
|
+
const named = candidates.slice(0, 4).map((c) => `#${c.id} ${c.text}`).join("、");
|
|
161
|
+
return {
|
|
162
|
+
error: candidates.length
|
|
163
|
+
? `「${ref}」匹配到 ${candidates.length} 条,不能猜:${named} —— 用编号重发一次`
|
|
164
|
+
: `清单里没有「${ref}」这一条(现有 ${ledger.items.length} 条)—— 先 tm_ledger { action:"list" } 看一眼`,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const next = {
|
|
168
|
+
...item,
|
|
169
|
+
status,
|
|
170
|
+
at: now,
|
|
171
|
+
...(String(note ?? "").trim() ? { note: String(note).trim().slice(0, 400) } : {}),
|
|
172
|
+
};
|
|
173
|
+
return { ledger: { ...ledger, items: ledger.items.map((i) => (i.id === item.id ? next : i)), updated: now }, item: next };
|
|
174
|
+
}
|
|
175
|
+
export function renderLedger(ledger) {
|
|
176
|
+
const open = openItems(ledger);
|
|
177
|
+
const done = ledger.items.length - open.length;
|
|
178
|
+
const head = `清单 ${ledger.sessionID}:共 ${ledger.items.length} 条 · 未完成 ${open.length} · 已完成 ${done}`;
|
|
179
|
+
if (!ledger.items.length)
|
|
180
|
+
return `${head}\n(空 —— 每接一个新要求就先加一条,再动手)`;
|
|
181
|
+
const lines = ledger.items.map((i) => {
|
|
182
|
+
const note = i.note ? ` —— ${i.note}` : "";
|
|
183
|
+
return `- ${MARKS[i.status]} #${i.id} ${i.text}${note}`;
|
|
184
|
+
});
|
|
185
|
+
return [head, ...lines].join("\n");
|
|
186
|
+
}
|
|
187
|
+
/** The line `tm_join` appends when the round settled but the LEDGER did not —
|
|
188
|
+
* the goal tripwire's shape applied to a list the plugin actually owns. */
|
|
189
|
+
export function ledgerGoalLine(ledger, max = 6) {
|
|
190
|
+
const open = openItems(ledger);
|
|
191
|
+
if (!open.length)
|
|
192
|
+
return null;
|
|
193
|
+
const named = open
|
|
194
|
+
.slice(0, max)
|
|
195
|
+
.map((i) => `「${i.text}」(${i.status === "blocked" ? "卡住" : i.status === "doing" ? "进行中" : "未开始"})`)
|
|
196
|
+
.join("、");
|
|
197
|
+
return (`⚠ 目标未达成:tm_ledger 还有 ${open.length} 项未完成 —— ${named}` +
|
|
198
|
+
(open.length > max ? ` …+${open.length - max}` : "") +
|
|
199
|
+
`\n按目标指令:要么继续做掉,要么向用户写明哪一条被什么卡住;不要把这轮当成收尾。` +
|
|
200
|
+
`做完了就 tm_ledger { action:"done", id:#编号 } 更新状态,再收尾。`);
|
|
201
|
+
}
|
|
202
|
+
const DESCRIPTION = `你自己的任务清单(LEDGER)——这个宿主没有 todowrite,清单由本插件记在宿主的 ctx.storage 里。
|
|
203
|
+
- { action:"add", text:"…" }:接一个新要求就先加一条,再加进清单之后的活(中途插入的要求同样先加,别把原清单换掉)。同样的话说过两遍会告诉你它已经在第几条,不重复加。
|
|
204
|
+
- { action:"doing" | "done" | "blocked", id:"#编号 或一句话" }:改状态。blocked 是一个状态,不是收工的理由——note 里写清被什么卡住(这是别人复述不出来的那半句)。
|
|
205
|
+
- { action:"list" }:把整张清单读回来。上下文被压缩过、或者你不记得走到哪儿了,先读这个,别凭印象继续。
|
|
206
|
+
- 编号在答复里一定会回给你;id 用编号最准,用一句话的片段也行,但撞上两条会拒绝并把候选列给你,不会替你猜。
|
|
207
|
+
- 答复里会说明这条清单是否真的进了 ctx.storage:没进去就是失败,不会算"已记录"。`;
|
|
208
|
+
const LEDGER_ARGS = {
|
|
209
|
+
action: { descriptor: 'action: "add" | "doing" | "done" | "blocked" | "list"' },
|
|
210
|
+
text: { descriptor: "text: string (add 用:一条要求的原文,越短越好)" },
|
|
211
|
+
id: { descriptor: 'id: number|string (改状态用:清单编号,或者能唯一对上的一条的片段)' },
|
|
212
|
+
note: { descriptor: "note: string (可选:blocked 被什么卡住 / done 凭什么判定完成)" },
|
|
213
|
+
};
|
|
214
|
+
export function buildLedgerTool(deps) {
|
|
215
|
+
const tool = "tm_ledger";
|
|
216
|
+
const now = deps.now ?? (() => Date.now());
|
|
217
|
+
return {
|
|
218
|
+
description: DESCRIPTION,
|
|
219
|
+
args: LEDGER_ARGS,
|
|
220
|
+
execute: async (rawArgs, ctx) => {
|
|
221
|
+
const c = (ctx ?? {});
|
|
222
|
+
if (deps.onlyAgent && String(c.agent ?? "") !== deps.onlyAgent) {
|
|
223
|
+
return toToolResult(tmError(tool, "permission", `tm_ledger 只有领队能用(现在的调用方是「${String(c.agent || "未知")}」)。` +
|
|
224
|
+
`专家的状态写在 STATUS 里,由领队并进它的那张清单——不要另起一张。`));
|
|
225
|
+
}
|
|
226
|
+
const args = (rawArgs ?? {});
|
|
227
|
+
const sessionID = String(c.sessionID ?? "").trim();
|
|
228
|
+
if (!sessionID) {
|
|
229
|
+
return toToolResult(tmError(tool, "args", "这个调用没有带 sessionID —— 清单是按会话存的,不能凭空写到一个未知会话上。"));
|
|
230
|
+
}
|
|
231
|
+
if (!deps.store.available()) {
|
|
232
|
+
return toToolResult(tmError(tool, "client", `这个宿主没有给出可写的 ctx.storage(${deps.store.kind}),所以清单没地方落。` +
|
|
233
|
+
`不要把这件事当成"清单功能坏了":把状态写进 STATUS/CHANGES 里,照样可核对。`));
|
|
234
|
+
}
|
|
235
|
+
let ledger;
|
|
236
|
+
try {
|
|
237
|
+
ledger = (await deps.store.load(sessionID)) ?? emptyLedger(sessionID);
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
return toToolResult(tmError(tool, "execute", `读清单失败(${deps.store.kind}):${String(err?.message ?? err).slice(0, 160)}`));
|
|
241
|
+
}
|
|
242
|
+
const action = String(args.action ?? "").trim().toLowerCase();
|
|
243
|
+
if (!["add", "doing", "done", "blocked", "list"].includes(action)) {
|
|
244
|
+
return toToolResult(tmError(tool, "args", `action 只能是 add / doing / done / blocked / list,收到「${action || "(空)"}」`));
|
|
245
|
+
}
|
|
246
|
+
if (action === "list") {
|
|
247
|
+
return toToolResult({ ok: true, output: renderLedger(ledger), meta: { open: openItems(ledger).length } });
|
|
248
|
+
}
|
|
249
|
+
let answer = "";
|
|
250
|
+
if (action === "add") {
|
|
251
|
+
const texts = Array.isArray(args.text)
|
|
252
|
+
? args.text.map(String)
|
|
253
|
+
: String(args.text ?? "")
|
|
254
|
+
.split(/\r?\n|;/)
|
|
255
|
+
.map((s) => s.trim())
|
|
256
|
+
.filter(Boolean);
|
|
257
|
+
if (!texts.length) {
|
|
258
|
+
return toToolResult(tmError(tool, "args", "add 需要 text —— 空的一条要求只会让清单变长,不会让活变少"));
|
|
259
|
+
}
|
|
260
|
+
const max = ledgerMaxItems(deps.env);
|
|
261
|
+
if (ledger.items.length + texts.length > max) {
|
|
262
|
+
return toToolResult(tmError(tool, "args", `清单已有 ${ledger.items.length} 条,再加 ${texts.length} 条会超过上限 ${max}(TM_LEDGER_MAX_ITEMS)。` +
|
|
263
|
+
`宿主的 ctx.storage 不设 TTL,也不会替你回收:先把已完成的条目在回复里总结掉,或显式清一次,别让它无声涨下去。`));
|
|
264
|
+
}
|
|
265
|
+
let merged = 0;
|
|
266
|
+
const added = [];
|
|
267
|
+
for (const t of texts) {
|
|
268
|
+
const r = addItem(ledger, t, now());
|
|
269
|
+
ledger = r.ledger;
|
|
270
|
+
if (r.merged)
|
|
271
|
+
merged++;
|
|
272
|
+
else
|
|
273
|
+
added.push(r.item);
|
|
274
|
+
}
|
|
275
|
+
answer = added.length
|
|
276
|
+
? `已记 ${added.map((i) => `#${i.id} ${i.text}`).join(";")}${merged ? `(另有 ${merged} 条重复,没再加)` : ""}`
|
|
277
|
+
: `这 ${merged} 条已经在清单上了,没重复加:${texts.map((t) => { const f = findItem(ledger, t); return f.item ? `#${f.item.id}(${f.item.status})` : "?"; }).join("、")}`;
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
const ref = (args.id ?? args.text);
|
|
281
|
+
if (ref === undefined || String(ref).trim() === "") {
|
|
282
|
+
return toToolResult(tmError(tool, "args", `${action} 需要 id —— 编号,或者能唯一对上的一条的片段`));
|
|
283
|
+
}
|
|
284
|
+
const r = markItem(ledger, ref, action, typeof args.note === "string" ? args.note : undefined, now());
|
|
285
|
+
if ("error" in r)
|
|
286
|
+
return toToolResult(tmError(tool, "args", r.error));
|
|
287
|
+
ledger = r.ledger;
|
|
288
|
+
answer = `#${r.item.id} → ${action}:${r.item.text}${r.item.note ? `(${r.item.note})` : ""}`;
|
|
289
|
+
}
|
|
290
|
+
try {
|
|
291
|
+
await deps.store.save(ledger);
|
|
292
|
+
}
|
|
293
|
+
catch (err) {
|
|
294
|
+
// The change did not land. Saying 已记录 here would be the unverified
|
|
295
|
+
// "done" this product treats as its own defect class.
|
|
296
|
+
return toToolResult(tmError(tool, "execute", `${answer}\n但这次改动没写进 ${deps.store.kind}:${String(err?.message ?? err).slice(0, 160)} —— 清单还是上一次的样子。`));
|
|
297
|
+
}
|
|
298
|
+
deps.onWrite?.(sessionID, action);
|
|
299
|
+
const rest = openItems(ledger);
|
|
300
|
+
return toToolResult({
|
|
301
|
+
ok: true,
|
|
302
|
+
output: `${answer}\n(已写入 ${deps.store.kind} · 未完成 ${rest.length} 条${rest.length ? `:${rest.slice(0, 6).map((i) => `#${i.id}`).join(" ")}` : ""})`,
|
|
303
|
+
meta: { open: rest.length },
|
|
304
|
+
});
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
//# sourceMappingURL=ledger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ledger.js","sourceRoot":"","sources":["../../src/tm/ledger.ts"],"names":[],"mappings":"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"}
|
package/dist/tm/perm-ask.d.ts
CHANGED
|
@@ -73,8 +73,6 @@ export declare function getAskWaitMs(): number;
|
|
|
73
73
|
* nobody answered is "timed-out" — three different answers that need three
|
|
74
74
|
* different next moves. */
|
|
75
75
|
export declare function askUserForTarget(ctx: unknown, req: TmAskRequest, waitMs?: number): Promise<AskOutcome>;
|
|
76
|
-
|
|
77
|
-
* cosmetic: "用户未批准" for a dialog nobody saw teaches the agent to give up
|
|
78
|
-
* (or retry silently) instead of telling the human to look at the screen. */
|
|
76
|
+
export declare function setAskUnavailableNote(note: string): void;
|
|
79
77
|
export declare function askRefusalNote(outcome: AskOutcome, waitMs?: number): string;
|
|
80
78
|
//# sourceMappingURL=perm-ask.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"perm-ask.d.ts","sourceRoot":"","sources":["../../src/tm/perm-ask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,YAAY;IAC3B,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAA;IAClB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAM7D,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAElF;AAED;6CAC6C;AAC7C,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CASpD;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,aAAa,CAAA;AAE9E;;;;4DAI4D;AAC5D,eAAO,MAAM,iBAAiB,OAAQ,CAAA;AAEtC,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,UAAU,CAAA;IACnB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;qDAEiD;IACjD,WAAW,EAAE,OAAO,CAAA;CACrB;AAED;;;;+DAI+D;AAC/D,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,YAAY,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,WAAW,SAAoB,GAC9B,OAAO,CAAC,SAAS,CAAC,CAkBpB;AAED;;0BAE0B;AAC1B,wBAAgB,YAAY,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAOnD;AAMD;;;;;wDAKwD;AACxD,eAAO,MAAM,YAAY,QAAS,CAAA;AAIlC;;4CAE4C;AAC5C,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE7C;AACD,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;4BAG4B;AAC5B,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,YAAY,EACjB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,UAAU,CAAC,CAgBrB;AAED
|
|
1
|
+
{"version":3,"file":"perm-ask.d.ts","sourceRoot":"","sources":["../../src/tm/perm-ask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,YAAY;IAC3B,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAA;IAClB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAM7D,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAElF;AAED;6CAC6C;AAC7C,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CASpD;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,aAAa,CAAA;AAE9E;;;;4DAI4D;AAC5D,eAAO,MAAM,iBAAiB,OAAQ,CAAA;AAEtC,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,UAAU,CAAA;IACnB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;qDAEiD;IACjD,WAAW,EAAE,OAAO,CAAA;CACrB;AAED;;;;+DAI+D;AAC/D,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,YAAY,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,WAAW,SAAoB,GAC9B,OAAO,CAAC,SAAS,CAAC,CAkBpB;AAED;;0BAE0B;AAC1B,wBAAgB,YAAY,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAOnD;AAMD;;;;;wDAKwD;AACxD,eAAO,MAAM,YAAY,QAAS,CAAA;AAIlC;;4CAE4C;AAC5C,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE7C;AACD,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;4BAG4B;AAC5B,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,YAAY,EACjB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,UAAU,CAAC,CAgBrB;AAUD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAExD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAY,GAAG,MAAM,CAU9E"}
|
package/dist/tm/perm-ask.js
CHANGED
|
@@ -133,6 +133,15 @@ export async function askUserForTarget(ctx, req, waitMs) {
|
|
|
133
133
|
/** One sentence naming WHY the dialog did not grant access. This is not
|
|
134
134
|
* cosmetic: "用户未批准" for a dialog nobody saw teaches the agent to give up
|
|
135
135
|
* (or retry silently) instead of telling the human to look at the screen. */
|
|
136
|
+
/** What "we could not ask" means on THIS host generation. v1 says 旧版协议
|
|
137
|
+
* because there it is true; the v2 personality replaces the sentence because
|
|
138
|
+
* on v2 the absence is the NEW protocol, and telling the model the host is old
|
|
139
|
+
* would send it looking for an upgrade it already has. */
|
|
140
|
+
let unavailableNote = "宿主无法弹出确认窗口(旧版协议)。";
|
|
141
|
+
export function setAskUnavailableNote(note) {
|
|
142
|
+
if (typeof note === "string" && note.trim())
|
|
143
|
+
unavailableNote = note;
|
|
144
|
+
}
|
|
136
145
|
export function askRefusalNote(outcome, waitMs = askWaitMs) {
|
|
137
146
|
if (outcome === "rejected")
|
|
138
147
|
return "用户未批准。";
|
|
@@ -141,6 +150,6 @@ export function askRefusalNote(outcome, waitMs = askWaitMs) {
|
|
|
141
150
|
`所以这不是被拒绝,是没有人在界面上点它。请提醒用户查看待确认的对话框;` +
|
|
142
151
|
`如果确实不想开权限,就改用白名单内的源,不要重复调用。`);
|
|
143
152
|
}
|
|
144
|
-
return
|
|
153
|
+
return unavailableNote;
|
|
145
154
|
}
|
|
146
155
|
//# sourceMappingURL=perm-ask.js.map
|
package/dist/tm/perm-ask.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"perm-ask.js","sourceRoot":"","sources":["../../src/tm/perm-ask.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"perm-ask.js","sourceRoot":"","sources":["../../src/tm/perm-ask.ts"],"names":[],"mappings":"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"}
|
package/dist/tm/preview.d.ts
CHANGED
|
@@ -35,6 +35,61 @@ export declare function detectContentType(content: string, hint?: ContentType):
|
|
|
35
35
|
* chars/4 char-count cut would under-count CJK bodies up to 4×), and the
|
|
36
36
|
* marker's own cost is reserved up front so it always survives the cut.
|
|
37
37
|
*/
|
|
38
|
+
/**
|
|
39
|
+
* Cap an ADDRESSING payload — a browser accessibility snapshot, whose [ref=eN] tokens
|
|
40
|
+
* are the arguments of the next click.
|
|
41
|
+
*
|
|
42
|
+
* A head cut (what capTokens does) is the wrong shape here: the interactive nodes are
|
|
43
|
+
* spread through the tree, so a plain budget loses the tail's refs while keeping
|
|
44
|
+
* hundreds of tokens of static text nobody will address by. This keeps every line that
|
|
45
|
+
* carries an addressing token and spends the rest of the budget on the other lines in
|
|
46
|
+
* their original order. When the addressing lines alone do not fit, it says HOW MANY
|
|
47
|
+
* were dropped — "some refs are not in front of you" is the fact the model needs, and
|
|
48
|
+
* a silent tail cut is how a wrong-element click gets reported as 已点击.
|
|
49
|
+
*
|
|
50
|
+
* The addressing pattern is deliberately wide (any `key=value` token whose key ends in
|
|
51
|
+
* `ref` / `id`, plus the `[uid=…]` shape our own tm_browser mints), because matching
|
|
52
|
+
* the host's future snapshot format is a guess; over-collecting only costs budget.
|
|
53
|
+
*/
|
|
54
|
+
/** How far an addressing payload may overtake its nominal budget: every ref line is
|
|
55
|
+
* kept up to `budget × this`, because the alternative is a click against a ref the
|
|
56
|
+
* model cannot see. Past that, the note says how many addressing lines were dropped. */
|
|
57
|
+
export declare const ADDRESSING_OVERTAKE_FACTOR = 4;
|
|
58
|
+
export declare function capKeepingAddressing(text: string, maxTokens: number): {
|
|
59
|
+
text: string;
|
|
60
|
+
kept: number;
|
|
61
|
+
dropped: number;
|
|
62
|
+
total: number;
|
|
63
|
+
addressesDropped: number;
|
|
64
|
+
fellBack: boolean;
|
|
65
|
+
};
|
|
66
|
+
/** How far a table payload may overtake its nominal budget — same reasoning as the
|
|
67
|
+
* snapshot cap: a truncated row is not a smaller table, it is an unreadable one. */
|
|
68
|
+
export declare const TABLE_OVERTAKE_FACTOR = 4;
|
|
69
|
+
/** Does this payload carry a Markdown table? A line starting with `|` followed by an
|
|
70
|
+
* alignment row is the whole test — prose that merely quotes a pipe is not a report. */
|
|
71
|
+
export declare function hasMarkdownTable(text: string): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Cap a REPORT payload: keep the tables, drop the prose around them.
|
|
74
|
+
*
|
|
75
|
+
* The generic offload (≤80-token preview + handle) is right for a 50 KB log and wrong
|
|
76
|
+
* for a report, and on this host the wrongness reaches the user: a `tm_stats` call made
|
|
77
|
+
* from inside Code Mode comes back as the `execute` result, is offloaded whole, and the
|
|
78
|
+
* lead ends up describing a table it had to page back in row by row. A live session
|
|
79
|
+
* measured exactly that on a 2 917-token report.
|
|
80
|
+
*
|
|
81
|
+
* Table lines are structural: a row is only readable with its header and alignment row,
|
|
82
|
+
* so they are kept as a unit, along with the heading above each table. Everything else
|
|
83
|
+
* is filler. Same rule as capKeepingAddressing and for the same reason — spend the
|
|
84
|
+
* budget on the part the reader cannot reconstruct.
|
|
85
|
+
*/
|
|
86
|
+
export declare function capKeepingTables(text: string, maxTokens: number): {
|
|
87
|
+
text: string;
|
|
88
|
+
kept: number;
|
|
89
|
+
dropped: number;
|
|
90
|
+
total: number;
|
|
91
|
+
tablesDropped: number;
|
|
92
|
+
};
|
|
38
93
|
export declare function capTokens(text: string, maxTokens: number): string;
|
|
39
94
|
export interface PreviewOptions {
|
|
40
95
|
/** Raw-line scan budget for the branch builders (TM_PREVIEW_LINES). */
|
package/dist/tm/preview.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/tm/preview.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAA;AAiB7E,yEAAyE;AACzE,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,CAQzD;AAsBD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAc7D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,WAAW,CAGlF;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAyBjE;AA2KD,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,GAAE,cAAmB,GAAG,MAAM,CAwBzG;AA+CD,sFAAsF;AACtF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAqBlF"}
|
|
1
|
+
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/tm/preview.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAA;AAiB7E,yEAAyE;AACzE,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,CAQzD;AAsBD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAc7D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,WAAW,CAGlF;AAED;;;;;GAKG;AACH;;;;;;;;;;;;;;;GAeG;AACH;;yFAEyF;AACzF,eAAO,MAAM,0BAA0B,IAAI,CAAA;AAE3C,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAmF7G;AAED;qFACqF;AACrF,eAAO,MAAM,qBAAqB,IAAI,CAAA;AAEtC;yFACyF;AACzF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOtD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CA2EvF;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAyBjE;AA2KD,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,GAAE,cAAmB,GAAG,MAAM,CAwBzG;AA+CD,sFAAsF;AACtF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAqBlF"}
|