@ai-ecoverse/slicc-spectrum 1.77.1 → 1.79.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,6 +14,50 @@ import "./chunk-AXQFWXYZ.js";
14
14
 
15
15
  // src/dummy/approvals.ts
16
16
  var minutes = 6e4;
17
+ var mara = { kind: "guest", name: "Seat 2 (Mara)" };
18
+ function guestFixtures(now2 = Date.now()) {
19
+ return [
20
+ {
21
+ id: "guest-note",
22
+ kind: "guest-message",
23
+ requester: mara,
24
+ agentId: "cone-sliccy",
25
+ agentName: "sliccy",
26
+ text: "Could you tidy the harbor schedule?\nKeep <b>Tuesday</b> as it is and **skip** the ferry rows.",
27
+ attachments: [
28
+ { name: "schedule.csv", mimeType: "text/csv", size: 18432 },
29
+ { name: "pier-map.png", mimeType: "image/png", size: 2411725 }
30
+ ],
31
+ createdAt: now2,
32
+ expiresAt: now2 + 5 * minutes,
33
+ always: false,
34
+ verdict: { decision: "allow", reason: "it asks for an edit inside the shared folder." }
35
+ },
36
+ {
37
+ id: "guest-fetch",
38
+ kind: "guest-tool",
39
+ requester: mara,
40
+ agentId: "scoop-docs",
41
+ agentName: "docs-pass",
42
+ tool: "fetch",
43
+ summary: "GET https://tides.example/api/harbor?days=7",
44
+ createdAt: now2 + 1,
45
+ expiresAt: now2 + 5 * minutes,
46
+ always: false,
47
+ verdict: { decision: "deny", reason: "guests may not reach hosts outside the session." }
48
+ },
49
+ {
50
+ id: "guest-late",
51
+ kind: "guest-message",
52
+ requester: { kind: "guest", name: "Seat 3 (Ilse)" },
53
+ agentId: "cone-sliccy",
54
+ text: "Is the pier map up to date?",
55
+ createdAt: now2 + 2,
56
+ expiresAt: now2 + 5 * minutes,
57
+ always: false
58
+ }
59
+ ];
60
+ }
17
61
  function approvalFixtures(scenario, now2 = Date.now()) {
18
62
  const agent = {
19
63
  id: "sudo-jq",
@@ -57,6 +101,7 @@ function approvalFixtures(scenario, now2 = Date.now()) {
57
101
  always: true
58
102
  }
59
103
  ];
104
+ if (scenario === "guest" || scenario === "guest-follower") return guestFixtures(now2);
60
105
  if (scenario === "none") return [];
61
106
  if (scenario === "user") return [user];
62
107
  if (scenario === "many") return [agent, user, cache];
@@ -74,7 +119,8 @@ var DummyApprovals = class extends Emitter {
74
119
  this.#approvals = approvalFixtures(scenario);
75
120
  this.#time = time;
76
121
  this.#fail = scenario === "fail";
77
- if (scenario !== "follower") this.decide = (id, decision) => this.#decide(id, decision);
122
+ if (scenario !== "follower" && scenario !== "guest-follower")
123
+ this.decide = (id, decision) => this.#decide(id, decision);
78
124
  if (scenario === "elsewhere" || scenario === "withdrawn")
79
125
  void time.sleep(100).then(() => this.end("sudo-jq", scenario === "elsewhere" ? "answered" : "withdrawn"));
80
126
  }
@@ -93,6 +139,7 @@ var DummyApprovals = class extends Emitter {
93
139
  async #decide(id, decision) {
94
140
  await this.#time.sleep(10);
95
141
  if (this.#fail) throw new Error("The kernel stopped waiting. Run the command again.");
142
+ if (id === "guest-late") throw new Error("Someone else already answered this.");
96
143
  this.decisions.push([id, decision]);
97
144
  this.end(id, "answered");
98
145
  }
@@ -437,6 +484,88 @@ var DummyFollow = class extends Emitter {
437
484
  }
438
485
  };
439
486
 
487
+ // src/dummy/guests.ts
488
+ var hour = 36e5;
489
+ var day = 24 * hour;
490
+ var cap = 30 * day;
491
+ var guestsUnavailable = "Guests need the tray hub. Connect this SLICC to a tray to invite one.";
492
+ var guestsRefused = "The hub couldn\u2019t make a link right now. Try again in a minute.";
493
+ function guestsFixtures(scenario, now2 = Date.now()) {
494
+ if (scenario === "none" || scenario === "unavailable") return [];
495
+ return [
496
+ {
497
+ id: "seat-mara",
498
+ label: "Seat 1 (Mara)",
499
+ agentId: "cone-sliccy",
500
+ createdAt: now2 - 2 * hour,
501
+ expiresAt: now2 + 5 * day + 3 * hour,
502
+ gates: { messages: "user", tools: "user" },
503
+ connected: true,
504
+ pending: 2
505
+ },
506
+ {
507
+ id: "seat-ole",
508
+ label: "Seat 2 (Ole)",
509
+ agentId: "cone-harbor",
510
+ createdAt: now2 - 3 * day,
511
+ expiresAt: null,
512
+ gates: { messages: "scoop:quiet-otter", tools: "agent" },
513
+ connected: false,
514
+ pending: 0
515
+ }
516
+ ];
517
+ }
518
+ var DummyGuests = class extends Emitter {
519
+ scenario;
520
+ #seats;
521
+ #clock;
522
+ #count = 0;
523
+ constructor(scenario, clock2) {
524
+ super();
525
+ this.scenario = scenario;
526
+ this.#clock = clock2;
527
+ this.#seats = guestsFixtures(scenario);
528
+ }
529
+ list() {
530
+ return this.#seats;
531
+ }
532
+ unavailable() {
533
+ return this.scenario === "unavailable" ? guestsUnavailable : null;
534
+ }
535
+ setScenario(scenario) {
536
+ this.scenario = scenario;
537
+ this.#seats = guestsFixtures(scenario);
538
+ this.emit("unavailable", this.unavailable());
539
+ this.emit("seats", this.#seats);
540
+ }
541
+ async mint(agentId, draft) {
542
+ await this.#clock.sleep(4);
543
+ const refused = this.unavailable() ?? (this.scenario === "fail" ? guestsRefused : null);
544
+ if (refused) throw new Error(refused);
545
+ this.#count += 1;
546
+ const now2 = Date.now();
547
+ const seat = {
548
+ id: `seat-${now2.toString(36)}-${this.#count}`,
549
+ label: draft.label,
550
+ agentId,
551
+ createdAt: now2,
552
+ expiresAt: draft.expiresAt === null ? null : Math.min(draft.expiresAt, now2 + cap),
553
+ gates: draft.gates,
554
+ connected: false,
555
+ pending: 0
556
+ };
557
+ this.#seats = [...this.#seats, seat];
558
+ this.emit("seats", this.#seats);
559
+ return { seat, url: `https://www.example.com/guest/${seat.id}#k=Tq7Lm2Vx9Rb4` };
560
+ }
561
+ async revoke(id) {
562
+ await this.#clock.sleep(4);
563
+ if (!this.#seats.some((seat) => seat.id === id)) throw new Error("That guest is already gone.");
564
+ this.#seats = this.#seats.filter((seat) => seat.id !== id);
565
+ this.emit("seats", this.#seats);
566
+ }
567
+ };
568
+
440
569
  // src/dummy/script.ts
441
570
  var units = "/workspace/harbor/src/lib/units.ts";
442
571
  var kelvin = `
@@ -2331,16 +2460,16 @@ var status = `<!DOCTYPE html>
2331
2460
  `;
2332
2461
 
2333
2462
  // src/dummy/extras.ts
2334
- var day = 864e5;
2463
+ var day2 = 864e5;
2335
2464
  var now = Date.UTC(2026, 9, 5, 9, 0);
2336
2465
  function frozenConversation(topic, reply) {
2337
2466
  return [
2338
- { id: `f-${topic}-1`, role: "user", text: topic, createdAt: now - 3 * day },
2467
+ { id: `f-${topic}-1`, role: "user", text: topic, createdAt: now - 3 * day2 },
2339
2468
  {
2340
2469
  id: `f-${topic}-2`,
2341
2470
  role: "assistant",
2342
2471
  status: "done",
2343
- createdAt: now - 3 * day + 6e4,
2472
+ createdAt: now - 3 * day2 + 6e4,
2344
2473
  parts: [{ type: "text", text: reply }]
2345
2474
  }
2346
2475
  ];
@@ -2354,7 +2483,7 @@ var frozen = [
2354
2483
  title: "Write the onboarding guide for new contributors",
2355
2484
  model: "claude-sonnet-5-5",
2356
2485
  messages: 42,
2357
- frozenAt: now - 2 * day
2486
+ frozenAt: now - 2 * day2
2358
2487
  },
2359
2488
  messages: frozenConversation(
2360
2489
  "Write the onboarding guide for new contributors",
@@ -2369,7 +2498,7 @@ var frozen = [
2369
2498
  title: "Spike: can the cache move to KV without a cold start?",
2370
2499
  model: "claude-opus-5-5",
2371
2500
  messages: 118,
2372
- frozenAt: now - 6 * day
2501
+ frozenAt: now - 6 * day2
2373
2502
  },
2374
2503
  messages: frozenConversation(
2375
2504
  "Spike: can the cache move to KV without a cold start?",
@@ -2384,7 +2513,7 @@ var frozen = [
2384
2513
  title: "Summarize Q3 uptime and incidents",
2385
2514
  model: "claude-haiku-4-5",
2386
2515
  messages: 17,
2387
- frozenAt: now - 21 * day
2516
+ frozenAt: now - 21 * day2
2388
2517
  },
2389
2518
  messages: frozenConversation(
2390
2519
  "Summarize Q3 uptime and incidents",
@@ -2399,7 +2528,7 @@ var frozen = [
2399
2528
  title: "Check the tide tables against the harbor feed",
2400
2529
  model: "claude-haiku-4-5",
2401
2530
  messages: 9,
2402
- frozenAt: now - 1 * day
2531
+ frozenAt: now - 1 * day2
2403
2532
  },
2404
2533
  messages: frozenConversation(
2405
2534
  "Check the tide tables against the harbor feed",
@@ -2414,7 +2543,7 @@ var frozen = [
2414
2543
  title: "Write the nightly digest of merged pull requests",
2415
2544
  model: "claude-sonnet-5-5",
2416
2545
  messages: 6,
2417
- frozenAt: now - 3 * day
2546
+ frozenAt: now - 3 * day2
2418
2547
  },
2419
2548
  messages: frozenConversation(
2420
2549
  "Write the nightly digest of merged pull requests",
@@ -2430,7 +2559,7 @@ var memories = [
2430
2559
  title: "Lead with the result",
2431
2560
  body: "Keep replies short. Lead with the result, then the evidence.",
2432
2561
  tag: "feedback",
2433
- updatedAt: now - 5 * day
2562
+ updatedAt: now - 5 * day2
2434
2563
  },
2435
2564
  {
2436
2565
  id: "mem-2",
@@ -2439,7 +2568,7 @@ var memories = [
2439
2568
  title: "Tests before \u201Cfixed\u201D",
2440
2569
  body: "Run the tests before saying something is fixed, and quote the summary line.",
2441
2570
  tag: "feedback",
2442
- updatedAt: now - 9 * day
2571
+ updatedAt: now - 9 * day2
2443
2572
  },
2444
2573
  {
2445
2574
  id: "mem-3",
@@ -2448,7 +2577,7 @@ var memories = [
2448
2577
  title: "Works in UTC",
2449
2578
  body: "Schedules, timestamps and cron expressions are in UTC unless stated otherwise.",
2450
2579
  tag: "user",
2451
- updatedAt: now - 30 * day
2580
+ updatedAt: now - 30 * day2
2452
2581
  },
2453
2582
  {
2454
2583
  id: "mem-4",
@@ -2457,7 +2586,7 @@ var memories = [
2457
2586
  title: "harbor",
2458
2587
  body: "Forecast API, deployed as a worker. Cache bugs show up around midnight UTC. Staging deploys are frozen on Fridays.",
2459
2588
  tag: "project",
2460
- updatedAt: now - day
2589
+ updatedAt: now - day2
2461
2590
  },
2462
2591
  {
2463
2592
  id: "mem-5",
@@ -2466,7 +2595,7 @@ var memories = [
2466
2595
  title: "release-notes",
2467
2596
  body: "Drafted every Friday from merged pull requests, grouped as features, fixes and chores.",
2468
2597
  tag: "project",
2469
- updatedAt: now - 4 * day
2598
+ updatedAt: now - 4 * day2
2470
2599
  },
2471
2600
  {
2472
2601
  id: "mem-6",
@@ -2475,7 +2604,7 @@ var memories = [
2475
2604
  title: "Cache keys",
2476
2605
  body: "Cache keys are `city:UTC-date`. Never key on local time.",
2477
2606
  tag: "project",
2478
- updatedAt: now - 2 * day
2607
+ updatedAt: now - 2 * day2
2479
2608
  },
2480
2609
  {
2481
2610
  id: "mem-7",
@@ -2484,7 +2613,7 @@ var memories = [
2484
2613
  title: "Retries",
2485
2614
  body: "Retry upstream calls three times with exponential backoff starting at 250 ms.",
2486
2615
  tag: null,
2487
- updatedAt: now - 2 * day
2616
+ updatedAt: now - 2 * day2
2488
2617
  },
2489
2618
  {
2490
2619
  id: "mem-8",
@@ -2493,7 +2622,7 @@ var memories = [
2493
2622
  title: "Past tense, no ticket numbers",
2494
2623
  body: "One sentence per change, in the past tense, without ticket numbers.",
2495
2624
  tag: "feedback",
2496
- updatedAt: now - 7 * day
2625
+ updatedAt: now - 7 * day2
2497
2626
  },
2498
2627
  {
2499
2628
  id: "mem-9",
@@ -2502,7 +2631,7 @@ var memories = [
2502
2631
  title: "Read the tests first",
2503
2632
  body: "Start a review from the tests, then read the change they cover.",
2504
2633
  tag: "feedback",
2505
- updatedAt: now - 3 * day,
2634
+ updatedAt: now - 3 * day2,
2506
2635
  source: "entry"
2507
2636
  },
2508
2637
  {
@@ -2512,7 +2641,7 @@ var memories = [
2512
2641
  title: "Checks",
2513
2642
  body: "Flag any change to cache keys. Ask for a test when a retry count changes.",
2514
2643
  tag: null,
2515
- updatedAt: now - 3 * day,
2644
+ updatedAt: now - 3 * day2,
2516
2645
  source: "notes"
2517
2646
  }
2518
2647
  ];
@@ -5896,8 +6025,8 @@ Done in 3.8s`
5896
6025
 
5897
6026
  // src/dummy/vault.ts
5898
6027
  var minute2 = 6e4;
5899
- var hour = 60 * minute2;
5900
- var day2 = 24 * hour;
6028
+ var hour2 = 60 * minute2;
6029
+ var day3 = 24 * hour2;
5901
6030
  var harbor = { domain: "api.harbor.example", header: "Authorization", methods: [], paths: [] };
5902
6031
  var pier = {
5903
6032
  domain: "packages.pier.example",
@@ -5918,7 +6047,7 @@ function vaultSecrets(now2 = Date.now()) {
5918
6047
  rules: [harbor],
5919
6048
  exits: ["proxy", "tailscale", "device:link-pier"],
5920
6049
  exec: false,
5921
- createdAt: now2 - 12 * day2,
6050
+ createdAt: now2 - 12 * day3,
5922
6051
  usedAt: now2 - 4 * minute2
5923
6052
  },
5924
6053
  {
@@ -5932,9 +6061,9 @@ function vaultSecrets(now2 = Date.now()) {
5932
6061
  rules: [pier],
5933
6062
  exec: "argv",
5934
6063
  execArgv: [["pier", "publish"]],
5935
- createdAt: now2 - 3 * day2,
5936
- usedAt: now2 - 2 * hour,
5937
- expiresAt: now2 + 3 * day2
6064
+ createdAt: now2 - 3 * day3,
6065
+ usedAt: now2 - 2 * hour2,
6066
+ expiresAt: now2 + 3 * day3
5938
6067
  },
5939
6068
  {
5940
6069
  name: "TIDE_MAIL",
@@ -5961,7 +6090,7 @@ function vaultSecrets(now2 = Date.now()) {
5961
6090
  }
5962
6091
  ],
5963
6092
  exec: false,
5964
- createdAt: now2 - 20 * day2,
6093
+ createdAt: now2 - 20 * day3,
5965
6094
  expiresAt: now2 + 50 * minute2
5966
6095
  },
5967
6096
  {
@@ -5974,7 +6103,7 @@ function vaultSecrets(now2 = Date.now()) {
5974
6103
  domains: [],
5975
6104
  rules: [],
5976
6105
  exec: "any",
5977
- createdAt: now2 - 2 * hour
6106
+ createdAt: now2 - 2 * hour2
5978
6107
  },
5979
6108
  {
5980
6109
  name: "BUOY_OLD_TOKEN",
@@ -5986,8 +6115,8 @@ function vaultSecrets(now2 = Date.now()) {
5986
6115
  domains: ["buoy.example"],
5987
6116
  rules: [{ domain: "buoy.example", header: "X-Buoy-Key", methods: ["GET"], paths: [] }],
5988
6117
  exec: "shell",
5989
- createdAt: now2 - 40 * day2,
5990
- removedAt: now2 - day2
6118
+ createdAt: now2 - 40 * day3,
6119
+ removedAt: now2 - day3
5991
6120
  }
5992
6121
  ];
5993
6122
  }
@@ -6004,7 +6133,7 @@ function accountRecords(now2 = Date.now()) {
6004
6133
  domains: ["docs.example"],
6005
6134
  rules: [{ domain: "docs.example", header: "Authorization", methods: [], paths: [] }],
6006
6135
  exec: false,
6007
- createdAt: now2 - 6 * day2,
6136
+ createdAt: now2 - 6 * day3,
6008
6137
  usedAt: now2 - 20 * minute2
6009
6138
  }
6010
6139
  ];
@@ -6030,7 +6159,7 @@ function vaultAudit(now2 = Date.now()) {
6030
6159
  type: "materialize",
6031
6160
  seq: 11,
6032
6161
  id: "audit-11",
6033
- at: now2 - 2 * hour,
6162
+ at: now2 - 2 * hour2,
6034
6163
  name: "PIER_PUBLISH_TOKEN",
6035
6164
  exec: "argv",
6036
6165
  path: "/usr/bin/pier",
@@ -6046,7 +6175,7 @@ function vaultAudit(now2 = Date.now()) {
6046
6175
  type: "materialize",
6047
6176
  seq: 10,
6048
6177
  id: "audit-10",
6049
- at: now2 - 3 * hour,
6178
+ at: now2 - 3 * hour2,
6050
6179
  name: "PIER_PUBLISH_TOKEN",
6051
6180
  uid: 1001,
6052
6181
  tag: "docs-pass",
@@ -6065,7 +6194,7 @@ function vaultAudit(now2 = Date.now()) {
6065
6194
  type: "forward",
6066
6195
  seq: 9,
6067
6196
  id: "audit-9",
6068
- at: now2 - 6 * hour,
6197
+ at: now2 - 6 * hour2,
6069
6198
  name: "HARBOR_API_KEY",
6070
6199
  domain: "api.harbor.example",
6071
6200
  method: "POST",
@@ -6077,7 +6206,7 @@ function vaultAudit(now2 = Date.now()) {
6077
6206
  type: "policy",
6078
6207
  seq: 8,
6079
6208
  id: "audit-8",
6080
- at: now2 - day2,
6209
+ at: now2 - day3,
6081
6210
  file: "/etc/slicc/secrets-policy.toml",
6082
6211
  sha256: "4e07408562bedb8b60ce05c1decfe3ad",
6083
6212
  accepted: true,
@@ -6095,7 +6224,7 @@ function vaultAudit(now2 = Date.now()) {
6095
6224
  type: "remove",
6096
6225
  seq: 7,
6097
6226
  id: "audit-7",
6098
- at: now2 - day2 - hour,
6227
+ at: now2 - day3 - hour2,
6099
6228
  name: "BUOY_OLD_TOKEN"
6100
6229
  },
6101
6230
  {
@@ -6103,7 +6232,7 @@ function vaultAudit(now2 = Date.now()) {
6103
6232
  type: "seal",
6104
6233
  seq: 6,
6105
6234
  id: "audit-6",
6106
- at: now2 - 3 * day2,
6235
+ at: now2 - 3 * day3,
6107
6236
  name: "PIER_PUBLISH_TOKEN",
6108
6237
  source: "jerk:cone@link-pier",
6109
6238
  rotated: false
@@ -6116,7 +6245,7 @@ function vaultOlder(now2 = Date.now()) {
6116
6245
  type: "materialize",
6117
6246
  seq: 5,
6118
6247
  id: "audit-5",
6119
- at: now2 - 4 * day2,
6248
+ at: now2 - 4 * day3,
6120
6249
  name: "PIER_PUBLISH_TOKEN",
6121
6250
  uid: 1e3,
6122
6251
  tag: null,
@@ -6134,7 +6263,7 @@ function vaultOlder(now2 = Date.now()) {
6134
6263
  type: "policy",
6135
6264
  seq: 4,
6136
6265
  id: "audit-4",
6137
- at: now2 - 5 * day2,
6266
+ at: now2 - 5 * day3,
6138
6267
  file: "/etc/fnox/config.toml",
6139
6268
  sha256: "8f14e45fceea167a5a36dedd4bea2543",
6140
6269
  accepted: false,
@@ -6145,7 +6274,7 @@ function vaultOlder(now2 = Date.now()) {
6145
6274
  type: "restore",
6146
6275
  seq: 3,
6147
6276
  id: "audit-3",
6148
- at: now2 - 6 * day2,
6277
+ at: now2 - 6 * day3,
6149
6278
  name: "TIDE_MAIL",
6150
6279
  uid: 0,
6151
6280
  tag: null
@@ -6154,7 +6283,7 @@ function vaultOlder(now2 = Date.now()) {
6154
6283
  type: "mcp",
6155
6284
  seq: 2,
6156
6285
  id: "audit-2",
6157
- at: now2 - 7 * day2,
6286
+ at: now2 - 7 * day3,
6158
6287
  name: "DOCS_MCP_TOKEN",
6159
6288
  uid: 1e3,
6160
6289
  tag: "cone",
@@ -6596,6 +6725,9 @@ function vaultAccounts(accounts2) {
6596
6725
  (account) => account.auth === "api-key" || account.id === "github" ? { ...account, store: "vault" } : account
6597
6726
  );
6598
6727
  }
6728
+ function guestsPort(guests, time) {
6729
+ return guests === "off" ? {} : { guests: new DummyGuests(guests, time) };
6730
+ }
6599
6731
  function createDummyModel({
6600
6732
  delay = 30,
6601
6733
  storage = null,
@@ -6613,6 +6745,7 @@ function createDummyModel({
6613
6745
  approvals = "off",
6614
6746
  follow = "off",
6615
6747
  vault = "off",
6748
+ guests = "off",
6616
6749
  accounts: accounts2 = "settings",
6617
6750
  providers = "connected",
6618
6751
  hold = "off",
@@ -6689,7 +6822,8 @@ function createDummyModel({
6689
6822
  ...follow === "off" ? {} : { follow: new DummyFollow(follow, time) },
6690
6823
  ...vault === "off" ? {} : {
6691
6824
  vault: new DummyVault(vault, time, accounts2 === "vault" ? accountRecords() : [])
6692
- }
6825
+ },
6826
+ ...guestsPort(guests, time)
6693
6827
  };
6694
6828
  base.vault?.on("status", (status2) => {
6695
6829
  if (!status2.locked && agent.hold()?.reason === "locked") agent.setHold(null);
@@ -6704,6 +6838,7 @@ export {
6704
6838
  DummyBrowser,
6705
6839
  DummyChanges,
6706
6840
  DummyFollow,
6841
+ DummyGuests,
6707
6842
  DummyNetwork,
6708
6843
  DummyNotices,
6709
6844
  DummyTabs,
@@ -6715,6 +6850,9 @@ export {
6715
6850
  browserHistory,
6716
6851
  createDummyModel,
6717
6852
  followFixtures,
6853
+ guestsFixtures,
6854
+ guestsRefused,
6855
+ guestsUnavailable,
6718
6856
  joinUrl,
6719
6857
  leadersFixtures,
6720
6858
  linksFixtures,