@standardagents/code 0.14.1-issue.653.6647dc-linux-x64-gnu → 0.14.1-issue.658.a1599e-darwin-arm64
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/Standard Code Daemon.app/Contents/CodeResources +0 -0
- package/Standard Code Daemon.app/Contents/Helpers/tmux +0 -0
- package/Standard Code Daemon.app/Contents/Info.plist +42 -0
- package/Standard Code Daemon.app/Contents/MacOS/standardd +4 -0
- package/{lib/standard-plugin-runner/index.mjs → Standard Code Daemon.app/Contents/Resources/plugin-runner/index.mjs } +62 -30
- package/{lib/standard-plugin-runner/runtime.json → Standard Code Daemon.app/Contents/Resources/plugin-runner/runtime.json } +1 -1
- package/{lib/standard-plugin-runner/sdk.mjs → Standard Code Daemon.app/Contents/Resources/plugin-runner/sdk.mjs } +141 -77
- package/{lib/standard-plugin-runner/worker.mjs → Standard Code Daemon.app/Contents/Resources/plugin-runner/worker.mjs } +188 -86
- package/Standard Code Daemon.app/Contents/Resources/tmux/TMUX-ARTIFACT-MANIFEST.sha256 +6 -0
- package/Standard Code Daemon.app/Contents/Resources/tmux/TMUX-ARTIFACT-METADATA.txt +23 -0
- package/Standard Code Daemon.app/Contents/Resources/tmux/TMUX-BUILD-TOOLS.txt +11 -0
- package/Standard Code Daemon.app/Contents/Resources/tmux/TMUX-OTOOL-L.txt +4 -0
- package/Standard Code Daemon.app/Contents/Resources/tmux/TMUX-SIGNED-RUNTIME.sha256 +1 -0
- package/Standard Code Daemon.app/Contents/Resources/tmux/licenses/libevent.txt +99 -0
- package/Standard Code Daemon.app/Contents/Resources/tmux/licenses/tmux.txt +13 -0
- package/Standard Code Daemon.app/Contents/_CodeSignature/CodeResources +269 -0
- package/Standard Code.app/Contents/CodeResources +0 -0
- package/Standard Code.app/Contents/Info.plist +42 -0
- package/Standard Code.app/Contents/MacOS/standard +0 -0
- package/Standard Code.app/Contents/_CodeSignature/CodeResources +115 -0
- package/licenses/THIRD-PARTY.txt +0 -33
- package/manifest.json +1 -1
- package/manifest.sig +1 -1
- package/package.json +6 -9
- package/bin/standard +0 -4
- package/bin/standardd +0 -4
- package/bin/tmux +0 -0
- /package/{lib/standard-plugin-runner → Standard Code Daemon.app/Contents/Resources/plugin-runner}/THIRD-PARTY.txt +0 -0
- /package/{lib/standard-plugin-runner → Standard Code Daemon.app/Contents/Resources/plugin-runner}/loader.mjs +0 -0
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>CFBundleDisplayName</key>
|
|
6
|
+
<string>Standard Code Daemon</string>
|
|
7
|
+
<key>CFBundleExecutable</key>
|
|
8
|
+
<string>standardd</string>
|
|
9
|
+
<key>CFBundleIdentifier</key>
|
|
10
|
+
<string>ai.standardcode.standardd</string>
|
|
11
|
+
<key>CFBundleInfoDictionaryVersion</key>
|
|
12
|
+
<string>6.0</string>
|
|
13
|
+
<key>CFBundleName</key>
|
|
14
|
+
<string>Standard Code Daemon</string>
|
|
15
|
+
<key>CFBundlePackageType</key>
|
|
16
|
+
<string>APPL</string>
|
|
17
|
+
<key>CFBundleShortVersionString</key>
|
|
18
|
+
<string>0.14.1-issue.658.a1599e</string>
|
|
19
|
+
<key>CFBundleVersion</key>
|
|
20
|
+
<string>1</string>
|
|
21
|
+
<key>LSBackgroundOnly</key>
|
|
22
|
+
<true/>
|
|
23
|
+
<key>LSMinimumSystemVersion</key>
|
|
24
|
+
<string>11.0</string>
|
|
25
|
+
<key>NSLocalNetworkUsageDescription</key>
|
|
26
|
+
<string>Standard Code uses your local network to establish faster, encrypted direct connections to your other devices.</string>
|
|
27
|
+
<key>StandardCodeChannel</key>
|
|
28
|
+
<string>team</string>
|
|
29
|
+
<key>StandardCodeCommit</key>
|
|
30
|
+
<string>a1599e20b8d4621a2b3bcd0fd9023a4cb66bb96e</string>
|
|
31
|
+
<key>StandardCodeComponent</key>
|
|
32
|
+
<string>standardd</string>
|
|
33
|
+
<key>StandardCodeRelease</key>
|
|
34
|
+
<string>npm-a1599e20b8d4</string>
|
|
35
|
+
<key>StandardCodeTmuxSHA256</key>
|
|
36
|
+
<string>2875498eaff99cdb5b422198ff74befc39381bdd869e8e0210a097f0dc61027c</string>
|
|
37
|
+
<key>StandardCodeUnixProtocol</key>
|
|
38
|
+
<integer>1</integer>
|
|
39
|
+
<key>StandardCodeVersion</key>
|
|
40
|
+
<string>0.14.1-issue.658.a1599e</string>
|
|
41
|
+
</dict>
|
|
42
|
+
</plist>
|
|
@@ -29,7 +29,22 @@ var SURFACE_KINDS = Object.freeze([
|
|
|
29
29
|
"key",
|
|
30
30
|
"link"
|
|
31
31
|
]);
|
|
32
|
-
var PRESENTATIONS = Object.freeze(["popover", "column", "pane"]);
|
|
32
|
+
var PRESENTATIONS = Object.freeze(["popover", "column", "pane", "stage"]);
|
|
33
|
+
var MUX_EXPRESSIONS = Object.freeze([
|
|
34
|
+
"neutral",
|
|
35
|
+
"blink",
|
|
36
|
+
"happy",
|
|
37
|
+
"happy-smile",
|
|
38
|
+
"sad",
|
|
39
|
+
"grin",
|
|
40
|
+
"surprise",
|
|
41
|
+
"sleepy",
|
|
42
|
+
"angry",
|
|
43
|
+
"focus",
|
|
44
|
+
"question",
|
|
45
|
+
"exclaim",
|
|
46
|
+
"cross"
|
|
47
|
+
]);
|
|
33
48
|
var ANCHORS = Object.freeze([
|
|
34
49
|
"plugins",
|
|
35
50
|
"machine.before",
|
|
@@ -58,6 +73,7 @@ var LIMITS = Object.freeze({
|
|
|
58
73
|
canvasColumns: 512,
|
|
59
74
|
canvasRows: 256,
|
|
60
75
|
canvasHoverBytes: 512,
|
|
76
|
+
canvasShapes: 256,
|
|
61
77
|
stateKeys: 256,
|
|
62
78
|
stateValueBytes: 64 * 1024
|
|
63
79
|
});
|
|
@@ -71,13 +87,13 @@ var PluginError = class extends Error {
|
|
|
71
87
|
function ensure(condition, code, message) {
|
|
72
88
|
if (!condition) throw new PluginError(code, message);
|
|
73
89
|
}
|
|
74
|
-
function object(
|
|
75
|
-
return
|
|
90
|
+
function object(value2) {
|
|
91
|
+
return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
|
|
76
92
|
}
|
|
77
|
-
function identifier(
|
|
78
|
-
return typeof
|
|
93
|
+
function identifier(value2) {
|
|
94
|
+
return typeof value2 === "string" && /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/.test(value2);
|
|
79
95
|
}
|
|
80
|
-
function jsonBytes(
|
|
96
|
+
function jsonBytes(value2, limit = LIMITS.frameBytes) {
|
|
81
97
|
const seen = /* @__PURE__ */ new Set();
|
|
82
98
|
function visit(item, depth) {
|
|
83
99
|
ensure(depth <= 32, "invalid_payload", "JSON nesting exceeds 32 levels");
|
|
@@ -93,21 +109,21 @@ function jsonBytes(value, limit = LIMITS.frameBytes) {
|
|
|
93
109
|
for (const child of Object.values(item)) visit(child, depth + 1);
|
|
94
110
|
seen.delete(item);
|
|
95
111
|
}
|
|
96
|
-
visit(
|
|
97
|
-
const text = JSON.stringify(
|
|
112
|
+
visit(value2, 0);
|
|
113
|
+
const text = JSON.stringify(value2);
|
|
98
114
|
ensure(Buffer.byteLength(text) <= limit, "payload_too_large", `Payload exceeds ${limit} bytes`);
|
|
99
115
|
return text;
|
|
100
116
|
}
|
|
101
|
-
function freeze(
|
|
102
|
-
if (
|
|
103
|
-
Object.values(
|
|
104
|
-
Object.freeze(
|
|
117
|
+
function freeze(value2) {
|
|
118
|
+
if (value2 && typeof value2 === "object") {
|
|
119
|
+
Object.values(value2).forEach(freeze);
|
|
120
|
+
Object.freeze(value2);
|
|
105
121
|
}
|
|
106
|
-
return
|
|
122
|
+
return value2;
|
|
107
123
|
}
|
|
108
|
-
function validateManifest(
|
|
109
|
-
ensure(object(
|
|
110
|
-
jsonBytes(
|
|
124
|
+
function validateManifest(value2) {
|
|
125
|
+
ensure(object(value2), "invalid_manifest", "package.json must contain a standardPlugin object");
|
|
126
|
+
jsonBytes(value2, LIMITS.manifestBytes);
|
|
111
127
|
const allowed = [
|
|
112
128
|
"apiVersion",
|
|
113
129
|
"id",
|
|
@@ -121,8 +137,8 @@ function validateManifest(value) {
|
|
|
121
137
|
"configSchema",
|
|
122
138
|
"hookTimeoutMs"
|
|
123
139
|
];
|
|
124
|
-
ensure(Object.keys(
|
|
125
|
-
const manifest = structuredClone({ singleton: false, order: 0, capabilities: [], contributions: [], hookTimeoutMs: 5e3, ...
|
|
140
|
+
ensure(Object.keys(value2).every((key) => allowed.includes(key)), "invalid_manifest", "Unknown manifest field");
|
|
141
|
+
const manifest = structuredClone({ singleton: false, order: 0, capabilities: [], contributions: [], hookTimeoutMs: 5e3, ...value2 });
|
|
126
142
|
ensure(manifest.apiVersion === 1, "incompatible_version", "Plugin requires a different SDK API version");
|
|
127
143
|
ensure(identifier(manifest.id), "invalid_manifest", "Plugin id must be a stable identifier");
|
|
128
144
|
ensure(
|
|
@@ -192,6 +208,11 @@ function validateManifest(value) {
|
|
|
192
208
|
"Only panels, cards, and commands declare a presentation"
|
|
193
209
|
);
|
|
194
210
|
ensure(declaration.kind !== "card" || declaration.anchor === "plugins", "invalid_manifest", "Cards use the plugins anchor");
|
|
211
|
+
ensure(
|
|
212
|
+
declaration.presentation !== "stage" || declaration.kind !== "panel" || declaration.anchor === "account",
|
|
213
|
+
"invalid_manifest",
|
|
214
|
+
"Stage panels use the account anchor"
|
|
215
|
+
);
|
|
195
216
|
}
|
|
196
217
|
for (const declaration of manifest.contributions) {
|
|
197
218
|
ensure(
|
|
@@ -346,11 +367,11 @@ var RpcPeer = class {
|
|
|
346
367
|
const id = `${this.idPrefix}-${++this.nextId}`;
|
|
347
368
|
return new Promise((resolve2, reject) => {
|
|
348
369
|
let timer;
|
|
349
|
-
const finish = (error,
|
|
370
|
+
const finish = (error, value2) => {
|
|
350
371
|
if (!this.pending.delete(id)) return;
|
|
351
372
|
this.clock.clearTimeout(timer);
|
|
352
373
|
signal?.removeEventListener("abort", cancel);
|
|
353
|
-
error ? reject(error) : resolve2(
|
|
374
|
+
error ? reject(error) : resolve2(value2);
|
|
354
375
|
};
|
|
355
376
|
const cancelWith = (code) => {
|
|
356
377
|
finish(new PluginError(code, code === "timeout" ? "Request deadline elapsed" : "Request was cancelled"));
|
|
@@ -420,8 +441,8 @@ var RpcPeer = class {
|
|
|
420
441
|
ensure(!controller.signal.aborted, "cancelled", "Request was cancelled");
|
|
421
442
|
ensure(typeof this.onRequest === "function", "unsupported_operation", "No request handler");
|
|
422
443
|
return this.onRequest(frame.operation, { signal: controller.signal, timeoutMs: frame.timeoutMs });
|
|
423
|
-
}).then((
|
|
424
|
-
if (!controller.signal.aborted) respond({ ok: true, value:
|
|
444
|
+
}).then((value2) => {
|
|
445
|
+
if (!controller.signal.aborted) respond({ ok: true, value: value2 ?? null });
|
|
425
446
|
}, (error) => {
|
|
426
447
|
if (!controller.signal.aborted) respond({ ok: false, error: wireError(error) });
|
|
427
448
|
}).finally(() => {
|
|
@@ -456,14 +477,25 @@ var VIEW_LIMITS = Object.freeze({
|
|
|
456
477
|
actionValueBytes: 512
|
|
457
478
|
});
|
|
458
479
|
var TONES = Object.freeze(["ok", "info", "warn", "error", "muted", "accent", "pending", "bright"]);
|
|
459
|
-
function compact(
|
|
460
|
-
return Object.fromEntries(Object.entries(
|
|
480
|
+
function compact(value2) {
|
|
481
|
+
return Object.fromEntries(Object.entries(value2).filter(([, item]) => item !== void 0));
|
|
461
482
|
}
|
|
462
483
|
var node = (type, fields) => compact({ type, ...fields });
|
|
484
|
+
var clockTime = (at) => `${new Date(at).toISOString().slice(11, 16)} UTC`;
|
|
485
|
+
var timeSpan = (style, at, { text: fallback, tone, weight, mono } = {}) => compact({
|
|
486
|
+
text: fallback ?? (style === "duration" ? `since ${clockTime(at)}` : clockTime(at)),
|
|
487
|
+
tone,
|
|
488
|
+
weight,
|
|
489
|
+
mono,
|
|
490
|
+
time: { at: Math.max(0, Math.floor(at)), style }
|
|
491
|
+
});
|
|
492
|
+
var value = (content) => Array.isArray(content) ? { value: content.map((span) => span.text).join(""), valueSpans: content.map(compact) } : { value: content };
|
|
463
493
|
var ui = Object.freeze({
|
|
464
494
|
view: (root, { title } = {}) => compact({ kind: "view", root, title }),
|
|
465
|
-
action: (actionId, { value, opens, agentPicker } = {}) => compact({ actionId, value, opens, agentPicker }),
|
|
466
|
-
span: (
|
|
495
|
+
action: (actionId, { value: value2, opens, agentPicker } = {}) => compact({ actionId, value: value2, opens, agentPicker }),
|
|
496
|
+
span: (content, { tone, weight, mono, time } = {}) => compact({ text: content, tone, weight, mono, time }),
|
|
497
|
+
elapsed: (since, options) => timeSpan("duration", since, options),
|
|
498
|
+
relativeTime: (at, options) => timeSpan("relative", at, options),
|
|
467
499
|
stack: (items, { gap } = {}) => node("stack", { gap, children: items }),
|
|
468
500
|
row: (items, { align } = {}) => node("row", { children: items, align }),
|
|
469
501
|
divider: (label) => node("divider", { label }),
|
|
@@ -471,18 +503,18 @@ var ui = Object.freeze({
|
|
|
471
503
|
text: (content, { tone, weight, mono } = {}) => node("text", { ...Array.isArray(content) ? { spans: content.map(compact) } : { text: content }, tone, weight, mono }),
|
|
472
504
|
badge: (label, tone) => node("badge", { label, tone }),
|
|
473
505
|
dot: (tone) => node("dot", { tone }),
|
|
474
|
-
progress: (
|
|
506
|
+
progress: (value2, max, { tone, label } = {}) => node("progress", { value: value2, max, tone, label }),
|
|
475
507
|
segments: (items) => node("segments", { items: items.map(compact) }),
|
|
476
508
|
card: (items, { title, tone, tags, action, externalAction, footer } = {}) => node("card", { title, tone, tags, action, externalAction, footer, children: items }),
|
|
477
|
-
stat: (label,
|
|
478
|
-
kv: (items) => node("kv", { items: items.map(compact) }),
|
|
509
|
+
stat: (label, content, { tone, hint } = {}) => node("stat", { label, ...value(content), tone, hint }),
|
|
510
|
+
kv: (items) => node("kv", { items: items.map((item) => compact({ ...item, ...value(item.value) })) }),
|
|
479
511
|
tabs: (id, items, { filters, action } = {}) => node("tabs", { id, items: items.map(compact), filters, action }),
|
|
480
512
|
select: (id, label, options, { filters, action } = {}) => node("select", { id, label, options: options.map(compact), filters, action }),
|
|
481
513
|
table: (id, columns, rows = []) => node("table", { id, columns: columns.map(compact), rows: rows.map(compact) }),
|
|
482
514
|
log: (lines) => node("log", { lines }),
|
|
483
515
|
/** `action` is an action object or an action id. */
|
|
484
516
|
button: (label, action) => node("button", { label, action: typeof action === "string" ? { actionId: action } : action }),
|
|
485
|
-
input: (id,
|
|
517
|
+
input: (id, value2, action, { placeholder, maxLength } = {}) => node("input", { id, value: value2, placeholder, maxLength, action: typeof action === "string" ? { actionId: action } : action })
|
|
486
518
|
});
|
|
487
519
|
|
|
488
520
|
// ../plugin-sdk/src/runtime.mjs
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"schema":1,"productVersion":"0.14.1-issue.
|
|
1
|
+
{"schema":1,"productVersion":"0.14.1-issue.658.a1599e","commit":"a1599e20b8d4621a2b3bcd0fd9023a4cb66bb96e","protocolVersion":1,"sdkApiVersion":1,"minimumNodeMajor":20,"loader":{"typescript":"5.9.2"},"files":["index.mjs","worker.mjs","loader.mjs","sdk.mjs","runtime.json","THIRD-PARTY.txt"]}
|
|
@@ -25,7 +25,22 @@ var SURFACE_KINDS = Object.freeze([
|
|
|
25
25
|
"key",
|
|
26
26
|
"link"
|
|
27
27
|
]);
|
|
28
|
-
var PRESENTATIONS = Object.freeze(["popover", "column", "pane"]);
|
|
28
|
+
var PRESENTATIONS = Object.freeze(["popover", "column", "pane", "stage"]);
|
|
29
|
+
var MUX_EXPRESSIONS = Object.freeze([
|
|
30
|
+
"neutral",
|
|
31
|
+
"blink",
|
|
32
|
+
"happy",
|
|
33
|
+
"happy-smile",
|
|
34
|
+
"sad",
|
|
35
|
+
"grin",
|
|
36
|
+
"surprise",
|
|
37
|
+
"sleepy",
|
|
38
|
+
"angry",
|
|
39
|
+
"focus",
|
|
40
|
+
"question",
|
|
41
|
+
"exclaim",
|
|
42
|
+
"cross"
|
|
43
|
+
]);
|
|
29
44
|
var ANCHORS = Object.freeze([
|
|
30
45
|
"plugins",
|
|
31
46
|
"machine.before",
|
|
@@ -54,6 +69,7 @@ var LIMITS = Object.freeze({
|
|
|
54
69
|
canvasColumns: 512,
|
|
55
70
|
canvasRows: 256,
|
|
56
71
|
canvasHoverBytes: 512,
|
|
72
|
+
canvasShapes: 256,
|
|
57
73
|
stateKeys: 256,
|
|
58
74
|
stateValueBytes: 64 * 1024
|
|
59
75
|
});
|
|
@@ -67,13 +83,13 @@ var PluginError = class extends Error {
|
|
|
67
83
|
function ensure(condition, code, message) {
|
|
68
84
|
if (!condition) throw new PluginError(code, message);
|
|
69
85
|
}
|
|
70
|
-
function object(
|
|
71
|
-
return
|
|
86
|
+
function object(value2) {
|
|
87
|
+
return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
|
|
72
88
|
}
|
|
73
|
-
function identifier(
|
|
74
|
-
return typeof
|
|
89
|
+
function identifier(value2) {
|
|
90
|
+
return typeof value2 === "string" && /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/.test(value2);
|
|
75
91
|
}
|
|
76
|
-
function jsonBytes(
|
|
92
|
+
function jsonBytes(value2, limit = LIMITS.frameBytes) {
|
|
77
93
|
const seen = /* @__PURE__ */ new Set();
|
|
78
94
|
function visit(item, depth) {
|
|
79
95
|
ensure(depth <= 32, "invalid_payload", "JSON nesting exceeds 32 levels");
|
|
@@ -89,21 +105,21 @@ function jsonBytes(value, limit = LIMITS.frameBytes) {
|
|
|
89
105
|
for (const child of Object.values(item)) visit(child, depth + 1);
|
|
90
106
|
seen.delete(item);
|
|
91
107
|
}
|
|
92
|
-
visit(
|
|
93
|
-
const text2 = JSON.stringify(
|
|
108
|
+
visit(value2, 0);
|
|
109
|
+
const text2 = JSON.stringify(value2);
|
|
94
110
|
ensure(Buffer.byteLength(text2) <= limit, "payload_too_large", `Payload exceeds ${limit} bytes`);
|
|
95
111
|
return text2;
|
|
96
112
|
}
|
|
97
|
-
function freeze(
|
|
98
|
-
if (
|
|
99
|
-
Object.values(
|
|
100
|
-
Object.freeze(
|
|
113
|
+
function freeze(value2) {
|
|
114
|
+
if (value2 && typeof value2 === "object") {
|
|
115
|
+
Object.values(value2).forEach(freeze);
|
|
116
|
+
Object.freeze(value2);
|
|
101
117
|
}
|
|
102
|
-
return
|
|
118
|
+
return value2;
|
|
103
119
|
}
|
|
104
|
-
function validateManifest(
|
|
105
|
-
ensure(object(
|
|
106
|
-
jsonBytes(
|
|
120
|
+
function validateManifest(value2) {
|
|
121
|
+
ensure(object(value2), "invalid_manifest", "package.json must contain a standardPlugin object");
|
|
122
|
+
jsonBytes(value2, LIMITS.manifestBytes);
|
|
107
123
|
const allowed = [
|
|
108
124
|
"apiVersion",
|
|
109
125
|
"id",
|
|
@@ -117,8 +133,8 @@ function validateManifest(value) {
|
|
|
117
133
|
"configSchema",
|
|
118
134
|
"hookTimeoutMs"
|
|
119
135
|
];
|
|
120
|
-
ensure(Object.keys(
|
|
121
|
-
const manifest = structuredClone({ singleton: false, order: 0, capabilities: [], contributions: [], hookTimeoutMs: 5e3, ...
|
|
136
|
+
ensure(Object.keys(value2).every((key) => allowed.includes(key)), "invalid_manifest", "Unknown manifest field");
|
|
137
|
+
const manifest = structuredClone({ singleton: false, order: 0, capabilities: [], contributions: [], hookTimeoutMs: 5e3, ...value2 });
|
|
122
138
|
ensure(manifest.apiVersion === 1, "incompatible_version", "Plugin requires a different SDK API version");
|
|
123
139
|
ensure(identifier(manifest.id), "invalid_manifest", "Plugin id must be a stable identifier");
|
|
124
140
|
ensure(
|
|
@@ -188,6 +204,11 @@ function validateManifest(value) {
|
|
|
188
204
|
"Only panels, cards, and commands declare a presentation"
|
|
189
205
|
);
|
|
190
206
|
ensure(declaration.kind !== "card" || declaration.anchor === "plugins", "invalid_manifest", "Cards use the plugins anchor");
|
|
207
|
+
ensure(
|
|
208
|
+
declaration.presentation !== "stage" || declaration.kind !== "panel" || declaration.anchor === "account",
|
|
209
|
+
"invalid_manifest",
|
|
210
|
+
"Stage panels use the account anchor"
|
|
211
|
+
);
|
|
191
212
|
}
|
|
192
213
|
for (const declaration of manifest.contributions) {
|
|
193
214
|
ensure(
|
|
@@ -204,29 +225,29 @@ function validateManifest(value) {
|
|
|
204
225
|
// ../plugin-sdk/src/collection.mjs
|
|
205
226
|
var COLLECTION_FILE = "standard-plugins.json";
|
|
206
227
|
var COLLECTION_LIMITS = Object.freeze({ entries: 256, pathLength: 512 });
|
|
207
|
-
function relativePath(
|
|
208
|
-
return typeof
|
|
228
|
+
function relativePath(value2) {
|
|
229
|
+
return typeof value2 === "string" && value2.length > 0 && value2.length <= COLLECTION_LIMITS.pathLength && !/[\\]/.test(value2) && !value2.startsWith("/") && value2.split("/").every((part) => part && part !== "." && part !== "..");
|
|
209
230
|
}
|
|
210
|
-
function freeze2(
|
|
211
|
-
if (
|
|
212
|
-
Object.values(
|
|
213
|
-
Object.freeze(
|
|
231
|
+
function freeze2(value2) {
|
|
232
|
+
if (value2 && typeof value2 === "object") {
|
|
233
|
+
Object.values(value2).forEach(freeze2);
|
|
234
|
+
Object.freeze(value2);
|
|
214
235
|
}
|
|
215
|
-
return
|
|
236
|
+
return value2;
|
|
216
237
|
}
|
|
217
|
-
function validateCollection(
|
|
218
|
-
ensure(object(
|
|
219
|
-
jsonBytes(
|
|
220
|
-
ensure(Object.keys(
|
|
221
|
-
ensure(
|
|
238
|
+
function validateCollection(value2) {
|
|
239
|
+
ensure(object(value2), "invalid_collection", `${COLLECTION_FILE} must contain an object`);
|
|
240
|
+
jsonBytes(value2, LIMITS.manifestBytes);
|
|
241
|
+
ensure(Object.keys(value2).every((key) => ["schema", "plugins"].includes(key)), "invalid_collection", "Unknown collection field");
|
|
242
|
+
ensure(value2.schema === 1, "invalid_collection", "Collection schema must be 1");
|
|
222
243
|
ensure(
|
|
223
|
-
Array.isArray(
|
|
244
|
+
Array.isArray(value2.plugins) && value2.plugins.length >= 1 && value2.plugins.length <= COLLECTION_LIMITS.entries,
|
|
224
245
|
"invalid_collection",
|
|
225
246
|
`Collection must list between 1 and ${COLLECTION_LIMITS.entries} plugins`
|
|
226
247
|
);
|
|
227
248
|
const ids = /* @__PURE__ */ new Set();
|
|
228
249
|
const paths = /* @__PURE__ */ new Set();
|
|
229
|
-
const plugins =
|
|
250
|
+
const plugins = value2.plugins.map((entry) => {
|
|
230
251
|
ensure(object(entry) && Object.keys(entry).every((key) => ["id", "path"].includes(key)), "invalid_collection", "Invalid collection entry");
|
|
231
252
|
ensure(identifier(entry.id), "invalid_collection", "Collection entry id must be a stable identifier");
|
|
232
253
|
ensure(relativePath(entry.path), "invalid_collection", "Collection entry path must be a relative POSIX path");
|
|
@@ -314,68 +335,78 @@ var VIEW_LIMITS = Object.freeze({
|
|
|
314
335
|
});
|
|
315
336
|
var TONES = Object.freeze(["ok", "info", "warn", "error", "muted", "accent", "pending", "bright"]);
|
|
316
337
|
var WEIGHTS = ["normal", "bold", "dim"];
|
|
338
|
+
var TIME_STYLES = ["duration", "relative"];
|
|
317
339
|
var ALIGNS = ["start", "center", "end"];
|
|
318
340
|
var FORBIDDEN = /[\u0000-\u001f\u007f-\u009f\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/;
|
|
319
341
|
var invalid = (message) => ensure(false, "invalid_payload", message);
|
|
320
|
-
function text(
|
|
321
|
-
if (typeof
|
|
322
|
-
ensure(!FORBIDDEN.test(
|
|
342
|
+
function text(value2, field) {
|
|
343
|
+
if (typeof value2 !== "string") invalid(`Plugin view ${field} must be a string`);
|
|
344
|
+
ensure(!FORBIDDEN.test(value2), "invalid_payload", "Plugin view text contains a control or bidirectional character");
|
|
323
345
|
}
|
|
324
|
-
function optionalText(
|
|
325
|
-
if (
|
|
346
|
+
function optionalText(value2, field) {
|
|
347
|
+
if (value2 !== void 0) text(value2, field);
|
|
326
348
|
}
|
|
327
|
-
function choice(
|
|
328
|
-
ensure(
|
|
349
|
+
function choice(value2, choices, field) {
|
|
350
|
+
ensure(value2 === void 0 || choices.includes(value2), "invalid_payload", `Invalid plugin view ${field}`);
|
|
329
351
|
}
|
|
330
|
-
function tone(
|
|
331
|
-
choice(
|
|
352
|
+
function tone(value2) {
|
|
353
|
+
choice(value2, TONES, "tone");
|
|
332
354
|
}
|
|
333
|
-
function integer(
|
|
334
|
-
ensure(
|
|
355
|
+
function integer(value2, max, field) {
|
|
356
|
+
ensure(value2 === void 0 || Number.isInteger(value2) && value2 >= 0 && value2 <= max, "invalid_payload", `Invalid plugin view ${field}`);
|
|
335
357
|
}
|
|
336
|
-
function flag(
|
|
337
|
-
ensure(
|
|
358
|
+
function flag(value2, field) {
|
|
359
|
+
ensure(value2 === void 0 || typeof value2 === "boolean", "invalid_payload", `Invalid plugin view ${field}`);
|
|
338
360
|
}
|
|
339
|
-
function number(
|
|
340
|
-
ensure(typeof
|
|
361
|
+
function number(value2) {
|
|
362
|
+
ensure(typeof value2 === "number" && Number.isFinite(value2), "invalid_payload", "Plugin view number is not finite");
|
|
341
363
|
}
|
|
342
|
-
function list(
|
|
343
|
-
if (optional &&
|
|
344
|
-
ensure(Array.isArray(
|
|
345
|
-
return
|
|
364
|
+
function list(value2, field, optional = false) {
|
|
365
|
+
if (optional && value2 === void 0) return [];
|
|
366
|
+
ensure(Array.isArray(value2), "invalid_payload", `Plugin view ${field} must be an array`);
|
|
367
|
+
return value2;
|
|
346
368
|
}
|
|
347
|
-
function entries(
|
|
348
|
-
for (const item of list(
|
|
369
|
+
function entries(value2, field, optional, check) {
|
|
370
|
+
for (const item of list(value2, field, optional)) {
|
|
349
371
|
ensure(object(item), "invalid_payload", `Plugin view ${field} must contain objects`);
|
|
350
372
|
check(item);
|
|
351
373
|
}
|
|
352
374
|
}
|
|
353
|
-
function bounded(
|
|
354
|
-
const values = list(
|
|
375
|
+
function bounded(value2, field, limit, optional = false) {
|
|
376
|
+
const values = list(value2, field, optional);
|
|
355
377
|
ensure(values.length <= limit, "invalid_payload", `Plugin view ${field} has more than ${limit} entries`);
|
|
356
378
|
return values;
|
|
357
379
|
}
|
|
358
|
-
function boundedEntries(
|
|
359
|
-
entries(bounded(
|
|
380
|
+
function boundedEntries(value2, field, check) {
|
|
381
|
+
entries(bounded(value2, field, VIEW_LIMITS.items), field, false, check);
|
|
360
382
|
}
|
|
361
|
-
function spans(
|
|
362
|
-
entries(
|
|
383
|
+
function spans(value2, optional) {
|
|
384
|
+
entries(value2, "spans", optional, (span) => {
|
|
363
385
|
text(span.text, "span text");
|
|
364
386
|
tone(span.tone);
|
|
365
387
|
choice(span.weight, WEIGHTS, "weight");
|
|
366
388
|
flag(span.mono, "mono");
|
|
389
|
+
if (span.time !== void 0) {
|
|
390
|
+
ensure(
|
|
391
|
+
object(span.time) && Number.isSafeInteger(span.time.at) && span.time.at >= 0,
|
|
392
|
+
"invalid_payload",
|
|
393
|
+
"Plugin view time must be epoch milliseconds"
|
|
394
|
+
);
|
|
395
|
+
choice(span.time.style, TIME_STYLES, "time style");
|
|
396
|
+
ensure(span.time.style !== void 0, "invalid_payload", "Invalid plugin view time style");
|
|
397
|
+
}
|
|
367
398
|
});
|
|
368
399
|
}
|
|
369
|
-
function action(
|
|
370
|
-
if (optional &&
|
|
371
|
-
ensure(object(
|
|
372
|
-
text(
|
|
373
|
-
optionalText(
|
|
374
|
-
optionalText(
|
|
375
|
-
if (
|
|
376
|
-
ensure(object(
|
|
377
|
-
text(
|
|
378
|
-
text(
|
|
400
|
+
function action(value2, optional = true) {
|
|
401
|
+
if (optional && value2 === void 0) return;
|
|
402
|
+
ensure(object(value2), "invalid_payload", "Plugin view action must be an object");
|
|
403
|
+
text(value2.actionId, "action id");
|
|
404
|
+
optionalText(value2.value, "action value");
|
|
405
|
+
optionalText(value2.opens, "action opens");
|
|
406
|
+
if (value2.agentPicker !== void 0) {
|
|
407
|
+
ensure(object(value2.agentPicker), "invalid_payload", "Agent picker needs a project and machine");
|
|
408
|
+
text(value2.agentPicker.machineId, "agent picker machine");
|
|
409
|
+
text(value2.agentPicker.projectId, "agent picker project");
|
|
379
410
|
}
|
|
380
411
|
}
|
|
381
412
|
function meter(item) {
|
|
@@ -439,6 +470,7 @@ var NODES = {
|
|
|
439
470
|
stat(node2) {
|
|
440
471
|
text(node2.label, "label");
|
|
441
472
|
text(node2.value, "value");
|
|
473
|
+
spans(node2.valueSpans, true);
|
|
442
474
|
tone(node2.tone);
|
|
443
475
|
optionalText(node2.hint, "hint");
|
|
444
476
|
},
|
|
@@ -446,6 +478,7 @@ var NODES = {
|
|
|
446
478
|
boundedEntries(node2.items, "items", (item) => {
|
|
447
479
|
text(item.label, "label");
|
|
448
480
|
text(item.value, "value");
|
|
481
|
+
spans(item.valueSpans, true);
|
|
449
482
|
flag(item.mono, "mono");
|
|
450
483
|
flag(item.copy, "copy");
|
|
451
484
|
});
|
|
@@ -578,14 +611,43 @@ function validateView(root, { kind, manifest } = {}) {
|
|
|
578
611
|
ensure(cardLines(root) <= VIEW_LIMITS.cardLines, "payload_too_large", "A card view is taller than 6 lines");
|
|
579
612
|
}
|
|
580
613
|
}
|
|
581
|
-
function compact(
|
|
582
|
-
return Object.fromEntries(Object.entries(
|
|
614
|
+
function compact(value2) {
|
|
615
|
+
return Object.fromEntries(Object.entries(value2).filter(([, item]) => item !== void 0));
|
|
583
616
|
}
|
|
584
617
|
var node = (type, fields) => compact({ type, ...fields });
|
|
618
|
+
function formatTime({ at, style }, now) {
|
|
619
|
+
const elapsed = Math.max(0, now - at);
|
|
620
|
+
if (style === "duration") {
|
|
621
|
+
const seconds2 = Math.floor(elapsed / 1e3);
|
|
622
|
+
const minutes2 = Math.floor(seconds2 / 60), hours2 = Math.floor(minutes2 / 60);
|
|
623
|
+
const pad = (value2) => String(value2).padStart(2, "0");
|
|
624
|
+
if (hours2) return `${hours2}h ${pad(minutes2 % 60)}m ${pad(seconds2 % 60)}s`;
|
|
625
|
+
return minutes2 ? `${minutes2}m ${pad(seconds2 % 60)}s` : `${seconds2}s`;
|
|
626
|
+
}
|
|
627
|
+
const seconds = Math.round(elapsed / 1e3);
|
|
628
|
+
if (seconds < 45) return "now";
|
|
629
|
+
const minutes = Math.round(seconds / 60);
|
|
630
|
+
if (minutes < 60) return `${minutes}m`;
|
|
631
|
+
const hours = Math.floor(minutes / 60);
|
|
632
|
+
if (hours < 24) return minutes % 60 ? `${hours}h ${minutes % 60}m` : `${hours}h`;
|
|
633
|
+
const days = Math.floor(hours / 24);
|
|
634
|
+
return hours % 24 ? `${days}d ${hours % 24}h` : `${days}d`;
|
|
635
|
+
}
|
|
636
|
+
var clockTime = (at) => `${new Date(at).toISOString().slice(11, 16)} UTC`;
|
|
637
|
+
var timeSpan = (style, at, { text: fallback, tone: tone2, weight, mono } = {}) => compact({
|
|
638
|
+
text: fallback ?? (style === "duration" ? `since ${clockTime(at)}` : clockTime(at)),
|
|
639
|
+
tone: tone2,
|
|
640
|
+
weight,
|
|
641
|
+
mono,
|
|
642
|
+
time: { at: Math.max(0, Math.floor(at)), style }
|
|
643
|
+
});
|
|
644
|
+
var value = (content) => Array.isArray(content) ? { value: content.map((span) => span.text).join(""), valueSpans: content.map(compact) } : { value: content };
|
|
585
645
|
var ui = Object.freeze({
|
|
586
646
|
view: (root, { title } = {}) => compact({ kind: "view", root, title }),
|
|
587
|
-
action: (actionId, { value, opens, agentPicker } = {}) => compact({ actionId, value, opens, agentPicker }),
|
|
588
|
-
span: (
|
|
647
|
+
action: (actionId, { value: value2, opens, agentPicker } = {}) => compact({ actionId, value: value2, opens, agentPicker }),
|
|
648
|
+
span: (content, { tone: tone2, weight, mono, time } = {}) => compact({ text: content, tone: tone2, weight, mono, time }),
|
|
649
|
+
elapsed: (since, options) => timeSpan("duration", since, options),
|
|
650
|
+
relativeTime: (at, options) => timeSpan("relative", at, options),
|
|
589
651
|
stack: (items, { gap } = {}) => node("stack", { gap, children: items }),
|
|
590
652
|
row: (items, { align } = {}) => node("row", { children: items, align }),
|
|
591
653
|
divider: (label) => node("divider", { label }),
|
|
@@ -593,18 +655,18 @@ var ui = Object.freeze({
|
|
|
593
655
|
text: (content, { tone: tone2, weight, mono } = {}) => node("text", { ...Array.isArray(content) ? { spans: content.map(compact) } : { text: content }, tone: tone2, weight, mono }),
|
|
594
656
|
badge: (label, tone2) => node("badge", { label, tone: tone2 }),
|
|
595
657
|
dot: (tone2) => node("dot", { tone: tone2 }),
|
|
596
|
-
progress: (
|
|
658
|
+
progress: (value2, max, { tone: tone2, label } = {}) => node("progress", { value: value2, max, tone: tone2, label }),
|
|
597
659
|
segments: (items) => node("segments", { items: items.map(compact) }),
|
|
598
660
|
card: (items, { title, tone: tone2, tags, action: action2, externalAction, footer } = {}) => node("card", { title, tone: tone2, tags, action: action2, externalAction, footer, children: items }),
|
|
599
|
-
stat: (label,
|
|
600
|
-
kv: (items) => node("kv", { items: items.map(compact) }),
|
|
661
|
+
stat: (label, content, { tone: tone2, hint } = {}) => node("stat", { label, ...value(content), tone: tone2, hint }),
|
|
662
|
+
kv: (items) => node("kv", { items: items.map((item) => compact({ ...item, ...value(item.value) })) }),
|
|
601
663
|
tabs: (id, items, { filters, action: action2 } = {}) => node("tabs", { id, items: items.map(compact), filters, action: action2 }),
|
|
602
664
|
select: (id, label, options, { filters, action: action2 } = {}) => node("select", { id, label, options: options.map(compact), filters, action: action2 }),
|
|
603
665
|
table: (id, columns, rows = []) => node("table", { id, columns: columns.map(compact), rows: rows.map(compact) }),
|
|
604
666
|
log: (lines) => node("log", { lines }),
|
|
605
667
|
/** `action` is an action object or an action id. */
|
|
606
668
|
button: (label, action2) => node("button", { label, action: typeof action2 === "string" ? { actionId: action2 } : action2 }),
|
|
607
|
-
input: (id,
|
|
669
|
+
input: (id, value2, action2, { placeholder, maxLength } = {}) => node("input", { id, value: value2, placeholder, maxLength, action: typeof action2 === "string" ? { actionId: action2 } : action2 })
|
|
608
670
|
});
|
|
609
671
|
|
|
610
672
|
// ../plugin-sdk/src/index.mjs
|
|
@@ -618,6 +680,7 @@ function definePlugin(definition) {
|
|
|
618
680
|
}
|
|
619
681
|
export {
|
|
620
682
|
COLLECTION_FILE,
|
|
683
|
+
MUX_EXPRESSIONS,
|
|
621
684
|
PRESENTATIONS,
|
|
622
685
|
PluginError,
|
|
623
686
|
SDK_PACKAGE,
|
|
@@ -625,6 +688,7 @@ export {
|
|
|
625
688
|
VIEW_LIMITS,
|
|
626
689
|
checkPackageForPublish,
|
|
627
690
|
definePlugin,
|
|
691
|
+
formatTime,
|
|
628
692
|
lockfileRequirement,
|
|
629
693
|
resolveCollection,
|
|
630
694
|
ui,
|