@standardagents/code 0.14.1-issue.658.a1599e-linux-x64-gnu → 0.14.1-issue.663.fbc3a1

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.
@@ -1,698 +0,0 @@
1
- import { createRequire as __standardCreateRequire } from 'node:module'; import { fileURLToPath as __standardFileURLToPath } from 'node:url'; import { dirname as __standardDirname } from 'node:path'; const require = __standardCreateRequire(import.meta.url); const __filename = __standardFileURLToPath(import.meta.url); const __dirname = __standardDirname(__filename);
2
-
3
- // ../plugin-sdk/src/manifest.mjs
4
- var CAPABILITIES = Object.freeze([
5
- "surfaces",
6
- "events",
7
- "hooks",
8
- "panes",
9
- "projects",
10
- "notifications",
11
- "url",
12
- "fetch",
13
- "secrets",
14
- "webhook"
15
- ]);
16
- var SURFACE_KINDS = Object.freeze([
17
- "section",
18
- "card",
19
- "slot",
20
- "badge",
21
- "panel",
22
- "overlay",
23
- "menu",
24
- "command",
25
- "key",
26
- "link"
27
- ]);
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
- ]);
44
- var ANCHORS = Object.freeze([
45
- "plugins",
46
- "machine.before",
47
- "machine.after",
48
- "project.before",
49
- "project.after",
50
- "pane.header",
51
- "pane.footer",
52
- "account",
53
- "machine",
54
- "project",
55
- "pane",
56
- "section"
57
- ]);
58
- var LIMITS = Object.freeze({
59
- manifestBytes: 65536,
60
- frameBytes: 262144,
61
- responseFrameBytes: 64 * 1024 * 1024,
62
- pendingRequests: 128,
63
- subscriptions: 256,
64
- schedules: 128,
65
- contributions: 256,
66
- queuedBytes: 4 * 1024 * 1024,
67
- hookTimeoutMs: 6e4,
68
- requestTimeoutMs: 3e4,
69
- canvasColumns: 512,
70
- canvasRows: 256,
71
- canvasHoverBytes: 512,
72
- canvasShapes: 256,
73
- stateKeys: 256,
74
- stateValueBytes: 64 * 1024
75
- });
76
- var PluginError = class extends Error {
77
- constructor(code, message) {
78
- super(message);
79
- this.name = "PluginError";
80
- this.code = code;
81
- }
82
- };
83
- function ensure(condition, code, message) {
84
- if (!condition) throw new PluginError(code, message);
85
- }
86
- function object(value2) {
87
- return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
88
- }
89
- function identifier(value2) {
90
- return typeof value2 === "string" && /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/.test(value2);
91
- }
92
- function jsonBytes(value2, limit = LIMITS.frameBytes) {
93
- const seen = /* @__PURE__ */ new Set();
94
- function visit(item, depth) {
95
- ensure(depth <= 32, "invalid_payload", "JSON nesting exceeds 32 levels");
96
- if (item === null || typeof item === "string" || typeof item === "boolean") return;
97
- if (typeof item === "number") {
98
- ensure(Number.isFinite(item), "invalid_payload", "JSON numbers must be finite");
99
- return;
100
- }
101
- ensure(object(item) || Array.isArray(item), "invalid_payload", "Payload must contain JSON values");
102
- ensure(!seen.has(item), "invalid_payload", "Payload contains a cycle");
103
- ensure(Array.isArray(item) || [Object.prototype, null].includes(Object.getPrototypeOf(item)), "invalid_payload", "Payload must contain plain objects");
104
- seen.add(item);
105
- for (const child of Object.values(item)) visit(child, depth + 1);
106
- seen.delete(item);
107
- }
108
- visit(value2, 0);
109
- const text2 = JSON.stringify(value2);
110
- ensure(Buffer.byteLength(text2) <= limit, "payload_too_large", `Payload exceeds ${limit} bytes`);
111
- return text2;
112
- }
113
- function freeze(value2) {
114
- if (value2 && typeof value2 === "object") {
115
- Object.values(value2).forEach(freeze);
116
- Object.freeze(value2);
117
- }
118
- return value2;
119
- }
120
- function validateManifest(value2) {
121
- ensure(object(value2), "invalid_manifest", "package.json must contain a standardPlugin object");
122
- jsonBytes(value2, LIMITS.manifestBytes);
123
- const allowed = [
124
- "apiVersion",
125
- "id",
126
- "name",
127
- "version",
128
- "entry",
129
- "singleton",
130
- "order",
131
- "capabilities",
132
- "contributions",
133
- "configSchema",
134
- "hookTimeoutMs"
135
- ];
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 });
138
- ensure(manifest.apiVersion === 1, "incompatible_version", "Plugin requires a different SDK API version");
139
- ensure(identifier(manifest.id), "invalid_manifest", "Plugin id must be a stable identifier");
140
- ensure(
141
- typeof manifest.name === "string" && manifest.name.trim().length > 0 && manifest.name.length <= 128,
142
- "invalid_manifest",
143
- "Plugin name is required and bounded to 128 characters"
144
- );
145
- ensure(
146
- typeof manifest.version === "string" && /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?$/.test(manifest.version),
147
- "invalid_manifest",
148
- "Plugin version must be semantic"
149
- );
150
- ensure(
151
- typeof manifest.entry === "string" && manifest.entry.length <= 512 && !/[\\\u0000?#]/.test(manifest.entry) && !manifest.entry.startsWith("/") && manifest.entry.split("/").every((part) => part && part !== "..") && /\.(?:mjs|cjs|js|mts|ts)$/.test(manifest.entry),
152
- "invalid_manifest",
153
- "Plugin entry must be a relative JavaScript or TypeScript file"
154
- );
155
- ensure(
156
- typeof manifest.singleton === "boolean" && Number.isSafeInteger(manifest.order) && Math.abs(manifest.order) <= 2147483647,
157
- "invalid_manifest",
158
- "Invalid singleton or order"
159
- );
160
- ensure(
161
- Number.isSafeInteger(manifest.hookTimeoutMs) && manifest.hookTimeoutMs > 0 && manifest.hookTimeoutMs <= LIMITS.hookTimeoutMs,
162
- "invalid_manifest",
163
- "Hook timeout must be between 1 and 60000 ms"
164
- );
165
- ensure(Array.isArray(manifest.capabilities) && manifest.capabilities.every((item) => CAPABILITIES.includes(item)) && new Set(manifest.capabilities).size === manifest.capabilities.length, "invalid_manifest", "Unknown or repeated capability");
166
- ensure(
167
- Array.isArray(manifest.contributions) && manifest.contributions.length <= LIMITS.contributions,
168
- "invalid_manifest",
169
- "Too many contributions"
170
- );
171
- const ids = /* @__PURE__ */ new Set();
172
- for (const declaration of manifest.contributions) {
173
- ensure(object(declaration) && identifier(declaration.id) && !ids.has(declaration.id) && SURFACE_KINDS.includes(declaration.kind) && ANCHORS.includes(declaration.anchor), "invalid_manifest", "Invalid contribution declaration");
174
- ids.add(declaration.id);
175
- ensure(
176
- declaration.icon === void 0 || ["card", "panel"].includes(declaration.kind) && typeof declaration.icon === "string" && /^[\uE000-\uF8FF\u{F0000}-\u{FFFFD}\u{100000}-\u{10FFFD}]$/u.test(declaration.icon),
177
- "invalid_manifest",
178
- "Card or panel icon must be one Nerd Font private-use glyph"
179
- );
180
- ensure(
181
- declaration.border === void 0 || typeof declaration.border === "boolean" && declaration.kind === "card",
182
- "invalid_manifest",
183
- "Only sidebar cards declare a boolean border preference"
184
- );
185
- for (const [key, choices] of Object.entries({
186
- merge: ["by-machine", "by-identity"],
187
- width: ["full", "half"],
188
- position: ["top", "after-open", "before-danger", "bottom"],
189
- presentation: PRESENTATIONS
190
- })) {
191
- ensure(declaration[key] === void 0 || choices.includes(declaration[key]), "invalid_manifest", `Invalid contribution ${key}`);
192
- }
193
- for (const key of ["title", "group", "chord", "pattern", "actionId"]) {
194
- ensure(
195
- declaration[key] === void 0 || typeof declaration[key] === "string" && declaration[key].length <= 512,
196
- "invalid_manifest",
197
- `Invalid contribution ${key}`
198
- );
199
- }
200
- ensure(declaration.opens === void 0 || identifier(declaration.opens), "invalid_manifest", "Invalid contribution opens");
201
- ensure(
202
- declaration.presentation === void 0 || ["panel", "card", "command"].includes(declaration.kind),
203
- "invalid_manifest",
204
- "Only panels, cards, and commands declare a presentation"
205
- );
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
- );
212
- }
213
- for (const declaration of manifest.contributions) {
214
- ensure(
215
- declaration.opens === void 0 || manifest.contributions.some((item) => item.id === declaration.opens && item.kind === "panel"),
216
- "invalid_manifest",
217
- "Contribution opens must name a declared panel"
218
- );
219
- }
220
- ensure(!manifest.contributions.length || manifest.capabilities.includes("surfaces"), "invalid_manifest", "Contributions require surfaces capability");
221
- ensure(manifest.configSchema === void 0 || object(manifest.configSchema), "invalid_manifest", "Configuration schema must be an object");
222
- return freeze(manifest);
223
- }
224
-
225
- // ../plugin-sdk/src/collection.mjs
226
- var COLLECTION_FILE = "standard-plugins.json";
227
- var COLLECTION_LIMITS = Object.freeze({ entries: 256, pathLength: 512 });
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 !== "..");
230
- }
231
- function freeze2(value2) {
232
- if (value2 && typeof value2 === "object") {
233
- Object.values(value2).forEach(freeze2);
234
- Object.freeze(value2);
235
- }
236
- return value2;
237
- }
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");
243
- ensure(
244
- Array.isArray(value2.plugins) && value2.plugins.length >= 1 && value2.plugins.length <= COLLECTION_LIMITS.entries,
245
- "invalid_collection",
246
- `Collection must list between 1 and ${COLLECTION_LIMITS.entries} plugins`
247
- );
248
- const ids = /* @__PURE__ */ new Set();
249
- const paths = /* @__PURE__ */ new Set();
250
- const plugins = value2.plugins.map((entry) => {
251
- ensure(object(entry) && Object.keys(entry).every((key) => ["id", "path"].includes(key)), "invalid_collection", "Invalid collection entry");
252
- ensure(identifier(entry.id), "invalid_collection", "Collection entry id must be a stable identifier");
253
- ensure(relativePath(entry.path), "invalid_collection", "Collection entry path must be a relative POSIX path");
254
- ensure(!ids.has(entry.id), "invalid_collection", `Collection repeats plugin id ${entry.id}`);
255
- ensure(!paths.has(entry.path), "invalid_collection", `Collection repeats path ${entry.path}`);
256
- ids.add(entry.id);
257
- paths.add(entry.path);
258
- return { id: entry.id, path: entry.path };
259
- });
260
- return freeze2({ schema: 1, plugins });
261
- }
262
- function resolveCollection({ collection, packageJson } = {}) {
263
- if (collection !== void 0) return validateCollection(collection);
264
- ensure(
265
- object(packageJson) && packageJson.standardPlugin !== void 0,
266
- "invalid_collection",
267
- `Source needs ${COLLECTION_FILE} or a package.json with a standardPlugin manifest`
268
- );
269
- const manifest = validateManifest(packageJson.standardPlugin);
270
- return freeze2({ schema: 1, plugins: [{ id: manifest.id, path: "" }] });
271
- }
272
-
273
- // ../plugin-sdk/src/publish.mjs
274
- var SDK_PACKAGE = "@standardagents/code-plugin-sdk";
275
- var SOURCE_KINDS = Object.freeze(["git", "npm"]);
276
- var LOCKFILES = Object.freeze({ git: Object.freeze(["package-lock.json", "npm-shrinkwrap.json"]), npm: Object.freeze(["npm-shrinkwrap.json"]) });
277
- function names(section) {
278
- return object(section) ? Object.keys(section) : [];
279
- }
280
- function runtimeDependencies(packageJson) {
281
- ensure(object(packageJson), "invalid_package", "package.json must contain an object");
282
- return [.../* @__PURE__ */ new Set([...names(packageJson.dependencies), ...names(packageJson.optionalDependencies)])];
283
- }
284
- function lockfileRequirement({ packageJson, sourceKind }) {
285
- ensure(SOURCE_KINDS.includes(sourceKind), "invalid_source", "Source kind must be git or npm");
286
- const dependencies = runtimeDependencies(packageJson);
287
- return Object.freeze({ required: dependencies.length > 0, dependencies: Object.freeze(dependencies), lockfiles: LOCKFILES[sourceKind] });
288
- }
289
- function normalize(path) {
290
- return path.replace(/^\.\//, "");
291
- }
292
- function checkPackageForPublish({ packageJson, files, sourceKind = "npm", requireManifest = true, expectedId } = {}) {
293
- ensure(Array.isArray(files) && files.every((file) => typeof file === "string"), "invalid_source", "files must list relative paths");
294
- const problems = [];
295
- const problem = (code, message) => problems.push(Object.freeze({ code, message }));
296
- if (!object(packageJson)) return Object.freeze([Object.freeze({ code: "invalid_package", message: "package.json must contain an object" })]);
297
- const present = new Set(files.map(normalize));
298
- if (packageJson.private === true && sourceKind === "npm") problem("package_private", "package.json marks the package private, so npm refuses to publish it");
299
- const requirement = lockfileRequirement({ packageJson, sourceKind });
300
- if (requirement.required && !requirement.lockfiles.some((name) => present.has(name))) {
301
- problem("lockfile_missing", `Dependencies (${requirement.dependencies.join(", ")}) need ${requirement.lockfiles.join(" or ")} beside package.json`);
302
- }
303
- for (const section of ["dependencies", "optionalDependencies"]) {
304
- if (names(packageJson[section]).includes(SDK_PACKAGE)) problem("sdk_dependency", `${SDK_PACKAGE} belongs under peerDependencies, not ${section}`);
305
- }
306
- let manifest = null;
307
- if (packageJson.standardPlugin === void 0) {
308
- if (requireManifest) problem("manifest_missing", "package.json has no standardPlugin manifest");
309
- } else {
310
- try {
311
- manifest = validateManifest(packageJson.standardPlugin);
312
- } catch (error) {
313
- if (!(error instanceof PluginError)) throw error;
314
- problem(error.code, error.message);
315
- }
316
- }
317
- if (manifest) {
318
- if (!names(packageJson.peerDependencies).includes(SDK_PACKAGE)) problem("sdk_peer_missing", `${SDK_PACKAGE} must be listed under peerDependencies`);
319
- if (!present.has(normalize(manifest.entry))) problem("entry_missing", `Entry ${manifest.entry} is not among the package files`);
320
- if (expectedId !== void 0 && manifest.id !== expectedId) problem("id_mismatch", `Manifest id ${manifest.id} differs from collection entry ${expectedId}`);
321
- }
322
- return Object.freeze(problems);
323
- }
324
-
325
- // ../plugin-sdk/src/view.mjs
326
- var VIEW_LIMITS = Object.freeze({
327
- depth: 8,
328
- nodes: 4096,
329
- tableRows: 512,
330
- tableColumns: 12,
331
- items: 512,
332
- logLines: 2048,
333
- cardLines: 6,
334
- actionValueBytes: 512
335
- });
336
- var TONES = Object.freeze(["ok", "info", "warn", "error", "muted", "accent", "pending", "bright"]);
337
- var WEIGHTS = ["normal", "bold", "dim"];
338
- var TIME_STYLES = ["duration", "relative"];
339
- var ALIGNS = ["start", "center", "end"];
340
- var FORBIDDEN = /[\u0000-\u001f\u007f-\u009f\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/;
341
- var invalid = (message) => ensure(false, "invalid_payload", message);
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");
345
- }
346
- function optionalText(value2, field) {
347
- if (value2 !== void 0) text(value2, field);
348
- }
349
- function choice(value2, choices, field) {
350
- ensure(value2 === void 0 || choices.includes(value2), "invalid_payload", `Invalid plugin view ${field}`);
351
- }
352
- function tone(value2) {
353
- choice(value2, TONES, "tone");
354
- }
355
- function integer(value2, max, field) {
356
- ensure(value2 === void 0 || Number.isInteger(value2) && value2 >= 0 && value2 <= max, "invalid_payload", `Invalid plugin view ${field}`);
357
- }
358
- function flag(value2, field) {
359
- ensure(value2 === void 0 || typeof value2 === "boolean", "invalid_payload", `Invalid plugin view ${field}`);
360
- }
361
- function number(value2) {
362
- ensure(typeof value2 === "number" && Number.isFinite(value2), "invalid_payload", "Plugin view number is not finite");
363
- }
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;
368
- }
369
- function entries(value2, field, optional, check) {
370
- for (const item of list(value2, field, optional)) {
371
- ensure(object(item), "invalid_payload", `Plugin view ${field} must contain objects`);
372
- check(item);
373
- }
374
- }
375
- function bounded(value2, field, limit, optional = false) {
376
- const values = list(value2, field, optional);
377
- ensure(values.length <= limit, "invalid_payload", `Plugin view ${field} has more than ${limit} entries`);
378
- return values;
379
- }
380
- function boundedEntries(value2, field, check) {
381
- entries(bounded(value2, field, VIEW_LIMITS.items), field, false, check);
382
- }
383
- function spans(value2, optional) {
384
- entries(value2, "spans", optional, (span) => {
385
- text(span.text, "span text");
386
- tone(span.tone);
387
- choice(span.weight, WEIGHTS, "weight");
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
- }
398
- });
399
- }
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");
410
- }
411
- }
412
- function meter(item) {
413
- number(item.value);
414
- number(item.max);
415
- tone(item.tone);
416
- optionalText(item.label, "label");
417
- }
418
- function children(node2, depth, count) {
419
- for (const child of list(node2.children, "children", true)) walk(child, depth + 1, count);
420
- }
421
- var NODES = {
422
- stack(node2, depth, count) {
423
- integer(node2.gap, 255, "gap");
424
- children(node2, depth, count);
425
- },
426
- row(node2, depth, count) {
427
- choice(node2.align, ALIGNS, "align");
428
- children(node2, depth, count);
429
- },
430
- divider(node2) {
431
- optionalText(node2.label, "label");
432
- },
433
- text(node2) {
434
- optionalText(node2.text, "text");
435
- spans(node2.spans, true);
436
- tone(node2.tone);
437
- choice(node2.weight, WEIGHTS, "weight");
438
- flag(node2.mono, "mono");
439
- },
440
- badge(node2) {
441
- text(node2.label, "label");
442
- tone(node2.tone);
443
- },
444
- dot(node2) {
445
- tone(node2.tone);
446
- },
447
- progress: meter,
448
- segments(node2) {
449
- boundedEntries(node2.items, "items", meter);
450
- },
451
- card(node2, depth, count) {
452
- optionalText(node2.title, "title");
453
- optionalText(node2.footer, "footer");
454
- tone(node2.tone);
455
- action(node2.action);
456
- action(node2.externalAction);
457
- boundedEntries(node2.tags ?? [], "tags", (tag) => {
458
- text(tag.label, "tag label");
459
- tone(tag.tone);
460
- });
461
- children(node2, depth, count);
462
- },
463
- input(node2) {
464
- text(node2.id, "id");
465
- text(node2.value, "value");
466
- optionalText(node2.placeholder, "placeholder");
467
- action(node2.action, false);
468
- integer(node2.maxLength, 4096, "maxLength");
469
- },
470
- stat(node2) {
471
- text(node2.label, "label");
472
- text(node2.value, "value");
473
- spans(node2.valueSpans, true);
474
- tone(node2.tone);
475
- optionalText(node2.hint, "hint");
476
- },
477
- kv(node2) {
478
- boundedEntries(node2.items, "items", (item) => {
479
- text(item.label, "label");
480
- text(item.value, "value");
481
- spans(item.valueSpans, true);
482
- flag(item.mono, "mono");
483
- flag(item.copy, "copy");
484
- });
485
- },
486
- tabs(node2) {
487
- text(node2.id, "id");
488
- optionalText(node2.filters, "filters");
489
- action(node2.action);
490
- boundedEntries(node2.items, "items", (item) => {
491
- text(item.id, "id");
492
- text(item.label, "label");
493
- optionalText(item.sublabel, "sublabel");
494
- tone(item.tone);
495
- integer(item.count, 4294967295, "count");
496
- optionalText(item.tag, "tag");
497
- });
498
- },
499
- select(node2) {
500
- text(node2.id, "id");
501
- text(node2.label, "label");
502
- optionalText(node2.filters, "filters");
503
- action(node2.action);
504
- boundedEntries(node2.options, "options", (option) => {
505
- text(option.id, "id");
506
- text(option.label, "label");
507
- optionalText(option.group, "group");
508
- integer(option.count, 4294967295, "count");
509
- optionalText(option.tag, "tag");
510
- });
511
- },
512
- table(node2, depth, count) {
513
- const columns = list(node2.columns, "columns");
514
- const rows = list(node2.rows, "rows", true);
515
- ensure(columns.length <= VIEW_LIMITS.tableColumns, "invalid_payload", "Plugin table has more than 12 columns");
516
- ensure(rows.length <= VIEW_LIMITS.tableRows, "invalid_payload", "Plugin table has more than 512 rows");
517
- text(node2.id, "id");
518
- entries(columns, "columns", false, (column) => {
519
- text(column.id, "column id");
520
- optionalText(column.label, "column label");
521
- if (column.width !== "fill") integer(column.width, 65535, "column width");
522
- integer(column.maxWidth, 65535, "column maxWidth");
523
- choice(column.align, ALIGNS, "align");
524
- integer(column.priority, 255, "column priority");
525
- });
526
- entries(rows, "rows", false, (row) => {
527
- text(row.id, "row id");
528
- tone(row.tone);
529
- spans(row.note, true);
530
- for (const tag of bounded(row.tags, "tags", VIEW_LIMITS.items, true)) text(tag, "tag");
531
- action(row.action);
532
- ensure(row.cells === void 0 || object(row.cells), "invalid_payload", "Plugin table cells must be an object");
533
- for (const [column, cell] of Object.entries(row.cells ?? {})) {
534
- text(column, "cell column");
535
- walk(cell, depth + 1, count);
536
- }
537
- });
538
- },
539
- log(node2) {
540
- for (const line of bounded(node2.lines, "lines", VIEW_LIMITS.logLines)) text(line, "log line");
541
- },
542
- button(node2) {
543
- text(node2.label, "label");
544
- action(node2.action, false);
545
- flag(node2.sticky, "sticky");
546
- }
547
- };
548
- function walk(node2, depth, count) {
549
- ensure(depth <= VIEW_LIMITS.depth, "invalid_payload", "Plugin view nests deeper than 8 nodes");
550
- ensure(++count.nodes <= VIEW_LIMITS.nodes, "invalid_payload", "Plugin view has more than 4096 nodes");
551
- ensure(object(node2) && typeof node2.type === "string", "invalid_payload", "Plugin view node requires a type");
552
- if (Object.hasOwn(NODES, node2.type)) NODES[node2.type](node2, depth, count);
553
- }
554
- function visitActions(node2, visit) {
555
- switch (node2.type) {
556
- case "stack":
557
- case "row":
558
- case "card":
559
- if (node2.type === "card") {
560
- if (node2.action !== void 0) visit(node2.action);
561
- if (node2.externalAction !== void 0) visit(node2.externalAction);
562
- }
563
- for (const child of node2.children ?? []) visitActions(child, visit);
564
- break;
565
- case "button":
566
- case "input":
567
- visit(node2.action);
568
- break;
569
- case "tabs":
570
- case "select":
571
- if (node2.action !== void 0) visit(node2.action);
572
- break;
573
- case "table":
574
- for (const row of node2.rows ?? []) {
575
- if (row.action !== void 0) visit(row.action);
576
- for (const cell of Object.values(row.cells ?? {})) visitActions(cell, visit);
577
- }
578
- break;
579
- }
580
- }
581
- var ONE_LINE = ["text", "badge", "dot", "progress", "segments", "stat", "divider"];
582
- var PANEL_ONLY = ["card", "kv", "tabs", "select", "table", "log", "button", "input"];
583
- function cardLines(node2) {
584
- if (node2.type === "stack") {
585
- const children2 = node2.children ?? [];
586
- return children2.reduce((total, child) => total + cardLines(child), (node2.gap ?? 0) * Math.max(children2.length - 1, 0));
587
- }
588
- if (node2.type === "row") return (node2.children ?? []).reduce((tallest, child) => Math.max(tallest, cardLines(child)), 0);
589
- if (ONE_LINE.includes(node2.type)) return 1;
590
- ensure(!PANEL_ONLY.includes(node2.type), "invalid_payload", `A card view cannot contain a ${node2.type} node`);
591
- return 0;
592
- }
593
- function validateView(root, { kind, manifest } = {}) {
594
- walk(root, 1, { nodes: 0 });
595
- jsonBytes(root, LIMITS.frameBytes);
596
- visitActions(root, (action2) => {
597
- ensure(identifier(action2.actionId), "invalid_payload", "Plugin view action id must be a plugin identifier");
598
- ensure(
599
- action2.value === void 0 || Buffer.byteLength(action2.value) <= VIEW_LIMITS.actionValueBytes,
600
- "payload_too_large",
601
- "Plugin view action value exceeds 512 bytes"
602
- );
603
- ensure(action2.opens === void 0 || identifier(action2.opens), "invalid_payload", "Plugin view action opens must be a plugin identifier");
604
- ensure(
605
- action2.opens === void 0 || !manifest || manifest.contributions.some((item) => item.id === action2.opens && item.kind === "panel"),
606
- "invalid_payload",
607
- "Plugin view action opens must name a declared panel"
608
- );
609
- });
610
- if (kind === "card") {
611
- ensure(cardLines(root) <= VIEW_LIMITS.cardLines, "payload_too_large", "A card view is taller than 6 lines");
612
- }
613
- }
614
- function compact(value2) {
615
- return Object.fromEntries(Object.entries(value2).filter(([, item]) => item !== void 0));
616
- }
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 };
645
- var ui = Object.freeze({
646
- view: (root, { title } = {}) => compact({ kind: "view", root, title }),
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),
651
- stack: (items, { gap } = {}) => node("stack", { gap, children: items }),
652
- row: (items, { align } = {}) => node("row", { children: items, align }),
653
- divider: (label) => node("divider", { label }),
654
- /** A string sets `text`; an array of spans sets `spans`. */
655
- text: (content, { tone: tone2, weight, mono } = {}) => node("text", { ...Array.isArray(content) ? { spans: content.map(compact) } : { text: content }, tone: tone2, weight, mono }),
656
- badge: (label, tone2) => node("badge", { label, tone: tone2 }),
657
- dot: (tone2) => node("dot", { tone: tone2 }),
658
- progress: (value2, max, { tone: tone2, label } = {}) => node("progress", { value: value2, max, tone: tone2, label }),
659
- segments: (items) => node("segments", { items: items.map(compact) }),
660
- card: (items, { title, tone: tone2, tags, action: action2, externalAction, footer } = {}) => node("card", { title, tone: tone2, tags, action: action2, externalAction, footer, children: items }),
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) })) }),
663
- tabs: (id, items, { filters, action: action2 } = {}) => node("tabs", { id, items: items.map(compact), filters, action: action2 }),
664
- select: (id, label, options, { filters, action: action2 } = {}) => node("select", { id, label, options: options.map(compact), filters, action: action2 }),
665
- table: (id, columns, rows = []) => node("table", { id, columns: columns.map(compact), rows: rows.map(compact) }),
666
- log: (lines) => node("log", { lines }),
667
- /** `action` is an action object or an action id. */
668
- button: (label, action2) => node("button", { label, action: typeof action2 === "string" ? { actionId: action2 } : action2 }),
669
- input: (id, value2, action2, { placeholder, maxLength } = {}) => node("input", { id, value: value2, placeholder, maxLength, action: typeof action2 === "string" ? { actionId: action2 } : action2 })
670
- });
671
-
672
- // ../plugin-sdk/src/index.mjs
673
- function definePlugin(definition) {
674
- ensure(
675
- definition && identifier(definition.id) && typeof definition.activate === "function",
676
- "invalid_plugin",
677
- "definePlugin requires an id and activate function"
678
- );
679
- return Object.freeze({ id: definition.id, activate: definition.activate });
680
- }
681
- export {
682
- COLLECTION_FILE,
683
- MUX_EXPRESSIONS,
684
- PRESENTATIONS,
685
- PluginError,
686
- SDK_PACKAGE,
687
- TONES,
688
- VIEW_LIMITS,
689
- checkPackageForPublish,
690
- definePlugin,
691
- formatTime,
692
- lockfileRequirement,
693
- resolveCollection,
694
- ui,
695
- validateCollection,
696
- validateManifest,
697
- validateView
698
- };