@ai-ecoverse/slicc-spectrum 1.60.2 → 1.62.0
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 +10 -5
- package/dist/slicc-dummy.js +451 -11
- package/dist/slicc-dummy.js.map +4 -4
- package/dist/slicc-ui.js +1263 -170
- package/dist/slicc-ui.js.map +4 -4
- package/dist/types/app/approvals.d.ts +2 -0
- package/dist/types/app/composer.d.ts +7 -2
- package/dist/types/app/secrets.d.ts +63 -0
- package/dist/types/app/vault.d.ts +36 -0
- package/dist/types/dummy/agent.d.ts +3 -1
- package/dist/types/dummy/approvals.d.ts +1 -1
- package/dist/types/dummy/index.d.ts +6 -2
- package/dist/types/dummy/vault.d.ts +42 -0
- package/dist/types/dummy.d.ts +2 -0
- package/dist/types/model/types.d.ts +248 -0
- package/dist/types/ui.d.ts +3 -1
- package/package.json +3 -3
package/dist/slicc-ui.js
CHANGED
|
@@ -6304,10 +6304,10 @@ function getNearestOverflowAncestor(node) {
|
|
|
6304
6304
|
}
|
|
6305
6305
|
return getNearestOverflowAncestor(parentNode);
|
|
6306
6306
|
}
|
|
6307
|
-
function getOverflowAncestors(node,
|
|
6307
|
+
function getOverflowAncestors(node, list5, traverseIframes) {
|
|
6308
6308
|
var _node$ownerDocument2;
|
|
6309
|
-
if (
|
|
6310
|
-
|
|
6309
|
+
if (list5 === void 0) {
|
|
6310
|
+
list5 = [];
|
|
6311
6311
|
}
|
|
6312
6312
|
if (traverseIframes === void 0) {
|
|
6313
6313
|
traverseIframes = true;
|
|
@@ -6317,9 +6317,9 @@ function getOverflowAncestors(node, list4, traverseIframes) {
|
|
|
6317
6317
|
const win = getWindow(scrollableAncestor);
|
|
6318
6318
|
if (isBody) {
|
|
6319
6319
|
const frameElement = getFrameElement(win);
|
|
6320
|
-
return
|
|
6320
|
+
return list5.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
|
|
6321
6321
|
} else {
|
|
6322
|
-
return
|
|
6322
|
+
return list5.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
|
|
6323
6323
|
}
|
|
6324
6324
|
}
|
|
6325
6325
|
function getFrameElement(win) {
|
|
@@ -12300,7 +12300,7 @@ function remoteLight(status2) {
|
|
|
12300
12300
|
"linked devices are watching the agent."
|
|
12301
12301
|
)
|
|
12302
12302
|
].join(" ");
|
|
12303
|
-
const by = (
|
|
12303
|
+
const by = (list5) => list5.length === 1 ? list5[0].name : `${list5.length} linked devices`;
|
|
12304
12304
|
if (asking2.length) {
|
|
12305
12305
|
const text2 = asking2.length === 1 ? `${asking2[0].name} asks to follow` : `${asking2.length} devices ask to follow`;
|
|
12306
12306
|
return { mode: "ask", variant: "notice", text: text2, tooltip };
|
|
@@ -12908,8 +12908,8 @@ var SliccNetwork = class extends ModelElement {
|
|
|
12908
12908
|
}
|
|
12909
12909
|
const device = status2.links?.devices.find((item2) => item2.id === exit.id);
|
|
12910
12910
|
if (device?.state === "connected") return A;
|
|
12911
|
-
const
|
|
12912
|
-
return b`<div class="warning" data-exit="device" data-held><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><div class="banner"><span>${
|
|
12911
|
+
const who2 = device ? `${device.name} is ${device.state}` : "The linked device isn\u2019t connected";
|
|
12912
|
+
return b`<div class="warning" data-exit="device" data-held><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><div class="banner"><span>${who2}. Internet traffic waits until it’s connected.</span><div class="actions"><swc-button size="s" variant="secondary" fill-style="outline" data-action="exit-direct" ?pending=${this.busy === "exit"} ?disabled=${this.#waiting("exit")} @click=${() => this.#act("exit", () => port.setExit?.(null), "error")}>Send directly</swc-button></div></div></div>`;
|
|
12913
12913
|
}
|
|
12914
12914
|
#exitPicker(port, status2) {
|
|
12915
12915
|
const tailnet = status2.tailnet;
|
|
@@ -13694,8 +13694,8 @@ var Panels = class {
|
|
|
13694
13694
|
if (bad) return bad;
|
|
13695
13695
|
this.quietly(() => this.#host.open(id, focus, section));
|
|
13696
13696
|
if (place3) {
|
|
13697
|
-
const
|
|
13698
|
-
if (
|
|
13697
|
+
const moved2 = this.move(id, place3);
|
|
13698
|
+
if (moved2.code !== 0) return moved2;
|
|
13699
13699
|
}
|
|
13700
13700
|
return ok(`${focus ? "focused" : info.open ? "showed" : "opened"} ${id}`);
|
|
13701
13701
|
}
|
|
@@ -13816,37 +13816,37 @@ function coneOf(agents, id) {
|
|
|
13816
13816
|
}
|
|
13817
13817
|
return agent?.kind === "cone" ? agent.id : null;
|
|
13818
13818
|
}
|
|
13819
|
-
function resolve(panels, raw2,
|
|
13819
|
+
function resolve(panels, raw2, reachable2, cone) {
|
|
13820
13820
|
if (/^(file|diff):./.test(raw2)) return raw2;
|
|
13821
13821
|
if (raw2 === "chat") {
|
|
13822
13822
|
const agent = cone === void 0 ? panels.active() : cone;
|
|
13823
|
-
return
|
|
13823
|
+
return reachable2.some((info) => info.id === `chat:${agent}`) ? `chat:${agent}` : null;
|
|
13824
13824
|
}
|
|
13825
13825
|
if (raw2 === "terminal") {
|
|
13826
|
-
const terminals =
|
|
13826
|
+
const terminals = reachable2.filter((info) => info.kind === "terminal");
|
|
13827
13827
|
const picked = terminals.find((info) => info.active) ?? terminals.filter((info) => info.open).at(-1) ?? terminals.at(-1);
|
|
13828
13828
|
return picked?.id ?? null;
|
|
13829
13829
|
}
|
|
13830
|
-
if (
|
|
13830
|
+
if (reachable2.some((info) => info.id === raw2)) return raw2;
|
|
13831
13831
|
const name = raw2.startsWith("sprinkle:") ? raw2.slice(9) : raw2;
|
|
13832
|
-
const sprinkles =
|
|
13832
|
+
const sprinkles = reachable2.filter((info) => info.kind === "sprinkle");
|
|
13833
13833
|
const found = sprinkles.find((info) => info.id === `sprinkle:${name}`) ?? sprinkles.find((info) => cone && info.id === `sprinkle:${cone}/${name}`) ?? sprinkles.find((info) => info.id.split("/").at(-1) === name);
|
|
13834
13834
|
return found?.id ?? null;
|
|
13835
13835
|
}
|
|
13836
13836
|
function state(info) {
|
|
13837
|
-
const
|
|
13838
|
-
return info.busy ? `${
|
|
13837
|
+
const shown3 = info.active ? "active" : info.visible ? "shown" : info.open ? "open" : "closed";
|
|
13838
|
+
return info.busy ? `${shown3} \xB7 busy: ${info.busy}` : shown3;
|
|
13839
13839
|
}
|
|
13840
13840
|
function table(rows) {
|
|
13841
13841
|
const lines = [["ID", "TITLE", "STATE"], ...rows.map((row) => [row.id, row.title, state(row)])];
|
|
13842
13842
|
const widths = [0, 1].map((column) => Math.max(...lines.map((line) => line[column].length)));
|
|
13843
|
-
return lines.map(([id, title,
|
|
13843
|
+
return lines.map(([id, title, shown3]) => `${id.padEnd(widths[0])} ${title.padEnd(widths[1])} ${shown3}`).join("\n");
|
|
13844
13844
|
}
|
|
13845
13845
|
var done = (result, note = "") => result.code === 0 ? { stdout: `${result.message}${note}
|
|
13846
13846
|
`, stderr: "", code: 0 } : { stdout: "", stderr: `panel: ${result.message}
|
|
13847
13847
|
`, code: result.code };
|
|
13848
13848
|
function act(scope, parsed) {
|
|
13849
|
-
const { panels, reachable, cone } = scope;
|
|
13849
|
+
const { panels, reachable: reachable2, cone } = scope;
|
|
13850
13850
|
if (parsed.verb === "reset") {
|
|
13851
13851
|
const recent = scope.agent ? panels.recentClose() : null;
|
|
13852
13852
|
if (recent)
|
|
@@ -13856,11 +13856,11 @@ function act(scope, parsed) {
|
|
|
13856
13856
|
return done(panels.reset());
|
|
13857
13857
|
}
|
|
13858
13858
|
const raw2 = parsed.id;
|
|
13859
|
-
const id = resolve(panels, raw2,
|
|
13859
|
+
const id = resolve(panels, raw2, reachable2, cone);
|
|
13860
13860
|
if (!id) return done(unknown(raw2));
|
|
13861
13861
|
let place3 = parsed.place;
|
|
13862
13862
|
if (typeof place3 === "object") {
|
|
13863
|
-
const ref = resolve(panels, place3.ref,
|
|
13863
|
+
const ref = resolve(panels, place3.ref, reachable2, cone);
|
|
13864
13864
|
if (!ref) return done(unknown(place3.ref));
|
|
13865
13865
|
place3 = { ...place3, ref };
|
|
13866
13866
|
}
|
|
@@ -13895,12 +13895,12 @@ ${help}`, code: 2 };
|
|
|
13895
13895
|
const agents = panels.agents();
|
|
13896
13896
|
const scoped2 = caller.agentId !== null || !!caller.cone;
|
|
13897
13897
|
const cone = scoped2 ? caller.cone ?? coneOf(agents, caller.agentId) : void 0;
|
|
13898
|
-
const
|
|
13898
|
+
const reachable2 = panels.list().filter(
|
|
13899
13899
|
(info) => !scoped2 || info.agent === null || !!cone && coneOf(agents, info.agent) === cone
|
|
13900
13900
|
);
|
|
13901
13901
|
if (parsed.verb !== "list")
|
|
13902
|
-
return act({ panels, agent: caller.agentId !== null, cone, reachable }, parsed);
|
|
13903
|
-
const body4 = parsed.json ? JSON.stringify(
|
|
13902
|
+
return act({ panels, agent: caller.agentId !== null, cone, reachable: reachable2 }, parsed);
|
|
13903
|
+
const body4 = parsed.json ? JSON.stringify(reachable2, null, 2) : table(reachable2);
|
|
13904
13904
|
return { stdout: `${body4}
|
|
13905
13905
|
`, stderr: "", code: 0 };
|
|
13906
13906
|
}
|
|
@@ -20681,12 +20681,12 @@ function user(message) {
|
|
|
20681
20681
|
const tag3 = delivered === "steer" || delivered === "follow-up" ? deliveries[delivered] : null;
|
|
20682
20682
|
const agent = message.origin === "agent";
|
|
20683
20683
|
const name = message.from ?? "an agent";
|
|
20684
|
-
const
|
|
20684
|
+
const who2 = agent ? name : message.from ? `From ${message.from}` : "You";
|
|
20685
20685
|
const label = agent ? `Request from ${name}` : message.from ? `Message from ${message.from}` : "Your message";
|
|
20686
20686
|
return b`<swc-conversation-turn type="user" class="message user" accessible-label=${label} data-id=${message.id} data-mode=${message.mode ?? "send"} data-delivered=${delivered ?? "run"} data-origin=${message.origin ?? "user"}>
|
|
20687
20687
|
<div class="bubble">
|
|
20688
20688
|
<div class="meta">
|
|
20689
|
-
<span class="who">${
|
|
20689
|
+
<span class="who">${who2}</span><span>${time(message.createdAt)}</span>
|
|
20690
20690
|
${agent ? b`<swc-badge class="origin" size="s" variant="indigo">Agent</swc-badge>` : A}
|
|
20691
20691
|
${tag3 ? b`<swc-badge class="tag" size="s" variant=${delivered === "steer" ? "notice" : "informative"} subtle>${tag3}</swc-badge>` : A}
|
|
20692
20692
|
</div>
|
|
@@ -21945,8 +21945,8 @@ var SliccUpdates = class extends ModelElement {
|
|
|
21945
21945
|
#checked(at) {
|
|
21946
21946
|
if (at === null) return b`<span>Not checked yet</span>`;
|
|
21947
21947
|
const date = new Date(at);
|
|
21948
|
-
const
|
|
21949
|
-
return b`<span>Checked <time datetime=${date.toISOString()}>${
|
|
21948
|
+
const shown3 = date.toLocaleString("en-GB", { dateStyle: "medium", timeStyle: "short" });
|
|
21949
|
+
return b`<span>Checked <time datetime=${date.toISOString()}>${shown3}</time></span>`;
|
|
21950
21950
|
}
|
|
21951
21951
|
#item(item2) {
|
|
21952
21952
|
const [variant, state3] = states[item2.state];
|
|
@@ -22011,14 +22011,14 @@ var SliccUpdates = class extends ModelElement {
|
|
|
22011
22011
|
#package(item2, all2, act2) {
|
|
22012
22012
|
const light = packageLight(item2);
|
|
22013
22013
|
const busy = this.busy.get(item2.id);
|
|
22014
|
-
const
|
|
22014
|
+
const shown3 = busy ? [busy] : act2 ? item2.actions : [];
|
|
22015
22015
|
const error = this.problems.get(item2.id) ?? item2.error;
|
|
22016
22016
|
return b`<li data-id=${item2.id} data-state=${item2.state}>
|
|
22017
22017
|
<div class="name">
|
|
22018
22018
|
<h3 title=${item2.package}>${item2.label}</h3>
|
|
22019
22019
|
${light ? b`<swc-status-light size="s" variant=${light[0]}>${light[1]}</swc-status-light>` : A}
|
|
22020
22020
|
</div>
|
|
22021
|
-
<div class="buttons">${
|
|
22021
|
+
<div class="buttons">${shown3.map(
|
|
22022
22022
|
(action) => b`<swc-button
|
|
22023
22023
|
size="s"
|
|
22024
22024
|
variant="secondary"
|
|
@@ -22035,7 +22035,7 @@ var SliccUpdates = class extends ModelElement {
|
|
|
22035
22035
|
(warning) => b`<span><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle>${warning}</span>`
|
|
22036
22036
|
)}</p>` : A}
|
|
22037
22037
|
${item2.commands.length ? b`<p class="commands"><span class="hidden">Commands: </span>${item2.commands.map(
|
|
22038
|
-
(
|
|
22038
|
+
(command3) => b`<code>${command3}</code>`
|
|
22039
22039
|
)}</p>` : A}
|
|
22040
22040
|
${this.#packageProgress(item2)}
|
|
22041
22041
|
${error ? b`<div class="error" role="alert" data-error>
|
|
@@ -22716,9 +22716,9 @@ var SliccApp = class extends ThemedElement {
|
|
|
22716
22716
|
if (!model) return [];
|
|
22717
22717
|
const selected = this.#cone();
|
|
22718
22718
|
const cones = model.agent.list().filter((agent) => agent.kind === "cone");
|
|
22719
|
-
const
|
|
22720
|
-
const order = [selected, ...cones.map((cone) => cone.id), ...
|
|
22721
|
-
return
|
|
22719
|
+
const list5 = model.sprinkles.list();
|
|
22720
|
+
const order = [selected, ...cones.map((cone) => cone.id), ...list5.map((item2) => item2.agentId)];
|
|
22721
|
+
return list5.map((sprinkle) => {
|
|
22722
22722
|
const cone = cones.find((agent) => agent.id === sprinkle.agentId && agent.id !== selected);
|
|
22723
22723
|
return cone ? { ...sprinkle, title: `${cone.name} / ${sprinkle.title}` } : sprinkle;
|
|
22724
22724
|
}).sort((a22, b13) => order.indexOf(a22.agentId) - order.indexOf(b13.agentId));
|
|
@@ -22774,11 +22774,11 @@ var SliccApp = class extends ThemedElement {
|
|
|
22774
22774
|
#rail(items, side) {
|
|
22775
22775
|
const primary = side === "bottom" ? items.filter((item2) => phoneRail.includes(item2.id)) : items;
|
|
22776
22776
|
const fit = primary.length < items.length ? Math.min(primary.length, railCapacity(this.#width, Infinity)) : railCapacity(this.#width, items.length);
|
|
22777
|
-
const
|
|
22778
|
-
const grouped = new Set(
|
|
22779
|
-
return b`<nav class=${`rail ${side}`} aria-label=${`Panels, ${side}`} @dragover=${this.#railOver} @dragleave=${this.#railLeave} @drop=${this.#railDrop}>${
|
|
22780
|
-
(item2, index) => b`${grouped && index &&
|
|
22781
|
-
)}${this.#more(items.filter((item2) => !
|
|
22777
|
+
const shown3 = side === "bottom" ? primary.slice(0, fit) : items;
|
|
22778
|
+
const grouped = new Set(shown3.map((item2) => item2.cone).filter(Boolean)).size > 1;
|
|
22779
|
+
return b`<nav class=${`rail ${side}`} aria-label=${`Panels, ${side}`} @dragover=${this.#railOver} @dragleave=${this.#railLeave} @drop=${this.#railDrop}>${shown3.map(
|
|
22780
|
+
(item2, index) => b`${grouped && index && shown3[index - 1].cone !== item2.cone ? b`<span class="cones" aria-hidden="true"></span>` : A}${this.#railButton(item2, side)}`
|
|
22781
|
+
)}${this.#more(items.filter((item2) => !shown3.includes(item2)))}</nav>`;
|
|
22782
22782
|
}
|
|
22783
22783
|
#rails() {
|
|
22784
22784
|
const dock = this.renderRoot.querySelector("slicc-dock");
|
|
@@ -23021,6 +23021,202 @@ function sudo(approval) {
|
|
|
23021
23021
|
const as = approval.target && approval.target !== "root" ? `-u ${approval.target} ` : "";
|
|
23022
23022
|
return `sudo ${as}${approval.command}`;
|
|
23023
23023
|
}
|
|
23024
|
+
var rulePaths = ["/etc/fnox", "/etc/fnox/config.toml", "/etc/slicc/secrets-policy.toml"];
|
|
23025
|
+
var ruleParents = ["/", "/etc", "/etc/slicc"];
|
|
23026
|
+
function absolute(cwd, word) {
|
|
23027
|
+
const parts2 = [];
|
|
23028
|
+
for (const part2 of `${word.startsWith("/") ? "" : cwd}/${word}`.split("/")) {
|
|
23029
|
+
if (part2 === "..") parts2.pop();
|
|
23030
|
+
else if (part2 && part2 !== ".") parts2.push(part2);
|
|
23031
|
+
const alias = parts2.join("/").match(/^proc\/([^/]+)\/(?:task\/[^/]+\/)?(root|cwd)$/);
|
|
23032
|
+
if (alias?.[2] === "root") parts2.length = 0;
|
|
23033
|
+
else if (alias && /^(?:self|thread-self)$/.test(alias[1]))
|
|
23034
|
+
parts2.splice(0, parts2.length, ...cwd.split("/").filter(Boolean));
|
|
23035
|
+
}
|
|
23036
|
+
return `/${parts2.join("/")}`;
|
|
23037
|
+
}
|
|
23038
|
+
function pattern(path) {
|
|
23039
|
+
const source = path.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*\//g, "").replace(/\*\*/g, "").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]").replace(/\u0001/g, "(?:.*/)?").replace(/\u0002/g, ".*");
|
|
23040
|
+
return new RegExp(`^${source}$`);
|
|
23041
|
+
}
|
|
23042
|
+
var opaque = /^\/(?:proc\/[^/]+\/(?:task\/[^/]+\/)?(?:cwd|fd|map_files)|dev\/fd)(?:\/|$)/;
|
|
23043
|
+
var certain = (rules) => rules.startsWith("/") && !opaque.test(rules) && !rules.endsWith("\u2026");
|
|
23044
|
+
var readOnly = [
|
|
23045
|
+
"cat",
|
|
23046
|
+
"cd",
|
|
23047
|
+
"df",
|
|
23048
|
+
"diff",
|
|
23049
|
+
"du",
|
|
23050
|
+
"echo",
|
|
23051
|
+
"file",
|
|
23052
|
+
"grep",
|
|
23053
|
+
"head",
|
|
23054
|
+
"ls",
|
|
23055
|
+
"pwd",
|
|
23056
|
+
"readlink",
|
|
23057
|
+
"realpath",
|
|
23058
|
+
"stat",
|
|
23059
|
+
"tail",
|
|
23060
|
+
"tree",
|
|
23061
|
+
"wc"
|
|
23062
|
+
];
|
|
23063
|
+
function candidates(word) {
|
|
23064
|
+
if (word === "--") return [];
|
|
23065
|
+
if (word.startsWith("--")) return [word];
|
|
23066
|
+
if (!word.startsWith("-")) return [word];
|
|
23067
|
+
const slash = word.indexOf("/");
|
|
23068
|
+
const cluster2 = Array.from(word.slice(2), (_9, index) => word.slice(index + 2));
|
|
23069
|
+
return [...cluster2, ...slash > 2 ? [word.slice(slash)] : []];
|
|
23070
|
+
}
|
|
23071
|
+
function protects(path, whole) {
|
|
23072
|
+
const inside = (candidate) => candidate === "/etc/fnox" || candidate.startsWith("/etc/fnox/");
|
|
23073
|
+
if (opaque.test(path)) return true;
|
|
23074
|
+
if (/[[{$]/.test(path)) {
|
|
23075
|
+
const prefix = path.slice(0, path.search(/[*?[{$]/));
|
|
23076
|
+
return inside(prefix) || rulePaths.some((rule) => rule.startsWith(prefix));
|
|
23077
|
+
}
|
|
23078
|
+
if (!/[*?]/.test(path))
|
|
23079
|
+
return inside(path) || rulePaths.includes(path) || whole && ruleParents.includes(path);
|
|
23080
|
+
const glob = pattern(path);
|
|
23081
|
+
const top = path.split("/").slice(0, 3).join("/");
|
|
23082
|
+
return rulePaths.some((rule) => glob.test(rule)) || top !== path && pattern(top).test("/etc/fnox") || whole && ruleParents.some((parent) => glob.test(parent));
|
|
23083
|
+
}
|
|
23084
|
+
var command2 = (word) => word.split("/").pop() ?? "";
|
|
23085
|
+
var trusted = (word) => readOnly.includes(word.replace(/^\/(?:usr\/)?bin\/(?=[^/]+$)/, ""));
|
|
23086
|
+
var expansion = /\$\([^)]*\)?|\$\{[^}]*\}?|\$[\w@*#?$!-]*|`[^`]*`?/;
|
|
23087
|
+
function moved(cwds, word) {
|
|
23088
|
+
for (const cwd of [...cwds]) {
|
|
23089
|
+
const next = absolute(cwd, word);
|
|
23090
|
+
if (protects(next, false) || cwds.size >= 64) return next;
|
|
23091
|
+
cwds.add(next);
|
|
23092
|
+
}
|
|
23093
|
+
return null;
|
|
23094
|
+
}
|
|
23095
|
+
function touched(cwds, word, whole) {
|
|
23096
|
+
for (const candidate of candidates(word))
|
|
23097
|
+
for (const cwd of cwds) {
|
|
23098
|
+
const path = absolute(cwd, candidate);
|
|
23099
|
+
if (protects(path, whole)) return path;
|
|
23100
|
+
}
|
|
23101
|
+
return null;
|
|
23102
|
+
}
|
|
23103
|
+
function ansi(command3) {
|
|
23104
|
+
const escape2 = /\\(?:x([0-9a-fA-F]{1,2})|u([0-9a-fA-F]{1,4})|U([0-9a-fA-F]{1,8})|([0-7]{1,3})|([\s\S]))/g;
|
|
23105
|
+
return command3.replace(
|
|
23106
|
+
/\$'((?:[^'\\]|\\[\s\S])*)'/g,
|
|
23107
|
+
(_9, body4) => `'${body4.replace(escape2, (_match, hex, short2, long, octal, plain) => {
|
|
23108
|
+
if (octal) return String.fromCharCode(Number.parseInt(octal, 8));
|
|
23109
|
+
if (plain) return plain;
|
|
23110
|
+
return String.fromCodePoint(
|
|
23111
|
+
Math.min(Number.parseInt(hex ?? short2 ?? long, 16), 1114111)
|
|
23112
|
+
);
|
|
23113
|
+
}).replace(/'/g, "'\\''")}'`
|
|
23114
|
+
).replace(/\$"/g, '"');
|
|
23115
|
+
}
|
|
23116
|
+
function unglob(command3) {
|
|
23117
|
+
const chars = Array.from(command3);
|
|
23118
|
+
const close = /* @__PURE__ */ new Map();
|
|
23119
|
+
const open = [];
|
|
23120
|
+
for (const [index, char] of chars.entries()) {
|
|
23121
|
+
if (char === "(") open.push(index);
|
|
23122
|
+
else if (char === ")" && open.length) close.set(open.pop(), index);
|
|
23123
|
+
}
|
|
23124
|
+
const out = [];
|
|
23125
|
+
for (let index = 0; index < chars.length; index++) {
|
|
23126
|
+
const end = close.get(index);
|
|
23127
|
+
if (end !== void 0 && /^[?*+@!]$/.test(out.at(-1) ?? "")) {
|
|
23128
|
+
out[out.length - 1] = "*";
|
|
23129
|
+
index = end;
|
|
23130
|
+
} else out.push(chars[index]);
|
|
23131
|
+
}
|
|
23132
|
+
return out.join("");
|
|
23133
|
+
}
|
|
23134
|
+
var separators = /[;&|\n()`]/;
|
|
23135
|
+
function hide2(char) {
|
|
23136
|
+
return separators.test(char) ? String.fromCharCode(57344 + char.charCodeAt(0)) : char;
|
|
23137
|
+
}
|
|
23138
|
+
function unshield(segment2) {
|
|
23139
|
+
return segment2.replace(
|
|
23140
|
+
/[\ue000-\ue07f]/g,
|
|
23141
|
+
(char) => String.fromCharCode(char.charCodeAt(0) - 57344)
|
|
23142
|
+
);
|
|
23143
|
+
}
|
|
23144
|
+
function shield(text2) {
|
|
23145
|
+
let out = "";
|
|
23146
|
+
let quote = "";
|
|
23147
|
+
for (let index = 0; index < text2.length; index++) {
|
|
23148
|
+
const char = text2[index];
|
|
23149
|
+
if (quote === '"' && char === "\\") out += hide2(char) + hide2(text2[++index] ?? "");
|
|
23150
|
+
else if (quote) {
|
|
23151
|
+
out += char === quote ? char : hide2(char);
|
|
23152
|
+
if (char === quote) quote = "";
|
|
23153
|
+
} else if (char === "'" || char === '"') {
|
|
23154
|
+
quote = char;
|
|
23155
|
+
out += char;
|
|
23156
|
+
} else if (char === "\\") out += char + hide2(text2[++index] ?? "");
|
|
23157
|
+
else out += char;
|
|
23158
|
+
}
|
|
23159
|
+
return out;
|
|
23160
|
+
}
|
|
23161
|
+
function quoted(segment2) {
|
|
23162
|
+
const words = [];
|
|
23163
|
+
let word = "";
|
|
23164
|
+
let quote = "";
|
|
23165
|
+
for (let index = 0; index < segment2.length; index++) {
|
|
23166
|
+
const char = segment2[index];
|
|
23167
|
+
if (quote === '"' && char === "\\" && /["\\$`\n]/.test(segment2[index + 1] ?? ""))
|
|
23168
|
+
word += segment2[++index];
|
|
23169
|
+
else if (quote) {
|
|
23170
|
+
if (char === quote) quote = "";
|
|
23171
|
+
else word += char;
|
|
23172
|
+
} else if (char === "'" || char === '"') quote = char;
|
|
23173
|
+
else if (char === "\\") word += segment2[++index] ?? "";
|
|
23174
|
+
else if (/[\s<>=]/.test(char)) {
|
|
23175
|
+
words.push(word);
|
|
23176
|
+
word = "";
|
|
23177
|
+
} else word += char;
|
|
23178
|
+
}
|
|
23179
|
+
return [...words, word];
|
|
23180
|
+
}
|
|
23181
|
+
function commas(words) {
|
|
23182
|
+
return words.flatMap((word) => word.includes(",") ? [word, ...word.split(",")] : [word]).filter(Boolean);
|
|
23183
|
+
}
|
|
23184
|
+
function scan2(words, cwds, whole) {
|
|
23185
|
+
let cd = false;
|
|
23186
|
+
for (const [index, word] of words.entries()) {
|
|
23187
|
+
let hit = null;
|
|
23188
|
+
if (index === 0 || words[index - 1] === "-c") {
|
|
23189
|
+
cd = ["cd", "pushd"].includes(command2(word));
|
|
23190
|
+
hit = touched(cwds, word, whole);
|
|
23191
|
+
} else if (!cd) hit = touched(cwds, word, whole);
|
|
23192
|
+
else if (!word.startsWith("-")) {
|
|
23193
|
+
cd = false;
|
|
23194
|
+
hit = moved(cwds, word);
|
|
23195
|
+
}
|
|
23196
|
+
if (hit) return hit;
|
|
23197
|
+
}
|
|
23198
|
+
return null;
|
|
23199
|
+
}
|
|
23200
|
+
function secretRules(approval) {
|
|
23201
|
+
if (approval.command.length > 4096) return `${approval.command.slice(0, 40)}\u2026`;
|
|
23202
|
+
const start = absolute("/", approval.cwd ?? "/");
|
|
23203
|
+
if (protects(start, false)) return start;
|
|
23204
|
+
const cwds = /* @__PURE__ */ new Set([start]);
|
|
23205
|
+
const text2 = unglob(ansi(approval.command.replace(/\\\n/g, "")));
|
|
23206
|
+
const plain = text2.split(separators).map((segment2) => commas(segment2.split(/[\s<>=]+/).map((word) => word.replace(/['"\\]/g, ""))));
|
|
23207
|
+
const aware = shield(text2).split(separators).map((segment2) => commas(quoted(unshield(segment2))));
|
|
23208
|
+
const segments = JSON.stringify(aware) === JSON.stringify(plain) ? plain : [...plain, ...aware];
|
|
23209
|
+
const whole = segments.some((words) => words.length > 0 && !trusted(words[0]));
|
|
23210
|
+
for (const words of segments) {
|
|
23211
|
+
const hit = scan2(words, cwds, whole);
|
|
23212
|
+
if (hit) return hit;
|
|
23213
|
+
}
|
|
23214
|
+
const named = segments.flat().find((word) => !word.startsWith("/") && /fnox|secrets-policy/.test(word));
|
|
23215
|
+
if (named) return absolute([...cwds].pop() ?? start, named);
|
|
23216
|
+
const home2 = segments.flat().find((word) => /^~(?:[+-](?:\/|$)|.*\/\.\.(?:\/|$))/.test(word));
|
|
23217
|
+
if (home2) return home2;
|
|
23218
|
+
return segments.flat().some((word) => word.includes("$")) || text2.includes("`") ? text2.match(expansion)[0] : null;
|
|
23219
|
+
}
|
|
23024
23220
|
function waiting(model, now) {
|
|
23025
23221
|
return [...model?.approvals?.list() ?? []].filter((approval) => approval.expiresAt > now).sort((a22, b13) => a22.createdAt - b13.createdAt);
|
|
23026
23222
|
}
|
|
@@ -23086,6 +23282,27 @@ var SliccApprovals = class extends ModelElement {
|
|
|
23086
23282
|
margin-block-start: var(--swc-spacing-300);
|
|
23087
23283
|
font-variant-numeric: tabular-nums;
|
|
23088
23284
|
}
|
|
23285
|
+
.rules {
|
|
23286
|
+
display: flex;
|
|
23287
|
+
align-items: flex-start;
|
|
23288
|
+
gap: var(--swc-spacing-100);
|
|
23289
|
+
margin-block-start: var(--swc-spacing-200);
|
|
23290
|
+
padding: var(--swc-spacing-200) var(--swc-spacing-300);
|
|
23291
|
+
border-radius: var(--swc-corner-radius-medium-default);
|
|
23292
|
+
background: var(--swc-notice-subtle-background-color-default);
|
|
23293
|
+
--swc-icon-color: var(--swc-icon-color-notice);
|
|
23294
|
+
}
|
|
23295
|
+
.rules swc-icon-alert-triangle {
|
|
23296
|
+
flex: none;
|
|
23297
|
+
margin-block-start: 0.15em;
|
|
23298
|
+
}
|
|
23299
|
+
.rules p {
|
|
23300
|
+
margin: 0;
|
|
23301
|
+
}
|
|
23302
|
+
.rules code {
|
|
23303
|
+
font-family: var(--swc-code-font-family-stack);
|
|
23304
|
+
overflow-wrap: anywhere;
|
|
23305
|
+
}
|
|
23089
23306
|
.problem {
|
|
23090
23307
|
display: flex;
|
|
23091
23308
|
align-items: flex-start;
|
|
@@ -23140,6 +23357,7 @@ var SliccApprovals = class extends ModelElement {
|
|
|
23140
23357
|
async decide(approval, decision) {
|
|
23141
23358
|
const port = this.model?.approvals;
|
|
23142
23359
|
if (!port?.decide || this.busy || decision !== "deny" && !this.#armed) return;
|
|
23360
|
+
if (decision === "always" && secretRules(approval)) return;
|
|
23143
23361
|
this.busy = decision;
|
|
23144
23362
|
this.failure = null;
|
|
23145
23363
|
this.#pending.add(approval.id);
|
|
@@ -23161,15 +23379,15 @@ var SliccApprovals = class extends ModelElement {
|
|
|
23161
23379
|
}
|
|
23162
23380
|
willUpdate(changed) {
|
|
23163
23381
|
super.willUpdate(changed);
|
|
23164
|
-
const
|
|
23382
|
+
const list5 = this.#current();
|
|
23165
23383
|
const showing = this.#showing;
|
|
23166
23384
|
if (showing && this.#pending.has(showing.id)) return;
|
|
23167
|
-
if (showing && !this.gone && !this.#done.has(showing.id) && !
|
|
23385
|
+
if (showing && !this.gone && !this.#done.has(showing.id) && !list5.some((approval) => approval.id === showing.id)) {
|
|
23168
23386
|
const reason = this.#ended.get(showing.id) ?? (showing.expiresAt <= this.now ? "expired" : "answered");
|
|
23169
23387
|
if (reason !== "withdrawn") this.gone = { approval: showing, reason: gone(reason) };
|
|
23170
23388
|
}
|
|
23171
23389
|
if (this.gone) return;
|
|
23172
|
-
const next =
|
|
23390
|
+
const next = list5[0] ?? null;
|
|
23173
23391
|
if (next?.id === showing?.id) return;
|
|
23174
23392
|
this.#showing = next;
|
|
23175
23393
|
clearTimeout(this.#arming);
|
|
@@ -23240,10 +23458,12 @@ var SliccApprovals = class extends ModelElement {
|
|
|
23240
23458
|
);
|
|
23241
23459
|
}
|
|
23242
23460
|
const held = this.#showing && this.#pending.has(this.#showing.id) ? this.#showing : null;
|
|
23243
|
-
const
|
|
23244
|
-
const [approval, ...rest] = held ? [held, ...
|
|
23461
|
+
const list5 = this.#current();
|
|
23462
|
+
const [approval, ...rest] = held ? [held, ...list5.filter(({ id }) => id !== held.id)] : list5;
|
|
23245
23463
|
if (!approval) return A;
|
|
23246
23464
|
const failure2 = this.failure?.id === approval.id ? this.failure.message : "";
|
|
23465
|
+
const rules = secretRules(approval);
|
|
23466
|
+
const always = approval.always && !rules;
|
|
23247
23467
|
return this.#dialog(
|
|
23248
23468
|
approval,
|
|
23249
23469
|
approval.id,
|
|
@@ -23251,12 +23471,13 @@ var SliccApprovals = class extends ModelElement {
|
|
|
23251
23471
|
<h2 id="title" slot="heading">Allow sudo?</h2>
|
|
23252
23472
|
${this.#request(approval)}
|
|
23253
23473
|
${approval.cwd ? b`<p class="cwd">In ${approval.cwd}</p>` : A}
|
|
23254
|
-
${
|
|
23474
|
+
${rules ? b`<div class="rules" data-secret-rules=${rules}><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><p>${certain(rules) ? b`<strong>This changes secret rules.</strong> It names <code>${rules}</code>, where SLICC keeps which secrets programs may use and where they may be sent.` : b`<strong>This may change secret rules.</strong> SLICC can't tell where <code>${rules}</code> leads, and it could reach the files where SLICC keeps which secrets programs may use and where they may be sent.`} Allow it only if you asked for this change.</p></div>` : A}
|
|
23475
|
+
${always ? b`<p class="hint">Always allow lets ${approval.requester.name} run exactly this command with sudo without asking again.</p>` : A}
|
|
23255
23476
|
${failure2 ? b`<p class="problem" role="alert" data-error><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><span>${failure2}</span></p>` : A}
|
|
23256
23477
|
<p class="timer" data-timer>Denied automatically in ${countdown(approval.expiresAt - this.now)}.</p>
|
|
23257
23478
|
${rest.length ? b`<p class="more" data-more>${rest.length === 1 ? "1 more request is waiting." : `${rest.length} more requests are waiting.`}</p>` : A}
|
|
23258
23479
|
${this.#button(approval, "deny", "Deny", "secondary")}
|
|
23259
|
-
${
|
|
23480
|
+
${always ? this.#button(approval, "always", "Always allow", "secondary") : A}
|
|
23260
23481
|
${this.#button(approval, "once", "Allow once", "accent")}
|
|
23261
23482
|
</sp-alert-dialog>`
|
|
23262
23483
|
);
|
|
@@ -24168,9 +24389,9 @@ var SliccBrowser = class extends ModelElement {
|
|
|
24168
24389
|
if (visible2 && tab && !this.#ticker)
|
|
24169
24390
|
this.#ticker = setInterval(() => this.requestUpdate(), 1e3);
|
|
24170
24391
|
if (!(visible2 && tab)) this.#still();
|
|
24171
|
-
const
|
|
24172
|
-
const count =
|
|
24173
|
-
if (
|
|
24392
|
+
const list5 = this.renderRoot.querySelector(".actions:not(.last)");
|
|
24393
|
+
const count = list5?.childElementCount ?? 0;
|
|
24394
|
+
if (list5 && count !== this.#count) list5.scrollTop = list5.scrollHeight;
|
|
24174
24395
|
this.#count = count;
|
|
24175
24396
|
}
|
|
24176
24397
|
#still() {
|
|
@@ -25064,18 +25285,18 @@ function failedTurns(messages, messageId) {
|
|
|
25064
25285
|
}
|
|
25065
25286
|
return ids;
|
|
25066
25287
|
}
|
|
25067
|
-
var
|
|
25288
|
+
var touched2 = false;
|
|
25068
25289
|
document.addEventListener(
|
|
25069
25290
|
"pointerdown",
|
|
25070
25291
|
(event2) => {
|
|
25071
|
-
|
|
25292
|
+
touched2 = event2.pointerType !== "mouse";
|
|
25072
25293
|
},
|
|
25073
25294
|
true
|
|
25074
25295
|
);
|
|
25075
25296
|
document.addEventListener(
|
|
25076
25297
|
"keydown",
|
|
25077
25298
|
() => {
|
|
25078
|
-
|
|
25299
|
+
touched2 = false;
|
|
25079
25300
|
},
|
|
25080
25301
|
true
|
|
25081
25302
|
);
|
|
@@ -25251,7 +25472,7 @@ var SliccChat = class extends ThemedElement {
|
|
|
25251
25472
|
this.#observe();
|
|
25252
25473
|
}
|
|
25253
25474
|
focus() {
|
|
25254
|
-
if (!
|
|
25475
|
+
if (!touched2 && globalThis.matchMedia("(pointer: fine)").matches)
|
|
25255
25476
|
this.focusOn("slicc-composer", ".log");
|
|
25256
25477
|
else this.focusOn(".log");
|
|
25257
25478
|
}
|
|
@@ -26257,7 +26478,7 @@ e25("swc-icon-clock", o84);
|
|
|
26257
26478
|
// src/app/composer.ts
|
|
26258
26479
|
var limit = 25 * 1024 * 1024;
|
|
26259
26480
|
function available(model) {
|
|
26260
|
-
return commands2.filter((
|
|
26481
|
+
return commands2.filter((command3) => command3.available?.(model) ?? true);
|
|
26261
26482
|
}
|
|
26262
26483
|
var commands2 = [
|
|
26263
26484
|
{
|
|
@@ -26336,20 +26557,21 @@ function trigger(text2, caret) {
|
|
|
26336
26557
|
const argument = before.match(/^\/(\w+)\s+(\S*)$/);
|
|
26337
26558
|
if (argument)
|
|
26338
26559
|
return { kind: "argument", start: before.length - argument[2].length, query: argument[2] };
|
|
26339
|
-
const
|
|
26340
|
-
if (
|
|
26560
|
+
const command3 = before.match(/^\/([\w:-]*)$/);
|
|
26561
|
+
if (command3) return { kind: "command", start: 0, query: command3[1] };
|
|
26341
26562
|
const mention = before.match(/(^|\s)@([\w./-]*)$/);
|
|
26342
26563
|
if (mention)
|
|
26343
26564
|
return { kind: "mention", start: before.length - mention[2].length - 1, query: mention[2] };
|
|
26344
26565
|
return null;
|
|
26345
26566
|
}
|
|
26346
|
-
var SliccComposer = class extends
|
|
26567
|
+
var SliccComposer = class extends ThemedElement {
|
|
26347
26568
|
static properties = {
|
|
26348
|
-
...
|
|
26569
|
+
...ThemedElement.properties,
|
|
26349
26570
|
value: { state: true },
|
|
26350
26571
|
attachments: { state: true },
|
|
26351
26572
|
popup: { state: true },
|
|
26352
26573
|
dictating: { state: true },
|
|
26574
|
+
blocked: { state: true },
|
|
26353
26575
|
agent: {}
|
|
26354
26576
|
};
|
|
26355
26577
|
#drafts = /* @__PURE__ */ new Map();
|
|
@@ -26365,6 +26587,7 @@ var SliccComposer = class extends ModelElement {
|
|
|
26365
26587
|
this.attachments = [];
|
|
26366
26588
|
this.popup = null;
|
|
26367
26589
|
this.dictating = false;
|
|
26590
|
+
this.blocked = false;
|
|
26368
26591
|
this.agent = "";
|
|
26369
26592
|
}
|
|
26370
26593
|
static styles = [
|
|
@@ -26403,6 +26626,38 @@ var SliccComposer = class extends ModelElement {
|
|
|
26403
26626
|
border: var(--swc-border-width-100) dashed var(--swc-gray-300);
|
|
26404
26627
|
color: var(--swc-neutral-content-color-default);
|
|
26405
26628
|
}
|
|
26629
|
+
.hold {
|
|
26630
|
+
display: flex;
|
|
26631
|
+
flex-wrap: wrap;
|
|
26632
|
+
align-items: center;
|
|
26633
|
+
gap: var(--swc-spacing-100);
|
|
26634
|
+
margin: 0 0 var(--swc-spacing-100);
|
|
26635
|
+
padding: var(--swc-spacing-75) var(--swc-spacing-100) var(--swc-spacing-75) var(--swc-spacing-200);
|
|
26636
|
+
border-radius: var(--swc-corner-radius-medium-default);
|
|
26637
|
+
background: var(--swc-informative-subtle-background-color-default);
|
|
26638
|
+
color: var(--swc-neutral-content-color-default);
|
|
26639
|
+
}
|
|
26640
|
+
.hold[data-hold='locked'] {
|
|
26641
|
+
background: var(--swc-notice-subtle-background-color-default);
|
|
26642
|
+
}
|
|
26643
|
+
.hold swc-icon-lock,
|
|
26644
|
+
.hold swc-progress-circle {
|
|
26645
|
+
flex: none;
|
|
26646
|
+
}
|
|
26647
|
+
.hold .text {
|
|
26648
|
+
flex: 1;
|
|
26649
|
+
min-inline-size: 12em;
|
|
26650
|
+
}
|
|
26651
|
+
.hold .blocked {
|
|
26652
|
+
flex-basis: 100%;
|
|
26653
|
+
display: flex;
|
|
26654
|
+
align-items: center;
|
|
26655
|
+
gap: var(--swc-spacing-75);
|
|
26656
|
+
color: var(--swc-negative-content-color-default);
|
|
26657
|
+
}
|
|
26658
|
+
.hold .held {
|
|
26659
|
+
color: var(--swc-neutral-subdued-content-color-default);
|
|
26660
|
+
}
|
|
26406
26661
|
.queued swc-icon-clock {
|
|
26407
26662
|
flex: none;
|
|
26408
26663
|
color: var(--swc-neutral-subdued-content-color-default);
|
|
@@ -26597,9 +26852,14 @@ var SliccComposer = class extends ModelElement {
|
|
|
26597
26852
|
});
|
|
26598
26853
|
const update = () => this.requestUpdate();
|
|
26599
26854
|
return [
|
|
26855
|
+
...super.subscribe(model),
|
|
26600
26856
|
model.agent.on("active", (id) => {
|
|
26601
26857
|
if (!this.agent) this.#switch(id);
|
|
26602
26858
|
}),
|
|
26859
|
+
model.agent.on("hold", (hold) => {
|
|
26860
|
+
if (hold?.reason !== "locked") this.blocked = false;
|
|
26861
|
+
update();
|
|
26862
|
+
}),
|
|
26603
26863
|
model.agent.on("agents", update),
|
|
26604
26864
|
model.agent.on("messages", update),
|
|
26605
26865
|
model.agent.on("message", update),
|
|
@@ -26644,14 +26904,14 @@ var SliccComposer = class extends ModelElement {
|
|
|
26644
26904
|
const text2 = this.value.trim();
|
|
26645
26905
|
const attachments = this.attachments.filter((attachment2) => !attachment2.error);
|
|
26646
26906
|
if (!model || !text2 && attachments.length === 0 || this.#held()) return;
|
|
26647
|
-
const
|
|
26648
|
-
const known =
|
|
26907
|
+
const command3 = text2.match(/^\/(\w+)(?:\s+(.*))?$/);
|
|
26908
|
+
const known = command3 && available(model).find((candidate) => candidate.name === command3[1]);
|
|
26649
26909
|
this.value = "";
|
|
26650
26910
|
this.attachments = [];
|
|
26651
26911
|
this.popup = null;
|
|
26652
26912
|
this.#history = -1;
|
|
26653
26913
|
if (known) {
|
|
26654
|
-
known.run(model, this.#agent, (
|
|
26914
|
+
known.run(model, this.#agent, (command3[2] ?? "").trim());
|
|
26655
26915
|
return;
|
|
26656
26916
|
}
|
|
26657
26917
|
const busy = this.#busy();
|
|
@@ -26739,22 +26999,22 @@ var SliccComposer = class extends ModelElement {
|
|
|
26739
26999
|
const model = this.model;
|
|
26740
27000
|
if (kind === "command") {
|
|
26741
27001
|
const usable = available(model);
|
|
26742
|
-
const builtins = usable.map((
|
|
26743
|
-
value:
|
|
26744
|
-
label: `/${
|
|
26745
|
-
detail:
|
|
27002
|
+
const builtins = usable.map((command3) => ({
|
|
27003
|
+
value: command3.name,
|
|
27004
|
+
label: `/${command3.name}`,
|
|
27005
|
+
detail: command3.detail
|
|
26746
27006
|
}));
|
|
26747
|
-
const own4 = model.agent.commands(this.#agent).filter((
|
|
26748
|
-
value:
|
|
26749
|
-
label: `/${
|
|
26750
|
-
detail:
|
|
26751
|
-
group:
|
|
27007
|
+
const own4 = model.agent.commands(this.#agent).filter((command3) => !usable.some((builtin) => builtin.name === command3.name)).map((command3) => ({
|
|
27008
|
+
value: command3.name,
|
|
27009
|
+
label: `/${command3.name}`,
|
|
27010
|
+
detail: command3.description,
|
|
27011
|
+
group: command3.kind === "skill" ? "Skills" : "Prompts"
|
|
26752
27012
|
})).sort((a22, b13) => a22.group === b13.group ? 0 : a22.group === "Prompts" ? -1 : 1);
|
|
26753
27013
|
return filter([...builtins, ...own4], query, Number.POSITIVE_INFINITY);
|
|
26754
27014
|
}
|
|
26755
27015
|
if (kind === "argument") {
|
|
26756
27016
|
const name = this.value.match(/^\/(\w+)/)?.[1];
|
|
26757
|
-
return filter(commands2.find((
|
|
27017
|
+
return filter(commands2.find((command3) => command3.name === name)?.args?.(model) ?? [], query);
|
|
26758
27018
|
}
|
|
26759
27019
|
const files = this.#paths.map((path) => ({
|
|
26760
27020
|
value: path,
|
|
@@ -26774,7 +27034,7 @@ var SliccComposer = class extends ModelElement {
|
|
|
26774
27034
|
if (this.popup?.kind === "file" || this.popup?.kind === "secret") return;
|
|
26775
27035
|
const found = trigger(this.value, area.selectionStart ?? this.value.length);
|
|
26776
27036
|
const name = this.value.match(/^\/(\w+)/)?.[1];
|
|
26777
|
-
const takes = commands2.some((
|
|
27037
|
+
const takes = commands2.some((command3) => command3.name === name && command3.args);
|
|
26778
27038
|
this.popup = found && (found.kind !== "argument" || takes) ? { ...found, items: this.#choices(found.kind, found.query), index: 0 } : null;
|
|
26779
27039
|
}
|
|
26780
27040
|
openPopup(kind) {
|
|
@@ -26985,6 +27245,26 @@ var SliccComposer = class extends ModelElement {
|
|
|
26985
27245
|
) : b`<div class="empty">Nothing matches.</div>`}
|
|
26986
27246
|
</div>`;
|
|
26987
27247
|
}
|
|
27248
|
+
#hold() {
|
|
27249
|
+
const hold = this.model?.agent.hold?.();
|
|
27250
|
+
if (!hold) return A;
|
|
27251
|
+
const locked = hold.reason === "locked";
|
|
27252
|
+
const vault = this.model?.vault;
|
|
27253
|
+
const held = hold.held === 1 ? "1 tool result held" : `${hold.held} tool results held`;
|
|
27254
|
+
return b`<div class="hold" role="status" data-hold=${hold.reason}>
|
|
27255
|
+
${locked ? b`<swc-icon-lock size="s" aria-hidden="true"></swc-icon-lock>` : b`<swc-progress-circle size="s" label="Waiting" aria-hidden="true"></swc-progress-circle>`}
|
|
27256
|
+
<span class="text">${locked ? "Unlock the vault to continue" : "Waiting for the vault"}${hold.held ? b`<span class="held"> · ${held}</span>` : A}</span>
|
|
27257
|
+
${locked && vault ? b`<slicc-vault-button
|
|
27258
|
+
data-action="unlock-vault"
|
|
27259
|
+
.vault=${vault}
|
|
27260
|
+
.config=${{ intent: { kind: "unlock" }, label: "Unlock", size: "s", variant: "accent", theme: this.color }}
|
|
27261
|
+
@vault-popup=${(event2) => {
|
|
27262
|
+
this.blocked = event2.detail.state === "blocked";
|
|
27263
|
+
}}
|
|
27264
|
+
></slicc-vault-button>` : A}
|
|
27265
|
+
${locked && this.blocked ? b`<span class="blocked" role="alert" data-popup="blocked"><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle>The browser blocked the vault window. Allow pop-ups for this site, then try again.</span>` : A}
|
|
27266
|
+
</div>`;
|
|
27267
|
+
}
|
|
26988
27268
|
#queue() {
|
|
26989
27269
|
const queued = this.model?.agent.queue(this.#agent) ?? [];
|
|
26990
27270
|
if (queued.length === 0) return A;
|
|
@@ -27015,6 +27295,7 @@ var SliccComposer = class extends ModelElement {
|
|
|
27015
27295
|
const speech = "SpeechRecognition" in globalThis || "webkitSpeechRecognition" in globalThis;
|
|
27016
27296
|
const held = this.#held();
|
|
27017
27297
|
return b`<div class="column">
|
|
27298
|
+
${this.#hold()}
|
|
27018
27299
|
${this.#queue()}
|
|
27019
27300
|
${this.#popup()}
|
|
27020
27301
|
<swc-prompt-field
|
|
@@ -27368,8 +27649,8 @@ var SliccMemory = class extends ModelElement {
|
|
|
27368
27649
|
const scopes = this.#scopes;
|
|
27369
27650
|
const scope = this.scope;
|
|
27370
27651
|
const option2 = (item2) => b`<sp-menu-item value=${item2.id}>${item2.label}</sp-menu-item>`;
|
|
27371
|
-
const
|
|
27372
|
-
return b`<div class="bar"><span>${
|
|
27652
|
+
const shown3 = visible(all2, scope, this.tag, this.query);
|
|
27653
|
+
return b`<div class="bar"><span>${shown3.length} of ${all2.filter((memory) => memory.scope === scope).length} memories</span><span class="spacer"></span>
|
|
27373
27654
|
<swc-action-button size="s" quiet @click=${() => this.editing = "new"}><swc-icon-add slot="icon"></swc-icon-add>Remember</swc-action-button>
|
|
27374
27655
|
</div>
|
|
27375
27656
|
<div class="tools">
|
|
@@ -27391,7 +27672,7 @@ var SliccMemory = class extends ModelElement {
|
|
|
27391
27672
|
</div>
|
|
27392
27673
|
<div class="list">
|
|
27393
27674
|
${this.editing === "new" ? b`<div class="row">${this.#form({ scope })}</div>` : A}
|
|
27394
|
-
${
|
|
27675
|
+
${shown3.length ? sections(shown3).map(
|
|
27395
27676
|
([section, items]) => b`<h3>${section}</h3>${items.map((memory) => this.#row(memory))}`
|
|
27396
27677
|
) : b`<div class="note">${all2.length ? "No memories match." : "No memories yet."}</div>`}
|
|
27397
27678
|
</div>`;
|
|
@@ -27699,10 +27980,10 @@ var SliccMonitor = class extends ModelElement {
|
|
|
27699
27980
|
const surface2 = surfaces2[section.id];
|
|
27700
27981
|
const rows = section.rows.length > 0;
|
|
27701
27982
|
const open = rows && (this.expanded[section.id] ?? flag !== null);
|
|
27702
|
-
const
|
|
27983
|
+
const list5 = `rows-${section.id}`;
|
|
27703
27984
|
return b`<li class="section" data-id=${section.id} data-open=${open ? "" : A}>
|
|
27704
27985
|
<div class="line">
|
|
27705
|
-
${rows ? b`<button class="toggle" aria-expanded=${open ? "true" : "false"} aria-controls=${open ?
|
|
27986
|
+
${rows ? b`<button class="toggle" aria-expanded=${open ? "true" : "false"} aria-controls=${open ? list5 : A} @click=${() => {
|
|
27706
27987
|
this.expanded = { ...this.expanded, [section.id]: !open };
|
|
27707
27988
|
}}><span class="chevron"><swc-icon-chevron-right size="s" aria-hidden="true"></swc-icon-chevron-right></span><span class="name">${section.label}</span></button>` : b`<span class="chevron"></span><span class="name">${section.label}</span>`}
|
|
27708
27989
|
${flag ? b`<swc-badge size="s" variant=${flag.variant} subtle>${flag.text}</swc-badge>` : A}
|
|
@@ -27711,7 +27992,7 @@ var SliccMonitor = class extends ModelElement {
|
|
|
27711
27992
|
>Open</swc-action-button
|
|
27712
27993
|
>` : A}
|
|
27713
27994
|
</div>
|
|
27714
|
-
${open ? b`<ul class="rows" id=${
|
|
27995
|
+
${open ? b`<ul class="rows" id=${list5} aria-label=${section.label}>${c(
|
|
27715
27996
|
section.rows,
|
|
27716
27997
|
(row, i25) => row.id ?? i25,
|
|
27717
27998
|
(row) => this.#row(row)
|
|
@@ -27918,6 +28199,748 @@ var SliccNotices = class extends ModelElement {
|
|
|
27918
28199
|
}
|
|
27919
28200
|
};
|
|
27920
28201
|
|
|
28202
|
+
// src/app/vault.ts
|
|
28203
|
+
var exitNames = {
|
|
28204
|
+
"vault-direct": "Straight from the vault",
|
|
28205
|
+
"local-proxy": "Local proxy",
|
|
28206
|
+
"cli-v": "Local SLICC, direct",
|
|
28207
|
+
tailscale: "Tailscale",
|
|
28208
|
+
"local-link": "Linked SLICC, through this page"
|
|
28209
|
+
};
|
|
28210
|
+
function devicesOf(model) {
|
|
28211
|
+
return model?.network?.status().links?.devices ?? [];
|
|
28212
|
+
}
|
|
28213
|
+
function deviceName2(id, devices) {
|
|
28214
|
+
return (devices.find((device) => device.id === id)?.name ?? id).replace(/^slicc\b/i, "SLICC");
|
|
28215
|
+
}
|
|
28216
|
+
function exitLabel(exit, devices) {
|
|
28217
|
+
if (exit.startsWith("device:")) return deviceName2(exit.slice("device:".length), devices);
|
|
28218
|
+
return exitNames[exit];
|
|
28219
|
+
}
|
|
28220
|
+
function list4(items) {
|
|
28221
|
+
if (items.length < 2) return items.join("");
|
|
28222
|
+
return `${items.slice(0, -1).join(", ")} and ${items[items.length - 1]}`;
|
|
28223
|
+
}
|
|
28224
|
+
function ruleLine(rule) {
|
|
28225
|
+
const methods = rule.methods.length ? rule.methods.join(" or ") : "any method";
|
|
28226
|
+
const paths = rule.paths.length ? rule.paths.join(" or ") : "any path";
|
|
28227
|
+
return `${rule.domain}, in ${rule.header}, ${methods}, ${paths}`;
|
|
28228
|
+
}
|
|
28229
|
+
function shellWord(word) {
|
|
28230
|
+
return /^[\w@%+=:,./-]+$/.test(word) ? word : `'${word.replace(/'/g, "'\\''")}'`;
|
|
28231
|
+
}
|
|
28232
|
+
function execLine(grant) {
|
|
28233
|
+
if (grant === false) return "Never revealed to programs";
|
|
28234
|
+
if (grant === true) return "Revealed to any program that asks";
|
|
28235
|
+
return `Revealed only to ${list4(grant.argv.map((argv) => argv.map(shellWord).join(" ")))}`;
|
|
28236
|
+
}
|
|
28237
|
+
function widening(change, devices) {
|
|
28238
|
+
switch (change.kind) {
|
|
28239
|
+
case "rule":
|
|
28240
|
+
return `${change.secret} may now be sent to ${ruleLine(change.rule)}`;
|
|
28241
|
+
case "methods":
|
|
28242
|
+
return `${change.secret} may now use ${list4(change.methods)} on ${change.domain}`;
|
|
28243
|
+
case "paths":
|
|
28244
|
+
return `${change.secret} may now reach ${list4(change.paths)} on ${change.domain}`;
|
|
28245
|
+
case "exec": {
|
|
28246
|
+
const line = execLine(change.grant);
|
|
28247
|
+
return `${change.secret}: ${line[0].toLowerCase()}${line.slice(1)}`;
|
|
28248
|
+
}
|
|
28249
|
+
case "exit":
|
|
28250
|
+
return `${change.secret} may now leave through ${exitLabel(change.exit, devices)}`;
|
|
28251
|
+
default:
|
|
28252
|
+
return `The limit ${change.field} rose from ${change.from} to ${change.to}`;
|
|
28253
|
+
}
|
|
28254
|
+
}
|
|
28255
|
+
function shown2(element2, style = getComputedStyle(element2)) {
|
|
28256
|
+
return !element2.hidden && !element2.inert && style.display !== "none";
|
|
28257
|
+
}
|
|
28258
|
+
function disabled(element2) {
|
|
28259
|
+
if (element2.matches(":disabled")) return true;
|
|
28260
|
+
if (!element2.matches("button, input, select, textarea")) return false;
|
|
28261
|
+
let fieldset = element2.closest("fieldset[disabled]");
|
|
28262
|
+
while (fieldset) {
|
|
28263
|
+
if (!fieldset.querySelector(":scope > legend")?.contains(element2)) return true;
|
|
28264
|
+
fieldset = fieldset.parentElement?.closest("fieldset[disabled]") ?? null;
|
|
28265
|
+
}
|
|
28266
|
+
return false;
|
|
28267
|
+
}
|
|
28268
|
+
function reachable(element2) {
|
|
28269
|
+
const radio = element2;
|
|
28270
|
+
if (radio.localName !== "input" || radio.type !== "radio" || !radio.name) return true;
|
|
28271
|
+
const root2 = radio.getRootNode();
|
|
28272
|
+
const group = Array.from(root2.querySelectorAll("input[type=radio]")).filter(
|
|
28273
|
+
(other) => other.name === radio.name && other.form === radio.form
|
|
28274
|
+
);
|
|
28275
|
+
const checked = group.find((other) => other.checked);
|
|
28276
|
+
return checked ? checked === radio : radio === group[0] || radio === group.at(-1);
|
|
28277
|
+
}
|
|
28278
|
+
function tabbables(root2, stop, out = []) {
|
|
28279
|
+
for (const child of Array.from(root2.children)) {
|
|
28280
|
+
if (child === stop) {
|
|
28281
|
+
out.push(null);
|
|
28282
|
+
continue;
|
|
28283
|
+
}
|
|
28284
|
+
const style = getComputedStyle(child);
|
|
28285
|
+
if (!shown2(child, style)) continue;
|
|
28286
|
+
if (child.localName === "details" && !child.open) {
|
|
28287
|
+
const summary = child.querySelector(":scope > summary");
|
|
28288
|
+
if (summary && shown2(summary) && getComputedStyle(summary).visibility !== "hidden" && !(summary.hasAttribute("tabindex") && summary.tabIndex < 0))
|
|
28289
|
+
out.push(summary);
|
|
28290
|
+
continue;
|
|
28291
|
+
}
|
|
28292
|
+
if (child.tabIndex >= 0 && !disabled(child) && style.visibility !== "hidden" && reachable(child))
|
|
28293
|
+
out.push(child);
|
|
28294
|
+
if (child.shadowRoot) tabbables(child.shadowRoot, stop, out);
|
|
28295
|
+
tabbables(child, stop, out);
|
|
28296
|
+
}
|
|
28297
|
+
return out;
|
|
28298
|
+
}
|
|
28299
|
+
function sequential(order) {
|
|
28300
|
+
const rank = (element2) => element2 && element2.tabIndex > 0 ? element2.tabIndex : Number.POSITIVE_INFINITY;
|
|
28301
|
+
return [...order].sort((a22, b13) => rank(a22) - rank(b13) || 0);
|
|
28302
|
+
}
|
|
28303
|
+
var SliccVaultButton = class extends i2 {
|
|
28304
|
+
static properties = {
|
|
28305
|
+
vault: { attribute: false },
|
|
28306
|
+
config: { attribute: false }
|
|
28307
|
+
};
|
|
28308
|
+
#button = null;
|
|
28309
|
+
#off = null;
|
|
28310
|
+
#ready = false;
|
|
28311
|
+
#sent = "";
|
|
28312
|
+
static styles = i`
|
|
28313
|
+
:host {
|
|
28314
|
+
display: inline-flex;
|
|
28315
|
+
vertical-align: middle;
|
|
28316
|
+
}
|
|
28317
|
+
iframe {
|
|
28318
|
+
border: 0;
|
|
28319
|
+
background: transparent;
|
|
28320
|
+
color-scheme: normal;
|
|
28321
|
+
}
|
|
28322
|
+
`;
|
|
28323
|
+
constructor() {
|
|
28324
|
+
super();
|
|
28325
|
+
this.vault = null;
|
|
28326
|
+
this.config = null;
|
|
28327
|
+
}
|
|
28328
|
+
connectedCallback() {
|
|
28329
|
+
super.connectedCallback();
|
|
28330
|
+
this.requestUpdate();
|
|
28331
|
+
}
|
|
28332
|
+
disconnectedCallback() {
|
|
28333
|
+
super.disconnectedCallback();
|
|
28334
|
+
this.#drop();
|
|
28335
|
+
}
|
|
28336
|
+
focus() {
|
|
28337
|
+
this.#button?.post({ type: "slicc-vault", v: 1, op: "focus" });
|
|
28338
|
+
}
|
|
28339
|
+
updated(changed) {
|
|
28340
|
+
if (changed.has("vault")) this.#drop();
|
|
28341
|
+
if (!this.#button && this.vault) this.#mount(this.vault);
|
|
28342
|
+
this.#send();
|
|
28343
|
+
}
|
|
28344
|
+
#mount(vault) {
|
|
28345
|
+
const button = vault.button();
|
|
28346
|
+
this.#button = button;
|
|
28347
|
+
this.#off = button.listen((event2) => this.#event(event2));
|
|
28348
|
+
this.renderRoot.append(button.element);
|
|
28349
|
+
}
|
|
28350
|
+
#drop() {
|
|
28351
|
+
this.#off?.();
|
|
28352
|
+
this.#button?.element.remove();
|
|
28353
|
+
this.#button = null;
|
|
28354
|
+
this.#off = null;
|
|
28355
|
+
this.#ready = false;
|
|
28356
|
+
this.#sent = "";
|
|
28357
|
+
}
|
|
28358
|
+
#send() {
|
|
28359
|
+
if (!(this.#ready && this.#button && this.config)) return;
|
|
28360
|
+
const sent = JSON.stringify(this.config);
|
|
28361
|
+
if (sent === this.#sent) return;
|
|
28362
|
+
this.#sent = sent;
|
|
28363
|
+
this.#button.post({ type: "slicc-vault", v: 1, op: "button", button: this.config });
|
|
28364
|
+
}
|
|
28365
|
+
#event(event2) {
|
|
28366
|
+
const element2 = this.#button?.element;
|
|
28367
|
+
if (event2.event === "ready") {
|
|
28368
|
+
this.#ready = true;
|
|
28369
|
+
this.#send();
|
|
28370
|
+
} else if (event2.event === "size") {
|
|
28371
|
+
element2.style.width = `${event2.width}px`;
|
|
28372
|
+
element2.style.height = `${event2.height}px`;
|
|
28373
|
+
element2.style.margin = `${-event2.inset}px`;
|
|
28374
|
+
} else if (event2.event === "label") {
|
|
28375
|
+
element2.title = event2.label;
|
|
28376
|
+
} else if (event2.event === "focus") {
|
|
28377
|
+
const order = sequential(tabbables(this.ownerDocument, this));
|
|
28378
|
+
const at = order.indexOf(null);
|
|
28379
|
+
order[event2.direction === "next" ? at + 1 : at - 1]?.focus();
|
|
28380
|
+
} else if (event2.event === "popup") {
|
|
28381
|
+
const { intent, state: state3, result } = event2;
|
|
28382
|
+
this.dispatchEvent(
|
|
28383
|
+
new CustomEvent("vault-popup", {
|
|
28384
|
+
detail: { intent, state: state3, ...result ? { result } : {} },
|
|
28385
|
+
bubbles: true,
|
|
28386
|
+
composed: true
|
|
28387
|
+
})
|
|
28388
|
+
);
|
|
28389
|
+
}
|
|
28390
|
+
}
|
|
28391
|
+
};
|
|
28392
|
+
|
|
28393
|
+
// src/app/secrets.ts
|
|
28394
|
+
var kinds = { secret: null, grant: "Sign-in", model: "Model key", mcp: "MCP server" };
|
|
28395
|
+
var lockModes = {
|
|
28396
|
+
auto: "Unlocks with this browser",
|
|
28397
|
+
passkey: "Unlocks with a passkey",
|
|
28398
|
+
passphrase: "Unlocks with a passphrase"
|
|
28399
|
+
};
|
|
28400
|
+
function until(at, now = Date.now()) {
|
|
28401
|
+
const minutes = Math.ceil((at - now) / 6e4);
|
|
28402
|
+
if (minutes <= 0) return "expired";
|
|
28403
|
+
if (minutes < 60) return `in ${minutes} min`;
|
|
28404
|
+
const hours = Math.round(minutes / 60);
|
|
28405
|
+
if (hours < 24) return `in ${hours} h`;
|
|
28406
|
+
const days = Math.round(hours / 24);
|
|
28407
|
+
return `in ${days} ${days === 1 ? "day" : "days"}`;
|
|
28408
|
+
}
|
|
28409
|
+
function who(entry) {
|
|
28410
|
+
if (entry.tag) return entry.tag;
|
|
28411
|
+
if (entry.uid === null) return "the vault";
|
|
28412
|
+
return entry.uid === 0 ? "root" : `uid ${entry.uid}`;
|
|
28413
|
+
}
|
|
28414
|
+
function sourceLine(secret, devices) {
|
|
28415
|
+
const on = secret.sourceDevice ? ` on ${deviceName2(secret.sourceDevice, devices)}` : "";
|
|
28416
|
+
const [kind, detail = ""] = secret.source.split(/:(.*)/s);
|
|
28417
|
+
if (kind === "popup") return `Entered in the vault${on}`;
|
|
28418
|
+
if (kind === "process") return `Saved by a program${on}`;
|
|
28419
|
+
if (kind === "import") return `Imported from ${detail}`;
|
|
28420
|
+
if (kind === "oauth") {
|
|
28421
|
+
const as = secret.account ? ` as ${secret.account}` : "";
|
|
28422
|
+
return `Signed in to ${secret.provider ?? detail}${as}`;
|
|
28423
|
+
}
|
|
28424
|
+
return `A jerk lease for ${detail.split("@")[0]}${on}`;
|
|
28425
|
+
}
|
|
28426
|
+
function startOfDay(now) {
|
|
28427
|
+
const date = new Date(now);
|
|
28428
|
+
date.setHours(0, 0, 0, 0);
|
|
28429
|
+
return date.getTime();
|
|
28430
|
+
}
|
|
28431
|
+
function revealed(name, entries, now = Date.now(), more = false) {
|
|
28432
|
+
const reveals = entries.filter(
|
|
28433
|
+
(entry) => entry.type === "materialize" && entry.name === name
|
|
28434
|
+
);
|
|
28435
|
+
if (!reveals.length) return null;
|
|
28436
|
+
const [last] = reveals;
|
|
28437
|
+
const start = startOfDay(now);
|
|
28438
|
+
const today = reveals.filter((entry) => entry.at >= start).length;
|
|
28439
|
+
const partial = more && (entries[entries.length - 1]?.at ?? 0) >= start;
|
|
28440
|
+
const when = today ? `${partial ? "at least " : ""}${today} ${today === 1 ? "time" : "times"} today` : since(last.at, now);
|
|
28441
|
+
return b`Revealed to programs ${when}, last by ${who(last)} with <code>${last.argv}</code>`;
|
|
28442
|
+
}
|
|
28443
|
+
function auditLine(entry, devices) {
|
|
28444
|
+
switch (entry.type) {
|
|
28445
|
+
case "inject":
|
|
28446
|
+
case "forward":
|
|
28447
|
+
return b`${entry.type === "inject" ? "Sent to" : "Forwarded to"} ${entry.domain}: <code>${entry.method} ${entry.path}</code>, through ${exitLabel(entry.exit, devices)}`;
|
|
28448
|
+
case "materialize":
|
|
28449
|
+
return b`Revealed to <code>${entry.argv}</code> in <code>${entry.cwd}</code>`;
|
|
28450
|
+
case "seal":
|
|
28451
|
+
return b`${entry.rotated ? "Value replaced" : "Value saved"}`;
|
|
28452
|
+
case "remove":
|
|
28453
|
+
return b`Removed`;
|
|
28454
|
+
case "restore":
|
|
28455
|
+
return b`Restored`;
|
|
28456
|
+
default: {
|
|
28457
|
+
const count = entry.widened.length;
|
|
28458
|
+
const widened = count ? `, widening ${count} ${count === 1 ? "rule" : "rules"}` : "";
|
|
28459
|
+
return b`<code>${entry.file}</code> ${entry.accepted ? `changed${widened}` : "changed and was refused"}${entry.warning ? b`. ${entry.warning}` : A}`;
|
|
28460
|
+
}
|
|
28461
|
+
}
|
|
28462
|
+
}
|
|
28463
|
+
function merged(...pages) {
|
|
28464
|
+
const bySeq = /* @__PURE__ */ new Map();
|
|
28465
|
+
for (const page of pages) for (const entry of page) bySeq.set(entry.seq, entry);
|
|
28466
|
+
return [...bySeq.values()].sort((a22, b13) => b13.seq - a22.seq);
|
|
28467
|
+
}
|
|
28468
|
+
function prompt2(text2) {
|
|
28469
|
+
return text2.length > 200 ? `${text2.slice(0, 199)}\u2026` : text2;
|
|
28470
|
+
}
|
|
28471
|
+
var SliccSecrets = class extends ThemedElement {
|
|
28472
|
+
static properties = {
|
|
28473
|
+
...ThemedElement.properties,
|
|
28474
|
+
older: { state: true },
|
|
28475
|
+
more: { state: true },
|
|
28476
|
+
loading: { state: true },
|
|
28477
|
+
reveals: { state: true },
|
|
28478
|
+
popup: { state: true },
|
|
28479
|
+
acking: { state: true },
|
|
28480
|
+
failure: { state: true }
|
|
28481
|
+
};
|
|
28482
|
+
#tick;
|
|
28483
|
+
constructor() {
|
|
28484
|
+
super();
|
|
28485
|
+
this.older = [];
|
|
28486
|
+
this.more = null;
|
|
28487
|
+
this.loading = false;
|
|
28488
|
+
this.reveals = false;
|
|
28489
|
+
this.popup = null;
|
|
28490
|
+
this.acking = /* @__PURE__ */ new Set();
|
|
28491
|
+
this.failure = null;
|
|
28492
|
+
}
|
|
28493
|
+
static styles = i`
|
|
28494
|
+
:host {
|
|
28495
|
+
display: block;
|
|
28496
|
+
container-type: inline-size;
|
|
28497
|
+
}
|
|
28498
|
+
h2 {
|
|
28499
|
+
font-size: var(--swc-heading-size-xs);
|
|
28500
|
+
font-weight: var(--swc-bold-font-weight);
|
|
28501
|
+
line-height: var(--swc-heading-line-height);
|
|
28502
|
+
color: var(--swc-heading-color);
|
|
28503
|
+
margin: 0;
|
|
28504
|
+
}
|
|
28505
|
+
h3 {
|
|
28506
|
+
font-size: var(--swc-font-size-100);
|
|
28507
|
+
font-weight: var(--swc-bold-font-weight);
|
|
28508
|
+
color: var(--swc-heading-color);
|
|
28509
|
+
margin: var(--swc-spacing-400) 0 var(--swc-spacing-100);
|
|
28510
|
+
}
|
|
28511
|
+
p {
|
|
28512
|
+
margin: var(--swc-spacing-100) 0;
|
|
28513
|
+
}
|
|
28514
|
+
ul,
|
|
28515
|
+
ol {
|
|
28516
|
+
list-style: none;
|
|
28517
|
+
margin: 0;
|
|
28518
|
+
padding: 0;
|
|
28519
|
+
}
|
|
28520
|
+
code {
|
|
28521
|
+
font-family: var(--swc-code-font-family, ui-monospace, monospace);
|
|
28522
|
+
font-size: 0.9em;
|
|
28523
|
+
overflow-wrap: anywhere;
|
|
28524
|
+
}
|
|
28525
|
+
.head {
|
|
28526
|
+
display: flex;
|
|
28527
|
+
flex-wrap: wrap;
|
|
28528
|
+
align-items: baseline;
|
|
28529
|
+
gap: var(--swc-spacing-200) var(--swc-spacing-300);
|
|
28530
|
+
margin: var(--swc-spacing-500) 0 var(--swc-spacing-200);
|
|
28531
|
+
}
|
|
28532
|
+
.head slicc-vault-button {
|
|
28533
|
+
align-self: center;
|
|
28534
|
+
margin-inline-start: auto;
|
|
28535
|
+
}
|
|
28536
|
+
.muted {
|
|
28537
|
+
color: var(--swc-neutral-subdued-content-color-default);
|
|
28538
|
+
}
|
|
28539
|
+
.box {
|
|
28540
|
+
display: grid;
|
|
28541
|
+
gap: var(--swc-spacing-100);
|
|
28542
|
+
padding: var(--swc-spacing-200) var(--swc-spacing-300);
|
|
28543
|
+
margin: var(--swc-spacing-200) 0;
|
|
28544
|
+
border-radius: var(--swc-corner-radius-100);
|
|
28545
|
+
border: var(--swc-border-width-100) solid var(--swc-gray-200);
|
|
28546
|
+
background: var(--swc-background-layer-1-color);
|
|
28547
|
+
}
|
|
28548
|
+
.box.notice {
|
|
28549
|
+
border-color: var(--swc-notice-visual-color);
|
|
28550
|
+
--swc-icon-color: var(--swc-notice-visual-color);
|
|
28551
|
+
}
|
|
28552
|
+
.box .title {
|
|
28553
|
+
display: flex;
|
|
28554
|
+
align-items: flex-start;
|
|
28555
|
+
gap: var(--swc-spacing-100);
|
|
28556
|
+
font-weight: var(--swc-bold-font-weight);
|
|
28557
|
+
}
|
|
28558
|
+
.box ul {
|
|
28559
|
+
list-style: disc;
|
|
28560
|
+
padding-inline-start: var(--swc-spacing-400);
|
|
28561
|
+
}
|
|
28562
|
+
.box .actions {
|
|
28563
|
+
display: flex;
|
|
28564
|
+
flex-wrap: wrap;
|
|
28565
|
+
align-items: center;
|
|
28566
|
+
gap: var(--swc-spacing-200);
|
|
28567
|
+
}
|
|
28568
|
+
.prompt {
|
|
28569
|
+
margin: 0;
|
|
28570
|
+
padding-inline-start: var(--swc-spacing-200);
|
|
28571
|
+
border-inline-start: var(--swc-border-width-200) solid var(--swc-gray-300);
|
|
28572
|
+
overflow-wrap: anywhere;
|
|
28573
|
+
}
|
|
28574
|
+
.said {
|
|
28575
|
+
white-space: pre-wrap;
|
|
28576
|
+
}
|
|
28577
|
+
.from {
|
|
28578
|
+
display: block;
|
|
28579
|
+
font-size: var(--swc-font-size-75);
|
|
28580
|
+
color: var(--swc-neutral-subdued-content-color-default);
|
|
28581
|
+
}
|
|
28582
|
+
.secrets {
|
|
28583
|
+
display: grid;
|
|
28584
|
+
gap: var(--swc-spacing-200);
|
|
28585
|
+
}
|
|
28586
|
+
.secret {
|
|
28587
|
+
display: grid;
|
|
28588
|
+
grid-template-columns: minmax(0, 1fr) max-content;
|
|
28589
|
+
gap: var(--swc-spacing-100) var(--swc-spacing-300);
|
|
28590
|
+
padding: var(--swc-spacing-200) 0;
|
|
28591
|
+
border-top: var(--swc-border-width-100) solid var(--swc-gray-200);
|
|
28592
|
+
}
|
|
28593
|
+
.secret:first-child {
|
|
28594
|
+
border-top: 0;
|
|
28595
|
+
}
|
|
28596
|
+
.name {
|
|
28597
|
+
display: flex;
|
|
28598
|
+
flex-wrap: wrap;
|
|
28599
|
+
align-items: baseline;
|
|
28600
|
+
gap: var(--swc-spacing-100) var(--swc-spacing-200);
|
|
28601
|
+
min-width: 0;
|
|
28602
|
+
}
|
|
28603
|
+
.name code {
|
|
28604
|
+
font-size: var(--swc-font-size-100);
|
|
28605
|
+
font-weight: var(--swc-bold-font-weight);
|
|
28606
|
+
}
|
|
28607
|
+
.secret slicc-vault-button {
|
|
28608
|
+
align-self: start;
|
|
28609
|
+
}
|
|
28610
|
+
.removed {
|
|
28611
|
+
margin-top: var(--swc-spacing-200);
|
|
28612
|
+
border-top: var(--swc-border-width-100) solid var(--swc-gray-200);
|
|
28613
|
+
padding-top: var(--swc-spacing-200);
|
|
28614
|
+
}
|
|
28615
|
+
.removed summary {
|
|
28616
|
+
cursor: pointer;
|
|
28617
|
+
font-size: var(--swc-font-size-75);
|
|
28618
|
+
color: var(--swc-neutral-subdued-content-color-default);
|
|
28619
|
+
}
|
|
28620
|
+
.removed .secret dl,
|
|
28621
|
+
.removed .secret .name code {
|
|
28622
|
+
color: var(--swc-neutral-subdued-content-color-default);
|
|
28623
|
+
}
|
|
28624
|
+
dl {
|
|
28625
|
+
grid-column: 1 / -1;
|
|
28626
|
+
display: grid;
|
|
28627
|
+
grid-template-columns: max-content minmax(0, 1fr);
|
|
28628
|
+
gap: var(--swc-spacing-50) var(--swc-spacing-300);
|
|
28629
|
+
margin: 0;
|
|
28630
|
+
font-size: var(--swc-font-size-75);
|
|
28631
|
+
line-height: var(--swc-line-height-200);
|
|
28632
|
+
}
|
|
28633
|
+
dt {
|
|
28634
|
+
color: var(--swc-neutral-subdued-content-color-default);
|
|
28635
|
+
}
|
|
28636
|
+
dd {
|
|
28637
|
+
margin: 0;
|
|
28638
|
+
min-width: 0;
|
|
28639
|
+
overflow-wrap: anywhere;
|
|
28640
|
+
}
|
|
28641
|
+
.audit-head {
|
|
28642
|
+
display: flex;
|
|
28643
|
+
flex-wrap: wrap;
|
|
28644
|
+
align-items: baseline;
|
|
28645
|
+
justify-content: space-between;
|
|
28646
|
+
gap: var(--swc-spacing-200);
|
|
28647
|
+
margin: var(--swc-spacing-400) 0 var(--swc-spacing-100);
|
|
28648
|
+
}
|
|
28649
|
+
.audit-head h3 {
|
|
28650
|
+
margin-block: 0;
|
|
28651
|
+
}
|
|
28652
|
+
.audit li {
|
|
28653
|
+
display: grid;
|
|
28654
|
+
grid-template-columns: 7em minmax(0, 1fr);
|
|
28655
|
+
gap: var(--swc-spacing-50) var(--swc-spacing-300);
|
|
28656
|
+
padding: var(--swc-spacing-100) 0;
|
|
28657
|
+
border-top: var(--swc-border-width-100) solid var(--swc-gray-200);
|
|
28658
|
+
font-size: var(--swc-font-size-75);
|
|
28659
|
+
line-height: var(--swc-line-height-200);
|
|
28660
|
+
}
|
|
28661
|
+
.audit time {
|
|
28662
|
+
color: var(--swc-neutral-subdued-content-color-default);
|
|
28663
|
+
}
|
|
28664
|
+
.audit .what {
|
|
28665
|
+
overflow-wrap: anywhere;
|
|
28666
|
+
}
|
|
28667
|
+
.audit .by {
|
|
28668
|
+
color: var(--swc-neutral-subdued-content-color-default);
|
|
28669
|
+
}
|
|
28670
|
+
.row {
|
|
28671
|
+
display: flex;
|
|
28672
|
+
flex-wrap: wrap;
|
|
28673
|
+
align-items: center;
|
|
28674
|
+
gap: var(--swc-spacing-200);
|
|
28675
|
+
margin-top: var(--swc-spacing-200);
|
|
28676
|
+
}
|
|
28677
|
+
.error {
|
|
28678
|
+
display: flex;
|
|
28679
|
+
align-items: flex-start;
|
|
28680
|
+
gap: var(--swc-spacing-100);
|
|
28681
|
+
color: var(--swc-negative-content-color-default);
|
|
28682
|
+
font-size: var(--swc-font-size-75);
|
|
28683
|
+
--swc-icon-color: var(--swc-negative-content-color-default);
|
|
28684
|
+
}
|
|
28685
|
+
@container (max-width: 480px) {
|
|
28686
|
+
.secret {
|
|
28687
|
+
grid-template-columns: minmax(0, 1fr);
|
|
28688
|
+
}
|
|
28689
|
+
.secret slicc-vault-button {
|
|
28690
|
+
order: 1;
|
|
28691
|
+
justify-self: start;
|
|
28692
|
+
}
|
|
28693
|
+
dl {
|
|
28694
|
+
grid-template-columns: minmax(0, 1fr);
|
|
28695
|
+
}
|
|
28696
|
+
dd {
|
|
28697
|
+
margin-bottom: var(--swc-spacing-75);
|
|
28698
|
+
}
|
|
28699
|
+
.audit li {
|
|
28700
|
+
grid-template-columns: minmax(0, 1fr);
|
|
28701
|
+
}
|
|
28702
|
+
}
|
|
28703
|
+
`;
|
|
28704
|
+
#pushed = [];
|
|
28705
|
+
disconnectedCallback() {
|
|
28706
|
+
super.disconnectedCallback();
|
|
28707
|
+
clearTimeout(this.#tick);
|
|
28708
|
+
this.older = [];
|
|
28709
|
+
this.more = null;
|
|
28710
|
+
this.#pushed = [];
|
|
28711
|
+
}
|
|
28712
|
+
willUpdate(changed) {
|
|
28713
|
+
super.willUpdate(changed);
|
|
28714
|
+
const before = changed.get("model");
|
|
28715
|
+
if (!changed.has("model") || before?.vault === this.model?.vault) return;
|
|
28716
|
+
this.older = [];
|
|
28717
|
+
this.more = null;
|
|
28718
|
+
this.loading = false;
|
|
28719
|
+
this.popup = null;
|
|
28720
|
+
this.acking = /* @__PURE__ */ new Set();
|
|
28721
|
+
this.failure = null;
|
|
28722
|
+
this.#pushed = [];
|
|
28723
|
+
}
|
|
28724
|
+
updated() {
|
|
28725
|
+
clearTimeout(this.#tick);
|
|
28726
|
+
if (!this.isConnected) return;
|
|
28727
|
+
const now = Date.now();
|
|
28728
|
+
const next = Math.min(
|
|
28729
|
+
now + 6e4,
|
|
28730
|
+
...(this.model?.vault?.list()?.secrets ?? []).map((secret) => secret.expiresAt ?? Number.POSITIVE_INFINITY).filter((at) => at > now)
|
|
28731
|
+
);
|
|
28732
|
+
this.#tick = setTimeout(() => this.requestUpdate(), next - now);
|
|
28733
|
+
}
|
|
28734
|
+
#listed(vault) {
|
|
28735
|
+
this.#pushed = [];
|
|
28736
|
+
const head2 = vault.list()?.audit ?? [];
|
|
28737
|
+
const last = head2[head2.length - 1];
|
|
28738
|
+
if (this.older.length && (!last || last.seq > this.older[0].seq + 1)) {
|
|
28739
|
+
this.older = [];
|
|
28740
|
+
this.more = null;
|
|
28741
|
+
}
|
|
28742
|
+
this.requestUpdate();
|
|
28743
|
+
}
|
|
28744
|
+
#noticed(notice) {
|
|
28745
|
+
this.#pushed = [...this.#pushed.filter((item2) => item2.id !== notice.id), notice];
|
|
28746
|
+
this.requestUpdate();
|
|
28747
|
+
}
|
|
28748
|
+
subscribe(model) {
|
|
28749
|
+
const update = () => this.requestUpdate();
|
|
28750
|
+
return [
|
|
28751
|
+
...super.subscribe(model),
|
|
28752
|
+
...model.vault ? [
|
|
28753
|
+
model.vault.on("status", update),
|
|
28754
|
+
model.vault.on("list", () => this.#listed(model.vault)),
|
|
28755
|
+
model.vault.on("notice", (notice) => this.#noticed(notice))
|
|
28756
|
+
] : [],
|
|
28757
|
+
...model.network ? [model.network.on("network", update)] : []
|
|
28758
|
+
];
|
|
28759
|
+
}
|
|
28760
|
+
#button(config) {
|
|
28761
|
+
const theme3 = this.color;
|
|
28762
|
+
return b`<slicc-vault-button
|
|
28763
|
+
.vault=${this.model?.vault}
|
|
28764
|
+
.config=${{ size: "m", variant: "secondary", ...config, theme: theme3 }}
|
|
28765
|
+
@vault-popup=${(event2) => this.#popup(event2.detail)}
|
|
28766
|
+
></slicc-vault-button>`;
|
|
28767
|
+
}
|
|
28768
|
+
#popup(detail) {
|
|
28769
|
+
this.popup = detail;
|
|
28770
|
+
}
|
|
28771
|
+
async showOlder(vault, entries) {
|
|
28772
|
+
this.loading = true;
|
|
28773
|
+
this.failure = null;
|
|
28774
|
+
try {
|
|
28775
|
+
const before = entries[entries.length - 1]?.seq;
|
|
28776
|
+
const page = await vault.audit(before);
|
|
28777
|
+
if (this.model?.vault !== vault || !this.isConnected) return;
|
|
28778
|
+
const shown3 = merged(vault.list()?.audit ?? [], this.older);
|
|
28779
|
+
if (shown3[shown3.length - 1]?.seq !== before) return;
|
|
28780
|
+
this.older = merged(this.older, page.audit);
|
|
28781
|
+
this.more = page.more;
|
|
28782
|
+
} catch (error) {
|
|
28783
|
+
if (this.model?.vault === vault && this.isConnected) this.failure = error.message;
|
|
28784
|
+
} finally {
|
|
28785
|
+
if (this.model?.vault === vault) this.loading = false;
|
|
28786
|
+
}
|
|
28787
|
+
}
|
|
28788
|
+
async acknowledge(vault, notice) {
|
|
28789
|
+
if (this.acking.has(notice.id)) return;
|
|
28790
|
+
this.acking = /* @__PURE__ */ new Set([...this.acking, notice.id]);
|
|
28791
|
+
this.failure = null;
|
|
28792
|
+
try {
|
|
28793
|
+
await vault.acknowledge(notice.id);
|
|
28794
|
+
if (this.model?.vault === vault)
|
|
28795
|
+
this.#pushed = this.#pushed.filter((item2) => item2.id !== notice.id);
|
|
28796
|
+
} catch (error) {
|
|
28797
|
+
if (this.model?.vault === vault && this.isConnected) this.failure = error.message;
|
|
28798
|
+
} finally {
|
|
28799
|
+
if (this.model?.vault === vault)
|
|
28800
|
+
this.acking = new Set([...this.acking].filter((id) => id !== notice.id));
|
|
28801
|
+
}
|
|
28802
|
+
}
|
|
28803
|
+
#request(request2) {
|
|
28804
|
+
const asker = who(request2);
|
|
28805
|
+
const what = request2.kind === "value" ? b`${asker} asks for <code>${request2.name}</code>` : request2.kind === "oauth" ? b`${asker} asks you to sign in to ${request2.provider}` : b`${asker} asks for a jerk lease for ${request2.provider}`;
|
|
28806
|
+
return b`<div class="box" data-request=${request2.id}>
|
|
28807
|
+
<span class="title">${what}</span>
|
|
28808
|
+
${request2.prompt ? b`<p class="prompt" data-prompt><span class="from">From the agent, not checked by SLICC:</span> <span class="said">${prompt2(request2.prompt)}</span></p>` : A}
|
|
28809
|
+
<div class="actions">
|
|
28810
|
+
${this.#button({ intent: { kind: "request", request: request2.id }, label: "Answer in the vault", variant: "accent" })}
|
|
28811
|
+
<span class="muted">Expires ${until(request2.expiresAt)}</span>
|
|
28812
|
+
</div>
|
|
28813
|
+
</div>`;
|
|
28814
|
+
}
|
|
28815
|
+
#notice(vault, notice, devices) {
|
|
28816
|
+
return b`<div class="box notice" role="alert" data-notice=${notice.id}>
|
|
28817
|
+
<span class="title"><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><span>Rules widened in <code>${notice.file}</code> ${since(notice.at)}</span></span>
|
|
28818
|
+
<ul>${notice.widened.map((change) => b`<li>${widening(change, devices)}</li>`)}</ul>
|
|
28819
|
+
<span>If you didn’t mean this, change the file back with sudo.</span>
|
|
28820
|
+
<div class="actions"><swc-button size="s" variant="secondary" data-action="acknowledge" ?pending=${this.acking.has(notice.id)} @click=${() => this.acknowledge(vault, notice)}>Acknowledge</swc-button></div>
|
|
28821
|
+
</div>`;
|
|
28822
|
+
}
|
|
28823
|
+
#state(secret) {
|
|
28824
|
+
const [variant, label] = secret.state === "removed" ? ["neutral", "Removed"] : secret.expiresAt !== void 0 && secret.expiresAt <= Date.now() ? ["notice", "Expired"] : secret.state === "inert" ? ["neutral", "No rule yet"] : ["positive", "Active"];
|
|
28825
|
+
return b`<swc-status-light size="s" variant=${variant}>${label}</swc-status-light>`;
|
|
28826
|
+
}
|
|
28827
|
+
#action(secret) {
|
|
28828
|
+
if (secret.state === "removed")
|
|
28829
|
+
return this.#button({
|
|
28830
|
+
intent: { kind: "manage", name: secret.name },
|
|
28831
|
+
label: "Manage",
|
|
28832
|
+
size: "s"
|
|
28833
|
+
});
|
|
28834
|
+
if (secret.source.startsWith("oauth:"))
|
|
28835
|
+
return this.#button({
|
|
28836
|
+
intent: { kind: "signin", provider: secret.source.slice("oauth:".length) },
|
|
28837
|
+
label: "Sign in again",
|
|
28838
|
+
size: "s"
|
|
28839
|
+
});
|
|
28840
|
+
return this.#button({
|
|
28841
|
+
intent: { kind: "enter", name: secret.name },
|
|
28842
|
+
label: "Replace value",
|
|
28843
|
+
size: "s"
|
|
28844
|
+
});
|
|
28845
|
+
}
|
|
28846
|
+
#secret(secret, entries, devices, more) {
|
|
28847
|
+
const kind = kinds[secret.kind];
|
|
28848
|
+
const reveal = revealed(secret.name, entries, Date.now(), more);
|
|
28849
|
+
const gone2 = secret.state === "removed";
|
|
28850
|
+
return b`<li class="secret" data-secret=${secret.name} data-state=${secret.state}>
|
|
28851
|
+
<div class="name">
|
|
28852
|
+
<code>${secret.name}</code>
|
|
28853
|
+
${kind ? b`<swc-badge size="s" variant="neutral" subtle>${kind}</swc-badge>` : A}
|
|
28854
|
+
${this.#state(secret)}
|
|
28855
|
+
</div>
|
|
28856
|
+
${this.#action(secret)}
|
|
28857
|
+
<dl>
|
|
28858
|
+
<dt>${gone2 ? "Was sent to" : "Sent to"}</dt>
|
|
28859
|
+
<dd data-rules>${secret.rules.length ? secret.rules.map((rule, index) => b`${index ? b`<br />` : A}${ruleLine(rule)}`) : "Nowhere yet: no rule names it"}</dd>
|
|
28860
|
+
<dt>${gone2 ? "Left through" : "Leaves through"}</dt>
|
|
28861
|
+
<dd data-exits>${list4(secret.exits.map((exit) => exitLabel(exit, devices)))}</dd>
|
|
28862
|
+
<dt>Programs</dt>
|
|
28863
|
+
<dd data-exec>${execLine(secret.exec)}${reveal ? b`<br />${reveal}` : A}</dd>
|
|
28864
|
+
<dt>From</dt>
|
|
28865
|
+
<dd data-source>${sourceLine(secret, devices)}</dd>
|
|
28866
|
+
${secret.usedAt ? b`<dt>Last used</dt><dd data-used>${since(secret.usedAt)}</dd>` : A}
|
|
28867
|
+
${secret.expiresAt ? b`<dt>Expires</dt><dd data-expires>${until(secret.expiresAt)}</dd>` : A}
|
|
28868
|
+
${secret.removedAt ? b`<dt>Removed</dt><dd>${since(secret.removedAt)}</dd>` : A}
|
|
28869
|
+
</dl>
|
|
28870
|
+
</li>`;
|
|
28871
|
+
}
|
|
28872
|
+
#secrets(list5, entries, devices) {
|
|
28873
|
+
const more = this.more ?? list5.auditMore;
|
|
28874
|
+
const row = (secret) => this.#secret(secret, entries, devices, more);
|
|
28875
|
+
const live = list5.secrets.filter((secret) => secret.state !== "removed");
|
|
28876
|
+
const removed = list5.secrets.filter((secret) => secret.state === "removed");
|
|
28877
|
+
return b`${live.length ? b`<ul class="secrets" aria-labelledby="secrets">${live.map(row)}</ul>` : A}
|
|
28878
|
+
${removed.length ? b`<details class="removed" data-removed>
|
|
28879
|
+
<summary>Removed (${removed.length})</summary>
|
|
28880
|
+
<ul class="secrets">${removed.map(row)}</ul>
|
|
28881
|
+
</details>` : A}`;
|
|
28882
|
+
}
|
|
28883
|
+
#entry(entry, devices) {
|
|
28884
|
+
const date = new Date(entry.at);
|
|
28885
|
+
const name = entry.type === "policy" ? null : entry.name;
|
|
28886
|
+
return b`<li data-seq=${entry.seq} data-type=${entry.type}>
|
|
28887
|
+
<time datetime=${date.toISOString()} title=${date.toLocaleString("en-GB", { dateStyle: "medium", timeStyle: "short" })}>${since(entry.at)}</time>
|
|
28888
|
+
<span class="what">${name ? b`<code>${name}</code> · ` : A}${auditLine(entry, devices)}${entry.type === "policy" ? A : b` <span class="by">by ${who(entry)}</span>`}</span>
|
|
28889
|
+
</li>`;
|
|
28890
|
+
}
|
|
28891
|
+
#audit(vault, list5, entries, devices) {
|
|
28892
|
+
const shown3 = this.reveals ? entries.filter((entry) => entry.type === "materialize") : entries;
|
|
28893
|
+
const more = this.more ?? list5.auditMore;
|
|
28894
|
+
return b`<div class="audit-head">
|
|
28895
|
+
<h3 id="secrets-audit">Activity</h3>
|
|
28896
|
+
<sp-switch size="s" data-action="reveals" .checked=${this.reveals} @change=${(event2) => {
|
|
28897
|
+
this.reveals = event2.target.checked;
|
|
28898
|
+
}}>Only reveals to programs</sp-switch>
|
|
28899
|
+
</div>
|
|
28900
|
+
${shown3.length ? b`<ol class="audit" aria-labelledby="secrets-audit">${shown3.map((entry) => this.#entry(entry, devices))}</ol>` : b`<p class="muted" data-audit-empty>${this.reveals ? more ? "No reveals in the activity loaded so far." : "No program has been given a secret." : "Nothing has used a secret yet."}</p>`}
|
|
28901
|
+
${more ? b`<div class="row"><swc-button size="s" variant="secondary" fill-style="outline" data-action="older" ?pending=${this.loading} @click=${() => this.showOlder(vault, entries)}>Show older</swc-button></div>` : A}`;
|
|
28902
|
+
}
|
|
28903
|
+
#feedback() {
|
|
28904
|
+
if (this.popup?.state === "blocked")
|
|
28905
|
+
return b`<div class="error" role="alert" data-popup="blocked"><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><span>The browser blocked the vault window. Allow pop-ups for this site, then try again.</span></div>`;
|
|
28906
|
+
if (this.popup?.state === "done" && this.popup.result)
|
|
28907
|
+
return b`<p role="status" data-popup="done">Saved <code>${this.popup.result.name}</code> in the vault.</p>`;
|
|
28908
|
+
return A;
|
|
28909
|
+
}
|
|
28910
|
+
render() {
|
|
28911
|
+
const vault = this.model?.vault;
|
|
28912
|
+
if (!vault) return A;
|
|
28913
|
+
const status2 = vault.status();
|
|
28914
|
+
const current = vault.list();
|
|
28915
|
+
const devices = devicesOf(this.model);
|
|
28916
|
+
const entries = merged(current?.audit ?? [], this.older);
|
|
28917
|
+
const listed = current?.notices ?? [];
|
|
28918
|
+
const notices = [
|
|
28919
|
+
...listed,
|
|
28920
|
+
...this.#pushed.filter((notice) => !listed.some((item2) => item2.id === notice.id))
|
|
28921
|
+
].filter((notice) => !notice.acknowledged);
|
|
28922
|
+
return b`<section aria-labelledby="secrets" data-vault=${status2 ? status2.locked ? "locked" : "unlocked" : "loading"}>
|
|
28923
|
+
<div class="head">
|
|
28924
|
+
<h2 id="secrets">Secrets</h2>
|
|
28925
|
+
${status2 ? b`<swc-status-light size="m" variant=${status2.locked ? "notice" : "positive"}>${status2.locked ? "Locked" : "Unlocked"}</swc-status-light><span class="muted">${lockModes[status2.lock]}</span>` : A}
|
|
28926
|
+
${status2?.locked ? this.#button({ intent: { kind: "unlock" }, label: "Unlock", variant: "accent" }) : this.#button({ intent: { kind: "manage" }, label: "Open the vault" })}
|
|
28927
|
+
</div>
|
|
28928
|
+
<p class="muted">Agents and programs use secrets by name. The values stay in the vault, so SLICC never sees or shows them.</p>
|
|
28929
|
+
${this.#feedback()}
|
|
28930
|
+
${this.failure ? b`<div class="error" role="alert" data-error="vault"><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><span>${this.failure}</span></div>` : A}
|
|
28931
|
+
${status2?.waiting.length ? b`<h3>Waiting for you</h3>${status2.waiting.map((request2) => this.#request(request2))}` : A}
|
|
28932
|
+
${notices.map((notice) => this.#notice(vault, notice, devices))}
|
|
28933
|
+
${!current ? b`<p class="muted" data-loading>Loading secrets…</p>` : current.secrets.length ? this.#secrets(current, entries, devices) : b`<p data-empty>No secrets yet. When an agent or program needs one, it asks here, and you enter the value in the vault.</p>`}
|
|
28934
|
+
<p class="muted" data-policy>Rules live in <code>/etc/fnox/config.toml</code> and <code>/etc/slicc/secrets-policy.toml</code>. Change them with sudo; SLICC asks you before every change.</p>
|
|
28935
|
+
<div class="row">
|
|
28936
|
+
${this.#button({ intent: { kind: "import" }, label: "Import\u2026", size: "s" })}
|
|
28937
|
+
${this.#button({ intent: { kind: "export" }, label: "Export\u2026", size: "s" })}
|
|
28938
|
+
</div>
|
|
28939
|
+
${current ? this.#audit(vault, current, entries, devices) : A}
|
|
28940
|
+
</section>`;
|
|
28941
|
+
}
|
|
28942
|
+
};
|
|
28943
|
+
|
|
27921
28944
|
// src/app/settings.ts
|
|
27922
28945
|
var accountStatus = {
|
|
27923
28946
|
connected: ["positive", "Connected"],
|
|
@@ -28275,6 +29298,7 @@ var SliccSettings = class extends ModelElement {
|
|
|
28275
29298
|
<div class="accounts">${providers.map((account) => this.#account(account))}</div>
|
|
28276
29299
|
${servers.length ? b`<h2>MCP servers</h2>
|
|
28277
29300
|
<div class="accounts" data-group="mcp">${servers.map((account) => this.#account(account))}</div>` : A}
|
|
29301
|
+
${this.model?.vault ? b`<slicc-secrets .model=${this.model}></slicc-secrets>` : A}
|
|
28278
29302
|
</div>`;
|
|
28279
29303
|
}
|
|
28280
29304
|
};
|
|
@@ -31070,14 +32094,14 @@ var RegexSource = class {
|
|
|
31070
32094
|
return CAPTURING_REGEX_SOURCE.test(regexSource);
|
|
31071
32095
|
}
|
|
31072
32096
|
static replaceCaptures(regexSource, captureSource, captureIndices) {
|
|
31073
|
-
return regexSource.replace(CAPTURING_REGEX_SOURCE, (match, index, commandIndex,
|
|
32097
|
+
return regexSource.replace(CAPTURING_REGEX_SOURCE, (match, index, commandIndex, command3) => {
|
|
31074
32098
|
let capture = captureIndices[parseInt(index || commandIndex, 10)];
|
|
31075
32099
|
if (capture) {
|
|
31076
32100
|
let result = captureSource.substring(capture.start, capture.end);
|
|
31077
32101
|
while (result[0] === ".") {
|
|
31078
32102
|
result = result.substring(1);
|
|
31079
32103
|
}
|
|
31080
|
-
switch (
|
|
32104
|
+
switch (command3) {
|
|
31081
32105
|
case "downcase":
|
|
31082
32106
|
return result.toLowerCase();
|
|
31083
32107
|
case "upcase":
|
|
@@ -32091,8 +33115,8 @@ var IncludeOnlyRule = class extends Rule {
|
|
|
32091
33115
|
}
|
|
32092
33116
|
}
|
|
32093
33117
|
collectPatterns(grammar2, out) {
|
|
32094
|
-
for (const
|
|
32095
|
-
const rule = grammar2.getRule(
|
|
33118
|
+
for (const pattern2 of this.patterns) {
|
|
33119
|
+
const rule = grammar2.getRule(pattern2);
|
|
32096
33120
|
rule.collectPatterns(grammar2, out);
|
|
32097
33121
|
}
|
|
32098
33122
|
}
|
|
@@ -32159,8 +33183,8 @@ var BeginEndRule = class extends Rule {
|
|
|
32159
33183
|
_getCachedCompiledPatterns(grammar2, endRegexSource) {
|
|
32160
33184
|
if (!this._cachedCompiledPatterns) {
|
|
32161
33185
|
this._cachedCompiledPatterns = new RegExpSourceList();
|
|
32162
|
-
for (const
|
|
32163
|
-
const rule = grammar2.getRule(
|
|
33186
|
+
for (const pattern2 of this.patterns) {
|
|
33187
|
+
const rule = grammar2.getRule(pattern2);
|
|
32164
33188
|
rule.collectPatterns(grammar2, this._cachedCompiledPatterns);
|
|
32165
33189
|
}
|
|
32166
33190
|
if (this.applyEndPatternLast) {
|
|
@@ -32232,8 +33256,8 @@ var BeginWhileRule = class extends Rule {
|
|
|
32232
33256
|
_getCachedCompiledPatterns(grammar2) {
|
|
32233
33257
|
if (!this._cachedCompiledPatterns) {
|
|
32234
33258
|
this._cachedCompiledPatterns = new RegExpSourceList();
|
|
32235
|
-
for (const
|
|
32236
|
-
const rule = grammar2.getRule(
|
|
33259
|
+
for (const pattern2 of this.patterns) {
|
|
33260
|
+
const rule = grammar2.getRule(pattern2);
|
|
32237
33261
|
rule.collectPatterns(grammar2, this._cachedCompiledPatterns);
|
|
32238
33262
|
}
|
|
32239
33263
|
}
|
|
@@ -32354,14 +33378,14 @@ var RuleFactory = class _RuleFactory {
|
|
|
32354
33378
|
let r39 = [];
|
|
32355
33379
|
if (patterns) {
|
|
32356
33380
|
for (let i25 = 0, len = patterns.length; i25 < len; i25++) {
|
|
32357
|
-
const
|
|
33381
|
+
const pattern2 = patterns[i25];
|
|
32358
33382
|
let ruleId = -1;
|
|
32359
|
-
if (
|
|
32360
|
-
const reference2 = parseInclude(
|
|
33383
|
+
if (pattern2.include) {
|
|
33384
|
+
const reference2 = parseInclude(pattern2.include);
|
|
32361
33385
|
switch (reference2.kind) {
|
|
32362
33386
|
case 0:
|
|
32363
33387
|
case 1:
|
|
32364
|
-
ruleId = _RuleFactory.getCompiledRuleId(repository[
|
|
33388
|
+
ruleId = _RuleFactory.getCompiledRuleId(repository[pattern2.include], helper, repository);
|
|
32365
33389
|
break;
|
|
32366
33390
|
case 2:
|
|
32367
33391
|
let localIncludedRule = repository[reference2.ruleName];
|
|
@@ -32390,7 +33414,7 @@ var RuleFactory = class _RuleFactory {
|
|
|
32390
33414
|
break;
|
|
32391
33415
|
}
|
|
32392
33416
|
} else {
|
|
32393
|
-
ruleId = _RuleFactory.getCompiledRuleId(
|
|
33417
|
+
ruleId = _RuleFactory.getCompiledRuleId(pattern2, helper, repository);
|
|
32394
33418
|
}
|
|
32395
33419
|
if (ruleId !== -1) {
|
|
32396
33420
|
const rule = helper.getRule(ruleId);
|
|
@@ -37233,13 +38257,13 @@ function splitTokens(tokens, breakpoints) {
|
|
|
37233
38257
|
});
|
|
37234
38258
|
});
|
|
37235
38259
|
}
|
|
37236
|
-
function flatTokenVariants(
|
|
38260
|
+
function flatTokenVariants(merged2, variantsOrder, cssVariablePrefix, defaultColor, colorsRendering = "css-vars") {
|
|
37237
38261
|
const token2 = {
|
|
37238
|
-
content:
|
|
37239
|
-
explanation:
|
|
37240
|
-
offset:
|
|
38262
|
+
content: merged2.content,
|
|
38263
|
+
explanation: merged2.explanation,
|
|
38264
|
+
offset: merged2.offset
|
|
37241
38265
|
};
|
|
37242
|
-
const styles = variantsOrder.map((t88) => getTokenStyleObject(
|
|
38266
|
+
const styles = variantsOrder.map((t88) => getTokenStyleObject(merged2.variants[t88]));
|
|
37243
38267
|
const styleKeys = new Set(styles.flatMap((t88) => Object.keys(t88)));
|
|
37244
38268
|
const mergedStyles = {};
|
|
37245
38269
|
const varKey = (idx, key2) => {
|
|
@@ -39349,25 +40373,25 @@ var namedCaptureDelim = r35`\(\?<(?![=!])(?<captureName>[^>]+)>`;
|
|
|
39349
40373
|
var captureDelim = r35`${namedCaptureDelim}|(?<unnamed>\()(?!\?)`;
|
|
39350
40374
|
var token = new RegExp(r35`${namedCaptureDelim}|${recursiveToken}|\(\?|\\?.`, "gsu");
|
|
39351
40375
|
var overlappingRecursionMsg = "Cannot use multiple overlapping recursions";
|
|
39352
|
-
function recursion(
|
|
40376
|
+
function recursion(pattern2, data) {
|
|
39353
40377
|
const { hiddenCaptures, mode } = {
|
|
39354
40378
|
hiddenCaptures: [],
|
|
39355
40379
|
mode: "plugin",
|
|
39356
40380
|
...data
|
|
39357
40381
|
};
|
|
39358
40382
|
let captureTransfers = data?.captureTransfers ?? /* @__PURE__ */ new Map();
|
|
39359
|
-
if (!new RegExp(recursiveToken, "su").test(
|
|
40383
|
+
if (!new RegExp(recursiveToken, "su").test(pattern2)) {
|
|
39360
40384
|
return {
|
|
39361
|
-
pattern,
|
|
40385
|
+
pattern: pattern2,
|
|
39362
40386
|
captureTransfers,
|
|
39363
40387
|
hiddenCaptures
|
|
39364
40388
|
};
|
|
39365
40389
|
}
|
|
39366
|
-
if (mode === "plugin" && hasUnescaped(
|
|
40390
|
+
if (mode === "plugin" && hasUnescaped(pattern2, r35`\(\?\(DEFINE\)`, Context.DEFAULT)) {
|
|
39367
40391
|
throw new Error("DEFINE groups cannot be used with recursion");
|
|
39368
40392
|
}
|
|
39369
40393
|
const addedHiddenCaptures = [];
|
|
39370
|
-
const hasNumberedBackref = hasUnescaped(
|
|
40394
|
+
const hasNumberedBackref = hasUnescaped(pattern2, r35`\\[1-9]`, Context.DEFAULT);
|
|
39371
40395
|
const groupContentsStartPos = /* @__PURE__ */ new Map();
|
|
39372
40396
|
const openGroups = [];
|
|
39373
40397
|
let hasRecursed = false;
|
|
@@ -39375,7 +40399,7 @@ function recursion(pattern, data) {
|
|
|
39375
40399
|
let numCapturesPassed = 0;
|
|
39376
40400
|
let match;
|
|
39377
40401
|
token.lastIndex = 0;
|
|
39378
|
-
while (match = token.exec(
|
|
40402
|
+
while (match = token.exec(pattern2)) {
|
|
39379
40403
|
const { 0: m15, groups: { captureName, rDepth, gRNameOrNum, gRDepth } } = match;
|
|
39380
40404
|
if (m15 === "[") {
|
|
39381
40405
|
numCharClassesOpen++;
|
|
@@ -39392,13 +40416,13 @@ function recursion(pattern, data) {
|
|
|
39392
40416
|
`${mode === "external" ? "Backrefs" : "Numbered backrefs"} cannot be used with global recursion`
|
|
39393
40417
|
);
|
|
39394
40418
|
}
|
|
39395
|
-
const left =
|
|
39396
|
-
const right =
|
|
40419
|
+
const left = pattern2.slice(0, match.index);
|
|
40420
|
+
const right = pattern2.slice(token.lastIndex);
|
|
39397
40421
|
if (hasUnescaped(right, recursiveToken, Context.DEFAULT)) {
|
|
39398
40422
|
throw new Error(overlappingRecursionMsg);
|
|
39399
40423
|
}
|
|
39400
40424
|
const reps = +rDepth - 1;
|
|
39401
|
-
|
|
40425
|
+
pattern2 = makeRecursive(
|
|
39402
40426
|
left,
|
|
39403
40427
|
right,
|
|
39404
40428
|
reps,
|
|
@@ -39432,7 +40456,7 @@ function recursion(pattern, data) {
|
|
|
39432
40456
|
throw new Error(r35`Recursive \g cannot be used outside the referenced group "${mode === "external" ? gRNameOrNum : r35`\g<${gRNameOrNum}&R=${gRDepth}>`}"`);
|
|
39433
40457
|
}
|
|
39434
40458
|
const startPos = groupContentsStartPos.get(gRNameOrNum);
|
|
39435
|
-
const groupContents = getGroupContents(
|
|
40459
|
+
const groupContents = getGroupContents(pattern2, startPos);
|
|
39436
40460
|
if (hasNumberedBackref && hasUnescaped(groupContents, r35`${namedCaptureDelim}|\((?!\?)`, Context.DEFAULT)) {
|
|
39437
40461
|
throw new Error(
|
|
39438
40462
|
// When used in `external` mode by transpilers other than Regex+, backrefs might have
|
|
@@ -39440,11 +40464,11 @@ function recursion(pattern, data) {
|
|
|
39440
40464
|
`${mode === "external" ? "Backrefs" : "Numbered backrefs"} cannot be used with recursion of capturing groups`
|
|
39441
40465
|
);
|
|
39442
40466
|
}
|
|
39443
|
-
const groupContentsLeft =
|
|
40467
|
+
const groupContentsLeft = pattern2.slice(startPos, match.index);
|
|
39444
40468
|
const groupContentsRight = groupContents.slice(groupContentsLeft.length + m15.length);
|
|
39445
40469
|
const numAddedHiddenCapturesPreExpansion = addedHiddenCaptures.length;
|
|
39446
40470
|
const reps = +gRDepth - 1;
|
|
39447
|
-
const
|
|
40471
|
+
const expansion2 = makeRecursive(
|
|
39448
40472
|
groupContentsLeft,
|
|
39449
40473
|
groupContentsRight,
|
|
39450
40474
|
reps,
|
|
@@ -39461,10 +40485,10 @@ function recursion(pattern, data) {
|
|
|
39461
40485
|
numAddedHiddenCapturesPreExpansion,
|
|
39462
40486
|
numCapturesPassed
|
|
39463
40487
|
);
|
|
39464
|
-
const pre =
|
|
39465
|
-
const post =
|
|
39466
|
-
|
|
39467
|
-
token.lastIndex +=
|
|
40488
|
+
const pre = pattern2.slice(0, startPos);
|
|
40489
|
+
const post = pattern2.slice(startPos + groupContents.length);
|
|
40490
|
+
pattern2 = `${pre}${expansion2}${post}`;
|
|
40491
|
+
token.lastIndex += expansion2.length - m15.length - groupContentsLeft.length - groupContentsRight.length;
|
|
39468
40492
|
openGroups.forEach((g7) => g7.hasRecursedWithin = true);
|
|
39469
40493
|
hasRecursed = true;
|
|
39470
40494
|
} else if (captureName) {
|
|
@@ -39491,7 +40515,7 @@ function recursion(pattern, data) {
|
|
|
39491
40515
|
}
|
|
39492
40516
|
hiddenCaptures.push(...addedHiddenCaptures);
|
|
39493
40517
|
return {
|
|
39494
|
-
pattern,
|
|
40518
|
+
pattern: pattern2,
|
|
39495
40519
|
captureTransfers,
|
|
39496
40520
|
hiddenCaptures
|
|
39497
40521
|
};
|
|
@@ -39522,14 +40546,14 @@ function makeRecursive(left, right, reps, isSubpattern, hiddenCaptures, addedHid
|
|
|
39522
40546
|
];
|
|
39523
40547
|
return `${left}${repeatWithDepth(`(?:${left}`, "forward", ...rest)}(?:)${repeatWithDepth(`${right})`, "backward", ...rest)}${right}`;
|
|
39524
40548
|
}
|
|
39525
|
-
function repeatWithDepth(
|
|
40549
|
+
function repeatWithDepth(pattern2, direction, reps, namesInRecursed, hiddenCaptures, addedHiddenCaptures, numCapturesPassed) {
|
|
39526
40550
|
const startNum = 2;
|
|
39527
40551
|
const getDepthNum = (i25) => direction === "forward" ? i25 + startNum : reps - i25 + startNum - 1;
|
|
39528
40552
|
let result = "";
|
|
39529
40553
|
for (let i25 = 0; i25 < reps; i25++) {
|
|
39530
40554
|
const depthNum = getDepthNum(i25);
|
|
39531
40555
|
result += replaceUnescaped(
|
|
39532
|
-
|
|
40556
|
+
pattern2,
|
|
39533
40557
|
r35`${captureDelim}|\\k<(?<backref>[^>]+)>`,
|
|
39534
40558
|
({ 0: m15, groups: { captureName, unnamed, backref } }) => {
|
|
39535
40559
|
if (backref && namesInRecursed && !namesInRecursed.has(backref)) {
|
|
@@ -40612,8 +41636,8 @@ function isLoneGLookaround(node, options) {
|
|
|
40612
41636
|
function isValidJsGroupName(name) {
|
|
40613
41637
|
return /^[$_\p{IDS}][$\u200C\u200D\p{IDC}]*$/u.test(name);
|
|
40614
41638
|
}
|
|
40615
|
-
function parseFragment(
|
|
40616
|
-
const ast = J2(
|
|
41639
|
+
function parseFragment(pattern2, options) {
|
|
41640
|
+
const ast = J2(pattern2, {
|
|
40617
41641
|
...options,
|
|
40618
41642
|
// Providing a custom set of Unicode property names avoids converting some JS Unicode
|
|
40619
41643
|
// properties (ex: `\p{Alpha}`) to Onig POSIX classes
|
|
@@ -41209,13 +42233,13 @@ var EmulatedRegExp = class _EmulatedRegExp extends RegExp {
|
|
|
41209
42233
|
@param {EmulatedRegExp} pattern
|
|
41210
42234
|
@param {string} [flags]
|
|
41211
42235
|
*/
|
|
41212
|
-
constructor(
|
|
42236
|
+
constructor(pattern2, flags, options) {
|
|
41213
42237
|
const lazyCompile = !!options?.lazyCompile;
|
|
41214
|
-
if (
|
|
42238
|
+
if (pattern2 instanceof RegExp) {
|
|
41215
42239
|
if (options) {
|
|
41216
42240
|
throw new Error("Cannot provide options when copying a regexp");
|
|
41217
42241
|
}
|
|
41218
|
-
const re3 =
|
|
42242
|
+
const re3 = pattern2;
|
|
41219
42243
|
super(re3, flags);
|
|
41220
42244
|
this.#pattern = re3.source;
|
|
41221
42245
|
if (re3 instanceof _EmulatedRegExp) {
|
|
@@ -41231,8 +42255,8 @@ var EmulatedRegExp = class _EmulatedRegExp extends RegExp {
|
|
|
41231
42255
|
transfers: [],
|
|
41232
42256
|
...options
|
|
41233
42257
|
};
|
|
41234
|
-
super(lazyCompile ? "" :
|
|
41235
|
-
this.#pattern =
|
|
42258
|
+
super(lazyCompile ? "" : pattern2, flags);
|
|
42259
|
+
this.#pattern = pattern2;
|
|
41236
42260
|
this.#captureMap = createCaptureMap(opts.hiddenCaptures, opts.transfers);
|
|
41237
42261
|
this.#strategy = opts.strategy;
|
|
41238
42262
|
this.rawOptions = options ?? {};
|
|
@@ -41358,13 +42382,13 @@ function createCaptureMap(hiddenCaptures, transfers) {
|
|
|
41358
42382
|
}
|
|
41359
42383
|
return captureMap;
|
|
41360
42384
|
}
|
|
41361
|
-
function createNameMap(
|
|
42385
|
+
function createNameMap(pattern2) {
|
|
41362
42386
|
const re3 = /(?<capture>\((?:\?<(?![=!])(?<name>[^>]+)>|(?!\?)))|\\?./gsu;
|
|
41363
42387
|
const map = /* @__PURE__ */ new Map();
|
|
41364
42388
|
let numCharClassesOpen = 0;
|
|
41365
42389
|
let numCaptures = 0;
|
|
41366
42390
|
let match;
|
|
41367
|
-
while (match = re3.exec(
|
|
42391
|
+
while (match = re3.exec(pattern2)) {
|
|
41368
42392
|
const { 0: m15, groups: { capture, name } } = match;
|
|
41369
42393
|
if (m15 === "[") {
|
|
41370
42394
|
numCharClassesOpen++;
|
|
@@ -41381,16 +42405,16 @@ function createNameMap(pattern) {
|
|
|
41381
42405
|
}
|
|
41382
42406
|
return map;
|
|
41383
42407
|
}
|
|
41384
|
-
function toRegExp(
|
|
41385
|
-
const d22 = toRegExpDetails(
|
|
42408
|
+
function toRegExp(pattern2, options) {
|
|
42409
|
+
const d22 = toRegExpDetails(pattern2, options);
|
|
41386
42410
|
if (d22.options) {
|
|
41387
42411
|
return new EmulatedRegExp(d22.pattern, d22.flags, d22.options);
|
|
41388
42412
|
}
|
|
41389
42413
|
return new RegExp(d22.pattern, d22.flags);
|
|
41390
42414
|
}
|
|
41391
|
-
function toRegExpDetails(
|
|
42415
|
+
function toRegExpDetails(pattern2, options) {
|
|
41392
42416
|
const opts = getOptions(options);
|
|
41393
|
-
const onigurumaAst = J2(
|
|
42417
|
+
const onigurumaAst = J2(pattern2, {
|
|
41394
42418
|
flags: opts.flags,
|
|
41395
42419
|
normalizeUnknownPropertyNames: true,
|
|
41396
42420
|
rules: {
|
|
@@ -41443,8 +42467,8 @@ function toRegExpDetails(pattern, options) {
|
|
|
41443
42467
|
}
|
|
41444
42468
|
|
|
41445
42469
|
// node_modules/@shikijs/engine-javascript/dist/engine-compile.mjs
|
|
41446
|
-
function defaultJavaScriptRegexConstructor(
|
|
41447
|
-
return toRegExp(
|
|
42470
|
+
function defaultJavaScriptRegexConstructor(pattern2, options) {
|
|
42471
|
+
return toRegExp(pattern2, {
|
|
41448
42472
|
global: true,
|
|
41449
42473
|
hasIndices: true,
|
|
41450
42474
|
lazyCompileLength: 3e3,
|
|
@@ -41464,7 +42488,7 @@ function createJavaScriptRegexEngine(options = {}) {
|
|
|
41464
42488
|
cache: /* @__PURE__ */ new Map(),
|
|
41465
42489
|
...options
|
|
41466
42490
|
};
|
|
41467
|
-
_options.regexConstructor ||= (
|
|
42491
|
+
_options.regexConstructor ||= (pattern2) => defaultJavaScriptRegexConstructor(pattern2, { target: _options.target });
|
|
41468
42492
|
return {
|
|
41469
42493
|
createScanner(patterns) {
|
|
41470
42494
|
return new JavaScriptScanner(patterns, _options);
|
|
@@ -42794,8 +43818,8 @@ var InteractionManager = class {
|
|
|
42794
43818
|
const indexes = this.getLineIndex(point.lineNumber, point.side);
|
|
42795
43819
|
if (indexes == null) return;
|
|
42796
43820
|
const lineIndex = this.mode === "diff" ? `${indexes[0]},${indexes[1]}` : `${indexes[0]}`;
|
|
42797
|
-
const
|
|
42798
|
-
for (const element2 of
|
|
43821
|
+
const candidates2 = this.pre.querySelectorAll(`[data-column-number="${point.lineNumber}"][data-line-index="${lineIndex}"]`);
|
|
43822
|
+
for (const element2 of candidates2) {
|
|
42799
43823
|
if (!(element2 instanceof HTMLElement)) continue;
|
|
42800
43824
|
const target = this.resolvePointerTarget(getElementPath(element2));
|
|
42801
43825
|
if (!isLinePointerTarget(target)) continue;
|
|
@@ -44047,6 +45071,7 @@ var EXTENSION_TO_FILE_FORMAT = {
|
|
|
44047
45071
|
mli: "ocaml",
|
|
44048
45072
|
mll: "ocaml",
|
|
44049
45073
|
mly: "ocaml",
|
|
45074
|
+
odin: "odin",
|
|
44050
45075
|
pas: "pascal",
|
|
44051
45076
|
p: "pascal",
|
|
44052
45077
|
pl: "prolog",
|
|
@@ -44079,6 +45104,17 @@ var EXTENSION_TO_FILE_FORMAT = {
|
|
|
44079
45104
|
py: "python",
|
|
44080
45105
|
pyw: "python",
|
|
44081
45106
|
pyi: "python",
|
|
45107
|
+
BUCK: "python",
|
|
45108
|
+
BUILD: "python",
|
|
45109
|
+
PACKAGE: "python",
|
|
45110
|
+
WORKSPACE: "python",
|
|
45111
|
+
Tiltfile: "python",
|
|
45112
|
+
bazel: "python",
|
|
45113
|
+
bxl: "python",
|
|
45114
|
+
bzl: "python",
|
|
45115
|
+
bzlmod: "python",
|
|
45116
|
+
star: "python",
|
|
45117
|
+
sky: "python",
|
|
44082
45118
|
qml: "qml",
|
|
44083
45119
|
qmldir: "qmldir",
|
|
44084
45120
|
qss: "qss",
|
|
@@ -44189,16 +45225,22 @@ var EXTENSION_TO_FILE_FORMAT = {
|
|
|
44189
45225
|
sty: "tex"
|
|
44190
45226
|
};
|
|
44191
45227
|
function getFiletypeFromFileName(fileName) {
|
|
45228
|
+
const format = matchFiletypeFromName(fileName);
|
|
45229
|
+
if (format != null) return format;
|
|
45230
|
+
const baseName = fileName.split(/[/\\]/).pop() ?? fileName;
|
|
45231
|
+
return baseName === fileName ? "text" : matchFiletypeFromName(baseName) ?? "text";
|
|
45232
|
+
}
|
|
45233
|
+
function matchFiletypeFromName(fileName) {
|
|
44192
45234
|
if (CUSTOM_EXTENSION_TO_FILE_FORMAT.has(fileName)) return CUSTOM_EXTENSION_TO_FILE_FORMAT.get(fileName) ?? "text";
|
|
44193
|
-
if (EXTENSION_TO_FILE_FORMAT
|
|
45235
|
+
if (Object.hasOwn(EXTENSION_TO_FILE_FORMAT, fileName)) return EXTENSION_TO_FILE_FORMAT[fileName] ?? null;
|
|
44194
45236
|
const compoundMatch = fileName.match(/\.([^/\\]+\.[^/\\]+)$/);
|
|
44195
45237
|
if (compoundMatch != null) {
|
|
44196
45238
|
if (CUSTOM_EXTENSION_TO_FILE_FORMAT.has(compoundMatch[1])) return CUSTOM_EXTENSION_TO_FILE_FORMAT.get(compoundMatch[1]) ?? "text";
|
|
44197
|
-
if (EXTENSION_TO_FILE_FORMAT
|
|
45239
|
+
if (Object.hasOwn(EXTENSION_TO_FILE_FORMAT, compoundMatch[1])) return EXTENSION_TO_FILE_FORMAT[compoundMatch[1]] ?? "text";
|
|
44198
45240
|
}
|
|
44199
45241
|
const simpleMatch = fileName.match(/\.([^.]+)$/)?.[1] ?? "";
|
|
44200
45242
|
if (CUSTOM_EXTENSION_TO_FILE_FORMAT.has(simpleMatch)) return CUSTOM_EXTENSION_TO_FILE_FORMAT.get(simpleMatch) ?? "text";
|
|
44201
|
-
return EXTENSION_TO_FILE_FORMAT[simpleMatch] ?? "text";
|
|
45243
|
+
return Object.hasOwn(EXTENSION_TO_FILE_FORMAT, simpleMatch) ? EXTENSION_TO_FILE_FORMAT[simpleMatch] ?? "text" : null;
|
|
44202
45244
|
}
|
|
44203
45245
|
|
|
44204
45246
|
// node_modules/@pierre/diffs/dist/utils/getHighlighterOptions.js
|
|
@@ -44564,8 +45606,8 @@ function normalizeThemeColors(theme3) {
|
|
|
44564
45606
|
function fill(colors, key2, value) {
|
|
44565
45607
|
if (value != null && value !== "") colors[key2] = value;
|
|
44566
45608
|
}
|
|
44567
|
-
function firstColor(...
|
|
44568
|
-
for (const candidate of
|
|
45609
|
+
function firstColor(...candidates2) {
|
|
45610
|
+
for (const candidate of candidates2) if (candidate != null && candidate !== "") return candidate;
|
|
44569
45611
|
}
|
|
44570
45612
|
function matchesSurface(color, surface2) {
|
|
44571
45613
|
return surface2 != null && color.toLowerCase() === surface2.toLowerCase();
|
|
@@ -45671,6 +46713,12 @@ function isStyleNode(element2) {
|
|
|
45671
46713
|
return typeof tagName === "string" && tagName.toLowerCase() === "style";
|
|
45672
46714
|
}
|
|
45673
46715
|
|
|
46716
|
+
// node_modules/@pierre/diffs/dist/utils/platform.js
|
|
46717
|
+
var _isSafari = void 0;
|
|
46718
|
+
function isSafari() {
|
|
46719
|
+
return _isSafari ??= "safari" in window && "pushNotification" in window.safari || /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
46720
|
+
}
|
|
46721
|
+
|
|
45674
46722
|
// node_modules/@pierre/diffs/dist/utils/editSessionAnnotations.js
|
|
45675
46723
|
function adoptEditSessionAnnotations(annotations, getName, previousSession) {
|
|
45676
46724
|
const slotNames = /* @__PURE__ */ new Map();
|
|
@@ -45762,10 +46810,31 @@ function createHostThemeStyleNode() {
|
|
|
45762
46810
|
return node;
|
|
45763
46811
|
}
|
|
45764
46812
|
|
|
45765
|
-
// node_modules/@pierre/diffs/dist/
|
|
45766
|
-
var
|
|
45767
|
-
|
|
45768
|
-
|
|
46813
|
+
// node_modules/@pierre/diffs/dist/worker/errors.js
|
|
46814
|
+
var WorkerPoolTerminatedError = class extends Error {
|
|
46815
|
+
constructor() {
|
|
46816
|
+
super("WorkerPoolManager: operation canceled because the pool terminated");
|
|
46817
|
+
this.name = "WorkerPoolTerminatedError";
|
|
46818
|
+
}
|
|
46819
|
+
};
|
|
46820
|
+
var WorkerPoolTaskCanceledError = class extends Error {
|
|
46821
|
+
constructor() {
|
|
46822
|
+
super("WorkerPoolManager: operation canceled before the task completed");
|
|
46823
|
+
this.name = "WorkerPoolTaskCanceledError";
|
|
46824
|
+
}
|
|
46825
|
+
};
|
|
46826
|
+
var WorkerPoolWorkerError = class extends Error {
|
|
46827
|
+
constructor(message, options) {
|
|
46828
|
+
super(message, options);
|
|
46829
|
+
this.name = "WorkerPoolWorkerError";
|
|
46830
|
+
}
|
|
46831
|
+
};
|
|
46832
|
+
var reportedWorkerErrors = /* @__PURE__ */ new WeakSet();
|
|
46833
|
+
function isWorkerPoolCancellation(error) {
|
|
46834
|
+
return error instanceof WorkerPoolTerminatedError || error instanceof WorkerPoolTaskCanceledError;
|
|
46835
|
+
}
|
|
46836
|
+
function isHandledWorkerPoolError(error) {
|
|
46837
|
+
return isWorkerPoolCancellation(error) || error instanceof WorkerPoolWorkerError && reportedWorkerErrors.has(error);
|
|
45769
46838
|
}
|
|
45770
46839
|
|
|
45771
46840
|
// node_modules/@pierre/diffs/dist/components/web-components.js
|
|
@@ -46417,6 +47486,7 @@ var File = class {
|
|
|
46417
47486
|
const tokenizeMaxLength = this.options.tokenizeMaxLength ?? 1e5;
|
|
46418
47487
|
if (this.fileRenderer.getOrCreateLineCache(file).length > tokenizeMaxLength) return;
|
|
46419
47488
|
await workerManager.primeFileHighlightCache(file).catch((error) => {
|
|
47489
|
+
if (isHandledWorkerPoolError(error)) return;
|
|
46420
47490
|
console.error(error);
|
|
46421
47491
|
});
|
|
46422
47492
|
}
|
|
@@ -49288,13 +50358,13 @@ function getChangeIterationRanges(state3, content, diffStyle) {
|
|
|
49288
50358
|
}
|
|
49289
50359
|
if (iterationRanges.length === 0) return iterationRanges;
|
|
49290
50360
|
iterationRanges.sort((a22, b13) => a22[0] - b13[0]);
|
|
49291
|
-
const
|
|
50361
|
+
const merged2 = [iterationRanges[0]];
|
|
49292
50362
|
for (const [start, end] of iterationRanges.slice(1)) {
|
|
49293
|
-
const last =
|
|
50363
|
+
const last = merged2[merged2.length - 1];
|
|
49294
50364
|
if (start <= last[1]) last[1] = Math.max(last[1], end);
|
|
49295
|
-
else
|
|
50365
|
+
else merged2.push([start, end]);
|
|
49296
50366
|
}
|
|
49297
|
-
return
|
|
50367
|
+
return merged2;
|
|
49298
50368
|
}
|
|
49299
50369
|
function getChangeLineData({ hunkIndex, hunk, collapsedAfter, collapsedBefore, diffStyle, index, unifiedLineIndex, splitLineIndex, additionLineIndex, deletionLineIndex, additionLineNumber, deletionLineNumber, content, isLastContent, unifiedCount, splitCount }) {
|
|
49300
50370
|
const unifiedDeletionLineIndex = index < content.deletions ? unifiedLineIndex + index : void 0;
|
|
@@ -50491,7 +51561,7 @@ var DiffHunksRenderer = class {
|
|
|
50491
51561
|
* row set without a line-count change — the host must escalate to a full
|
|
50492
51562
|
* re-render instead of its cheap refresh path.
|
|
50493
51563
|
*/
|
|
50494
|
-
updateRenderCache(dirtyLines, themeType, lineCountChangeInFlight = false) {
|
|
51564
|
+
updateRenderCache(dirtyLines, themeType, lineCountChangeInFlight = false, changedDocumentLines, documentLineCount) {
|
|
50495
51565
|
this.pendingStructuralRows = void 0;
|
|
50496
51566
|
const { renderCache } = this;
|
|
50497
51567
|
if (renderCache == null) return false;
|
|
@@ -50502,13 +51572,27 @@ var DiffHunksRenderer = class {
|
|
|
50502
51572
|
const pendingStructuralRows = this.pendingStructuralRows = lineCountChangeInFlight ? /* @__PURE__ */ new Map() : void 0;
|
|
50503
51573
|
const changedAdditionLines = [];
|
|
50504
51574
|
const previousAdditionLines = /* @__PURE__ */ new Map();
|
|
51575
|
+
if (pendingStructuralRows == null && changedDocumentLines != null) {
|
|
51576
|
+
const additionLineCount = diff.additionLines.length;
|
|
51577
|
+
const canAppendFinalRow = canAppendFinalDocumentRow(diff.additionLines, documentLineCount);
|
|
51578
|
+
for (const [line, text2] of changedDocumentLines) {
|
|
51579
|
+
if (line < 0 || line > additionLineCount || line === additionLineCount && (text2 === "" || !canAppendFinalRow)) continue;
|
|
51580
|
+
const previous = diff.additionLines[line] ?? "";
|
|
51581
|
+
if (previous !== text2) {
|
|
51582
|
+
diff.additionLines[line] = text2;
|
|
51583
|
+
changedAdditionLines.push(line);
|
|
51584
|
+
previousAdditionLines.set(line, previous);
|
|
51585
|
+
if (!dirtyLines.has(line)) hastLines[line] = createPlainAdditionLineElement(line, cleanLastNewline(text2));
|
|
51586
|
+
}
|
|
51587
|
+
}
|
|
51588
|
+
}
|
|
50505
51589
|
for (const [line, tokens] of dirtyLines) {
|
|
50506
51590
|
const prevProps = hastLines[line]?.properties ?? {};
|
|
50507
51591
|
const lineText = tokens.map((a22) => a22[2]).join("");
|
|
50508
51592
|
const canSyncDiffLine = line < diff.additionLines.length;
|
|
50509
51593
|
const prevLine = canSyncDiffLine ? diff.additionLines[line] ?? "" : "";
|
|
50510
51594
|
const prevText = cleanLastNewline(prevLine);
|
|
50511
|
-
if (pendingStructuralRows == null && canSyncDiffLine) {
|
|
51595
|
+
if (pendingStructuralRows == null && canSyncDiffLine && changedDocumentLines?.has(line) !== true) {
|
|
50512
51596
|
diff.additionLines[line] = applyLineTextWithNewline(prevLine, lineText);
|
|
50513
51597
|
if (prevText !== lineText) {
|
|
50514
51598
|
changedAdditionLines.push(line);
|
|
@@ -51502,6 +52586,9 @@ function realignAdditionHastLines(previousLines, nextLines, hastLines, textDocum
|
|
|
51502
52586
|
for (let index = prefix; index < nextLines.length; index++) realigned[index] ??= createPlainAdditionLineElement(index, textDocument.getLineText(index));
|
|
51503
52587
|
return realigned;
|
|
51504
52588
|
}
|
|
52589
|
+
function canAppendFinalDocumentRow(additionLines, documentLineCount) {
|
|
52590
|
+
return documentLineCount === additionLines.length + 1 && additionLines.at(-1)?.endsWith("\n") === true;
|
|
52591
|
+
}
|
|
51505
52592
|
function createPlainAdditionLineElement(lineIndex, lineText, unifiedLineIndex = lineIndex, splitLineIndex = lineIndex) {
|
|
51506
52593
|
return {
|
|
51507
52594
|
type: "element",
|
|
@@ -51604,6 +52691,7 @@ function getDiffHunksRendererOptions(options) {
|
|
|
51604
52691
|
hunkSeparators: typeof options?.hunkSeparators === "function" ? "custom" : options?.hunkSeparators,
|
|
51605
52692
|
expandUnchanged: options?.expandUnchanged,
|
|
51606
52693
|
loadDiffFiles: options?.loadDiffFiles,
|
|
52694
|
+
parseDiffOptions: options?.parseDiffOptions,
|
|
51607
52695
|
collapsedContextThreshold: options?.collapsedContextThreshold,
|
|
51608
52696
|
lineDiffType: options?.lineDiffType,
|
|
51609
52697
|
maxLineDiffLength: options?.maxLineDiffLength,
|
|
@@ -52596,7 +53684,7 @@ var FileDiff = class {
|
|
|
52596
53684
|
this.detachAdditionLines();
|
|
52597
53685
|
this.hunksRenderer.beginEditSession(editSessionDiff);
|
|
52598
53686
|
const { shouldRefreshDiffsView, lineCountChangeInFlight } = options;
|
|
52599
|
-
if (this.hunksRenderer.updateRenderCache(dirtyLines, themeType, lineCountChangeInFlight)) {
|
|
53687
|
+
if (this.hunksRenderer.updateRenderCache(dirtyLines, themeType, lineCountChangeInFlight, options.changedDocumentLines, options.documentLineCount)) {
|
|
52600
53688
|
if (this.refreshViewTimeout != null) {
|
|
52601
53689
|
clearTimeout(this.refreshViewTimeout);
|
|
52602
53690
|
this.refreshViewTimeout = void 0;
|
|
@@ -52743,6 +53831,7 @@ var FileDiff = class {
|
|
|
52743
53831
|
const tokenizeMaxLength = this.options.tokenizeMaxLength ?? 1e5;
|
|
52744
53832
|
if (Math.max(fileDiff.additionLines.length, fileDiff.deletionLines.length) > tokenizeMaxLength) return;
|
|
52745
53833
|
await workerManager.primeDiffHighlightCache(fileDiff).catch((error) => {
|
|
53834
|
+
if (isHandledWorkerPoolError(error)) return;
|
|
52746
53835
|
console.error(error);
|
|
52747
53836
|
});
|
|
52748
53837
|
}
|
|
@@ -54240,9 +55329,9 @@ function disableTextSelection(rootNode = document) {
|
|
|
54240
55329
|
}
|
|
54241
55330
|
function getDockviewTheme(element2) {
|
|
54242
55331
|
function toClassList(element3) {
|
|
54243
|
-
const
|
|
54244
|
-
for (let i25 = 0; i25 < element3.classList.length; i25++)
|
|
54245
|
-
return
|
|
55332
|
+
const list5 = [];
|
|
55333
|
+
for (let i25 = 0; i25 < element3.classList.length; i25++) list5.push(element3.classList.item(i25));
|
|
55334
|
+
return list5;
|
|
54246
55335
|
}
|
|
54247
55336
|
let theme3 = void 0;
|
|
54248
55337
|
let parent = element2;
|
|
@@ -55446,7 +56535,7 @@ var BranchNode = class BranchNode2 extends CompositeDisposable {
|
|
|
55446
56535
|
if (child instanceof BranchNode2) child.proportionalLayout = value;
|
|
55447
56536
|
});
|
|
55448
56537
|
}
|
|
55449
|
-
constructor(orientation, proportionalLayout, styles, size4, orthogonalSize,
|
|
56538
|
+
constructor(orientation, proportionalLayout, styles, size4, orthogonalSize, disabled2, margin, childDescriptors) {
|
|
55450
56539
|
super();
|
|
55451
56540
|
this.orientation = orientation;
|
|
55452
56541
|
this.styles = styles;
|
|
@@ -55489,7 +56578,7 @@ var BranchNode = class BranchNode2 extends CompositeDisposable {
|
|
|
55489
56578
|
});
|
|
55490
56579
|
this.splitview.layout(this.size, this.orthogonalSize);
|
|
55491
56580
|
}
|
|
55492
|
-
this.disabled =
|
|
56581
|
+
this.disabled = disabled2;
|
|
55493
56582
|
this.addDisposables(this._onDidChange, this._onDidVisibilityChange, this.splitview.onDidSashEnd(() => {
|
|
55494
56583
|
this._onDidChange.fire({});
|
|
55495
56584
|
}));
|
|
@@ -65093,9 +66182,9 @@ var ENTERPRISE_MODULE_NAMES = /* @__PURE__ */ new Set([
|
|
|
65093
66182
|
var _warnedMissingModule = /* @__PURE__ */ new Set();
|
|
65094
66183
|
function missingModuleMessage(moduleName, reason) {
|
|
65095
66184
|
const reasons = reason === void 0 ? [] : [].concat(reason);
|
|
65096
|
-
const
|
|
66185
|
+
const quoted2 = reasons.map((r39) => `\`${r39}\``).join(", ");
|
|
65097
66186
|
const requires = reasons.length > 1 ? "require" : "requires";
|
|
65098
|
-
const needed = reasons.length ? `${
|
|
66187
|
+
const needed = reasons.length ? `${quoted2} ${requires} the "${moduleName}" module` : `The "${moduleName}" module is required`;
|
|
65099
66188
|
if (ENTERPRISE_MODULE_NAMES.has(moduleName)) return `dockview: ${needed}, which ships in dockview-enterprise.
|
|
65100
66189
|
|
|
65101
66190
|
npm install dockview-enterprise
|
|
@@ -65695,9 +66784,9 @@ var RootDropTargetService = class {
|
|
|
65695
66784
|
}
|
|
65696
66785
|
setOptions(options) {
|
|
65697
66786
|
if ("dndEdges" in options) {
|
|
65698
|
-
const
|
|
65699
|
-
this._html5Target.disabled =
|
|
65700
|
-
this._pointerTarget.disabled =
|
|
66787
|
+
const disabled2 = typeof options.dndEdges === "boolean" && options.dndEdges === false;
|
|
66788
|
+
this._html5Target.disabled = disabled2;
|
|
66789
|
+
this._pointerTarget.disabled = disabled2;
|
|
65701
66790
|
}
|
|
65702
66791
|
if ("dndEdges" in options || "dockToEdgeGroups" in options) {
|
|
65703
66792
|
const model = resolveRootOverlayModel({
|
|
@@ -66076,16 +67165,16 @@ var nextContextMenuItemId = () => `dv-ctx-menu-item-${_nextId++}`;
|
|
|
66076
67165
|
function isItemConfig(item2) {
|
|
66077
67166
|
return typeof item2 === "object";
|
|
66078
67167
|
}
|
|
66079
|
-
function buildItem(label, close, action,
|
|
67168
|
+
function buildItem(label, close, action, disabled2) {
|
|
66080
67169
|
const el = document.createElement("div");
|
|
66081
67170
|
el.className = "dv-context-menu-item";
|
|
66082
67171
|
el.setAttribute("role", "menuitem");
|
|
66083
|
-
if (
|
|
67172
|
+
if (disabled2) {
|
|
66084
67173
|
el.classList.add("dv-context-menu-item--disabled");
|
|
66085
67174
|
el.setAttribute("aria-disabled", "true");
|
|
66086
67175
|
}
|
|
66087
67176
|
el.textContent = label;
|
|
66088
|
-
if (!
|
|
67177
|
+
if (!disabled2) el.addEventListener("click", () => {
|
|
66089
67178
|
action();
|
|
66090
67179
|
close();
|
|
66091
67180
|
});
|
|
@@ -71287,9 +72376,9 @@ var getBaseFileName = (path) => {
|
|
|
71287
72376
|
};
|
|
71288
72377
|
var getExtensionCandidates = (fileName) => {
|
|
71289
72378
|
const segments = fileName.toLowerCase().split(".");
|
|
71290
|
-
const
|
|
71291
|
-
for (let index = 1; index < segments.length; index += 1)
|
|
71292
|
-
return
|
|
72379
|
+
const candidates2 = [];
|
|
72380
|
+
for (let index = 1; index < segments.length; index += 1) candidates2.push(segments.slice(index).join("."));
|
|
72381
|
+
return candidates2;
|
|
71293
72382
|
};
|
|
71294
72383
|
function remapEntryToIcon(entry, remappedFrom) {
|
|
71295
72384
|
if (typeof entry === "string") return {
|
|
@@ -77442,8 +78531,8 @@ function getFileTreeRowAriaLabel(row) {
|
|
|
77442
78531
|
if (flattenedSegments == null || flattenedSegments.length === 0) return row.name;
|
|
77443
78532
|
return flattenedSegments.map((segment2) => segment2.name).join(" / ");
|
|
77444
78533
|
}
|
|
77445
|
-
function computeStickyRowsFromCandidates(
|
|
77446
|
-
return
|
|
78534
|
+
function computeStickyRowsFromCandidates(candidates2, scrollTop, itemHeight, totalRowCount) {
|
|
78535
|
+
return candidates2.map((candidate, slotDepth) => {
|
|
77447
78536
|
const defaultTop = slotDepth * itemHeight;
|
|
77448
78537
|
const nextBoundaryIndex = candidate.subtreeEndIndex + 1;
|
|
77449
78538
|
if (nextBoundaryIndex >= totalRowCount) return {
|
|
@@ -77490,9 +78579,9 @@ function getPointElement(rootNode, clientX, clientY) {
|
|
|
77490
78579
|
return element2 instanceof HTMLElement ? element2 : null;
|
|
77491
78580
|
}
|
|
77492
78581
|
function getShadowPointElementByGeometry(rootNode, clientX, clientY) {
|
|
77493
|
-
const
|
|
77494
|
-
for (let index =
|
|
77495
|
-
const candidate =
|
|
78582
|
+
const candidates2 = Array.from(rootNode.querySelectorAll('[data-type="item"], [data-item-flattened-subitem]'));
|
|
78583
|
+
for (let index = candidates2.length - 1; index >= 0; index--) {
|
|
78584
|
+
const candidate = candidates2[index];
|
|
77496
78585
|
const rect = candidate.getBoundingClientRect();
|
|
77497
78586
|
if (clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom) return candidate;
|
|
77498
78587
|
}
|
|
@@ -80010,6 +81099,8 @@ var elements = {
|
|
|
80010
81099
|
"slicc-network": SliccNetwork,
|
|
80011
81100
|
"slicc-notices": SliccNotices,
|
|
80012
81101
|
"slicc-approvals": SliccApprovals,
|
|
81102
|
+
"slicc-secrets": SliccSecrets,
|
|
81103
|
+
"slicc-vault-button": SliccVaultButton,
|
|
80013
81104
|
"slicc-confirm": SliccConfirm,
|
|
80014
81105
|
"slicc-prompt": SliccPrompt,
|
|
80015
81106
|
"slicc-app": SliccApp
|
|
@@ -80046,7 +81137,9 @@ export {
|
|
|
80046
81137
|
SliccNetwork,
|
|
80047
81138
|
SliccNotices,
|
|
80048
81139
|
SliccPrompt,
|
|
81140
|
+
SliccSecrets,
|
|
80049
81141
|
SliccUpdates,
|
|
81142
|
+
SliccVaultButton,
|
|
80050
81143
|
confirm,
|
|
80051
81144
|
define2 as define,
|
|
80052
81145
|
grammarBase,
|