@ai-ecoverse/slicc-spectrum 2.6.0 → 2.8.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 +13 -6
- package/dist/{chunk-NMHCUT6N.js → chunk-3MP6GPRK.js} +2172 -1995
- package/dist/chunk-3MP6GPRK.js.map +7 -0
- package/dist/slicc-dummy.js +162 -12
- package/dist/slicc-dummy.js.map +4 -4
- package/dist/slicc-ui.js +184 -70
- package/dist/slicc-ui.js.map +4 -4
- package/dist/types/app/composer.d.ts +6 -1
- package/dist/types/app/tool-title.d.ts +3 -0
- package/dist/types/dummy/agent.d.ts +1 -0
- 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 +20 -0
- 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";
|
|
@@ -1944,6 +2073,7 @@ var labels = {
|
|
|
1944
2073
|
"Count the routes": "Walk through every kind of tool",
|
|
1945
2074
|
"Ask the API for Lisbon": "Compare the docs with the live API",
|
|
1946
2075
|
"Switch the page to Celsius": "Move the forecast docs to Celsius, then build and test the site",
|
|
2076
|
+
"git status --short": "Summarise the working tree",
|
|
1947
2077
|
[fixtures(`${repro}/round2/fixtures`)]: replayLabel
|
|
1948
2078
|
};
|
|
1949
2079
|
function label(title) {
|
|
@@ -2596,6 +2726,13 @@ var DummyAgent = class extends Emitter {
|
|
|
2596
2726
|
starting() {
|
|
2597
2727
|
return this.#starting;
|
|
2598
2728
|
}
|
|
2729
|
+
setTitle(agentId, title) {
|
|
2730
|
+
const agent = this.#agent(agentId);
|
|
2731
|
+
if (!agent) return;
|
|
2732
|
+
if (title === void 0) delete agent.title;
|
|
2733
|
+
else agent.title = title;
|
|
2734
|
+
this.#changed();
|
|
2735
|
+
}
|
|
2599
2736
|
setStarting(line) {
|
|
2600
2737
|
this.#arrival++;
|
|
2601
2738
|
this.#starting = line || null;
|
|
@@ -4175,6 +4312,7 @@ var DummyFiles = class extends Emitter {
|
|
|
4175
4312
|
|
|
4176
4313
|
// src/dummy/live.ts
|
|
4177
4314
|
function liveFixtures(scenario, now2 = Date.now()) {
|
|
4315
|
+
if (scenario === "empty") return [];
|
|
4178
4316
|
const screen = {
|
|
4179
4317
|
id: "live-screen",
|
|
4180
4318
|
kind: "screen",
|
|
@@ -4801,9 +4939,9 @@ var outdatedDevice = {
|
|
|
4801
4939
|
note: "Update slicc to 1.47.0 or later to share this computer\u2019s browsers."
|
|
4802
4940
|
};
|
|
4803
4941
|
var others = linkedDevices.filter((device) => device.id !== pairedDevice.id);
|
|
4804
|
-
function grant(device, key,
|
|
4805
|
-
const access = { ...device.access, [key]:
|
|
4806
|
-
if (key === "view" && !
|
|
4942
|
+
function grant(device, key, allowed2) {
|
|
4943
|
+
const access = { ...device.access, [key]: allowed2 };
|
|
4944
|
+
if (key === "view" && !allowed2 && "control" in access) access.control = false;
|
|
4807
4945
|
const next = { ...device, access, asking: device.asking && !access.view };
|
|
4808
4946
|
if (!access.view && !access.control) next.controlling = void 0;
|
|
4809
4947
|
else if (!access.control && next.controlling === "prompt") next.controlling = "watch";
|
|
@@ -4910,8 +5048,8 @@ var DummyNetwork = class extends Emitter {
|
|
|
4910
5048
|
({ links: this.#links, exit: this.#exit } = linksFixtures(links));
|
|
4911
5049
|
this.setExit = (exit) => this.#setExit(exit);
|
|
4912
5050
|
this.unlink = (id) => this.#unlink(id);
|
|
4913
|
-
this.setRemoteControl = (id,
|
|
4914
|
-
this.setAccess = (id, key,
|
|
5051
|
+
this.setRemoteControl = (id, allowed2) => this.#control(id, allowed2);
|
|
5052
|
+
this.setAccess = (id, key, allowed2) => this.#access(id, key, allowed2);
|
|
4915
5053
|
this.rotateJoinUrl = () => this.#rotate();
|
|
4916
5054
|
this.retryLinks = () => this.#retry();
|
|
4917
5055
|
this.mountFolder = (source) => this.#mountFolder(source);
|
|
@@ -5022,22 +5160,22 @@ var DummyNetwork = class extends Emitter {
|
|
|
5022
5160
|
this.#exit = exit;
|
|
5023
5161
|
this.#emit();
|
|
5024
5162
|
}
|
|
5025
|
-
async #control(id,
|
|
5163
|
+
async #control(id, allowed2) {
|
|
5026
5164
|
await this.#clock.sleep(4);
|
|
5027
5165
|
const links = this.#links;
|
|
5028
5166
|
const devices = links.devices.map((device) => {
|
|
5029
5167
|
if (device.id !== id) return device;
|
|
5030
|
-
const next = { ...device, control: { ...device.control, allowed } };
|
|
5031
|
-
return
|
|
5168
|
+
const next = { ...device, control: { ...device.control, allowed: allowed2 } };
|
|
5169
|
+
return allowed2 ? next : { ...next, controlling: void 0 };
|
|
5032
5170
|
});
|
|
5033
5171
|
this.#links = { ...links, devices };
|
|
5034
5172
|
this.#emit();
|
|
5035
5173
|
}
|
|
5036
|
-
async #access(id, key,
|
|
5174
|
+
async #access(id, key, allowed2) {
|
|
5037
5175
|
await this.#clock.sleep(4);
|
|
5038
5176
|
const links = this.#links;
|
|
5039
5177
|
const devices = links.devices.map(
|
|
5040
|
-
(device) => device.id === id ? grant(device, key,
|
|
5178
|
+
(device) => device.id === id ? grant(device, key, allowed2) : device
|
|
5041
5179
|
);
|
|
5042
5180
|
this.#links = { ...links, devices };
|
|
5043
5181
|
this.#emit();
|
|
@@ -7549,6 +7687,16 @@ var movedDocs = "https://docs.eu.example/mcp";
|
|
|
7549
7687
|
function hinted(login) {
|
|
7550
7688
|
return login === "code" || login === "url" || login === "lookalike";
|
|
7551
7689
|
}
|
|
7690
|
+
function capturePorts(capture, live, switches, time) {
|
|
7691
|
+
const livePort = live !== "off" ? new DummyLive(live) : capture === "off" ? void 0 : new DummyLive("empty");
|
|
7692
|
+
const switchPort = switches === "off" ? void 0 : new DummySwitches();
|
|
7693
|
+
const capturePort = capture === "off" ? void 0 : new DummyCapture(capture, time, livePort, switchPort);
|
|
7694
|
+
return {
|
|
7695
|
+
...livePort ? { live: livePort } : {},
|
|
7696
|
+
...capturePort ? { capture: capturePort } : {},
|
|
7697
|
+
...switchPort ? { switches: switchPort } : {}
|
|
7698
|
+
};
|
|
7699
|
+
}
|
|
7552
7700
|
function signInChat(conversations2, login) {
|
|
7553
7701
|
if (!hinted(login)) return conversations2;
|
|
7554
7702
|
return {
|
|
@@ -7625,6 +7773,7 @@ function createDummyModel({
|
|
|
7625
7773
|
approvals = "off",
|
|
7626
7774
|
asks = "off",
|
|
7627
7775
|
live = "off",
|
|
7776
|
+
capture = "off",
|
|
7628
7777
|
switches = "off",
|
|
7629
7778
|
follow = "off",
|
|
7630
7779
|
vault = "off",
|
|
@@ -7647,6 +7796,7 @@ function createDummyModel({
|
|
|
7647
7796
|
older = "off"
|
|
7648
7797
|
} = {}) {
|
|
7649
7798
|
const time = clock(delay);
|
|
7799
|
+
const capturePortsOn = capturePorts(capture, live, switches, time);
|
|
7650
7800
|
const mount = mounts === "off" ? null : { scenario: mounts, point: mountPoint, files: mounted };
|
|
7651
7801
|
const pending2 = changes === "git" ? [...pending, skillEdit] : pending;
|
|
7652
7802
|
const files3 = new DummyFiles(files, directories, pending2, time, mount);
|
|
@@ -7716,8 +7866,7 @@ function createDummyModel({
|
|
|
7716
7866
|
...noticePort ? { notices: noticePort } : {},
|
|
7717
7867
|
...tabs2 === "off" ? {} : { tabs: new DummyTabs(tabs2, time) },
|
|
7718
7868
|
...approvals === "off" ? {} : { approvals: new DummyApprovals(approvals, time, vaultPort) },
|
|
7719
|
-
...
|
|
7720
|
-
...switches === "off" ? {} : { switches: new DummySwitches() },
|
|
7869
|
+
...capturePortsOn,
|
|
7721
7870
|
...follow === "off" ? {} : { follow: new DummyFollow(follow, time) },
|
|
7722
7871
|
...vaultPort ? { vault: vaultPort } : {},
|
|
7723
7872
|
...guestsPort(guests, time)
|
|
@@ -7733,6 +7882,7 @@ function createDummyModel({
|
|
|
7733
7882
|
export {
|
|
7734
7883
|
DummyApprovals,
|
|
7735
7884
|
DummyBrowser,
|
|
7885
|
+
DummyCapture,
|
|
7736
7886
|
DummyChanges,
|
|
7737
7887
|
DummyFollow,
|
|
7738
7888
|
DummyGuestAgent,
|