@standardagents/code 0.14.1-issue.613.b9157a-linux-x64-gnu → 0.14.1-issue.646.5eed10-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 } +53 -9
- 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 } +32 -6
- package/{lib/standard-plugin-runner/worker.mjs → Standard Code Daemon.app/Contents/Resources/plugin-runner/worker.mjs } +151 -11
- 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.646.5eed10</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>5eed100b733b3f65fe55bfb402f796607a7af86a</string>
|
|
31
|
+
<key>StandardCodeComponent</key>
|
|
32
|
+
<string>standardd</string>
|
|
33
|
+
<key>StandardCodeRelease</key>
|
|
34
|
+
<string>npm-5eed100b733b</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.646.5eed10</string>
|
|
41
|
+
</dict>
|
|
42
|
+
</plist>
|
|
@@ -161,9 +161,9 @@ function validateManifest(value) {
|
|
|
161
161
|
ensure(object(declaration) && identifier(declaration.id) && !ids.has(declaration.id) && SURFACE_KINDS.includes(declaration.kind) && ANCHORS.includes(declaration.anchor), "invalid_manifest", "Invalid contribution declaration");
|
|
162
162
|
ids.add(declaration.id);
|
|
163
163
|
ensure(
|
|
164
|
-
declaration.icon === void 0 || declaration.kind
|
|
164
|
+
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),
|
|
165
165
|
"invalid_manifest",
|
|
166
|
-
"Card icon must be one Nerd Font private-use glyph"
|
|
166
|
+
"Card or panel icon must be one Nerd Font private-use glyph"
|
|
167
167
|
);
|
|
168
168
|
ensure(
|
|
169
169
|
declaration.border === void 0 || typeof declaration.border === "boolean" && declaration.kind === "card",
|
|
@@ -224,9 +224,11 @@ var OPERATIONS = Object.freeze({
|
|
|
224
224
|
"state.get": null,
|
|
225
225
|
"state.set": null,
|
|
226
226
|
"state.keys": null,
|
|
227
|
+
"panel.open": "surfaces",
|
|
227
228
|
"context.get": null,
|
|
228
229
|
"popover.open": "surfaces",
|
|
229
230
|
"canvas.write": "surfaces",
|
|
231
|
+
"remote.request": "surfaces",
|
|
230
232
|
"canvas.focus": "surfaces",
|
|
231
233
|
"subscription.add": null,
|
|
232
234
|
"subscription.remove": null,
|
|
@@ -279,8 +281,14 @@ function validateEnvelope(frame, { inbound = false } = {}) {
|
|
|
279
281
|
jsonBytes(frame, frameLimit(frame, inbound));
|
|
280
282
|
ensure(object(frame) && frame.version === RUNNER_PROTOCOL_VERSION, "incompatible_version", "Daemon and runner protocol versions differ");
|
|
281
283
|
validateProducer(frame.producer);
|
|
282
|
-
ensure(["request", "response", "cancel", "surface"].includes(frame.kind), "invalid_payload", "Unknown runner frame kind");
|
|
283
|
-
if (frame.kind === "
|
|
284
|
+
ensure(["request", "response", "cancel", "surface", "report"].includes(frame.kind), "invalid_payload", "Unknown runner frame kind");
|
|
285
|
+
if (frame.kind === "report") {
|
|
286
|
+
ensure(
|
|
287
|
+
identifier(frame.name) && object(frame.entity) && typeof frame.sequence === "string" && /^(0|[1-9]\d{0,19})$/.test(frame.sequence) && BigInt(frame.sequence) <= 18446744073709551615n && Number.isInteger(frame.schemaVersion) && frame.schemaVersion > 0 && frame.schemaVersion <= 65535 && Object.hasOwn(frame, "value") && frame.value !== void 0,
|
|
288
|
+
"invalid_payload",
|
|
289
|
+
"Invalid report replacement"
|
|
290
|
+
);
|
|
291
|
+
} else if (frame.kind === "surface") {
|
|
284
292
|
ensure(object(frame.key) && identifier(frame.key.contributionId) && typeof frame.sequence === "string" && /^(0|[1-9]\d{0,19})$/.test(frame.sequence) && BigInt(frame.sequence) <= 18446744073709551615n && Object.hasOwn(frame, "content"), "invalid_payload", "Invalid surface replacement");
|
|
285
293
|
} else {
|
|
286
294
|
ensure(typeof frame.id === "string" && frame.id.length > 0 && frame.id.length <= 128, "invalid_payload", "Missing correlation id");
|
|
@@ -309,13 +317,14 @@ function wireError(error) {
|
|
|
309
317
|
}
|
|
310
318
|
var realClock = Object.freeze({ now: () => Date.now(), setTimeout: (fn, ms) => setTimeout(fn, ms), clearTimeout: (id) => clearTimeout(id) });
|
|
311
319
|
var RpcPeer = class {
|
|
312
|
-
constructor({ producer, send, clock = realClock, onRequest, onSurface, onError = () => {
|
|
320
|
+
constructor({ producer, send, clock = realClock, onRequest, onSurface, onReport, onError = () => {
|
|
313
321
|
}, idPrefix = "host" }) {
|
|
314
322
|
this.producer = Object.freeze({ ...validateProducer(producer) });
|
|
315
323
|
this.send = send;
|
|
316
324
|
this.clock = clock;
|
|
317
325
|
this.onRequest = onRequest;
|
|
318
326
|
this.onSurface = onSurface;
|
|
327
|
+
this.onReport = onReport;
|
|
319
328
|
this.onError = onError;
|
|
320
329
|
this.pending = /* @__PURE__ */ new Map();
|
|
321
330
|
this.incoming = /* @__PURE__ */ new Map();
|
|
@@ -370,6 +379,10 @@ var RpcPeer = class {
|
|
|
370
379
|
this.onSurface?.(frame);
|
|
371
380
|
return;
|
|
372
381
|
}
|
|
382
|
+
if (frame.kind === "report") {
|
|
383
|
+
this.onReport?.(frame);
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
373
386
|
if (frame.kind === "response") {
|
|
374
387
|
const result = frame.result;
|
|
375
388
|
this.pending.get(frame.id)?.finish(result.ok ? null : new PluginError(result.error.code, result.error.message), result.value);
|
|
@@ -449,7 +462,7 @@ function compact(value) {
|
|
|
449
462
|
var node = (type, fields) => compact({ type, ...fields });
|
|
450
463
|
var ui = Object.freeze({
|
|
451
464
|
view: (root, { title } = {}) => compact({ kind: "view", root, title }),
|
|
452
|
-
action: (actionId, { value, opens } = {}) => compact({ actionId, value, opens }),
|
|
465
|
+
action: (actionId, { value, opens, agentPicker } = {}) => compact({ actionId, value, opens, agentPicker }),
|
|
453
466
|
span: (value, { tone, weight, mono } = {}) => compact({ text: value, tone, weight, mono }),
|
|
454
467
|
stack: (items, { gap } = {}) => node("stack", { gap, children: items }),
|
|
455
468
|
row: (items, { align } = {}) => node("row", { children: items, align }),
|
|
@@ -460,7 +473,7 @@ var ui = Object.freeze({
|
|
|
460
473
|
dot: (tone) => node("dot", { tone }),
|
|
461
474
|
progress: (value, max, { tone, label } = {}) => node("progress", { value, max, tone, label }),
|
|
462
475
|
segments: (items) => node("segments", { items: items.map(compact) }),
|
|
463
|
-
card: (items, { title, tone } = {}) => node("card", { title, tone, children: items }),
|
|
476
|
+
card: (items, { title, tone, tags, action, externalAction, footer } = {}) => node("card", { title, tone, tags, action, externalAction, footer, children: items }),
|
|
464
477
|
stat: (label, value, { tone, hint } = {}) => node("stat", { label, value, tone, hint }),
|
|
465
478
|
kv: (items) => node("kv", { items: items.map(compact) }),
|
|
466
479
|
tabs: (id, items, { filters, action } = {}) => node("tabs", { id, items: items.map(compact), filters, action }),
|
|
@@ -468,7 +481,8 @@ var ui = Object.freeze({
|
|
|
468
481
|
table: (id, columns, rows = []) => node("table", { id, columns: columns.map(compact), rows: rows.map(compact) }),
|
|
469
482
|
log: (lines) => node("log", { lines }),
|
|
470
483
|
/** `action` is an action object or an action id. */
|
|
471
|
-
button: (label, action) => node("button", { label, action: typeof action === "string" ? { actionId: action } : action })
|
|
484
|
+
button: (label, action) => node("button", { label, action: typeof action === "string" ? { actionId: action } : action }),
|
|
485
|
+
input: (id, value, action, { placeholder, maxLength } = {}) => node("input", { id, value, placeholder, maxLength, action: typeof action === "string" ? { actionId: action } : action })
|
|
472
486
|
});
|
|
473
487
|
|
|
474
488
|
// ../plugin-sdk/src/runtime.mjs
|
|
@@ -535,7 +549,7 @@ var Outbox = class {
|
|
|
535
549
|
const frame = framed(message);
|
|
536
550
|
const serialized = jsonBytes(message, frameLimit(frame, true));
|
|
537
551
|
const size = Buffer.byteLength(serialized);
|
|
538
|
-
const key = frame.kind === "surface" ? JSON.stringify([frame.producer, frame.key]) : null;
|
|
552
|
+
const key = frame.kind === "surface" ? JSON.stringify(["surface", frame.producer, frame.key]) : frame.kind === "report" ? JSON.stringify(["report", frame.producer, frame.name, frame.entity]) : null;
|
|
539
553
|
const previous = key === null ? -1 : this.queue.findIndex((item2) => item2.key === key);
|
|
540
554
|
const replaced = previous < 0 ? 0 : this.queue[previous].size;
|
|
541
555
|
const budget = LIMITS.queuedBytes + (frame.kind === "response" ? LIMITS.responseFrameBytes : 0);
|
|
@@ -742,6 +756,7 @@ var PluginSupervisor = class {
|
|
|
742
756
|
health: "stopped",
|
|
743
757
|
busy: false,
|
|
744
758
|
surfaces: /* @__PURE__ */ new Map(),
|
|
759
|
+
reports: /* @__PURE__ */ new Map(),
|
|
745
760
|
subscriptions: /* @__PURE__ */ new Set(),
|
|
746
761
|
desired: false,
|
|
747
762
|
generation: 0,
|
|
@@ -914,6 +929,19 @@ var PluginSupervisor = class {
|
|
|
914
929
|
this.send({ ...frame, sequence: String(++slot.sequence) });
|
|
915
930
|
return;
|
|
916
931
|
}
|
|
932
|
+
if (frame.kind === "report") {
|
|
933
|
+
ensure(slot.manifest.capabilities.includes("surfaces"), "capability_denied", "Worker cannot publish reports");
|
|
934
|
+
const key = JSON.stringify([frame.name, frame.entity]);
|
|
935
|
+
ensure(
|
|
936
|
+
frame.value === null || slot.reports.has(key) || slot.reports.size < LIMITS.contributions,
|
|
937
|
+
"queue_full",
|
|
938
|
+
"Too many live reports"
|
|
939
|
+
);
|
|
940
|
+
if (frame.value === null) slot.reports.delete(key);
|
|
941
|
+
else slot.reports.set(key, { name: frame.name, entity: frame.entity });
|
|
942
|
+
this.send({ ...frame, sequence: String(++slot.sequence) });
|
|
943
|
+
return;
|
|
944
|
+
}
|
|
917
945
|
try {
|
|
918
946
|
authorize(frame.operation, slot.manifest.capabilities);
|
|
919
947
|
if (frame.operation.op === "subscription.add") {
|
|
@@ -996,6 +1024,22 @@ var PluginSupervisor = class {
|
|
|
996
1024
|
}
|
|
997
1025
|
}
|
|
998
1026
|
slot.surfaces.clear();
|
|
1027
|
+
for (const report of slot.reports.values()) {
|
|
1028
|
+
try {
|
|
1029
|
+
this.send({
|
|
1030
|
+
version: RUNNER_PROTOCOL_VERSION,
|
|
1031
|
+
producer: slot.producer,
|
|
1032
|
+
kind: "report",
|
|
1033
|
+
...report,
|
|
1034
|
+
sequence: String(++slot.sequence),
|
|
1035
|
+
schemaVersion: 1,
|
|
1036
|
+
value: null
|
|
1037
|
+
});
|
|
1038
|
+
} catch (error) {
|
|
1039
|
+
this.onDiagnostic(error);
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
slot.reports.clear();
|
|
999
1043
|
slot.health = "stopped";
|
|
1000
1044
|
})().finally(() => {
|
|
1001
1045
|
slot.stopping = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"schema":1,"productVersion":"0.14.1-issue.
|
|
1
|
+
{"schema":1,"productVersion":"0.14.1-issue.646.5eed10","commit":"5eed100b733b3f65fe55bfb402f796607a7af86a","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"]}
|
|
@@ -157,9 +157,9 @@ function validateManifest(value) {
|
|
|
157
157
|
ensure(object(declaration) && identifier(declaration.id) && !ids.has(declaration.id) && SURFACE_KINDS.includes(declaration.kind) && ANCHORS.includes(declaration.anchor), "invalid_manifest", "Invalid contribution declaration");
|
|
158
158
|
ids.add(declaration.id);
|
|
159
159
|
ensure(
|
|
160
|
-
declaration.icon === void 0 || declaration.kind
|
|
160
|
+
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),
|
|
161
161
|
"invalid_manifest",
|
|
162
|
-
"Card icon must be one Nerd Font private-use glyph"
|
|
162
|
+
"Card or panel icon must be one Nerd Font private-use glyph"
|
|
163
163
|
);
|
|
164
164
|
ensure(
|
|
165
165
|
declaration.border === void 0 || typeof declaration.border === "boolean" && declaration.kind === "card",
|
|
@@ -372,6 +372,11 @@ function action(value, optional = true) {
|
|
|
372
372
|
text(value.actionId, "action id");
|
|
373
373
|
optionalText(value.value, "action value");
|
|
374
374
|
optionalText(value.opens, "action opens");
|
|
375
|
+
if (value.agentPicker !== void 0) {
|
|
376
|
+
ensure(object(value.agentPicker), "invalid_payload", "Agent picker needs a project and machine");
|
|
377
|
+
text(value.agentPicker.machineId, "agent picker machine");
|
|
378
|
+
text(value.agentPicker.projectId, "agent picker project");
|
|
379
|
+
}
|
|
375
380
|
}
|
|
376
381
|
function meter(item) {
|
|
377
382
|
number(item.value);
|
|
@@ -414,9 +419,23 @@ var NODES = {
|
|
|
414
419
|
},
|
|
415
420
|
card(node2, depth, count) {
|
|
416
421
|
optionalText(node2.title, "title");
|
|
422
|
+
optionalText(node2.footer, "footer");
|
|
417
423
|
tone(node2.tone);
|
|
424
|
+
action(node2.action);
|
|
425
|
+
action(node2.externalAction);
|
|
426
|
+
boundedEntries(node2.tags ?? [], "tags", (tag) => {
|
|
427
|
+
text(tag.label, "tag label");
|
|
428
|
+
tone(tag.tone);
|
|
429
|
+
});
|
|
418
430
|
children(node2, depth, count);
|
|
419
431
|
},
|
|
432
|
+
input(node2) {
|
|
433
|
+
text(node2.id, "id");
|
|
434
|
+
text(node2.value, "value");
|
|
435
|
+
optionalText(node2.placeholder, "placeholder");
|
|
436
|
+
action(node2.action, false);
|
|
437
|
+
integer(node2.maxLength, 4096, "maxLength");
|
|
438
|
+
},
|
|
420
439
|
stat(node2) {
|
|
421
440
|
text(node2.label, "label");
|
|
422
441
|
text(node2.value, "value");
|
|
@@ -490,6 +509,7 @@ var NODES = {
|
|
|
490
509
|
button(node2) {
|
|
491
510
|
text(node2.label, "label");
|
|
492
511
|
action(node2.action, false);
|
|
512
|
+
flag(node2.sticky, "sticky");
|
|
493
513
|
}
|
|
494
514
|
};
|
|
495
515
|
function walk(node2, depth, count) {
|
|
@@ -503,9 +523,14 @@ function visitActions(node2, visit) {
|
|
|
503
523
|
case "stack":
|
|
504
524
|
case "row":
|
|
505
525
|
case "card":
|
|
526
|
+
if (node2.type === "card") {
|
|
527
|
+
if (node2.action !== void 0) visit(node2.action);
|
|
528
|
+
if (node2.externalAction !== void 0) visit(node2.externalAction);
|
|
529
|
+
}
|
|
506
530
|
for (const child of node2.children ?? []) visitActions(child, visit);
|
|
507
531
|
break;
|
|
508
532
|
case "button":
|
|
533
|
+
case "input":
|
|
509
534
|
visit(node2.action);
|
|
510
535
|
break;
|
|
511
536
|
case "tabs":
|
|
@@ -521,7 +546,7 @@ function visitActions(node2, visit) {
|
|
|
521
546
|
}
|
|
522
547
|
}
|
|
523
548
|
var ONE_LINE = ["text", "badge", "dot", "progress", "segments", "stat", "divider"];
|
|
524
|
-
var PANEL_ONLY = ["card", "kv", "tabs", "select", "table", "log", "button"];
|
|
549
|
+
var PANEL_ONLY = ["card", "kv", "tabs", "select", "table", "log", "button", "input"];
|
|
525
550
|
function cardLines(node2) {
|
|
526
551
|
if (node2.type === "stack") {
|
|
527
552
|
const children2 = node2.children ?? [];
|
|
@@ -559,7 +584,7 @@ function compact(value) {
|
|
|
559
584
|
var node = (type, fields) => compact({ type, ...fields });
|
|
560
585
|
var ui = Object.freeze({
|
|
561
586
|
view: (root, { title } = {}) => compact({ kind: "view", root, title }),
|
|
562
|
-
action: (actionId, { value, opens } = {}) => compact({ actionId, value, opens }),
|
|
587
|
+
action: (actionId, { value, opens, agentPicker } = {}) => compact({ actionId, value, opens, agentPicker }),
|
|
563
588
|
span: (value, { tone: tone2, weight, mono } = {}) => compact({ text: value, tone: tone2, weight, mono }),
|
|
564
589
|
stack: (items, { gap } = {}) => node("stack", { gap, children: items }),
|
|
565
590
|
row: (items, { align } = {}) => node("row", { children: items, align }),
|
|
@@ -570,7 +595,7 @@ var ui = Object.freeze({
|
|
|
570
595
|
dot: (tone2) => node("dot", { tone: tone2 }),
|
|
571
596
|
progress: (value, max, { tone: tone2, label } = {}) => node("progress", { value, max, tone: tone2, label }),
|
|
572
597
|
segments: (items) => node("segments", { items: items.map(compact) }),
|
|
573
|
-
card: (items, { title, tone: tone2 } = {}) => node("card", { title, tone: tone2, children: items }),
|
|
598
|
+
card: (items, { title, tone: tone2, tags, action: action2, externalAction, footer } = {}) => node("card", { title, tone: tone2, tags, action: action2, externalAction, footer, children: items }),
|
|
574
599
|
stat: (label, value, { tone: tone2, hint } = {}) => node("stat", { label, value, tone: tone2, hint }),
|
|
575
600
|
kv: (items) => node("kv", { items: items.map(compact) }),
|
|
576
601
|
tabs: (id, items, { filters, action: action2 } = {}) => node("tabs", { id, items: items.map(compact), filters, action: action2 }),
|
|
@@ -578,7 +603,8 @@ var ui = Object.freeze({
|
|
|
578
603
|
table: (id, columns, rows = []) => node("table", { id, columns: columns.map(compact), rows: rows.map(compact) }),
|
|
579
604
|
log: (lines) => node("log", { lines }),
|
|
580
605
|
/** `action` is an action object or an action id. */
|
|
581
|
-
button: (label, action2) => node("button", { label, action: typeof action2 === "string" ? { actionId: action2 } : action2 })
|
|
606
|
+
button: (label, action2) => node("button", { label, action: typeof action2 === "string" ? { actionId: action2 } : action2 }),
|
|
607
|
+
input: (id, value, action2, { placeholder, maxLength } = {}) => node("input", { id, value, placeholder, maxLength, action: typeof action2 === "string" ? { actionId: action2 } : action2 })
|
|
582
608
|
});
|
|
583
609
|
|
|
584
610
|
// ../plugin-sdk/src/index.mjs
|
|
@@ -161,9 +161,9 @@ function validateManifest(value) {
|
|
|
161
161
|
ensure(object(declaration) && identifier(declaration.id) && !ids.has(declaration.id) && SURFACE_KINDS.includes(declaration.kind) && ANCHORS.includes(declaration.anchor), "invalid_manifest", "Invalid contribution declaration");
|
|
162
162
|
ids.add(declaration.id);
|
|
163
163
|
ensure(
|
|
164
|
-
declaration.icon === void 0 || declaration.kind
|
|
164
|
+
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),
|
|
165
165
|
"invalid_manifest",
|
|
166
|
-
"Card icon must be one Nerd Font private-use glyph"
|
|
166
|
+
"Card or panel icon must be one Nerd Font private-use glyph"
|
|
167
167
|
);
|
|
168
168
|
ensure(
|
|
169
169
|
declaration.border === void 0 || typeof declaration.border === "boolean" && declaration.kind === "card",
|
|
@@ -224,9 +224,11 @@ var OPERATIONS = Object.freeze({
|
|
|
224
224
|
"state.get": null,
|
|
225
225
|
"state.set": null,
|
|
226
226
|
"state.keys": null,
|
|
227
|
+
"panel.open": "surfaces",
|
|
227
228
|
"context.get": null,
|
|
228
229
|
"popover.open": "surfaces",
|
|
229
230
|
"canvas.write": "surfaces",
|
|
231
|
+
"remote.request": "surfaces",
|
|
230
232
|
"canvas.focus": "surfaces",
|
|
231
233
|
"subscription.add": null,
|
|
232
234
|
"subscription.remove": null,
|
|
@@ -279,8 +281,14 @@ function validateEnvelope(frame, { inbound = false } = {}) {
|
|
|
279
281
|
jsonBytes(frame, frameLimit(frame, inbound));
|
|
280
282
|
ensure(object(frame) && frame.version === RUNNER_PROTOCOL_VERSION, "incompatible_version", "Daemon and runner protocol versions differ");
|
|
281
283
|
validateProducer(frame.producer);
|
|
282
|
-
ensure(["request", "response", "cancel", "surface"].includes(frame.kind), "invalid_payload", "Unknown runner frame kind");
|
|
283
|
-
if (frame.kind === "
|
|
284
|
+
ensure(["request", "response", "cancel", "surface", "report"].includes(frame.kind), "invalid_payload", "Unknown runner frame kind");
|
|
285
|
+
if (frame.kind === "report") {
|
|
286
|
+
ensure(
|
|
287
|
+
identifier(frame.name) && object(frame.entity) && typeof frame.sequence === "string" && /^(0|[1-9]\d{0,19})$/.test(frame.sequence) && BigInt(frame.sequence) <= 18446744073709551615n && Number.isInteger(frame.schemaVersion) && frame.schemaVersion > 0 && frame.schemaVersion <= 65535 && Object.hasOwn(frame, "value") && frame.value !== void 0,
|
|
288
|
+
"invalid_payload",
|
|
289
|
+
"Invalid report replacement"
|
|
290
|
+
);
|
|
291
|
+
} else if (frame.kind === "surface") {
|
|
284
292
|
ensure(object(frame.key) && identifier(frame.key.contributionId) && typeof frame.sequence === "string" && /^(0|[1-9]\d{0,19})$/.test(frame.sequence) && BigInt(frame.sequence) <= 18446744073709551615n && Object.hasOwn(frame, "content"), "invalid_payload", "Invalid surface replacement");
|
|
285
293
|
} else {
|
|
286
294
|
ensure(typeof frame.id === "string" && frame.id.length > 0 && frame.id.length <= 128, "invalid_payload", "Missing correlation id");
|
|
@@ -309,13 +317,14 @@ function wireError(error) {
|
|
|
309
317
|
}
|
|
310
318
|
var realClock = Object.freeze({ now: () => Date.now(), setTimeout: (fn, ms) => setTimeout(fn, ms), clearTimeout: (id) => clearTimeout(id) });
|
|
311
319
|
var RpcPeer = class {
|
|
312
|
-
constructor({ producer, send, clock = realClock, onRequest, onSurface, onError = () => {
|
|
320
|
+
constructor({ producer, send, clock = realClock, onRequest, onSurface, onReport, onError = () => {
|
|
313
321
|
}, idPrefix = "host" }) {
|
|
314
322
|
this.producer = Object.freeze({ ...validateProducer(producer) });
|
|
315
323
|
this.send = send;
|
|
316
324
|
this.clock = clock;
|
|
317
325
|
this.onRequest = onRequest;
|
|
318
326
|
this.onSurface = onSurface;
|
|
327
|
+
this.onReport = onReport;
|
|
319
328
|
this.onError = onError;
|
|
320
329
|
this.pending = /* @__PURE__ */ new Map();
|
|
321
330
|
this.incoming = /* @__PURE__ */ new Map();
|
|
@@ -370,6 +379,10 @@ var RpcPeer = class {
|
|
|
370
379
|
this.onSurface?.(frame);
|
|
371
380
|
return;
|
|
372
381
|
}
|
|
382
|
+
if (frame.kind === "report") {
|
|
383
|
+
this.onReport?.(frame);
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
373
386
|
if (frame.kind === "response") {
|
|
374
387
|
const result = frame.result;
|
|
375
388
|
this.pending.get(frame.id)?.finish(result.ok ? null : new PluginError(result.error.code, result.error.message), result.value);
|
|
@@ -502,6 +515,11 @@ function action(value, optional = true) {
|
|
|
502
515
|
text(value.actionId, "action id");
|
|
503
516
|
optionalText(value.value, "action value");
|
|
504
517
|
optionalText(value.opens, "action opens");
|
|
518
|
+
if (value.agentPicker !== void 0) {
|
|
519
|
+
ensure(object(value.agentPicker), "invalid_payload", "Agent picker needs a project and machine");
|
|
520
|
+
text(value.agentPicker.machineId, "agent picker machine");
|
|
521
|
+
text(value.agentPicker.projectId, "agent picker project");
|
|
522
|
+
}
|
|
505
523
|
}
|
|
506
524
|
function meter(item) {
|
|
507
525
|
number(item.value);
|
|
@@ -544,9 +562,23 @@ var NODES = {
|
|
|
544
562
|
},
|
|
545
563
|
card(node2, depth, count) {
|
|
546
564
|
optionalText(node2.title, "title");
|
|
565
|
+
optionalText(node2.footer, "footer");
|
|
547
566
|
tone(node2.tone);
|
|
567
|
+
action(node2.action);
|
|
568
|
+
action(node2.externalAction);
|
|
569
|
+
boundedEntries(node2.tags ?? [], "tags", (tag) => {
|
|
570
|
+
text(tag.label, "tag label");
|
|
571
|
+
tone(tag.tone);
|
|
572
|
+
});
|
|
548
573
|
children(node2, depth, count);
|
|
549
574
|
},
|
|
575
|
+
input(node2) {
|
|
576
|
+
text(node2.id, "id");
|
|
577
|
+
text(node2.value, "value");
|
|
578
|
+
optionalText(node2.placeholder, "placeholder");
|
|
579
|
+
action(node2.action, false);
|
|
580
|
+
integer(node2.maxLength, 4096, "maxLength");
|
|
581
|
+
},
|
|
550
582
|
stat(node2) {
|
|
551
583
|
text(node2.label, "label");
|
|
552
584
|
text(node2.value, "value");
|
|
@@ -620,6 +652,7 @@ var NODES = {
|
|
|
620
652
|
button(node2) {
|
|
621
653
|
text(node2.label, "label");
|
|
622
654
|
action(node2.action, false);
|
|
655
|
+
flag(node2.sticky, "sticky");
|
|
623
656
|
}
|
|
624
657
|
};
|
|
625
658
|
function walk(node2, depth, count) {
|
|
@@ -633,9 +666,14 @@ function visitActions(node2, visit) {
|
|
|
633
666
|
case "stack":
|
|
634
667
|
case "row":
|
|
635
668
|
case "card":
|
|
669
|
+
if (node2.type === "card") {
|
|
670
|
+
if (node2.action !== void 0) visit(node2.action);
|
|
671
|
+
if (node2.externalAction !== void 0) visit(node2.externalAction);
|
|
672
|
+
}
|
|
636
673
|
for (const child of node2.children ?? []) visitActions(child, visit);
|
|
637
674
|
break;
|
|
638
675
|
case "button":
|
|
676
|
+
case "input":
|
|
639
677
|
visit(node2.action);
|
|
640
678
|
break;
|
|
641
679
|
case "tabs":
|
|
@@ -651,7 +689,7 @@ function visitActions(node2, visit) {
|
|
|
651
689
|
}
|
|
652
690
|
}
|
|
653
691
|
var ONE_LINE = ["text", "badge", "dot", "progress", "segments", "stat", "divider"];
|
|
654
|
-
var PANEL_ONLY = ["card", "kv", "tabs", "select", "table", "log", "button"];
|
|
692
|
+
var PANEL_ONLY = ["card", "kv", "tabs", "select", "table", "log", "button", "input"];
|
|
655
693
|
function cardLines(node2) {
|
|
656
694
|
if (node2.type === "stack") {
|
|
657
695
|
const children2 = node2.children ?? [];
|
|
@@ -689,7 +727,7 @@ function compact(value) {
|
|
|
689
727
|
var node = (type, fields) => compact({ type, ...fields });
|
|
690
728
|
var ui = Object.freeze({
|
|
691
729
|
view: (root, { title } = {}) => compact({ kind: "view", root, title }),
|
|
692
|
-
action: (actionId, { value, opens } = {}) => compact({ actionId, value, opens }),
|
|
730
|
+
action: (actionId, { value, opens, agentPicker } = {}) => compact({ actionId, value, opens, agentPicker }),
|
|
693
731
|
span: (value, { tone: tone2, weight, mono } = {}) => compact({ text: value, tone: tone2, weight, mono }),
|
|
694
732
|
stack: (items, { gap } = {}) => node("stack", { gap, children: items }),
|
|
695
733
|
row: (items, { align } = {}) => node("row", { children: items, align }),
|
|
@@ -700,7 +738,7 @@ var ui = Object.freeze({
|
|
|
700
738
|
dot: (tone2) => node("dot", { tone: tone2 }),
|
|
701
739
|
progress: (value, max, { tone: tone2, label } = {}) => node("progress", { value, max, tone: tone2, label }),
|
|
702
740
|
segments: (items) => node("segments", { items: items.map(compact) }),
|
|
703
|
-
card: (items, { title, tone: tone2 } = {}) => node("card", { title, tone: tone2, children: items }),
|
|
741
|
+
card: (items, { title, tone: tone2, tags, action: action2, externalAction, footer } = {}) => node("card", { title, tone: tone2, tags, action: action2, externalAction, footer, children: items }),
|
|
704
742
|
stat: (label, value, { tone: tone2, hint } = {}) => node("stat", { label, value, tone: tone2, hint }),
|
|
705
743
|
kv: (items) => node("kv", { items: items.map(compact) }),
|
|
706
744
|
tabs: (id, items, { filters, action: action2 } = {}) => node("tabs", { id, items: items.map(compact), filters, action: action2 }),
|
|
@@ -708,7 +746,8 @@ var ui = Object.freeze({
|
|
|
708
746
|
table: (id, columns, rows = []) => node("table", { id, columns: columns.map(compact), rows: rows.map(compact) }),
|
|
709
747
|
log: (lines) => node("log", { lines }),
|
|
710
748
|
/** `action` is an action object or an action id. */
|
|
711
|
-
button: (label, action2) => node("button", { label, action: typeof action2 === "string" ? { actionId: action2 } : action2 })
|
|
749
|
+
button: (label, action2) => node("button", { label, action: typeof action2 === "string" ? { actionId: action2 } : action2 }),
|
|
750
|
+
input: (id, value, action2, { placeholder, maxLength } = {}) => node("input", { id, value, placeholder, maxLength, action: typeof action2 === "string" ? { actionId: action2 } : action2 })
|
|
712
751
|
});
|
|
713
752
|
|
|
714
753
|
// ../plugin-sdk/src/row-layout.mjs
|
|
@@ -850,7 +889,7 @@ function validateContent(content, declaration, manifest) {
|
|
|
850
889
|
if (content.kind === "view") {
|
|
851
890
|
validateView(content.root, { kind: declaration.kind, manifest });
|
|
852
891
|
if (content.title !== void 0) {
|
|
853
|
-
ensure(
|
|
892
|
+
ensure(["card", "panel"].includes(kind) && Array.isArray(content.title), "invalid_payload", "Styled titles belong to card or panel views");
|
|
854
893
|
validatePassiveText(content.title, 512, "card title");
|
|
855
894
|
}
|
|
856
895
|
}
|
|
@@ -890,6 +929,7 @@ function createRuntime({ manifest: input, producer, send, clock = realClock, onE
|
|
|
890
929
|
const schedules = /* @__PURE__ */ new Set();
|
|
891
930
|
const cleanups = /* @__PURE__ */ new Set();
|
|
892
931
|
const publishers = /* @__PURE__ */ new Map();
|
|
932
|
+
const reports = /* @__PURE__ */ new Map();
|
|
893
933
|
let visibility = /* @__PURE__ */ new Set();
|
|
894
934
|
let counter = 0;
|
|
895
935
|
let sequence = 0n;
|
|
@@ -961,6 +1001,76 @@ function createRuntime({ manifest: input, producer, send, clock = realClock, onE
|
|
|
961
1001
|
publishers.set(identity, publisher);
|
|
962
1002
|
return { publisher, key };
|
|
963
1003
|
}
|
|
1004
|
+
function report(name, entity) {
|
|
1005
|
+
active();
|
|
1006
|
+
ensure(
|
|
1007
|
+
manifest.capabilities.includes("surfaces") && identifier(name),
|
|
1008
|
+
"capability_denied",
|
|
1009
|
+
"Reports require surfaces capability and a valid name"
|
|
1010
|
+
);
|
|
1011
|
+
const owner = validateEntity(entity);
|
|
1012
|
+
ensure(
|
|
1013
|
+
["account", "machine", "project", "pane"].includes(owner.kind),
|
|
1014
|
+
"invalid_payload",
|
|
1015
|
+
"Reports need an owned entity"
|
|
1016
|
+
);
|
|
1017
|
+
if (owner.kind === "machine") {
|
|
1018
|
+
ensure(
|
|
1019
|
+
owner.id === producer.machineId && (owner.machineId === void 0 || owner.machineId === producer.machineId),
|
|
1020
|
+
"invalid_payload",
|
|
1021
|
+
"Report machine must be the local machine"
|
|
1022
|
+
);
|
|
1023
|
+
}
|
|
1024
|
+
if (owner.kind === "project" || owner.kind === "pane") {
|
|
1025
|
+
ensure(
|
|
1026
|
+
owner.machineId === producer.machineId && owner.generation !== void 0 && owner.generation !== "0",
|
|
1027
|
+
"invalid_payload",
|
|
1028
|
+
"Report entity needs its local machine and generation"
|
|
1029
|
+
);
|
|
1030
|
+
}
|
|
1031
|
+
const key = JSON.stringify([name, owner]);
|
|
1032
|
+
ensure(
|
|
1033
|
+
!reports.has(key) && reports.size < LIMITS.contributions,
|
|
1034
|
+
"queue_full",
|
|
1035
|
+
"Report publisher exists or capacity is full"
|
|
1036
|
+
);
|
|
1037
|
+
let disposed = false;
|
|
1038
|
+
const sendReport = (value, schemaVersion) => {
|
|
1039
|
+
active();
|
|
1040
|
+
ensure(!disposed, "disposed", "Report publisher is disposed");
|
|
1041
|
+
ensure(
|
|
1042
|
+
Number.isInteger(schemaVersion) && schemaVersion > 0 && schemaVersion <= 65535,
|
|
1043
|
+
"invalid_payload",
|
|
1044
|
+
"Invalid report schema version"
|
|
1045
|
+
);
|
|
1046
|
+
if (value !== null) jsonBytes(value);
|
|
1047
|
+
peer.transmit(peer.frame("report", {
|
|
1048
|
+
name,
|
|
1049
|
+
entity: owner,
|
|
1050
|
+
sequence: String(++sequence),
|
|
1051
|
+
schemaVersion,
|
|
1052
|
+
value
|
|
1053
|
+
}));
|
|
1054
|
+
};
|
|
1055
|
+
const publisher = {
|
|
1056
|
+
replace: (value, schemaVersion = 1) => {
|
|
1057
|
+
ensure(value !== null && value !== void 0, "invalid_payload", "Report value is required");
|
|
1058
|
+
sendReport(value, schemaVersion);
|
|
1059
|
+
},
|
|
1060
|
+
clear: () => sendReport(null, 1),
|
|
1061
|
+
dispose() {
|
|
1062
|
+
if (disposed) return;
|
|
1063
|
+
try {
|
|
1064
|
+
if (!lifetime.signal.aborted) sendReport(null, 1);
|
|
1065
|
+
} finally {
|
|
1066
|
+
disposed = true;
|
|
1067
|
+
reports.delete(key);
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
};
|
|
1071
|
+
reports.set(key, publisher);
|
|
1072
|
+
return publisher;
|
|
1073
|
+
}
|
|
964
1074
|
function subscribe(kind, name, handler, condition = always, registration) {
|
|
965
1075
|
active();
|
|
966
1076
|
ensure(typeof handler === "function", "invalid_payload", "Subscription requires a handler");
|
|
@@ -1170,6 +1280,28 @@ function createRuntime({ manifest: input, producer, send, clock = realClock, onE
|
|
|
1170
1280
|
kind,
|
|
1171
1281
|
(id, entity) => publish(kind, id, entity).publisher
|
|
1172
1282
|
])),
|
|
1283
|
+
report,
|
|
1284
|
+
remote: Object.freeze({ request(remoteReport, operation, payload, options) {
|
|
1285
|
+
active();
|
|
1286
|
+
ensure(object(remoteReport) && object(remoteReport.source), "invalid_payload", "A current source report is required");
|
|
1287
|
+
const source = validateProducer(remoteReport.source.producer);
|
|
1288
|
+
ensure(
|
|
1289
|
+
source.pluginId === manifest.id && identifier(remoteReport.name) && identifier(operation),
|
|
1290
|
+
"invalid_payload",
|
|
1291
|
+
"Invalid remote report request"
|
|
1292
|
+
);
|
|
1293
|
+
const entity = validateEntity(remoteReport.entity);
|
|
1294
|
+
ensure(typeof remoteReport.sequence === "string" && /^(0|[1-9]\d{0,19})$/.test(remoteReport.sequence) && BigInt(remoteReport.sequence) > 0n, "invalid_payload", "Invalid report sequence");
|
|
1295
|
+
jsonBytes(payload, 224 * 1024);
|
|
1296
|
+
return request("remote.request", {
|
|
1297
|
+
source,
|
|
1298
|
+
name: remoteReport.name,
|
|
1299
|
+
entity,
|
|
1300
|
+
sequence: remoteReport.sequence,
|
|
1301
|
+
operation,
|
|
1302
|
+
payload
|
|
1303
|
+
}, options);
|
|
1304
|
+
} }),
|
|
1173
1305
|
canvas(id, spec, entity) {
|
|
1174
1306
|
const { publisher, key } = publish(null, id, entity);
|
|
1175
1307
|
try {
|
|
@@ -1202,6 +1334,7 @@ function createRuntime({ manifest: input, producer, send, clock = realClock, onE
|
|
|
1202
1334
|
panes: Object.freeze(Object.fromEntries(["create", "close", "restart", "input", "focus", "wait"].map((name) => [name, method(`pane.${name}`)]))),
|
|
1203
1335
|
projects: Object.freeze({ create: method("project.create"), remove: method("project.remove") }),
|
|
1204
1336
|
notifications: Object.freeze({ show: method("notification.show") }),
|
|
1337
|
+
panels: Object.freeze({ open: (contributionId, options) => request("panel.open", { contributionId }, options) }),
|
|
1205
1338
|
url: Object.freeze({ open: (url, options) => request("url.open", { url }, options) }),
|
|
1206
1339
|
fetch: method("fetch"),
|
|
1207
1340
|
secrets: Object.freeze({ get: (name, options) => request("secret.get", { name }, options) }),
|
|
@@ -1237,6 +1370,13 @@ function createRuntime({ manifest: input, producer, send, clock = realClock, onE
|
|
|
1237
1370
|
onError(error);
|
|
1238
1371
|
}
|
|
1239
1372
|
}
|
|
1373
|
+
for (const publisher of reports.values()) {
|
|
1374
|
+
try {
|
|
1375
|
+
publisher.dispose();
|
|
1376
|
+
} catch (error) {
|
|
1377
|
+
onError(error);
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1240
1380
|
lifetime.abort();
|
|
1241
1381
|
for (const disposable of schedules) disposable.dispose();
|
|
1242
1382
|
peer.dispose();
|
|
@@ -1311,7 +1451,7 @@ var Outbox = class {
|
|
|
1311
1451
|
const frame = framed(message);
|
|
1312
1452
|
const serialized = jsonBytes(message, frameLimit(frame, true));
|
|
1313
1453
|
const size = Buffer.byteLength(serialized);
|
|
1314
|
-
const key = frame.kind === "surface" ? JSON.stringify([frame.producer, frame.key]) : null;
|
|
1454
|
+
const key = frame.kind === "surface" ? JSON.stringify(["surface", frame.producer, frame.key]) : frame.kind === "report" ? JSON.stringify(["report", frame.producer, frame.name, frame.entity]) : null;
|
|
1315
1455
|
const previous = key === null ? -1 : this.queue.findIndex((item2) => item2.key === key);
|
|
1316
1456
|
const replaced = previous < 0 ? 0 : this.queue[previous].size;
|
|
1317
1457
|
const budget = LIMITS.queuedBytes + (frame.kind === "response" ? LIMITS.responseFrameBytes : 0);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
a774785fae578c8118b708a9d48336a7a3ca0672c869f855d9f3a1596166cb3f TMUX-ARTIFACT-METADATA.txt
|
|
2
|
+
d7a3388a2b6deaf41b28bfd6c952ae086c5d01fe68526f3be86553c727fab8d9 TMUX-BUILD-TOOLS.txt
|
|
3
|
+
0d8aed2221c91178434a92607e2f324018370048c048e9de1b28b576be30d855 TMUX-OTOOL-L.txt
|
|
4
|
+
b632af894bba85cba0f93d6c54d508325c462af2c697405971bc57db87f31e22 bin/tmux
|
|
5
|
+
ff02effc9b331edcdac387d198691bfa3e575e7d244ad10cb826aa51ef085670 licenses/libevent.txt
|
|
6
|
+
2116115d46eeb1e736acfa562eed14fe6c34760794bc5b484642fe694adde0fd licenses/tmux.txt
|