@ai-ecoverse/slicc-spectrum 2.5.0 → 2.7.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.
- package/README.md +12 -5
- package/dist/{chunk-NMHCUT6N.js → chunk-3MP6GPRK.js} +2172 -1995
- package/dist/chunk-3MP6GPRK.js.map +7 -0
- package/dist/slicc-dummy.js +168 -14
- package/dist/slicc-dummy.js.map +4 -4
- package/dist/slicc-ui.js +106 -19
- package/dist/slicc-ui.js.map +3 -3
- package/dist/types/app/composer.d.ts +6 -1
- package/dist/types/dummy/capture.d.ts +11 -0
- package/dist/types/dummy/index.d.ts +4 -1
- package/dist/types/dummy/live.d.ts +1 -1
- package/dist/types/dummy.d.ts +2 -0
- package/dist/types/model/types.d.ts +22 -1
- package/package.json +4 -4
- package/dist/chunk-NMHCUT6N.js.map +0 -7
package/dist/slicc-dummy.js
CHANGED
|
@@ -794,6 +794,135 @@ var DummyBrowser = class extends Emitter {
|
|
|
794
794
|
}
|
|
795
795
|
};
|
|
796
796
|
|
|
797
|
+
// src/dummy/capture.ts
|
|
798
|
+
var PNG = Uint8Array.from(
|
|
799
|
+
atob(
|
|
800
|
+
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="
|
|
801
|
+
),
|
|
802
|
+
(char) => char.charCodeAt(0)
|
|
803
|
+
);
|
|
804
|
+
function denied(what) {
|
|
805
|
+
throw new DOMException(`${what} was denied`, "NotAllowedError");
|
|
806
|
+
}
|
|
807
|
+
function switchKey(kind) {
|
|
808
|
+
return kind === "audio" ? "microphone" : kind === "video" ? "camera" : "screen";
|
|
809
|
+
}
|
|
810
|
+
function allowed(switches, kind) {
|
|
811
|
+
const key = switchKey(kind);
|
|
812
|
+
const found = switches?.list().find((item) => item.key === key);
|
|
813
|
+
return !found || found.on;
|
|
814
|
+
}
|
|
815
|
+
var DummyCapture = class {
|
|
816
|
+
kinds;
|
|
817
|
+
still;
|
|
818
|
+
#live;
|
|
819
|
+
#switches;
|
|
820
|
+
#clock;
|
|
821
|
+
#deny;
|
|
822
|
+
#active = /* @__PURE__ */ new Map();
|
|
823
|
+
#prior = null;
|
|
824
|
+
constructor(scenario, clock2, live, switches) {
|
|
825
|
+
this.#clock = clock2;
|
|
826
|
+
this.#live = live;
|
|
827
|
+
this.#switches = switches;
|
|
828
|
+
this.#deny = scenario === "deny";
|
|
829
|
+
this.kinds = scenario === "audio" ? ["audio"] : ["audio", "video"];
|
|
830
|
+
this.still = () => this.#still();
|
|
831
|
+
if (live) {
|
|
832
|
+
this.#prior = live.act.bind(live);
|
|
833
|
+
live.act = (id) => {
|
|
834
|
+
const session2 = this.#active.get(id);
|
|
835
|
+
if (session2) session2.stop();
|
|
836
|
+
else this.#prior?.(id);
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
async record(kind) {
|
|
841
|
+
if (this.#deny || !allowed(this.#switches, kind))
|
|
842
|
+
denied(kind === "audio" ? "Microphone access" : "Camera access");
|
|
843
|
+
if (this.kinds && !this.kinds.includes(kind))
|
|
844
|
+
throw new DOMException(`Recording ${kind} isn\u2019t supported here`, "NotSupportedError");
|
|
845
|
+
const id = `capture-${kind}`;
|
|
846
|
+
if (this.#active.has(id)) throw new DOMException("Already recording", "InvalidStateError");
|
|
847
|
+
let settle;
|
|
848
|
+
let fail;
|
|
849
|
+
let done = false;
|
|
850
|
+
const finished = new Promise((resolve2, reject) => {
|
|
851
|
+
settle = resolve2;
|
|
852
|
+
fail = reject;
|
|
853
|
+
});
|
|
854
|
+
const mimeType = kind === "audio" ? "audio/webm" : "video/webm";
|
|
855
|
+
const name2 = "recording.webm";
|
|
856
|
+
const started = Date.now();
|
|
857
|
+
const item = {
|
|
858
|
+
id,
|
|
859
|
+
kind: kind === "audio" ? "microphone" : "camera",
|
|
860
|
+
label: kind === "audio" ? "Recording microphone" : "Recording camera",
|
|
861
|
+
what: kind === "audio" ? "Desk microphone" : "Face camera",
|
|
862
|
+
asker: "you",
|
|
863
|
+
since: started,
|
|
864
|
+
action: { label: "Stop" }
|
|
865
|
+
};
|
|
866
|
+
const end = (take, error) => {
|
|
867
|
+
if (done) return;
|
|
868
|
+
done = true;
|
|
869
|
+
this.#active.delete(id);
|
|
870
|
+
if (this.#live?.items().some((row) => row.id === id)) this.#prior?.(id);
|
|
871
|
+
if (error) fail(error);
|
|
872
|
+
else if (take) settle(take);
|
|
873
|
+
};
|
|
874
|
+
const session2 = {
|
|
875
|
+
stop: () => end({
|
|
876
|
+
blob: new Blob([PNG], { type: mimeType }),
|
|
877
|
+
mimeType,
|
|
878
|
+
name: name2,
|
|
879
|
+
durationMs: Math.max(0, Date.now() - started)
|
|
880
|
+
}),
|
|
881
|
+
cancel: () => end(null, new DOMException("Recording cancelled", "AbortError"))
|
|
882
|
+
};
|
|
883
|
+
this.#active.set(id, session2);
|
|
884
|
+
this.#live?.add(item);
|
|
885
|
+
return { ...session2, finished };
|
|
886
|
+
}
|
|
887
|
+
async #still() {
|
|
888
|
+
if (this.#deny || !allowed(this.#switches, "screen")) denied("Screen capture");
|
|
889
|
+
await this.#clock.sleep();
|
|
890
|
+
const id = "capture-still";
|
|
891
|
+
if (this.#active.has(id)) throw new DOMException("Already capturing", "InvalidStateError");
|
|
892
|
+
const item = {
|
|
893
|
+
id,
|
|
894
|
+
kind: "screen",
|
|
895
|
+
label: "Taking a photo",
|
|
896
|
+
what: "This screen",
|
|
897
|
+
asker: "you",
|
|
898
|
+
since: Date.now(),
|
|
899
|
+
action: { label: "Cancel" }
|
|
900
|
+
};
|
|
901
|
+
return await new Promise((resolve2, reject) => {
|
|
902
|
+
let done = false;
|
|
903
|
+
const finish = (still, error) => {
|
|
904
|
+
if (done) return;
|
|
905
|
+
done = true;
|
|
906
|
+
this.#active.delete(id);
|
|
907
|
+
if (this.#live?.items().some((row) => row.id === id)) this.#prior?.(id);
|
|
908
|
+
if (error) reject(error);
|
|
909
|
+
else if (still) resolve2(still);
|
|
910
|
+
};
|
|
911
|
+
const abort = () => finish(null, new DOMException("Screenshot cancelled", "AbortError"));
|
|
912
|
+
this.#active.set(id, { stop: abort, cancel: abort });
|
|
913
|
+
this.#live?.add(item);
|
|
914
|
+
void this.#clock.sleep().then(() => {
|
|
915
|
+
if (done) return;
|
|
916
|
+
finish({
|
|
917
|
+
blob: new Blob([PNG], { type: "image/png" }),
|
|
918
|
+
mimeType: "image/png",
|
|
919
|
+
name: "screenshot.png"
|
|
920
|
+
});
|
|
921
|
+
});
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
};
|
|
925
|
+
|
|
797
926
|
// src/dummy/changes.ts
|
|
798
927
|
var repos = ["/workspace/harbor", "/workspace/skills"];
|
|
799
928
|
var linkCommand = "curl -fsSL https://get.sliccy.ai/slicc | sh";
|
|
@@ -4175,6 +4304,7 @@ var DummyFiles = class extends Emitter {
|
|
|
4175
4304
|
|
|
4176
4305
|
// src/dummy/live.ts
|
|
4177
4306
|
function liveFixtures(scenario, now2 = Date.now()) {
|
|
4307
|
+
if (scenario === "empty") return [];
|
|
4178
4308
|
const screen = {
|
|
4179
4309
|
id: "live-screen",
|
|
4180
4310
|
kind: "screen",
|
|
@@ -4708,7 +4838,7 @@ var followers = [
|
|
|
4708
4838
|
exit: true,
|
|
4709
4839
|
state: "connected",
|
|
4710
4840
|
kind: "cli",
|
|
4711
|
-
access: { control: true, fixed: true }
|
|
4841
|
+
access: { control: true, browser: true, fixed: true }
|
|
4712
4842
|
},
|
|
4713
4843
|
{
|
|
4714
4844
|
id: "link-pier",
|
|
@@ -4720,9 +4850,21 @@ var followers = [
|
|
|
4720
4850
|
exit: true,
|
|
4721
4851
|
state: "connected",
|
|
4722
4852
|
kind: "cli",
|
|
4723
|
-
access: { control: true },
|
|
4853
|
+
access: { control: true, browser: true },
|
|
4724
4854
|
controlling: "prompt"
|
|
4725
4855
|
},
|
|
4856
|
+
{
|
|
4857
|
+
id: "link-dock",
|
|
4858
|
+
name: "slicc on dock-builder",
|
|
4859
|
+
host: "dock-builder.slicc.internal",
|
|
4860
|
+
address: "198.18.57.13",
|
|
4861
|
+
mode: "remote",
|
|
4862
|
+
offers: ["http"],
|
|
4863
|
+
exit: false,
|
|
4864
|
+
state: "connected",
|
|
4865
|
+
kind: "cli",
|
|
4866
|
+
access: { control: false, browser: false }
|
|
4867
|
+
},
|
|
4726
4868
|
{
|
|
4727
4869
|
id: "link-bay",
|
|
4728
4870
|
name: "SLICC on bay-laptop",
|
|
@@ -4789,9 +4931,9 @@ var outdatedDevice = {
|
|
|
4789
4931
|
note: "Update slicc to 1.47.0 or later to share this computer\u2019s browsers."
|
|
4790
4932
|
};
|
|
4791
4933
|
var others = linkedDevices.filter((device) => device.id !== pairedDevice.id);
|
|
4792
|
-
function grant(device, key,
|
|
4793
|
-
const access = { ...device.access, [key]:
|
|
4794
|
-
if (key === "view" && !
|
|
4934
|
+
function grant(device, key, allowed2) {
|
|
4935
|
+
const access = { ...device.access, [key]: allowed2 };
|
|
4936
|
+
if (key === "view" && !allowed2 && "control" in access) access.control = false;
|
|
4795
4937
|
const next = { ...device, access, asking: device.asking && !access.view };
|
|
4796
4938
|
if (!access.view && !access.control) next.controlling = void 0;
|
|
4797
4939
|
else if (!access.control && next.controlling === "prompt") next.controlling = "watch";
|
|
@@ -4898,8 +5040,8 @@ var DummyNetwork = class extends Emitter {
|
|
|
4898
5040
|
({ links: this.#links, exit: this.#exit } = linksFixtures(links));
|
|
4899
5041
|
this.setExit = (exit) => this.#setExit(exit);
|
|
4900
5042
|
this.unlink = (id) => this.#unlink(id);
|
|
4901
|
-
this.setRemoteControl = (id,
|
|
4902
|
-
this.setAccess = (id, key,
|
|
5043
|
+
this.setRemoteControl = (id, allowed2) => this.#control(id, allowed2);
|
|
5044
|
+
this.setAccess = (id, key, allowed2) => this.#access(id, key, allowed2);
|
|
4903
5045
|
this.rotateJoinUrl = () => this.#rotate();
|
|
4904
5046
|
this.retryLinks = () => this.#retry();
|
|
4905
5047
|
this.mountFolder = (source) => this.#mountFolder(source);
|
|
@@ -5010,22 +5152,22 @@ var DummyNetwork = class extends Emitter {
|
|
|
5010
5152
|
this.#exit = exit;
|
|
5011
5153
|
this.#emit();
|
|
5012
5154
|
}
|
|
5013
|
-
async #control(id,
|
|
5155
|
+
async #control(id, allowed2) {
|
|
5014
5156
|
await this.#clock.sleep(4);
|
|
5015
5157
|
const links = this.#links;
|
|
5016
5158
|
const devices = links.devices.map((device) => {
|
|
5017
5159
|
if (device.id !== id) return device;
|
|
5018
|
-
const next = { ...device, control: { ...device.control, allowed } };
|
|
5019
|
-
return
|
|
5160
|
+
const next = { ...device, control: { ...device.control, allowed: allowed2 } };
|
|
5161
|
+
return allowed2 ? next : { ...next, controlling: void 0 };
|
|
5020
5162
|
});
|
|
5021
5163
|
this.#links = { ...links, devices };
|
|
5022
5164
|
this.#emit();
|
|
5023
5165
|
}
|
|
5024
|
-
async #access(id, key,
|
|
5166
|
+
async #access(id, key, allowed2) {
|
|
5025
5167
|
await this.#clock.sleep(4);
|
|
5026
5168
|
const links = this.#links;
|
|
5027
5169
|
const devices = links.devices.map(
|
|
5028
|
-
(device) => device.id === id ? grant(device, key,
|
|
5170
|
+
(device) => device.id === id ? grant(device, key, allowed2) : device
|
|
5029
5171
|
);
|
|
5030
5172
|
this.#links = { ...links, devices };
|
|
5031
5173
|
this.#emit();
|
|
@@ -7537,6 +7679,16 @@ var movedDocs = "https://docs.eu.example/mcp";
|
|
|
7537
7679
|
function hinted(login) {
|
|
7538
7680
|
return login === "code" || login === "url" || login === "lookalike";
|
|
7539
7681
|
}
|
|
7682
|
+
function capturePorts(capture, live, switches, time) {
|
|
7683
|
+
const livePort = live !== "off" ? new DummyLive(live) : capture === "off" ? void 0 : new DummyLive("empty");
|
|
7684
|
+
const switchPort = switches === "off" ? void 0 : new DummySwitches();
|
|
7685
|
+
const capturePort = capture === "off" ? void 0 : new DummyCapture(capture, time, livePort, switchPort);
|
|
7686
|
+
return {
|
|
7687
|
+
...livePort ? { live: livePort } : {},
|
|
7688
|
+
...capturePort ? { capture: capturePort } : {},
|
|
7689
|
+
...switchPort ? { switches: switchPort } : {}
|
|
7690
|
+
};
|
|
7691
|
+
}
|
|
7540
7692
|
function signInChat(conversations2, login) {
|
|
7541
7693
|
if (!hinted(login)) return conversations2;
|
|
7542
7694
|
return {
|
|
@@ -7613,6 +7765,7 @@ function createDummyModel({
|
|
|
7613
7765
|
approvals = "off",
|
|
7614
7766
|
asks = "off",
|
|
7615
7767
|
live = "off",
|
|
7768
|
+
capture = "off",
|
|
7616
7769
|
switches = "off",
|
|
7617
7770
|
follow = "off",
|
|
7618
7771
|
vault = "off",
|
|
@@ -7635,6 +7788,7 @@ function createDummyModel({
|
|
|
7635
7788
|
older = "off"
|
|
7636
7789
|
} = {}) {
|
|
7637
7790
|
const time = clock(delay);
|
|
7791
|
+
const capturePortsOn = capturePorts(capture, live, switches, time);
|
|
7638
7792
|
const mount = mounts === "off" ? null : { scenario: mounts, point: mountPoint, files: mounted };
|
|
7639
7793
|
const pending2 = changes === "git" ? [...pending, skillEdit] : pending;
|
|
7640
7794
|
const files3 = new DummyFiles(files, directories, pending2, time, mount);
|
|
@@ -7704,8 +7858,7 @@ function createDummyModel({
|
|
|
7704
7858
|
...noticePort ? { notices: noticePort } : {},
|
|
7705
7859
|
...tabs2 === "off" ? {} : { tabs: new DummyTabs(tabs2, time) },
|
|
7706
7860
|
...approvals === "off" ? {} : { approvals: new DummyApprovals(approvals, time, vaultPort) },
|
|
7707
|
-
...
|
|
7708
|
-
...switches === "off" ? {} : { switches: new DummySwitches() },
|
|
7861
|
+
...capturePortsOn,
|
|
7709
7862
|
...follow === "off" ? {} : { follow: new DummyFollow(follow, time) },
|
|
7710
7863
|
...vaultPort ? { vault: vaultPort } : {},
|
|
7711
7864
|
...guestsPort(guests, time)
|
|
@@ -7721,6 +7874,7 @@ function createDummyModel({
|
|
|
7721
7874
|
export {
|
|
7722
7875
|
DummyApprovals,
|
|
7723
7876
|
DummyBrowser,
|
|
7877
|
+
DummyCapture,
|
|
7724
7878
|
DummyChanges,
|
|
7725
7879
|
DummyFollow,
|
|
7726
7880
|
DummyGuestAgent,
|