@struktoai/mirage-node 0.0.1-alpha.1
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 +230 -0
- package/dist/box-4P7DCJH7.js +8 -0
- package/dist/box-4P7DCJH7.js.map +1 -0
- package/dist/chunk-35PVZRWU.js +24 -0
- package/dist/chunk-35PVZRWU.js.map +1 -0
- package/dist/chunk-3PBSL7BS.js +93 -0
- package/dist/chunk-3PBSL7BS.js.map +1 -0
- package/dist/chunk-3Y625AUP.js +24 -0
- package/dist/chunk-3Y625AUP.js.map +1 -0
- package/dist/chunk-5E6BULAK.js +92 -0
- package/dist/chunk-5E6BULAK.js.map +1 -0
- package/dist/chunk-5ITBZN55.js +24 -0
- package/dist/chunk-5ITBZN55.js.map +1 -0
- package/dist/chunk-6M2NL363.js +94 -0
- package/dist/chunk-6M2NL363.js.map +1 -0
- package/dist/chunk-6M3QVVOH.js +32 -0
- package/dist/chunk-6M3QVVOH.js.map +1 -0
- package/dist/chunk-6VKNSO6U.js +56 -0
- package/dist/chunk-6VKNSO6U.js.map +1 -0
- package/dist/chunk-6Y6GWMFF.js +24 -0
- package/dist/chunk-6Y6GWMFF.js.map +1 -0
- package/dist/chunk-7QXJ4KWQ.js +132 -0
- package/dist/chunk-7QXJ4KWQ.js.map +1 -0
- package/dist/chunk-ALAMUIGJ.js +57 -0
- package/dist/chunk-ALAMUIGJ.js.map +1 -0
- package/dist/chunk-DCJQ2PIX.js +100 -0
- package/dist/chunk-DCJQ2PIX.js.map +1 -0
- package/dist/chunk-EKPH4MMD.js +27 -0
- package/dist/chunk-EKPH4MMD.js.map +1 -0
- package/dist/chunk-FZ2GJ4BJ.js +29 -0
- package/dist/chunk-FZ2GJ4BJ.js.map +1 -0
- package/dist/chunk-G7O6DAWU.js +178 -0
- package/dist/chunk-G7O6DAWU.js.map +1 -0
- package/dist/chunk-GCB4JUF7.js +94 -0
- package/dist/chunk-GCB4JUF7.js.map +1 -0
- package/dist/chunk-GKQNMLQU.js +7757 -0
- package/dist/chunk-GKQNMLQU.js.map +1 -0
- package/dist/chunk-GO67AOYK.js +24 -0
- package/dist/chunk-GO67AOYK.js.map +1 -0
- package/dist/chunk-GPF66TH2.js +24 -0
- package/dist/chunk-GPF66TH2.js.map +1 -0
- package/dist/chunk-H3JR7MN3.js +45 -0
- package/dist/chunk-H3JR7MN3.js.map +1 -0
- package/dist/chunk-H74QYTN7.js +50 -0
- package/dist/chunk-H74QYTN7.js.map +1 -0
- package/dist/chunk-HEQL3LPK.js +66 -0
- package/dist/chunk-HEQL3LPK.js.map +1 -0
- package/dist/chunk-HXWGG4K7.js +66 -0
- package/dist/chunk-HXWGG4K7.js.map +1 -0
- package/dist/chunk-I4RRGZGB.js +24 -0
- package/dist/chunk-I4RRGZGB.js.map +1 -0
- package/dist/chunk-ICSS5ETT.js +67 -0
- package/dist/chunk-ICSS5ETT.js.map +1 -0
- package/dist/chunk-KINMBZHC.js +18 -0
- package/dist/chunk-KINMBZHC.js.map +1 -0
- package/dist/chunk-LBBM3LKK.js +99 -0
- package/dist/chunk-LBBM3LKK.js.map +1 -0
- package/dist/chunk-LPMPTQYP.js +36 -0
- package/dist/chunk-LPMPTQYP.js.map +1 -0
- package/dist/chunk-M42JTWPR.js +2794 -0
- package/dist/chunk-M42JTWPR.js.map +1 -0
- package/dist/chunk-MVE5VVMQ.js +91 -0
- package/dist/chunk-MVE5VVMQ.js.map +1 -0
- package/dist/chunk-MY3NUJJD.js +67 -0
- package/dist/chunk-MY3NUJJD.js.map +1 -0
- package/dist/chunk-NOZZFJEB.js +93 -0
- package/dist/chunk-NOZZFJEB.js.map +1 -0
- package/dist/chunk-OYJXYJTE.js +2358 -0
- package/dist/chunk-OYJXYJTE.js.map +1 -0
- package/dist/chunk-PEZYBKZH.js +124 -0
- package/dist/chunk-PEZYBKZH.js.map +1 -0
- package/dist/chunk-QWWOBAYU.js +26 -0
- package/dist/chunk-QWWOBAYU.js.map +1 -0
- package/dist/chunk-RQYYYBQG.js +24 -0
- package/dist/chunk-RQYYYBQG.js.map +1 -0
- package/dist/chunk-T2WWAEKH.js +7591 -0
- package/dist/chunk-T2WWAEKH.js.map +1 -0
- package/dist/chunk-U6QSXTUS.js +7 -0
- package/dist/chunk-U6QSXTUS.js.map +1 -0
- package/dist/chunk-UWMOTOXA.js +93 -0
- package/dist/chunk-UWMOTOXA.js.map +1 -0
- package/dist/chunk-UZZD4MRJ.js +95 -0
- package/dist/chunk-UZZD4MRJ.js.map +1 -0
- package/dist/chunk-V5OLWE7F.js +88 -0
- package/dist/chunk-V5OLWE7F.js.map +1 -0
- package/dist/chunk-VCLMTMSO.js +23 -0
- package/dist/chunk-VCLMTMSO.js.map +1 -0
- package/dist/chunk-WSDQ2MRG.js +102 -0
- package/dist/chunk-WSDQ2MRG.js.map +1 -0
- package/dist/chunk-XDEEOTVK.js +93 -0
- package/dist/chunk-XDEEOTVK.js.map +1 -0
- package/dist/chunk-XQUQSNCA.js +117 -0
- package/dist/chunk-XQUQSNCA.js.map +1 -0
- package/dist/chunk-XVYZO2FG.js +14 -0
- package/dist/chunk-XVYZO2FG.js.map +1 -0
- package/dist/chunk-ZC4KNEOQ.js +50 -0
- package/dist/chunk-ZC4KNEOQ.js.map +1 -0
- package/dist/config-5ZPGISS6.js +13 -0
- package/dist/config-5ZPGISS6.js.map +1 -0
- package/dist/config-6HWSKHEU.js +9 -0
- package/dist/config-6HWSKHEU.js.map +1 -0
- package/dist/config-6TNFPYZF.js +9 -0
- package/dist/config-6TNFPYZF.js.map +1 -0
- package/dist/config-BHLXQ3OL.js +9 -0
- package/dist/config-BHLXQ3OL.js.map +1 -0
- package/dist/config-E7UOEWEP.js +9 -0
- package/dist/config-E7UOEWEP.js.map +1 -0
- package/dist/config-FNR6LJ5H.js +11 -0
- package/dist/config-FNR6LJ5H.js.map +1 -0
- package/dist/config-HIZHA5VD.js +13 -0
- package/dist/config-HIZHA5VD.js.map +1 -0
- package/dist/config-HNSDNQZH.js +9 -0
- package/dist/config-HNSDNQZH.js.map +1 -0
- package/dist/config-IXLFUSMQ.js +9 -0
- package/dist/config-IXLFUSMQ.js.map +1 -0
- package/dist/config-J3TM7NIS.js +9 -0
- package/dist/config-J3TM7NIS.js.map +1 -0
- package/dist/config-JXLZ4XEW.js +9 -0
- package/dist/config-JXLZ4XEW.js.map +1 -0
- package/dist/config-KQCEMLNZ.js +9 -0
- package/dist/config-KQCEMLNZ.js.map +1 -0
- package/dist/config-MOLWOSRG.js +9 -0
- package/dist/config-MOLWOSRG.js.map +1 -0
- package/dist/config-R3XJ5OW4.js +9 -0
- package/dist/config-R3XJ5OW4.js.map +1 -0
- package/dist/config-S47UDVRZ.js +13 -0
- package/dist/config-S47UDVRZ.js.map +1 -0
- package/dist/config-UKZ72IDO.js +13 -0
- package/dist/config-UKZ72IDO.js.map +1 -0
- package/dist/config-V7XI5UTG.js +9 -0
- package/dist/config-V7XI5UTG.js.map +1 -0
- package/dist/config-YLIX3ZBT.js +9 -0
- package/dist/config-YLIX3ZBT.js.map +1 -0
- package/dist/config-Z5JGDOKE.js +9 -0
- package/dist/config-Z5JGDOKE.js.map +1 -0
- package/dist/config-ZCZZAH5W.js +9 -0
- package/dist/config-ZCZZAH5W.js.map +1 -0
- package/dist/config-ZZGIWDUC.js +9 -0
- package/dist/config-ZZGIWDUC.js.map +1 -0
- package/dist/discord-2PWP2MGX.js +8 -0
- package/dist/discord-2PWP2MGX.js.map +1 -0
- package/dist/disk-C7TJNU2B.js +8 -0
- package/dist/disk-C7TJNU2B.js.map +1 -0
- package/dist/dropbox-L5DPYGKR.js +8 -0
- package/dist/dropbox-L5DPYGKR.js.map +1 -0
- package/dist/email-HASRFBKC.js +8 -0
- package/dist/email-HASRFBKC.js.map +1 -0
- package/dist/gcs-P5QMKTPR.js +10 -0
- package/dist/gcs-P5QMKTPR.js.map +1 -0
- package/dist/gdocs-IF2I35HZ.js +8 -0
- package/dist/gdocs-IF2I35HZ.js.map +1 -0
- package/dist/gdrive-TAETVCKP.js +8 -0
- package/dist/gdrive-TAETVCKP.js.map +1 -0
- package/dist/github-5E6GSCNZ.js +8 -0
- package/dist/github-5E6GSCNZ.js.map +1 -0
- package/dist/github_ci-2DSZI3Y7.js +8 -0
- package/dist/github_ci-2DSZI3Y7.js.map +1 -0
- package/dist/gmail-F5VYGKOT.js +8 -0
- package/dist/gmail-F5VYGKOT.js.map +1 -0
- package/dist/gsheets-BAO54CQ7.js +8 -0
- package/dist/gsheets-BAO54CQ7.js.map +1 -0
- package/dist/gslides-A62CEEMR.js +8 -0
- package/dist/gslides-A62CEEMR.js.map +1 -0
- package/dist/index.d.ts +1671 -0
- package/dist/index.js +3564 -0
- package/dist/index.js.map +1 -0
- package/dist/langfuse-YKBYRQLU.js +8 -0
- package/dist/langfuse-YKBYRQLU.js.map +1 -0
- package/dist/linear-WJDQ6JDE.js +8 -0
- package/dist/linear-WJDQ6JDE.js.map +1 -0
- package/dist/mongodb-MK4DVSIK.js +7 -0
- package/dist/mongodb-MK4DVSIK.js.map +1 -0
- package/dist/oci-KZ7XFZ2X.js +10 -0
- package/dist/oci-KZ7XFZ2X.js.map +1 -0
- package/dist/postgres-M2N2APFZ.js +7 -0
- package/dist/postgres-M2N2APFZ.js.map +1 -0
- package/dist/r2-X4DDNSAZ.js +10 -0
- package/dist/r2-X4DDNSAZ.js.map +1 -0
- package/dist/redis-NVCXUUIO.js +7 -0
- package/dist/redis-NVCXUUIO.js.map +1 -0
- package/dist/s3-HVAL7ZX3.js +8 -0
- package/dist/s3-HVAL7ZX3.js.map +1 -0
- package/dist/slack-GUQMDGLP.js +8 -0
- package/dist/slack-GUQMDGLP.js.map +1 -0
- package/dist/ssh-LY6WYVVD.js +9 -0
- package/dist/ssh-LY6WYVVD.js.map +1 -0
- package/dist/supabase-H3ZP4Y3W.js +10 -0
- package/dist/supabase-H3ZP4Y3W.js.map +1 -0
- package/dist/trello-WR6TEDYD.js +8 -0
- package/dist/trello-WR6TEDYD.js.map +1 -0
- package/package.json +118 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,3564 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DropboxResource
|
|
3
|
+
} from "./chunk-5E6BULAK.js";
|
|
4
|
+
import {
|
|
5
|
+
BoxResource
|
|
6
|
+
} from "./chunk-6M2NL363.js";
|
|
7
|
+
import {
|
|
8
|
+
normalizeBoxConfig,
|
|
9
|
+
redactBoxConfig
|
|
10
|
+
} from "./chunk-EKPH4MMD.js";
|
|
11
|
+
import {
|
|
12
|
+
GmailResource
|
|
13
|
+
} from "./chunk-UWMOTOXA.js";
|
|
14
|
+
import {
|
|
15
|
+
normalizeGmailConfig,
|
|
16
|
+
redactGmailConfig
|
|
17
|
+
} from "./chunk-GO67AOYK.js";
|
|
18
|
+
import {
|
|
19
|
+
EMAIL_COMMANDS,
|
|
20
|
+
EMAIL_OPS,
|
|
21
|
+
EMAIL_PROMPT,
|
|
22
|
+
EMAIL_WRITE_PROMPT,
|
|
23
|
+
EmailAccessor,
|
|
24
|
+
EmailResource
|
|
25
|
+
} from "./chunk-OYJXYJTE.js";
|
|
26
|
+
import {
|
|
27
|
+
buildEmailConfig,
|
|
28
|
+
normalizeEmailConfig,
|
|
29
|
+
redactEmailConfig
|
|
30
|
+
} from "./chunk-H74QYTN7.js";
|
|
31
|
+
import {
|
|
32
|
+
GDocsResource
|
|
33
|
+
} from "./chunk-NOZZFJEB.js";
|
|
34
|
+
import {
|
|
35
|
+
GSheetsResource
|
|
36
|
+
} from "./chunk-3PBSL7BS.js";
|
|
37
|
+
import {
|
|
38
|
+
normalizeGSheetsConfig,
|
|
39
|
+
redactGSheetsConfig
|
|
40
|
+
} from "./chunk-I4RRGZGB.js";
|
|
41
|
+
import {
|
|
42
|
+
GSlidesResource
|
|
43
|
+
} from "./chunk-XDEEOTVK.js";
|
|
44
|
+
import {
|
|
45
|
+
normalizeGSlidesConfig,
|
|
46
|
+
redactGSlidesConfig
|
|
47
|
+
} from "./chunk-5ITBZN55.js";
|
|
48
|
+
import {
|
|
49
|
+
GDriveResource
|
|
50
|
+
} from "./chunk-MVE5VVMQ.js";
|
|
51
|
+
import {
|
|
52
|
+
normalizeGDriveConfig,
|
|
53
|
+
redactGDriveConfig
|
|
54
|
+
} from "./chunk-35PVZRWU.js";
|
|
55
|
+
import {
|
|
56
|
+
normalizeDropboxConfig,
|
|
57
|
+
redactDropboxConfig
|
|
58
|
+
} from "./chunk-RQYYYBQG.js";
|
|
59
|
+
import {
|
|
60
|
+
LinearResource
|
|
61
|
+
} from "./chunk-UZZD4MRJ.js";
|
|
62
|
+
import {
|
|
63
|
+
LangfuseResource
|
|
64
|
+
} from "./chunk-DCJQ2PIX.js";
|
|
65
|
+
import {
|
|
66
|
+
normalizeLangfuseConfig,
|
|
67
|
+
redactLangfuseConfig
|
|
68
|
+
} from "./chunk-6M3QVVOH.js";
|
|
69
|
+
import {
|
|
70
|
+
GitHubResource
|
|
71
|
+
} from "./chunk-PEZYBKZH.js";
|
|
72
|
+
import {
|
|
73
|
+
normalizeGitHubConfig,
|
|
74
|
+
redactGitHubConfig
|
|
75
|
+
} from "./chunk-VCLMTMSO.js";
|
|
76
|
+
import {
|
|
77
|
+
GitHubCIResource
|
|
78
|
+
} from "./chunk-GCB4JUF7.js";
|
|
79
|
+
import {
|
|
80
|
+
normalizeGitHubCIConfig,
|
|
81
|
+
redactGitHubCIConfig
|
|
82
|
+
} from "./chunk-GPF66TH2.js";
|
|
83
|
+
import {
|
|
84
|
+
normalizeGDocsConfig,
|
|
85
|
+
redactGDocsConfig
|
|
86
|
+
} from "./chunk-3Y625AUP.js";
|
|
87
|
+
import {
|
|
88
|
+
SlackResource
|
|
89
|
+
} from "./chunk-V5OLWE7F.js";
|
|
90
|
+
import {
|
|
91
|
+
SSHAccessor,
|
|
92
|
+
SSHResource,
|
|
93
|
+
SSH_COMMANDS,
|
|
94
|
+
SSH_OPS,
|
|
95
|
+
SSH_PROMPT
|
|
96
|
+
} from "./chunk-M42JTWPR.js";
|
|
97
|
+
import {
|
|
98
|
+
normalizeSshConfig,
|
|
99
|
+
redactSshConfig
|
|
100
|
+
} from "./chunk-FZ2GJ4BJ.js";
|
|
101
|
+
import {
|
|
102
|
+
DiscordResource
|
|
103
|
+
} from "./chunk-WSDQ2MRG.js";
|
|
104
|
+
import {
|
|
105
|
+
normalizeDiscordConfig,
|
|
106
|
+
redactDiscordConfig
|
|
107
|
+
} from "./chunk-XVYZO2FG.js";
|
|
108
|
+
import {
|
|
109
|
+
TrelloResource
|
|
110
|
+
} from "./chunk-LBBM3LKK.js";
|
|
111
|
+
import {
|
|
112
|
+
normalizeTrelloConfig,
|
|
113
|
+
redactTrelloConfig
|
|
114
|
+
} from "./chunk-QWWOBAYU.js";
|
|
115
|
+
import {
|
|
116
|
+
normalizeLinearConfig,
|
|
117
|
+
redactLinearConfig
|
|
118
|
+
} from "./chunk-6Y6GWMFF.js";
|
|
119
|
+
import {
|
|
120
|
+
OCIResource,
|
|
121
|
+
OCI_PROMPT
|
|
122
|
+
} from "./chunk-HXWGG4K7.js";
|
|
123
|
+
import {
|
|
124
|
+
R2Resource,
|
|
125
|
+
R2_PROMPT
|
|
126
|
+
} from "./chunk-ICSS5ETT.js";
|
|
127
|
+
import {
|
|
128
|
+
redactR2Config
|
|
129
|
+
} from "./chunk-6VKNSO6U.js";
|
|
130
|
+
import {
|
|
131
|
+
SUPABASE_PROMPT,
|
|
132
|
+
SupabaseResource
|
|
133
|
+
} from "./chunk-HEQL3LPK.js";
|
|
134
|
+
import {
|
|
135
|
+
redactSupabaseConfig,
|
|
136
|
+
resolvedSupabaseEndpoint
|
|
137
|
+
} from "./chunk-ALAMUIGJ.js";
|
|
138
|
+
import {
|
|
139
|
+
PostgresResource,
|
|
140
|
+
PostgresStore
|
|
141
|
+
} from "./chunk-XQUQSNCA.js";
|
|
142
|
+
import {
|
|
143
|
+
MongoDBResource,
|
|
144
|
+
MongoDBStore
|
|
145
|
+
} from "./chunk-7QXJ4KWQ.js";
|
|
146
|
+
import {
|
|
147
|
+
normalizeSlackConfig,
|
|
148
|
+
redactSlackConfig
|
|
149
|
+
} from "./chunk-KINMBZHC.js";
|
|
150
|
+
import {
|
|
151
|
+
DISK_COMMANDS,
|
|
152
|
+
DISK_OPS,
|
|
153
|
+
DISK_PROMPT,
|
|
154
|
+
DiskResource,
|
|
155
|
+
stat,
|
|
156
|
+
stream
|
|
157
|
+
} from "./chunk-GKQNMLQU.js";
|
|
158
|
+
import "./chunk-U6QSXTUS.js";
|
|
159
|
+
import {
|
|
160
|
+
REDIS_COMMANDS,
|
|
161
|
+
REDIS_OPS,
|
|
162
|
+
REDIS_PROMPT,
|
|
163
|
+
RedisAccessor,
|
|
164
|
+
RedisResource,
|
|
165
|
+
RedisStore,
|
|
166
|
+
loadOptionalPeer,
|
|
167
|
+
stat as stat2
|
|
168
|
+
} from "./chunk-T2WWAEKH.js";
|
|
169
|
+
import {
|
|
170
|
+
GCSResource,
|
|
171
|
+
GCS_PROMPT
|
|
172
|
+
} from "./chunk-MY3NUJJD.js";
|
|
173
|
+
import {
|
|
174
|
+
S3Resource
|
|
175
|
+
} from "./chunk-G7O6DAWU.js";
|
|
176
|
+
import {
|
|
177
|
+
redactConfig
|
|
178
|
+
} from "./chunk-LPMPTQYP.js";
|
|
179
|
+
import {
|
|
180
|
+
GCS_ENDPOINT,
|
|
181
|
+
redactGcsConfig
|
|
182
|
+
} from "./chunk-H3JR7MN3.js";
|
|
183
|
+
import {
|
|
184
|
+
redactOciConfig
|
|
185
|
+
} from "./chunk-ZC4KNEOQ.js";
|
|
186
|
+
|
|
187
|
+
// src/index.ts
|
|
188
|
+
export * from "@struktoai/mirage-core";
|
|
189
|
+
|
|
190
|
+
// src/workspace.ts
|
|
191
|
+
import { readFileSync } from "fs";
|
|
192
|
+
import { createRequire } from "module";
|
|
193
|
+
import {
|
|
194
|
+
createShellParser,
|
|
195
|
+
ExecuteResult as ExecuteResult2,
|
|
196
|
+
Workspace as CoreWorkspace
|
|
197
|
+
} from "@struktoai/mirage-core";
|
|
198
|
+
|
|
199
|
+
// src/native.ts
|
|
200
|
+
import { spawn } from "child_process";
|
|
201
|
+
import { ExecuteResult } from "@struktoai/mirage-core";
|
|
202
|
+
function concatChunks(chunks) {
|
|
203
|
+
let total = 0;
|
|
204
|
+
for (const c of chunks) total += c.byteLength;
|
|
205
|
+
const out = new Uint8Array(total);
|
|
206
|
+
let offset = 0;
|
|
207
|
+
for (const c of chunks) {
|
|
208
|
+
out.set(c, offset);
|
|
209
|
+
offset += c.byteLength;
|
|
210
|
+
}
|
|
211
|
+
return out;
|
|
212
|
+
}
|
|
213
|
+
function nativeExec(command31, options) {
|
|
214
|
+
return new Promise((resolve, reject) => {
|
|
215
|
+
const env = options.env ?? process.env;
|
|
216
|
+
const spawnOpts = {
|
|
217
|
+
cwd: options.cwd,
|
|
218
|
+
env
|
|
219
|
+
};
|
|
220
|
+
if (options.signal !== void 0) spawnOpts.signal = options.signal;
|
|
221
|
+
const proc = spawn("sh", ["-c", command31], spawnOpts);
|
|
222
|
+
const stdoutChunks = [];
|
|
223
|
+
const stderrChunks = [];
|
|
224
|
+
let killed = false;
|
|
225
|
+
const timeoutMs = options.timeoutMs ?? null;
|
|
226
|
+
const timer = timeoutMs !== null ? setTimeout(() => {
|
|
227
|
+
killed = true;
|
|
228
|
+
proc.kill("SIGKILL");
|
|
229
|
+
proc.stdout.destroy();
|
|
230
|
+
proc.stderr.destroy();
|
|
231
|
+
}, timeoutMs) : null;
|
|
232
|
+
proc.stdout.on("data", (chunk) => {
|
|
233
|
+
stdoutChunks.push(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength));
|
|
234
|
+
});
|
|
235
|
+
proc.stderr.on("data", (chunk) => {
|
|
236
|
+
stderrChunks.push(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength));
|
|
237
|
+
});
|
|
238
|
+
proc.on("error", (err) => {
|
|
239
|
+
if (timer !== null) clearTimeout(timer);
|
|
240
|
+
if (err.name === "AbortError" || options.signal?.aborted === true) {
|
|
241
|
+
reject(new DOMException("execute aborted", "AbortError"));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
reject(err);
|
|
245
|
+
});
|
|
246
|
+
proc.on("close", (code) => {
|
|
247
|
+
if (timer !== null) clearTimeout(timer);
|
|
248
|
+
if (options.signal?.aborted === true) {
|
|
249
|
+
reject(new DOMException("execute aborted", "AbortError"));
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
if (killed) {
|
|
253
|
+
resolve(new ExecuteResult(new Uint8Array(), new TextEncoder().encode("timeout\n"), 124));
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
resolve(new ExecuteResult(concatChunks(stdoutChunks), concatChunks(stderrChunks), code ?? 0));
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
function nativeExecStream(command31, options) {
|
|
261
|
+
const env = options.env ?? process.env;
|
|
262
|
+
const spawnOpts = {
|
|
263
|
+
cwd: options.cwd,
|
|
264
|
+
env
|
|
265
|
+
};
|
|
266
|
+
const proc = spawn("sh", ["-c", command31], spawnOpts);
|
|
267
|
+
return {
|
|
268
|
+
raw: proc,
|
|
269
|
+
stdoutStream() {
|
|
270
|
+
return proc.stdout;
|
|
271
|
+
},
|
|
272
|
+
stderrStream() {
|
|
273
|
+
return proc.stderr;
|
|
274
|
+
},
|
|
275
|
+
wait() {
|
|
276
|
+
return new Promise((resolve) => {
|
|
277
|
+
proc.on("close", (code) => {
|
|
278
|
+
resolve(code ?? 0);
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// src/workspace/fuse.ts
|
|
286
|
+
import { rmSync } from "fs";
|
|
287
|
+
|
|
288
|
+
// src/fuse/mount.ts
|
|
289
|
+
import { execSync } from "child_process";
|
|
290
|
+
import { mkdtempSync } from "fs";
|
|
291
|
+
import { tmpdir } from "os";
|
|
292
|
+
import { join } from "path";
|
|
293
|
+
|
|
294
|
+
// src/fuse/fs.ts
|
|
295
|
+
import { FileType } from "@struktoai/mirage-core";
|
|
296
|
+
|
|
297
|
+
// src/fuse/platform/macos.ts
|
|
298
|
+
var MACOS_METADATA = /* @__PURE__ */ new Set([
|
|
299
|
+
".DS_Store",
|
|
300
|
+
".Spotlight-V100",
|
|
301
|
+
".fseventsd",
|
|
302
|
+
".Trashes"
|
|
303
|
+
]);
|
|
304
|
+
function isMacosMetadata(name) {
|
|
305
|
+
return MACOS_METADATA.has(name) || name.startsWith("._");
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// src/fuse/fs.ts
|
|
309
|
+
var ENV_AGENT_ID = "MIRAGE_AGENT_ID";
|
|
310
|
+
var MIRAGE_DIR = "/.mirage";
|
|
311
|
+
var MIRAGE_WHOAMI = "/.mirage/whoami";
|
|
312
|
+
var ENOENT = -2;
|
|
313
|
+
var EACCES = -13;
|
|
314
|
+
var ENOTDIR = -20;
|
|
315
|
+
var EEXIST = -17;
|
|
316
|
+
var ENOTEMPTY = -66;
|
|
317
|
+
var EIO = -5;
|
|
318
|
+
var PREFETCH_TTL_MS = 3e4;
|
|
319
|
+
var UNKNOWN_SIZE_SENTINEL = 100 * 1024 * 1024;
|
|
320
|
+
function classifyError(err) {
|
|
321
|
+
const msg = (err instanceof Error ? err.message : String(err)).toLowerCase();
|
|
322
|
+
if (msg.includes("not empty") || msg.includes("enotempty")) return ENOTEMPTY;
|
|
323
|
+
if (msg.includes("not a directory") || msg.includes("enotdir")) return ENOTDIR;
|
|
324
|
+
if (msg.includes("permission") || msg.includes("eacces") || msg.includes("read-only"))
|
|
325
|
+
return EACCES;
|
|
326
|
+
if (msg.includes("file exists") || msg.includes("eexist")) return EEXIST;
|
|
327
|
+
if (msg.includes("not found") || msg.includes("no such") || msg.includes("enoent") || msg.includes("no mount"))
|
|
328
|
+
return ENOENT;
|
|
329
|
+
return EIO;
|
|
330
|
+
}
|
|
331
|
+
var MirageFS = class {
|
|
332
|
+
ws;
|
|
333
|
+
agentId;
|
|
334
|
+
now;
|
|
335
|
+
prefixes;
|
|
336
|
+
handles = /* @__PURE__ */ new Map();
|
|
337
|
+
prefetchCache = /* @__PURE__ */ new Map();
|
|
338
|
+
prefetchInflight = /* @__PURE__ */ new Map();
|
|
339
|
+
nextFh = 1;
|
|
340
|
+
uid;
|
|
341
|
+
gid;
|
|
342
|
+
constructor(ws, options = {}) {
|
|
343
|
+
this.ws = ws;
|
|
344
|
+
this.agentId = options.agentId ?? process.env[ENV_AGENT_ID] ?? `agent-${Math.random().toString(36).slice(2, 10)}`;
|
|
345
|
+
this.now = /* @__PURE__ */ new Date();
|
|
346
|
+
this.prefixes = ws.mounts().map((m) => m.prefix);
|
|
347
|
+
this.uid = typeof process.getuid === "function" ? process.getuid() : 0;
|
|
348
|
+
this.gid = typeof process.getgid === "function" ? process.getgid() : 0;
|
|
349
|
+
}
|
|
350
|
+
// ── helpers ──────────────────────────────────────────────────────
|
|
351
|
+
whoamiContent() {
|
|
352
|
+
const lines = [`agent: ${this.agentId}`, "cwd: /", `mounts: ${this.prefixes.join(", ")}`];
|
|
353
|
+
return new TextEncoder().encode(lines.join("\n") + "\n");
|
|
354
|
+
}
|
|
355
|
+
dirStat() {
|
|
356
|
+
return {
|
|
357
|
+
mtime: this.now,
|
|
358
|
+
atime: this.now,
|
|
359
|
+
ctime: this.now,
|
|
360
|
+
nlink: 2,
|
|
361
|
+
size: 0,
|
|
362
|
+
mode: 16877,
|
|
363
|
+
uid: this.uid,
|
|
364
|
+
gid: this.gid
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
fileStat(size) {
|
|
368
|
+
return {
|
|
369
|
+
mtime: this.now,
|
|
370
|
+
atime: this.now,
|
|
371
|
+
ctime: this.now,
|
|
372
|
+
nlink: 1,
|
|
373
|
+
size,
|
|
374
|
+
mode: 33188,
|
|
375
|
+
uid: this.uid,
|
|
376
|
+
gid: this.gid
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
isVirtualDir(path) {
|
|
380
|
+
const bare = path.replace(/\/+$/, "");
|
|
381
|
+
const normalized = bare + "/";
|
|
382
|
+
for (const p of this.prefixes) {
|
|
383
|
+
const pBare = p.replace(/\/+$/, "");
|
|
384
|
+
if (p.startsWith(normalized) || pBare === bare) return true;
|
|
385
|
+
}
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
virtualChildren(path) {
|
|
389
|
+
const normalized = path === "/" ? "/" : path.replace(/\/+$/, "") + "/";
|
|
390
|
+
const children = /* @__PURE__ */ new Set();
|
|
391
|
+
for (const p of this.prefixes) {
|
|
392
|
+
if (p.startsWith(normalized) && p !== normalized) {
|
|
393
|
+
const rest = p.slice(normalized.length);
|
|
394
|
+
const child = rest.split("/")[0];
|
|
395
|
+
if (child !== void 0 && child !== "") children.add(child);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
return [...children].sort();
|
|
399
|
+
}
|
|
400
|
+
cachedSize(path) {
|
|
401
|
+
for (const ctx of this.handles.values()) {
|
|
402
|
+
if (ctx.path === path && ctx.data !== void 0) return ctx.data.byteLength;
|
|
403
|
+
}
|
|
404
|
+
const entry = this.prefetchCache.get(path);
|
|
405
|
+
if (entry !== void 0 && entry.expires > Date.now()) return entry.data.byteLength;
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
cachedData(path) {
|
|
409
|
+
for (const ctx of this.handles.values()) {
|
|
410
|
+
if (ctx.path === path && ctx.data !== void 0) return ctx.data;
|
|
411
|
+
}
|
|
412
|
+
const entry = this.prefetchCache.get(path);
|
|
413
|
+
if (entry !== void 0 && entry.expires > Date.now()) return entry.data;
|
|
414
|
+
if (entry !== void 0) this.prefetchCache.delete(path);
|
|
415
|
+
return null;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Fetch bytes for a size-unknown file and cache them so the immediate
|
|
419
|
+
* getattr → open → read burst (and subsequent stats within the TTL) reuse
|
|
420
|
+
* the same fetch. Required because @zkochan/fuse-native doesn't expose
|
|
421
|
+
* libfuse's `direct_io` flag — without a real size from getattr, the kernel
|
|
422
|
+
* decides the file is empty and never issues read().
|
|
423
|
+
*/
|
|
424
|
+
async prefetch(path) {
|
|
425
|
+
const cached = this.cachedData(path);
|
|
426
|
+
if (cached !== null) return cached;
|
|
427
|
+
const inflight = this.prefetchInflight.get(path);
|
|
428
|
+
if (inflight !== void 0) return inflight;
|
|
429
|
+
const promise = (async () => {
|
|
430
|
+
try {
|
|
431
|
+
const data = await this.ws.fs.readFile(path);
|
|
432
|
+
this.prefetchCache.set(path, { data, expires: Date.now() + PREFETCH_TTL_MS });
|
|
433
|
+
return data;
|
|
434
|
+
} catch {
|
|
435
|
+
return null;
|
|
436
|
+
} finally {
|
|
437
|
+
this.prefetchInflight.delete(path);
|
|
438
|
+
}
|
|
439
|
+
})();
|
|
440
|
+
this.prefetchInflight.set(path, promise);
|
|
441
|
+
return promise;
|
|
442
|
+
}
|
|
443
|
+
/** Drain and return accumulated op records (mirrors Python's drain_ops). */
|
|
444
|
+
drainOps() {
|
|
445
|
+
const records = [...this.ws.records];
|
|
446
|
+
this.ws.records.length = 0;
|
|
447
|
+
return records;
|
|
448
|
+
}
|
|
449
|
+
// ── FUSE op surface (mirrors mfusepy Operations) ─────────────────
|
|
450
|
+
ops() {
|
|
451
|
+
return {
|
|
452
|
+
readdir: this.readdir.bind(this),
|
|
453
|
+
getattr: this.getattr.bind(this),
|
|
454
|
+
open: this.open.bind(this),
|
|
455
|
+
read: this.read.bind(this),
|
|
456
|
+
write: this.write.bind(this),
|
|
457
|
+
create: this.create.bind(this),
|
|
458
|
+
unlink: this.unlink.bind(this),
|
|
459
|
+
mkdir: this.mkdir.bind(this),
|
|
460
|
+
rmdir: this.rmdir.bind(this),
|
|
461
|
+
rename: this.rename.bind(this),
|
|
462
|
+
release: this.release.bind(this),
|
|
463
|
+
truncate: this.truncate.bind(this),
|
|
464
|
+
flush: this.flush.bind(this),
|
|
465
|
+
fsync: this.fsync.bind(this),
|
|
466
|
+
utimens: this.utimens.bind(this),
|
|
467
|
+
chmod: this.chmod.bind(this),
|
|
468
|
+
chown: this.chown.bind(this),
|
|
469
|
+
access: this.access.bind(this),
|
|
470
|
+
statfs: this.statfs.bind(this)
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
getattr(path, cb) {
|
|
474
|
+
void (async () => {
|
|
475
|
+
if (path === "/" || path === MIRAGE_DIR) {
|
|
476
|
+
cb(0, this.dirStat());
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
if (path === MIRAGE_WHOAMI) {
|
|
480
|
+
cb(0, this.fileStat(this.whoamiContent().byteLength));
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
const name = path.slice(path.lastIndexOf("/") + 1);
|
|
484
|
+
if (isMacosMetadata(name)) {
|
|
485
|
+
cb(ENOENT);
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
if (this.isVirtualDir(path)) {
|
|
489
|
+
cb(0, this.dirStat());
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
try {
|
|
493
|
+
const s = await this.ws.fs.stat(path);
|
|
494
|
+
if (s.type === FileType.DIRECTORY) {
|
|
495
|
+
cb(0, this.dirStat());
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
let size = s.size;
|
|
499
|
+
size ??= this.cachedSize(path) ?? UNKNOWN_SIZE_SENTINEL;
|
|
500
|
+
cb(0, this.fileStat(size));
|
|
501
|
+
} catch (err) {
|
|
502
|
+
cb(classifyError(err));
|
|
503
|
+
}
|
|
504
|
+
})();
|
|
505
|
+
}
|
|
506
|
+
readdir(path, cb) {
|
|
507
|
+
void (async () => {
|
|
508
|
+
if (path === MIRAGE_DIR) {
|
|
509
|
+
cb(0, [".", "..", "whoami"]);
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
const names = new Set(this.virtualChildren(path));
|
|
513
|
+
if (path === "/") names.add(".mirage");
|
|
514
|
+
try {
|
|
515
|
+
const entries = await this.ws.fs.readdir(path);
|
|
516
|
+
for (const e of entries) {
|
|
517
|
+
const part = e.replace(/\/+$/, "").split("/").pop() ?? "";
|
|
518
|
+
if (part !== "" && !isMacosMetadata(part)) names.add(part);
|
|
519
|
+
}
|
|
520
|
+
} catch {
|
|
521
|
+
if (names.size === 0) {
|
|
522
|
+
cb(ENOENT);
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
cb(0, [".", "..", ...[...names].sort()]);
|
|
527
|
+
})();
|
|
528
|
+
}
|
|
529
|
+
read(path, fd, buf, len, pos, cb) {
|
|
530
|
+
void (async () => {
|
|
531
|
+
if (path === MIRAGE_WHOAMI) {
|
|
532
|
+
const data = this.whoamiContent();
|
|
533
|
+
const slice = data.subarray(pos, pos + len);
|
|
534
|
+
buf.set(slice, 0);
|
|
535
|
+
cb(slice.byteLength);
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
const ctx = this.handles.get(fd);
|
|
539
|
+
try {
|
|
540
|
+
if (ctx !== void 0 && ctx.data === void 0) {
|
|
541
|
+
const cached = this.cachedData(path);
|
|
542
|
+
ctx.data = cached ?? await this.ws.fs.readFile(path);
|
|
543
|
+
}
|
|
544
|
+
const data = ctx?.data ?? this.cachedData(path) ?? await this.ws.fs.readFile(path);
|
|
545
|
+
const slice = data.subarray(pos, pos + len);
|
|
546
|
+
buf.set(slice, 0);
|
|
547
|
+
cb(slice.byteLength);
|
|
548
|
+
} catch {
|
|
549
|
+
cb(0);
|
|
550
|
+
}
|
|
551
|
+
})();
|
|
552
|
+
}
|
|
553
|
+
write(path, fd, buf, len, pos, cb) {
|
|
554
|
+
const ctx = this.handles.get(fd);
|
|
555
|
+
const data = new Uint8Array(buf.subarray(0, len));
|
|
556
|
+
if (ctx !== void 0) {
|
|
557
|
+
ctx.writeBuf ??= [];
|
|
558
|
+
ctx.writeBuf.push([pos, data]);
|
|
559
|
+
cb(len);
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
void (async () => {
|
|
563
|
+
try {
|
|
564
|
+
let existing = new Uint8Array(0);
|
|
565
|
+
try {
|
|
566
|
+
existing = await this.ws.fs.readFile(path, { raw: true });
|
|
567
|
+
} catch {
|
|
568
|
+
}
|
|
569
|
+
let merged = existing;
|
|
570
|
+
if (pos > merged.byteLength) {
|
|
571
|
+
const padded = new Uint8Array(pos + data.byteLength);
|
|
572
|
+
padded.set(merged, 0);
|
|
573
|
+
padded.set(data, pos);
|
|
574
|
+
merged = padded;
|
|
575
|
+
} else {
|
|
576
|
+
const size = Math.max(merged.byteLength, pos + data.byteLength);
|
|
577
|
+
const out = new Uint8Array(size);
|
|
578
|
+
out.set(merged.subarray(0, pos), 0);
|
|
579
|
+
out.set(data, pos);
|
|
580
|
+
if (pos + data.byteLength < merged.byteLength) {
|
|
581
|
+
out.set(merged.subarray(pos + data.byteLength), pos + data.byteLength);
|
|
582
|
+
}
|
|
583
|
+
merged = out;
|
|
584
|
+
}
|
|
585
|
+
await this.ws.fs.writeFile(path, merged);
|
|
586
|
+
cb(len);
|
|
587
|
+
} catch {
|
|
588
|
+
cb(0);
|
|
589
|
+
}
|
|
590
|
+
})();
|
|
591
|
+
}
|
|
592
|
+
create(path, _mode, cb) {
|
|
593
|
+
void (async () => {
|
|
594
|
+
try {
|
|
595
|
+
try {
|
|
596
|
+
await this.ws.dispatch("create", path);
|
|
597
|
+
} catch (dispatchErr) {
|
|
598
|
+
const msg = (dispatchErr instanceof Error ? dispatchErr.message : String(dispatchErr)).toLowerCase();
|
|
599
|
+
if (!msg.includes("no op")) throw dispatchErr;
|
|
600
|
+
await this.ws.fs.writeFile(path, new Uint8Array(0));
|
|
601
|
+
}
|
|
602
|
+
const fh = this.nextFh++;
|
|
603
|
+
this.handles.set(fh, { path });
|
|
604
|
+
cb(0, fh);
|
|
605
|
+
} catch (err) {
|
|
606
|
+
cb(classifyError(err));
|
|
607
|
+
}
|
|
608
|
+
})();
|
|
609
|
+
}
|
|
610
|
+
mkdir(path, _mode, cb) {
|
|
611
|
+
void (async () => {
|
|
612
|
+
try {
|
|
613
|
+
await this.ws.fs.mkdir(path);
|
|
614
|
+
cb(0);
|
|
615
|
+
} catch (err) {
|
|
616
|
+
cb(classifyError(err));
|
|
617
|
+
}
|
|
618
|
+
})();
|
|
619
|
+
}
|
|
620
|
+
unlink(path, cb) {
|
|
621
|
+
void (async () => {
|
|
622
|
+
try {
|
|
623
|
+
await this.ws.fs.unlink(path);
|
|
624
|
+
cb(0);
|
|
625
|
+
} catch (err) {
|
|
626
|
+
cb(classifyError(err));
|
|
627
|
+
}
|
|
628
|
+
})();
|
|
629
|
+
}
|
|
630
|
+
rename(src, dst, cb) {
|
|
631
|
+
void (async () => {
|
|
632
|
+
try {
|
|
633
|
+
await this.ws.fs.rename(src, dst);
|
|
634
|
+
cb(0);
|
|
635
|
+
} catch (err) {
|
|
636
|
+
cb(classifyError(err));
|
|
637
|
+
}
|
|
638
|
+
})();
|
|
639
|
+
}
|
|
640
|
+
rmdir(path, cb) {
|
|
641
|
+
void (async () => {
|
|
642
|
+
try {
|
|
643
|
+
try {
|
|
644
|
+
const entries = await this.ws.fs.readdir(path);
|
|
645
|
+
if (entries.length > 0) {
|
|
646
|
+
cb(ENOTEMPTY);
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
} catch {
|
|
650
|
+
}
|
|
651
|
+
await this.ws.fs.rmdir(path);
|
|
652
|
+
cb(0);
|
|
653
|
+
} catch (err) {
|
|
654
|
+
cb(classifyError(err));
|
|
655
|
+
}
|
|
656
|
+
})();
|
|
657
|
+
}
|
|
658
|
+
truncate(path, size, cb) {
|
|
659
|
+
void (async () => {
|
|
660
|
+
try {
|
|
661
|
+
try {
|
|
662
|
+
await this.ws.dispatch("truncate", path, [size]);
|
|
663
|
+
} catch (dispatchErr) {
|
|
664
|
+
const msg = (dispatchErr instanceof Error ? dispatchErr.message : String(dispatchErr)).toLowerCase();
|
|
665
|
+
if (!msg.includes("no op")) throw dispatchErr;
|
|
666
|
+
const data = await this.ws.fs.readFile(path, { raw: true }).catch(() => new Uint8Array(0));
|
|
667
|
+
const out = new Uint8Array(size);
|
|
668
|
+
out.set(data.subarray(0, Math.min(data.byteLength, size)), 0);
|
|
669
|
+
await this.ws.fs.writeFile(path, out);
|
|
670
|
+
}
|
|
671
|
+
cb(0);
|
|
672
|
+
} catch (err) {
|
|
673
|
+
cb(classifyError(err));
|
|
674
|
+
}
|
|
675
|
+
})();
|
|
676
|
+
}
|
|
677
|
+
statfs(_path, cb) {
|
|
678
|
+
cb(0, {
|
|
679
|
+
bsize: 4096,
|
|
680
|
+
frsize: 4096,
|
|
681
|
+
blocks: 1024 * 1024,
|
|
682
|
+
bfree: 1024 * 1024,
|
|
683
|
+
bavail: 1024 * 1024,
|
|
684
|
+
files: 1e6,
|
|
685
|
+
ffree: 1e6,
|
|
686
|
+
favail: 1e6,
|
|
687
|
+
namemax: 255
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
// chmod / chown / utimens / access are no-ops for the filesystem but must
|
|
691
|
+
// validate path existence — callers like `touch`/`chmod` on a missing file
|
|
692
|
+
// should fail with ENOENT, not silently succeed.
|
|
693
|
+
chmod(path, _mode, cb) {
|
|
694
|
+
this.getattrValidate(path, cb);
|
|
695
|
+
}
|
|
696
|
+
chown(path, _uid, _gid, cb) {
|
|
697
|
+
this.getattrValidate(path, cb);
|
|
698
|
+
}
|
|
699
|
+
utimens(path, _atime, _mtime, cb) {
|
|
700
|
+
this.getattrValidate(path, cb);
|
|
701
|
+
}
|
|
702
|
+
access(path, _amode, cb) {
|
|
703
|
+
this.getattrValidate(path, cb);
|
|
704
|
+
}
|
|
705
|
+
getattrValidate(path, cb) {
|
|
706
|
+
this.getattr(path, (code) => {
|
|
707
|
+
cb(code);
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
open(path, _flags, cb) {
|
|
711
|
+
void (async () => {
|
|
712
|
+
if (path === MIRAGE_WHOAMI) {
|
|
713
|
+
const fh = this.nextFh++;
|
|
714
|
+
this.handles.set(fh, { path });
|
|
715
|
+
cb(0, fh);
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
try {
|
|
719
|
+
const s = await this.ws.fs.stat(path);
|
|
720
|
+
const ctx = { path };
|
|
721
|
+
if (s.size === null && s.type !== FileType.DIRECTORY) {
|
|
722
|
+
const data = await this.prefetch(path);
|
|
723
|
+
if (data !== null) ctx.data = data;
|
|
724
|
+
}
|
|
725
|
+
const fh = this.nextFh++;
|
|
726
|
+
this.handles.set(fh, ctx);
|
|
727
|
+
cb(0, fh);
|
|
728
|
+
} catch (err) {
|
|
729
|
+
cb(classifyError(err));
|
|
730
|
+
}
|
|
731
|
+
})();
|
|
732
|
+
}
|
|
733
|
+
release(_path, fd, cb) {
|
|
734
|
+
this.handles.delete(fd);
|
|
735
|
+
cb(0);
|
|
736
|
+
}
|
|
737
|
+
flush(path, fd, cb) {
|
|
738
|
+
const ctx = this.handles.get(fd);
|
|
739
|
+
if (ctx?.writeBuf === void 0 || ctx.writeBuf.length === 0) {
|
|
740
|
+
cb(0);
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
const writes = ctx.writeBuf;
|
|
744
|
+
ctx.writeBuf = [];
|
|
745
|
+
void (async () => {
|
|
746
|
+
try {
|
|
747
|
+
let existing = new Uint8Array(0);
|
|
748
|
+
try {
|
|
749
|
+
existing = await this.ws.fs.readFile(path, { raw: true });
|
|
750
|
+
} catch {
|
|
751
|
+
}
|
|
752
|
+
let total = existing.byteLength;
|
|
753
|
+
for (const [off, chunk] of writes) {
|
|
754
|
+
total = Math.max(total, off + chunk.byteLength);
|
|
755
|
+
}
|
|
756
|
+
const merged = new Uint8Array(total);
|
|
757
|
+
merged.set(existing, 0);
|
|
758
|
+
for (const [off, chunk] of writes) {
|
|
759
|
+
merged.set(chunk, off);
|
|
760
|
+
}
|
|
761
|
+
await this.ws.fs.writeFile(path, merged);
|
|
762
|
+
cb(0);
|
|
763
|
+
} catch (err) {
|
|
764
|
+
cb(classifyError(err));
|
|
765
|
+
}
|
|
766
|
+
})();
|
|
767
|
+
}
|
|
768
|
+
fsync(path, _datasync, fd, cb) {
|
|
769
|
+
this.flush(path, fd, cb);
|
|
770
|
+
}
|
|
771
|
+
};
|
|
772
|
+
|
|
773
|
+
// src/fuse/mount.ts
|
|
774
|
+
async function loadFuse() {
|
|
775
|
+
const mod = await loadOptionalPeer(
|
|
776
|
+
() => import("@zkochan/fuse-native"),
|
|
777
|
+
{
|
|
778
|
+
feature: "FUSE support",
|
|
779
|
+
packageName: "@zkochan/fuse-native",
|
|
780
|
+
docsUrl: "https://mirage.dev/typescript/setup/fuse"
|
|
781
|
+
}
|
|
782
|
+
);
|
|
783
|
+
const Fuse = mod.default ?? mod;
|
|
784
|
+
if (typeof Fuse !== "function") {
|
|
785
|
+
throw new Error("@zkochan/fuse-native did not export a constructor");
|
|
786
|
+
}
|
|
787
|
+
return Fuse;
|
|
788
|
+
}
|
|
789
|
+
function forceUnmount(mountpoint) {
|
|
790
|
+
try {
|
|
791
|
+
if (process.platform === "darwin") {
|
|
792
|
+
execSync(`diskutil unmount force ${JSON.stringify(mountpoint)}`, { stdio: "ignore" });
|
|
793
|
+
} else {
|
|
794
|
+
execSync(`fusermount -u ${JSON.stringify(mountpoint)}`, { stdio: "ignore" });
|
|
795
|
+
}
|
|
796
|
+
} catch {
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
async function mount(ws, options = {}) {
|
|
800
|
+
const Fuse = await loadFuse();
|
|
801
|
+
const mountpoint = options.mountpoint ?? mkdtempSync(join(tmpdir(), "mirage-fuse-"));
|
|
802
|
+
const agentId = options.agentId;
|
|
803
|
+
const mfs = new MirageFS(ws, agentId !== void 0 ? { agentId } : {});
|
|
804
|
+
const autoUnmount = options.autoUnmount ?? process.platform === "linux";
|
|
805
|
+
const fuseOpts = {
|
|
806
|
+
force: true,
|
|
807
|
+
mkdir: true,
|
|
808
|
+
...autoUnmount ? { autoUnmount: true } : {},
|
|
809
|
+
...options.fuseOptions ?? {}
|
|
810
|
+
};
|
|
811
|
+
const fuse = new Fuse(mountpoint, mfs.ops(), fuseOpts);
|
|
812
|
+
await new Promise((resolve, reject) => {
|
|
813
|
+
fuse.mount((err) => {
|
|
814
|
+
if (err === null) resolve();
|
|
815
|
+
else reject(err);
|
|
816
|
+
});
|
|
817
|
+
});
|
|
818
|
+
return {
|
|
819
|
+
mountpoint,
|
|
820
|
+
unmount: () => new Promise((resolve, reject) => {
|
|
821
|
+
fuse.unmount((err) => {
|
|
822
|
+
if (err === null) resolve();
|
|
823
|
+
else reject(err);
|
|
824
|
+
});
|
|
825
|
+
})
|
|
826
|
+
};
|
|
827
|
+
}
|
|
828
|
+
function mountBackground(ws, options = {}) {
|
|
829
|
+
return mount(ws, options);
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
// src/workspace/fuse.ts
|
|
833
|
+
var SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
834
|
+
var FuseCleanupRegistry = class {
|
|
835
|
+
mounts = /* @__PURE__ */ new Set();
|
|
836
|
+
installed = false;
|
|
837
|
+
exiting = false;
|
|
838
|
+
register(entry) {
|
|
839
|
+
this.mounts.add(entry);
|
|
840
|
+
this.install();
|
|
841
|
+
}
|
|
842
|
+
unregister(entry) {
|
|
843
|
+
this.mounts.delete(entry);
|
|
844
|
+
}
|
|
845
|
+
install() {
|
|
846
|
+
if (this.installed) return;
|
|
847
|
+
this.installed = true;
|
|
848
|
+
for (const sig of SIGNALS) {
|
|
849
|
+
process.on(sig, this.onSignal);
|
|
850
|
+
}
|
|
851
|
+
process.on("beforeExit", this.onExit);
|
|
852
|
+
process.on("exit", this.onExit);
|
|
853
|
+
}
|
|
854
|
+
onSignal = (sig) => {
|
|
855
|
+
if (this.exiting) return;
|
|
856
|
+
this.exiting = true;
|
|
857
|
+
this.drainSync();
|
|
858
|
+
process.kill(process.pid, sig);
|
|
859
|
+
};
|
|
860
|
+
onExit = () => {
|
|
861
|
+
if (this.exiting) return;
|
|
862
|
+
this.exiting = true;
|
|
863
|
+
this.drainSync();
|
|
864
|
+
};
|
|
865
|
+
drainSync() {
|
|
866
|
+
for (const entry of this.mounts) {
|
|
867
|
+
forceUnmount(entry.mountpoint);
|
|
868
|
+
try {
|
|
869
|
+
rmSync(entry.mountpoint, { recursive: true, force: true });
|
|
870
|
+
} catch {
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
this.mounts.clear();
|
|
874
|
+
}
|
|
875
|
+
};
|
|
876
|
+
var CLEANUP = new FuseCleanupRegistry();
|
|
877
|
+
var FuseManager = class {
|
|
878
|
+
handle = null;
|
|
879
|
+
externalMountpoint = null;
|
|
880
|
+
auto = false;
|
|
881
|
+
cleanupEntry = null;
|
|
882
|
+
get mountpoint() {
|
|
883
|
+
if (this.handle !== null) return this.handle.mountpoint;
|
|
884
|
+
return this.externalMountpoint;
|
|
885
|
+
}
|
|
886
|
+
set mountpoint(path) {
|
|
887
|
+
this.externalMountpoint = path;
|
|
888
|
+
}
|
|
889
|
+
async setup(ws, options = {}) {
|
|
890
|
+
if (this.handle !== null) return this.handle.mountpoint;
|
|
891
|
+
this.handle = await mount(ws, options);
|
|
892
|
+
this.auto = true;
|
|
893
|
+
this.externalMountpoint = null;
|
|
894
|
+
this.cleanupEntry = { mountpoint: this.handle.mountpoint, handle: this.handle };
|
|
895
|
+
CLEANUP.register(this.cleanupEntry);
|
|
896
|
+
ws.setFuseMountpoint(this.handle.mountpoint, { owned: true });
|
|
897
|
+
return this.handle.mountpoint;
|
|
898
|
+
}
|
|
899
|
+
async unmount(ws) {
|
|
900
|
+
if (this.handle === null) {
|
|
901
|
+
if (ws !== void 0) ws.setFuseMountpoint(null);
|
|
902
|
+
this.externalMountpoint = null;
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
905
|
+
const mp = this.handle.mountpoint;
|
|
906
|
+
try {
|
|
907
|
+
await this.handle.unmount();
|
|
908
|
+
} finally {
|
|
909
|
+
if (this.cleanupEntry !== null) {
|
|
910
|
+
CLEANUP.unregister(this.cleanupEntry);
|
|
911
|
+
this.cleanupEntry = null;
|
|
912
|
+
}
|
|
913
|
+
this.handle = null;
|
|
914
|
+
this.auto = false;
|
|
915
|
+
ws?.setFuseMountpoint(null);
|
|
916
|
+
try {
|
|
917
|
+
rmSync(mp, { recursive: true, force: true });
|
|
918
|
+
} catch {
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
async close(ws) {
|
|
923
|
+
if (this.auto) await this.unmount(ws);
|
|
924
|
+
}
|
|
925
|
+
};
|
|
926
|
+
|
|
927
|
+
// src/workspace.ts
|
|
928
|
+
var requireCjs = createRequire(import.meta.url);
|
|
929
|
+
var cachedParser = null;
|
|
930
|
+
function loadShellParser() {
|
|
931
|
+
if (cachedParser !== null) return cachedParser;
|
|
932
|
+
const enginePath = requireCjs.resolve("web-tree-sitter/web-tree-sitter.wasm");
|
|
933
|
+
const grammarPath = requireCjs.resolve("tree-sitter-bash/tree-sitter-bash.wasm");
|
|
934
|
+
cachedParser = createShellParser({
|
|
935
|
+
engineWasm: readFileSync(enginePath),
|
|
936
|
+
grammarWasm: readFileSync(grammarPath)
|
|
937
|
+
});
|
|
938
|
+
return cachedParser;
|
|
939
|
+
}
|
|
940
|
+
var Workspace = class extends CoreWorkspace {
|
|
941
|
+
defaultNative;
|
|
942
|
+
autoFuseManager;
|
|
943
|
+
fuseSetupPromise = null;
|
|
944
|
+
constructor(resources, options = {}) {
|
|
945
|
+
super(resources, {
|
|
946
|
+
...options,
|
|
947
|
+
shellParserFactory: options.shellParserFactory ?? loadShellParser
|
|
948
|
+
});
|
|
949
|
+
this.defaultNative = options.native ?? false;
|
|
950
|
+
this.autoFuseManager = options.fuse === true ? new FuseManager() : null;
|
|
951
|
+
if (this.autoFuseManager !== null) {
|
|
952
|
+
const fm = this.autoFuseManager;
|
|
953
|
+
this.fuseSetupPromise = fm.setup(this).then(() => void 0);
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
async ensureFuseReady() {
|
|
957
|
+
if (this.fuseSetupPromise !== null) {
|
|
958
|
+
await this.fuseSetupPromise;
|
|
959
|
+
this.fuseSetupPromise = null;
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
async execute(command31, options = {}) {
|
|
963
|
+
await this.ensureFuseReady();
|
|
964
|
+
const useNative = options.native ?? this.defaultNative;
|
|
965
|
+
if (useNative) {
|
|
966
|
+
const mp = this.fuseMountpoint;
|
|
967
|
+
if (mp === null) {
|
|
968
|
+
console.warn(
|
|
969
|
+
"native=true requires FUSE. Install macFUSE (macOS) or libfuse (Linux) and set ws.setFuseMountpoint(). Falling back to virtual mode."
|
|
970
|
+
);
|
|
971
|
+
} else if (this.ownsFuseMount) {
|
|
972
|
+
throw new Error(
|
|
973
|
+
"native=true with a same-process FUSE mount would deadlock (Node single event loop). Workarounds:\n 1. Mount FUSE in a helper process; call nativeExec from this process.\n 2. Point nativeExec at a mountpoint created by another tool (then call ws.setFuseMountpoint(path) without using FuseManager).\n 3. Use execute() without native=true (virtual executor is in-process safe).\nSee https://mirage.dev/typescript/limitations for details."
|
|
974
|
+
);
|
|
975
|
+
} else {
|
|
976
|
+
const opts = { cwd: mp };
|
|
977
|
+
if (options.signal !== void 0) opts.signal = options.signal;
|
|
978
|
+
const { stdout, stderr, exitCode } = await nativeExec(command31, opts);
|
|
979
|
+
return new ExecuteResult2(stdout, stderr, exitCode);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
return super.execute(command31, options);
|
|
983
|
+
}
|
|
984
|
+
async close() {
|
|
985
|
+
await this.ensureFuseReady().catch(() => void 0);
|
|
986
|
+
if (this.autoFuseManager !== null) {
|
|
987
|
+
await this.autoFuseManager.close(this);
|
|
988
|
+
}
|
|
989
|
+
await super.close();
|
|
990
|
+
}
|
|
991
|
+
};
|
|
992
|
+
|
|
993
|
+
// src/fs_monkey.ts
|
|
994
|
+
import { Buffer as Buffer2 } from "buffer";
|
|
995
|
+
import { createRequire as createRequire2 } from "module";
|
|
996
|
+
import { FileType as FileType2 } from "@struktoai/mirage-core";
|
|
997
|
+
var requireCjs2 = createRequire2(import.meta.url);
|
|
998
|
+
var fs = requireCjs2("node:fs");
|
|
999
|
+
var fsMonkey = requireCjs2("fs-monkey");
|
|
1000
|
+
var { patchFs } = fsMonkey;
|
|
1001
|
+
function mountedPath(ws, p) {
|
|
1002
|
+
try {
|
|
1003
|
+
return ws.registry.mountFor(p) !== null;
|
|
1004
|
+
} catch {
|
|
1005
|
+
return false;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
async function mirageStat(ws, p) {
|
|
1009
|
+
const s = await ws.fs.stat(p);
|
|
1010
|
+
const isDir = s.type === FileType2.DIRECTORY;
|
|
1011
|
+
const mtime = s.modified !== null ? new Date(s.modified) : /* @__PURE__ */ new Date(0);
|
|
1012
|
+
return {
|
|
1013
|
+
isFile: () => !isDir,
|
|
1014
|
+
isDirectory: () => isDir,
|
|
1015
|
+
isBlockDevice: () => false,
|
|
1016
|
+
isCharacterDevice: () => false,
|
|
1017
|
+
isSymbolicLink: () => false,
|
|
1018
|
+
isFIFO: () => false,
|
|
1019
|
+
isSocket: () => false,
|
|
1020
|
+
size: s.size ?? 0,
|
|
1021
|
+
mtime,
|
|
1022
|
+
mtimeMs: mtime.getTime(),
|
|
1023
|
+
atime: mtime,
|
|
1024
|
+
atimeMs: mtime.getTime(),
|
|
1025
|
+
ctime: mtime,
|
|
1026
|
+
ctimeMs: mtime.getTime(),
|
|
1027
|
+
birthtime: mtime,
|
|
1028
|
+
birthtimeMs: mtime.getTime(),
|
|
1029
|
+
mode: 0,
|
|
1030
|
+
nlink: 1,
|
|
1031
|
+
uid: 0,
|
|
1032
|
+
gid: 0,
|
|
1033
|
+
rdev: 0,
|
|
1034
|
+
blksize: 0,
|
|
1035
|
+
blocks: 0,
|
|
1036
|
+
dev: 0,
|
|
1037
|
+
ino: 0
|
|
1038
|
+
};
|
|
1039
|
+
}
|
|
1040
|
+
function patchNodeFs(ws) {
|
|
1041
|
+
const originalFs = { ...fs };
|
|
1042
|
+
const vol = {
|
|
1043
|
+
promises: {
|
|
1044
|
+
readFile: async (p, opts) => {
|
|
1045
|
+
if (mountedPath(ws, p)) {
|
|
1046
|
+
const bytes = await ws.fs.readFile(p);
|
|
1047
|
+
const encoding = typeof opts === "string" ? opts : opts?.encoding;
|
|
1048
|
+
if (encoding !== void 0) return Buffer2.from(bytes).toString(encoding);
|
|
1049
|
+
return Buffer2.from(bytes);
|
|
1050
|
+
}
|
|
1051
|
+
const native = originalFs.promises.readFile;
|
|
1052
|
+
return native(p, opts);
|
|
1053
|
+
},
|
|
1054
|
+
writeFile: async (p, data) => {
|
|
1055
|
+
if (mountedPath(ws, p)) {
|
|
1056
|
+
await ws.fs.writeFile(p, typeof data === "string" ? data : data);
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
1059
|
+
const native = originalFs.promises.writeFile;
|
|
1060
|
+
await native(p, data);
|
|
1061
|
+
},
|
|
1062
|
+
readdir: async (p) => {
|
|
1063
|
+
if (mountedPath(ws, p)) {
|
|
1064
|
+
const entries = await ws.fs.readdir(p);
|
|
1065
|
+
return entries.map((e) => {
|
|
1066
|
+
const trimmed = e.endsWith("/") ? e.slice(0, -1) : e;
|
|
1067
|
+
return trimmed.slice(trimmed.lastIndexOf("/") + 1);
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
const native = originalFs.promises.readdir;
|
|
1071
|
+
return native(p);
|
|
1072
|
+
},
|
|
1073
|
+
stat: async (p) => {
|
|
1074
|
+
if (mountedPath(ws, p)) return mirageStat(ws, p);
|
|
1075
|
+
const native = originalFs.promises.stat;
|
|
1076
|
+
return native(p);
|
|
1077
|
+
},
|
|
1078
|
+
unlink: async (p) => {
|
|
1079
|
+
if (mountedPath(ws, p)) return ws.fs.unlink(p);
|
|
1080
|
+
const native = originalFs.promises.unlink;
|
|
1081
|
+
await native(p);
|
|
1082
|
+
},
|
|
1083
|
+
mkdir: async (p) => {
|
|
1084
|
+
if (mountedPath(ws, p)) return ws.fs.mkdir(p);
|
|
1085
|
+
const native = originalFs.promises.mkdir;
|
|
1086
|
+
await native(p);
|
|
1087
|
+
},
|
|
1088
|
+
rmdir: async (p) => {
|
|
1089
|
+
if (mountedPath(ws, p)) return ws.fs.rmdir(p);
|
|
1090
|
+
const native = originalFs.promises.rmdir;
|
|
1091
|
+
await native(p);
|
|
1092
|
+
}
|
|
1093
|
+
},
|
|
1094
|
+
readFileSync: () => {
|
|
1095
|
+
throw new Error("mirage.patchNodeFs: sync fs methods not supported \u2014 use fs.promises.*");
|
|
1096
|
+
},
|
|
1097
|
+
readFile: (p, cb) => {
|
|
1098
|
+
if (mountedPath(ws, p)) {
|
|
1099
|
+
ws.fs.readFile(p).then((data) => {
|
|
1100
|
+
cb(null, Buffer2.from(data));
|
|
1101
|
+
}).catch((err) => {
|
|
1102
|
+
cb(err);
|
|
1103
|
+
});
|
|
1104
|
+
return;
|
|
1105
|
+
}
|
|
1106
|
+
const native = originalFs.readFile;
|
|
1107
|
+
native(p, cb);
|
|
1108
|
+
},
|
|
1109
|
+
readdir: (p, cb) => {
|
|
1110
|
+
if (mountedPath(ws, p)) {
|
|
1111
|
+
ws.fs.readdir(p).then((entries) => {
|
|
1112
|
+
cb(
|
|
1113
|
+
null,
|
|
1114
|
+
entries.map((e) => {
|
|
1115
|
+
const trimmed = e.endsWith("/") ? e.slice(0, -1) : e;
|
|
1116
|
+
return trimmed.slice(trimmed.lastIndexOf("/") + 1);
|
|
1117
|
+
})
|
|
1118
|
+
);
|
|
1119
|
+
}).catch((err) => {
|
|
1120
|
+
cb(err);
|
|
1121
|
+
});
|
|
1122
|
+
return;
|
|
1123
|
+
}
|
|
1124
|
+
const native = originalFs.readdir;
|
|
1125
|
+
native(p, cb);
|
|
1126
|
+
}
|
|
1127
|
+
};
|
|
1128
|
+
patchFs(vol, fs);
|
|
1129
|
+
return function restore() {
|
|
1130
|
+
for (const [k, v] of Object.entries(originalFs)) {
|
|
1131
|
+
const desc = Object.getOwnPropertyDescriptor(fs, k);
|
|
1132
|
+
if (desc?.writable === false && desc.set === void 0) continue;
|
|
1133
|
+
try {
|
|
1134
|
+
fs[k] = v;
|
|
1135
|
+
} catch {
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
// src/commands/builtin/redis/provision.ts
|
|
1142
|
+
import {
|
|
1143
|
+
Precision,
|
|
1144
|
+
ProvisionResult
|
|
1145
|
+
} from "@struktoai/mirage-core";
|
|
1146
|
+
async function resolveSizes(accessor, paths, index) {
|
|
1147
|
+
const resolved = [];
|
|
1148
|
+
let missing = 0;
|
|
1149
|
+
for (const p of paths) {
|
|
1150
|
+
const pathStr = p.original;
|
|
1151
|
+
let size = null;
|
|
1152
|
+
if (index !== void 0) {
|
|
1153
|
+
const lookup = await index.get(pathStr);
|
|
1154
|
+
if (lookup.entry !== void 0 && lookup.entry !== null) {
|
|
1155
|
+
size = lookup.entry.size;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
if (size === null) {
|
|
1159
|
+
try {
|
|
1160
|
+
const fileStat = await stat2(accessor, p);
|
|
1161
|
+
size = fileStat.size;
|
|
1162
|
+
} catch {
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
if (size !== null) {
|
|
1166
|
+
resolved.push([pathStr, size]);
|
|
1167
|
+
} else {
|
|
1168
|
+
missing += 1;
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
return { resolved, missing };
|
|
1172
|
+
}
|
|
1173
|
+
async function fileReadProvision(accessor, paths, _texts, _opts) {
|
|
1174
|
+
if (paths.length === 0) {
|
|
1175
|
+
return new ProvisionResult({ precision: Precision.UNKNOWN });
|
|
1176
|
+
}
|
|
1177
|
+
const { resolved, missing } = await resolveSizes(accessor, paths, void 0);
|
|
1178
|
+
if (missing > 0 || resolved.length === 0) {
|
|
1179
|
+
return new ProvisionResult({ precision: Precision.UNKNOWN });
|
|
1180
|
+
}
|
|
1181
|
+
const total = resolved.reduce((sum, [, size]) => sum + size, 0);
|
|
1182
|
+
return new ProvisionResult({
|
|
1183
|
+
networkReadLow: total,
|
|
1184
|
+
networkReadHigh: total,
|
|
1185
|
+
readOps: resolved.length,
|
|
1186
|
+
precision: Precision.EXACT
|
|
1187
|
+
});
|
|
1188
|
+
}
|
|
1189
|
+
async function headTailProvision(accessor, paths, _texts, _opts) {
|
|
1190
|
+
if (paths.length === 0) {
|
|
1191
|
+
return new ProvisionResult({ precision: Precision.UNKNOWN });
|
|
1192
|
+
}
|
|
1193
|
+
const { resolved, missing } = await resolveSizes(accessor, paths, void 0);
|
|
1194
|
+
if (missing > 0 || resolved.length === 0) {
|
|
1195
|
+
return new ProvisionResult({ precision: Precision.UNKNOWN });
|
|
1196
|
+
}
|
|
1197
|
+
const total = resolved.reduce((sum, [, size]) => sum + size, 0);
|
|
1198
|
+
return new ProvisionResult({
|
|
1199
|
+
networkReadLow: total,
|
|
1200
|
+
networkReadHigh: total,
|
|
1201
|
+
readOps: resolved.length,
|
|
1202
|
+
precision: Precision.EXACT
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1205
|
+
function metadataProvision(_accessor, paths, _texts, _opts) {
|
|
1206
|
+
const n = Math.max(1, paths.length > 0 ? paths.length : 1);
|
|
1207
|
+
return new ProvisionResult({
|
|
1208
|
+
networkReadLow: 0,
|
|
1209
|
+
networkReadHigh: 0,
|
|
1210
|
+
readOps: n,
|
|
1211
|
+
precision: Precision.EXACT
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
// src/cache/redis/file.ts
|
|
1216
|
+
import {
|
|
1217
|
+
defaultFingerprint,
|
|
1218
|
+
parseLimit
|
|
1219
|
+
} from "@struktoai/mirage-core";
|
|
1220
|
+
var RedisFileCacheStore = class extends RedisResource {
|
|
1221
|
+
limit;
|
|
1222
|
+
dataPrefix;
|
|
1223
|
+
metaPrefix;
|
|
1224
|
+
maxDrainBytes;
|
|
1225
|
+
constructor(options = {}) {
|
|
1226
|
+
super({
|
|
1227
|
+
url: options.url ?? "redis://localhost:6379/0",
|
|
1228
|
+
keyPrefix: options.keyPrefix ?? "mirage:cache:"
|
|
1229
|
+
});
|
|
1230
|
+
this.limit = parseLimit(options.cacheLimit ?? "512MB");
|
|
1231
|
+
this.dataPrefix = `${this.keyPrefix}data:`;
|
|
1232
|
+
this.metaPrefix = `${this.keyPrefix}meta:`;
|
|
1233
|
+
this.maxDrainBytes = options.maxDrainBytes ?? null;
|
|
1234
|
+
}
|
|
1235
|
+
cacheSize = 0;
|
|
1236
|
+
get cacheLimit() {
|
|
1237
|
+
return this.limit;
|
|
1238
|
+
}
|
|
1239
|
+
cacheClient() {
|
|
1240
|
+
return this.store.client();
|
|
1241
|
+
}
|
|
1242
|
+
async get(key) {
|
|
1243
|
+
const c = await this.cacheClient();
|
|
1244
|
+
const mod = await this.module();
|
|
1245
|
+
const blob = mod.RESP_TYPES.BLOB_STRING;
|
|
1246
|
+
const mapping = { [blob]: Buffer };
|
|
1247
|
+
const typed = c;
|
|
1248
|
+
const raw = await typed.withTypeMapping(mapping).get(`${this.dataPrefix}${key}`);
|
|
1249
|
+
if (raw === null) return null;
|
|
1250
|
+
return new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength);
|
|
1251
|
+
}
|
|
1252
|
+
async set(key, data, options = {}) {
|
|
1253
|
+
const fp = options.fingerprint ?? defaultFingerprint(data);
|
|
1254
|
+
const c = await this.cacheClient();
|
|
1255
|
+
const dk = `${this.dataPrefix}${key}`;
|
|
1256
|
+
const mk = `${this.metaPrefix}${key}`;
|
|
1257
|
+
const pipe = c.multi();
|
|
1258
|
+
pipe.set(dk, Buffer.from(data.buffer, data.byteOffset, data.byteLength));
|
|
1259
|
+
pipe.set(mk, fp);
|
|
1260
|
+
if (options.ttl !== null && options.ttl !== void 0) {
|
|
1261
|
+
pipe.expire(dk, options.ttl);
|
|
1262
|
+
pipe.expire(mk, options.ttl);
|
|
1263
|
+
}
|
|
1264
|
+
await pipe.exec();
|
|
1265
|
+
}
|
|
1266
|
+
async add(key, data, options = {}) {
|
|
1267
|
+
const c = await this.cacheClient();
|
|
1268
|
+
const exists = await c.exists(`${this.dataPrefix}${key}`);
|
|
1269
|
+
if (exists) return false;
|
|
1270
|
+
await this.set(key, data, options);
|
|
1271
|
+
return true;
|
|
1272
|
+
}
|
|
1273
|
+
async remove(key) {
|
|
1274
|
+
const c = await this.cacheClient();
|
|
1275
|
+
const pipe = c.multi();
|
|
1276
|
+
pipe.del(`${this.dataPrefix}${key}`);
|
|
1277
|
+
pipe.del(`${this.metaPrefix}${key}`);
|
|
1278
|
+
await pipe.exec();
|
|
1279
|
+
}
|
|
1280
|
+
async exists(key) {
|
|
1281
|
+
const k = typeof key === "string" ? key : key.stripPrefix;
|
|
1282
|
+
const c = await this.cacheClient();
|
|
1283
|
+
return await c.exists(`${this.dataPrefix}${k}`) > 0;
|
|
1284
|
+
}
|
|
1285
|
+
async isFresh(key, remoteFingerprint) {
|
|
1286
|
+
const c = await this.cacheClient();
|
|
1287
|
+
const fp = await c.get(`${this.metaPrefix}${key}`);
|
|
1288
|
+
if (fp === null) return false;
|
|
1289
|
+
return fp === remoteFingerprint;
|
|
1290
|
+
}
|
|
1291
|
+
async clear() {
|
|
1292
|
+
const c = await this.cacheClient();
|
|
1293
|
+
for (const pattern of [`${this.dataPrefix}*`, `${this.metaPrefix}*`]) {
|
|
1294
|
+
const batch = [];
|
|
1295
|
+
for await (const k of c.scanIterator({ MATCH: pattern })) {
|
|
1296
|
+
if (Array.isArray(k)) batch.push(...k);
|
|
1297
|
+
else batch.push(k);
|
|
1298
|
+
}
|
|
1299
|
+
if (batch.length > 0) await c.del(batch);
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
async allCached(keys) {
|
|
1303
|
+
for (const k of keys) {
|
|
1304
|
+
if (!await this.exists(k)) return false;
|
|
1305
|
+
}
|
|
1306
|
+
return true;
|
|
1307
|
+
}
|
|
1308
|
+
async multiGet(keys) {
|
|
1309
|
+
const out = [];
|
|
1310
|
+
for (const k of keys) out.push(await this.get(k));
|
|
1311
|
+
return out;
|
|
1312
|
+
}
|
|
1313
|
+
};
|
|
1314
|
+
|
|
1315
|
+
// src/cache/redis/index_cache.ts
|
|
1316
|
+
import {
|
|
1317
|
+
IndexCacheStore,
|
|
1318
|
+
IndexEntry,
|
|
1319
|
+
LookupStatus
|
|
1320
|
+
} from "@struktoai/mirage-core";
|
|
1321
|
+
var ENTRY_PREFIX = "mirage:idx:entry:";
|
|
1322
|
+
var CHILDREN_PREFIX = "mirage:idx:children:";
|
|
1323
|
+
var RedisIndexCacheStore = class _RedisIndexCacheStore extends IndexCacheStore {
|
|
1324
|
+
ttl;
|
|
1325
|
+
url;
|
|
1326
|
+
providedClient;
|
|
1327
|
+
entryPrefix;
|
|
1328
|
+
childrenPrefix;
|
|
1329
|
+
clientPromise = null;
|
|
1330
|
+
constructor(options = {}) {
|
|
1331
|
+
super();
|
|
1332
|
+
this.ttl = options.ttl ?? 600;
|
|
1333
|
+
this.url = options.url ?? "redis://localhost:6379/0";
|
|
1334
|
+
this.providedClient = options.client ?? null;
|
|
1335
|
+
const prefix = options.keyPrefix ?? "";
|
|
1336
|
+
this.entryPrefix = `${prefix}${ENTRY_PREFIX}`;
|
|
1337
|
+
this.childrenPrefix = `${prefix}${CHILDREN_PREFIX}`;
|
|
1338
|
+
}
|
|
1339
|
+
static fromConfig(config, extra = {}) {
|
|
1340
|
+
return new _RedisIndexCacheStore({ ttl: config.ttl ?? 600, ...extra });
|
|
1341
|
+
}
|
|
1342
|
+
entryKey(path) {
|
|
1343
|
+
return `${this.entryPrefix}${path}`;
|
|
1344
|
+
}
|
|
1345
|
+
childrenKey(path) {
|
|
1346
|
+
return `${this.childrenPrefix}${path}`;
|
|
1347
|
+
}
|
|
1348
|
+
client() {
|
|
1349
|
+
if (this.providedClient !== null) return Promise.resolve(this.providedClient);
|
|
1350
|
+
this.clientPromise ??= (async () => {
|
|
1351
|
+
const mod = await loadOptionalPeer(
|
|
1352
|
+
() => import("redis"),
|
|
1353
|
+
{ feature: "RedisIndexCacheStore", packageName: "redis" }
|
|
1354
|
+
);
|
|
1355
|
+
const c = mod.createClient({
|
|
1356
|
+
url: this.url,
|
|
1357
|
+
socket: { reconnectStrategy: false }
|
|
1358
|
+
});
|
|
1359
|
+
await c.connect();
|
|
1360
|
+
return c;
|
|
1361
|
+
})();
|
|
1362
|
+
return this.clientPromise;
|
|
1363
|
+
}
|
|
1364
|
+
async get(resourcePath) {
|
|
1365
|
+
const c = await this.client();
|
|
1366
|
+
const raw = await c.get(this.entryKey(resourcePath));
|
|
1367
|
+
if (raw === null) return { status: LookupStatus.NOT_FOUND };
|
|
1368
|
+
const parsed = JSON.parse(raw);
|
|
1369
|
+
return { entry: new IndexEntry(parsed) };
|
|
1370
|
+
}
|
|
1371
|
+
async put(resourcePath, entry) {
|
|
1372
|
+
const c = await this.client();
|
|
1373
|
+
const stored = entry.indexTime === "" ? entry.copyWith({ indexTime: (/* @__PURE__ */ new Date()).toISOString() }) : entry;
|
|
1374
|
+
await c.set(this.entryKey(resourcePath), JSON.stringify(this.serialize(stored)));
|
|
1375
|
+
}
|
|
1376
|
+
async listDir(resourcePath) {
|
|
1377
|
+
const c = await this.client();
|
|
1378
|
+
const key = this.childrenKey(resourcePath);
|
|
1379
|
+
const exists = await c.exists(key);
|
|
1380
|
+
if (!exists) return { status: LookupStatus.NOT_FOUND };
|
|
1381
|
+
const ttlRemaining = await c.ttl(key);
|
|
1382
|
+
if (ttlRemaining === -2) return { status: LookupStatus.EXPIRED };
|
|
1383
|
+
const raw = await c.lRange(key, 0, -1);
|
|
1384
|
+
return { entries: [...raw].sort() };
|
|
1385
|
+
}
|
|
1386
|
+
async setDir(resourcePath, entries, expiredAt) {
|
|
1387
|
+
const c = await this.client();
|
|
1388
|
+
const now = /* @__PURE__ */ new Date();
|
|
1389
|
+
const nowIso = now.toISOString();
|
|
1390
|
+
const prefix = resourcePath === "/" ? "/" : `${resourcePath}/`;
|
|
1391
|
+
const pipe = c.multi();
|
|
1392
|
+
const childKeys = [];
|
|
1393
|
+
for (const [name, entry] of entries) {
|
|
1394
|
+
const fullPath = prefix + name;
|
|
1395
|
+
const stored = entry.indexTime === "" ? entry.copyWith({ indexTime: nowIso }) : entry;
|
|
1396
|
+
pipe.set(this.entryKey(fullPath), JSON.stringify(this.serialize(stored)));
|
|
1397
|
+
childKeys.push(fullPath);
|
|
1398
|
+
}
|
|
1399
|
+
const childrenKey = this.childrenKey(resourcePath);
|
|
1400
|
+
pipe.del(childrenKey);
|
|
1401
|
+
if (childKeys.length > 0) {
|
|
1402
|
+
childKeys.sort();
|
|
1403
|
+
pipe.rPush(childrenKey, childKeys);
|
|
1404
|
+
}
|
|
1405
|
+
const ttlSeconds = expiredAt !== null && expiredAt !== void 0 ? Math.max(1, Math.floor((expiredAt.getTime() - now.getTime()) / 1e3)) : Math.max(1, Math.floor(this.ttl));
|
|
1406
|
+
pipe.expire(childrenKey, ttlSeconds);
|
|
1407
|
+
await pipe.exec();
|
|
1408
|
+
}
|
|
1409
|
+
async invalidateDir(resourcePath) {
|
|
1410
|
+
const c = await this.client();
|
|
1411
|
+
await c.del(this.childrenKey(resourcePath));
|
|
1412
|
+
}
|
|
1413
|
+
async clear() {
|
|
1414
|
+
const c = await this.client();
|
|
1415
|
+
for (const pattern of [`${this.entryPrefix}*`, `${this.childrenPrefix}*`]) {
|
|
1416
|
+
const keys = [];
|
|
1417
|
+
for await (const k of c.scanIterator({ MATCH: pattern })) {
|
|
1418
|
+
if (Array.isArray(k)) keys.push(...k);
|
|
1419
|
+
else keys.push(k);
|
|
1420
|
+
}
|
|
1421
|
+
if (keys.length > 0) await c.del(keys);
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
async close() {
|
|
1425
|
+
if (this.providedClient !== null) return;
|
|
1426
|
+
if (this.clientPromise === null) return;
|
|
1427
|
+
const c = await this.clientPromise;
|
|
1428
|
+
const typed = c;
|
|
1429
|
+
if (typeof typed.destroy === "function") typed.destroy();
|
|
1430
|
+
else if (c.isOpen) await c.quit();
|
|
1431
|
+
this.clientPromise = null;
|
|
1432
|
+
}
|
|
1433
|
+
serialize(e) {
|
|
1434
|
+
return {
|
|
1435
|
+
id: e.id,
|
|
1436
|
+
name: e.name,
|
|
1437
|
+
resourceType: e.resourceType,
|
|
1438
|
+
remoteTime: e.remoteTime,
|
|
1439
|
+
indexTime: e.indexTime,
|
|
1440
|
+
vfsName: e.vfsName,
|
|
1441
|
+
size: e.size
|
|
1442
|
+
};
|
|
1443
|
+
}
|
|
1444
|
+
};
|
|
1445
|
+
|
|
1446
|
+
// src/resource/sscholar/sscholar.ts
|
|
1447
|
+
import {
|
|
1448
|
+
HttpSSCholarDriver,
|
|
1449
|
+
PathSpec,
|
|
1450
|
+
RAMIndexCacheStore,
|
|
1451
|
+
ResourceName,
|
|
1452
|
+
SSCHOLAR_PAPER_COMMANDS,
|
|
1453
|
+
SSCHOLAR_PAPER_OPS,
|
|
1454
|
+
SSCHOLAR_PAPER_PROMPT,
|
|
1455
|
+
SSCholarAccessor,
|
|
1456
|
+
resolveSSCholarConfig,
|
|
1457
|
+
resolveSSCholarPaperGlob,
|
|
1458
|
+
sscholarPaperRead,
|
|
1459
|
+
sscholarPaperReaddir,
|
|
1460
|
+
sscholarPaperStat
|
|
1461
|
+
} from "@struktoai/mirage-core";
|
|
1462
|
+
var SSCholarPaperResource = class {
|
|
1463
|
+
kind = ResourceName.SSCHOLAR_PAPER;
|
|
1464
|
+
isRemote = true;
|
|
1465
|
+
indexTtl = 0;
|
|
1466
|
+
prompt;
|
|
1467
|
+
config;
|
|
1468
|
+
driver;
|
|
1469
|
+
accessor;
|
|
1470
|
+
index;
|
|
1471
|
+
constructor(options = {}) {
|
|
1472
|
+
const opts = "config" in options || "driver" in options || "prefix" in options ? options : { config: options };
|
|
1473
|
+
this.config = resolveSSCholarConfig(opts.config ?? {});
|
|
1474
|
+
this.driver = opts.driver ?? new HttpSSCholarDriver({ baseUrl: this.config.baseUrl, apiKey: this.config.apiKey });
|
|
1475
|
+
this.accessor = new SSCholarAccessor(this.driver, this.config);
|
|
1476
|
+
this.index = new RAMIndexCacheStore({ ttl: this.indexTtl });
|
|
1477
|
+
this.prompt = SSCHOLAR_PAPER_PROMPT.replace("{prefix}", opts.prefix ?? "");
|
|
1478
|
+
}
|
|
1479
|
+
open() {
|
|
1480
|
+
return Promise.resolve();
|
|
1481
|
+
}
|
|
1482
|
+
async close() {
|
|
1483
|
+
await this.driver.close();
|
|
1484
|
+
}
|
|
1485
|
+
ops() {
|
|
1486
|
+
return SSCHOLAR_PAPER_OPS;
|
|
1487
|
+
}
|
|
1488
|
+
commands() {
|
|
1489
|
+
return SSCHOLAR_PAPER_COMMANDS;
|
|
1490
|
+
}
|
|
1491
|
+
readFile(p) {
|
|
1492
|
+
return sscholarPaperRead(this.accessor, p, this.index);
|
|
1493
|
+
}
|
|
1494
|
+
readdir(p) {
|
|
1495
|
+
return sscholarPaperReaddir(this.accessor, p, this.index);
|
|
1496
|
+
}
|
|
1497
|
+
stat(p) {
|
|
1498
|
+
return sscholarPaperStat(this.accessor, p, this.index);
|
|
1499
|
+
}
|
|
1500
|
+
glob(paths, prefix = "") {
|
|
1501
|
+
const effective = prefix !== "" ? paths.map(
|
|
1502
|
+
(p) => p.prefix !== "" ? p : new PathSpec({
|
|
1503
|
+
original: p.original,
|
|
1504
|
+
directory: p.directory,
|
|
1505
|
+
...p.pattern !== null ? { pattern: p.pattern } : {},
|
|
1506
|
+
resolved: p.resolved,
|
|
1507
|
+
prefix
|
|
1508
|
+
})
|
|
1509
|
+
) : paths;
|
|
1510
|
+
return resolveSSCholarPaperGlob(this.accessor, effective, this.index);
|
|
1511
|
+
}
|
|
1512
|
+
};
|
|
1513
|
+
|
|
1514
|
+
// src/resource/sscholar/author.ts
|
|
1515
|
+
import {
|
|
1516
|
+
HttpSSCholarDriver as HttpSSCholarDriver2,
|
|
1517
|
+
PathSpec as PathSpec2,
|
|
1518
|
+
RAMIndexCacheStore as RAMIndexCacheStore2,
|
|
1519
|
+
ResourceName as ResourceName2,
|
|
1520
|
+
SSCHOLAR_AUTHOR_COMMANDS,
|
|
1521
|
+
SSCHOLAR_AUTHOR_OPS,
|
|
1522
|
+
SSCHOLAR_AUTHOR_PROMPT,
|
|
1523
|
+
SSCholarAccessor as SSCholarAccessor2,
|
|
1524
|
+
resolveSSCholarAuthorGlob,
|
|
1525
|
+
resolveSSCholarConfig as resolveSSCholarConfig2,
|
|
1526
|
+
sscholarAuthorRead,
|
|
1527
|
+
sscholarAuthorReaddir,
|
|
1528
|
+
sscholarAuthorStat
|
|
1529
|
+
} from "@struktoai/mirage-core";
|
|
1530
|
+
var SSCholarAuthorResource = class {
|
|
1531
|
+
kind = ResourceName2.SSCHOLAR_AUTHOR;
|
|
1532
|
+
isRemote = true;
|
|
1533
|
+
indexTtl = 0;
|
|
1534
|
+
prompt;
|
|
1535
|
+
config;
|
|
1536
|
+
driver;
|
|
1537
|
+
accessor;
|
|
1538
|
+
index;
|
|
1539
|
+
constructor(options = {}) {
|
|
1540
|
+
const opts = "config" in options || "driver" in options || "prefix" in options ? options : { config: options };
|
|
1541
|
+
this.config = resolveSSCholarConfig2(opts.config ?? {});
|
|
1542
|
+
this.driver = opts.driver ?? new HttpSSCholarDriver2({ baseUrl: this.config.baseUrl, apiKey: this.config.apiKey });
|
|
1543
|
+
this.accessor = new SSCholarAccessor2(this.driver, this.config);
|
|
1544
|
+
this.index = new RAMIndexCacheStore2({ ttl: this.indexTtl });
|
|
1545
|
+
this.prompt = SSCHOLAR_AUTHOR_PROMPT.replace("{prefix}", opts.prefix ?? "");
|
|
1546
|
+
}
|
|
1547
|
+
open() {
|
|
1548
|
+
return Promise.resolve();
|
|
1549
|
+
}
|
|
1550
|
+
async close() {
|
|
1551
|
+
await this.driver.close();
|
|
1552
|
+
}
|
|
1553
|
+
ops() {
|
|
1554
|
+
return SSCHOLAR_AUTHOR_OPS;
|
|
1555
|
+
}
|
|
1556
|
+
commands() {
|
|
1557
|
+
return SSCHOLAR_AUTHOR_COMMANDS;
|
|
1558
|
+
}
|
|
1559
|
+
readFile(p) {
|
|
1560
|
+
return sscholarAuthorRead(this.accessor, p, this.index);
|
|
1561
|
+
}
|
|
1562
|
+
readdir(p) {
|
|
1563
|
+
return sscholarAuthorReaddir(this.accessor, p, this.index);
|
|
1564
|
+
}
|
|
1565
|
+
stat(p) {
|
|
1566
|
+
return sscholarAuthorStat(this.accessor, p, this.index);
|
|
1567
|
+
}
|
|
1568
|
+
glob(paths, prefix = "") {
|
|
1569
|
+
const effective = prefix !== "" ? paths.map(
|
|
1570
|
+
(p) => p.prefix !== "" ? p : new PathSpec2({
|
|
1571
|
+
original: p.original,
|
|
1572
|
+
directory: p.directory,
|
|
1573
|
+
...p.pattern !== null ? { pattern: p.pattern } : {},
|
|
1574
|
+
resolved: p.resolved,
|
|
1575
|
+
prefix
|
|
1576
|
+
})
|
|
1577
|
+
) : paths;
|
|
1578
|
+
return resolveSSCholarAuthorGlob(this.accessor, effective, this.index);
|
|
1579
|
+
}
|
|
1580
|
+
};
|
|
1581
|
+
|
|
1582
|
+
// src/resource/vercel/vercel.ts
|
|
1583
|
+
import {
|
|
1584
|
+
HttpVercelDriver,
|
|
1585
|
+
PathSpec as PathSpec3,
|
|
1586
|
+
RAMIndexCacheStore as RAMIndexCacheStore3,
|
|
1587
|
+
ResourceName as ResourceName3,
|
|
1588
|
+
VERCEL_COMMANDS,
|
|
1589
|
+
VERCEL_OPS,
|
|
1590
|
+
VERCEL_PROMPT,
|
|
1591
|
+
VercelAccessor,
|
|
1592
|
+
resolveVercelConfig,
|
|
1593
|
+
resolveVercelGlob,
|
|
1594
|
+
vercelRead,
|
|
1595
|
+
vercelReaddir,
|
|
1596
|
+
vercelStat
|
|
1597
|
+
} from "@struktoai/mirage-core";
|
|
1598
|
+
var VercelResource = class {
|
|
1599
|
+
kind = ResourceName3.VERCEL;
|
|
1600
|
+
isRemote = true;
|
|
1601
|
+
indexTtl = 60;
|
|
1602
|
+
prompt;
|
|
1603
|
+
config;
|
|
1604
|
+
driver;
|
|
1605
|
+
accessor;
|
|
1606
|
+
index;
|
|
1607
|
+
constructor(options = {}) {
|
|
1608
|
+
const opts = "config" in options || "driver" in options || "prefix" in options ? options : { config: options };
|
|
1609
|
+
this.config = resolveVercelConfig(opts.config ?? {});
|
|
1610
|
+
this.driver = opts.driver ?? new HttpVercelDriver({
|
|
1611
|
+
baseUrl: this.config.baseUrl,
|
|
1612
|
+
token: this.config.token,
|
|
1613
|
+
teamId: this.config.teamId
|
|
1614
|
+
});
|
|
1615
|
+
this.accessor = new VercelAccessor(this.driver, this.config);
|
|
1616
|
+
this.index = new RAMIndexCacheStore3({ ttl: this.indexTtl });
|
|
1617
|
+
this.prompt = VERCEL_PROMPT.replace("{prefix}", opts.prefix ?? "");
|
|
1618
|
+
}
|
|
1619
|
+
open() {
|
|
1620
|
+
return Promise.resolve();
|
|
1621
|
+
}
|
|
1622
|
+
async close() {
|
|
1623
|
+
await this.driver.close();
|
|
1624
|
+
}
|
|
1625
|
+
ops() {
|
|
1626
|
+
return VERCEL_OPS;
|
|
1627
|
+
}
|
|
1628
|
+
commands() {
|
|
1629
|
+
return VERCEL_COMMANDS;
|
|
1630
|
+
}
|
|
1631
|
+
readFile(p) {
|
|
1632
|
+
return vercelRead(this.accessor, p, this.index);
|
|
1633
|
+
}
|
|
1634
|
+
readdir(p) {
|
|
1635
|
+
return vercelReaddir(this.accessor, p, this.index);
|
|
1636
|
+
}
|
|
1637
|
+
stat(p) {
|
|
1638
|
+
return vercelStat(this.accessor, p, this.index);
|
|
1639
|
+
}
|
|
1640
|
+
glob(paths, prefix = "") {
|
|
1641
|
+
const effective = prefix !== "" ? paths.map(
|
|
1642
|
+
(p) => p.prefix !== "" ? p : new PathSpec3({
|
|
1643
|
+
original: p.original,
|
|
1644
|
+
directory: p.directory,
|
|
1645
|
+
...p.pattern !== null ? { pattern: p.pattern } : {},
|
|
1646
|
+
resolved: p.resolved,
|
|
1647
|
+
prefix
|
|
1648
|
+
})
|
|
1649
|
+
) : paths;
|
|
1650
|
+
return resolveVercelGlob(this.accessor, effective, this.index);
|
|
1651
|
+
}
|
|
1652
|
+
};
|
|
1653
|
+
|
|
1654
|
+
// src/resource/posthog/posthog.ts
|
|
1655
|
+
import {
|
|
1656
|
+
HttpPostHogDriver,
|
|
1657
|
+
PathSpec as PathSpec4,
|
|
1658
|
+
RAMIndexCacheStore as RAMIndexCacheStore4,
|
|
1659
|
+
ResourceName as ResourceName4,
|
|
1660
|
+
POSTHOG_COMMANDS,
|
|
1661
|
+
POSTHOG_OPS,
|
|
1662
|
+
POSTHOG_PROMPT,
|
|
1663
|
+
PostHogAccessor,
|
|
1664
|
+
posthogRead,
|
|
1665
|
+
posthogReaddir,
|
|
1666
|
+
posthogStat,
|
|
1667
|
+
resolvePostHogConfig,
|
|
1668
|
+
resolvePostHogGlob
|
|
1669
|
+
} from "@struktoai/mirage-core";
|
|
1670
|
+
var PostHogResource = class {
|
|
1671
|
+
kind = ResourceName4.POSTHOG;
|
|
1672
|
+
isRemote = true;
|
|
1673
|
+
indexTtl = 60;
|
|
1674
|
+
prompt;
|
|
1675
|
+
config;
|
|
1676
|
+
driver;
|
|
1677
|
+
accessor;
|
|
1678
|
+
index;
|
|
1679
|
+
constructor(options = {}) {
|
|
1680
|
+
const opts = "config" in options || "driver" in options || "prefix" in options ? options : { config: options };
|
|
1681
|
+
this.config = resolvePostHogConfig(opts.config ?? {});
|
|
1682
|
+
this.driver = opts.driver ?? new HttpPostHogDriver({ baseUrl: this.config.baseUrl, apiKey: this.config.apiKey });
|
|
1683
|
+
this.accessor = new PostHogAccessor(this.driver, this.config);
|
|
1684
|
+
this.index = new RAMIndexCacheStore4({ ttl: this.indexTtl });
|
|
1685
|
+
this.prompt = POSTHOG_PROMPT.replace("{prefix}", opts.prefix ?? "");
|
|
1686
|
+
}
|
|
1687
|
+
open() {
|
|
1688
|
+
return Promise.resolve();
|
|
1689
|
+
}
|
|
1690
|
+
async close() {
|
|
1691
|
+
await this.driver.close();
|
|
1692
|
+
}
|
|
1693
|
+
ops() {
|
|
1694
|
+
return POSTHOG_OPS;
|
|
1695
|
+
}
|
|
1696
|
+
commands() {
|
|
1697
|
+
return POSTHOG_COMMANDS;
|
|
1698
|
+
}
|
|
1699
|
+
readFile(p) {
|
|
1700
|
+
return posthogRead(this.accessor, p, this.index);
|
|
1701
|
+
}
|
|
1702
|
+
readdir(p) {
|
|
1703
|
+
return posthogReaddir(this.accessor, p, this.index);
|
|
1704
|
+
}
|
|
1705
|
+
stat(p) {
|
|
1706
|
+
return posthogStat(this.accessor, p, this.index);
|
|
1707
|
+
}
|
|
1708
|
+
glob(paths, prefix = "") {
|
|
1709
|
+
const effective = prefix !== "" ? paths.map(
|
|
1710
|
+
(p) => p.prefix !== "" ? p : new PathSpec4({
|
|
1711
|
+
original: p.original,
|
|
1712
|
+
directory: p.directory,
|
|
1713
|
+
...p.pattern !== null ? { pattern: p.pattern } : {},
|
|
1714
|
+
resolved: p.resolved,
|
|
1715
|
+
prefix
|
|
1716
|
+
})
|
|
1717
|
+
) : paths;
|
|
1718
|
+
return resolvePostHogGlob(this.accessor, effective, this.index);
|
|
1719
|
+
}
|
|
1720
|
+
};
|
|
1721
|
+
|
|
1722
|
+
// src/resource/registry.ts
|
|
1723
|
+
import { normalizeFields } from "@struktoai/mirage-core";
|
|
1724
|
+
var REGISTRY = {
|
|
1725
|
+
ram: async (_config2) => {
|
|
1726
|
+
const { RAMResource } = await import("@struktoai/mirage-core");
|
|
1727
|
+
return new RAMResource();
|
|
1728
|
+
},
|
|
1729
|
+
disk: async (config) => {
|
|
1730
|
+
const { DiskResource: DiskResource2 } = await import("./disk-C7TJNU2B.js");
|
|
1731
|
+
const norm2 = normalizeFields(config);
|
|
1732
|
+
return new DiskResource2(norm2);
|
|
1733
|
+
},
|
|
1734
|
+
redis: async (config) => {
|
|
1735
|
+
const { RedisResource: RedisResource2 } = await import("./redis-NVCXUUIO.js");
|
|
1736
|
+
const norm2 = normalizeFields(config);
|
|
1737
|
+
return new RedisResource2(norm2);
|
|
1738
|
+
},
|
|
1739
|
+
s3: async (config) => {
|
|
1740
|
+
const { S3Resource: S3Resource2 } = await import("./s3-HVAL7ZX3.js");
|
|
1741
|
+
const { normalizeS3Config } = await import("./config-ZZGIWDUC.js");
|
|
1742
|
+
return new S3Resource2(normalizeS3Config(config));
|
|
1743
|
+
},
|
|
1744
|
+
gcs: async (config) => {
|
|
1745
|
+
const { GCSResource: GCSResource2 } = await import("./gcs-P5QMKTPR.js");
|
|
1746
|
+
const { normalizeGcsConfig } = await import("./config-HIZHA5VD.js");
|
|
1747
|
+
return new GCSResource2(normalizeGcsConfig(config));
|
|
1748
|
+
},
|
|
1749
|
+
oci: async (config) => {
|
|
1750
|
+
const { OCIResource: OCIResource2 } = await import("./oci-KZ7XFZ2X.js");
|
|
1751
|
+
const { normalizeOciConfig } = await import("./config-UKZ72IDO.js");
|
|
1752
|
+
return new OCIResource2(normalizeOciConfig(config));
|
|
1753
|
+
},
|
|
1754
|
+
r2: async (config) => {
|
|
1755
|
+
const { R2Resource: R2Resource2 } = await import("./r2-X4DDNSAZ.js");
|
|
1756
|
+
const { normalizeR2Config } = await import("./config-S47UDVRZ.js");
|
|
1757
|
+
return new R2Resource2(normalizeR2Config(config));
|
|
1758
|
+
},
|
|
1759
|
+
supabase: async (config) => {
|
|
1760
|
+
const { SupabaseResource: SupabaseResource2 } = await import("./supabase-H3ZP4Y3W.js");
|
|
1761
|
+
const { normalizeSupabaseConfig } = await import("./config-5ZPGISS6.js");
|
|
1762
|
+
return new SupabaseResource2(normalizeSupabaseConfig(config));
|
|
1763
|
+
},
|
|
1764
|
+
postgres: async (config) => {
|
|
1765
|
+
const { PostgresResource: PostgresResource2 } = await import("./postgres-M2N2APFZ.js");
|
|
1766
|
+
const { normalizePostgresConfig } = await import("@struktoai/mirage-core");
|
|
1767
|
+
return new PostgresResource2(normalizePostgresConfig(config));
|
|
1768
|
+
},
|
|
1769
|
+
mongodb: async (config) => {
|
|
1770
|
+
const { MongoDBResource: MongoDBResource2 } = await import("./mongodb-MK4DVSIK.js");
|
|
1771
|
+
const { normalizeMongoDBConfig } = await import("@struktoai/mirage-core");
|
|
1772
|
+
return new MongoDBResource2(normalizeMongoDBConfig(config));
|
|
1773
|
+
},
|
|
1774
|
+
slack: async (config) => {
|
|
1775
|
+
const { SlackResource: SlackResource2 } = await import("./slack-GUQMDGLP.js");
|
|
1776
|
+
const { normalizeSlackConfig: normalizeSlackConfig2 } = await import("./config-YLIX3ZBT.js");
|
|
1777
|
+
return new SlackResource2(normalizeSlackConfig2(config));
|
|
1778
|
+
},
|
|
1779
|
+
ssh: async (config) => {
|
|
1780
|
+
const { SSHResource: SSHResource2 } = await import("./ssh-LY6WYVVD.js");
|
|
1781
|
+
const { normalizeSshConfig: normalizeSshConfig2 } = await import("./config-6TNFPYZF.js");
|
|
1782
|
+
return new SSHResource2(normalizeSshConfig2(config));
|
|
1783
|
+
},
|
|
1784
|
+
discord: async (config) => {
|
|
1785
|
+
const { DiscordResource: DiscordResource2 } = await import("./discord-2PWP2MGX.js");
|
|
1786
|
+
const { normalizeDiscordConfig: normalizeDiscordConfig2 } = await import("./config-ZCZZAH5W.js");
|
|
1787
|
+
return new DiscordResource2(normalizeDiscordConfig2(config));
|
|
1788
|
+
},
|
|
1789
|
+
trello: async (config) => {
|
|
1790
|
+
const { TrelloResource: TrelloResource2 } = await import("./trello-WR6TEDYD.js");
|
|
1791
|
+
const { normalizeTrelloConfig: normalizeTrelloConfig2 } = await import("./config-JXLZ4XEW.js");
|
|
1792
|
+
return new TrelloResource2(normalizeTrelloConfig2(config));
|
|
1793
|
+
},
|
|
1794
|
+
linear: async (config) => {
|
|
1795
|
+
const { LinearResource: LinearResource2 } = await import("./linear-WJDQ6JDE.js");
|
|
1796
|
+
const { normalizeLinearConfig: normalizeLinearConfig2 } = await import("./config-Z5JGDOKE.js");
|
|
1797
|
+
return new LinearResource2(normalizeLinearConfig2(config));
|
|
1798
|
+
},
|
|
1799
|
+
langfuse: async (config) => {
|
|
1800
|
+
const { LangfuseResource: LangfuseResource2 } = await import("./langfuse-YKBYRQLU.js");
|
|
1801
|
+
const { normalizeLangfuseConfig: normalizeLangfuseConfig2 } = await import("./config-MOLWOSRG.js");
|
|
1802
|
+
return new LangfuseResource2(normalizeLangfuseConfig2(config));
|
|
1803
|
+
},
|
|
1804
|
+
github: async (config) => {
|
|
1805
|
+
const { GitHubResource: GitHubResource2 } = await import("./github-5E6GSCNZ.js");
|
|
1806
|
+
const { normalizeGitHubConfig: normalizeGitHubConfig2 } = await import("./config-V7XI5UTG.js");
|
|
1807
|
+
return GitHubResource2.create(normalizeGitHubConfig2(config));
|
|
1808
|
+
},
|
|
1809
|
+
github_ci: async (config) => {
|
|
1810
|
+
const { GitHubCIResource: GitHubCIResource2 } = await import("./github_ci-2DSZI3Y7.js");
|
|
1811
|
+
const { normalizeGitHubCIConfig: normalizeGitHubCIConfig2 } = await import("./config-HNSDNQZH.js");
|
|
1812
|
+
return new GitHubCIResource2(normalizeGitHubCIConfig2(config));
|
|
1813
|
+
},
|
|
1814
|
+
gdocs: async (config) => {
|
|
1815
|
+
const { GDocsResource: GDocsResource2 } = await import("./gdocs-IF2I35HZ.js");
|
|
1816
|
+
const { normalizeGDocsConfig: normalizeGDocsConfig2 } = await import("./config-IXLFUSMQ.js");
|
|
1817
|
+
return new GDocsResource2(normalizeGDocsConfig2(config));
|
|
1818
|
+
},
|
|
1819
|
+
gsheets: async (config) => {
|
|
1820
|
+
const { GSheetsResource: GSheetsResource2 } = await import("./gsheets-BAO54CQ7.js");
|
|
1821
|
+
const { normalizeGSheetsConfig: normalizeGSheetsConfig2 } = await import("./config-KQCEMLNZ.js");
|
|
1822
|
+
return new GSheetsResource2(normalizeGSheetsConfig2(config));
|
|
1823
|
+
},
|
|
1824
|
+
gslides: async (config) => {
|
|
1825
|
+
const { GSlidesResource: GSlidesResource2 } = await import("./gslides-A62CEEMR.js");
|
|
1826
|
+
const { normalizeGSlidesConfig: normalizeGSlidesConfig2 } = await import("./config-BHLXQ3OL.js");
|
|
1827
|
+
return new GSlidesResource2(normalizeGSlidesConfig2(config));
|
|
1828
|
+
},
|
|
1829
|
+
gdrive: async (config) => {
|
|
1830
|
+
const { GDriveResource: GDriveResource2 } = await import("./gdrive-TAETVCKP.js");
|
|
1831
|
+
const { normalizeGDriveConfig: normalizeGDriveConfig2 } = await import("./config-E7UOEWEP.js");
|
|
1832
|
+
return new GDriveResource2(normalizeGDriveConfig2(config));
|
|
1833
|
+
},
|
|
1834
|
+
dropbox: async (config) => {
|
|
1835
|
+
const { DropboxResource: DropboxResource2 } = await import("./dropbox-L5DPYGKR.js");
|
|
1836
|
+
const { normalizeDropboxConfig: normalizeDropboxConfig2 } = await import("./config-R3XJ5OW4.js");
|
|
1837
|
+
return new DropboxResource2(normalizeDropboxConfig2(config));
|
|
1838
|
+
},
|
|
1839
|
+
box: async (config) => {
|
|
1840
|
+
const { BoxResource: BoxResource2 } = await import("./box-4P7DCJH7.js");
|
|
1841
|
+
const { normalizeBoxConfig: normalizeBoxConfig2 } = await import("./config-J3TM7NIS.js");
|
|
1842
|
+
return new BoxResource2(normalizeBoxConfig2(config));
|
|
1843
|
+
},
|
|
1844
|
+
gmail: async (config) => {
|
|
1845
|
+
const { GmailResource: GmailResource2 } = await import("./gmail-F5VYGKOT.js");
|
|
1846
|
+
const { normalizeGmailConfig: normalizeGmailConfig2 } = await import("./config-6HWSKHEU.js");
|
|
1847
|
+
return new GmailResource2(normalizeGmailConfig2(config));
|
|
1848
|
+
},
|
|
1849
|
+
email: async (config) => {
|
|
1850
|
+
const { EmailResource: EmailResource2 } = await import("./email-HASRFBKC.js");
|
|
1851
|
+
const { normalizeEmailConfig: normalizeEmailConfig2 } = await import("./config-FNR6LJ5H.js");
|
|
1852
|
+
return new EmailResource2(normalizeEmailConfig2(config));
|
|
1853
|
+
}
|
|
1854
|
+
};
|
|
1855
|
+
function knownResources() {
|
|
1856
|
+
return Object.keys(REGISTRY).sort();
|
|
1857
|
+
}
|
|
1858
|
+
function register(name, factory) {
|
|
1859
|
+
REGISTRY[name] = factory;
|
|
1860
|
+
}
|
|
1861
|
+
async function buildResource(name, config = {}) {
|
|
1862
|
+
const factory = REGISTRY[name];
|
|
1863
|
+
if (factory === void 0) {
|
|
1864
|
+
throw new Error(
|
|
1865
|
+
`unknown resource ${JSON.stringify(name)}; known: ${knownResources().join(", ")}`
|
|
1866
|
+
);
|
|
1867
|
+
}
|
|
1868
|
+
return factory(config);
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
// src/commands/local_audio/disk/cat_mp3.ts
|
|
1872
|
+
import {
|
|
1873
|
+
IOResult,
|
|
1874
|
+
ResourceName as ResourceName5,
|
|
1875
|
+
command,
|
|
1876
|
+
materialize,
|
|
1877
|
+
specOf
|
|
1878
|
+
} from "@struktoai/mirage-core";
|
|
1879
|
+
|
|
1880
|
+
// src/commands/local_audio/utils.ts
|
|
1881
|
+
import { createRequire as createRequire3 } from "module";
|
|
1882
|
+
import { join as join2 } from "path";
|
|
1883
|
+
import { parseBuffer } from "music-metadata";
|
|
1884
|
+
var _config = {};
|
|
1885
|
+
var ENC = new TextEncoder();
|
|
1886
|
+
var DEC = new TextDecoder();
|
|
1887
|
+
var _sherpa = null;
|
|
1888
|
+
var _wavefile = null;
|
|
1889
|
+
var _recognizer = null;
|
|
1890
|
+
var _loadedModelDir = null;
|
|
1891
|
+
var require2 = createRequire3(import.meta.url);
|
|
1892
|
+
function loadSherpa() {
|
|
1893
|
+
if (_sherpa !== null) return _sherpa;
|
|
1894
|
+
try {
|
|
1895
|
+
_sherpa = require2("sherpa-onnx-node");
|
|
1896
|
+
return _sherpa;
|
|
1897
|
+
} catch {
|
|
1898
|
+
throw new Error(
|
|
1899
|
+
"Audio transcription requires 'sherpa-onnx-node'. Install with: npm i sherpa-onnx-node (or pnpm/yarn add)."
|
|
1900
|
+
);
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
function loadWavefile() {
|
|
1904
|
+
if (_wavefile !== null) return _wavefile;
|
|
1905
|
+
try {
|
|
1906
|
+
_wavefile = require2("wavefile");
|
|
1907
|
+
return _wavefile;
|
|
1908
|
+
} catch {
|
|
1909
|
+
throw new Error(
|
|
1910
|
+
"Built-in WAV decoding requires 'wavefile'. Install with: npm i wavefile (or pass a custom recognizer via configure({ recognizer }) to skip it)."
|
|
1911
|
+
);
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
function getRecognizer(modelDir) {
|
|
1915
|
+
if (_recognizer !== null && _loadedModelDir === modelDir) return _recognizer;
|
|
1916
|
+
const sherpa = loadSherpa();
|
|
1917
|
+
_recognizer = new sherpa.OfflineRecognizer({
|
|
1918
|
+
featConfig: { sampleRate: 16e3, featureDim: 80 },
|
|
1919
|
+
modelConfig: {
|
|
1920
|
+
whisper: {
|
|
1921
|
+
encoder: join2(modelDir, "base-encoder.int8.onnx"),
|
|
1922
|
+
decoder: join2(modelDir, "base-decoder.int8.onnx")
|
|
1923
|
+
},
|
|
1924
|
+
tokens: join2(modelDir, "base-tokens.txt"),
|
|
1925
|
+
numThreads: 2,
|
|
1926
|
+
provider: "cpu"
|
|
1927
|
+
}
|
|
1928
|
+
});
|
|
1929
|
+
_loadedModelDir = modelDir;
|
|
1930
|
+
return _recognizer;
|
|
1931
|
+
}
|
|
1932
|
+
function configure(opts) {
|
|
1933
|
+
if (opts.modelDir !== void 0) _config.modelDir = opts.modelDir;
|
|
1934
|
+
if (opts.recognizer !== void 0) _config.recognizer = opts.recognizer;
|
|
1935
|
+
if (opts.modelDir !== void 0 && opts.modelDir !== _loadedModelDir) {
|
|
1936
|
+
_recognizer = null;
|
|
1937
|
+
_loadedModelDir = null;
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
function getConfig() {
|
|
1941
|
+
return _config;
|
|
1942
|
+
}
|
|
1943
|
+
async function* transcribe(raw, startSec, endSec) {
|
|
1944
|
+
if (_config.recognizer !== void 0) {
|
|
1945
|
+
for await (const chunk of _config.recognizer(raw, startSec, endSec)) {
|
|
1946
|
+
yield typeof chunk === "string" ? ENC.encode(chunk) : chunk;
|
|
1947
|
+
}
|
|
1948
|
+
return;
|
|
1949
|
+
}
|
|
1950
|
+
if (_config.modelDir !== void 0) {
|
|
1951
|
+
const isWav = raw.byteLength >= 12 && DEC.decode(raw.subarray(0, 4)) === "RIFF";
|
|
1952
|
+
if (!isWav) {
|
|
1953
|
+
throw new Error(
|
|
1954
|
+
"Built-in transcriber handles WAV only. For MP3/OGG/other, pass a custom transcriber via configure({ recognizer: (raw, startSec?, endSec?) => AsyncIterable<string | Uint8Array> })."
|
|
1955
|
+
);
|
|
1956
|
+
}
|
|
1957
|
+
const { WaveFile } = loadWavefile();
|
|
1958
|
+
const w = new WaveFile(raw);
|
|
1959
|
+
w.toSampleRate(16e3);
|
|
1960
|
+
w.toBitDepth("32f");
|
|
1961
|
+
let samples = w.getSamples(true, Float32Array);
|
|
1962
|
+
if (startSec !== void 0 || endSec !== void 0) {
|
|
1963
|
+
const s = Math.max(0, Math.floor((startSec ?? 0) * 16e3));
|
|
1964
|
+
const e = endSec !== void 0 ? Math.min(samples.length, Math.floor(endSec * 16e3)) : samples.length;
|
|
1965
|
+
samples = samples.subarray(s, e);
|
|
1966
|
+
}
|
|
1967
|
+
const recognizer = getRecognizer(_config.modelDir);
|
|
1968
|
+
const stream2 = recognizer.createStream();
|
|
1969
|
+
stream2.acceptWaveform({ sampleRate: 16e3, samples });
|
|
1970
|
+
const result = await recognizer.decodeAsync(stream2);
|
|
1971
|
+
const text = result.text.trim();
|
|
1972
|
+
if (text !== "") yield ENC.encode(`${text}
|
|
1973
|
+
`);
|
|
1974
|
+
return;
|
|
1975
|
+
}
|
|
1976
|
+
throw new Error(
|
|
1977
|
+
"Audio transcription not configured. Call configure({ modelDir }) to use the built-in sherpa-onnx+wavefile pipeline, or configure({ recognizer }) to plug your own."
|
|
1978
|
+
);
|
|
1979
|
+
}
|
|
1980
|
+
async function metadata(raw) {
|
|
1981
|
+
const parsed = await parseBuffer(raw, void 0, { duration: true });
|
|
1982
|
+
const f = parsed.format;
|
|
1983
|
+
return {
|
|
1984
|
+
duration: f.duration ?? null,
|
|
1985
|
+
sampleRate: f.sampleRate ?? null,
|
|
1986
|
+
channels: f.numberOfChannels ?? null,
|
|
1987
|
+
bitrate: f.bitrate !== void 0 ? f.bitrate / 1e3 : null
|
|
1988
|
+
};
|
|
1989
|
+
}
|
|
1990
|
+
function estimateByteRange(meta, fileSize, startSec, endSec) {
|
|
1991
|
+
const duration = meta.duration ?? 0;
|
|
1992
|
+
if (duration <= 0) return [0, fileSize];
|
|
1993
|
+
const start = startSec ?? 0;
|
|
1994
|
+
const end = endSec ?? duration;
|
|
1995
|
+
const ratioStart = Math.max(0, start / duration);
|
|
1996
|
+
const ratioEnd = Math.min(1, end / duration);
|
|
1997
|
+
return [Math.floor(ratioStart * fileSize), Math.floor(ratioEnd * fileSize)];
|
|
1998
|
+
}
|
|
1999
|
+
function formatDuration(duration) {
|
|
2000
|
+
const total = Math.floor(duration);
|
|
2001
|
+
const hours = Math.floor(total / 3600);
|
|
2002
|
+
const minutes = Math.floor(total % 3600 / 60);
|
|
2003
|
+
const seconds = total % 60;
|
|
2004
|
+
const mm = String(minutes).padStart(2, "0");
|
|
2005
|
+
const ss = String(seconds).padStart(2, "0");
|
|
2006
|
+
if (hours > 0) return `${String(hours)}:${mm}:${ss}`;
|
|
2007
|
+
return `${String(minutes)}:${ss}`;
|
|
2008
|
+
}
|
|
2009
|
+
function formatMetadata(meta, path, fileSize) {
|
|
2010
|
+
const lines = [`${path}:`];
|
|
2011
|
+
const { duration, sampleRate, channels, bitrate } = meta;
|
|
2012
|
+
if (duration !== null) lines.push(` Duration: ${formatDuration(duration)}`);
|
|
2013
|
+
else lines.push(" Duration: unknown");
|
|
2014
|
+
if (sampleRate !== null) lines.push(` Sample rate: ${String(Math.floor(sampleRate))} Hz`);
|
|
2015
|
+
if (channels !== null) {
|
|
2016
|
+
const ch = Math.floor(channels);
|
|
2017
|
+
const label = ch === 1 ? "mono" : ch === 2 ? "stereo" : `${String(ch)} channels`;
|
|
2018
|
+
lines.push(` Channels: ${String(ch)} (${label})`);
|
|
2019
|
+
}
|
|
2020
|
+
if (bitrate !== null) lines.push(` Bitrate: ${bitrate.toFixed(1)} kbps`);
|
|
2021
|
+
if (fileSize !== void 0 && fileSize !== null) {
|
|
2022
|
+
if (fileSize >= 1048576) lines.push(` File size: ${(fileSize / 1048576).toFixed(1)} MB`);
|
|
2023
|
+
else if (fileSize >= 1024) lines.push(` File size: ${(fileSize / 1024).toFixed(1)} KB`);
|
|
2024
|
+
else lines.push(` File size: ${String(fileSize)} B`);
|
|
2025
|
+
}
|
|
2026
|
+
return lines.join("\n");
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
// src/commands/local_audio/disk/cat_mp3.ts
|
|
2030
|
+
var ENC2 = new TextEncoder();
|
|
2031
|
+
async function catMp3Command(accessor, paths, _texts, _opts) {
|
|
2032
|
+
if (paths.length === 0) {
|
|
2033
|
+
return [null, new IOResult({ exitCode: 1, stderr: ENC2.encode("cat: missing operand\n") })];
|
|
2034
|
+
}
|
|
2035
|
+
const first = paths[0];
|
|
2036
|
+
if (first === void 0) return [null, new IOResult()];
|
|
2037
|
+
try {
|
|
2038
|
+
const raw = await materialize(stream(accessor, first));
|
|
2039
|
+
const out = transcribe(raw);
|
|
2040
|
+
return [out, new IOResult({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2041
|
+
} catch (err) {
|
|
2042
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2043
|
+
return [
|
|
2044
|
+
null,
|
|
2045
|
+
new IOResult({
|
|
2046
|
+
exitCode: 1,
|
|
2047
|
+
stderr: ENC2.encode(`cat: ${first.original}: failed to read as mp3: ${msg}
|
|
2048
|
+
`)
|
|
2049
|
+
})
|
|
2050
|
+
];
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
var DISK_LOCAL_AUDIO_CAT_MP3 = command({
|
|
2054
|
+
name: "cat",
|
|
2055
|
+
resource: ResourceName5.DISK,
|
|
2056
|
+
spec: specOf("cat"),
|
|
2057
|
+
filetype: ".mp3",
|
|
2058
|
+
fn: catMp3Command
|
|
2059
|
+
});
|
|
2060
|
+
|
|
2061
|
+
// src/commands/local_audio/disk/cat_ogg.ts
|
|
2062
|
+
import {
|
|
2063
|
+
IOResult as IOResult2,
|
|
2064
|
+
ResourceName as ResourceName6,
|
|
2065
|
+
command as command2,
|
|
2066
|
+
materialize as materialize2,
|
|
2067
|
+
specOf as specOf2
|
|
2068
|
+
} from "@struktoai/mirage-core";
|
|
2069
|
+
var ENC3 = new TextEncoder();
|
|
2070
|
+
async function catOggCommand(accessor, paths, _texts, _opts) {
|
|
2071
|
+
if (paths.length === 0) {
|
|
2072
|
+
return [null, new IOResult2({ exitCode: 1, stderr: ENC3.encode("cat: missing operand\n") })];
|
|
2073
|
+
}
|
|
2074
|
+
const first = paths[0];
|
|
2075
|
+
if (first === void 0) return [null, new IOResult2()];
|
|
2076
|
+
try {
|
|
2077
|
+
const raw = await materialize2(stream(accessor, first));
|
|
2078
|
+
const out = transcribe(raw);
|
|
2079
|
+
return [out, new IOResult2({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2080
|
+
} catch (err) {
|
|
2081
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2082
|
+
return [
|
|
2083
|
+
null,
|
|
2084
|
+
new IOResult2({
|
|
2085
|
+
exitCode: 1,
|
|
2086
|
+
stderr: ENC3.encode(`cat: ${first.original}: failed to read as ogg: ${msg}
|
|
2087
|
+
`)
|
|
2088
|
+
})
|
|
2089
|
+
];
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
var DISK_LOCAL_AUDIO_CAT_OGG = command2({
|
|
2093
|
+
name: "cat",
|
|
2094
|
+
resource: ResourceName6.DISK,
|
|
2095
|
+
spec: specOf2("cat"),
|
|
2096
|
+
filetype: ".ogg",
|
|
2097
|
+
fn: catOggCommand
|
|
2098
|
+
});
|
|
2099
|
+
|
|
2100
|
+
// src/commands/local_audio/disk/cat_wav.ts
|
|
2101
|
+
import {
|
|
2102
|
+
IOResult as IOResult3,
|
|
2103
|
+
ResourceName as ResourceName7,
|
|
2104
|
+
command as command3,
|
|
2105
|
+
materialize as materialize3,
|
|
2106
|
+
specOf as specOf3
|
|
2107
|
+
} from "@struktoai/mirage-core";
|
|
2108
|
+
var ENC4 = new TextEncoder();
|
|
2109
|
+
async function catWavCommand(accessor, paths, _texts, _opts) {
|
|
2110
|
+
if (paths.length === 0) {
|
|
2111
|
+
return [null, new IOResult3({ exitCode: 1, stderr: ENC4.encode("cat: missing operand\n") })];
|
|
2112
|
+
}
|
|
2113
|
+
const first = paths[0];
|
|
2114
|
+
if (first === void 0) return [null, new IOResult3()];
|
|
2115
|
+
try {
|
|
2116
|
+
const raw = await materialize3(stream(accessor, first));
|
|
2117
|
+
const out = transcribe(raw);
|
|
2118
|
+
return [out, new IOResult3({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2119
|
+
} catch (err) {
|
|
2120
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2121
|
+
return [
|
|
2122
|
+
null,
|
|
2123
|
+
new IOResult3({
|
|
2124
|
+
exitCode: 1,
|
|
2125
|
+
stderr: ENC4.encode(`cat: ${first.original}: failed to read as wav: ${msg}
|
|
2126
|
+
`)
|
|
2127
|
+
})
|
|
2128
|
+
];
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
var DISK_LOCAL_AUDIO_CAT_WAV = command3({
|
|
2132
|
+
name: "cat",
|
|
2133
|
+
resource: ResourceName7.DISK,
|
|
2134
|
+
spec: specOf3("cat"),
|
|
2135
|
+
filetype: ".wav",
|
|
2136
|
+
fn: catWavCommand
|
|
2137
|
+
});
|
|
2138
|
+
|
|
2139
|
+
// src/commands/local_audio/disk/grep_mp3.ts
|
|
2140
|
+
import {
|
|
2141
|
+
IOResult as IOResult4,
|
|
2142
|
+
ResourceName as ResourceName8,
|
|
2143
|
+
command as command4,
|
|
2144
|
+
materialize as materialize4,
|
|
2145
|
+
specOf as specOf4
|
|
2146
|
+
} from "@struktoai/mirage-core";
|
|
2147
|
+
var ENC5 = new TextEncoder();
|
|
2148
|
+
var DEC2 = new TextDecoder();
|
|
2149
|
+
async function grepMp3Command(accessor, paths, texts, opts) {
|
|
2150
|
+
if (paths.length === 0 || texts.length === 0) {
|
|
2151
|
+
return [null, new IOResult4({ exitCode: 1, stderr: ENC5.encode("grep: missing operand\n") })];
|
|
2152
|
+
}
|
|
2153
|
+
const first = paths[0];
|
|
2154
|
+
if (first === void 0) return [null, new IOResult4()];
|
|
2155
|
+
const pattern = texts[0] ?? "";
|
|
2156
|
+
const ignoreCase = opts.flags.i === true;
|
|
2157
|
+
try {
|
|
2158
|
+
const raw = await materialize4(stream(accessor, first));
|
|
2159
|
+
const text = DEC2.decode(await materialize4(transcribe(raw)));
|
|
2160
|
+
const flags = ignoreCase ? "i" : "";
|
|
2161
|
+
const re = new RegExp(pattern, flags);
|
|
2162
|
+
if (re.test(text)) {
|
|
2163
|
+
const out = ENC5.encode(text);
|
|
2164
|
+
return [out, new IOResult4({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2165
|
+
}
|
|
2166
|
+
return [
|
|
2167
|
+
null,
|
|
2168
|
+
new IOResult4({
|
|
2169
|
+
exitCode: 1,
|
|
2170
|
+
reads: { [first.original]: raw },
|
|
2171
|
+
cache: [first.original]
|
|
2172
|
+
})
|
|
2173
|
+
];
|
|
2174
|
+
} catch (err) {
|
|
2175
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2176
|
+
return [
|
|
2177
|
+
null,
|
|
2178
|
+
new IOResult4({
|
|
2179
|
+
exitCode: 1,
|
|
2180
|
+
stderr: ENC5.encode(`grep: ${first.original}: failed to read as mp3: ${msg}
|
|
2181
|
+
`)
|
|
2182
|
+
})
|
|
2183
|
+
];
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
var DISK_LOCAL_AUDIO_GREP_MP3 = command4({
|
|
2187
|
+
name: "grep",
|
|
2188
|
+
resource: ResourceName8.DISK,
|
|
2189
|
+
spec: specOf4("grep"),
|
|
2190
|
+
filetype: ".mp3",
|
|
2191
|
+
fn: grepMp3Command
|
|
2192
|
+
});
|
|
2193
|
+
|
|
2194
|
+
// src/commands/local_audio/disk/grep_ogg.ts
|
|
2195
|
+
import {
|
|
2196
|
+
IOResult as IOResult5,
|
|
2197
|
+
ResourceName as ResourceName9,
|
|
2198
|
+
command as command5,
|
|
2199
|
+
materialize as materialize5,
|
|
2200
|
+
specOf as specOf5
|
|
2201
|
+
} from "@struktoai/mirage-core";
|
|
2202
|
+
var ENC6 = new TextEncoder();
|
|
2203
|
+
var DEC3 = new TextDecoder();
|
|
2204
|
+
async function grepOggCommand(accessor, paths, texts, opts) {
|
|
2205
|
+
if (paths.length === 0 || texts.length === 0) {
|
|
2206
|
+
return [null, new IOResult5({ exitCode: 1, stderr: ENC6.encode("grep: missing operand\n") })];
|
|
2207
|
+
}
|
|
2208
|
+
const first = paths[0];
|
|
2209
|
+
if (first === void 0) return [null, new IOResult5()];
|
|
2210
|
+
const pattern = texts[0] ?? "";
|
|
2211
|
+
const ignoreCase = opts.flags.i === true;
|
|
2212
|
+
try {
|
|
2213
|
+
const raw = await materialize5(stream(accessor, first));
|
|
2214
|
+
const text = DEC3.decode(await materialize5(transcribe(raw)));
|
|
2215
|
+
const flags = ignoreCase ? "i" : "";
|
|
2216
|
+
const re = new RegExp(pattern, flags);
|
|
2217
|
+
if (re.test(text)) {
|
|
2218
|
+
const out = ENC6.encode(text);
|
|
2219
|
+
return [out, new IOResult5({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2220
|
+
}
|
|
2221
|
+
return [
|
|
2222
|
+
null,
|
|
2223
|
+
new IOResult5({
|
|
2224
|
+
exitCode: 1,
|
|
2225
|
+
reads: { [first.original]: raw },
|
|
2226
|
+
cache: [first.original]
|
|
2227
|
+
})
|
|
2228
|
+
];
|
|
2229
|
+
} catch (err) {
|
|
2230
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2231
|
+
return [
|
|
2232
|
+
null,
|
|
2233
|
+
new IOResult5({
|
|
2234
|
+
exitCode: 1,
|
|
2235
|
+
stderr: ENC6.encode(`grep: ${first.original}: failed to read as ogg: ${msg}
|
|
2236
|
+
`)
|
|
2237
|
+
})
|
|
2238
|
+
];
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
var DISK_LOCAL_AUDIO_GREP_OGG = command5({
|
|
2242
|
+
name: "grep",
|
|
2243
|
+
resource: ResourceName9.DISK,
|
|
2244
|
+
spec: specOf5("grep"),
|
|
2245
|
+
filetype: ".ogg",
|
|
2246
|
+
fn: grepOggCommand
|
|
2247
|
+
});
|
|
2248
|
+
|
|
2249
|
+
// src/commands/local_audio/disk/grep_wav.ts
|
|
2250
|
+
import {
|
|
2251
|
+
IOResult as IOResult6,
|
|
2252
|
+
ResourceName as ResourceName10,
|
|
2253
|
+
command as command6,
|
|
2254
|
+
materialize as materialize6,
|
|
2255
|
+
specOf as specOf6
|
|
2256
|
+
} from "@struktoai/mirage-core";
|
|
2257
|
+
var ENC7 = new TextEncoder();
|
|
2258
|
+
var DEC4 = new TextDecoder();
|
|
2259
|
+
async function grepWavCommand(accessor, paths, texts, opts) {
|
|
2260
|
+
if (paths.length === 0 || texts.length === 0) {
|
|
2261
|
+
return [null, new IOResult6({ exitCode: 1, stderr: ENC7.encode("grep: missing operand\n") })];
|
|
2262
|
+
}
|
|
2263
|
+
const first = paths[0];
|
|
2264
|
+
if (first === void 0) return [null, new IOResult6()];
|
|
2265
|
+
const pattern = texts[0] ?? "";
|
|
2266
|
+
const ignoreCase = opts.flags.i === true;
|
|
2267
|
+
try {
|
|
2268
|
+
const raw = await materialize6(stream(accessor, first));
|
|
2269
|
+
const text = DEC4.decode(await materialize6(transcribe(raw)));
|
|
2270
|
+
const flags = ignoreCase ? "i" : "";
|
|
2271
|
+
const re = new RegExp(pattern, flags);
|
|
2272
|
+
if (re.test(text)) {
|
|
2273
|
+
const out = ENC7.encode(text);
|
|
2274
|
+
return [out, new IOResult6({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2275
|
+
}
|
|
2276
|
+
return [
|
|
2277
|
+
null,
|
|
2278
|
+
new IOResult6({
|
|
2279
|
+
exitCode: 1,
|
|
2280
|
+
reads: { [first.original]: raw },
|
|
2281
|
+
cache: [first.original]
|
|
2282
|
+
})
|
|
2283
|
+
];
|
|
2284
|
+
} catch (err) {
|
|
2285
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2286
|
+
return [
|
|
2287
|
+
null,
|
|
2288
|
+
new IOResult6({
|
|
2289
|
+
exitCode: 1,
|
|
2290
|
+
stderr: ENC7.encode(`grep: ${first.original}: failed to read as wav: ${msg}
|
|
2291
|
+
`)
|
|
2292
|
+
})
|
|
2293
|
+
];
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
var DISK_LOCAL_AUDIO_GREP_WAV = command6({
|
|
2297
|
+
name: "grep",
|
|
2298
|
+
resource: ResourceName10.DISK,
|
|
2299
|
+
spec: specOf6("grep"),
|
|
2300
|
+
filetype: ".wav",
|
|
2301
|
+
fn: grepWavCommand
|
|
2302
|
+
});
|
|
2303
|
+
|
|
2304
|
+
// src/commands/local_audio/disk/head_mp3.ts
|
|
2305
|
+
import {
|
|
2306
|
+
IOResult as IOResult7,
|
|
2307
|
+
ResourceName as ResourceName11,
|
|
2308
|
+
command as command7,
|
|
2309
|
+
materialize as materialize7,
|
|
2310
|
+
specOf as specOf7
|
|
2311
|
+
} from "@struktoai/mirage-core";
|
|
2312
|
+
var ENC8 = new TextEncoder();
|
|
2313
|
+
async function headMp3Command(accessor, paths, _texts, opts) {
|
|
2314
|
+
if (paths.length === 0) {
|
|
2315
|
+
return [null, new IOResult7({ exitCode: 1, stderr: ENC8.encode("head: missing operand\n") })];
|
|
2316
|
+
}
|
|
2317
|
+
const first = paths[0];
|
|
2318
|
+
if (first === void 0) return [null, new IOResult7()];
|
|
2319
|
+
if (typeof opts.flags.c === "string") {
|
|
2320
|
+
return [
|
|
2321
|
+
null,
|
|
2322
|
+
new IOResult7({ exitCode: 1, stderr: ENC8.encode("head: -c not supported for audio files\n") })
|
|
2323
|
+
];
|
|
2324
|
+
}
|
|
2325
|
+
const n = typeof opts.flags.n === "string" ? Number.parseInt(opts.flags.n, 10) : 10;
|
|
2326
|
+
try {
|
|
2327
|
+
const raw = await materialize7(stream(accessor, first));
|
|
2328
|
+
const out = transcribe(raw, void 0, n);
|
|
2329
|
+
return [out, new IOResult7({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2330
|
+
} catch (err) {
|
|
2331
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2332
|
+
return [
|
|
2333
|
+
null,
|
|
2334
|
+
new IOResult7({
|
|
2335
|
+
exitCode: 1,
|
|
2336
|
+
stderr: ENC8.encode(`head: ${first.original}: failed to read as mp3: ${msg}
|
|
2337
|
+
`)
|
|
2338
|
+
})
|
|
2339
|
+
];
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
var DISK_LOCAL_AUDIO_HEAD_MP3 = command7({
|
|
2343
|
+
name: "head",
|
|
2344
|
+
resource: ResourceName11.DISK,
|
|
2345
|
+
spec: specOf7("head"),
|
|
2346
|
+
filetype: ".mp3",
|
|
2347
|
+
fn: headMp3Command
|
|
2348
|
+
});
|
|
2349
|
+
|
|
2350
|
+
// src/commands/local_audio/disk/head_ogg.ts
|
|
2351
|
+
import {
|
|
2352
|
+
IOResult as IOResult8,
|
|
2353
|
+
ResourceName as ResourceName12,
|
|
2354
|
+
command as command8,
|
|
2355
|
+
materialize as materialize8,
|
|
2356
|
+
specOf as specOf8
|
|
2357
|
+
} from "@struktoai/mirage-core";
|
|
2358
|
+
var ENC9 = new TextEncoder();
|
|
2359
|
+
async function headOggCommand(accessor, paths, _texts, opts) {
|
|
2360
|
+
if (paths.length === 0) {
|
|
2361
|
+
return [null, new IOResult8({ exitCode: 1, stderr: ENC9.encode("head: missing operand\n") })];
|
|
2362
|
+
}
|
|
2363
|
+
const first = paths[0];
|
|
2364
|
+
if (first === void 0) return [null, new IOResult8()];
|
|
2365
|
+
if (typeof opts.flags.c === "string") {
|
|
2366
|
+
return [
|
|
2367
|
+
null,
|
|
2368
|
+
new IOResult8({ exitCode: 1, stderr: ENC9.encode("head: -c not supported for audio files\n") })
|
|
2369
|
+
];
|
|
2370
|
+
}
|
|
2371
|
+
const n = typeof opts.flags.n === "string" ? Number.parseInt(opts.flags.n, 10) : 10;
|
|
2372
|
+
try {
|
|
2373
|
+
const raw = await materialize8(stream(accessor, first));
|
|
2374
|
+
const out = transcribe(raw, void 0, n);
|
|
2375
|
+
return [out, new IOResult8({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2376
|
+
} catch (err) {
|
|
2377
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2378
|
+
return [
|
|
2379
|
+
null,
|
|
2380
|
+
new IOResult8({
|
|
2381
|
+
exitCode: 1,
|
|
2382
|
+
stderr: ENC9.encode(`head: ${first.original}: failed to read as ogg: ${msg}
|
|
2383
|
+
`)
|
|
2384
|
+
})
|
|
2385
|
+
];
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
2388
|
+
var DISK_LOCAL_AUDIO_HEAD_OGG = command8({
|
|
2389
|
+
name: "head",
|
|
2390
|
+
resource: ResourceName12.DISK,
|
|
2391
|
+
spec: specOf8("head"),
|
|
2392
|
+
filetype: ".ogg",
|
|
2393
|
+
fn: headOggCommand
|
|
2394
|
+
});
|
|
2395
|
+
|
|
2396
|
+
// src/commands/local_audio/disk/head_wav.ts
|
|
2397
|
+
import {
|
|
2398
|
+
IOResult as IOResult9,
|
|
2399
|
+
ResourceName as ResourceName13,
|
|
2400
|
+
command as command9,
|
|
2401
|
+
materialize as materialize9,
|
|
2402
|
+
specOf as specOf9
|
|
2403
|
+
} from "@struktoai/mirage-core";
|
|
2404
|
+
var ENC10 = new TextEncoder();
|
|
2405
|
+
async function headWavCommand(accessor, paths, _texts, opts) {
|
|
2406
|
+
if (paths.length === 0) {
|
|
2407
|
+
return [null, new IOResult9({ exitCode: 1, stderr: ENC10.encode("head: missing operand\n") })];
|
|
2408
|
+
}
|
|
2409
|
+
const first = paths[0];
|
|
2410
|
+
if (first === void 0) return [null, new IOResult9()];
|
|
2411
|
+
if (typeof opts.flags.c === "string") {
|
|
2412
|
+
return [
|
|
2413
|
+
null,
|
|
2414
|
+
new IOResult9({ exitCode: 1, stderr: ENC10.encode("head: -c not supported for audio files\n") })
|
|
2415
|
+
];
|
|
2416
|
+
}
|
|
2417
|
+
const n = typeof opts.flags.n === "string" ? Number.parseInt(opts.flags.n, 10) : 10;
|
|
2418
|
+
try {
|
|
2419
|
+
const raw = await materialize9(stream(accessor, first));
|
|
2420
|
+
const out = transcribe(raw, void 0, n);
|
|
2421
|
+
return [out, new IOResult9({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2422
|
+
} catch (err) {
|
|
2423
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2424
|
+
return [
|
|
2425
|
+
null,
|
|
2426
|
+
new IOResult9({
|
|
2427
|
+
exitCode: 1,
|
|
2428
|
+
stderr: ENC10.encode(`head: ${first.original}: failed to read as wav: ${msg}
|
|
2429
|
+
`)
|
|
2430
|
+
})
|
|
2431
|
+
];
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
var DISK_LOCAL_AUDIO_HEAD_WAV = command9({
|
|
2435
|
+
name: "head",
|
|
2436
|
+
resource: ResourceName13.DISK,
|
|
2437
|
+
spec: specOf9("head"),
|
|
2438
|
+
filetype: ".wav",
|
|
2439
|
+
fn: headWavCommand
|
|
2440
|
+
});
|
|
2441
|
+
|
|
2442
|
+
// src/commands/local_audio/disk/stat_mp3.ts
|
|
2443
|
+
import {
|
|
2444
|
+
IOResult as IOResult10,
|
|
2445
|
+
ResourceName as ResourceName14,
|
|
2446
|
+
command as command10,
|
|
2447
|
+
materialize as materialize10,
|
|
2448
|
+
specOf as specOf10
|
|
2449
|
+
} from "@struktoai/mirage-core";
|
|
2450
|
+
var ENC11 = new TextEncoder();
|
|
2451
|
+
async function statMp3Command(accessor, paths, _texts, _opts) {
|
|
2452
|
+
if (paths.length === 0) {
|
|
2453
|
+
return [null, new IOResult10({ exitCode: 1, stderr: ENC11.encode("stat: missing operand\n") })];
|
|
2454
|
+
}
|
|
2455
|
+
const first = paths[0];
|
|
2456
|
+
if (first === void 0) return [null, new IOResult10()];
|
|
2457
|
+
try {
|
|
2458
|
+
const raw = await materialize10(stream(accessor, first));
|
|
2459
|
+
const meta = await metadata(raw);
|
|
2460
|
+
const fs2 = await stat(accessor, first);
|
|
2461
|
+
const out = ENC11.encode(formatMetadata(meta, first.original, fs2.size ?? null));
|
|
2462
|
+
return [out, new IOResult10({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2463
|
+
} catch (err) {
|
|
2464
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2465
|
+
return [
|
|
2466
|
+
null,
|
|
2467
|
+
new IOResult10({
|
|
2468
|
+
exitCode: 1,
|
|
2469
|
+
stderr: ENC11.encode(`stat: ${first.original}: failed to read as mp3: ${msg}
|
|
2470
|
+
`)
|
|
2471
|
+
})
|
|
2472
|
+
];
|
|
2473
|
+
}
|
|
2474
|
+
}
|
|
2475
|
+
var DISK_LOCAL_AUDIO_STAT_MP3 = command10({
|
|
2476
|
+
name: "stat",
|
|
2477
|
+
resource: ResourceName14.DISK,
|
|
2478
|
+
spec: specOf10("stat"),
|
|
2479
|
+
filetype: ".mp3",
|
|
2480
|
+
fn: statMp3Command
|
|
2481
|
+
});
|
|
2482
|
+
|
|
2483
|
+
// src/commands/local_audio/disk/stat_ogg.ts
|
|
2484
|
+
import {
|
|
2485
|
+
IOResult as IOResult11,
|
|
2486
|
+
ResourceName as ResourceName15,
|
|
2487
|
+
command as command11,
|
|
2488
|
+
materialize as materialize11,
|
|
2489
|
+
specOf as specOf11
|
|
2490
|
+
} from "@struktoai/mirage-core";
|
|
2491
|
+
var ENC12 = new TextEncoder();
|
|
2492
|
+
async function statOggCommand(accessor, paths, _texts, _opts) {
|
|
2493
|
+
if (paths.length === 0) {
|
|
2494
|
+
return [null, new IOResult11({ exitCode: 1, stderr: ENC12.encode("stat: missing operand\n") })];
|
|
2495
|
+
}
|
|
2496
|
+
const first = paths[0];
|
|
2497
|
+
if (first === void 0) return [null, new IOResult11()];
|
|
2498
|
+
try {
|
|
2499
|
+
const raw = await materialize11(stream(accessor, first));
|
|
2500
|
+
const meta = await metadata(raw);
|
|
2501
|
+
const fs2 = await stat(accessor, first);
|
|
2502
|
+
const out = ENC12.encode(formatMetadata(meta, first.original, fs2.size ?? null));
|
|
2503
|
+
return [out, new IOResult11({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2504
|
+
} catch (err) {
|
|
2505
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2506
|
+
return [
|
|
2507
|
+
null,
|
|
2508
|
+
new IOResult11({
|
|
2509
|
+
exitCode: 1,
|
|
2510
|
+
stderr: ENC12.encode(`stat: ${first.original}: failed to read as ogg: ${msg}
|
|
2511
|
+
`)
|
|
2512
|
+
})
|
|
2513
|
+
];
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
var DISK_LOCAL_AUDIO_STAT_OGG = command11({
|
|
2517
|
+
name: "stat",
|
|
2518
|
+
resource: ResourceName15.DISK,
|
|
2519
|
+
spec: specOf11("stat"),
|
|
2520
|
+
filetype: ".ogg",
|
|
2521
|
+
fn: statOggCommand
|
|
2522
|
+
});
|
|
2523
|
+
|
|
2524
|
+
// src/commands/local_audio/disk/stat_wav.ts
|
|
2525
|
+
import {
|
|
2526
|
+
IOResult as IOResult12,
|
|
2527
|
+
ResourceName as ResourceName16,
|
|
2528
|
+
command as command12,
|
|
2529
|
+
materialize as materialize12,
|
|
2530
|
+
specOf as specOf12
|
|
2531
|
+
} from "@struktoai/mirage-core";
|
|
2532
|
+
var ENC13 = new TextEncoder();
|
|
2533
|
+
async function statWavCommand(accessor, paths, _texts, _opts) {
|
|
2534
|
+
if (paths.length === 0) {
|
|
2535
|
+
return [null, new IOResult12({ exitCode: 1, stderr: ENC13.encode("stat: missing operand\n") })];
|
|
2536
|
+
}
|
|
2537
|
+
const first = paths[0];
|
|
2538
|
+
if (first === void 0) return [null, new IOResult12()];
|
|
2539
|
+
try {
|
|
2540
|
+
const raw = await materialize12(stream(accessor, first));
|
|
2541
|
+
const meta = await metadata(raw);
|
|
2542
|
+
const fs2 = await stat(accessor, first);
|
|
2543
|
+
const out = ENC13.encode(formatMetadata(meta, first.original, fs2.size ?? null));
|
|
2544
|
+
return [out, new IOResult12({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2545
|
+
} catch (err) {
|
|
2546
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2547
|
+
return [
|
|
2548
|
+
null,
|
|
2549
|
+
new IOResult12({
|
|
2550
|
+
exitCode: 1,
|
|
2551
|
+
stderr: ENC13.encode(`stat: ${first.original}: failed to read as wav: ${msg}
|
|
2552
|
+
`)
|
|
2553
|
+
})
|
|
2554
|
+
];
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
var DISK_LOCAL_AUDIO_STAT_WAV = command12({
|
|
2558
|
+
name: "stat",
|
|
2559
|
+
resource: ResourceName16.DISK,
|
|
2560
|
+
spec: specOf12("stat"),
|
|
2561
|
+
filetype: ".wav",
|
|
2562
|
+
fn: statWavCommand
|
|
2563
|
+
});
|
|
2564
|
+
|
|
2565
|
+
// src/commands/local_audio/disk/tail_mp3.ts
|
|
2566
|
+
import {
|
|
2567
|
+
IOResult as IOResult13,
|
|
2568
|
+
ResourceName as ResourceName17,
|
|
2569
|
+
command as command13,
|
|
2570
|
+
materialize as materialize13,
|
|
2571
|
+
specOf as specOf13
|
|
2572
|
+
} from "@struktoai/mirage-core";
|
|
2573
|
+
var ENC14 = new TextEncoder();
|
|
2574
|
+
async function tailMp3Command(accessor, paths, _texts, opts) {
|
|
2575
|
+
if (paths.length === 0) {
|
|
2576
|
+
return [null, new IOResult13({ exitCode: 1, stderr: ENC14.encode("tail: missing operand\n") })];
|
|
2577
|
+
}
|
|
2578
|
+
const first = paths[0];
|
|
2579
|
+
if (first === void 0) return [null, new IOResult13()];
|
|
2580
|
+
if (typeof opts.flags.c === "string") {
|
|
2581
|
+
return [
|
|
2582
|
+
null,
|
|
2583
|
+
new IOResult13({ exitCode: 1, stderr: ENC14.encode("tail: -c not supported for audio files\n") })
|
|
2584
|
+
];
|
|
2585
|
+
}
|
|
2586
|
+
const n = typeof opts.flags.n === "string" ? Number.parseInt(opts.flags.n, 10) : 10;
|
|
2587
|
+
try {
|
|
2588
|
+
const raw = await materialize13(stream(accessor, first));
|
|
2589
|
+
const meta = await metadata(raw);
|
|
2590
|
+
const duration = meta.duration ?? 0;
|
|
2591
|
+
const start = Math.max(0, duration - n);
|
|
2592
|
+
const out = transcribe(raw, start);
|
|
2593
|
+
return [out, new IOResult13({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2594
|
+
} catch (err) {
|
|
2595
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2596
|
+
return [
|
|
2597
|
+
null,
|
|
2598
|
+
new IOResult13({
|
|
2599
|
+
exitCode: 1,
|
|
2600
|
+
stderr: ENC14.encode(`tail: ${first.original}: failed to read as mp3: ${msg}
|
|
2601
|
+
`)
|
|
2602
|
+
})
|
|
2603
|
+
];
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
var DISK_LOCAL_AUDIO_TAIL_MP3 = command13({
|
|
2607
|
+
name: "tail",
|
|
2608
|
+
resource: ResourceName17.DISK,
|
|
2609
|
+
spec: specOf13("tail"),
|
|
2610
|
+
filetype: ".mp3",
|
|
2611
|
+
fn: tailMp3Command
|
|
2612
|
+
});
|
|
2613
|
+
|
|
2614
|
+
// src/commands/local_audio/disk/tail_ogg.ts
|
|
2615
|
+
import {
|
|
2616
|
+
IOResult as IOResult14,
|
|
2617
|
+
ResourceName as ResourceName18,
|
|
2618
|
+
command as command14,
|
|
2619
|
+
materialize as materialize14,
|
|
2620
|
+
specOf as specOf14
|
|
2621
|
+
} from "@struktoai/mirage-core";
|
|
2622
|
+
var ENC15 = new TextEncoder();
|
|
2623
|
+
async function tailOggCommand(accessor, paths, _texts, opts) {
|
|
2624
|
+
if (paths.length === 0) {
|
|
2625
|
+
return [null, new IOResult14({ exitCode: 1, stderr: ENC15.encode("tail: missing operand\n") })];
|
|
2626
|
+
}
|
|
2627
|
+
const first = paths[0];
|
|
2628
|
+
if (first === void 0) return [null, new IOResult14()];
|
|
2629
|
+
if (typeof opts.flags.c === "string") {
|
|
2630
|
+
return [
|
|
2631
|
+
null,
|
|
2632
|
+
new IOResult14({ exitCode: 1, stderr: ENC15.encode("tail: -c not supported for audio files\n") })
|
|
2633
|
+
];
|
|
2634
|
+
}
|
|
2635
|
+
const n = typeof opts.flags.n === "string" ? Number.parseInt(opts.flags.n, 10) : 10;
|
|
2636
|
+
try {
|
|
2637
|
+
const raw = await materialize14(stream(accessor, first));
|
|
2638
|
+
const meta = await metadata(raw);
|
|
2639
|
+
const duration = meta.duration ?? 0;
|
|
2640
|
+
const start = Math.max(0, duration - n);
|
|
2641
|
+
const out = transcribe(raw, start);
|
|
2642
|
+
return [out, new IOResult14({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2643
|
+
} catch (err) {
|
|
2644
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2645
|
+
return [
|
|
2646
|
+
null,
|
|
2647
|
+
new IOResult14({
|
|
2648
|
+
exitCode: 1,
|
|
2649
|
+
stderr: ENC15.encode(`tail: ${first.original}: failed to read as ogg: ${msg}
|
|
2650
|
+
`)
|
|
2651
|
+
})
|
|
2652
|
+
];
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
var DISK_LOCAL_AUDIO_TAIL_OGG = command14({
|
|
2656
|
+
name: "tail",
|
|
2657
|
+
resource: ResourceName18.DISK,
|
|
2658
|
+
spec: specOf14("tail"),
|
|
2659
|
+
filetype: ".ogg",
|
|
2660
|
+
fn: tailOggCommand
|
|
2661
|
+
});
|
|
2662
|
+
|
|
2663
|
+
// src/commands/local_audio/disk/tail_wav.ts
|
|
2664
|
+
import {
|
|
2665
|
+
IOResult as IOResult15,
|
|
2666
|
+
ResourceName as ResourceName19,
|
|
2667
|
+
command as command15,
|
|
2668
|
+
materialize as materialize15,
|
|
2669
|
+
specOf as specOf15
|
|
2670
|
+
} from "@struktoai/mirage-core";
|
|
2671
|
+
var ENC16 = new TextEncoder();
|
|
2672
|
+
async function tailWavCommand(accessor, paths, _texts, opts) {
|
|
2673
|
+
if (paths.length === 0) {
|
|
2674
|
+
return [null, new IOResult15({ exitCode: 1, stderr: ENC16.encode("tail: missing operand\n") })];
|
|
2675
|
+
}
|
|
2676
|
+
const first = paths[0];
|
|
2677
|
+
if (first === void 0) return [null, new IOResult15()];
|
|
2678
|
+
if (typeof opts.flags.c === "string") {
|
|
2679
|
+
return [
|
|
2680
|
+
null,
|
|
2681
|
+
new IOResult15({ exitCode: 1, stderr: ENC16.encode("tail: -c not supported for audio files\n") })
|
|
2682
|
+
];
|
|
2683
|
+
}
|
|
2684
|
+
const n = typeof opts.flags.n === "string" ? Number.parseInt(opts.flags.n, 10) : 10;
|
|
2685
|
+
try {
|
|
2686
|
+
const raw = await materialize15(stream(accessor, first));
|
|
2687
|
+
const meta = await metadata(raw);
|
|
2688
|
+
const duration = meta.duration ?? 0;
|
|
2689
|
+
const start = Math.max(0, duration - n);
|
|
2690
|
+
const out = transcribe(raw, start);
|
|
2691
|
+
return [out, new IOResult15({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2692
|
+
} catch (err) {
|
|
2693
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2694
|
+
return [
|
|
2695
|
+
null,
|
|
2696
|
+
new IOResult15({
|
|
2697
|
+
exitCode: 1,
|
|
2698
|
+
stderr: ENC16.encode(`tail: ${first.original}: failed to read as wav: ${msg}
|
|
2699
|
+
`)
|
|
2700
|
+
})
|
|
2701
|
+
];
|
|
2702
|
+
}
|
|
2703
|
+
}
|
|
2704
|
+
var DISK_LOCAL_AUDIO_TAIL_WAV = command15({
|
|
2705
|
+
name: "tail",
|
|
2706
|
+
resource: ResourceName19.DISK,
|
|
2707
|
+
spec: specOf15("tail"),
|
|
2708
|
+
filetype: ".wav",
|
|
2709
|
+
fn: tailWavCommand
|
|
2710
|
+
});
|
|
2711
|
+
|
|
2712
|
+
// src/commands/local_audio/disk/index.ts
|
|
2713
|
+
var DISK_LOCAL_AUDIO_COMMANDS = [
|
|
2714
|
+
...DISK_LOCAL_AUDIO_CAT_WAV,
|
|
2715
|
+
...DISK_LOCAL_AUDIO_CAT_MP3,
|
|
2716
|
+
...DISK_LOCAL_AUDIO_CAT_OGG,
|
|
2717
|
+
...DISK_LOCAL_AUDIO_HEAD_WAV,
|
|
2718
|
+
...DISK_LOCAL_AUDIO_HEAD_MP3,
|
|
2719
|
+
...DISK_LOCAL_AUDIO_HEAD_OGG,
|
|
2720
|
+
...DISK_LOCAL_AUDIO_TAIL_WAV,
|
|
2721
|
+
...DISK_LOCAL_AUDIO_TAIL_MP3,
|
|
2722
|
+
...DISK_LOCAL_AUDIO_TAIL_OGG,
|
|
2723
|
+
...DISK_LOCAL_AUDIO_GREP_WAV,
|
|
2724
|
+
...DISK_LOCAL_AUDIO_GREP_MP3,
|
|
2725
|
+
...DISK_LOCAL_AUDIO_GREP_OGG,
|
|
2726
|
+
...DISK_LOCAL_AUDIO_STAT_WAV,
|
|
2727
|
+
...DISK_LOCAL_AUDIO_STAT_MP3,
|
|
2728
|
+
...DISK_LOCAL_AUDIO_STAT_OGG
|
|
2729
|
+
];
|
|
2730
|
+
|
|
2731
|
+
// src/commands/local_audio/ram/cat_mp3.ts
|
|
2732
|
+
import {
|
|
2733
|
+
IOResult as IOResult16,
|
|
2734
|
+
ResourceName as ResourceName20,
|
|
2735
|
+
command as command16,
|
|
2736
|
+
specOf as specOf16
|
|
2737
|
+
} from "@struktoai/mirage-core";
|
|
2738
|
+
|
|
2739
|
+
// src/commands/local_audio/ram/read.ts
|
|
2740
|
+
function norm(p) {
|
|
2741
|
+
return `/${p.replace(/^\/+|\/+$/g, "")}`;
|
|
2742
|
+
}
|
|
2743
|
+
function readRam(accessor, path) {
|
|
2744
|
+
const p = norm(path.stripPrefix);
|
|
2745
|
+
const data = accessor.store.files.get(p);
|
|
2746
|
+
if (data === void 0) throw new Error(`file not found: ${p}`);
|
|
2747
|
+
return data;
|
|
2748
|
+
}
|
|
2749
|
+
|
|
2750
|
+
// src/commands/local_audio/ram/cat_mp3.ts
|
|
2751
|
+
var ENC17 = new TextEncoder();
|
|
2752
|
+
function catMp3Command2(accessor, paths, _texts, _opts) {
|
|
2753
|
+
if (paths.length === 0) {
|
|
2754
|
+
return [null, new IOResult16({ exitCode: 1, stderr: ENC17.encode("cat: missing operand\n") })];
|
|
2755
|
+
}
|
|
2756
|
+
const first = paths[0];
|
|
2757
|
+
if (first === void 0) return [null, new IOResult16()];
|
|
2758
|
+
try {
|
|
2759
|
+
const raw = readRam(accessor, first);
|
|
2760
|
+
const out = transcribe(raw);
|
|
2761
|
+
return [out, new IOResult16({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2762
|
+
} catch (err) {
|
|
2763
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2764
|
+
return [
|
|
2765
|
+
null,
|
|
2766
|
+
new IOResult16({
|
|
2767
|
+
exitCode: 1,
|
|
2768
|
+
stderr: ENC17.encode(`cat: ${first.original}: failed to read as mp3: ${msg}
|
|
2769
|
+
`)
|
|
2770
|
+
})
|
|
2771
|
+
];
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
var RAM_LOCAL_AUDIO_CAT_MP3 = command16({
|
|
2775
|
+
name: "cat",
|
|
2776
|
+
resource: ResourceName20.RAM,
|
|
2777
|
+
spec: specOf16("cat"),
|
|
2778
|
+
filetype: ".mp3",
|
|
2779
|
+
fn: catMp3Command2
|
|
2780
|
+
});
|
|
2781
|
+
|
|
2782
|
+
// src/commands/local_audio/ram/cat_ogg.ts
|
|
2783
|
+
import {
|
|
2784
|
+
IOResult as IOResult17,
|
|
2785
|
+
ResourceName as ResourceName21,
|
|
2786
|
+
command as command17,
|
|
2787
|
+
specOf as specOf17
|
|
2788
|
+
} from "@struktoai/mirage-core";
|
|
2789
|
+
var ENC18 = new TextEncoder();
|
|
2790
|
+
function catOggCommand2(accessor, paths, _texts, _opts) {
|
|
2791
|
+
if (paths.length === 0) {
|
|
2792
|
+
return [null, new IOResult17({ exitCode: 1, stderr: ENC18.encode("cat: missing operand\n") })];
|
|
2793
|
+
}
|
|
2794
|
+
const first = paths[0];
|
|
2795
|
+
if (first === void 0) return [null, new IOResult17()];
|
|
2796
|
+
try {
|
|
2797
|
+
const raw = readRam(accessor, first);
|
|
2798
|
+
const out = transcribe(raw);
|
|
2799
|
+
return [out, new IOResult17({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2800
|
+
} catch (err) {
|
|
2801
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2802
|
+
return [
|
|
2803
|
+
null,
|
|
2804
|
+
new IOResult17({
|
|
2805
|
+
exitCode: 1,
|
|
2806
|
+
stderr: ENC18.encode(`cat: ${first.original}: failed to read as ogg: ${msg}
|
|
2807
|
+
`)
|
|
2808
|
+
})
|
|
2809
|
+
];
|
|
2810
|
+
}
|
|
2811
|
+
}
|
|
2812
|
+
var RAM_LOCAL_AUDIO_CAT_OGG = command17({
|
|
2813
|
+
name: "cat",
|
|
2814
|
+
resource: ResourceName21.RAM,
|
|
2815
|
+
spec: specOf17("cat"),
|
|
2816
|
+
filetype: ".ogg",
|
|
2817
|
+
fn: catOggCommand2
|
|
2818
|
+
});
|
|
2819
|
+
|
|
2820
|
+
// src/commands/local_audio/ram/cat_wav.ts
|
|
2821
|
+
import {
|
|
2822
|
+
IOResult as IOResult18,
|
|
2823
|
+
ResourceName as ResourceName22,
|
|
2824
|
+
command as command18,
|
|
2825
|
+
specOf as specOf18
|
|
2826
|
+
} from "@struktoai/mirage-core";
|
|
2827
|
+
var ENC19 = new TextEncoder();
|
|
2828
|
+
function catWavCommand2(accessor, paths, _texts, _opts) {
|
|
2829
|
+
if (paths.length === 0) {
|
|
2830
|
+
return [null, new IOResult18({ exitCode: 1, stderr: ENC19.encode("cat: missing operand\n") })];
|
|
2831
|
+
}
|
|
2832
|
+
const first = paths[0];
|
|
2833
|
+
if (first === void 0) return [null, new IOResult18()];
|
|
2834
|
+
try {
|
|
2835
|
+
const raw = readRam(accessor, first);
|
|
2836
|
+
const out = transcribe(raw);
|
|
2837
|
+
return [out, new IOResult18({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2838
|
+
} catch (err) {
|
|
2839
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2840
|
+
return [
|
|
2841
|
+
null,
|
|
2842
|
+
new IOResult18({
|
|
2843
|
+
exitCode: 1,
|
|
2844
|
+
stderr: ENC19.encode(`cat: ${first.original}: failed to read as wav: ${msg}
|
|
2845
|
+
`)
|
|
2846
|
+
})
|
|
2847
|
+
];
|
|
2848
|
+
}
|
|
2849
|
+
}
|
|
2850
|
+
var RAM_LOCAL_AUDIO_CAT_WAV = command18({
|
|
2851
|
+
name: "cat",
|
|
2852
|
+
resource: ResourceName22.RAM,
|
|
2853
|
+
spec: specOf18("cat"),
|
|
2854
|
+
filetype: ".wav",
|
|
2855
|
+
fn: catWavCommand2
|
|
2856
|
+
});
|
|
2857
|
+
|
|
2858
|
+
// src/commands/local_audio/ram/grep_mp3.ts
|
|
2859
|
+
import {
|
|
2860
|
+
IOResult as IOResult19,
|
|
2861
|
+
ResourceName as ResourceName23,
|
|
2862
|
+
command as command19,
|
|
2863
|
+
materialize as materialize16,
|
|
2864
|
+
specOf as specOf19
|
|
2865
|
+
} from "@struktoai/mirage-core";
|
|
2866
|
+
var ENC20 = new TextEncoder();
|
|
2867
|
+
var DEC5 = new TextDecoder();
|
|
2868
|
+
async function grepMp3Command2(accessor, paths, texts, opts) {
|
|
2869
|
+
if (paths.length === 0 || texts.length === 0) {
|
|
2870
|
+
return [null, new IOResult19({ exitCode: 1, stderr: ENC20.encode("grep: missing operand\n") })];
|
|
2871
|
+
}
|
|
2872
|
+
const first = paths[0];
|
|
2873
|
+
if (first === void 0) return [null, new IOResult19()];
|
|
2874
|
+
const pattern = texts[0] ?? "";
|
|
2875
|
+
const ignoreCase = opts.flags.i === true;
|
|
2876
|
+
try {
|
|
2877
|
+
const raw = readRam(accessor, first);
|
|
2878
|
+
const text = DEC5.decode(await materialize16(transcribe(raw)));
|
|
2879
|
+
const flags = ignoreCase ? "i" : "";
|
|
2880
|
+
const re = new RegExp(pattern, flags);
|
|
2881
|
+
if (re.test(text)) {
|
|
2882
|
+
const out = ENC20.encode(text);
|
|
2883
|
+
return [out, new IOResult19({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2884
|
+
}
|
|
2885
|
+
return [
|
|
2886
|
+
null,
|
|
2887
|
+
new IOResult19({
|
|
2888
|
+
exitCode: 1,
|
|
2889
|
+
reads: { [first.original]: raw },
|
|
2890
|
+
cache: [first.original]
|
|
2891
|
+
})
|
|
2892
|
+
];
|
|
2893
|
+
} catch (err) {
|
|
2894
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2895
|
+
return [
|
|
2896
|
+
null,
|
|
2897
|
+
new IOResult19({
|
|
2898
|
+
exitCode: 1,
|
|
2899
|
+
stderr: ENC20.encode(`grep: ${first.original}: failed to read as mp3: ${msg}
|
|
2900
|
+
`)
|
|
2901
|
+
})
|
|
2902
|
+
];
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
var RAM_LOCAL_AUDIO_GREP_MP3 = command19({
|
|
2906
|
+
name: "grep",
|
|
2907
|
+
resource: ResourceName23.RAM,
|
|
2908
|
+
spec: specOf19("grep"),
|
|
2909
|
+
filetype: ".mp3",
|
|
2910
|
+
fn: grepMp3Command2
|
|
2911
|
+
});
|
|
2912
|
+
|
|
2913
|
+
// src/commands/local_audio/ram/grep_ogg.ts
|
|
2914
|
+
import {
|
|
2915
|
+
IOResult as IOResult20,
|
|
2916
|
+
ResourceName as ResourceName24,
|
|
2917
|
+
command as command20,
|
|
2918
|
+
materialize as materialize17,
|
|
2919
|
+
specOf as specOf20
|
|
2920
|
+
} from "@struktoai/mirage-core";
|
|
2921
|
+
var ENC21 = new TextEncoder();
|
|
2922
|
+
var DEC6 = new TextDecoder();
|
|
2923
|
+
async function grepOggCommand2(accessor, paths, texts, opts) {
|
|
2924
|
+
if (paths.length === 0 || texts.length === 0) {
|
|
2925
|
+
return [null, new IOResult20({ exitCode: 1, stderr: ENC21.encode("grep: missing operand\n") })];
|
|
2926
|
+
}
|
|
2927
|
+
const first = paths[0];
|
|
2928
|
+
if (first === void 0) return [null, new IOResult20()];
|
|
2929
|
+
const pattern = texts[0] ?? "";
|
|
2930
|
+
const ignoreCase = opts.flags.i === true;
|
|
2931
|
+
try {
|
|
2932
|
+
const raw = readRam(accessor, first);
|
|
2933
|
+
const text = DEC6.decode(await materialize17(transcribe(raw)));
|
|
2934
|
+
const flags = ignoreCase ? "i" : "";
|
|
2935
|
+
const re = new RegExp(pattern, flags);
|
|
2936
|
+
if (re.test(text)) {
|
|
2937
|
+
const out = ENC21.encode(text);
|
|
2938
|
+
return [out, new IOResult20({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2939
|
+
}
|
|
2940
|
+
return [
|
|
2941
|
+
null,
|
|
2942
|
+
new IOResult20({
|
|
2943
|
+
exitCode: 1,
|
|
2944
|
+
reads: { [first.original]: raw },
|
|
2945
|
+
cache: [first.original]
|
|
2946
|
+
})
|
|
2947
|
+
];
|
|
2948
|
+
} catch (err) {
|
|
2949
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2950
|
+
return [
|
|
2951
|
+
null,
|
|
2952
|
+
new IOResult20({
|
|
2953
|
+
exitCode: 1,
|
|
2954
|
+
stderr: ENC21.encode(`grep: ${first.original}: failed to read as ogg: ${msg}
|
|
2955
|
+
`)
|
|
2956
|
+
})
|
|
2957
|
+
];
|
|
2958
|
+
}
|
|
2959
|
+
}
|
|
2960
|
+
var RAM_LOCAL_AUDIO_GREP_OGG = command20({
|
|
2961
|
+
name: "grep",
|
|
2962
|
+
resource: ResourceName24.RAM,
|
|
2963
|
+
spec: specOf20("grep"),
|
|
2964
|
+
filetype: ".ogg",
|
|
2965
|
+
fn: grepOggCommand2
|
|
2966
|
+
});
|
|
2967
|
+
|
|
2968
|
+
// src/commands/local_audio/ram/grep_wav.ts
|
|
2969
|
+
import {
|
|
2970
|
+
IOResult as IOResult21,
|
|
2971
|
+
ResourceName as ResourceName25,
|
|
2972
|
+
command as command21,
|
|
2973
|
+
materialize as materialize18,
|
|
2974
|
+
specOf as specOf21
|
|
2975
|
+
} from "@struktoai/mirage-core";
|
|
2976
|
+
var ENC22 = new TextEncoder();
|
|
2977
|
+
var DEC7 = new TextDecoder();
|
|
2978
|
+
async function grepWavCommand2(accessor, paths, texts, opts) {
|
|
2979
|
+
if (paths.length === 0 || texts.length === 0) {
|
|
2980
|
+
return [null, new IOResult21({ exitCode: 1, stderr: ENC22.encode("grep: missing operand\n") })];
|
|
2981
|
+
}
|
|
2982
|
+
const first = paths[0];
|
|
2983
|
+
if (first === void 0) return [null, new IOResult21()];
|
|
2984
|
+
const pattern = texts[0] ?? "";
|
|
2985
|
+
const ignoreCase = opts.flags.i === true;
|
|
2986
|
+
try {
|
|
2987
|
+
const raw = readRam(accessor, first);
|
|
2988
|
+
const text = DEC7.decode(await materialize18(transcribe(raw)));
|
|
2989
|
+
const flags = ignoreCase ? "i" : "";
|
|
2990
|
+
const re = new RegExp(pattern, flags);
|
|
2991
|
+
if (re.test(text)) {
|
|
2992
|
+
const out = ENC22.encode(text);
|
|
2993
|
+
return [out, new IOResult21({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
2994
|
+
}
|
|
2995
|
+
return [
|
|
2996
|
+
null,
|
|
2997
|
+
new IOResult21({
|
|
2998
|
+
exitCode: 1,
|
|
2999
|
+
reads: { [first.original]: raw },
|
|
3000
|
+
cache: [first.original]
|
|
3001
|
+
})
|
|
3002
|
+
];
|
|
3003
|
+
} catch (err) {
|
|
3004
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3005
|
+
return [
|
|
3006
|
+
null,
|
|
3007
|
+
new IOResult21({
|
|
3008
|
+
exitCode: 1,
|
|
3009
|
+
stderr: ENC22.encode(`grep: ${first.original}: failed to read as wav: ${msg}
|
|
3010
|
+
`)
|
|
3011
|
+
})
|
|
3012
|
+
];
|
|
3013
|
+
}
|
|
3014
|
+
}
|
|
3015
|
+
var RAM_LOCAL_AUDIO_GREP_WAV = command21({
|
|
3016
|
+
name: "grep",
|
|
3017
|
+
resource: ResourceName25.RAM,
|
|
3018
|
+
spec: specOf21("grep"),
|
|
3019
|
+
filetype: ".wav",
|
|
3020
|
+
fn: grepWavCommand2
|
|
3021
|
+
});
|
|
3022
|
+
|
|
3023
|
+
// src/commands/local_audio/ram/head_mp3.ts
|
|
3024
|
+
import {
|
|
3025
|
+
IOResult as IOResult22,
|
|
3026
|
+
ResourceName as ResourceName26,
|
|
3027
|
+
command as command22,
|
|
3028
|
+
specOf as specOf22
|
|
3029
|
+
} from "@struktoai/mirage-core";
|
|
3030
|
+
var ENC23 = new TextEncoder();
|
|
3031
|
+
function headMp3Command2(accessor, paths, _texts, opts) {
|
|
3032
|
+
if (paths.length === 0) {
|
|
3033
|
+
return [null, new IOResult22({ exitCode: 1, stderr: ENC23.encode("head: missing operand\n") })];
|
|
3034
|
+
}
|
|
3035
|
+
const first = paths[0];
|
|
3036
|
+
if (first === void 0) return [null, new IOResult22()];
|
|
3037
|
+
if (typeof opts.flags.c === "string") {
|
|
3038
|
+
return [
|
|
3039
|
+
null,
|
|
3040
|
+
new IOResult22({ exitCode: 1, stderr: ENC23.encode("head: -c not supported for audio files\n") })
|
|
3041
|
+
];
|
|
3042
|
+
}
|
|
3043
|
+
const n = typeof opts.flags.n === "string" ? Number.parseInt(opts.flags.n, 10) : 10;
|
|
3044
|
+
try {
|
|
3045
|
+
const raw = readRam(accessor, first);
|
|
3046
|
+
const out = transcribe(raw, void 0, n);
|
|
3047
|
+
return [out, new IOResult22({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
3048
|
+
} catch (err) {
|
|
3049
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3050
|
+
return [
|
|
3051
|
+
null,
|
|
3052
|
+
new IOResult22({
|
|
3053
|
+
exitCode: 1,
|
|
3054
|
+
stderr: ENC23.encode(`head: ${first.original}: failed to read as mp3: ${msg}
|
|
3055
|
+
`)
|
|
3056
|
+
})
|
|
3057
|
+
];
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
3060
|
+
var RAM_LOCAL_AUDIO_HEAD_MP3 = command22({
|
|
3061
|
+
name: "head",
|
|
3062
|
+
resource: ResourceName26.RAM,
|
|
3063
|
+
spec: specOf22("head"),
|
|
3064
|
+
filetype: ".mp3",
|
|
3065
|
+
fn: headMp3Command2
|
|
3066
|
+
});
|
|
3067
|
+
|
|
3068
|
+
// src/commands/local_audio/ram/head_ogg.ts
|
|
3069
|
+
import {
|
|
3070
|
+
IOResult as IOResult23,
|
|
3071
|
+
ResourceName as ResourceName27,
|
|
3072
|
+
command as command23,
|
|
3073
|
+
specOf as specOf23
|
|
3074
|
+
} from "@struktoai/mirage-core";
|
|
3075
|
+
var ENC24 = new TextEncoder();
|
|
3076
|
+
function headOggCommand2(accessor, paths, _texts, opts) {
|
|
3077
|
+
if (paths.length === 0) {
|
|
3078
|
+
return [null, new IOResult23({ exitCode: 1, stderr: ENC24.encode("head: missing operand\n") })];
|
|
3079
|
+
}
|
|
3080
|
+
const first = paths[0];
|
|
3081
|
+
if (first === void 0) return [null, new IOResult23()];
|
|
3082
|
+
if (typeof opts.flags.c === "string") {
|
|
3083
|
+
return [
|
|
3084
|
+
null,
|
|
3085
|
+
new IOResult23({ exitCode: 1, stderr: ENC24.encode("head: -c not supported for audio files\n") })
|
|
3086
|
+
];
|
|
3087
|
+
}
|
|
3088
|
+
const n = typeof opts.flags.n === "string" ? Number.parseInt(opts.flags.n, 10) : 10;
|
|
3089
|
+
try {
|
|
3090
|
+
const raw = readRam(accessor, first);
|
|
3091
|
+
const out = transcribe(raw, void 0, n);
|
|
3092
|
+
return [out, new IOResult23({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
3093
|
+
} catch (err) {
|
|
3094
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3095
|
+
return [
|
|
3096
|
+
null,
|
|
3097
|
+
new IOResult23({
|
|
3098
|
+
exitCode: 1,
|
|
3099
|
+
stderr: ENC24.encode(`head: ${first.original}: failed to read as ogg: ${msg}
|
|
3100
|
+
`)
|
|
3101
|
+
})
|
|
3102
|
+
];
|
|
3103
|
+
}
|
|
3104
|
+
}
|
|
3105
|
+
var RAM_LOCAL_AUDIO_HEAD_OGG = command23({
|
|
3106
|
+
name: "head",
|
|
3107
|
+
resource: ResourceName27.RAM,
|
|
3108
|
+
spec: specOf23("head"),
|
|
3109
|
+
filetype: ".ogg",
|
|
3110
|
+
fn: headOggCommand2
|
|
3111
|
+
});
|
|
3112
|
+
|
|
3113
|
+
// src/commands/local_audio/ram/head_wav.ts
|
|
3114
|
+
import {
|
|
3115
|
+
IOResult as IOResult24,
|
|
3116
|
+
ResourceName as ResourceName28,
|
|
3117
|
+
command as command24,
|
|
3118
|
+
specOf as specOf24
|
|
3119
|
+
} from "@struktoai/mirage-core";
|
|
3120
|
+
var ENC25 = new TextEncoder();
|
|
3121
|
+
function headWavCommand2(accessor, paths, _texts, opts) {
|
|
3122
|
+
if (paths.length === 0) {
|
|
3123
|
+
return [null, new IOResult24({ exitCode: 1, stderr: ENC25.encode("head: missing operand\n") })];
|
|
3124
|
+
}
|
|
3125
|
+
const first = paths[0];
|
|
3126
|
+
if (first === void 0) return [null, new IOResult24()];
|
|
3127
|
+
if (typeof opts.flags.c === "string") {
|
|
3128
|
+
return [
|
|
3129
|
+
null,
|
|
3130
|
+
new IOResult24({ exitCode: 1, stderr: ENC25.encode("head: -c not supported for audio files\n") })
|
|
3131
|
+
];
|
|
3132
|
+
}
|
|
3133
|
+
const n = typeof opts.flags.n === "string" ? Number.parseInt(opts.flags.n, 10) : 10;
|
|
3134
|
+
try {
|
|
3135
|
+
const raw = readRam(accessor, first);
|
|
3136
|
+
const out = transcribe(raw, void 0, n);
|
|
3137
|
+
return [out, new IOResult24({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
3138
|
+
} catch (err) {
|
|
3139
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3140
|
+
return [
|
|
3141
|
+
null,
|
|
3142
|
+
new IOResult24({
|
|
3143
|
+
exitCode: 1,
|
|
3144
|
+
stderr: ENC25.encode(`head: ${first.original}: failed to read as wav: ${msg}
|
|
3145
|
+
`)
|
|
3146
|
+
})
|
|
3147
|
+
];
|
|
3148
|
+
}
|
|
3149
|
+
}
|
|
3150
|
+
var RAM_LOCAL_AUDIO_HEAD_WAV = command24({
|
|
3151
|
+
name: "head",
|
|
3152
|
+
resource: ResourceName28.RAM,
|
|
3153
|
+
spec: specOf24("head"),
|
|
3154
|
+
filetype: ".wav",
|
|
3155
|
+
fn: headWavCommand2
|
|
3156
|
+
});
|
|
3157
|
+
|
|
3158
|
+
// src/commands/local_audio/ram/stat_mp3.ts
|
|
3159
|
+
import {
|
|
3160
|
+
IOResult as IOResult25,
|
|
3161
|
+
ResourceName as ResourceName29,
|
|
3162
|
+
command as command25,
|
|
3163
|
+
specOf as specOf25
|
|
3164
|
+
} from "@struktoai/mirage-core";
|
|
3165
|
+
var ENC26 = new TextEncoder();
|
|
3166
|
+
async function statMp3Command2(accessor, paths, _texts, _opts) {
|
|
3167
|
+
if (paths.length === 0) {
|
|
3168
|
+
return [null, new IOResult25({ exitCode: 1, stderr: ENC26.encode("stat: missing operand\n") })];
|
|
3169
|
+
}
|
|
3170
|
+
const first = paths[0];
|
|
3171
|
+
if (first === void 0) return [null, new IOResult25()];
|
|
3172
|
+
try {
|
|
3173
|
+
const raw = readRam(accessor, first);
|
|
3174
|
+
const meta = await metadata(raw);
|
|
3175
|
+
const out = ENC26.encode(formatMetadata(meta, first.original, null));
|
|
3176
|
+
return [out, new IOResult25({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
3177
|
+
} catch (err) {
|
|
3178
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3179
|
+
return [
|
|
3180
|
+
null,
|
|
3181
|
+
new IOResult25({
|
|
3182
|
+
exitCode: 1,
|
|
3183
|
+
stderr: ENC26.encode(`stat: ${first.original}: failed to read as mp3: ${msg}
|
|
3184
|
+
`)
|
|
3185
|
+
})
|
|
3186
|
+
];
|
|
3187
|
+
}
|
|
3188
|
+
}
|
|
3189
|
+
var RAM_LOCAL_AUDIO_STAT_MP3 = command25({
|
|
3190
|
+
name: "stat",
|
|
3191
|
+
resource: ResourceName29.RAM,
|
|
3192
|
+
spec: specOf25("stat"),
|
|
3193
|
+
filetype: ".mp3",
|
|
3194
|
+
fn: statMp3Command2
|
|
3195
|
+
});
|
|
3196
|
+
|
|
3197
|
+
// src/commands/local_audio/ram/stat_ogg.ts
|
|
3198
|
+
import {
|
|
3199
|
+
IOResult as IOResult26,
|
|
3200
|
+
ResourceName as ResourceName30,
|
|
3201
|
+
command as command26,
|
|
3202
|
+
specOf as specOf26
|
|
3203
|
+
} from "@struktoai/mirage-core";
|
|
3204
|
+
var ENC27 = new TextEncoder();
|
|
3205
|
+
async function statOggCommand2(accessor, paths, _texts, _opts) {
|
|
3206
|
+
if (paths.length === 0) {
|
|
3207
|
+
return [null, new IOResult26({ exitCode: 1, stderr: ENC27.encode("stat: missing operand\n") })];
|
|
3208
|
+
}
|
|
3209
|
+
const first = paths[0];
|
|
3210
|
+
if (first === void 0) return [null, new IOResult26()];
|
|
3211
|
+
try {
|
|
3212
|
+
const raw = readRam(accessor, first);
|
|
3213
|
+
const meta = await metadata(raw);
|
|
3214
|
+
const out = ENC27.encode(formatMetadata(meta, first.original, null));
|
|
3215
|
+
return [out, new IOResult26({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
3216
|
+
} catch (err) {
|
|
3217
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3218
|
+
return [
|
|
3219
|
+
null,
|
|
3220
|
+
new IOResult26({
|
|
3221
|
+
exitCode: 1,
|
|
3222
|
+
stderr: ENC27.encode(`stat: ${first.original}: failed to read as ogg: ${msg}
|
|
3223
|
+
`)
|
|
3224
|
+
})
|
|
3225
|
+
];
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3228
|
+
var RAM_LOCAL_AUDIO_STAT_OGG = command26({
|
|
3229
|
+
name: "stat",
|
|
3230
|
+
resource: ResourceName30.RAM,
|
|
3231
|
+
spec: specOf26("stat"),
|
|
3232
|
+
filetype: ".ogg",
|
|
3233
|
+
fn: statOggCommand2
|
|
3234
|
+
});
|
|
3235
|
+
|
|
3236
|
+
// src/commands/local_audio/ram/stat_wav.ts
|
|
3237
|
+
import {
|
|
3238
|
+
IOResult as IOResult27,
|
|
3239
|
+
ResourceName as ResourceName31,
|
|
3240
|
+
command as command27,
|
|
3241
|
+
specOf as specOf27
|
|
3242
|
+
} from "@struktoai/mirage-core";
|
|
3243
|
+
var ENC28 = new TextEncoder();
|
|
3244
|
+
async function statWavCommand2(accessor, paths, _texts, _opts) {
|
|
3245
|
+
if (paths.length === 0) {
|
|
3246
|
+
return [null, new IOResult27({ exitCode: 1, stderr: ENC28.encode("stat: missing operand\n") })];
|
|
3247
|
+
}
|
|
3248
|
+
const first = paths[0];
|
|
3249
|
+
if (first === void 0) return [null, new IOResult27()];
|
|
3250
|
+
try {
|
|
3251
|
+
const raw = readRam(accessor, first);
|
|
3252
|
+
const meta = await metadata(raw);
|
|
3253
|
+
const out = ENC28.encode(formatMetadata(meta, first.original, null));
|
|
3254
|
+
return [out, new IOResult27({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
3255
|
+
} catch (err) {
|
|
3256
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3257
|
+
return [
|
|
3258
|
+
null,
|
|
3259
|
+
new IOResult27({
|
|
3260
|
+
exitCode: 1,
|
|
3261
|
+
stderr: ENC28.encode(`stat: ${first.original}: failed to read as wav: ${msg}
|
|
3262
|
+
`)
|
|
3263
|
+
})
|
|
3264
|
+
];
|
|
3265
|
+
}
|
|
3266
|
+
}
|
|
3267
|
+
var RAM_LOCAL_AUDIO_STAT_WAV = command27({
|
|
3268
|
+
name: "stat",
|
|
3269
|
+
resource: ResourceName31.RAM,
|
|
3270
|
+
spec: specOf27("stat"),
|
|
3271
|
+
filetype: ".wav",
|
|
3272
|
+
fn: statWavCommand2
|
|
3273
|
+
});
|
|
3274
|
+
|
|
3275
|
+
// src/commands/local_audio/ram/tail_mp3.ts
|
|
3276
|
+
import {
|
|
3277
|
+
IOResult as IOResult28,
|
|
3278
|
+
ResourceName as ResourceName32,
|
|
3279
|
+
command as command28,
|
|
3280
|
+
specOf as specOf28
|
|
3281
|
+
} from "@struktoai/mirage-core";
|
|
3282
|
+
var ENC29 = new TextEncoder();
|
|
3283
|
+
async function tailMp3Command2(accessor, paths, _texts, opts) {
|
|
3284
|
+
if (paths.length === 0) {
|
|
3285
|
+
return [null, new IOResult28({ exitCode: 1, stderr: ENC29.encode("tail: missing operand\n") })];
|
|
3286
|
+
}
|
|
3287
|
+
const first = paths[0];
|
|
3288
|
+
if (first === void 0) return [null, new IOResult28()];
|
|
3289
|
+
if (typeof opts.flags.c === "string") {
|
|
3290
|
+
return [
|
|
3291
|
+
null,
|
|
3292
|
+
new IOResult28({ exitCode: 1, stderr: ENC29.encode("tail: -c not supported for audio files\n") })
|
|
3293
|
+
];
|
|
3294
|
+
}
|
|
3295
|
+
const n = typeof opts.flags.n === "string" ? Number.parseInt(opts.flags.n, 10) : 10;
|
|
3296
|
+
try {
|
|
3297
|
+
const raw = readRam(accessor, first);
|
|
3298
|
+
const meta = await metadata(raw);
|
|
3299
|
+
const duration = meta.duration ?? 0;
|
|
3300
|
+
const start = Math.max(0, duration - n);
|
|
3301
|
+
const out = transcribe(raw, start);
|
|
3302
|
+
return [out, new IOResult28({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
3303
|
+
} catch (err) {
|
|
3304
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3305
|
+
return [
|
|
3306
|
+
null,
|
|
3307
|
+
new IOResult28({
|
|
3308
|
+
exitCode: 1,
|
|
3309
|
+
stderr: ENC29.encode(`tail: ${first.original}: failed to read as mp3: ${msg}
|
|
3310
|
+
`)
|
|
3311
|
+
})
|
|
3312
|
+
];
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
var RAM_LOCAL_AUDIO_TAIL_MP3 = command28({
|
|
3316
|
+
name: "tail",
|
|
3317
|
+
resource: ResourceName32.RAM,
|
|
3318
|
+
spec: specOf28("tail"),
|
|
3319
|
+
filetype: ".mp3",
|
|
3320
|
+
fn: tailMp3Command2
|
|
3321
|
+
});
|
|
3322
|
+
|
|
3323
|
+
// src/commands/local_audio/ram/tail_ogg.ts
|
|
3324
|
+
import {
|
|
3325
|
+
IOResult as IOResult29,
|
|
3326
|
+
ResourceName as ResourceName33,
|
|
3327
|
+
command as command29,
|
|
3328
|
+
specOf as specOf29
|
|
3329
|
+
} from "@struktoai/mirage-core";
|
|
3330
|
+
var ENC30 = new TextEncoder();
|
|
3331
|
+
async function tailOggCommand2(accessor, paths, _texts, opts) {
|
|
3332
|
+
if (paths.length === 0) {
|
|
3333
|
+
return [null, new IOResult29({ exitCode: 1, stderr: ENC30.encode("tail: missing operand\n") })];
|
|
3334
|
+
}
|
|
3335
|
+
const first = paths[0];
|
|
3336
|
+
if (first === void 0) return [null, new IOResult29()];
|
|
3337
|
+
if (typeof opts.flags.c === "string") {
|
|
3338
|
+
return [
|
|
3339
|
+
null,
|
|
3340
|
+
new IOResult29({ exitCode: 1, stderr: ENC30.encode("tail: -c not supported for audio files\n") })
|
|
3341
|
+
];
|
|
3342
|
+
}
|
|
3343
|
+
const n = typeof opts.flags.n === "string" ? Number.parseInt(opts.flags.n, 10) : 10;
|
|
3344
|
+
try {
|
|
3345
|
+
const raw = readRam(accessor, first);
|
|
3346
|
+
const meta = await metadata(raw);
|
|
3347
|
+
const duration = meta.duration ?? 0;
|
|
3348
|
+
const start = Math.max(0, duration - n);
|
|
3349
|
+
const out = transcribe(raw, start);
|
|
3350
|
+
return [out, new IOResult29({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
3351
|
+
} catch (err) {
|
|
3352
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3353
|
+
return [
|
|
3354
|
+
null,
|
|
3355
|
+
new IOResult29({
|
|
3356
|
+
exitCode: 1,
|
|
3357
|
+
stderr: ENC30.encode(`tail: ${first.original}: failed to read as ogg: ${msg}
|
|
3358
|
+
`)
|
|
3359
|
+
})
|
|
3360
|
+
];
|
|
3361
|
+
}
|
|
3362
|
+
}
|
|
3363
|
+
var RAM_LOCAL_AUDIO_TAIL_OGG = command29({
|
|
3364
|
+
name: "tail",
|
|
3365
|
+
resource: ResourceName33.RAM,
|
|
3366
|
+
spec: specOf29("tail"),
|
|
3367
|
+
filetype: ".ogg",
|
|
3368
|
+
fn: tailOggCommand2
|
|
3369
|
+
});
|
|
3370
|
+
|
|
3371
|
+
// src/commands/local_audio/ram/tail_wav.ts
|
|
3372
|
+
import {
|
|
3373
|
+
IOResult as IOResult30,
|
|
3374
|
+
ResourceName as ResourceName34,
|
|
3375
|
+
command as command30,
|
|
3376
|
+
specOf as specOf30
|
|
3377
|
+
} from "@struktoai/mirage-core";
|
|
3378
|
+
var ENC31 = new TextEncoder();
|
|
3379
|
+
async function tailWavCommand2(accessor, paths, _texts, opts) {
|
|
3380
|
+
if (paths.length === 0) {
|
|
3381
|
+
return [null, new IOResult30({ exitCode: 1, stderr: ENC31.encode("tail: missing operand\n") })];
|
|
3382
|
+
}
|
|
3383
|
+
const first = paths[0];
|
|
3384
|
+
if (first === void 0) return [null, new IOResult30()];
|
|
3385
|
+
if (typeof opts.flags.c === "string") {
|
|
3386
|
+
return [
|
|
3387
|
+
null,
|
|
3388
|
+
new IOResult30({ exitCode: 1, stderr: ENC31.encode("tail: -c not supported for audio files\n") })
|
|
3389
|
+
];
|
|
3390
|
+
}
|
|
3391
|
+
const n = typeof opts.flags.n === "string" ? Number.parseInt(opts.flags.n, 10) : 10;
|
|
3392
|
+
try {
|
|
3393
|
+
const raw = readRam(accessor, first);
|
|
3394
|
+
const meta = await metadata(raw);
|
|
3395
|
+
const duration = meta.duration ?? 0;
|
|
3396
|
+
const start = Math.max(0, duration - n);
|
|
3397
|
+
const out = transcribe(raw, start);
|
|
3398
|
+
return [out, new IOResult30({ reads: { [first.original]: raw }, cache: [first.original] })];
|
|
3399
|
+
} catch (err) {
|
|
3400
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3401
|
+
return [
|
|
3402
|
+
null,
|
|
3403
|
+
new IOResult30({
|
|
3404
|
+
exitCode: 1,
|
|
3405
|
+
stderr: ENC31.encode(`tail: ${first.original}: failed to read as wav: ${msg}
|
|
3406
|
+
`)
|
|
3407
|
+
})
|
|
3408
|
+
];
|
|
3409
|
+
}
|
|
3410
|
+
}
|
|
3411
|
+
var RAM_LOCAL_AUDIO_TAIL_WAV = command30({
|
|
3412
|
+
name: "tail",
|
|
3413
|
+
resource: ResourceName34.RAM,
|
|
3414
|
+
spec: specOf30("tail"),
|
|
3415
|
+
filetype: ".wav",
|
|
3416
|
+
fn: tailWavCommand2
|
|
3417
|
+
});
|
|
3418
|
+
|
|
3419
|
+
// src/commands/local_audio/ram/index.ts
|
|
3420
|
+
var RAM_LOCAL_AUDIO_COMMANDS = [
|
|
3421
|
+
...RAM_LOCAL_AUDIO_CAT_WAV,
|
|
3422
|
+
...RAM_LOCAL_AUDIO_CAT_MP3,
|
|
3423
|
+
...RAM_LOCAL_AUDIO_CAT_OGG,
|
|
3424
|
+
...RAM_LOCAL_AUDIO_HEAD_WAV,
|
|
3425
|
+
...RAM_LOCAL_AUDIO_HEAD_MP3,
|
|
3426
|
+
...RAM_LOCAL_AUDIO_HEAD_OGG,
|
|
3427
|
+
...RAM_LOCAL_AUDIO_TAIL_WAV,
|
|
3428
|
+
...RAM_LOCAL_AUDIO_TAIL_MP3,
|
|
3429
|
+
...RAM_LOCAL_AUDIO_TAIL_OGG,
|
|
3430
|
+
...RAM_LOCAL_AUDIO_GREP_WAV,
|
|
3431
|
+
...RAM_LOCAL_AUDIO_GREP_MP3,
|
|
3432
|
+
...RAM_LOCAL_AUDIO_GREP_OGG,
|
|
3433
|
+
...RAM_LOCAL_AUDIO_STAT_WAV,
|
|
3434
|
+
...RAM_LOCAL_AUDIO_STAT_MP3,
|
|
3435
|
+
...RAM_LOCAL_AUDIO_STAT_OGG
|
|
3436
|
+
];
|
|
3437
|
+
|
|
3438
|
+
// src/commands/local_audio/index.ts
|
|
3439
|
+
var LOCAL_AUDIO_COMMANDS = {
|
|
3440
|
+
ram: RAM_LOCAL_AUDIO_COMMANDS,
|
|
3441
|
+
disk: DISK_LOCAL_AUDIO_COMMANDS
|
|
3442
|
+
};
|
|
3443
|
+
export {
|
|
3444
|
+
BoxResource,
|
|
3445
|
+
DISK_COMMANDS,
|
|
3446
|
+
DISK_LOCAL_AUDIO_COMMANDS,
|
|
3447
|
+
DISK_OPS,
|
|
3448
|
+
DISK_PROMPT,
|
|
3449
|
+
DiscordResource,
|
|
3450
|
+
DiskResource,
|
|
3451
|
+
DropboxResource,
|
|
3452
|
+
EMAIL_COMMANDS,
|
|
3453
|
+
EMAIL_OPS,
|
|
3454
|
+
EMAIL_PROMPT,
|
|
3455
|
+
EMAIL_WRITE_PROMPT,
|
|
3456
|
+
EmailAccessor,
|
|
3457
|
+
EmailResource,
|
|
3458
|
+
FuseManager,
|
|
3459
|
+
GCSResource,
|
|
3460
|
+
GCS_ENDPOINT,
|
|
3461
|
+
GCS_PROMPT,
|
|
3462
|
+
GDocsResource,
|
|
3463
|
+
GDriveResource,
|
|
3464
|
+
GSheetsResource,
|
|
3465
|
+
GSlidesResource,
|
|
3466
|
+
GitHubCIResource,
|
|
3467
|
+
GitHubResource,
|
|
3468
|
+
GmailResource,
|
|
3469
|
+
LOCAL_AUDIO_COMMANDS,
|
|
3470
|
+
LangfuseResource,
|
|
3471
|
+
LinearResource,
|
|
3472
|
+
MirageFS,
|
|
3473
|
+
MongoDBResource,
|
|
3474
|
+
MongoDBStore,
|
|
3475
|
+
OCIResource,
|
|
3476
|
+
OCI_PROMPT,
|
|
3477
|
+
PostHogResource,
|
|
3478
|
+
PostgresResource,
|
|
3479
|
+
PostgresStore,
|
|
3480
|
+
R2Resource,
|
|
3481
|
+
R2_PROMPT,
|
|
3482
|
+
RAM_LOCAL_AUDIO_COMMANDS,
|
|
3483
|
+
REDIS_COMMANDS,
|
|
3484
|
+
REDIS_OPS,
|
|
3485
|
+
REDIS_PROMPT,
|
|
3486
|
+
RedisAccessor,
|
|
3487
|
+
RedisFileCacheStore,
|
|
3488
|
+
RedisIndexCacheStore,
|
|
3489
|
+
RedisResource,
|
|
3490
|
+
RedisStore,
|
|
3491
|
+
S3Resource,
|
|
3492
|
+
SSCholarAuthorResource,
|
|
3493
|
+
SSCholarPaperResource,
|
|
3494
|
+
SSHAccessor,
|
|
3495
|
+
SSHResource,
|
|
3496
|
+
SSH_COMMANDS,
|
|
3497
|
+
SSH_OPS,
|
|
3498
|
+
SSH_PROMPT,
|
|
3499
|
+
SUPABASE_PROMPT,
|
|
3500
|
+
SlackResource,
|
|
3501
|
+
SupabaseResource,
|
|
3502
|
+
TrelloResource,
|
|
3503
|
+
VercelResource,
|
|
3504
|
+
Workspace,
|
|
3505
|
+
buildEmailConfig,
|
|
3506
|
+
buildResource,
|
|
3507
|
+
configure as configureLocalAudio,
|
|
3508
|
+
fileReadProvision,
|
|
3509
|
+
mount as fuseMount,
|
|
3510
|
+
mountBackground as fuseMountBackground,
|
|
3511
|
+
getConfig as getLocalAudioConfig,
|
|
3512
|
+
headTailProvision,
|
|
3513
|
+
isMacosMetadata,
|
|
3514
|
+
knownResources,
|
|
3515
|
+
estimateByteRange as localAudioEstimateByteRange,
|
|
3516
|
+
formatDuration as localAudioFormatDuration,
|
|
3517
|
+
formatMetadata as localAudioFormatMetadata,
|
|
3518
|
+
metadata as localAudioMetadata,
|
|
3519
|
+
transcribe as localAudioTranscribe,
|
|
3520
|
+
metadataProvision,
|
|
3521
|
+
nativeExec,
|
|
3522
|
+
nativeExecStream,
|
|
3523
|
+
normalizeBoxConfig,
|
|
3524
|
+
normalizeDiscordConfig,
|
|
3525
|
+
normalizeDropboxConfig,
|
|
3526
|
+
normalizeEmailConfig,
|
|
3527
|
+
normalizeGDocsConfig,
|
|
3528
|
+
normalizeGDriveConfig,
|
|
3529
|
+
normalizeGSheetsConfig,
|
|
3530
|
+
normalizeGSlidesConfig,
|
|
3531
|
+
normalizeGitHubCIConfig,
|
|
3532
|
+
normalizeGitHubConfig,
|
|
3533
|
+
normalizeGmailConfig,
|
|
3534
|
+
normalizeLangfuseConfig,
|
|
3535
|
+
normalizeLinearConfig,
|
|
3536
|
+
normalizeSlackConfig,
|
|
3537
|
+
normalizeSshConfig,
|
|
3538
|
+
normalizeTrelloConfig,
|
|
3539
|
+
patchNodeFs,
|
|
3540
|
+
redactBoxConfig,
|
|
3541
|
+
redactDiscordConfig,
|
|
3542
|
+
redactDropboxConfig,
|
|
3543
|
+
redactEmailConfig,
|
|
3544
|
+
redactGDocsConfig,
|
|
3545
|
+
redactGDriveConfig,
|
|
3546
|
+
redactGSheetsConfig,
|
|
3547
|
+
redactGSlidesConfig,
|
|
3548
|
+
redactGcsConfig,
|
|
3549
|
+
redactGitHubCIConfig,
|
|
3550
|
+
redactGitHubConfig,
|
|
3551
|
+
redactGmailConfig,
|
|
3552
|
+
redactLangfuseConfig,
|
|
3553
|
+
redactLinearConfig,
|
|
3554
|
+
redactOciConfig,
|
|
3555
|
+
redactR2Config,
|
|
3556
|
+
redactConfig as redactS3Config,
|
|
3557
|
+
redactSlackConfig,
|
|
3558
|
+
redactSshConfig,
|
|
3559
|
+
redactSupabaseConfig,
|
|
3560
|
+
redactTrelloConfig,
|
|
3561
|
+
register as registerResourceFactory,
|
|
3562
|
+
resolvedSupabaseEndpoint
|
|
3563
|
+
};
|
|
3564
|
+
//# sourceMappingURL=index.js.map
|