@ai-ecoverse/slicc-spectrum 1.60.2 → 1.62.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.
@@ -39,6 +39,19 @@ function approvalFixtures(scenario, now2 = Date.now()) {
39
39
  expiresAt: now2 + 5 * minutes,
40
40
  always: false
41
41
  };
42
+ if (scenario === "secrets")
43
+ return [
44
+ {
45
+ id: "sudo-rules",
46
+ kind: "sudo",
47
+ requester: { kind: "agent", name: "docs-pass", agentId: "scoop-docs" },
48
+ command: "cp fnox.toml /etc/fnox/config.toml",
49
+ cwd: "/home/cone/harbor",
50
+ createdAt: now2,
51
+ expiresAt: now2 + 5 * minutes,
52
+ always: true
53
+ }
54
+ ];
42
55
  if (scenario === "user") return [user];
43
56
  if (scenario === "many") return [agent, user, cache];
44
57
  if (scenario === "elsewhere" || scenario === "withdrawn") return [agent, user];
@@ -100,7 +113,7 @@ function titleFor(url) {
100
113
  var second = 1e3;
101
114
  function browserHistory(scenario, now2 = Date.now()) {
102
115
  if (scenario === "off") return [];
103
- const harbor = { tabId: "tab-preview", agentId: "cone-harbor" };
116
+ const harbor2 = { tabId: "tab-preview", agentId: "cone-harbor" };
104
117
  const otter = { tabId: "tab-pull", agentId: "scoop-otter" };
105
118
  return [
106
119
  {
@@ -112,13 +125,13 @@ function browserHistory(scenario, now2 = Date.now()) {
112
125
  { ...otter, kind: "snapshot", at: now2 - 296 * second },
113
126
  { ...otter, kind: "scroll", at: now2 - 290 * second },
114
127
  { ...otter, kind: "screenshot", at: now2 - 288 * second },
115
- { ...harbor, kind: "open", value: "http://localhost:8787/", at: now2 - 120 * second },
116
- { ...harbor, kind: "snapshot", at: now2 - 116 * second },
117
- { ...harbor, kind: "type", target: 'textbox "City"', length: 6, at: now2 - 110 * second },
118
- { ...harbor, kind: "click", target: 'button "Show forecast"', at: now2 - 106 * second },
119
- { ...harbor, kind: "snapshot", at: now2 - 100 * second },
128
+ { ...harbor2, kind: "open", value: "http://localhost:8787/", at: now2 - 120 * second },
129
+ { ...harbor2, kind: "snapshot", at: now2 - 116 * second },
130
+ { ...harbor2, kind: "type", target: 'textbox "City"', length: 6, at: now2 - 110 * second },
131
+ { ...harbor2, kind: "click", target: 'button "Show forecast"', at: now2 - 106 * second },
132
+ { ...harbor2, kind: "snapshot", at: now2 - 100 * second },
120
133
  {
121
- ...harbor,
134
+ ...harbor2,
122
135
  kind: "click",
123
136
  target: 'link "Tomorrow"',
124
137
  status: "failed",
@@ -132,8 +145,8 @@ function browserHistory(scenario, now2 = Date.now()) {
132
145
  value: "GET https://api.example.com/v2/tides",
133
146
  at: now2 - 80 * second
134
147
  },
135
- { ...harbor, kind: "eval", at: now2 - 70 * second },
136
- { ...harbor, kind: "press", value: "End", at: now2 - 64 * second }
148
+ { ...harbor2, kind: "eval", at: now2 - 70 * second },
149
+ { ...harbor2, kind: "press", value: "End", at: now2 - 64 * second }
137
150
  ];
138
151
  }
139
152
  var drive = [
@@ -591,6 +604,7 @@ var DummyAgent = class extends Emitter {
591
604
  #messages = /* @__PURE__ */ new Map();
592
605
  #queues = /* @__PURE__ */ new Map();
593
606
  #frozen = [];
607
+ #hold = null;
594
608
  #ice = /* @__PURE__ */ new Map();
595
609
  #suggestions = /* @__PURE__ */ new Map();
596
610
  #runs = /* @__PURE__ */ new Map();
@@ -1021,6 +1035,13 @@ var DummyAgent = class extends Emitter {
1021
1035
  ...body ? { body } : {}
1022
1036
  });
1023
1037
  }
1038
+ hold() {
1039
+ return this.#hold && { ...this.#hold };
1040
+ }
1041
+ setHold(hold) {
1042
+ this.#hold = hold && { ...hold };
1043
+ this.emit("hold", this.hold());
1044
+ }
1024
1045
  frozen() {
1025
1046
  const live = this.#agents.filter((agent) => !agent.frozen).map((agent) => {
1026
1047
  const messages = this.#messages.get(agent.id);
@@ -5441,6 +5462,411 @@ Done in 3.8s`
5441
5462
  }
5442
5463
  };
5443
5464
 
5465
+ // src/dummy/vault.ts
5466
+ var minute2 = 6e4;
5467
+ var hour = 60 * minute2;
5468
+ var day2 = 24 * hour;
5469
+ var harbor = { domain: "api.harbor.example", header: "Authorization", methods: [], paths: [] };
5470
+ var pier = {
5471
+ domain: "packages.pier.example",
5472
+ header: "Authorization",
5473
+ methods: ["PUT"],
5474
+ paths: ["/-/package/*"]
5475
+ };
5476
+ function vaultSecrets(now2 = Date.now()) {
5477
+ return [
5478
+ {
5479
+ name: "HARBOR_API_KEY",
5480
+ kind: "secret",
5481
+ placeholder: "fnox_proxy_harbor01",
5482
+ state: "active",
5483
+ source: "popup",
5484
+ sourceDevice: null,
5485
+ domains: ["api.harbor.example"],
5486
+ rules: [harbor],
5487
+ exits: ["vault-direct", "local-proxy", "tailscale", "device:link-pier"],
5488
+ exec: false,
5489
+ createdAt: now2 - 12 * day2,
5490
+ usedAt: now2 - 4 * minute2
5491
+ },
5492
+ {
5493
+ name: "PIER_PUBLISH_TOKEN",
5494
+ kind: "secret",
5495
+ placeholder: "fnox_proxy_pier0002",
5496
+ state: "active",
5497
+ source: "jerk:cone@link-pier",
5498
+ sourceDevice: "link-pier",
5499
+ domains: ["packages.pier.example"],
5500
+ rules: [pier],
5501
+ exits: ["local-proxy"],
5502
+ exec: { argv: [["pier", "publish"]] },
5503
+ createdAt: now2 - 3 * day2,
5504
+ usedAt: now2 - 2 * hour,
5505
+ expiresAt: now2 + 3 * day2
5506
+ },
5507
+ {
5508
+ name: "TIDE_MAIL",
5509
+ kind: "grant",
5510
+ placeholder: "fnox_proxy_tide0003",
5511
+ state: "active",
5512
+ source: "oauth:tide-mail",
5513
+ sourceDevice: null,
5514
+ provider: "Tide Mail",
5515
+ account: "cone@tide.example",
5516
+ domains: ["mail.tide.example"],
5517
+ rules: [
5518
+ {
5519
+ domain: "mail.tide.example",
5520
+ header: "Authorization",
5521
+ methods: ["GET", "POST"],
5522
+ paths: ["/v1/messages/*"]
5523
+ },
5524
+ {
5525
+ domain: "files.tide.example",
5526
+ header: "Authorization",
5527
+ methods: ["GET"],
5528
+ paths: ["/v1/attachments/*"]
5529
+ }
5530
+ ],
5531
+ exits: ["vault-direct"],
5532
+ exec: false,
5533
+ createdAt: now2 - 20 * day2,
5534
+ expiresAt: now2 + 50 * minute2
5535
+ },
5536
+ {
5537
+ name: "REEF_DEPLOY_KEY",
5538
+ kind: "secret",
5539
+ placeholder: "fnox_proxy_reef0004",
5540
+ state: "inert",
5541
+ source: "process",
5542
+ sourceDevice: null,
5543
+ domains: [],
5544
+ rules: [],
5545
+ exits: ["vault-direct", "local-proxy", "cli-v"],
5546
+ exec: true,
5547
+ createdAt: now2 - 2 * hour
5548
+ },
5549
+ {
5550
+ name: "BUOY_OLD_TOKEN",
5551
+ kind: "secret",
5552
+ placeholder: "fnox_proxy_buoy0005",
5553
+ state: "removed",
5554
+ source: "import:six",
5555
+ sourceDevice: null,
5556
+ domains: ["buoy.example"],
5557
+ rules: [{ domain: "buoy.example", header: "X-Buoy-Key", methods: ["GET"], paths: [] }],
5558
+ exits: ["vault-direct"],
5559
+ exec: false,
5560
+ createdAt: now2 - 40 * day2,
5561
+ removedAt: now2 - day2
5562
+ }
5563
+ ];
5564
+ }
5565
+ function vaultAudit(now2 = Date.now()) {
5566
+ const who = { uid: 1e3, tag: "cone" };
5567
+ return [
5568
+ {
5569
+ ...who,
5570
+ type: "inject",
5571
+ seq: 12,
5572
+ id: "audit-12",
5573
+ at: now2 - 4 * minute2,
5574
+ name: "HARBOR_API_KEY",
5575
+ domain: "api.harbor.example",
5576
+ method: "GET",
5577
+ path: "/v2/ships",
5578
+ rule: harbor,
5579
+ exit: "local-proxy"
5580
+ },
5581
+ {
5582
+ ...who,
5583
+ type: "materialize",
5584
+ seq: 11,
5585
+ id: "audit-11",
5586
+ at: now2 - 2 * hour,
5587
+ name: "PIER_PUBLISH_TOKEN",
5588
+ grant: { argv: [["pier", "publish"]] },
5589
+ path: "/usr/bin/pier",
5590
+ argv: "pier publish --tag next",
5591
+ argvSha256: "b1946ac92492d2347c6235b4d2611184",
5592
+ cwd: "/home/cone/harbor",
5593
+ pid: 4211,
5594
+ ppid: 4100,
5595
+ ticket: "ticket-11",
5596
+ consumed: true
5597
+ },
5598
+ {
5599
+ type: "materialize",
5600
+ seq: 10,
5601
+ id: "audit-10",
5602
+ at: now2 - 3 * hour,
5603
+ name: "PIER_PUBLISH_TOKEN",
5604
+ uid: 1001,
5605
+ tag: "docs-pass",
5606
+ grant: { argv: [["pier", "publish"]] },
5607
+ path: "/usr/bin/pier",
5608
+ argv: "pier publish --dry-run",
5609
+ argvSha256: "591785b794601e212b260e25925636fd",
5610
+ cwd: "/home/cone/harbor/docs",
5611
+ pid: 3980,
5612
+ ppid: 3901,
5613
+ ticket: "ticket-10",
5614
+ consumed: true
5615
+ },
5616
+ {
5617
+ ...who,
5618
+ type: "forward",
5619
+ seq: 9,
5620
+ id: "audit-9",
5621
+ at: now2 - 6 * hour,
5622
+ name: "HARBOR_API_KEY",
5623
+ domain: "api.harbor.example",
5624
+ method: "POST",
5625
+ path: "/v2/ships/quay/berths",
5626
+ rule: harbor,
5627
+ exit: "device:link-pier"
5628
+ },
5629
+ {
5630
+ type: "policy",
5631
+ seq: 8,
5632
+ id: "audit-8",
5633
+ at: now2 - day2,
5634
+ file: "/etc/slicc/secrets-policy.toml",
5635
+ sha256: "4e07408562bedb8b60ce05c1decfe3ad",
5636
+ accepted: true,
5637
+ widened: [{ kind: "exit", secret: "HARBOR_API_KEY", exit: "tailscale" }]
5638
+ },
5639
+ {
5640
+ ...who,
5641
+ type: "remove",
5642
+ seq: 7,
5643
+ id: "audit-7",
5644
+ at: now2 - day2 - hour,
5645
+ name: "BUOY_OLD_TOKEN"
5646
+ },
5647
+ {
5648
+ ...who,
5649
+ type: "seal",
5650
+ seq: 6,
5651
+ id: "audit-6",
5652
+ at: now2 - 3 * day2,
5653
+ name: "PIER_PUBLISH_TOKEN",
5654
+ source: "jerk:cone@link-pier",
5655
+ rotated: false
5656
+ }
5657
+ ];
5658
+ }
5659
+ function vaultOlder(now2 = Date.now()) {
5660
+ return [
5661
+ {
5662
+ type: "materialize",
5663
+ seq: 5,
5664
+ id: "audit-5",
5665
+ at: now2 - 4 * day2,
5666
+ name: "PIER_PUBLISH_TOKEN",
5667
+ uid: 1e3,
5668
+ tag: null,
5669
+ grant: { argv: [["pier", "publish"]] },
5670
+ path: "/usr/bin/pier",
5671
+ argv: "pier publish",
5672
+ argvSha256: "2c26b46b68ffc68ff99b453c1d304134",
5673
+ cwd: "/home/cone/harbor",
5674
+ pid: 2210,
5675
+ ppid: 2200,
5676
+ ticket: "ticket-5",
5677
+ consumed: true
5678
+ },
5679
+ {
5680
+ type: "policy",
5681
+ seq: 4,
5682
+ id: "audit-4",
5683
+ at: now2 - 5 * day2,
5684
+ file: "/etc/fnox/config.toml",
5685
+ sha256: "8f14e45fceea167a5a36dedd4bea2543",
5686
+ accepted: false,
5687
+ widened: [],
5688
+ warning: "The file did not parse, so the vault kept the last good rules."
5689
+ },
5690
+ {
5691
+ type: "restore",
5692
+ seq: 3,
5693
+ id: "audit-3",
5694
+ at: now2 - 6 * day2,
5695
+ name: "TIDE_MAIL",
5696
+ uid: 0,
5697
+ tag: null
5698
+ }
5699
+ ];
5700
+ }
5701
+ function vaultNotice(now2 = Date.now()) {
5702
+ return {
5703
+ id: "notice-widened",
5704
+ at: now2 - 20 * minute2,
5705
+ file: "/etc/slicc/secrets-policy.toml",
5706
+ sha256: "c9f0f895fb98ab9159f51fd0297e236d",
5707
+ acknowledged: false,
5708
+ widened: [
5709
+ { kind: "exit", secret: "HARBOR_API_KEY", exit: "device:link-quay" },
5710
+ {
5711
+ kind: "methods",
5712
+ secret: "PIER_PUBLISH_TOKEN",
5713
+ domain: "packages.pier.example",
5714
+ methods: ["PUT", "DELETE"]
5715
+ }
5716
+ ]
5717
+ };
5718
+ }
5719
+ function vaultFixtures(scenario, now2 = Date.now()) {
5720
+ const empty = scenario === "empty";
5721
+ const notices = scenario === "notice" ? [vaultNotice(now2)] : [];
5722
+ const status = {
5723
+ version: "0.1.0",
5724
+ protocol: 1,
5725
+ origin: "https://vault.sliccy.ai",
5726
+ locked: scenario === "locked",
5727
+ lock: "passkey",
5728
+ waiting: scenario === "locked" ? [
5729
+ {
5730
+ id: "request-reef",
5731
+ kind: "value",
5732
+ name: "REEF_DEPLOY_KEY",
5733
+ prompt: "Needed to deploy the reef preview. It is the deploy key from the reef dashboard, under Settings > Keys.",
5734
+ uid: 1001,
5735
+ tag: "docs-pass",
5736
+ createdAt: now2 - minute2,
5737
+ expiresAt: now2 + 4 * minute2
5738
+ }
5739
+ ] : [],
5740
+ notices: notices.length
5741
+ };
5742
+ const list = {
5743
+ secrets: empty ? [] : vaultSecrets(now2),
5744
+ notices,
5745
+ audit: empty ? [] : vaultAudit(now2),
5746
+ auditMore: !empty
5747
+ };
5748
+ return { status, list };
5749
+ }
5750
+ var labels = {
5751
+ unlock: "Unlock the vault",
5752
+ enter: "Enter the value",
5753
+ request: "Answer in the vault",
5754
+ import: "Import",
5755
+ export: "Export",
5756
+ signin: "Sign in",
5757
+ manage: "Open the vault"
5758
+ };
5759
+ var DummyVaultButton = class {
5760
+ element;
5761
+ config = null;
5762
+ #listeners = /* @__PURE__ */ new Set();
5763
+ #vault;
5764
+ #button;
5765
+ constructor(vault, time) {
5766
+ this.#vault = vault;
5767
+ this.element = document.createElement("span");
5768
+ this.element.dataset.vaultButton = "";
5769
+ this.#button = document.createElement("swc-button");
5770
+ this.element.append(this.#button);
5771
+ this.#button.addEventListener("click", () => void this.#click());
5772
+ void time.sleep(0).then(() => this.#emit({ event: "ready" }));
5773
+ }
5774
+ post(message) {
5775
+ if (message.op === "focus") {
5776
+ this.#button.focus();
5777
+ return;
5778
+ }
5779
+ this.config = message.button;
5780
+ const { intent, label, size = "m", variant = "secondary", treatment = "fill" } = message.button;
5781
+ this.#button.textContent = label ?? (intent === "auto" ? this.#vault.autoLabel() : labels[intent.kind]);
5782
+ this.#button.setAttribute("size", size);
5783
+ this.#button.setAttribute("variant", variant);
5784
+ this.#button.setAttribute("fill-style", treatment);
5785
+ this.#button.toggleAttribute("disabled", !!message.button.disabled);
5786
+ }
5787
+ listen(listener) {
5788
+ this.#listeners.add(listener);
5789
+ return () => this.#listeners.delete(listener);
5790
+ }
5791
+ #emit(event) {
5792
+ const message = { type: "slicc-vault", v: 1, ...event };
5793
+ for (const listener of [...this.#listeners]) listener(message);
5794
+ }
5795
+ async #click() {
5796
+ const intent = this.config?.intent ?? "auto";
5797
+ const resolved = intent === "auto" ? this.#vault.autoIntent() : intent;
5798
+ this.#emit({ event: "popup", intent: resolved, state: "opened" });
5799
+ const result = await this.#vault.answer(resolved);
5800
+ this.#emit({ event: "popup", intent: resolved, state: "done", ...result ? { result } : {} });
5801
+ }
5802
+ };
5803
+ var DummyVault = class extends Emitter {
5804
+ #status;
5805
+ #list;
5806
+ #time;
5807
+ buttons = [];
5808
+ acknowledged = [];
5809
+ constructor(scenario, time) {
5810
+ super();
5811
+ const { status, list } = vaultFixtures(scenario);
5812
+ this.#status = status;
5813
+ this.#list = list;
5814
+ this.#time = time;
5815
+ }
5816
+ status() {
5817
+ return this.#status;
5818
+ }
5819
+ list() {
5820
+ return this.#list;
5821
+ }
5822
+ async audit(before, limit = 50) {
5823
+ await this.#time.sleep(5);
5824
+ const all = [...this.#list.audit, ...vaultOlder()];
5825
+ const page2 = all.filter((entry) => before === void 0 || entry.seq < before).slice(0, limit);
5826
+ const more = page2.length > 0 && all.some((entry) => entry.seq < page2[page2.length - 1].seq);
5827
+ return { audit: page2, more, ...more ? { next: page2[page2.length - 1].seq } : {} };
5828
+ }
5829
+ async acknowledge(notice) {
5830
+ await this.#time.sleep(5);
5831
+ this.acknowledged.push(notice);
5832
+ const notices = this.#list.notices.filter((item) => item.id !== notice);
5833
+ this.#list = { ...this.#list, notices };
5834
+ this.#status = { ...this.#status, notices: notices.length };
5835
+ this.emit("list", this.#list);
5836
+ this.emit("status", this.#status);
5837
+ }
5838
+ button() {
5839
+ const button = new DummyVaultButton(this, this.#time);
5840
+ this.buttons.push(button);
5841
+ return button;
5842
+ }
5843
+ autoLabel() {
5844
+ return this.#status.locked ? "Vault locked" : "Vault unlocked";
5845
+ }
5846
+ autoIntent() {
5847
+ return this.#status.locked ? { kind: "unlock" } : { kind: "manage" };
5848
+ }
5849
+ async answer(intent) {
5850
+ await this.#time.sleep(10);
5851
+ if (intent.kind === "unlock") {
5852
+ this.#status = { ...this.#status, locked: false };
5853
+ this.emit("status", this.#status);
5854
+ return null;
5855
+ }
5856
+ if (intent.kind !== "request" && intent.kind !== "enter") return null;
5857
+ const request = this.#status.waiting.find((item) => item.id === intent.request);
5858
+ const name2 = intent.kind === "enter" ? intent.name : request?.name ?? "NEW_SECRET";
5859
+ this.#status = {
5860
+ ...this.#status,
5861
+ locked: false,
5862
+ waiting: this.#status.waiting.filter((item) => item !== request)
5863
+ };
5864
+ this.emit("status", this.#status);
5865
+ const record = this.#list.secrets.find((secret) => secret.name === name2);
5866
+ return { name: name2, placeholder: record?.placeholder ?? "fnox_proxy_new00001", state: "active" };
5867
+ }
5868
+ };
5869
+
5444
5870
  // src/dummy/index.ts
5445
5871
  function createDummyModel({
5446
5872
  delay = 30,
@@ -5457,6 +5883,8 @@ function createDummyModel({
5457
5883
  tabs: tabs2 = "off",
5458
5884
  approvals = "off",
5459
5885
  follow = "off",
5886
+ vault = "off",
5887
+ hold = "off",
5460
5888
  browser: scenario = "idle",
5461
5889
  sprinkles: sprinkles2 = "builtin",
5462
5890
  monitor = "dummy"
@@ -5482,6 +5910,7 @@ function createDummyModel({
5482
5910
  stop(agentId);
5483
5911
  browser.release(agentId);
5484
5912
  };
5913
+ if (hold !== "off") agent.setHold({ reason: hold, held: 2 });
5485
5914
  if (scenario === "driving") void browser.run(drive);
5486
5915
  const base = {
5487
5916
  agent,
@@ -5515,8 +5944,12 @@ function createDummyModel({
5515
5944
  ...notices === "off" ? {} : { notices: new DummyNotices(notices, time) },
5516
5945
  ...tabs2 === "off" ? {} : { tabs: new DummyTabs(tabs2, time) },
5517
5946
  ...approvals === "off" ? {} : { approvals: new DummyApprovals(approvals, time) },
5518
- ...follow === "off" ? {} : { follow: new DummyFollow(follow, time) }
5947
+ ...follow === "off" ? {} : { follow: new DummyFollow(follow, time) },
5948
+ ...vault === "off" ? {} : { vault: new DummyVault(vault, time) }
5519
5949
  };
5950
+ base.vault?.on("status", (status) => {
5951
+ if (!status.locked && agent.hold()?.reason === "locked") agent.setHold(null);
5952
+ });
5520
5953
  return {
5521
5954
  ...base,
5522
5955
  monitor: new DummyMonitor(base, monitor === "agent" ? agentSections : void 0)
@@ -5531,6 +5964,8 @@ export {
5531
5964
  DummyNotices,
5532
5965
  DummyTabs,
5533
5966
  DummyUpdates,
5967
+ DummyVault,
5968
+ DummyVaultButton,
5534
5969
  approvalFixtures,
5535
5970
  browserHistory,
5536
5971
  createDummyModel,
@@ -5543,6 +5978,11 @@ export {
5543
5978
  page,
5544
5979
  tabsFixtures,
5545
5980
  tailnetFixtures,
5546
- updateFixtures
5981
+ updateFixtures,
5982
+ vaultAudit,
5983
+ vaultFixtures,
5984
+ vaultNotice,
5985
+ vaultOlder,
5986
+ vaultSecrets
5547
5987
  };
5548
5988
  //# sourceMappingURL=slicc-dummy.js.map