@ai-ecoverse/slicc-spectrum 1.76.0 → 1.77.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/slicc-dummy.js +139 -104
- package/dist/slicc-dummy.js.map +4 -4
- package/dist/slicc-ui.js +303 -57
- package/dist/slicc-ui.js.map +3 -3
- package/dist/types/app/chat.d.ts +1 -1
- package/dist/types/app/dips.d.ts +1 -0
- package/dist/types/app/messages.d.ts +10 -2
- package/dist/types/dummy/status.d.ts +1 -0
- package/dist/types/model/types.d.ts +1 -0
- package/package.json +3 -3
package/dist/slicc-ui.js
CHANGED
|
@@ -10083,6 +10083,11 @@ var panelCss = i`
|
|
|
10083
10083
|
.spacer {
|
|
10084
10084
|
flex: 1;
|
|
10085
10085
|
}
|
|
10086
|
+
.bar [data-watch-note] {
|
|
10087
|
+
flex: none;
|
|
10088
|
+
font-size: var(--swc-font-size-75);
|
|
10089
|
+
color: var(--swc-neutral-subdued-content-color-default);
|
|
10090
|
+
}
|
|
10086
10091
|
.body {
|
|
10087
10092
|
flex: 1;
|
|
10088
10093
|
min-height: 0;
|
|
@@ -11941,6 +11946,11 @@ var Dips = class extends Emitter {
|
|
|
11941
11946
|
this.#storage?.setItem(this.key, JSON.stringify(this.list()));
|
|
11942
11947
|
this.emit("change", this.list());
|
|
11943
11948
|
}
|
|
11949
|
+
attach(id) {
|
|
11950
|
+
if (!this.#out.delete(id)) return;
|
|
11951
|
+
this.#storage?.setItem(this.key, JSON.stringify(this.list()));
|
|
11952
|
+
this.emit("change", this.list());
|
|
11953
|
+
}
|
|
11944
11954
|
};
|
|
11945
11955
|
function dipsOf(node) {
|
|
11946
11956
|
let current = node;
|
|
@@ -14400,7 +14410,7 @@ function chatAgent(id) {
|
|
|
14400
14410
|
function chats(dock) {
|
|
14401
14411
|
return dock.api.panels.map((panel) => panel.id).filter((id) => chatAgent(id) !== null);
|
|
14402
14412
|
}
|
|
14403
|
-
function openChat(dock, agent, screen, focus = true,
|
|
14413
|
+
function openChat(dock, agent, screen, focus = true, reveal2 = true) {
|
|
14404
14414
|
const id = chatId(agent.id);
|
|
14405
14415
|
if (!dock.has(id)) {
|
|
14406
14416
|
const sibling = chats(dock)[0];
|
|
@@ -14415,7 +14425,7 @@ function openChat(dock, agent, screen, focus = true, reveal = true) {
|
|
|
14415
14425
|
});
|
|
14416
14426
|
}
|
|
14417
14427
|
if (focus) dock.focusPanel(id);
|
|
14418
|
-
else if (
|
|
14428
|
+
else if (reveal2) dock.reveal(id);
|
|
14419
14429
|
return id;
|
|
14420
14430
|
}
|
|
14421
14431
|
function openDocument(dock, kind, path, screen, focus = true) {
|
|
@@ -30885,11 +30895,14 @@ function question(item2, handlers) {
|
|
|
30885
30895
|
<swc-button size="s" variant="accent" data-action="answer" ?disabled=${handlers.readOnly} @click=${(event2) => event2.currentTarget.closest("form")?.requestSubmit()}>Answer</swc-button>
|
|
30886
30896
|
</form>`;
|
|
30887
30897
|
}
|
|
30888
|
-
return b`<div class="question" data-state=${item2.state} data-kind=${item2.kind}>
|
|
30898
|
+
return b`<div class="question decision" data-state=${item2.state} data-kind=${item2.kind}>
|
|
30889
30899
|
<div class="q">${item2.question}</div>
|
|
30890
30900
|
${body4}
|
|
30891
30901
|
</div>`;
|
|
30892
30902
|
}
|
|
30903
|
+
function questionTurn(item2, handlers, pile) {
|
|
30904
|
+
return b`<swc-conversation-turn type="system" class="message decision-turn" data-id=${item2.id} data-state=${item2.state} data-pending=${item2.state === "open" ? "" : A} accessible-label=${`Question: ${item2.question}`} style=${pileStyle(pile)} @click=${reveal} @keydown=${reveal}>${question(item2, handlers)}</swc-conversation-turn>`;
|
|
30905
|
+
}
|
|
30893
30906
|
var delegationVerbs = {
|
|
30894
30907
|
feed: "fed",
|
|
30895
30908
|
scoop: "started",
|
|
@@ -30947,7 +30960,7 @@ function part(entry, handlers) {
|
|
|
30947
30960
|
}
|
|
30948
30961
|
}
|
|
30949
30962
|
function silent(entry, showThinking) {
|
|
30950
|
-
return entry.type === "thinking" && !showThinking || entry.type === "link" && !!host2(entry.url);
|
|
30963
|
+
return entry.type === "question" || entry.type === "thinking" && !showThinking || entry.type === "link" && !!host2(entry.url);
|
|
30951
30964
|
}
|
|
30952
30965
|
function parts(entries, handlers, showThinking, extra = []) {
|
|
30953
30966
|
const out = [];
|
|
@@ -31180,9 +31193,66 @@ var lickIcons = {
|
|
|
31180
31193
|
"scoop-wait": "\u23F3",
|
|
31181
31194
|
"sudo-request": "\u{1F510}"
|
|
31182
31195
|
};
|
|
31183
|
-
function
|
|
31196
|
+
function pendingApproval(message) {
|
|
31197
|
+
return message.role === "lick" && message.channel === "sudo-request" && message.state === "pending";
|
|
31198
|
+
}
|
|
31199
|
+
function waiting(message, now = Date.now()) {
|
|
31200
|
+
const at = message.role === "lick" ? message.expiresAt : void 0;
|
|
31201
|
+
return pendingApproval(message) && !(at !== void 0 && at <= now);
|
|
31202
|
+
}
|
|
31203
|
+
function clock(ms) {
|
|
31204
|
+
const seconds = Math.ceil(ms / 1e3);
|
|
31205
|
+
return `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, "0")}`;
|
|
31206
|
+
}
|
|
31207
|
+
var still = () => globalThis.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
|
|
31208
|
+
function reveal(event2) {
|
|
31209
|
+
if (event2.target.closest("swc-button, input, textarea")) return;
|
|
31210
|
+
if (event2 instanceof KeyboardEvent && (event2.key !== "Enter" || event2.target !== event2.currentTarget))
|
|
31211
|
+
return;
|
|
31212
|
+
show(event2.currentTarget);
|
|
31213
|
+
}
|
|
31214
|
+
function show(turn) {
|
|
31215
|
+
const log = turn.closest(".log");
|
|
31216
|
+
if (!log) return;
|
|
31217
|
+
const origin2 = log.getBoundingClientRect().top;
|
|
31218
|
+
const pile = turn.getBoundingClientRect().top - origin2;
|
|
31219
|
+
turn.style.position = "static";
|
|
31220
|
+
const flow = turn.getBoundingClientRect();
|
|
31221
|
+
turn.style.position = "";
|
|
31222
|
+
const natural = flow.top - origin2;
|
|
31223
|
+
const bottom = Math.max(16, log.clientHeight - flow.height - 16);
|
|
31224
|
+
if (Math.abs(pile - natural) > 1)
|
|
31225
|
+
log.scrollTo({ top: log.scrollTop + natural - bottom, behavior: still() ? "auto" : "smooth" });
|
|
31226
|
+
}
|
|
31227
|
+
var flatPile = { stack: 0 };
|
|
31228
|
+
function pileStyle(pile) {
|
|
31229
|
+
return `--stack: ${pile.stack}`;
|
|
31230
|
+
}
|
|
31231
|
+
function spokenLeft(left, at) {
|
|
31232
|
+
if (left <= 0) return "Timed out";
|
|
31233
|
+
return left <= 6e4 ? "Less than a minute left" : `Expires at ${time(at)}`;
|
|
31234
|
+
}
|
|
31235
|
+
function decision(message, handlers, pile) {
|
|
31236
|
+
const at = message.expiresAt;
|
|
31237
|
+
const left = at === void 0 ? null : at - Date.now();
|
|
31238
|
+
const expired = left !== null && left <= 0;
|
|
31239
|
+
const timer = left === null ? A : b`<span class="timer" data-timer aria-hidden="true">${expired ? "Timed out" : clock(left)}</span><span class="sr">${spokenLeft(left, at)}</span>`;
|
|
31240
|
+
const actions2 = expired ? A : b`<div class="decide">
|
|
31241
|
+
<swc-button size="s" variant="secondary" fill-style="outline" data-action="deny" ?disabled=${handlers.readOnly} @click=${() => handlers.resolve(message.id, "dismissed")}>Deny</swc-button>
|
|
31242
|
+
<swc-button size="s" variant="accent" data-action="allow" ?disabled=${handlers.readOnly} @click=${() => handlers.resolve(message.id, "confirmed")}>Allow</swc-button>
|
|
31243
|
+
</div>`;
|
|
31244
|
+
return b`<swc-conversation-turn type="system" class="message decision-turn" accessible-label=${`Permission request from ${message.title}`} data-id=${message.id} data-pending=${expired ? A : ""} data-expired=${expired ? "" : A} style=${pileStyle(pile)} @click=${reveal} @keydown=${reveal}>
|
|
31245
|
+
<div class="decision" data-kind="approval">
|
|
31246
|
+
<div class="decision-head"><span class="who">${message.title}</span>${timer}</div>
|
|
31247
|
+
<p class="decision-text">${message.text}</p>
|
|
31248
|
+
${message.body ? b`<pre class="command">${message.body}</pre>` : A}
|
|
31249
|
+
${actions2}
|
|
31250
|
+
</div>
|
|
31251
|
+
</swc-conversation-turn>`;
|
|
31252
|
+
}
|
|
31253
|
+
function lick(message, handlers, stamp = true, pile = flatPile) {
|
|
31254
|
+
if (pendingApproval(message)) return decision(message, handlers, pile);
|
|
31184
31255
|
const [label] = lickLabels[message.channel];
|
|
31185
|
-
const decide = message.channel === "sudo-request" && message.state === "pending";
|
|
31186
31256
|
const outcome = message.state === "confirmed" ? "Allowed" : message.state === "dismissed" ? "Denied" : "";
|
|
31187
31257
|
const head2 = b`${message.severity ? b`<span class="sr">${severities[message.severity].prefix}</span>` : A}
|
|
31188
31258
|
${outcome ? b`<span class="sr">${outcome}. </span>` : A}
|
|
@@ -31190,28 +31260,20 @@ function lick(message, handlers, stamp = true) {
|
|
|
31190
31260
|
${message.count && message.count > 1 ? b`<span class="times" title="Coalesced events">×${message.count}</span>` : A}`;
|
|
31191
31261
|
const outcomeIcon = message.state === "confirmed" ? "\u{1F44D}" : message.state === "dismissed" ? "\u{1F44E}" : "";
|
|
31192
31262
|
const reaction = b`<span class="reactions"><span class="reaction" title=${label} aria-hidden="true">${lickIcons[message.channel]}</span>${outcomeIcon ? b`<span class="reaction" title=${outcome} aria-hidden="true">${outcomeIcon}</span>` : A}</span>`;
|
|
31193
|
-
const actions2 = decide ? b`<div class="decide">
|
|
31194
|
-
<swc-button size="s" variant="accent" data-action="allow" ?disabled=${handlers.readOnly} @click=${() => handlers.resolve(message.id, "confirmed")}>Allow</swc-button>
|
|
31195
|
-
<swc-button size="s" variant="secondary" fill-style="outline" data-action="deny" ?disabled=${handlers.readOnly} @click=${() => handlers.resolve(message.id, "dismissed")}>Deny</swc-button>
|
|
31196
|
-
</div>` : A;
|
|
31197
31263
|
const name = `${message.severity ? severities[message.severity].prefix : ""}${label} event`;
|
|
31198
31264
|
const byline2 = b`<div class="meta">${message.severity ? b`<span class="severity-icon">${severities[message.severity].icon}</span>` : A}<span class="who">${message.title}</span>${stamp ? when(message.createdAt) : unseen(message.createdAt)}</div>`;
|
|
31199
31265
|
if (!message.body) {
|
|
31200
31266
|
return outside(
|
|
31201
31267
|
name,
|
|
31202
31268
|
byline2,
|
|
31203
|
-
b`<div class="lick-frame"><div class="lick" data-id=${message.id} data-channel=${message.channel} data-severity=${message.severity ?? A}><div class="lick-head">${head2}</div
|
|
31269
|
+
b`<div class="lick-frame"><div class="lick" data-id=${message.id} data-channel=${message.channel} data-severity=${message.severity ?? A}><div class="lick-head">${head2}</div></div>${reaction}</div>`
|
|
31204
31270
|
);
|
|
31205
31271
|
}
|
|
31206
31272
|
const details = b`<details class="lick" data-id=${message.id} data-channel=${message.channel} data-severity=${message.severity ?? A}>
|
|
31207
31273
|
<summary class="lick-head">${head2}<swc-icon-chevron-right class="chevron" size="s" aria-hidden="true"></swc-icon-chevron-right></summary>
|
|
31208
31274
|
<pre class="output">${message.body}</pre>
|
|
31209
31275
|
</details>`;
|
|
31210
|
-
return outside(
|
|
31211
|
-
name,
|
|
31212
|
-
byline2,
|
|
31213
|
-
b`<div class="lick-frame">${decide ? b`<div class="pending">${details}${actions2}</div>` : details}${reaction}</div>`
|
|
31214
|
-
);
|
|
31276
|
+
return outside(name, byline2, b`<div class="lick-frame">${details}${reaction}</div>`);
|
|
31215
31277
|
}
|
|
31216
31278
|
var messageCss = i`
|
|
31217
31279
|
swc-conversation-thread > .message,
|
|
@@ -32014,15 +32076,97 @@ var messageCss = i`
|
|
|
32014
32076
|
gap: var(--swc-spacing-85);
|
|
32015
32077
|
padding: 0 var(--swc-spacing-100) var(--swc-spacing-100);
|
|
32016
32078
|
}
|
|
32017
|
-
.
|
|
32018
|
-
|
|
32019
|
-
|
|
32079
|
+
swc-conversation-turn.decision-turn {
|
|
32080
|
+
container-type: inline-size;
|
|
32081
|
+
transition:
|
|
32082
|
+
top var(--swc-animation-duration-300) var(--swc-animation-ease-out),
|
|
32083
|
+
transform var(--swc-animation-duration-300) var(--swc-animation-ease-out),
|
|
32084
|
+
filter var(--swc-animation-duration-300) var(--swc-animation-ease-out);
|
|
32020
32085
|
}
|
|
32021
|
-
|
|
32022
|
-
|
|
32086
|
+
@media (prefers-reduced-motion: reduce) {
|
|
32087
|
+
swc-conversation-turn.decision-turn {
|
|
32088
|
+
transition: none;
|
|
32089
|
+
}
|
|
32023
32090
|
}
|
|
32024
|
-
|
|
32025
|
-
|
|
32091
|
+
slicc-sprinkle[inline] {
|
|
32092
|
+
position: relative;
|
|
32093
|
+
inset-inline-start: 50%;
|
|
32094
|
+
inline-size: calc(100cqw + var(--swc-spacing-300) * 2);
|
|
32095
|
+
transform: translateX(-50%);
|
|
32096
|
+
}
|
|
32097
|
+
swc-conversation-turn.decision-turn[data-pending] {
|
|
32098
|
+
position: sticky;
|
|
32099
|
+
top: calc(var(--stack, 0) * (var(--swc-spacing-600) + var(--swc-spacing-75)));
|
|
32100
|
+
z-index: calc(var(--stack, 0) + 1);
|
|
32101
|
+
}
|
|
32102
|
+
swc-conversation-turn.decision-turn[data-pinned] {
|
|
32103
|
+
transform: scale(calc(1 - var(--depth, 0) * 0.03));
|
|
32104
|
+
transform-origin: top center;
|
|
32105
|
+
filter: blur(calc(var(--depth, 0) * 0.6px));
|
|
32106
|
+
}
|
|
32107
|
+
.decision-turn[data-pending] .decision {
|
|
32108
|
+
border-color: var(--swc-gray-300);
|
|
32109
|
+
box-shadow: var(--swc-drop-shadow-elevated);
|
|
32110
|
+
}
|
|
32111
|
+
.decision-turn[data-pending]:focus-visible {
|
|
32112
|
+
outline: none;
|
|
32113
|
+
}
|
|
32114
|
+
.decision-turn[data-pending]:focus-visible .decision {
|
|
32115
|
+
outline: var(--swc-focus-indicator-thickness) solid var(--swc-focus-indicator-color);
|
|
32116
|
+
outline-offset: var(--swc-focus-ring-gap);
|
|
32117
|
+
}
|
|
32118
|
+
.decision {
|
|
32119
|
+
display: flex;
|
|
32120
|
+
flex-direction: column;
|
|
32121
|
+
gap: var(--swc-spacing-100);
|
|
32122
|
+
margin-inline: var(--swc-spacing-700);
|
|
32123
|
+
padding: var(--swc-spacing-200) var(--swc-spacing-300);
|
|
32124
|
+
border: var(--swc-border-width-100) solid var(--swc-gray-200);
|
|
32125
|
+
border-radius: var(--swc-corner-radius-100);
|
|
32126
|
+
background: var(--swc-background-layer-1-color);
|
|
32127
|
+
font-size: var(--swc-font-size-200);
|
|
32128
|
+
}
|
|
32129
|
+
.decision-head {
|
|
32130
|
+
display: flex;
|
|
32131
|
+
align-items: baseline;
|
|
32132
|
+
justify-content: space-between;
|
|
32133
|
+
gap: var(--swc-spacing-100);
|
|
32134
|
+
font-size: var(--swc-font-size-100);
|
|
32135
|
+
}
|
|
32136
|
+
.decision-head .who {
|
|
32137
|
+
font-weight: var(--swc-bold-font-weight);
|
|
32138
|
+
}
|
|
32139
|
+
.timer {
|
|
32140
|
+
color: var(--swc-neutral-subdued-content-color-default);
|
|
32141
|
+
font-variant-numeric: tabular-nums;
|
|
32142
|
+
white-space: nowrap;
|
|
32143
|
+
}
|
|
32144
|
+
.decision-text {
|
|
32145
|
+
margin: 0;
|
|
32146
|
+
}
|
|
32147
|
+
.command {
|
|
32148
|
+
margin: 0;
|
|
32149
|
+
padding: var(--swc-spacing-75) var(--swc-spacing-100);
|
|
32150
|
+
border-radius: var(--swc-corner-radius-100);
|
|
32151
|
+
background: var(--swc-background-layer-2-color);
|
|
32152
|
+
font-size: var(--swc-font-size-75);
|
|
32153
|
+
white-space: pre-wrap;
|
|
32154
|
+
overflow-wrap: anywhere;
|
|
32155
|
+
}
|
|
32156
|
+
.decision .decide,
|
|
32157
|
+
.question.decision .options {
|
|
32158
|
+
justify-content: flex-end;
|
|
32159
|
+
padding: 0;
|
|
32160
|
+
}
|
|
32161
|
+
.question.decision .options {
|
|
32162
|
+
display: flex;
|
|
32163
|
+
flex-wrap: wrap;
|
|
32164
|
+
gap: var(--swc-spacing-85);
|
|
32165
|
+
}
|
|
32166
|
+
@container (inline-size < 480px) {
|
|
32167
|
+
.decision {
|
|
32168
|
+
margin-inline: var(--swc-spacing-300);
|
|
32169
|
+
}
|
|
32026
32170
|
}
|
|
32027
32171
|
`;
|
|
32028
32172
|
|
|
@@ -33291,6 +33435,11 @@ var SliccApp = class extends ThemedElement {
|
|
|
33291
33435
|
return cone ? { ...sprinkle, title: `${cone.name} / ${sprinkle.title}` } : sprinkle;
|
|
33292
33436
|
}).sort((a23, b13) => order.indexOf(a23.agentId) - order.indexOf(b13.agentId));
|
|
33293
33437
|
}
|
|
33438
|
+
#panelClosed = (event2) => {
|
|
33439
|
+
const id = event2.detail.id;
|
|
33440
|
+
this.panels.closed(id);
|
|
33441
|
+
if (id.startsWith("sprinkle:")) this.dips.attach(id.slice("sprinkle:".length));
|
|
33442
|
+
};
|
|
33294
33443
|
#detach(id, place3, open) {
|
|
33295
33444
|
const sprinkle = this.#sprinkle(id);
|
|
33296
33445
|
if (!sprinkle) return;
|
|
@@ -33546,7 +33695,7 @@ var SliccApp = class extends ThemedElement {
|
|
|
33546
33695
|
<main>
|
|
33547
33696
|
${rails.left}
|
|
33548
33697
|
<slicc-dock empty-text="All panels are closed. Open one from a rail or View." @layout-change=${this.#save}
|
|
33549
|
-
@panel-close=${
|
|
33698
|
+
@panel-close=${this.#panelClosed}
|
|
33550
33699
|
@active-panel-change=${this.#activated}
|
|
33551
33700
|
@external-drop=${this.#dropped}
|
|
33552
33701
|
@detach-sprinkle=${(event2) => this.#detach(event2.detail.id, null, true)}
|
|
@@ -33787,7 +33936,7 @@ var inCwd = (approval) => approval.alwaysScope === "cwd" && !!approval.cwd;
|
|
|
33787
33936
|
function alwaysHint(approval) {
|
|
33788
33937
|
return inCwd(approval) ? `Always allow lets ${approval.requester.name} run exactly this command with sudo, in ${approval.cwd}, without asking again.` : `Always allow lets ${approval.requester.name} run exactly this command with sudo without asking again.`;
|
|
33789
33938
|
}
|
|
33790
|
-
function
|
|
33939
|
+
function waiting2(model, now) {
|
|
33791
33940
|
return [...model?.approvals?.list() ?? []].filter((approval) => approval.expiresAt > now).sort((a23, b13) => a23.createdAt - b13.createdAt);
|
|
33792
33941
|
}
|
|
33793
33942
|
function gone(reason) {
|
|
@@ -33924,16 +34073,16 @@ var SliccApprovals = class extends ModelElement {
|
|
|
33924
34073
|
this.#timer = null;
|
|
33925
34074
|
}
|
|
33926
34075
|
}
|
|
33927
|
-
async decide(approval,
|
|
34076
|
+
async decide(approval, decision2) {
|
|
33928
34077
|
const port = this.model?.approvals;
|
|
33929
|
-
if (!port?.decide || this.busy ||
|
|
34078
|
+
if (!port?.decide || this.busy || decision2 !== "deny" && !this.#armed) return;
|
|
33930
34079
|
const verdict = secretRules(approval.command, approval.cwd);
|
|
33931
|
-
if (
|
|
33932
|
-
this.busy =
|
|
34080
|
+
if (decision2 === "always" && (verdict.certain ?? verdict.maybe)) return;
|
|
34081
|
+
this.busy = decision2;
|
|
33933
34082
|
this.failure = null;
|
|
33934
34083
|
this.#pending.add(approval.id);
|
|
33935
34084
|
try {
|
|
33936
|
-
await port.decide(approval.id,
|
|
34085
|
+
await port.decide(approval.id, decision2);
|
|
33937
34086
|
this.#done.add(approval.id);
|
|
33938
34087
|
} catch (error) {
|
|
33939
34088
|
this.failure = {
|
|
@@ -33946,7 +34095,7 @@ var SliccApprovals = class extends ModelElement {
|
|
|
33946
34095
|
}
|
|
33947
34096
|
}
|
|
33948
34097
|
#current() {
|
|
33949
|
-
return this.model?.approvals?.decide ?
|
|
34098
|
+
return this.model?.approvals?.decide ? waiting2(this.model, this.now) : [];
|
|
33950
34099
|
}
|
|
33951
34100
|
willUpdate(changed) {
|
|
33952
34101
|
super.willUpdate(changed);
|
|
@@ -33992,15 +34141,15 @@ var SliccApprovals = class extends ModelElement {
|
|
|
33992
34141
|
if (this.gone) this.close();
|
|
33993
34142
|
else void this.decide(approval, "deny");
|
|
33994
34143
|
}
|
|
33995
|
-
#button(approval,
|
|
34144
|
+
#button(approval, decision2, label, variant) {
|
|
33996
34145
|
return b`<swc-button
|
|
33997
34146
|
slot="button"
|
|
33998
34147
|
variant=${variant}
|
|
33999
34148
|
fill-style=${variant === "accent" ? A : "outline"}
|
|
34000
|
-
data-action=${
|
|
34001
|
-
?pending=${this.busy ===
|
|
34002
|
-
?disabled=${!!this.busy && this.busy !==
|
|
34003
|
-
@click=${() => this.decide(approval,
|
|
34149
|
+
data-action=${decision2}
|
|
34150
|
+
?pending=${this.busy === decision2}
|
|
34151
|
+
?disabled=${!!this.busy && this.busy !== decision2}
|
|
34152
|
+
@click=${() => this.decide(approval, decision2)}
|
|
34004
34153
|
>${label}</swc-button
|
|
34005
34154
|
>`;
|
|
34006
34155
|
}
|
|
@@ -35455,6 +35604,7 @@ e12([n({
|
|
|
35455
35604
|
e25("swc-action-group", o87);
|
|
35456
35605
|
|
|
35457
35606
|
// src/app/changes.ts
|
|
35607
|
+
var watchNote = b`<span data-watch-note>Watch only</span>`;
|
|
35458
35608
|
var layouts = [
|
|
35459
35609
|
["unified", "Unified"],
|
|
35460
35610
|
["split", "Split"]
|
|
@@ -35778,11 +35928,11 @@ var SliccChanges = class extends ModelElement {
|
|
|
35778
35928
|
return b`<div class="bar">
|
|
35779
35929
|
<span class="summary">${changes2.length} pending ${changes2.length === 1 ? "change" : "changes"}</span>
|
|
35780
35930
|
<span class="spacer"></span>
|
|
35781
|
-
${changes2.length
|
|
35782
|
-
<swc-action-button size="s" quiet data-action="revert-all" @click=${() => this.#all("revert")}>Revert all</swc-action-button>`
|
|
35931
|
+
${!changes2.length ? A : watchOnly(this.model) ? watchNote : b`<swc-action-button size="s" quiet data-action="accept-all" @click=${() => this.#all("accept")}>Accept all</swc-action-button>
|
|
35932
|
+
<swc-action-button size="s" quiet data-action="revert-all" @click=${() => this.#all("revert")}>Revert all</swc-action-button>`}
|
|
35783
35933
|
</div>
|
|
35784
35934
|
${errorLine(this.error)}
|
|
35785
|
-
${changes2.length ? this.#list(changes2) : b`<div class="note"
|
|
35935
|
+
${changes2.length ? this.#list(changes2) : b`<div class="note">${watchOnly(this.model) ? "No pending changes." : "No pending changes. Edits by agents show up here for review."}</div>`}`;
|
|
35786
35936
|
}
|
|
35787
35937
|
};
|
|
35788
35938
|
var SliccDiffPanel = class extends ThemedElement {
|
|
@@ -35892,7 +36042,7 @@ var SliccDiffPanel = class extends ThemedElement {
|
|
|
35892
36042
|
>`
|
|
35893
36043
|
)}
|
|
35894
36044
|
</swc-action-group>`}
|
|
35895
|
-
${watchOnly(model) ?
|
|
36045
|
+
${watchOnly(model) ? watchNote : b`<swc-action-button size="s" quiet data-action="accept" accessible-label="Accept" title="Accept" @click=${() => port?.accept(this.path)}>
|
|
35896
36046
|
<swc-icon-checkmark slot="icon"></swc-icon-checkmark><span class="label">Accept</span>
|
|
35897
36047
|
</swc-action-button>
|
|
35898
36048
|
<swc-action-button size="s" quiet data-action="revert" accessible-label="Revert" title="Revert" @click=${() => this.#revert(port, change)}>
|
|
@@ -36176,6 +36326,19 @@ var navigation = /* @__PURE__ */ new Set([
|
|
|
36176
36326
|
]);
|
|
36177
36327
|
var upward = /* @__PURE__ */ new Set(["ArrowUp", "PageUp", "Home"]);
|
|
36178
36328
|
var compactWidth = 560;
|
|
36329
|
+
function pendingKeys(messages) {
|
|
36330
|
+
return messages.flatMap((message) => {
|
|
36331
|
+
if (waiting(message)) return [message.id];
|
|
36332
|
+
if (message.role !== "assistant") return [];
|
|
36333
|
+
return message.parts.flatMap(
|
|
36334
|
+
(part2) => part2.type === "question" && part2.question.state === "open" ? [`${message.id}:${part2.question.id}`] : []
|
|
36335
|
+
);
|
|
36336
|
+
});
|
|
36337
|
+
}
|
|
36338
|
+
function pendingPiles(messages) {
|
|
36339
|
+
const keys = pendingKeys(messages);
|
|
36340
|
+
return new Map(keys.map((key2, stack) => [key2, { stack }]));
|
|
36341
|
+
}
|
|
36179
36342
|
var failed = (message) => message.role === "assistant" ? message.status === "error" : message.role === "system" && message.kind === "error";
|
|
36180
36343
|
function carriesFiles(event2) {
|
|
36181
36344
|
const types = [...event2.dataTransfer?.types ?? []];
|
|
@@ -36324,6 +36487,7 @@ var SliccChat = class extends ThemedElement {
|
|
|
36324
36487
|
padding: var(--swc-spacing-400) var(--swc-spacing-300) calc(var(--composer-height, 0px) + var(--swc-spacing-500));
|
|
36325
36488
|
scroll-padding-block-end: calc(var(--composer-height, 0px) + var(--swc-spacing-200));
|
|
36326
36489
|
font-size: var(--swc-font-size-200);
|
|
36490
|
+
scroll-padding-block-start: var(--pile, 0px);
|
|
36327
36491
|
}
|
|
36328
36492
|
@container (min-width: 600px) {
|
|
36329
36493
|
.column {
|
|
@@ -36429,7 +36593,21 @@ var SliccChat = class extends ThemedElement {
|
|
|
36429
36593
|
#from = 0;
|
|
36430
36594
|
#start = 0;
|
|
36431
36595
|
#settle;
|
|
36596
|
+
#tick;
|
|
36432
36597
|
#tail = "";
|
|
36598
|
+
#held = "";
|
|
36599
|
+
#focused = (event2) => {
|
|
36600
|
+
const turn = event2.target.closest(".decision-turn[data-pending]");
|
|
36601
|
+
this.#held = turn?.dataset.id ?? "";
|
|
36602
|
+
if (turn && Number(turn.style.getPropertyValue("--depth")) > 0) show(turn);
|
|
36603
|
+
};
|
|
36604
|
+
#refocus() {
|
|
36605
|
+
if (!this.#held || this.renderRoot.querySelector(":focus")) return;
|
|
36606
|
+
this.#held = "";
|
|
36607
|
+
const next = this.renderRoot.querySelector(".decision-turn[data-pending]");
|
|
36608
|
+
if (next) next.focus();
|
|
36609
|
+
else this.renderRoot.querySelector("slicc-composer")?.focus();
|
|
36610
|
+
}
|
|
36433
36611
|
#sent(agentId) {
|
|
36434
36612
|
const last = this.model?.agent.messages(agentId).at(-1);
|
|
36435
36613
|
return last?.role === "user" && last.id !== this.#tail && (last.origin ?? "user") === "user";
|
|
@@ -36458,6 +36636,7 @@ var SliccChat = class extends ThemedElement {
|
|
|
36458
36636
|
else if (reader && log.scrollTop < this.#last) this.#stuck = false;
|
|
36459
36637
|
this.#last = log.scrollTop;
|
|
36460
36638
|
this.#height = log.scrollHeight;
|
|
36639
|
+
this.#pile();
|
|
36461
36640
|
};
|
|
36462
36641
|
#intent = {
|
|
36463
36642
|
passive: true,
|
|
@@ -36505,9 +36684,6 @@ var SliccChat = class extends ThemedElement {
|
|
|
36505
36684
|
if (composer) this.#fit.observe(composer);
|
|
36506
36685
|
else this.style.setProperty("--composer-height", "0px");
|
|
36507
36686
|
}
|
|
36508
|
-
updated() {
|
|
36509
|
-
this.#attach();
|
|
36510
|
-
}
|
|
36511
36687
|
connectedCallback() {
|
|
36512
36688
|
super.connectedCallback();
|
|
36513
36689
|
globalThis.addEventListener("pointerup", this.#release, true);
|
|
@@ -36522,6 +36698,59 @@ var SliccChat = class extends ThemedElement {
|
|
|
36522
36698
|
this.#fit.disconnect();
|
|
36523
36699
|
this.#fitted = null;
|
|
36524
36700
|
clearTimeout(this.#settle);
|
|
36701
|
+
clearInterval(this.#tick);
|
|
36702
|
+
this.#tick = void 0;
|
|
36703
|
+
}
|
|
36704
|
+
updated() {
|
|
36705
|
+
this.#attach();
|
|
36706
|
+
const timed = this.#timed();
|
|
36707
|
+
if (timed && this.#tick === void 0)
|
|
36708
|
+
this.#tick = setInterval(() => this.requestUpdate(), 1e3);
|
|
36709
|
+
if (!timed && this.#tick !== void 0) {
|
|
36710
|
+
clearInterval(this.#tick);
|
|
36711
|
+
this.#tick = void 0;
|
|
36712
|
+
}
|
|
36713
|
+
this.#pile();
|
|
36714
|
+
this.#refocus();
|
|
36715
|
+
}
|
|
36716
|
+
#pile() {
|
|
36717
|
+
const turns = [
|
|
36718
|
+
...this.renderRoot.querySelectorAll(".decision-turn[data-pending]")
|
|
36719
|
+
];
|
|
36720
|
+
const drawn = turns.map((turn) => turn.getBoundingClientRect().top);
|
|
36721
|
+
for (const turn of turns) turn.style.position = "static";
|
|
36722
|
+
const flow = turns.map((turn) => turn.getBoundingClientRect().top);
|
|
36723
|
+
for (const turn of turns) turn.style.position = "";
|
|
36724
|
+
const pinned = turns.flatMap(
|
|
36725
|
+
(turn, index) => drawn[index] - flow[index] > 1 ? [{ turn, stack: Number.parseFloat(turn.style.getPropertyValue("--stack")) }] : []
|
|
36726
|
+
);
|
|
36727
|
+
for (const turn of turns) {
|
|
36728
|
+
if (!pinned.some((entry) => entry.turn === turn)) {
|
|
36729
|
+
turn.removeAttribute("data-pinned");
|
|
36730
|
+
turn.style.removeProperty("--depth");
|
|
36731
|
+
}
|
|
36732
|
+
}
|
|
36733
|
+
for (const { turn, stack } of pinned) {
|
|
36734
|
+
turn.setAttribute("data-pinned", "");
|
|
36735
|
+
turn.style.setProperty(
|
|
36736
|
+
"--depth",
|
|
36737
|
+
String(pinned.filter((other) => other.stack > stack).length)
|
|
36738
|
+
);
|
|
36739
|
+
}
|
|
36740
|
+
const log = this.renderRoot.querySelector(".log");
|
|
36741
|
+
const top = log?.getBoundingClientRect().top ?? 0;
|
|
36742
|
+
const reach3 = Math.max(
|
|
36743
|
+
0,
|
|
36744
|
+
...pinned.map(({ turn }) => turn.getBoundingClientRect().bottom - top)
|
|
36745
|
+
);
|
|
36746
|
+
log?.style.setProperty("--pile", `${reach3}px`);
|
|
36747
|
+
}
|
|
36748
|
+
#timed() {
|
|
36749
|
+
const model = this.model;
|
|
36750
|
+
if (!model) return false;
|
|
36751
|
+
return model.agent.messages(this.#id()).some(
|
|
36752
|
+
(message) => waiting(message) && "expiresAt" in message && message.expiresAt !== void 0
|
|
36753
|
+
);
|
|
36525
36754
|
}
|
|
36526
36755
|
firstUpdated() {
|
|
36527
36756
|
this.#observe();
|
|
@@ -36574,7 +36803,7 @@ var SliccChat = class extends ThemedElement {
|
|
|
36574
36803
|
new CustomEvent("show-surface", { detail: { id: "settings" }, bubbles: true, composed: true })
|
|
36575
36804
|
);
|
|
36576
36805
|
}
|
|
36577
|
-
#message(message, agent, suggestion, changed, extra, owners, stamp) {
|
|
36806
|
+
#message(message, agent, suggestion, changed, extra, owners, stamp, pile) {
|
|
36578
36807
|
const model = this.model;
|
|
36579
36808
|
const handlers = { ...this.#handlers, owners };
|
|
36580
36809
|
switch (message.role) {
|
|
@@ -36598,7 +36827,7 @@ var SliccChat = class extends ThemedElement {
|
|
|
36598
36827
|
case "system":
|
|
36599
36828
|
return system(message, this.#handlers);
|
|
36600
36829
|
default:
|
|
36601
|
-
return lick(message, this.#handlers, stamp);
|
|
36830
|
+
return lick(message, this.#handlers, stamp, pile);
|
|
36602
36831
|
}
|
|
36603
36832
|
}
|
|
36604
36833
|
#items(messages, agent) {
|
|
@@ -36613,6 +36842,7 @@ var SliccChat = class extends ThemedElement {
|
|
|
36613
36842
|
const owners = /* @__PURE__ */ new Map();
|
|
36614
36843
|
const into = /* @__PURE__ */ new Map();
|
|
36615
36844
|
const stamped = stamps(messages);
|
|
36845
|
+
const piles = pendingPiles(messages);
|
|
36616
36846
|
let anchor = null;
|
|
36617
36847
|
for (const message of messages) {
|
|
36618
36848
|
const calls = toolOnly(message, showThinking);
|
|
@@ -36653,12 +36883,24 @@ var SliccChat = class extends ThemedElement {
|
|
|
36653
36883
|
changed,
|
|
36654
36884
|
extra.get(message.id) ?? [],
|
|
36655
36885
|
owners,
|
|
36656
|
-
stamped.has(message.id)
|
|
36886
|
+
stamped.has(message.id),
|
|
36887
|
+
piles.get(message.id) ?? flatPile
|
|
36657
36888
|
)
|
|
36658
36889
|
]);
|
|
36890
|
+
out.push(...this.#questions(message, piles));
|
|
36659
36891
|
}
|
|
36660
36892
|
return out;
|
|
36661
36893
|
}
|
|
36894
|
+
#questions(message, piles) {
|
|
36895
|
+
if (message.role !== "assistant") return [];
|
|
36896
|
+
return message.parts.flatMap((part2) => {
|
|
36897
|
+
if (part2.type !== "question") return [];
|
|
36898
|
+
const key2 = `${message.id}:${part2.question.id}`;
|
|
36899
|
+
return [
|
|
36900
|
+
[key2, questionTurn(part2.question, this.#handlers, piles.get(key2) ?? flatPile)]
|
|
36901
|
+
];
|
|
36902
|
+
});
|
|
36903
|
+
}
|
|
36662
36904
|
#newChat(agent) {
|
|
36663
36905
|
this.model.agent.clear(agent.id);
|
|
36664
36906
|
this.renderRoot.querySelector("slicc-composer")?.focus();
|
|
@@ -36720,13 +36962,14 @@ var SliccChat = class extends ThemedElement {
|
|
|
36720
36962
|
@touchmove=${this.#intent}
|
|
36721
36963
|
@keydown=${this.#intent}
|
|
36722
36964
|
@pointerdown=${this.#hold}
|
|
36965
|
+
@focusin=${this.#focused}
|
|
36723
36966
|
>
|
|
36724
36967
|
<div class="column" @keydown=${this.#keys}>
|
|
36725
36968
|
${agent && messages.length > 0 ? b`<swc-conversation-thread>${c(
|
|
36726
36969
|
this.#items(messages, agent),
|
|
36727
36970
|
([key2]) => key2,
|
|
36728
36971
|
([, item2]) => item2
|
|
36729
|
-
)}</swc-conversation-thread>` : this.model?.tabs?.state().role === "connecting" ? b`<div class="empty" data-connecting>${connecting}</div>` : b`<div class="empty"
|
|
36972
|
+
)}</swc-conversation-thread>` : this.model?.tabs?.state().role === "connecting" ? b`<div class="empty" data-connecting>${connecting}</div>` : b`<div class="empty">${watch ? "No messages yet." : `No messages yet. Ask ${agent?.name ?? "the agent"} something.`}</div>`}
|
|
36730
36973
|
</div>
|
|
36731
36974
|
</div>
|
|
36732
36975
|
${this.dropping ? b`<swc-dropzone dragged size="l" aria-label="Attach files" dragged-message="Drop to attach"><p>Drop to attach</p></swc-dropzone>` : A}
|
|
@@ -37933,14 +38176,14 @@ function release(attachments) {
|
|
|
37933
38176
|
}
|
|
37934
38177
|
function retire(agent, id, attachments) {
|
|
37935
38178
|
const urls = new Set(attachments.flatMap((attachment2) => attachment2.url ?? []));
|
|
37936
|
-
const
|
|
38179
|
+
const waiting3 = () => agent.queue(id).some((message) => message.attachments?.some((attachment2) => urls.has(attachment2.url ?? "")));
|
|
37937
38180
|
const later = () => void setTimeout(() => release(attachments), linger);
|
|
37938
|
-
if (!
|
|
38181
|
+
if (!waiting3()) {
|
|
37939
38182
|
later();
|
|
37940
38183
|
return;
|
|
37941
38184
|
}
|
|
37942
38185
|
const off = agent.on("messages", () => {
|
|
37943
|
-
if (
|
|
38186
|
+
if (waiting3()) return;
|
|
37944
38187
|
off();
|
|
37945
38188
|
later();
|
|
37946
38189
|
});
|
|
@@ -38760,7 +39003,7 @@ var SliccComposer = class extends ThemedElement {
|
|
|
38760
39003
|
if (popup2.kind === "secret") {
|
|
38761
39004
|
const vault = this.model?.vault;
|
|
38762
39005
|
const valued = !!vault?.put && !blocked(vault);
|
|
38763
|
-
const
|
|
39006
|
+
const waiting3 = vault?.put ? blocked(vault) : null;
|
|
38764
39007
|
if (!valued) clearValues(this.renderRoot);
|
|
38765
39008
|
const submit = (event2) => {
|
|
38766
39009
|
event2.preventDefault();
|
|
@@ -38779,7 +39022,7 @@ var SliccComposer = class extends ThemedElement {
|
|
|
38779
39022
|
const described = (name) => this.secretField === name ? "secret-error" : A;
|
|
38780
39023
|
return b`<form class="popup secret" data-vault=${valued ? "on" : "off"} @submit=${submit} @keydown=${close} @input=${() => this.secretField = null}>
|
|
38781
39024
|
<strong>Share a secret</strong>
|
|
38782
|
-
<span class="lead">${valued ? "The value goes to the vault; the agent only sees its name. Leave the value empty to share a secret the vault already has." :
|
|
39025
|
+
<span class="lead">${valued ? "The value goes to the vault; the agent only sees its name. Leave the value empty to share a secret the vault already has." : waiting3 === "Unlock the vault first" ? "The vault is locked. You can share the name now and add the value once it is unlocked." : waiting3 ? "Waiting for the vault. You can share the name now and add the value in Settings \u203A Secrets later." : "Add the value in Settings \u203A Secrets. The agent only sees the name."}</span>
|
|
38783
39026
|
<label class="field"><span>Name</span><input name="name" placeholder="API_TOKEN" autocomplete="off" spellcheck="false" aria-invalid=${bad("name")} aria-describedby=${described("name")} /></label>
|
|
38784
39027
|
${valued ? b`<label class="field"><span>Value</span><input name="value" type="password" autocomplete="off" spellcheck="false" aria-invalid=${bad("value")} aria-describedby=${described("value")} /></label>` : A}
|
|
38785
39028
|
${this.secretError ? b`<span class="secret-error" role="alert" id="secret-error" data-error><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><span>${this.secretError}</span></span>` : A}
|
|
@@ -39502,7 +39745,7 @@ var SliccNotices = class extends ModelElement {
|
|
|
39502
39745
|
(notice) => notice.dismissible === false || !this.dismissed.has(notice.id)
|
|
39503
39746
|
);
|
|
39504
39747
|
const tabs = this.#tabs();
|
|
39505
|
-
const approvals = this.model?.approvals?.decide ? [] :
|
|
39748
|
+
const approvals = this.model?.approvals?.decide ? [] : waiting2(this.model, Date.now());
|
|
39506
39749
|
if (!notices.length && !approvals.length && tabs === A) return A;
|
|
39507
39750
|
return b`<div class="notices">${tabs}${approvals.map((approval) => this.#approval(approval))}${c(
|
|
39508
39751
|
notices,
|
|
@@ -40453,7 +40696,7 @@ var SliccSecrets = class extends ThemedElement {
|
|
|
40453
40696
|
}
|
|
40454
40697
|
#secret(vault, secret, entries, devices, more, locked) {
|
|
40455
40698
|
const kind = kinds[secret.kind];
|
|
40456
|
-
const
|
|
40699
|
+
const reveal2 = revealed(secret.name, entries, Date.now(), more);
|
|
40457
40700
|
const exec = execLine(secret.exec, secret.execArgv);
|
|
40458
40701
|
const gone3 = secret.state === "removed";
|
|
40459
40702
|
const form = this.#offline ? null : this.form;
|
|
@@ -40467,7 +40710,7 @@ var SliccSecrets = class extends ThemedElement {
|
|
|
40467
40710
|
<dl>
|
|
40468
40711
|
${this.#reach(secret, gone3)}
|
|
40469
40712
|
${secret.exits ? b`<dt>${gone3 ? "Left through" : "Leaves through"}</dt><dd data-exits>${secret.exits.length ? list4(secret.exits.map((exit) => exitLabel(exit, devices))) : "No exit"}</dd>` : A}
|
|
40470
|
-
${exec ||
|
|
40713
|
+
${exec || reveal2 ? b`<dt>Programs</dt><dd data-exec>${exec}${exec && reveal2 ? b`<br />` : A}${reveal2}</dd>` : A}
|
|
40471
40714
|
${secret.kind === "model" && secret.provider ? b`<dt>Provider</dt><dd data-provider>${this.#providerName(secret.provider)}</dd>` : A}
|
|
40472
40715
|
${secret.kind === "mcp" && secret.server ? b`<dt>Server</dt><dd data-server>${secret.server}</dd>` : A}
|
|
40473
40716
|
<dt>From</dt>
|
|
@@ -40576,7 +40819,7 @@ var SliccSecrets = class extends ThemedElement {
|
|
|
40576
40819
|
this.#offline = away(vault);
|
|
40577
40820
|
if (this.#offline && this.form) clearValues(this.renderRoot);
|
|
40578
40821
|
const now = Date.now();
|
|
40579
|
-
const
|
|
40822
|
+
const waiting3 = (status2?.waiting ?? []).filter((request2) => request2.expiresAt > now);
|
|
40580
40823
|
return b`<section aria-labelledby="secrets" data-vault=${status2 ? status2.locked ? "locked" : "unlocked" : "loading"}>
|
|
40581
40824
|
<div class="head">
|
|
40582
40825
|
<h2 id="secrets">Secrets</h2>
|
|
@@ -40586,7 +40829,7 @@ var SliccSecrets = class extends ThemedElement {
|
|
|
40586
40829
|
${this.#availability()}
|
|
40587
40830
|
${this.#feedback()}
|
|
40588
40831
|
${this.failure ? this.#error(this.failure, "vault") : A}
|
|
40589
|
-
${
|
|
40832
|
+
${waiting3.length ? b`<h3>Waiting for you</h3>${waiting3.map((request2) => this.#request(vault, request2))}` : A}
|
|
40590
40833
|
${this.#backup(vault, status2)}
|
|
40591
40834
|
${this.#tools(vault, locked)}
|
|
40592
40835
|
${!current ? this.#offline ? A : b`<p class="muted" data-loading>Loading secrets…</p>` : current.secrets.length ? this.#secrets(vault, current, entries, devices, locked) : b`<p data-empty>No secrets yet. Add one here, or enter the value when an agent or program asks for one.</p>`}
|
|
@@ -41474,6 +41717,9 @@ var SliccSprinkle = class extends ThemedElement {
|
|
|
41474
41717
|
height: auto;
|
|
41475
41718
|
background: none;
|
|
41476
41719
|
}
|
|
41720
|
+
:host([inline]) .handle {
|
|
41721
|
+
margin-inline-start: 20px;
|
|
41722
|
+
}
|
|
41477
41723
|
iframe {
|
|
41478
41724
|
display: block;
|
|
41479
41725
|
width: 100%;
|