@nuucognition/flint-cli 0.5.5 → 0.5.6-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-VAJMJ47E.js → chunk-6MPRSFXI.js} +2 -2
- package/dist/chunk-JSBRDJBE.js +30 -0
- package/dist/{chunk-XWUP7WHQ.js → chunk-WMXC6KO6.js} +70 -12
- package/dist/{chunk-C66KJDI7.js → chunk-X6OG5PEE.js} +1 -1
- package/dist/{dist-RGQKIZQW.js → dist-EAYA2DAP.js} +8 -3
- package/dist/{exports-FO5IMLM7-EN6H3N2A.js → exports-FO5IMLM7-4DUGQDXH.js} +2 -1
- package/dist/index.js +2997 -460
- package/dist/{mesh-config-BAIYF4KD-W2RGZQ2V.js → mesh-config-BAIYF4KD-Q3ZCQOCZ.js} +1 -0
- package/dist/{metadata-SJT4H53O-7W2752ZT.js → metadata-SJT4H53O-LEFHYM5Q.js} +1 -0
- package/dist/{registry-YN5W7EY7-SZNXPBV5.js → registry-YN5W7EY7-J52KXGG5.js} +2 -1
- package/dist/{utils-BBA2XQZO-YU5SL3JY.js → utils-BBA2XQZO-ETTV2PHU.js} +1 -0
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
LiveSessionManager,
|
|
3
|
+
OBSIDIAN_REPO_URL,
|
|
4
|
+
OBSIDIAN_WINDOWS_REPO_URL,
|
|
3
5
|
STANDARD_DIRECTORIES,
|
|
4
6
|
TranscriptWatcher,
|
|
5
7
|
addCodebaseReference,
|
|
@@ -121,7 +123,7 @@ import {
|
|
|
121
123
|
updateSession,
|
|
122
124
|
updateShards,
|
|
123
125
|
updateSourceRepository
|
|
124
|
-
} from "./chunk-
|
|
126
|
+
} from "./chunk-WMXC6KO6.js";
|
|
125
127
|
import {
|
|
126
128
|
cleanRegistryFile,
|
|
127
129
|
findFlintByName,
|
|
@@ -132,7 +134,7 @@ import {
|
|
|
132
134
|
registerFlintByPath,
|
|
133
135
|
unregisterFlint,
|
|
134
136
|
upsertFlintEntry
|
|
135
|
-
} from "./chunk-
|
|
137
|
+
} from "./chunk-X6OG5PEE.js";
|
|
136
138
|
import "./chunk-V7YA5RXL.js";
|
|
137
139
|
import {
|
|
138
140
|
generateSourceMeshExportMetadata,
|
|
@@ -148,7 +150,7 @@ import {
|
|
|
148
150
|
resolveDocument,
|
|
149
151
|
scanExportEligible,
|
|
150
152
|
scanExports
|
|
151
|
-
} from "./chunk-
|
|
153
|
+
} from "./chunk-6MPRSFXI.js";
|
|
152
154
|
import {
|
|
153
155
|
addExportToConfig,
|
|
154
156
|
addLatticeDeclaration,
|
|
@@ -170,6 +172,7 @@ import {
|
|
|
170
172
|
hasFlintJson,
|
|
171
173
|
hasFlintToml,
|
|
172
174
|
isLocalShard,
|
|
175
|
+
parse,
|
|
173
176
|
readFlintJson,
|
|
174
177
|
readFlintToml,
|
|
175
178
|
readLatticesState,
|
|
@@ -184,14 +187,227 @@ import {
|
|
|
184
187
|
writeFlintJson,
|
|
185
188
|
writeFlintToml
|
|
186
189
|
} from "./chunk-CBGQBE6C.js";
|
|
190
|
+
import {
|
|
191
|
+
__commonJS,
|
|
192
|
+
__toESM
|
|
193
|
+
} from "./chunk-JSBRDJBE.js";
|
|
194
|
+
|
|
195
|
+
// ../../node_modules/.pnpm/balanced-match@1.0.2/node_modules/balanced-match/index.js
|
|
196
|
+
var require_balanced_match = __commonJS({
|
|
197
|
+
"../../node_modules/.pnpm/balanced-match@1.0.2/node_modules/balanced-match/index.js"(exports, module) {
|
|
198
|
+
"use strict";
|
|
199
|
+
module.exports = balanced;
|
|
200
|
+
function balanced(a, b, str) {
|
|
201
|
+
if (a instanceof RegExp) a = maybeMatch(a, str);
|
|
202
|
+
if (b instanceof RegExp) b = maybeMatch(b, str);
|
|
203
|
+
var r = range(a, b, str);
|
|
204
|
+
return r && {
|
|
205
|
+
start: r[0],
|
|
206
|
+
end: r[1],
|
|
207
|
+
pre: str.slice(0, r[0]),
|
|
208
|
+
body: str.slice(r[0] + a.length, r[1]),
|
|
209
|
+
post: str.slice(r[1] + b.length)
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
function maybeMatch(reg, str) {
|
|
213
|
+
var m = str.match(reg);
|
|
214
|
+
return m ? m[0] : null;
|
|
215
|
+
}
|
|
216
|
+
balanced.range = range;
|
|
217
|
+
function range(a, b, str) {
|
|
218
|
+
var begs, beg, left, right, result;
|
|
219
|
+
var ai = str.indexOf(a);
|
|
220
|
+
var bi = str.indexOf(b, ai + 1);
|
|
221
|
+
var i = ai;
|
|
222
|
+
if (ai >= 0 && bi > 0) {
|
|
223
|
+
if (a === b) {
|
|
224
|
+
return [ai, bi];
|
|
225
|
+
}
|
|
226
|
+
begs = [];
|
|
227
|
+
left = str.length;
|
|
228
|
+
while (i >= 0 && !result) {
|
|
229
|
+
if (i == ai) {
|
|
230
|
+
begs.push(i);
|
|
231
|
+
ai = str.indexOf(a, i + 1);
|
|
232
|
+
} else if (begs.length == 1) {
|
|
233
|
+
result = [begs.pop(), bi];
|
|
234
|
+
} else {
|
|
235
|
+
beg = begs.pop();
|
|
236
|
+
if (beg < left) {
|
|
237
|
+
left = beg;
|
|
238
|
+
right = bi;
|
|
239
|
+
}
|
|
240
|
+
bi = str.indexOf(b, i + 1);
|
|
241
|
+
}
|
|
242
|
+
i = ai < bi && ai >= 0 ? ai : bi;
|
|
243
|
+
}
|
|
244
|
+
if (begs.length) {
|
|
245
|
+
result = [left, right];
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return result;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
// ../../node_modules/.pnpm/brace-expansion@2.0.2/node_modules/brace-expansion/index.js
|
|
254
|
+
var require_brace_expansion = __commonJS({
|
|
255
|
+
"../../node_modules/.pnpm/brace-expansion@2.0.2/node_modules/brace-expansion/index.js"(exports, module) {
|
|
256
|
+
"use strict";
|
|
257
|
+
var balanced = require_balanced_match();
|
|
258
|
+
module.exports = expandTop;
|
|
259
|
+
var escSlash = "\0SLASH" + Math.random() + "\0";
|
|
260
|
+
var escOpen = "\0OPEN" + Math.random() + "\0";
|
|
261
|
+
var escClose = "\0CLOSE" + Math.random() + "\0";
|
|
262
|
+
var escComma = "\0COMMA" + Math.random() + "\0";
|
|
263
|
+
var escPeriod = "\0PERIOD" + Math.random() + "\0";
|
|
264
|
+
function numeric(str) {
|
|
265
|
+
return parseInt(str, 10) == str ? parseInt(str, 10) : str.charCodeAt(0);
|
|
266
|
+
}
|
|
267
|
+
function escapeBraces(str) {
|
|
268
|
+
return str.split("\\\\").join(escSlash).split("\\{").join(escOpen).split("\\}").join(escClose).split("\\,").join(escComma).split("\\.").join(escPeriod);
|
|
269
|
+
}
|
|
270
|
+
function unescapeBraces(str) {
|
|
271
|
+
return str.split(escSlash).join("\\").split(escOpen).join("{").split(escClose).join("}").split(escComma).join(",").split(escPeriod).join(".");
|
|
272
|
+
}
|
|
273
|
+
function parseCommaParts(str) {
|
|
274
|
+
if (!str)
|
|
275
|
+
return [""];
|
|
276
|
+
var parts = [];
|
|
277
|
+
var m = balanced("{", "}", str);
|
|
278
|
+
if (!m)
|
|
279
|
+
return str.split(",");
|
|
280
|
+
var pre = m.pre;
|
|
281
|
+
var body = m.body;
|
|
282
|
+
var post = m.post;
|
|
283
|
+
var p = pre.split(",");
|
|
284
|
+
p[p.length - 1] += "{" + body + "}";
|
|
285
|
+
var postParts = parseCommaParts(post);
|
|
286
|
+
if (post.length) {
|
|
287
|
+
p[p.length - 1] += postParts.shift();
|
|
288
|
+
p.push.apply(p, postParts);
|
|
289
|
+
}
|
|
290
|
+
parts.push.apply(parts, p);
|
|
291
|
+
return parts;
|
|
292
|
+
}
|
|
293
|
+
function expandTop(str) {
|
|
294
|
+
if (!str)
|
|
295
|
+
return [];
|
|
296
|
+
if (str.substr(0, 2) === "{}") {
|
|
297
|
+
str = "\\{\\}" + str.substr(2);
|
|
298
|
+
}
|
|
299
|
+
return expand2(escapeBraces(str), true).map(unescapeBraces);
|
|
300
|
+
}
|
|
301
|
+
function embrace(str) {
|
|
302
|
+
return "{" + str + "}";
|
|
303
|
+
}
|
|
304
|
+
function isPadded(el) {
|
|
305
|
+
return /^-?0\d/.test(el);
|
|
306
|
+
}
|
|
307
|
+
function lte(i, y) {
|
|
308
|
+
return i <= y;
|
|
309
|
+
}
|
|
310
|
+
function gte(i, y) {
|
|
311
|
+
return i >= y;
|
|
312
|
+
}
|
|
313
|
+
function expand2(str, isTop) {
|
|
314
|
+
var expansions = [];
|
|
315
|
+
var m = balanced("{", "}", str);
|
|
316
|
+
if (!m) return [str];
|
|
317
|
+
var pre = m.pre;
|
|
318
|
+
var post = m.post.length ? expand2(m.post, false) : [""];
|
|
319
|
+
if (/\$$/.test(m.pre)) {
|
|
320
|
+
for (var k = 0; k < post.length; k++) {
|
|
321
|
+
var expansion = pre + "{" + m.body + "}" + post[k];
|
|
322
|
+
expansions.push(expansion);
|
|
323
|
+
}
|
|
324
|
+
} else {
|
|
325
|
+
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
|
326
|
+
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
|
327
|
+
var isSequence = isNumericSequence || isAlphaSequence;
|
|
328
|
+
var isOptions = m.body.indexOf(",") >= 0;
|
|
329
|
+
if (!isSequence && !isOptions) {
|
|
330
|
+
if (m.post.match(/,(?!,).*\}/)) {
|
|
331
|
+
str = m.pre + "{" + m.body + escClose + m.post;
|
|
332
|
+
return expand2(str);
|
|
333
|
+
}
|
|
334
|
+
return [str];
|
|
335
|
+
}
|
|
336
|
+
var n;
|
|
337
|
+
if (isSequence) {
|
|
338
|
+
n = m.body.split(/\.\./);
|
|
339
|
+
} else {
|
|
340
|
+
n = parseCommaParts(m.body);
|
|
341
|
+
if (n.length === 1) {
|
|
342
|
+
n = expand2(n[0], false).map(embrace);
|
|
343
|
+
if (n.length === 1) {
|
|
344
|
+
return post.map(function(p) {
|
|
345
|
+
return m.pre + n[0] + p;
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
var N;
|
|
351
|
+
if (isSequence) {
|
|
352
|
+
var x = numeric(n[0]);
|
|
353
|
+
var y = numeric(n[1]);
|
|
354
|
+
var width = Math.max(n[0].length, n[1].length);
|
|
355
|
+
var incr = n.length == 3 ? Math.abs(numeric(n[2])) : 1;
|
|
356
|
+
var test = lte;
|
|
357
|
+
var reverse = y < x;
|
|
358
|
+
if (reverse) {
|
|
359
|
+
incr *= -1;
|
|
360
|
+
test = gte;
|
|
361
|
+
}
|
|
362
|
+
var pad3 = n.some(isPadded);
|
|
363
|
+
N = [];
|
|
364
|
+
for (var i = x; test(i, y); i += incr) {
|
|
365
|
+
var c;
|
|
366
|
+
if (isAlphaSequence) {
|
|
367
|
+
c = String.fromCharCode(i);
|
|
368
|
+
if (c === "\\")
|
|
369
|
+
c = "";
|
|
370
|
+
} else {
|
|
371
|
+
c = String(i);
|
|
372
|
+
if (pad3) {
|
|
373
|
+
var need = width - c.length;
|
|
374
|
+
if (need > 0) {
|
|
375
|
+
var z = new Array(need + 1).join("0");
|
|
376
|
+
if (i < 0)
|
|
377
|
+
c = "-" + z + c.slice(1);
|
|
378
|
+
else
|
|
379
|
+
c = z + c;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
N.push(c);
|
|
384
|
+
}
|
|
385
|
+
} else {
|
|
386
|
+
N = [];
|
|
387
|
+
for (var j = 0; j < n.length; j++) {
|
|
388
|
+
N.push.apply(N, expand2(n[j], false));
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
for (var j = 0; j < N.length; j++) {
|
|
392
|
+
for (var k = 0; k < post.length; k++) {
|
|
393
|
+
var expansion = pre + N[j] + post[k];
|
|
394
|
+
if (!isTop || isSequence || expansion)
|
|
395
|
+
expansions.push(expansion);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return expansions;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
});
|
|
187
403
|
|
|
188
404
|
// src/index.ts
|
|
189
|
-
import { Command as
|
|
405
|
+
import { Command as Command38 } from "commander";
|
|
190
406
|
import { readFileSync as readFileSync11, existsSync as existsSync15, cpSync, mkdirSync as mkdirSync5, readdirSync as readdirSync8 } from "fs";
|
|
191
407
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
192
|
-
import { dirname as dirname4, join as
|
|
408
|
+
import { dirname as dirname4, join as join20 } from "path";
|
|
193
409
|
import { homedir as homedir11 } from "os";
|
|
194
|
-
import
|
|
410
|
+
import pc43 from "picocolors";
|
|
195
411
|
|
|
196
412
|
// ../../../main/packages/cli-core/dist/index.js
|
|
197
413
|
import { homedir } from "os";
|
|
@@ -275,7 +491,7 @@ function skipVoid(str, ptr, banNewLines, banComments) {
|
|
|
275
491
|
ptr++;
|
|
276
492
|
return banComments || c !== "#" ? ptr : skipVoid(str, skipComment(str, ptr), banNewLines);
|
|
277
493
|
}
|
|
278
|
-
function skipUntil(str, ptr,
|
|
494
|
+
function skipUntil(str, ptr, sep2, end, banNewLines = false) {
|
|
279
495
|
if (!end) {
|
|
280
496
|
ptr = indexOfNewline(str, ptr);
|
|
281
497
|
return ptr < 0 ? str.length : ptr;
|
|
@@ -284,7 +500,7 @@ function skipUntil(str, ptr, sep, end, banNewLines = false) {
|
|
|
284
500
|
let c = str[i];
|
|
285
501
|
if (c === "#") {
|
|
286
502
|
i = indexOfNewline(str, i);
|
|
287
|
-
} else if (c ===
|
|
503
|
+
} else if (c === sep2) {
|
|
288
504
|
return i + 1;
|
|
289
505
|
} else if (c === end || banNewLines && (c === "\n" || c === "\r" && str[i + 1] === "\n")) {
|
|
290
506
|
return i;
|
|
@@ -325,18 +541,18 @@ var TomlDate = class _TomlDate extends Date {
|
|
|
325
541
|
let hasTime = true;
|
|
326
542
|
let offset = "Z";
|
|
327
543
|
if (typeof date === "string") {
|
|
328
|
-
let
|
|
329
|
-
if (
|
|
330
|
-
if (!
|
|
544
|
+
let match2 = date.match(DATE_TIME_RE);
|
|
545
|
+
if (match2) {
|
|
546
|
+
if (!match2[1]) {
|
|
331
547
|
hasDate = false;
|
|
332
548
|
date = `0000-01-01T${date}`;
|
|
333
549
|
}
|
|
334
|
-
hasTime = !!
|
|
550
|
+
hasTime = !!match2[2];
|
|
335
551
|
hasTime && date[10] === " " && (date = date.replace(" ", "T"));
|
|
336
|
-
if (
|
|
552
|
+
if (match2[2] && +match2[2] > 23) {
|
|
337
553
|
date = "";
|
|
338
554
|
} else {
|
|
339
|
-
offset =
|
|
555
|
+
offset = match2[3] || null;
|
|
340
556
|
date = date.toUpperCase();
|
|
341
557
|
if (!offset && hasTime)
|
|
342
558
|
date += "Z";
|
|
@@ -820,7 +1036,7 @@ function peekTable(key, table, meta, type) {
|
|
|
820
1036
|
}
|
|
821
1037
|
return [k, t, state.c];
|
|
822
1038
|
}
|
|
823
|
-
function
|
|
1039
|
+
function parse2(toml, { maxDepth = 1e3, integersAsBigInt } = {}) {
|
|
824
1040
|
let res = {};
|
|
825
1041
|
let meta = {};
|
|
826
1042
|
let tbl = res;
|
|
@@ -1189,8 +1405,8 @@ async function defaultBrowserId() {
|
|
|
1189
1405
|
throw new Error("macOS only");
|
|
1190
1406
|
}
|
|
1191
1407
|
const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
|
|
1192
|
-
const
|
|
1193
|
-
const browserId =
|
|
1408
|
+
const match2 = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
|
|
1409
|
+
const browserId = match2?.groups.id ?? "com.apple.Safari";
|
|
1194
1410
|
if (browserId === "com.apple.safari") {
|
|
1195
1411
|
return "com.apple.Safari";
|
|
1196
1412
|
}
|
|
@@ -1254,11 +1470,11 @@ async function defaultBrowser(_execFileAsync = execFileAsync3) {
|
|
|
1254
1470
|
"/v",
|
|
1255
1471
|
"ProgId"
|
|
1256
1472
|
]);
|
|
1257
|
-
const
|
|
1258
|
-
if (!
|
|
1473
|
+
const match2 = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
|
|
1474
|
+
if (!match2) {
|
|
1259
1475
|
throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
|
|
1260
1476
|
}
|
|
1261
|
-
const { id } =
|
|
1477
|
+
const { id } = match2.groups;
|
|
1262
1478
|
const browser = windowsBrowserProgIds[id];
|
|
1263
1479
|
if (!browser) {
|
|
1264
1480
|
throw new UnknownBrowserError(`Unknown browser ID: ${id}`);
|
|
@@ -1566,10 +1782,10 @@ function normalizeRuntimeMode(input) {
|
|
|
1566
1782
|
function authEnvForMode(mode) {
|
|
1567
1783
|
return mode === "dev" ? "dev" : "prod";
|
|
1568
1784
|
}
|
|
1569
|
-
async function readConfigFile(
|
|
1785
|
+
async function readConfigFile(path10) {
|
|
1570
1786
|
try {
|
|
1571
|
-
const content = await fsReadFile(
|
|
1572
|
-
return
|
|
1787
|
+
const content = await fsReadFile(path10, "utf-8");
|
|
1788
|
+
return parse2(content);
|
|
1573
1789
|
} catch (error22) {
|
|
1574
1790
|
if (error22.code === "ENOENT") {
|
|
1575
1791
|
return null;
|
|
@@ -1577,10 +1793,10 @@ async function readConfigFile(path8) {
|
|
|
1577
1793
|
throw error22;
|
|
1578
1794
|
}
|
|
1579
1795
|
}
|
|
1580
|
-
function readConfigFileSync(
|
|
1796
|
+
function readConfigFileSync(path10) {
|
|
1581
1797
|
try {
|
|
1582
|
-
const content = fsReadFileSync(
|
|
1583
|
-
return
|
|
1798
|
+
const content = fsReadFileSync(path10, "utf-8");
|
|
1799
|
+
return parse2(content);
|
|
1584
1800
|
} catch (error22) {
|
|
1585
1801
|
if (error22.code === "ENOENT") {
|
|
1586
1802
|
return null;
|
|
@@ -1588,25 +1804,25 @@ function readConfigFileSync(path8) {
|
|
|
1588
1804
|
throw error22;
|
|
1589
1805
|
}
|
|
1590
1806
|
}
|
|
1591
|
-
async function writeConfigFile(
|
|
1592
|
-
await mkdir(dirname(
|
|
1593
|
-
await fsWriteFile(
|
|
1807
|
+
async function writeConfigFile(path10, data) {
|
|
1808
|
+
await mkdir(dirname(path10), { recursive: true });
|
|
1809
|
+
await fsWriteFile(path10, `${stringify(data)}
|
|
1594
1810
|
`, "utf-8");
|
|
1595
1811
|
}
|
|
1596
|
-
async function setConfigField(
|
|
1597
|
-
const existing = await readConfigFile(
|
|
1812
|
+
async function setConfigField(path10, key, value) {
|
|
1813
|
+
const existing = await readConfigFile(path10) ?? {};
|
|
1598
1814
|
existing[key] = value;
|
|
1599
|
-
await writeConfigFile(
|
|
1815
|
+
await writeConfigFile(path10, existing);
|
|
1600
1816
|
}
|
|
1601
|
-
async function setFeatureOverride(
|
|
1602
|
-
const existing = await readConfigFile(
|
|
1817
|
+
async function setFeatureOverride(path10, featureId, enabled) {
|
|
1818
|
+
const existing = await readConfigFile(path10) ?? {};
|
|
1603
1819
|
const features = existing.features && typeof existing.features === "object" && !Array.isArray(existing.features) ? { ...existing.features } : {};
|
|
1604
1820
|
features[featureId] = enabled;
|
|
1605
1821
|
existing.features = features;
|
|
1606
|
-
await writeConfigFile(
|
|
1822
|
+
await writeConfigFile(path10, existing);
|
|
1607
1823
|
}
|
|
1608
|
-
async function removeFeatureOverride(
|
|
1609
|
-
const existing = await readConfigFile(
|
|
1824
|
+
async function removeFeatureOverride(path10, featureId) {
|
|
1825
|
+
const existing = await readConfigFile(path10);
|
|
1610
1826
|
if (!existing) return;
|
|
1611
1827
|
const features = existing.features;
|
|
1612
1828
|
if (!features || typeof features !== "object" || Array.isArray(features)) {
|
|
@@ -1619,7 +1835,7 @@ async function removeFeatureOverride(path8, featureId) {
|
|
|
1619
1835
|
} else {
|
|
1620
1836
|
existing.features = next;
|
|
1621
1837
|
}
|
|
1622
|
-
await writeConfigFile(
|
|
1838
|
+
await writeConfigFile(path10, existing);
|
|
1623
1839
|
}
|
|
1624
1840
|
var CONFIG_FILENAME = "config.toml";
|
|
1625
1841
|
function getConfigDir(cliname) {
|
|
@@ -1628,10 +1844,10 @@ function getConfigDir(cliname) {
|
|
|
1628
1844
|
function getConfigPath(cliname) {
|
|
1629
1845
|
return join(getConfigDir(cliname), CONFIG_FILENAME);
|
|
1630
1846
|
}
|
|
1631
|
-
function mergeDefaults(config,
|
|
1632
|
-
if (!
|
|
1847
|
+
function mergeDefaults(config, defaults2) {
|
|
1848
|
+
if (!defaults2) return config;
|
|
1633
1849
|
return {
|
|
1634
|
-
...
|
|
1850
|
+
...defaults2,
|
|
1635
1851
|
...config
|
|
1636
1852
|
};
|
|
1637
1853
|
}
|
|
@@ -1828,9 +2044,9 @@ async function loadAuth(env = "prod") {
|
|
|
1828
2044
|
function loadAuthSync(env = "prod") {
|
|
1829
2045
|
try {
|
|
1830
2046
|
ensureNuuDirSync();
|
|
1831
|
-
const
|
|
1832
|
-
if (!existsSync(
|
|
1833
|
-
return normalizeCredentials(JSON.parse(readFileSync(
|
|
2047
|
+
const path10 = authPath(env);
|
|
2048
|
+
if (!existsSync(path10)) return null;
|
|
2049
|
+
return normalizeCredentials(JSON.parse(readFileSync(path10, "utf-8")));
|
|
1834
2050
|
} catch {
|
|
1835
2051
|
return null;
|
|
1836
2052
|
}
|
|
@@ -2319,6 +2535,7 @@ var FEATURES = createFeatureRegistry([
|
|
|
2319
2535
|
{ id: "code", tier: "prod", type: "command", description: "Launch AI coding agents", requiresAuth: false },
|
|
2320
2536
|
{ id: "orb", tier: "prod", type: "command", description: "Orbh meta-harness agent management", requiresAuth: false },
|
|
2321
2537
|
{ id: "server", tier: "prod", type: "command", description: "Flint runtime server", requiresAuth: false },
|
|
2538
|
+
{ id: "steel", tier: "prod", type: "command", description: "Manage Steel UI state", requiresAuth: false },
|
|
2322
2539
|
{ id: "runtime", tier: "dev", type: "command", description: "Flint runtime management", requiresAuth: false },
|
|
2323
2540
|
{ id: "obsidian.push", tier: "dev", type: "function", description: "Push obsidian config changes to remote", requiresAuth: false },
|
|
2324
2541
|
{ id: "agent.start", tier: "dev", type: "function", description: "Start AI agent session", requiresAuth: false }
|
|
@@ -2395,25 +2612,25 @@ function createProgressDisplay(label, total) {
|
|
|
2395
2612
|
import { homedir as homedir3 } from "os";
|
|
2396
2613
|
import { access } from "fs/promises";
|
|
2397
2614
|
import { createInterface } from "readline";
|
|
2398
|
-
function abbreviatePath(
|
|
2615
|
+
function abbreviatePath(path10) {
|
|
2399
2616
|
const home = homedir3();
|
|
2400
|
-
if (
|
|
2401
|
-
return
|
|
2617
|
+
if (path10.startsWith(home)) {
|
|
2618
|
+
return path10.replace(home, "~");
|
|
2402
2619
|
}
|
|
2403
|
-
return
|
|
2620
|
+
return path10;
|
|
2404
2621
|
}
|
|
2405
|
-
function expandPath(
|
|
2406
|
-
if (
|
|
2407
|
-
return
|
|
2622
|
+
function expandPath(path10) {
|
|
2623
|
+
if (path10.startsWith("~/")) {
|
|
2624
|
+
return path10.replace("~", homedir3());
|
|
2408
2625
|
}
|
|
2409
|
-
return
|
|
2626
|
+
return path10;
|
|
2410
2627
|
}
|
|
2411
2628
|
function padEnd(str, length) {
|
|
2412
2629
|
return str.padEnd(length);
|
|
2413
2630
|
}
|
|
2414
|
-
async function checkPathExists(
|
|
2631
|
+
async function checkPathExists(path10) {
|
|
2415
2632
|
try {
|
|
2416
|
-
await access(
|
|
2633
|
+
await access(path10);
|
|
2417
2634
|
return true;
|
|
2418
2635
|
} catch {
|
|
2419
2636
|
return false;
|
|
@@ -2664,12 +2881,12 @@ function resolvePath(flint, fullPath) {
|
|
|
2664
2881
|
}
|
|
2665
2882
|
function printFlint(flint, opts) {
|
|
2666
2883
|
const { nameColWidth, showStatus, fullPath, indent = " " } = opts;
|
|
2667
|
-
const
|
|
2884
|
+
const path10 = resolvePath(flint, fullPath);
|
|
2668
2885
|
const isBroken = showStatus && !flint.valid;
|
|
2669
2886
|
const tags = formatTags(flint.tags);
|
|
2670
2887
|
const nameCell = tags ? `${pc7.bold(flint.name)} ${tags}` : pc7.bold(flint.name);
|
|
2671
2888
|
const status = showStatus ? statusBadge(flint) + " " : "";
|
|
2672
|
-
const pathColor = isBroken ? pc7.red(
|
|
2889
|
+
const pathColor = isBroken ? pc7.red(path10) : pc7.dim(path10);
|
|
2673
2890
|
console.log(`${indent}${pad(nameCell, nameColWidth)}${status}${pathColor}`);
|
|
2674
2891
|
if (flint.description) {
|
|
2675
2892
|
console.log(`${indent} ${pc7.dim(truncate(flint.description, 65))}`);
|
|
@@ -2677,10 +2894,10 @@ function printFlint(flint, opts) {
|
|
|
2677
2894
|
}
|
|
2678
2895
|
function printGroupRow(flint, opts) {
|
|
2679
2896
|
const { nameColWidth, showStatus, fullPath } = opts;
|
|
2680
|
-
const
|
|
2897
|
+
const path10 = resolvePath(flint, fullPath);
|
|
2681
2898
|
const isBroken = showStatus && !flint.valid;
|
|
2682
2899
|
const status = showStatus ? statusBadge(flint) + " " : "";
|
|
2683
|
-
const pathColor = isBroken ? pc7.red(
|
|
2900
|
+
const pathColor = isBroken ? pc7.red(path10) : pc7.dim(path10);
|
|
2684
2901
|
console.log(` ${pad(flint.name, nameColWidth)}${status}${pathColor}`);
|
|
2685
2902
|
}
|
|
2686
2903
|
function measureNameCol(flints) {
|
|
@@ -3208,9 +3425,9 @@ Uninstalled ${pc8.bold(result.name)}`));
|
|
|
3208
3425
|
if (!existsSync3(gitDir)) continue;
|
|
3209
3426
|
try {
|
|
3210
3427
|
const url = execSync6("git remote get-url origin", { cwd: shardPath, encoding: "utf-8" }).trim();
|
|
3211
|
-
const
|
|
3212
|
-
if (
|
|
3213
|
-
gitRemotes.set(shard.name,
|
|
3428
|
+
const match2 = url.match(/(?:github\.com[/:])([\w.-]+\/[\w.-]+?)(?:\.git)?$/);
|
|
3429
|
+
if (match2) {
|
|
3430
|
+
gitRemotes.set(shard.name, match2[1]);
|
|
3214
3431
|
}
|
|
3215
3432
|
} catch {
|
|
3216
3433
|
}
|
|
@@ -3421,8 +3638,8 @@ Cloned ${pc8.bold(result.name)} for development`));
|
|
|
3421
3638
|
try {
|
|
3422
3639
|
const flintPath = await resolveFlint(options.path);
|
|
3423
3640
|
const installed = await getInstalledShardsWithVersions(flintPath);
|
|
3424
|
-
const
|
|
3425
|
-
if (!
|
|
3641
|
+
const match2 = resolveInstalledShardInfo(installed, name);
|
|
3642
|
+
if (!match2) {
|
|
3426
3643
|
console.error(pc8.red(`
|
|
3427
3644
|
Shard "${name}" not found.`));
|
|
3428
3645
|
console.log(pc8.dim(` Run ${pc8.cyan("flint shard list")} to see installed shards.`));
|
|
@@ -3430,11 +3647,11 @@ Shard "${name}" not found.`));
|
|
|
3430
3647
|
return;
|
|
3431
3648
|
}
|
|
3432
3649
|
const declarations = await getShardDeclarations(flintPath);
|
|
3433
|
-
const decl = declarations[
|
|
3650
|
+
const decl = declarations[match2.name];
|
|
3434
3651
|
const source = decl?.source || "";
|
|
3435
3652
|
console.log(pc8.dim(`
|
|
3436
|
-
Transitioning ${
|
|
3437
|
-
const result = await editShard(flintPath,
|
|
3653
|
+
Transitioning ${match2.folderName} to dev mode...`));
|
|
3654
|
+
const result = await editShard(flintPath, match2.folderName, source);
|
|
3438
3655
|
await updateGitignore(flintPath);
|
|
3439
3656
|
console.log(pc8.green(`
|
|
3440
3657
|
${pc8.bold(result.name)} is now in dev mode`));
|
|
@@ -3451,8 +3668,8 @@ ${pc8.bold(result.name)} is now in dev mode`));
|
|
|
3451
3668
|
try {
|
|
3452
3669
|
const flintPath = await resolveFlint(options.path);
|
|
3453
3670
|
const installed = await getInstalledShardsWithVersions(flintPath);
|
|
3454
|
-
const
|
|
3455
|
-
if (!
|
|
3671
|
+
const match2 = resolveInstalledShardInfo(installed, name);
|
|
3672
|
+
if (!match2) {
|
|
3456
3673
|
console.error(pc8.red(`
|
|
3457
3674
|
Shard "${name}" not found.`));
|
|
3458
3675
|
console.log(pc8.dim(` Run ${pc8.cyan("flint shard list")} to see installed shards.`));
|
|
@@ -3460,8 +3677,8 @@ Shard "${name}" not found.`));
|
|
|
3460
3677
|
return;
|
|
3461
3678
|
}
|
|
3462
3679
|
console.log(pc8.dim(`
|
|
3463
|
-
Freezing ${
|
|
3464
|
-
const result = await freezeShard(flintPath,
|
|
3680
|
+
Freezing ${match2.folderName}...`));
|
|
3681
|
+
const result = await freezeShard(flintPath, match2.folderName);
|
|
3465
3682
|
await updateGitignore(flintPath);
|
|
3466
3683
|
console.log(pc8.green(`
|
|
3467
3684
|
${pc8.bold(result.name)} is now a normal shard`));
|
|
@@ -3478,17 +3695,17 @@ ${pc8.bold(result.name)} is now a normal shard`));
|
|
|
3478
3695
|
try {
|
|
3479
3696
|
const flintPath = await resolveFlint(options.path);
|
|
3480
3697
|
const installed = await getInstalledShardsWithVersions(flintPath);
|
|
3481
|
-
const
|
|
3482
|
-
if (!
|
|
3698
|
+
const match2 = resolveInstalledShardInfo(installed, name);
|
|
3699
|
+
if (!match2) {
|
|
3483
3700
|
console.error(pc8.red(`
|
|
3484
3701
|
Shard "${name}" not found.`));
|
|
3485
3702
|
console.log(pc8.dim(` Run ${pc8.cyan("flint shard list")} to see installed shards.`));
|
|
3486
3703
|
console.log();
|
|
3487
3704
|
return;
|
|
3488
3705
|
}
|
|
3489
|
-
const result = await addShardGitRemote(flintPath,
|
|
3706
|
+
const result = await addShardGitRemote(flintPath, match2.folderName, url);
|
|
3490
3707
|
console.log(pc8.green(`
|
|
3491
|
-
Remote added to ${pc8.bold(
|
|
3708
|
+
Remote added to ${pc8.bold(match2.folderName)}`));
|
|
3492
3709
|
console.log(pc8.dim(` Remote: origin \u2192 ${url}`));
|
|
3493
3710
|
console.log(pc8.dim(` Source: ${result.ownerRepo}`));
|
|
3494
3711
|
console.log();
|
|
@@ -3614,15 +3831,15 @@ Shard not found: "${identifier}"`));
|
|
|
3614
3831
|
const installed = await getInstalledShardsWithVersions(flintPath);
|
|
3615
3832
|
const targets = [];
|
|
3616
3833
|
if (name) {
|
|
3617
|
-
const
|
|
3618
|
-
if (!
|
|
3834
|
+
const match2 = resolveInstalledShardInfo(installed, name);
|
|
3835
|
+
if (!match2) {
|
|
3619
3836
|
console.error(pc8.red(`
|
|
3620
3837
|
Shard "${name}" not found.`));
|
|
3621
3838
|
console.log(pc8.dim(` Run ${pc8.cyan("flint shard list")} to see installed shards.`));
|
|
3622
3839
|
console.log();
|
|
3623
3840
|
return;
|
|
3624
3841
|
}
|
|
3625
|
-
targets.push(
|
|
3842
|
+
targets.push(match2);
|
|
3626
3843
|
} else {
|
|
3627
3844
|
for (const s of installed) {
|
|
3628
3845
|
targets.push({ folderName: s.folderName });
|
|
@@ -3749,8 +3966,8 @@ Reinstalling ${shorthand}...
|
|
|
3749
3966
|
const { execSync: execSync6 } = await import("child_process");
|
|
3750
3967
|
const flintPath = await resolveFlint(options.path);
|
|
3751
3968
|
const installed = await getInstalledShardsWithVersions(flintPath);
|
|
3752
|
-
const
|
|
3753
|
-
if (!
|
|
3969
|
+
const match2 = resolveInstalledShardInfo(installed, name);
|
|
3970
|
+
if (!match2) {
|
|
3754
3971
|
console.error(pc8.red(`
|
|
3755
3972
|
Shard "${name}" not found.`));
|
|
3756
3973
|
console.log(pc8.dim(` Run ${pc8.cyan("flint shard list")} to see installed shards.`));
|
|
@@ -3758,28 +3975,28 @@ Shard "${name}" not found.`));
|
|
|
3758
3975
|
return;
|
|
3759
3976
|
}
|
|
3760
3977
|
const declarations = await getShardDeclarations(flintPath);
|
|
3761
|
-
const declaration = declarations[
|
|
3978
|
+
const declaration = declarations[match2.name];
|
|
3762
3979
|
const gitInitMode = declaration ? resolveShardMode(declaration) : void 0;
|
|
3763
3980
|
if (gitInitMode === "custom") {
|
|
3764
3981
|
console.error(pc8.red(`
|
|
3765
|
-
"${
|
|
3982
|
+
"${match2.folderName}" is a custom shard. Custom shards cannot have git remotes.`));
|
|
3766
3983
|
console.log();
|
|
3767
3984
|
return;
|
|
3768
3985
|
}
|
|
3769
3986
|
if (gitInitMode !== "dev") {
|
|
3770
3987
|
console.error(pc8.red(`
|
|
3771
|
-
"${
|
|
3988
|
+
"${match2.folderName}" is not a dev shard.`));
|
|
3772
3989
|
console.log();
|
|
3773
3990
|
return;
|
|
3774
3991
|
}
|
|
3775
|
-
const shardPath = join5(flintPath, "Shards",
|
|
3992
|
+
const shardPath = join5(flintPath, "Shards", match2.folderName);
|
|
3776
3993
|
const gitDir = join5(shardPath, ".git");
|
|
3777
3994
|
const hasGit = existsSync3(gitDir);
|
|
3778
3995
|
if (hasGit) {
|
|
3779
3996
|
try {
|
|
3780
3997
|
const existing = execSync6("git remote get-url origin", { cwd: shardPath, stdio: "pipe" }).toString().trim();
|
|
3781
3998
|
console.error(pc8.red(`
|
|
3782
|
-
"${
|
|
3999
|
+
"${match2.folderName}" already has a remote: ${existing}`));
|
|
3783
4000
|
console.log(pc8.dim(` Use ${pc8.cyan("flint shard push")} instead.`));
|
|
3784
4001
|
console.log();
|
|
3785
4002
|
return;
|
|
@@ -3787,7 +4004,7 @@ Shard "${name}" not found.`));
|
|
|
3787
4004
|
}
|
|
3788
4005
|
}
|
|
3789
4006
|
console.log(pc8.bold(`
|
|
3790
|
-
Initializing ${
|
|
4007
|
+
Initializing ${match2.folderName}...
|
|
3791
4008
|
`));
|
|
3792
4009
|
if (!hasGit) {
|
|
3793
4010
|
execSync6("git init", { cwd: shardPath, stdio: "pipe" });
|
|
@@ -3798,7 +4015,7 @@ Initializing ${match.folderName}...
|
|
|
3798
4015
|
execSync6('git commit -m "initial commit"', { cwd: shardPath, stdio: "pipe" });
|
|
3799
4016
|
execSync6("git push -u origin main", { cwd: shardPath, stdio: "inherit" });
|
|
3800
4017
|
console.log(pc8.green(`
|
|
3801
|
-
${pc8.bold(
|
|
4018
|
+
${pc8.bold(match2.folderName)} pushed to ${pc8.dim(url)}`));
|
|
3802
4019
|
console.log();
|
|
3803
4020
|
} catch (err) {
|
|
3804
4021
|
handleError(err);
|
|
@@ -3810,8 +4027,8 @@ Initializing ${match.folderName}...
|
|
|
3810
4027
|
const { execSync: execSync6 } = await import("child_process");
|
|
3811
4028
|
const flintPath = await resolveFlint(options.path);
|
|
3812
4029
|
const installed = await getInstalledShardsWithVersions(flintPath);
|
|
3813
|
-
const
|
|
3814
|
-
if (!
|
|
4030
|
+
const match2 = resolveInstalledShardInfo(installed, name);
|
|
4031
|
+
if (!match2) {
|
|
3815
4032
|
console.error(pc8.red(`
|
|
3816
4033
|
Shard "${name}" not found.`));
|
|
3817
4034
|
console.log(pc8.dim(` Run ${pc8.cyan("flint shard list")} to see installed shards.`));
|
|
@@ -3819,26 +4036,26 @@ Shard "${name}" not found.`));
|
|
|
3819
4036
|
return;
|
|
3820
4037
|
}
|
|
3821
4038
|
const declarations = await getShardDeclarations(flintPath);
|
|
3822
|
-
const declaration = declarations[
|
|
4039
|
+
const declaration = declarations[match2.name];
|
|
3823
4040
|
const shardMode = declaration ? resolveShardMode(declaration) : void 0;
|
|
3824
4041
|
if (shardMode === "custom") {
|
|
3825
4042
|
console.error(pc8.red(`
|
|
3826
|
-
"${
|
|
4043
|
+
"${match2.folderName}" is a custom shard. Custom shards are workspace-specific and cannot be pushed.`));
|
|
3827
4044
|
console.log();
|
|
3828
4045
|
return;
|
|
3829
4046
|
}
|
|
3830
4047
|
if (shardMode !== "dev") {
|
|
3831
4048
|
console.error(pc8.red(`
|
|
3832
|
-
"${
|
|
4049
|
+
"${match2.folderName}" is not a dev shard. Only dev shards can be pushed.`));
|
|
3833
4050
|
console.log();
|
|
3834
4051
|
return;
|
|
3835
4052
|
}
|
|
3836
|
-
const shardPath = join5(flintPath, "Shards",
|
|
4053
|
+
const shardPath = join5(flintPath, "Shards", match2.folderName);
|
|
3837
4054
|
const gitDir = join5(shardPath, ".git");
|
|
3838
4055
|
if (!existsSync3(gitDir)) {
|
|
3839
4056
|
console.error(pc8.red(`
|
|
3840
|
-
"${
|
|
3841
|
-
console.log(pc8.dim(` cd "Shards/${
|
|
4057
|
+
"${match2.folderName}" has no git repo. Initialize one first:`));
|
|
4058
|
+
console.log(pc8.dim(` cd "Shards/${match2.folderName}" && git init && git remote add origin <url>`));
|
|
3842
4059
|
console.log();
|
|
3843
4060
|
return;
|
|
3844
4061
|
}
|
|
@@ -3848,7 +4065,7 @@ Shard "${name}" not found.`));
|
|
|
3848
4065
|
const unpushed = execSync6("git log @{u}..HEAD --oneline", { cwd: shardPath, encoding: "utf-8" }).trim();
|
|
3849
4066
|
if (unpushed) {
|
|
3850
4067
|
console.log(pc8.bold(`
|
|
3851
|
-
Pushing ${
|
|
4068
|
+
Pushing ${match2.folderName}...
|
|
3852
4069
|
`));
|
|
3853
4070
|
execSync6("git push", { cwd: shardPath, stdio: "inherit" });
|
|
3854
4071
|
console.log(pc8.green(`
|
|
@@ -3859,7 +4076,7 @@ Pushing ${match.folderName}...
|
|
|
3859
4076
|
} catch {
|
|
3860
4077
|
}
|
|
3861
4078
|
console.log(pc8.dim(`
|
|
3862
|
-
No changes to push in "${
|
|
4079
|
+
No changes to push in "${match2.folderName}".`));
|
|
3863
4080
|
console.log();
|
|
3864
4081
|
return;
|
|
3865
4082
|
}
|
|
@@ -3872,9 +4089,9 @@ Invalid bump level "${level}". Use: patch, minor, or major.`));
|
|
|
3872
4089
|
console.log();
|
|
3873
4090
|
return;
|
|
3874
4091
|
}
|
|
3875
|
-
const { readFile:
|
|
4092
|
+
const { readFile: readFile10, writeFile: writeFile7 } = await import("fs/promises");
|
|
3876
4093
|
const yamlPath = join5(shardPath, "shard.yaml");
|
|
3877
|
-
const yamlContent = await
|
|
4094
|
+
const yamlContent = await readFile10(yamlPath, "utf-8");
|
|
3878
4095
|
const versionMatch = yamlContent.match(/^version:\s*"?(\d+)\.(\d+)\.(\d+)"?/m);
|
|
3879
4096
|
if (!versionMatch) {
|
|
3880
4097
|
console.error(pc8.red(`
|
|
@@ -3889,10 +4106,10 @@ Could not parse version from shard.yaml.`));
|
|
|
3889
4106
|
const updatedYaml = yamlContent.replace(/^version:\s*.+$/m, `version: "${bumpedVersion}"`);
|
|
3890
4107
|
await writeFile7(yamlPath, updatedYaml, "utf-8");
|
|
3891
4108
|
}
|
|
3892
|
-
const baseMessage = options.message || `update ${
|
|
4109
|
+
const baseMessage = options.message || `update ${match2.folderName.replace(/^\(Dev\)\s*/, "")} shard`;
|
|
3893
4110
|
const message = bumpedVersion ? `v${bumpedVersion} ${baseMessage}` : baseMessage;
|
|
3894
4111
|
console.log(pc8.bold(`
|
|
3895
|
-
Pushing ${
|
|
4112
|
+
Pushing ${match2.folderName}...
|
|
3896
4113
|
`));
|
|
3897
4114
|
execSync6("git add -A", { cwd: shardPath, stdio: "pipe" });
|
|
3898
4115
|
execSync6(`git commit -m "${message.replace(/"/g, '\\"')}"`, { cwd: shardPath, stdio: "pipe" });
|
|
@@ -3903,7 +4120,7 @@ Pushing ${match.folderName}...
|
|
|
3903
4120
|
execSync6(`git push -u origin ${branch}`, { cwd: shardPath, stdio: "inherit" });
|
|
3904
4121
|
}
|
|
3905
4122
|
console.log(pc8.green(`
|
|
3906
|
-
${pc8.bold(
|
|
4123
|
+
${pc8.bold(match2.folderName)} pushed.`));
|
|
3907
4124
|
console.log(pc8.dim(` ${message}`));
|
|
3908
4125
|
console.log();
|
|
3909
4126
|
} catch (err) {
|
|
@@ -3924,15 +4141,15 @@ Pushing ${match.folderName}...
|
|
|
3924
4141
|
try {
|
|
3925
4142
|
const flintPath = await resolveFlint(options.path);
|
|
3926
4143
|
const installed = await getInstalledShardsWithVersions(flintPath);
|
|
3927
|
-
const
|
|
3928
|
-
if (!
|
|
4144
|
+
const match2 = resolveInstalledShardInfo(installed, name);
|
|
4145
|
+
if (!match2) {
|
|
3929
4146
|
console.error(pc8.red(`
|
|
3930
4147
|
Shard "${name}" not found.`));
|
|
3931
4148
|
console.log(pc8.dim(` Run ${pc8.cyan("flint shard list")} to see installed shards.`));
|
|
3932
4149
|
console.log();
|
|
3933
4150
|
process.exit(1);
|
|
3934
4151
|
}
|
|
3935
|
-
const shardPath = join5(flintPath, "Shards",
|
|
4152
|
+
const shardPath = join5(flintPath, "Shards", match2.folderName);
|
|
3936
4153
|
const detail2 = await getShardInfo(flintPath, name);
|
|
3937
4154
|
if (!detail2) {
|
|
3938
4155
|
console.error(pc8.red(`
|
|
@@ -3940,7 +4157,7 @@ Cannot read shard info for "${name}".`));
|
|
|
3940
4157
|
process.exit(1);
|
|
3941
4158
|
}
|
|
3942
4159
|
const declarations = await getShardDeclarations(flintPath);
|
|
3943
|
-
const declaration = declarations[
|
|
4160
|
+
const declaration = declarations[match2.name];
|
|
3944
4161
|
let repo = "";
|
|
3945
4162
|
if (declaration?.source) {
|
|
3946
4163
|
const parsed = parseShardSource(declaration.source);
|
|
@@ -4969,11 +5186,12 @@ var REQUIRED_DIRS = [
|
|
|
4969
5186
|
"Exports",
|
|
4970
5187
|
"Workspace",
|
|
4971
5188
|
"Workspace/Bench",
|
|
4972
|
-
".flint"
|
|
5189
|
+
".flint",
|
|
5190
|
+
".steel"
|
|
4973
5191
|
];
|
|
4974
|
-
async function exists(
|
|
5192
|
+
async function exists(path10) {
|
|
4975
5193
|
try {
|
|
4976
|
-
await access2(
|
|
5194
|
+
await access2(path10);
|
|
4977
5195
|
return true;
|
|
4978
5196
|
} catch {
|
|
4979
5197
|
return false;
|
|
@@ -5198,9 +5416,9 @@ import pc12 from "picocolors";
|
|
|
5198
5416
|
import { readFile as readFile4, stat } from "fs/promises";
|
|
5199
5417
|
import { join as join7, basename as basename2 } from "path";
|
|
5200
5418
|
import { createInterface as createInterface2 } from "readline";
|
|
5201
|
-
async function exists2(
|
|
5419
|
+
async function exists2(path10) {
|
|
5202
5420
|
try {
|
|
5203
|
-
await stat(
|
|
5421
|
+
await stat(path10);
|
|
5204
5422
|
return true;
|
|
5205
5423
|
} catch {
|
|
5206
5424
|
return false;
|
|
@@ -5494,17 +5712,17 @@ import { resolve as resolve2 } from "path";
|
|
|
5494
5712
|
import { platform as platform3 } from "os";
|
|
5495
5713
|
import pc13 from "picocolors";
|
|
5496
5714
|
var execAsync2 = promisify7(exec2);
|
|
5497
|
-
async function openInObsidian(
|
|
5715
|
+
async function openInObsidian(path10) {
|
|
5498
5716
|
const os2 = platform3();
|
|
5499
5717
|
if (os2 === "darwin") {
|
|
5500
|
-
await execAsync2(`open -a "Obsidian" "${
|
|
5718
|
+
await execAsync2(`open -a "Obsidian" "${path10}"`);
|
|
5501
5719
|
} else if (os2 === "win32") {
|
|
5502
|
-
await execAsync2(`start "" "Obsidian" "${
|
|
5720
|
+
await execAsync2(`start "" "Obsidian" "${path10}"`);
|
|
5503
5721
|
} else {
|
|
5504
5722
|
try {
|
|
5505
|
-
await execAsync2(`obsidian "${
|
|
5723
|
+
await execAsync2(`obsidian "${path10}"`);
|
|
5506
5724
|
} catch {
|
|
5507
|
-
await execAsync2(`xdg-open "${
|
|
5725
|
+
await execAsync2(`xdg-open "${path10}"`);
|
|
5508
5726
|
}
|
|
5509
5727
|
}
|
|
5510
5728
|
}
|
|
@@ -6445,7 +6663,10 @@ import pc18 from "picocolors";
|
|
|
6445
6663
|
import { execSync as execSync2, spawnSync as spawnSync2 } from "child_process";
|
|
6446
6664
|
import { join as join8 } from "path";
|
|
6447
6665
|
import { stat as stat2, rm as rm2 } from "fs/promises";
|
|
6448
|
-
|
|
6666
|
+
import { platform as platform4 } from "os";
|
|
6667
|
+
function getExpectedRepoUrl() {
|
|
6668
|
+
return platform4() === "win32" ? OBSIDIAN_WINDOWS_REPO_URL : OBSIDIAN_REPO_URL;
|
|
6669
|
+
}
|
|
6449
6670
|
var obsidianCommand = new Command15("obsidian").description("Manage .obsidian configuration").option("-p, --path <dir>", "Path to flint (default: auto-detect)");
|
|
6450
6671
|
obsidianCommand.command("update").description("Force pull latest .obsidian from remote (discards local changes)").action(async () => {
|
|
6451
6672
|
const options = obsidianCommand.opts();
|
|
@@ -6462,11 +6683,20 @@ obsidianCommand.command("update").description("Force pull latest .obsidian from
|
|
|
6462
6683
|
console.log(pc18.dim("Run `flint init` to create a new flint with .obsidian."));
|
|
6463
6684
|
process.exit(1);
|
|
6464
6685
|
}
|
|
6465
|
-
console.log(pc18.dim("Fetching latest from remote..."));
|
|
6466
6686
|
try {
|
|
6467
|
-
|
|
6468
|
-
execSync2("git
|
|
6469
|
-
|
|
6687
|
+
const expectedUrl = getExpectedRepoUrl();
|
|
6688
|
+
const currentUrl = execSync2("git remote get-url origin", { cwd: obsidianDir, encoding: "utf-8" }).trim();
|
|
6689
|
+
if (currentUrl !== expectedUrl) {
|
|
6690
|
+
console.log(pc18.dim("Detected wrong platform repo. Re-cloning with correct one..."));
|
|
6691
|
+
await rm2(obsidianDir, { recursive: true, force: true });
|
|
6692
|
+
await cloneObsidian(flintPath);
|
|
6693
|
+
console.log(pc18.green("Re-cloned .obsidian with correct platform repo."));
|
|
6694
|
+
} else {
|
|
6695
|
+
console.log(pc18.dim("Fetching latest from remote..."));
|
|
6696
|
+
execSync2("git fetch origin", { cwd: obsidianDir, stdio: "pipe" });
|
|
6697
|
+
execSync2("git reset --hard origin/main", { cwd: obsidianDir, stdio: "pipe" });
|
|
6698
|
+
console.log(pc18.green("Updated .obsidian to latest from remote."));
|
|
6699
|
+
}
|
|
6470
6700
|
} catch (err) {
|
|
6471
6701
|
const message = err instanceof Error ? err.message : String(err);
|
|
6472
6702
|
console.error(pc18.red(`Error updating .obsidian: ${message}`));
|
|
@@ -6519,25 +6749,25 @@ obsidianCommand.command("reset").description("Delete and re-clone .obsidian from
|
|
|
6519
6749
|
process.exit(1);
|
|
6520
6750
|
}
|
|
6521
6751
|
const obsidianDir = join8(flintPath, ".obsidian");
|
|
6522
|
-
let
|
|
6752
|
+
let exists6 = false;
|
|
6523
6753
|
try {
|
|
6524
6754
|
await stat2(obsidianDir);
|
|
6525
|
-
|
|
6755
|
+
exists6 = true;
|
|
6526
6756
|
} catch {
|
|
6527
6757
|
}
|
|
6528
|
-
if (
|
|
6758
|
+
if (exists6 && !cmdOptions.force) {
|
|
6529
6759
|
console.log(pc18.yellow("Warning: This will delete your current .obsidian folder and re-clone from the template repo."));
|
|
6530
6760
|
console.log(pc18.yellow("Any local changes will be lost."));
|
|
6531
6761
|
console.log(pc18.dim("\nUse --force to skip this confirmation."));
|
|
6532
6762
|
process.exit(1);
|
|
6533
6763
|
}
|
|
6534
6764
|
try {
|
|
6535
|
-
if (
|
|
6765
|
+
if (exists6) {
|
|
6536
6766
|
console.log(pc18.dim("Removing existing .obsidian..."));
|
|
6537
6767
|
await rm2(obsidianDir, { recursive: true, force: true });
|
|
6538
6768
|
}
|
|
6539
6769
|
console.log(pc18.dim("Cloning .obsidian from template repo..."));
|
|
6540
|
-
|
|
6770
|
+
await cloneObsidian(flintPath);
|
|
6541
6771
|
console.log(pc18.green("Reset .obsidian to fresh state from template repo."));
|
|
6542
6772
|
} catch (err) {
|
|
6543
6773
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -7009,7 +7239,7 @@ repoCommand.command("add").description("Add a plate from a git repo").argument("
|
|
|
7009
7239
|
getPlateDeclaration,
|
|
7010
7240
|
nameFormats,
|
|
7011
7241
|
updateGitignore: updateGitignore2
|
|
7012
|
-
} = await import("./dist-
|
|
7242
|
+
} = await import("./dist-EAYA2DAP.js");
|
|
7013
7243
|
const { proper, slug } = nameFormats(name);
|
|
7014
7244
|
const existing = await getPlateDeclaration(flintPath, slug);
|
|
7015
7245
|
if (existing) {
|
|
@@ -7021,7 +7251,7 @@ repoCommand.command("add").description("Add a plate from a git repo").argument("
|
|
|
7021
7251
|
Cloning ${url}...`));
|
|
7022
7252
|
await clonePlateFromRepo(flintPath, slug, url, platePath);
|
|
7023
7253
|
await addPlateDeclaration(flintPath, slug, platePath, { title: proper });
|
|
7024
|
-
const { setPlateRepo } = await import("./dist-
|
|
7254
|
+
const { setPlateRepo } = await import("./dist-EAYA2DAP.js");
|
|
7025
7255
|
await setPlateRepo(flintPath, slug, url);
|
|
7026
7256
|
await updateGitignore2(flintPath);
|
|
7027
7257
|
console.log(pc22.green(`
|
|
@@ -7039,9 +7269,9 @@ Added plate: ${pc22.bold(proper)}`));
|
|
|
7039
7269
|
repoCommand.command("remove").description("Remove a repo-sourced plate").argument("<name>", "Plate declaration name or slug").option("-p, --path <dir>", "Path to flint (default: auto-detect)").action(async (name, options) => {
|
|
7040
7270
|
try {
|
|
7041
7271
|
const flintPath = await resolveFlintPath2(options.path);
|
|
7042
|
-
const { removePlateDeclaration, updateGitignore: updateGitignore2 } = await import("./dist-
|
|
7043
|
-
const { rm:
|
|
7044
|
-
const { join:
|
|
7272
|
+
const { removePlateDeclaration, updateGitignore: updateGitignore2 } = await import("./dist-EAYA2DAP.js");
|
|
7273
|
+
const { rm: rm6, stat: stat11 } = await import("fs/promises");
|
|
7274
|
+
const { join: join21 } = await import("path");
|
|
7045
7275
|
const plate = await getPlate(flintPath, name);
|
|
7046
7276
|
if (!plate) {
|
|
7047
7277
|
console.error(pc22.red(`Error: Plate "${name}" not found.`));
|
|
@@ -7049,7 +7279,7 @@ repoCommand.command("remove").description("Remove a repo-sourced plate").argumen
|
|
|
7049
7279
|
}
|
|
7050
7280
|
try {
|
|
7051
7281
|
await stat11(plate.path);
|
|
7052
|
-
await
|
|
7282
|
+
await rm6(plate.path, { recursive: true, force: true });
|
|
7053
7283
|
} catch {
|
|
7054
7284
|
}
|
|
7055
7285
|
await removePlateDeclaration(flintPath, plate.declarationName);
|
|
@@ -7073,11 +7303,11 @@ plateCommand.command("install").description("Install a Plate from a git repo URL
|
|
|
7073
7303
|
readPlateManifest,
|
|
7074
7304
|
setPlateRepo,
|
|
7075
7305
|
updateGitignore: updateGitignore2
|
|
7076
|
-
} = await import("./dist-
|
|
7077
|
-
const { join:
|
|
7078
|
-
const { mkdtemp: mkdtemp2, rm:
|
|
7306
|
+
} = await import("./dist-EAYA2DAP.js");
|
|
7307
|
+
const { join: join21 } = await import("path");
|
|
7308
|
+
const { mkdtemp: mkdtemp2, rm: rm6, rename: rename3 } = await import("fs/promises");
|
|
7079
7309
|
const { tmpdir: tmpdir2 } = await import("os");
|
|
7080
|
-
const tmpDir = await mkdtemp2(
|
|
7310
|
+
const tmpDir = await mkdtemp2(join21(tmpdir2(), "flint-plate-"));
|
|
7081
7311
|
console.log(pc22.dim(`
|
|
7082
7312
|
Cloning ${url}...`));
|
|
7083
7313
|
try {
|
|
@@ -7085,7 +7315,7 @@ Cloning ${url}...`));
|
|
|
7085
7315
|
} catch {
|
|
7086
7316
|
const { execSync: execSync6 } = await import("child_process");
|
|
7087
7317
|
execSync6(`git clone --depth 1 "${url}" "${tmpDir}"`, { timeout: 6e4, stdio: "ignore" });
|
|
7088
|
-
await
|
|
7318
|
+
await rm6(join21(tmpDir, ".git"), { recursive: true, force: true }).catch(() => {
|
|
7089
7319
|
});
|
|
7090
7320
|
}
|
|
7091
7321
|
const manifest = await readPlateManifest(tmpDir);
|
|
@@ -7093,15 +7323,15 @@ Cloning ${url}...`));
|
|
|
7093
7323
|
const title = manifest.title;
|
|
7094
7324
|
const existing = await getPlate(flintPath, slug);
|
|
7095
7325
|
if (existing) {
|
|
7096
|
-
await
|
|
7326
|
+
await rm6(tmpDir, { recursive: true, force: true });
|
|
7097
7327
|
console.error(pc22.red(`Error: Plate "${slug}" already exists.`));
|
|
7098
7328
|
process.exit(1);
|
|
7099
7329
|
}
|
|
7100
7330
|
const { mkdir: mkdir9 } = await import("fs/promises");
|
|
7101
7331
|
const platePath = `Plates/${title}`;
|
|
7102
|
-
const absolutePlatePath =
|
|
7103
|
-
await mkdir9(
|
|
7104
|
-
await
|
|
7332
|
+
const absolutePlatePath = join21(flintPath, platePath);
|
|
7333
|
+
await mkdir9(join21(flintPath, "Plates"), { recursive: true });
|
|
7334
|
+
await rename3(tmpDir, absolutePlatePath);
|
|
7105
7335
|
await addPlateDeclaration(flintPath, slug, platePath, { title });
|
|
7106
7336
|
await setPlateRepo(flintPath, slug, url);
|
|
7107
7337
|
await updateGitignore2(flintPath);
|
|
@@ -7122,7 +7352,7 @@ Installed plate: ${pc22.bold(title)}`));
|
|
|
7122
7352
|
plateCommand.command("push").description("Initialize a plate as a git repo, set remote, and push").argument("<name>", "Plate name").argument("<url>", "Git remote URL").option("-p, --path <dir>", "Path to flint (default: auto-detect)").action(async (name, url, options) => {
|
|
7123
7353
|
try {
|
|
7124
7354
|
const flintPath = await resolveFlintPath2(options.path);
|
|
7125
|
-
const { setPlateRepo } = await import("./dist-
|
|
7355
|
+
const { setPlateRepo } = await import("./dist-EAYA2DAP.js");
|
|
7126
7356
|
console.log(pc22.dim(`
|
|
7127
7357
|
Pushing plate "${name}"...`));
|
|
7128
7358
|
const result = await initPlateRepo(flintPath, name, url);
|
|
@@ -7148,7 +7378,7 @@ Pushing plate "${name}"...`));
|
|
|
7148
7378
|
plateCommand.command("sync").description("Sync plates that have a repo configured").option("-p, --path <dir>", "Path to flint (default: auto-detect)").action(async (options) => {
|
|
7149
7379
|
try {
|
|
7150
7380
|
const flintPath = await resolveFlintPath2(options.path);
|
|
7151
|
-
const { getPlateDeclarations, syncPlateRepos } = await import("./dist-
|
|
7381
|
+
const { getPlateDeclarations, syncPlateRepos } = await import("./dist-EAYA2DAP.js");
|
|
7152
7382
|
const declarations = await getPlateDeclarations(flintPath);
|
|
7153
7383
|
const hasRepos = Object.values(declarations).some((d) => d.repo);
|
|
7154
7384
|
if (!hasRepos) {
|
|
@@ -7424,9 +7654,9 @@ repoCommand2.addCommand(
|
|
|
7424
7654
|
}
|
|
7425
7655
|
})
|
|
7426
7656
|
);
|
|
7427
|
-
async function fileExists(
|
|
7657
|
+
async function fileExists(path10) {
|
|
7428
7658
|
try {
|
|
7429
|
-
await stat3(
|
|
7659
|
+
await stat3(path10);
|
|
7430
7660
|
return true;
|
|
7431
7661
|
} catch {
|
|
7432
7662
|
return false;
|
|
@@ -7445,12 +7675,12 @@ function parseExportRef(ref) {
|
|
|
7445
7675
|
}
|
|
7446
7676
|
async function findFlintByName2(name) {
|
|
7447
7677
|
const flints = await getFlintRegistry();
|
|
7448
|
-
let
|
|
7449
|
-
if (
|
|
7450
|
-
|
|
7451
|
-
if (
|
|
7452
|
-
|
|
7453
|
-
if (
|
|
7678
|
+
let match2 = flints.find((f) => f.name === name);
|
|
7679
|
+
if (match2) return match2;
|
|
7680
|
+
match2 = flints.find((f) => getSimplifiedName(f.name) === name);
|
|
7681
|
+
if (match2) return match2;
|
|
7682
|
+
match2 = flints.find((f) => getSimplifiedName(basename3(f.path)) === name);
|
|
7683
|
+
if (match2) return match2;
|
|
7454
7684
|
return null;
|
|
7455
7685
|
}
|
|
7456
7686
|
async function getRegisteredFlintsWithExports() {
|
|
@@ -7712,9 +7942,9 @@ function readPinsToml(latticeRoot) {
|
|
|
7712
7942
|
if (!recordsMatch) return [];
|
|
7713
7943
|
const recordsStr = recordsMatch[1];
|
|
7714
7944
|
const entryPattern = /\{\s*id\s*=\s*"([^"]+)"\s*,\s*title\s*=\s*"([^"]+)"\s*\}/g;
|
|
7715
|
-
let
|
|
7716
|
-
while ((
|
|
7717
|
-
records.push({ id:
|
|
7945
|
+
let match2;
|
|
7946
|
+
while ((match2 = entryPattern.exec(recordsStr)) !== null) {
|
|
7947
|
+
records.push({ id: match2[1], title: match2[2] });
|
|
7718
7948
|
}
|
|
7719
7949
|
return records;
|
|
7720
7950
|
}
|
|
@@ -8045,7 +8275,7 @@ var latticeCommand = new Command21("lattice").description("Manage lattice connec
|
|
|
8045
8275
|
// src/commands/server.ts
|
|
8046
8276
|
import { Command as Command22 } from "commander";
|
|
8047
8277
|
import { createRequire } from "module";
|
|
8048
|
-
import
|
|
8278
|
+
import path8 from "path";
|
|
8049
8279
|
import { spawn as spawn6 } from "child_process";
|
|
8050
8280
|
import { stat as stat6 } from "fs/promises";
|
|
8051
8281
|
import pc25 from "picocolors";
|
|
@@ -8054,8 +8284,8 @@ import pc25 from "picocolors";
|
|
|
8054
8284
|
import Fastify from "fastify";
|
|
8055
8285
|
import fastifyCors from "@fastify/cors";
|
|
8056
8286
|
import fastifyStatic from "@fastify/static";
|
|
8057
|
-
import { stat as
|
|
8058
|
-
import
|
|
8287
|
+
import { stat as stat5 } from "fs/promises";
|
|
8288
|
+
import path7 from "path";
|
|
8059
8289
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
8060
8290
|
import { join as join43 } from "path";
|
|
8061
8291
|
|
|
@@ -10358,12 +10588,12 @@ function readGeminiSessionId(transcriptPath) {
|
|
|
10358
10588
|
function parseGeminiSessionList(output) {
|
|
10359
10589
|
const mapping = /* @__PURE__ */ new Map();
|
|
10360
10590
|
for (const line of output.split("\n")) {
|
|
10361
|
-
const
|
|
10362
|
-
if (!
|
|
10591
|
+
const match2 = line.match(/^\s*(\d+)\.\s+.*\[(.+?)\]\s*$/);
|
|
10592
|
+
if (!match2) {
|
|
10363
10593
|
continue;
|
|
10364
10594
|
}
|
|
10365
|
-
const index =
|
|
10366
|
-
const sessionId =
|
|
10595
|
+
const index = match2[1];
|
|
10596
|
+
const sessionId = match2[2];
|
|
10367
10597
|
if (index && sessionId) {
|
|
10368
10598
|
mapping.set(sessionId, index);
|
|
10369
10599
|
}
|
|
@@ -10766,209 +10996,2241 @@ function killHarnessProcess(options) {
|
|
|
10766
10996
|
}
|
|
10767
10997
|
|
|
10768
10998
|
// ../../packages/flint-server/dist/index.js
|
|
10769
|
-
import {
|
|
10770
|
-
|
|
10771
|
-
|
|
10772
|
-
} from "@nuucognition/flint-runtime";
|
|
10773
|
-
import { existsSync as existsSync10, watch as watch3 } from "fs";
|
|
10774
|
-
import { stat as stat5 } from "fs/promises";
|
|
10775
|
-
import path3 from "path";
|
|
10776
|
-
import { mkdir as mkdir5, readFile as readFile6, writeFile as writeFile3 } from "fs/promises";
|
|
10777
|
-
import { homedir as homedir6 } from "os";
|
|
10778
|
-
import { join as join11, resolve as resolve7 } from "path";
|
|
10779
|
-
import { existsSync as existsSync23 } from "fs";
|
|
10780
|
-
import { stat as stat22, readFile as readFile22 } from "fs/promises";
|
|
10781
|
-
import path22 from "path";
|
|
10782
|
-
import { existsSync as existsSync33 } from "fs";
|
|
10999
|
+
import { randomUUID as randomUUID3, createHash as createHash2 } from "crypto";
|
|
11000
|
+
import { EventEmitter } from "events";
|
|
11001
|
+
import { readFile as readFile6, stat as stat4 } from "fs/promises";
|
|
10783
11002
|
import { spawn as spawn5 } from "child_process";
|
|
10784
|
-
import { readFile as readFile32 } from "fs/promises";
|
|
10785
|
-
import path32 from "path";
|
|
10786
|
-
import { readdir as readdir2 } from "fs/promises";
|
|
10787
11003
|
import path4 from "path";
|
|
10788
|
-
import
|
|
10789
|
-
import {
|
|
10790
|
-
|
|
10791
|
-
|
|
10792
|
-
|
|
10793
|
-
|
|
10794
|
-
|
|
10795
|
-
|
|
10796
|
-
var
|
|
10797
|
-
"
|
|
10798
|
-
|
|
10799
|
-
".js": "application/javascript; charset=utf-8",
|
|
10800
|
-
".json": "application/json; charset=utf-8",
|
|
10801
|
-
".map": "application/json; charset=utf-8",
|
|
10802
|
-
".mjs": "application/javascript; charset=utf-8",
|
|
10803
|
-
".png": "image/png",
|
|
10804
|
-
".svg": "image/svg+xml",
|
|
10805
|
-
".tsx": "text/plain; charset=utf-8",
|
|
10806
|
-
".txt": "text/plain; charset=utf-8",
|
|
10807
|
-
".woff": "font/woff",
|
|
10808
|
-
".woff2": "font/woff2"
|
|
10809
|
-
};
|
|
10810
|
-
function contentTypeFor(filePath) {
|
|
10811
|
-
return CONTENT_TYPES[path3.extname(filePath).toLowerCase()] ?? "application/octet-stream";
|
|
10812
|
-
}
|
|
10813
|
-
function isImmutableAsset(filePath) {
|
|
10814
|
-
return /\.[a-f0-9]{8,}\./i.test(path3.basename(filePath));
|
|
10815
|
-
}
|
|
10816
|
-
async function resolveFlintPath4(inputPath) {
|
|
10817
|
-
const resolved = path3.resolve(inputPath);
|
|
10818
|
-
const flintToml = path3.join(resolved, "flint.toml");
|
|
10819
|
-
const flintState = path3.join(resolved, ".flint");
|
|
10820
|
-
const hasConfig = await exists3(flintToml);
|
|
10821
|
-
const hasState = await exists3(flintState);
|
|
10822
|
-
if (!hasConfig && !hasState) {
|
|
10823
|
-
throw new Error(`Not a Flint workspace: ${resolved}`);
|
|
10824
|
-
}
|
|
10825
|
-
return resolved;
|
|
10826
|
-
}
|
|
10827
|
-
async function exists3(targetPath) {
|
|
10828
|
-
try {
|
|
10829
|
-
await stat5(targetPath);
|
|
10830
|
-
return true;
|
|
10831
|
-
} catch {
|
|
10832
|
-
return false;
|
|
11004
|
+
import chokidar from "chokidar";
|
|
11005
|
+
import { glob } from "glob";
|
|
11006
|
+
|
|
11007
|
+
// ../../node_modules/.pnpm/minimatch@9.0.9/node_modules/minimatch/dist/esm/index.js
|
|
11008
|
+
var import_brace_expansion = __toESM(require_brace_expansion(), 1);
|
|
11009
|
+
|
|
11010
|
+
// ../../node_modules/.pnpm/minimatch@9.0.9/node_modules/minimatch/dist/esm/assert-valid-pattern.js
|
|
11011
|
+
var MAX_PATTERN_LENGTH = 1024 * 64;
|
|
11012
|
+
var assertValidPattern = (pattern) => {
|
|
11013
|
+
if (typeof pattern !== "string") {
|
|
11014
|
+
throw new TypeError("invalid pattern");
|
|
10833
11015
|
}
|
|
10834
|
-
|
|
10835
|
-
|
|
10836
|
-
if (error3 instanceof Error) {
|
|
10837
|
-
return error3;
|
|
11016
|
+
if (pattern.length > MAX_PATTERN_LENGTH) {
|
|
11017
|
+
throw new TypeError("pattern is too long");
|
|
10838
11018
|
}
|
|
10839
|
-
|
|
10840
|
-
|
|
10841
|
-
|
|
10842
|
-
|
|
10843
|
-
|
|
10844
|
-
}
|
|
10845
|
-
|
|
10846
|
-
|
|
10847
|
-
|
|
10848
|
-
|
|
10849
|
-
|
|
10850
|
-
|
|
10851
|
-
}
|
|
10852
|
-
|
|
10853
|
-
|
|
10854
|
-
|
|
10855
|
-
|
|
10856
|
-
|
|
10857
|
-
|
|
10858
|
-
|
|
10859
|
-
|
|
10860
|
-
|
|
10861
|
-
|
|
10862
|
-
|
|
10863
|
-
|
|
10864
|
-
|
|
10865
|
-
|
|
10866
|
-
|
|
10867
|
-
|
|
10868
|
-
|
|
10869
|
-
|
|
10870
|
-
|
|
10871
|
-
|
|
10872
|
-
|
|
11019
|
+
};
|
|
11020
|
+
|
|
11021
|
+
// ../../node_modules/.pnpm/minimatch@9.0.9/node_modules/minimatch/dist/esm/brace-expressions.js
|
|
11022
|
+
var posixClasses = {
|
|
11023
|
+
"[:alnum:]": ["\\p{L}\\p{Nl}\\p{Nd}", true],
|
|
11024
|
+
"[:alpha:]": ["\\p{L}\\p{Nl}", true],
|
|
11025
|
+
"[:ascii:]": ["\\x00-\\x7f", false],
|
|
11026
|
+
"[:blank:]": ["\\p{Zs}\\t", true],
|
|
11027
|
+
"[:cntrl:]": ["\\p{Cc}", true],
|
|
11028
|
+
"[:digit:]": ["\\p{Nd}", true],
|
|
11029
|
+
"[:graph:]": ["\\p{Z}\\p{C}", true, true],
|
|
11030
|
+
"[:lower:]": ["\\p{Ll}", true],
|
|
11031
|
+
"[:print:]": ["\\p{C}", true],
|
|
11032
|
+
"[:punct:]": ["\\p{P}", true],
|
|
11033
|
+
"[:space:]": ["\\p{Z}\\t\\r\\n\\v\\f", true],
|
|
11034
|
+
"[:upper:]": ["\\p{Lu}", true],
|
|
11035
|
+
"[:word:]": ["\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}", true],
|
|
11036
|
+
"[:xdigit:]": ["A-Fa-f0-9", false]
|
|
11037
|
+
};
|
|
11038
|
+
var braceEscape = (s) => s.replace(/[[\]\\-]/g, "\\$&");
|
|
11039
|
+
var regexpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
|
11040
|
+
var rangesToString = (ranges) => ranges.join("");
|
|
11041
|
+
var parseClass = (glob2, position) => {
|
|
11042
|
+
const pos = position;
|
|
11043
|
+
if (glob2.charAt(pos) !== "[") {
|
|
11044
|
+
throw new Error("not in a brace expression");
|
|
11045
|
+
}
|
|
11046
|
+
const ranges = [];
|
|
11047
|
+
const negs = [];
|
|
11048
|
+
let i = pos + 1;
|
|
11049
|
+
let sawStart = false;
|
|
11050
|
+
let uflag = false;
|
|
11051
|
+
let escaping = false;
|
|
11052
|
+
let negate = false;
|
|
11053
|
+
let endPos = pos;
|
|
11054
|
+
let rangeStart = "";
|
|
11055
|
+
WHILE: while (i < glob2.length) {
|
|
11056
|
+
const c = glob2.charAt(i);
|
|
11057
|
+
if ((c === "!" || c === "^") && i === pos + 1) {
|
|
11058
|
+
negate = true;
|
|
11059
|
+
i++;
|
|
11060
|
+
continue;
|
|
10873
11061
|
}
|
|
10874
|
-
|
|
10875
|
-
|
|
10876
|
-
|
|
10877
|
-
const start = () => {
|
|
10878
|
-
if (closed) {
|
|
10879
|
-
return;
|
|
11062
|
+
if (c === "]" && sawStart && !escaping) {
|
|
11063
|
+
endPos = i + 1;
|
|
11064
|
+
break;
|
|
10880
11065
|
}
|
|
10881
|
-
|
|
10882
|
-
|
|
10883
|
-
|
|
11066
|
+
sawStart = true;
|
|
11067
|
+
if (c === "\\") {
|
|
11068
|
+
if (!escaping) {
|
|
11069
|
+
escaping = true;
|
|
11070
|
+
i++;
|
|
11071
|
+
continue;
|
|
11072
|
+
}
|
|
10884
11073
|
}
|
|
10885
|
-
|
|
10886
|
-
|
|
10887
|
-
|
|
10888
|
-
|
|
10889
|
-
|
|
10890
|
-
|
|
10891
|
-
|
|
11074
|
+
if (c === "[" && !escaping) {
|
|
11075
|
+
for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) {
|
|
11076
|
+
if (glob2.startsWith(cls, i)) {
|
|
11077
|
+
if (rangeStart) {
|
|
11078
|
+
return ["$.", false, glob2.length - pos, true];
|
|
11079
|
+
}
|
|
11080
|
+
i += cls.length;
|
|
11081
|
+
if (neg)
|
|
11082
|
+
negs.push(unip);
|
|
11083
|
+
else
|
|
11084
|
+
ranges.push(unip);
|
|
11085
|
+
uflag = uflag || u;
|
|
11086
|
+
continue WHILE;
|
|
11087
|
+
}
|
|
11088
|
+
}
|
|
10892
11089
|
}
|
|
10893
|
-
|
|
10894
|
-
|
|
10895
|
-
|
|
10896
|
-
|
|
10897
|
-
|
|
10898
|
-
|
|
10899
|
-
clearTimeout(retryTimer);
|
|
10900
|
-
retryTimer = null;
|
|
11090
|
+
escaping = false;
|
|
11091
|
+
if (rangeStart) {
|
|
11092
|
+
if (c > rangeStart) {
|
|
11093
|
+
ranges.push(braceEscape(rangeStart) + "-" + braceEscape(c));
|
|
11094
|
+
} else if (c === rangeStart) {
|
|
11095
|
+
ranges.push(braceEscape(c));
|
|
10901
11096
|
}
|
|
10902
|
-
|
|
10903
|
-
|
|
11097
|
+
rangeStart = "";
|
|
11098
|
+
i++;
|
|
11099
|
+
continue;
|
|
10904
11100
|
}
|
|
10905
|
-
|
|
10906
|
-
|
|
10907
|
-
|
|
10908
|
-
|
|
10909
|
-
async startRuntime(flintPath) {
|
|
10910
|
-
const resolved = await resolveFlintPath4(flintPath);
|
|
10911
|
-
const runtimeId = computeRuntimeId(resolved);
|
|
10912
|
-
const existing = this.runtimes.get(runtimeId);
|
|
10913
|
-
if (existing) {
|
|
10914
|
-
return existing.getStatus();
|
|
11101
|
+
if (glob2.startsWith("-]", i + 1)) {
|
|
11102
|
+
ranges.push(braceEscape(c + "-"));
|
|
11103
|
+
i += 2;
|
|
11104
|
+
continue;
|
|
10915
11105
|
}
|
|
10916
|
-
|
|
10917
|
-
|
|
10918
|
-
|
|
10919
|
-
|
|
10920
|
-
|
|
10921
|
-
|
|
10922
|
-
|
|
11106
|
+
if (glob2.startsWith("-", i + 1)) {
|
|
11107
|
+
rangeStart = c;
|
|
11108
|
+
i += 2;
|
|
11109
|
+
continue;
|
|
11110
|
+
}
|
|
11111
|
+
ranges.push(braceEscape(c));
|
|
11112
|
+
i++;
|
|
10923
11113
|
}
|
|
10924
|
-
|
|
10925
|
-
return
|
|
11114
|
+
if (endPos < i) {
|
|
11115
|
+
return ["", false, 0, false];
|
|
10926
11116
|
}
|
|
10927
|
-
|
|
10928
|
-
|
|
10929
|
-
if (!runtime2) {
|
|
10930
|
-
return false;
|
|
10931
|
-
}
|
|
10932
|
-
await runtime2.stop();
|
|
10933
|
-
this.runtimes.delete(id);
|
|
10934
|
-
return true;
|
|
11117
|
+
if (!ranges.length && !negs.length) {
|
|
11118
|
+
return ["$.", false, glob2.length - pos, true];
|
|
10935
11119
|
}
|
|
10936
|
-
|
|
10937
|
-
const
|
|
10938
|
-
|
|
10939
|
-
await runtime2.stop();
|
|
10940
|
-
this.runtimes.delete(id);
|
|
10941
|
-
}));
|
|
11120
|
+
if (negs.length === 0 && ranges.length === 1 && /^\\?.$/.test(ranges[0]) && !negate) {
|
|
11121
|
+
const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0];
|
|
11122
|
+
return [regexpEscape(r), false, endPos - pos, false];
|
|
10942
11123
|
}
|
|
11124
|
+
const sranges = "[" + (negate ? "^" : "") + rangesToString(ranges) + "]";
|
|
11125
|
+
const snegs = "[" + (negate ? "" : "^") + rangesToString(negs) + "]";
|
|
11126
|
+
const comb = ranges.length && negs.length ? "(" + sranges + "|" + snegs + ")" : ranges.length ? sranges : snegs;
|
|
11127
|
+
return [comb, uflag, endPos - pos, true];
|
|
10943
11128
|
};
|
|
10944
|
-
|
|
10945
|
-
|
|
10946
|
-
|
|
10947
|
-
|
|
10948
|
-
|
|
10949
|
-
|
|
10950
|
-
|
|
10951
|
-
|
|
10952
|
-
|
|
10953
|
-
|
|
10954
|
-
|
|
10955
|
-
|
|
11129
|
+
|
|
11130
|
+
// ../../node_modules/.pnpm/minimatch@9.0.9/node_modules/minimatch/dist/esm/unescape.js
|
|
11131
|
+
var unescape = (s, { windowsPathsNoEscape = false } = {}) => {
|
|
11132
|
+
return windowsPathsNoEscape ? s.replace(/\[([^\/\\])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, "$1$2").replace(/\\([^\/])/g, "$1");
|
|
11133
|
+
};
|
|
11134
|
+
|
|
11135
|
+
// ../../node_modules/.pnpm/minimatch@9.0.9/node_modules/minimatch/dist/esm/ast.js
|
|
11136
|
+
var _a;
|
|
11137
|
+
var types = /* @__PURE__ */ new Set(["!", "?", "+", "*", "@"]);
|
|
11138
|
+
var isExtglobType = (c) => types.has(c);
|
|
11139
|
+
var isExtglobAST = (c) => isExtglobType(c.type);
|
|
11140
|
+
var adoptionMap = /* @__PURE__ */ new Map([
|
|
11141
|
+
["!", ["@"]],
|
|
11142
|
+
["?", ["?", "@"]],
|
|
11143
|
+
["@", ["@"]],
|
|
11144
|
+
["*", ["*", "+", "?", "@"]],
|
|
11145
|
+
["+", ["+", "@"]]
|
|
11146
|
+
]);
|
|
11147
|
+
var adoptionWithSpaceMap = /* @__PURE__ */ new Map([
|
|
11148
|
+
["!", ["?"]],
|
|
11149
|
+
["@", ["?"]],
|
|
11150
|
+
["+", ["?", "*"]]
|
|
11151
|
+
]);
|
|
11152
|
+
var adoptionAnyMap = /* @__PURE__ */ new Map([
|
|
11153
|
+
["!", ["?", "@"]],
|
|
11154
|
+
["?", ["?", "@"]],
|
|
11155
|
+
["@", ["?", "@"]],
|
|
11156
|
+
["*", ["*", "+", "?", "@"]],
|
|
11157
|
+
["+", ["+", "@", "?", "*"]]
|
|
11158
|
+
]);
|
|
11159
|
+
var usurpMap = /* @__PURE__ */ new Map([
|
|
11160
|
+
["!", /* @__PURE__ */ new Map([["!", "@"]])],
|
|
11161
|
+
["?", /* @__PURE__ */ new Map([["*", "*"], ["+", "*"]])],
|
|
11162
|
+
["@", /* @__PURE__ */ new Map([["!", "!"], ["?", "?"], ["@", "@"], ["*", "*"], ["+", "+"]])],
|
|
11163
|
+
["+", /* @__PURE__ */ new Map([["?", "*"], ["*", "*"]])]
|
|
11164
|
+
]);
|
|
11165
|
+
var startNoTraversal = "(?!(?:^|/)\\.\\.?(?:$|/))";
|
|
11166
|
+
var startNoDot = "(?!\\.)";
|
|
11167
|
+
var addPatternStart = /* @__PURE__ */ new Set(["[", "."]);
|
|
11168
|
+
var justDots = /* @__PURE__ */ new Set(["..", "."]);
|
|
11169
|
+
var reSpecials = new Set("().*{}+?[]^$\\!");
|
|
11170
|
+
var regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
|
11171
|
+
var qmark = "[^/]";
|
|
11172
|
+
var star = qmark + "*?";
|
|
11173
|
+
var starNoEmpty = qmark + "+?";
|
|
11174
|
+
var AST = class {
|
|
11175
|
+
type;
|
|
11176
|
+
#root;
|
|
11177
|
+
#hasMagic;
|
|
11178
|
+
#uflag = false;
|
|
11179
|
+
#parts = [];
|
|
11180
|
+
#parent;
|
|
11181
|
+
#parentIndex;
|
|
11182
|
+
#negs;
|
|
11183
|
+
#filledNegs = false;
|
|
11184
|
+
#options;
|
|
11185
|
+
#toString;
|
|
11186
|
+
// set to true if it's an extglob with no children
|
|
11187
|
+
// (which really means one child of '')
|
|
11188
|
+
#emptyExt = false;
|
|
11189
|
+
constructor(type, parent, options = {}) {
|
|
11190
|
+
this.type = type;
|
|
11191
|
+
if (type)
|
|
11192
|
+
this.#hasMagic = true;
|
|
11193
|
+
this.#parent = parent;
|
|
11194
|
+
this.#root = this.#parent ? this.#parent.#root : this;
|
|
11195
|
+
this.#options = this.#root === this ? options : this.#root.#options;
|
|
11196
|
+
this.#negs = this.#root === this ? [] : this.#root.#negs;
|
|
11197
|
+
if (type === "!" && !this.#root.#filledNegs)
|
|
11198
|
+
this.#negs.push(this);
|
|
11199
|
+
this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0;
|
|
11200
|
+
}
|
|
11201
|
+
get hasMagic() {
|
|
11202
|
+
if (this.#hasMagic !== void 0)
|
|
11203
|
+
return this.#hasMagic;
|
|
11204
|
+
for (const p of this.#parts) {
|
|
11205
|
+
if (typeof p === "string")
|
|
11206
|
+
continue;
|
|
11207
|
+
if (p.type || p.hasMagic)
|
|
11208
|
+
return this.#hasMagic = true;
|
|
10956
11209
|
}
|
|
10957
|
-
return
|
|
11210
|
+
return this.#hasMagic;
|
|
10958
11211
|
}
|
|
10959
|
-
|
|
10960
|
-
|
|
10961
|
-
|
|
10962
|
-
|
|
10963
|
-
|
|
10964
|
-
|
|
10965
|
-
|
|
10966
|
-
|
|
10967
|
-
|
|
10968
|
-
|
|
11212
|
+
// reconstructs the pattern
|
|
11213
|
+
toString() {
|
|
11214
|
+
if (this.#toString !== void 0)
|
|
11215
|
+
return this.#toString;
|
|
11216
|
+
if (!this.type) {
|
|
11217
|
+
return this.#toString = this.#parts.map((p) => String(p)).join("");
|
|
11218
|
+
} else {
|
|
11219
|
+
return this.#toString = this.type + "(" + this.#parts.map((p) => String(p)).join("|") + ")";
|
|
11220
|
+
}
|
|
11221
|
+
}
|
|
11222
|
+
#fillNegs() {
|
|
11223
|
+
if (this !== this.#root)
|
|
11224
|
+
throw new Error("should only call on root");
|
|
11225
|
+
if (this.#filledNegs)
|
|
11226
|
+
return this;
|
|
11227
|
+
this.toString();
|
|
11228
|
+
this.#filledNegs = true;
|
|
11229
|
+
let n;
|
|
11230
|
+
while (n = this.#negs.pop()) {
|
|
11231
|
+
if (n.type !== "!")
|
|
11232
|
+
continue;
|
|
11233
|
+
let p = n;
|
|
11234
|
+
let pp = p.#parent;
|
|
11235
|
+
while (pp) {
|
|
11236
|
+
for (let i = p.#parentIndex + 1; !pp.type && i < pp.#parts.length; i++) {
|
|
11237
|
+
for (const part of n.#parts) {
|
|
11238
|
+
if (typeof part === "string") {
|
|
11239
|
+
throw new Error("string part in extglob AST??");
|
|
11240
|
+
}
|
|
11241
|
+
part.copyIn(pp.#parts[i]);
|
|
11242
|
+
}
|
|
11243
|
+
}
|
|
11244
|
+
p = pp;
|
|
11245
|
+
pp = p.#parent;
|
|
11246
|
+
}
|
|
11247
|
+
}
|
|
11248
|
+
return this;
|
|
10969
11249
|
}
|
|
10970
|
-
|
|
10971
|
-
|
|
11250
|
+
push(...parts) {
|
|
11251
|
+
for (const p of parts) {
|
|
11252
|
+
if (p === "")
|
|
11253
|
+
continue;
|
|
11254
|
+
if (typeof p !== "string" && !(p instanceof _a && p.#parent === this)) {
|
|
11255
|
+
throw new Error("invalid part: " + p);
|
|
11256
|
+
}
|
|
11257
|
+
this.#parts.push(p);
|
|
11258
|
+
}
|
|
11259
|
+
}
|
|
11260
|
+
toJSON() {
|
|
11261
|
+
const ret = this.type === null ? this.#parts.slice().map((p) => typeof p === "string" ? p : p.toJSON()) : [this.type, ...this.#parts.map((p) => p.toJSON())];
|
|
11262
|
+
if (this.isStart() && !this.type)
|
|
11263
|
+
ret.unshift([]);
|
|
11264
|
+
if (this.isEnd() && (this === this.#root || this.#root.#filledNegs && this.#parent?.type === "!")) {
|
|
11265
|
+
ret.push({});
|
|
11266
|
+
}
|
|
11267
|
+
return ret;
|
|
11268
|
+
}
|
|
11269
|
+
isStart() {
|
|
11270
|
+
if (this.#root === this)
|
|
11271
|
+
return true;
|
|
11272
|
+
if (!this.#parent?.isStart())
|
|
11273
|
+
return false;
|
|
11274
|
+
if (this.#parentIndex === 0)
|
|
11275
|
+
return true;
|
|
11276
|
+
const p = this.#parent;
|
|
11277
|
+
for (let i = 0; i < this.#parentIndex; i++) {
|
|
11278
|
+
const pp = p.#parts[i];
|
|
11279
|
+
if (!(pp instanceof _a && pp.type === "!")) {
|
|
11280
|
+
return false;
|
|
11281
|
+
}
|
|
11282
|
+
}
|
|
11283
|
+
return true;
|
|
11284
|
+
}
|
|
11285
|
+
isEnd() {
|
|
11286
|
+
if (this.#root === this)
|
|
11287
|
+
return true;
|
|
11288
|
+
if (this.#parent?.type === "!")
|
|
11289
|
+
return true;
|
|
11290
|
+
if (!this.#parent?.isEnd())
|
|
11291
|
+
return false;
|
|
11292
|
+
if (!this.type)
|
|
11293
|
+
return this.#parent?.isEnd();
|
|
11294
|
+
const pl = this.#parent ? this.#parent.#parts.length : 0;
|
|
11295
|
+
return this.#parentIndex === pl - 1;
|
|
11296
|
+
}
|
|
11297
|
+
copyIn(part) {
|
|
11298
|
+
if (typeof part === "string")
|
|
11299
|
+
this.push(part);
|
|
11300
|
+
else
|
|
11301
|
+
this.push(part.clone(this));
|
|
11302
|
+
}
|
|
11303
|
+
clone(parent) {
|
|
11304
|
+
const c = new _a(this.type, parent);
|
|
11305
|
+
for (const p of this.#parts) {
|
|
11306
|
+
c.copyIn(p);
|
|
11307
|
+
}
|
|
11308
|
+
return c;
|
|
11309
|
+
}
|
|
11310
|
+
static #parseAST(str, ast, pos, opt, extDepth) {
|
|
11311
|
+
const maxDepth = opt.maxExtglobRecursion ?? 2;
|
|
11312
|
+
let escaping = false;
|
|
11313
|
+
let inBrace = false;
|
|
11314
|
+
let braceStart = -1;
|
|
11315
|
+
let braceNeg = false;
|
|
11316
|
+
if (ast.type === null) {
|
|
11317
|
+
let i2 = pos;
|
|
11318
|
+
let acc2 = "";
|
|
11319
|
+
while (i2 < str.length) {
|
|
11320
|
+
const c = str.charAt(i2++);
|
|
11321
|
+
if (escaping || c === "\\") {
|
|
11322
|
+
escaping = !escaping;
|
|
11323
|
+
acc2 += c;
|
|
11324
|
+
continue;
|
|
11325
|
+
}
|
|
11326
|
+
if (inBrace) {
|
|
11327
|
+
if (i2 === braceStart + 1) {
|
|
11328
|
+
if (c === "^" || c === "!") {
|
|
11329
|
+
braceNeg = true;
|
|
11330
|
+
}
|
|
11331
|
+
} else if (c === "]" && !(i2 === braceStart + 2 && braceNeg)) {
|
|
11332
|
+
inBrace = false;
|
|
11333
|
+
}
|
|
11334
|
+
acc2 += c;
|
|
11335
|
+
continue;
|
|
11336
|
+
} else if (c === "[") {
|
|
11337
|
+
inBrace = true;
|
|
11338
|
+
braceStart = i2;
|
|
11339
|
+
braceNeg = false;
|
|
11340
|
+
acc2 += c;
|
|
11341
|
+
continue;
|
|
11342
|
+
}
|
|
11343
|
+
const doRecurse = !opt.noext && isExtglobType(c) && str.charAt(i2) === "(" && extDepth <= maxDepth;
|
|
11344
|
+
if (doRecurse) {
|
|
11345
|
+
ast.push(acc2);
|
|
11346
|
+
acc2 = "";
|
|
11347
|
+
const ext2 = new _a(c, ast);
|
|
11348
|
+
i2 = _a.#parseAST(str, ext2, i2, opt, extDepth + 1);
|
|
11349
|
+
ast.push(ext2);
|
|
11350
|
+
continue;
|
|
11351
|
+
}
|
|
11352
|
+
acc2 += c;
|
|
11353
|
+
}
|
|
11354
|
+
ast.push(acc2);
|
|
11355
|
+
return i2;
|
|
11356
|
+
}
|
|
11357
|
+
let i = pos + 1;
|
|
11358
|
+
let part = new _a(null, ast);
|
|
11359
|
+
const parts = [];
|
|
11360
|
+
let acc = "";
|
|
11361
|
+
while (i < str.length) {
|
|
11362
|
+
const c = str.charAt(i++);
|
|
11363
|
+
if (escaping || c === "\\") {
|
|
11364
|
+
escaping = !escaping;
|
|
11365
|
+
acc += c;
|
|
11366
|
+
continue;
|
|
11367
|
+
}
|
|
11368
|
+
if (inBrace) {
|
|
11369
|
+
if (i === braceStart + 1) {
|
|
11370
|
+
if (c === "^" || c === "!") {
|
|
11371
|
+
braceNeg = true;
|
|
11372
|
+
}
|
|
11373
|
+
} else if (c === "]" && !(i === braceStart + 2 && braceNeg)) {
|
|
11374
|
+
inBrace = false;
|
|
11375
|
+
}
|
|
11376
|
+
acc += c;
|
|
11377
|
+
continue;
|
|
11378
|
+
} else if (c === "[") {
|
|
11379
|
+
inBrace = true;
|
|
11380
|
+
braceStart = i;
|
|
11381
|
+
braceNeg = false;
|
|
11382
|
+
acc += c;
|
|
11383
|
+
continue;
|
|
11384
|
+
}
|
|
11385
|
+
const doRecurse = isExtglobType(c) && str.charAt(i) === "(" && /* c8 ignore start - the maxDepth is sufficient here */
|
|
11386
|
+
(extDepth <= maxDepth || ast && ast.#canAdoptType(c));
|
|
11387
|
+
if (doRecurse) {
|
|
11388
|
+
const depthAdd = ast && ast.#canAdoptType(c) ? 0 : 1;
|
|
11389
|
+
part.push(acc);
|
|
11390
|
+
acc = "";
|
|
11391
|
+
const ext2 = new _a(c, part);
|
|
11392
|
+
part.push(ext2);
|
|
11393
|
+
i = _a.#parseAST(str, ext2, i, opt, extDepth + depthAdd);
|
|
11394
|
+
continue;
|
|
11395
|
+
}
|
|
11396
|
+
if (c === "|") {
|
|
11397
|
+
part.push(acc);
|
|
11398
|
+
acc = "";
|
|
11399
|
+
parts.push(part);
|
|
11400
|
+
part = new _a(null, ast);
|
|
11401
|
+
continue;
|
|
11402
|
+
}
|
|
11403
|
+
if (c === ")") {
|
|
11404
|
+
if (acc === "" && ast.#parts.length === 0) {
|
|
11405
|
+
ast.#emptyExt = true;
|
|
11406
|
+
}
|
|
11407
|
+
part.push(acc);
|
|
11408
|
+
acc = "";
|
|
11409
|
+
ast.push(...parts, part);
|
|
11410
|
+
return i;
|
|
11411
|
+
}
|
|
11412
|
+
acc += c;
|
|
11413
|
+
}
|
|
11414
|
+
ast.type = null;
|
|
11415
|
+
ast.#hasMagic = void 0;
|
|
11416
|
+
ast.#parts = [str.substring(pos - 1)];
|
|
11417
|
+
return i;
|
|
11418
|
+
}
|
|
11419
|
+
#canAdoptWithSpace(child) {
|
|
11420
|
+
return this.#canAdopt(child, adoptionWithSpaceMap);
|
|
11421
|
+
}
|
|
11422
|
+
#canAdopt(child, map = adoptionMap) {
|
|
11423
|
+
if (!child || typeof child !== "object" || child.type !== null || child.#parts.length !== 1 || this.type === null) {
|
|
11424
|
+
return false;
|
|
11425
|
+
}
|
|
11426
|
+
const gc = child.#parts[0];
|
|
11427
|
+
if (!gc || typeof gc !== "object" || gc.type === null) {
|
|
11428
|
+
return false;
|
|
11429
|
+
}
|
|
11430
|
+
return this.#canAdoptType(gc.type, map);
|
|
11431
|
+
}
|
|
11432
|
+
#canAdoptType(c, map = adoptionAnyMap) {
|
|
11433
|
+
return !!map.get(this.type)?.includes(c);
|
|
11434
|
+
}
|
|
11435
|
+
#adoptWithSpace(child, index) {
|
|
11436
|
+
const gc = child.#parts[0];
|
|
11437
|
+
const blank = new _a(null, gc, this.options);
|
|
11438
|
+
blank.#parts.push("");
|
|
11439
|
+
gc.push(blank);
|
|
11440
|
+
this.#adopt(child, index);
|
|
11441
|
+
}
|
|
11442
|
+
#adopt(child, index) {
|
|
11443
|
+
const gc = child.#parts[0];
|
|
11444
|
+
this.#parts.splice(index, 1, ...gc.#parts);
|
|
11445
|
+
for (const p of gc.#parts) {
|
|
11446
|
+
if (typeof p === "object")
|
|
11447
|
+
p.#parent = this;
|
|
11448
|
+
}
|
|
11449
|
+
this.#toString = void 0;
|
|
11450
|
+
}
|
|
11451
|
+
#canUsurpType(c) {
|
|
11452
|
+
const m = usurpMap.get(this.type);
|
|
11453
|
+
return !!m?.has(c);
|
|
11454
|
+
}
|
|
11455
|
+
#canUsurp(child) {
|
|
11456
|
+
if (!child || typeof child !== "object" || child.type !== null || child.#parts.length !== 1 || this.type === null || this.#parts.length !== 1) {
|
|
11457
|
+
return false;
|
|
11458
|
+
}
|
|
11459
|
+
const gc = child.#parts[0];
|
|
11460
|
+
if (!gc || typeof gc !== "object" || gc.type === null) {
|
|
11461
|
+
return false;
|
|
11462
|
+
}
|
|
11463
|
+
return this.#canUsurpType(gc.type);
|
|
11464
|
+
}
|
|
11465
|
+
#usurp(child) {
|
|
11466
|
+
const m = usurpMap.get(this.type);
|
|
11467
|
+
const gc = child.#parts[0];
|
|
11468
|
+
const nt = m?.get(gc.type);
|
|
11469
|
+
if (!nt)
|
|
11470
|
+
return false;
|
|
11471
|
+
this.#parts = gc.#parts;
|
|
11472
|
+
for (const p of this.#parts) {
|
|
11473
|
+
if (typeof p === "object")
|
|
11474
|
+
p.#parent = this;
|
|
11475
|
+
}
|
|
11476
|
+
this.type = nt;
|
|
11477
|
+
this.#toString = void 0;
|
|
11478
|
+
this.#emptyExt = false;
|
|
11479
|
+
}
|
|
11480
|
+
#flatten() {
|
|
11481
|
+
if (!isExtglobAST(this)) {
|
|
11482
|
+
for (const p of this.#parts) {
|
|
11483
|
+
if (typeof p === "object")
|
|
11484
|
+
p.#flatten();
|
|
11485
|
+
}
|
|
11486
|
+
} else {
|
|
11487
|
+
let iterations = 0;
|
|
11488
|
+
let done = false;
|
|
11489
|
+
do {
|
|
11490
|
+
done = true;
|
|
11491
|
+
for (let i = 0; i < this.#parts.length; i++) {
|
|
11492
|
+
const c = this.#parts[i];
|
|
11493
|
+
if (typeof c === "object") {
|
|
11494
|
+
c.#flatten();
|
|
11495
|
+
if (this.#canAdopt(c)) {
|
|
11496
|
+
done = false;
|
|
11497
|
+
this.#adopt(c, i);
|
|
11498
|
+
} else if (this.#canAdoptWithSpace(c)) {
|
|
11499
|
+
done = false;
|
|
11500
|
+
this.#adoptWithSpace(c, i);
|
|
11501
|
+
} else if (this.#canUsurp(c)) {
|
|
11502
|
+
done = false;
|
|
11503
|
+
this.#usurp(c);
|
|
11504
|
+
}
|
|
11505
|
+
}
|
|
11506
|
+
}
|
|
11507
|
+
} while (!done && ++iterations < 10);
|
|
11508
|
+
}
|
|
11509
|
+
this.#toString = void 0;
|
|
11510
|
+
}
|
|
11511
|
+
static fromGlob(pattern, options = {}) {
|
|
11512
|
+
const ast = new _a(null, void 0, options);
|
|
11513
|
+
_a.#parseAST(pattern, ast, 0, options, 0);
|
|
11514
|
+
return ast;
|
|
11515
|
+
}
|
|
11516
|
+
// returns the regular expression if there's magic, or the unescaped
|
|
11517
|
+
// string if not.
|
|
11518
|
+
toMMPattern() {
|
|
11519
|
+
if (this !== this.#root)
|
|
11520
|
+
return this.#root.toMMPattern();
|
|
11521
|
+
const glob2 = this.toString();
|
|
11522
|
+
const [re, body, hasMagic, uflag] = this.toRegExpSource();
|
|
11523
|
+
const anyMagic = hasMagic || this.#hasMagic || this.#options.nocase && !this.#options.nocaseMagicOnly && glob2.toUpperCase() !== glob2.toLowerCase();
|
|
11524
|
+
if (!anyMagic) {
|
|
11525
|
+
return body;
|
|
11526
|
+
}
|
|
11527
|
+
const flags = (this.#options.nocase ? "i" : "") + (uflag ? "u" : "");
|
|
11528
|
+
return Object.assign(new RegExp(`^${re}$`, flags), {
|
|
11529
|
+
_src: re,
|
|
11530
|
+
_glob: glob2
|
|
11531
|
+
});
|
|
11532
|
+
}
|
|
11533
|
+
get options() {
|
|
11534
|
+
return this.#options;
|
|
11535
|
+
}
|
|
11536
|
+
// returns the string match, the regexp source, whether there's magic
|
|
11537
|
+
// in the regexp (so a regular expression is required) and whether or
|
|
11538
|
+
// not the uflag is needed for the regular expression (for posix classes)
|
|
11539
|
+
// TODO: instead of injecting the start/end at this point, just return
|
|
11540
|
+
// the BODY of the regexp, along with the start/end portions suitable
|
|
11541
|
+
// for binding the start/end in either a joined full-path makeRe context
|
|
11542
|
+
// (where we bind to (^|/), or a standalone matchPart context (where
|
|
11543
|
+
// we bind to ^, and not /). Otherwise slashes get duped!
|
|
11544
|
+
//
|
|
11545
|
+
// In part-matching mode, the start is:
|
|
11546
|
+
// - if not isStart: nothing
|
|
11547
|
+
// - if traversal possible, but not allowed: ^(?!\.\.?$)
|
|
11548
|
+
// - if dots allowed or not possible: ^
|
|
11549
|
+
// - if dots possible and not allowed: ^(?!\.)
|
|
11550
|
+
// end is:
|
|
11551
|
+
// - if not isEnd(): nothing
|
|
11552
|
+
// - else: $
|
|
11553
|
+
//
|
|
11554
|
+
// In full-path matching mode, we put the slash at the START of the
|
|
11555
|
+
// pattern, so start is:
|
|
11556
|
+
// - if first pattern: same as part-matching mode
|
|
11557
|
+
// - if not isStart(): nothing
|
|
11558
|
+
// - if traversal possible, but not allowed: /(?!\.\.?(?:$|/))
|
|
11559
|
+
// - if dots allowed or not possible: /
|
|
11560
|
+
// - if dots possible and not allowed: /(?!\.)
|
|
11561
|
+
// end is:
|
|
11562
|
+
// - if last pattern, same as part-matching mode
|
|
11563
|
+
// - else nothing
|
|
11564
|
+
//
|
|
11565
|
+
// Always put the (?:$|/) on negated tails, though, because that has to be
|
|
11566
|
+
// there to bind the end of the negated pattern portion, and it's easier to
|
|
11567
|
+
// just stick it in now rather than try to inject it later in the middle of
|
|
11568
|
+
// the pattern.
|
|
11569
|
+
//
|
|
11570
|
+
// We can just always return the same end, and leave it up to the caller
|
|
11571
|
+
// to know whether it's going to be used joined or in parts.
|
|
11572
|
+
// And, if the start is adjusted slightly, can do the same there:
|
|
11573
|
+
// - if not isStart: nothing
|
|
11574
|
+
// - if traversal possible, but not allowed: (?:/|^)(?!\.\.?$)
|
|
11575
|
+
// - if dots allowed or not possible: (?:/|^)
|
|
11576
|
+
// - if dots possible and not allowed: (?:/|^)(?!\.)
|
|
11577
|
+
//
|
|
11578
|
+
// But it's better to have a simpler binding without a conditional, for
|
|
11579
|
+
// performance, so probably better to return both start options.
|
|
11580
|
+
//
|
|
11581
|
+
// Then the caller just ignores the end if it's not the first pattern,
|
|
11582
|
+
// and the start always gets applied.
|
|
11583
|
+
//
|
|
11584
|
+
// But that's always going to be $ if it's the ending pattern, or nothing,
|
|
11585
|
+
// so the caller can just attach $ at the end of the pattern when building.
|
|
11586
|
+
//
|
|
11587
|
+
// So the todo is:
|
|
11588
|
+
// - better detect what kind of start is needed
|
|
11589
|
+
// - return both flavors of starting pattern
|
|
11590
|
+
// - attach $ at the end of the pattern when creating the actual RegExp
|
|
11591
|
+
//
|
|
11592
|
+
// Ah, but wait, no, that all only applies to the root when the first pattern
|
|
11593
|
+
// is not an extglob. If the first pattern IS an extglob, then we need all
|
|
11594
|
+
// that dot prevention biz to live in the extglob portions, because eg
|
|
11595
|
+
// +(*|.x*) can match .xy but not .yx.
|
|
11596
|
+
//
|
|
11597
|
+
// So, return the two flavors if it's #root and the first child is not an
|
|
11598
|
+
// AST, otherwise leave it to the child AST to handle it, and there,
|
|
11599
|
+
// use the (?:^|/) style of start binding.
|
|
11600
|
+
//
|
|
11601
|
+
// Even simplified further:
|
|
11602
|
+
// - Since the start for a join is eg /(?!\.) and the start for a part
|
|
11603
|
+
// is ^(?!\.), we can just prepend (?!\.) to the pattern (either root
|
|
11604
|
+
// or start or whatever) and prepend ^ or / at the Regexp construction.
|
|
11605
|
+
toRegExpSource(allowDot) {
|
|
11606
|
+
const dot = allowDot ?? !!this.#options.dot;
|
|
11607
|
+
if (this.#root === this) {
|
|
11608
|
+
this.#flatten();
|
|
11609
|
+
this.#fillNegs();
|
|
11610
|
+
}
|
|
11611
|
+
if (!isExtglobAST(this)) {
|
|
11612
|
+
const noEmpty = this.isStart() && this.isEnd();
|
|
11613
|
+
const src = this.#parts.map((p) => {
|
|
11614
|
+
const [re, _, hasMagic, uflag] = typeof p === "string" ? _a.#parseGlob(p, this.#hasMagic, noEmpty) : p.toRegExpSource(allowDot);
|
|
11615
|
+
this.#hasMagic = this.#hasMagic || hasMagic;
|
|
11616
|
+
this.#uflag = this.#uflag || uflag;
|
|
11617
|
+
return re;
|
|
11618
|
+
}).join("");
|
|
11619
|
+
let start2 = "";
|
|
11620
|
+
if (this.isStart()) {
|
|
11621
|
+
if (typeof this.#parts[0] === "string") {
|
|
11622
|
+
const dotTravAllowed = this.#parts.length === 1 && justDots.has(this.#parts[0]);
|
|
11623
|
+
if (!dotTravAllowed) {
|
|
11624
|
+
const aps = addPatternStart;
|
|
11625
|
+
const needNoTrav = (
|
|
11626
|
+
// dots are allowed, and the pattern starts with [ or .
|
|
11627
|
+
dot && aps.has(src.charAt(0)) || // the pattern starts with \., and then [ or .
|
|
11628
|
+
src.startsWith("\\.") && aps.has(src.charAt(2)) || // the pattern starts with \.\., and then [ or .
|
|
11629
|
+
src.startsWith("\\.\\.") && aps.has(src.charAt(4))
|
|
11630
|
+
);
|
|
11631
|
+
const needNoDot = !dot && !allowDot && aps.has(src.charAt(0));
|
|
11632
|
+
start2 = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : "";
|
|
11633
|
+
}
|
|
11634
|
+
}
|
|
11635
|
+
}
|
|
11636
|
+
let end = "";
|
|
11637
|
+
if (this.isEnd() && this.#root.#filledNegs && this.#parent?.type === "!") {
|
|
11638
|
+
end = "(?:$|\\/)";
|
|
11639
|
+
}
|
|
11640
|
+
const final2 = start2 + src + end;
|
|
11641
|
+
return [
|
|
11642
|
+
final2,
|
|
11643
|
+
unescape(src),
|
|
11644
|
+
this.#hasMagic = !!this.#hasMagic,
|
|
11645
|
+
this.#uflag
|
|
11646
|
+
];
|
|
11647
|
+
}
|
|
11648
|
+
const repeated = this.type === "*" || this.type === "+";
|
|
11649
|
+
const start = this.type === "!" ? "(?:(?!(?:" : "(?:";
|
|
11650
|
+
let body = this.#partsToRegExp(dot);
|
|
11651
|
+
if (this.isStart() && this.isEnd() && !body && this.type !== "!") {
|
|
11652
|
+
const s = this.toString();
|
|
11653
|
+
const me = this;
|
|
11654
|
+
me.#parts = [s];
|
|
11655
|
+
me.type = null;
|
|
11656
|
+
me.#hasMagic = void 0;
|
|
11657
|
+
return [s, unescape(this.toString()), false, false];
|
|
11658
|
+
}
|
|
11659
|
+
let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot ? "" : this.#partsToRegExp(true);
|
|
11660
|
+
if (bodyDotAllowed === body) {
|
|
11661
|
+
bodyDotAllowed = "";
|
|
11662
|
+
}
|
|
11663
|
+
if (bodyDotAllowed) {
|
|
11664
|
+
body = `(?:${body})(?:${bodyDotAllowed})*?`;
|
|
11665
|
+
}
|
|
11666
|
+
let final = "";
|
|
11667
|
+
if (this.type === "!" && this.#emptyExt) {
|
|
11668
|
+
final = (this.isStart() && !dot ? startNoDot : "") + starNoEmpty;
|
|
11669
|
+
} else {
|
|
11670
|
+
const close = this.type === "!" ? (
|
|
11671
|
+
// !() must match something,but !(x) can match ''
|
|
11672
|
+
"))" + (this.isStart() && !dot && !allowDot ? startNoDot : "") + star + ")"
|
|
11673
|
+
) : this.type === "@" ? ")" : this.type === "?" ? ")?" : this.type === "+" && bodyDotAllowed ? ")" : this.type === "*" && bodyDotAllowed ? `)?` : `)${this.type}`;
|
|
11674
|
+
final = start + body + close;
|
|
11675
|
+
}
|
|
11676
|
+
return [
|
|
11677
|
+
final,
|
|
11678
|
+
unescape(body),
|
|
11679
|
+
this.#hasMagic = !!this.#hasMagic,
|
|
11680
|
+
this.#uflag
|
|
11681
|
+
];
|
|
11682
|
+
}
|
|
11683
|
+
#partsToRegExp(dot) {
|
|
11684
|
+
return this.#parts.map((p) => {
|
|
11685
|
+
if (typeof p === "string") {
|
|
11686
|
+
throw new Error("string type in extglob ast??");
|
|
11687
|
+
}
|
|
11688
|
+
const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot);
|
|
11689
|
+
this.#uflag = this.#uflag || uflag;
|
|
11690
|
+
return re;
|
|
11691
|
+
}).filter((p) => !(this.isStart() && this.isEnd()) || !!p).join("|");
|
|
11692
|
+
}
|
|
11693
|
+
static #parseGlob(glob2, hasMagic, noEmpty = false) {
|
|
11694
|
+
let escaping = false;
|
|
11695
|
+
let re = "";
|
|
11696
|
+
let uflag = false;
|
|
11697
|
+
let inStar = false;
|
|
11698
|
+
for (let i = 0; i < glob2.length; i++) {
|
|
11699
|
+
const c = glob2.charAt(i);
|
|
11700
|
+
if (escaping) {
|
|
11701
|
+
escaping = false;
|
|
11702
|
+
re += (reSpecials.has(c) ? "\\" : "") + c;
|
|
11703
|
+
inStar = false;
|
|
11704
|
+
continue;
|
|
11705
|
+
}
|
|
11706
|
+
if (c === "\\") {
|
|
11707
|
+
if (i === glob2.length - 1) {
|
|
11708
|
+
re += "\\\\";
|
|
11709
|
+
} else {
|
|
11710
|
+
escaping = true;
|
|
11711
|
+
}
|
|
11712
|
+
continue;
|
|
11713
|
+
}
|
|
11714
|
+
if (c === "[") {
|
|
11715
|
+
const [src, needUflag, consumed, magic] = parseClass(glob2, i);
|
|
11716
|
+
if (consumed) {
|
|
11717
|
+
re += src;
|
|
11718
|
+
uflag = uflag || needUflag;
|
|
11719
|
+
i += consumed - 1;
|
|
11720
|
+
hasMagic = hasMagic || magic;
|
|
11721
|
+
inStar = false;
|
|
11722
|
+
continue;
|
|
11723
|
+
}
|
|
11724
|
+
}
|
|
11725
|
+
if (c === "*") {
|
|
11726
|
+
if (inStar)
|
|
11727
|
+
continue;
|
|
11728
|
+
inStar = true;
|
|
11729
|
+
re += noEmpty && /^[*]+$/.test(glob2) ? starNoEmpty : star;
|
|
11730
|
+
hasMagic = true;
|
|
11731
|
+
continue;
|
|
11732
|
+
} else {
|
|
11733
|
+
inStar = false;
|
|
11734
|
+
}
|
|
11735
|
+
if (c === "?") {
|
|
11736
|
+
re += qmark;
|
|
11737
|
+
hasMagic = true;
|
|
11738
|
+
continue;
|
|
11739
|
+
}
|
|
11740
|
+
re += regExpEscape(c);
|
|
11741
|
+
}
|
|
11742
|
+
return [re, unescape(glob2), !!hasMagic, uflag];
|
|
11743
|
+
}
|
|
11744
|
+
};
|
|
11745
|
+
_a = AST;
|
|
11746
|
+
|
|
11747
|
+
// ../../node_modules/.pnpm/minimatch@9.0.9/node_modules/minimatch/dist/esm/escape.js
|
|
11748
|
+
var escape = (s, { windowsPathsNoEscape = false } = {}) => {
|
|
11749
|
+
return windowsPathsNoEscape ? s.replace(/[?*()[\]]/g, "[$&]") : s.replace(/[?*()[\]\\]/g, "\\$&");
|
|
11750
|
+
};
|
|
11751
|
+
|
|
11752
|
+
// ../../node_modules/.pnpm/minimatch@9.0.9/node_modules/minimatch/dist/esm/index.js
|
|
11753
|
+
var minimatch = (p, pattern, options = {}) => {
|
|
11754
|
+
assertValidPattern(pattern);
|
|
11755
|
+
if (!options.nocomment && pattern.charAt(0) === "#") {
|
|
11756
|
+
return false;
|
|
11757
|
+
}
|
|
11758
|
+
return new Minimatch(pattern, options).match(p);
|
|
11759
|
+
};
|
|
11760
|
+
var starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/;
|
|
11761
|
+
var starDotExtTest = (ext2) => (f) => !f.startsWith(".") && f.endsWith(ext2);
|
|
11762
|
+
var starDotExtTestDot = (ext2) => (f) => f.endsWith(ext2);
|
|
11763
|
+
var starDotExtTestNocase = (ext2) => {
|
|
11764
|
+
ext2 = ext2.toLowerCase();
|
|
11765
|
+
return (f) => !f.startsWith(".") && f.toLowerCase().endsWith(ext2);
|
|
11766
|
+
};
|
|
11767
|
+
var starDotExtTestNocaseDot = (ext2) => {
|
|
11768
|
+
ext2 = ext2.toLowerCase();
|
|
11769
|
+
return (f) => f.toLowerCase().endsWith(ext2);
|
|
11770
|
+
};
|
|
11771
|
+
var starDotStarRE = /^\*+\.\*+$/;
|
|
11772
|
+
var starDotStarTest = (f) => !f.startsWith(".") && f.includes(".");
|
|
11773
|
+
var starDotStarTestDot = (f) => f !== "." && f !== ".." && f.includes(".");
|
|
11774
|
+
var dotStarRE = /^\.\*+$/;
|
|
11775
|
+
var dotStarTest = (f) => f !== "." && f !== ".." && f.startsWith(".");
|
|
11776
|
+
var starRE = /^\*+$/;
|
|
11777
|
+
var starTest = (f) => f.length !== 0 && !f.startsWith(".");
|
|
11778
|
+
var starTestDot = (f) => f.length !== 0 && f !== "." && f !== "..";
|
|
11779
|
+
var qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/;
|
|
11780
|
+
var qmarksTestNocase = ([$0, ext2 = ""]) => {
|
|
11781
|
+
const noext = qmarksTestNoExt([$0]);
|
|
11782
|
+
if (!ext2)
|
|
11783
|
+
return noext;
|
|
11784
|
+
ext2 = ext2.toLowerCase();
|
|
11785
|
+
return (f) => noext(f) && f.toLowerCase().endsWith(ext2);
|
|
11786
|
+
};
|
|
11787
|
+
var qmarksTestNocaseDot = ([$0, ext2 = ""]) => {
|
|
11788
|
+
const noext = qmarksTestNoExtDot([$0]);
|
|
11789
|
+
if (!ext2)
|
|
11790
|
+
return noext;
|
|
11791
|
+
ext2 = ext2.toLowerCase();
|
|
11792
|
+
return (f) => noext(f) && f.toLowerCase().endsWith(ext2);
|
|
11793
|
+
};
|
|
11794
|
+
var qmarksTestDot = ([$0, ext2 = ""]) => {
|
|
11795
|
+
const noext = qmarksTestNoExtDot([$0]);
|
|
11796
|
+
return !ext2 ? noext : (f) => noext(f) && f.endsWith(ext2);
|
|
11797
|
+
};
|
|
11798
|
+
var qmarksTest = ([$0, ext2 = ""]) => {
|
|
11799
|
+
const noext = qmarksTestNoExt([$0]);
|
|
11800
|
+
return !ext2 ? noext : (f) => noext(f) && f.endsWith(ext2);
|
|
11801
|
+
};
|
|
11802
|
+
var qmarksTestNoExt = ([$0]) => {
|
|
11803
|
+
const len = $0.length;
|
|
11804
|
+
return (f) => f.length === len && !f.startsWith(".");
|
|
11805
|
+
};
|
|
11806
|
+
var qmarksTestNoExtDot = ([$0]) => {
|
|
11807
|
+
const len = $0.length;
|
|
11808
|
+
return (f) => f.length === len && f !== "." && f !== "..";
|
|
11809
|
+
};
|
|
11810
|
+
var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
|
|
11811
|
+
var path3 = {
|
|
11812
|
+
win32: { sep: "\\" },
|
|
11813
|
+
posix: { sep: "/" }
|
|
11814
|
+
};
|
|
11815
|
+
var sep = defaultPlatform === "win32" ? path3.win32.sep : path3.posix.sep;
|
|
11816
|
+
minimatch.sep = sep;
|
|
11817
|
+
var GLOBSTAR = /* @__PURE__ */ Symbol("globstar **");
|
|
11818
|
+
minimatch.GLOBSTAR = GLOBSTAR;
|
|
11819
|
+
var qmark2 = "[^/]";
|
|
11820
|
+
var star2 = qmark2 + "*?";
|
|
11821
|
+
var twoStarDot = "(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?";
|
|
11822
|
+
var twoStarNoDot = "(?:(?!(?:\\/|^)\\.).)*?";
|
|
11823
|
+
var filter = (pattern, options = {}) => (p) => minimatch(p, pattern, options);
|
|
11824
|
+
minimatch.filter = filter;
|
|
11825
|
+
var ext = (a, b = {}) => Object.assign({}, a, b);
|
|
11826
|
+
var defaults = (def) => {
|
|
11827
|
+
if (!def || typeof def !== "object" || !Object.keys(def).length) {
|
|
11828
|
+
return minimatch;
|
|
11829
|
+
}
|
|
11830
|
+
const orig = minimatch;
|
|
11831
|
+
const m = (p, pattern, options = {}) => orig(p, pattern, ext(def, options));
|
|
11832
|
+
return Object.assign(m, {
|
|
11833
|
+
Minimatch: class Minimatch extends orig.Minimatch {
|
|
11834
|
+
constructor(pattern, options = {}) {
|
|
11835
|
+
super(pattern, ext(def, options));
|
|
11836
|
+
}
|
|
11837
|
+
static defaults(options) {
|
|
11838
|
+
return orig.defaults(ext(def, options)).Minimatch;
|
|
11839
|
+
}
|
|
11840
|
+
},
|
|
11841
|
+
AST: class AST extends orig.AST {
|
|
11842
|
+
/* c8 ignore start */
|
|
11843
|
+
constructor(type, parent, options = {}) {
|
|
11844
|
+
super(type, parent, ext(def, options));
|
|
11845
|
+
}
|
|
11846
|
+
/* c8 ignore stop */
|
|
11847
|
+
static fromGlob(pattern, options = {}) {
|
|
11848
|
+
return orig.AST.fromGlob(pattern, ext(def, options));
|
|
11849
|
+
}
|
|
11850
|
+
},
|
|
11851
|
+
unescape: (s, options = {}) => orig.unescape(s, ext(def, options)),
|
|
11852
|
+
escape: (s, options = {}) => orig.escape(s, ext(def, options)),
|
|
11853
|
+
filter: (pattern, options = {}) => orig.filter(pattern, ext(def, options)),
|
|
11854
|
+
defaults: (options) => orig.defaults(ext(def, options)),
|
|
11855
|
+
makeRe: (pattern, options = {}) => orig.makeRe(pattern, ext(def, options)),
|
|
11856
|
+
braceExpand: (pattern, options = {}) => orig.braceExpand(pattern, ext(def, options)),
|
|
11857
|
+
match: (list, pattern, options = {}) => orig.match(list, pattern, ext(def, options)),
|
|
11858
|
+
sep: orig.sep,
|
|
11859
|
+
GLOBSTAR
|
|
11860
|
+
});
|
|
11861
|
+
};
|
|
11862
|
+
minimatch.defaults = defaults;
|
|
11863
|
+
var braceExpand = (pattern, options = {}) => {
|
|
11864
|
+
assertValidPattern(pattern);
|
|
11865
|
+
if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
|
|
11866
|
+
return [pattern];
|
|
11867
|
+
}
|
|
11868
|
+
return (0, import_brace_expansion.default)(pattern);
|
|
11869
|
+
};
|
|
11870
|
+
minimatch.braceExpand = braceExpand;
|
|
11871
|
+
var makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe();
|
|
11872
|
+
minimatch.makeRe = makeRe;
|
|
11873
|
+
var match = (list, pattern, options = {}) => {
|
|
11874
|
+
const mm = new Minimatch(pattern, options);
|
|
11875
|
+
list = list.filter((f) => mm.match(f));
|
|
11876
|
+
if (mm.options.nonull && !list.length) {
|
|
11877
|
+
list.push(pattern);
|
|
11878
|
+
}
|
|
11879
|
+
return list;
|
|
11880
|
+
};
|
|
11881
|
+
minimatch.match = match;
|
|
11882
|
+
var globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/;
|
|
11883
|
+
var regExpEscape2 = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
|
11884
|
+
var Minimatch = class {
|
|
11885
|
+
options;
|
|
11886
|
+
set;
|
|
11887
|
+
pattern;
|
|
11888
|
+
windowsPathsNoEscape;
|
|
11889
|
+
nonegate;
|
|
11890
|
+
negate;
|
|
11891
|
+
comment;
|
|
11892
|
+
empty;
|
|
11893
|
+
preserveMultipleSlashes;
|
|
11894
|
+
partial;
|
|
11895
|
+
globSet;
|
|
11896
|
+
globParts;
|
|
11897
|
+
nocase;
|
|
11898
|
+
isWindows;
|
|
11899
|
+
platform;
|
|
11900
|
+
windowsNoMagicRoot;
|
|
11901
|
+
maxGlobstarRecursion;
|
|
11902
|
+
regexp;
|
|
11903
|
+
constructor(pattern, options = {}) {
|
|
11904
|
+
assertValidPattern(pattern);
|
|
11905
|
+
options = options || {};
|
|
11906
|
+
this.options = options;
|
|
11907
|
+
this.maxGlobstarRecursion = options.maxGlobstarRecursion ?? 200;
|
|
11908
|
+
this.pattern = pattern;
|
|
11909
|
+
this.platform = options.platform || defaultPlatform;
|
|
11910
|
+
this.isWindows = this.platform === "win32";
|
|
11911
|
+
this.windowsPathsNoEscape = !!options.windowsPathsNoEscape || options.allowWindowsEscape === false;
|
|
11912
|
+
if (this.windowsPathsNoEscape) {
|
|
11913
|
+
this.pattern = this.pattern.replace(/\\/g, "/");
|
|
11914
|
+
}
|
|
11915
|
+
this.preserveMultipleSlashes = !!options.preserveMultipleSlashes;
|
|
11916
|
+
this.regexp = null;
|
|
11917
|
+
this.negate = false;
|
|
11918
|
+
this.nonegate = !!options.nonegate;
|
|
11919
|
+
this.comment = false;
|
|
11920
|
+
this.empty = false;
|
|
11921
|
+
this.partial = !!options.partial;
|
|
11922
|
+
this.nocase = !!this.options.nocase;
|
|
11923
|
+
this.windowsNoMagicRoot = options.windowsNoMagicRoot !== void 0 ? options.windowsNoMagicRoot : !!(this.isWindows && this.nocase);
|
|
11924
|
+
this.globSet = [];
|
|
11925
|
+
this.globParts = [];
|
|
11926
|
+
this.set = [];
|
|
11927
|
+
this.make();
|
|
11928
|
+
}
|
|
11929
|
+
hasMagic() {
|
|
11930
|
+
if (this.options.magicalBraces && this.set.length > 1) {
|
|
11931
|
+
return true;
|
|
11932
|
+
}
|
|
11933
|
+
for (const pattern of this.set) {
|
|
11934
|
+
for (const part of pattern) {
|
|
11935
|
+
if (typeof part !== "string")
|
|
11936
|
+
return true;
|
|
11937
|
+
}
|
|
11938
|
+
}
|
|
11939
|
+
return false;
|
|
11940
|
+
}
|
|
11941
|
+
debug(..._) {
|
|
11942
|
+
}
|
|
11943
|
+
make() {
|
|
11944
|
+
const pattern = this.pattern;
|
|
11945
|
+
const options = this.options;
|
|
11946
|
+
if (!options.nocomment && pattern.charAt(0) === "#") {
|
|
11947
|
+
this.comment = true;
|
|
11948
|
+
return;
|
|
11949
|
+
}
|
|
11950
|
+
if (!pattern) {
|
|
11951
|
+
this.empty = true;
|
|
11952
|
+
return;
|
|
11953
|
+
}
|
|
11954
|
+
this.parseNegate();
|
|
11955
|
+
this.globSet = [...new Set(this.braceExpand())];
|
|
11956
|
+
if (options.debug) {
|
|
11957
|
+
this.debug = (...args) => console.error(...args);
|
|
11958
|
+
}
|
|
11959
|
+
this.debug(this.pattern, this.globSet);
|
|
11960
|
+
const rawGlobParts = this.globSet.map((s) => this.slashSplit(s));
|
|
11961
|
+
this.globParts = this.preprocess(rawGlobParts);
|
|
11962
|
+
this.debug(this.pattern, this.globParts);
|
|
11963
|
+
let set = this.globParts.map((s, _, __) => {
|
|
11964
|
+
if (this.isWindows && this.windowsNoMagicRoot) {
|
|
11965
|
+
const isUNC = s[0] === "" && s[1] === "" && (s[2] === "?" || !globMagic.test(s[2])) && !globMagic.test(s[3]);
|
|
11966
|
+
const isDrive = /^[a-z]:/i.test(s[0]);
|
|
11967
|
+
if (isUNC) {
|
|
11968
|
+
return [...s.slice(0, 4), ...s.slice(4).map((ss) => this.parse(ss))];
|
|
11969
|
+
} else if (isDrive) {
|
|
11970
|
+
return [s[0], ...s.slice(1).map((ss) => this.parse(ss))];
|
|
11971
|
+
}
|
|
11972
|
+
}
|
|
11973
|
+
return s.map((ss) => this.parse(ss));
|
|
11974
|
+
});
|
|
11975
|
+
this.debug(this.pattern, set);
|
|
11976
|
+
this.set = set.filter((s) => s.indexOf(false) === -1);
|
|
11977
|
+
if (this.isWindows) {
|
|
11978
|
+
for (let i = 0; i < this.set.length; i++) {
|
|
11979
|
+
const p = this.set[i];
|
|
11980
|
+
if (p[0] === "" && p[1] === "" && this.globParts[i][2] === "?" && typeof p[3] === "string" && /^[a-z]:$/i.test(p[3])) {
|
|
11981
|
+
p[2] = "?";
|
|
11982
|
+
}
|
|
11983
|
+
}
|
|
11984
|
+
}
|
|
11985
|
+
this.debug(this.pattern, this.set);
|
|
11986
|
+
}
|
|
11987
|
+
// various transforms to equivalent pattern sets that are
|
|
11988
|
+
// faster to process in a filesystem walk. The goal is to
|
|
11989
|
+
// eliminate what we can, and push all ** patterns as far
|
|
11990
|
+
// to the right as possible, even if it increases the number
|
|
11991
|
+
// of patterns that we have to process.
|
|
11992
|
+
preprocess(globParts) {
|
|
11993
|
+
if (this.options.noglobstar) {
|
|
11994
|
+
for (let i = 0; i < globParts.length; i++) {
|
|
11995
|
+
for (let j = 0; j < globParts[i].length; j++) {
|
|
11996
|
+
if (globParts[i][j] === "**") {
|
|
11997
|
+
globParts[i][j] = "*";
|
|
11998
|
+
}
|
|
11999
|
+
}
|
|
12000
|
+
}
|
|
12001
|
+
}
|
|
12002
|
+
const { optimizationLevel = 1 } = this.options;
|
|
12003
|
+
if (optimizationLevel >= 2) {
|
|
12004
|
+
globParts = this.firstPhasePreProcess(globParts);
|
|
12005
|
+
globParts = this.secondPhasePreProcess(globParts);
|
|
12006
|
+
} else if (optimizationLevel >= 1) {
|
|
12007
|
+
globParts = this.levelOneOptimize(globParts);
|
|
12008
|
+
} else {
|
|
12009
|
+
globParts = this.adjascentGlobstarOptimize(globParts);
|
|
12010
|
+
}
|
|
12011
|
+
return globParts;
|
|
12012
|
+
}
|
|
12013
|
+
// just get rid of adjascent ** portions
|
|
12014
|
+
adjascentGlobstarOptimize(globParts) {
|
|
12015
|
+
return globParts.map((parts) => {
|
|
12016
|
+
let gs = -1;
|
|
12017
|
+
while (-1 !== (gs = parts.indexOf("**", gs + 1))) {
|
|
12018
|
+
let i = gs;
|
|
12019
|
+
while (parts[i + 1] === "**") {
|
|
12020
|
+
i++;
|
|
12021
|
+
}
|
|
12022
|
+
if (i !== gs) {
|
|
12023
|
+
parts.splice(gs, i - gs);
|
|
12024
|
+
}
|
|
12025
|
+
}
|
|
12026
|
+
return parts;
|
|
12027
|
+
});
|
|
12028
|
+
}
|
|
12029
|
+
// get rid of adjascent ** and resolve .. portions
|
|
12030
|
+
levelOneOptimize(globParts) {
|
|
12031
|
+
return globParts.map((parts) => {
|
|
12032
|
+
parts = parts.reduce((set, part) => {
|
|
12033
|
+
const prev = set[set.length - 1];
|
|
12034
|
+
if (part === "**" && prev === "**") {
|
|
12035
|
+
return set;
|
|
12036
|
+
}
|
|
12037
|
+
if (part === "..") {
|
|
12038
|
+
if (prev && prev !== ".." && prev !== "." && prev !== "**") {
|
|
12039
|
+
set.pop();
|
|
12040
|
+
return set;
|
|
12041
|
+
}
|
|
12042
|
+
}
|
|
12043
|
+
set.push(part);
|
|
12044
|
+
return set;
|
|
12045
|
+
}, []);
|
|
12046
|
+
return parts.length === 0 ? [""] : parts;
|
|
12047
|
+
});
|
|
12048
|
+
}
|
|
12049
|
+
levelTwoFileOptimize(parts) {
|
|
12050
|
+
if (!Array.isArray(parts)) {
|
|
12051
|
+
parts = this.slashSplit(parts);
|
|
12052
|
+
}
|
|
12053
|
+
let didSomething = false;
|
|
12054
|
+
do {
|
|
12055
|
+
didSomething = false;
|
|
12056
|
+
if (!this.preserveMultipleSlashes) {
|
|
12057
|
+
for (let i = 1; i < parts.length - 1; i++) {
|
|
12058
|
+
const p = parts[i];
|
|
12059
|
+
if (i === 1 && p === "" && parts[0] === "")
|
|
12060
|
+
continue;
|
|
12061
|
+
if (p === "." || p === "") {
|
|
12062
|
+
didSomething = true;
|
|
12063
|
+
parts.splice(i, 1);
|
|
12064
|
+
i--;
|
|
12065
|
+
}
|
|
12066
|
+
}
|
|
12067
|
+
if (parts[0] === "." && parts.length === 2 && (parts[1] === "." || parts[1] === "")) {
|
|
12068
|
+
didSomething = true;
|
|
12069
|
+
parts.pop();
|
|
12070
|
+
}
|
|
12071
|
+
}
|
|
12072
|
+
let dd = 0;
|
|
12073
|
+
while (-1 !== (dd = parts.indexOf("..", dd + 1))) {
|
|
12074
|
+
const p = parts[dd - 1];
|
|
12075
|
+
if (p && p !== "." && p !== ".." && p !== "**") {
|
|
12076
|
+
didSomething = true;
|
|
12077
|
+
parts.splice(dd - 1, 2);
|
|
12078
|
+
dd -= 2;
|
|
12079
|
+
}
|
|
12080
|
+
}
|
|
12081
|
+
} while (didSomething);
|
|
12082
|
+
return parts.length === 0 ? [""] : parts;
|
|
12083
|
+
}
|
|
12084
|
+
// First phase: single-pattern processing
|
|
12085
|
+
// <pre> is 1 or more portions
|
|
12086
|
+
// <rest> is 1 or more portions
|
|
12087
|
+
// <p> is any portion other than ., .., '', or **
|
|
12088
|
+
// <e> is . or ''
|
|
12089
|
+
//
|
|
12090
|
+
// **/.. is *brutal* for filesystem walking performance, because
|
|
12091
|
+
// it effectively resets the recursive walk each time it occurs,
|
|
12092
|
+
// and ** cannot be reduced out by a .. pattern part like a regexp
|
|
12093
|
+
// or most strings (other than .., ., and '') can be.
|
|
12094
|
+
//
|
|
12095
|
+
// <pre>/**/../<p>/<p>/<rest> -> {<pre>/../<p>/<p>/<rest>,<pre>/**/<p>/<p>/<rest>}
|
|
12096
|
+
// <pre>/<e>/<rest> -> <pre>/<rest>
|
|
12097
|
+
// <pre>/<p>/../<rest> -> <pre>/<rest>
|
|
12098
|
+
// **/**/<rest> -> **/<rest>
|
|
12099
|
+
//
|
|
12100
|
+
// **/*/<rest> -> */**/<rest> <== not valid because ** doesn't follow
|
|
12101
|
+
// this WOULD be allowed if ** did follow symlinks, or * didn't
|
|
12102
|
+
firstPhasePreProcess(globParts) {
|
|
12103
|
+
let didSomething = false;
|
|
12104
|
+
do {
|
|
12105
|
+
didSomething = false;
|
|
12106
|
+
for (let parts of globParts) {
|
|
12107
|
+
let gs = -1;
|
|
12108
|
+
while (-1 !== (gs = parts.indexOf("**", gs + 1))) {
|
|
12109
|
+
let gss = gs;
|
|
12110
|
+
while (parts[gss + 1] === "**") {
|
|
12111
|
+
gss++;
|
|
12112
|
+
}
|
|
12113
|
+
if (gss > gs) {
|
|
12114
|
+
parts.splice(gs + 1, gss - gs);
|
|
12115
|
+
}
|
|
12116
|
+
let next = parts[gs + 1];
|
|
12117
|
+
const p = parts[gs + 2];
|
|
12118
|
+
const p2 = parts[gs + 3];
|
|
12119
|
+
if (next !== "..")
|
|
12120
|
+
continue;
|
|
12121
|
+
if (!p || p === "." || p === ".." || !p2 || p2 === "." || p2 === "..") {
|
|
12122
|
+
continue;
|
|
12123
|
+
}
|
|
12124
|
+
didSomething = true;
|
|
12125
|
+
parts.splice(gs, 1);
|
|
12126
|
+
const other = parts.slice(0);
|
|
12127
|
+
other[gs] = "**";
|
|
12128
|
+
globParts.push(other);
|
|
12129
|
+
gs--;
|
|
12130
|
+
}
|
|
12131
|
+
if (!this.preserveMultipleSlashes) {
|
|
12132
|
+
for (let i = 1; i < parts.length - 1; i++) {
|
|
12133
|
+
const p = parts[i];
|
|
12134
|
+
if (i === 1 && p === "" && parts[0] === "")
|
|
12135
|
+
continue;
|
|
12136
|
+
if (p === "." || p === "") {
|
|
12137
|
+
didSomething = true;
|
|
12138
|
+
parts.splice(i, 1);
|
|
12139
|
+
i--;
|
|
12140
|
+
}
|
|
12141
|
+
}
|
|
12142
|
+
if (parts[0] === "." && parts.length === 2 && (parts[1] === "." || parts[1] === "")) {
|
|
12143
|
+
didSomething = true;
|
|
12144
|
+
parts.pop();
|
|
12145
|
+
}
|
|
12146
|
+
}
|
|
12147
|
+
let dd = 0;
|
|
12148
|
+
while (-1 !== (dd = parts.indexOf("..", dd + 1))) {
|
|
12149
|
+
const p = parts[dd - 1];
|
|
12150
|
+
if (p && p !== "." && p !== ".." && p !== "**") {
|
|
12151
|
+
didSomething = true;
|
|
12152
|
+
const needDot = dd === 1 && parts[dd + 1] === "**";
|
|
12153
|
+
const splin = needDot ? ["."] : [];
|
|
12154
|
+
parts.splice(dd - 1, 2, ...splin);
|
|
12155
|
+
if (parts.length === 0)
|
|
12156
|
+
parts.push("");
|
|
12157
|
+
dd -= 2;
|
|
12158
|
+
}
|
|
12159
|
+
}
|
|
12160
|
+
}
|
|
12161
|
+
} while (didSomething);
|
|
12162
|
+
return globParts;
|
|
12163
|
+
}
|
|
12164
|
+
// second phase: multi-pattern dedupes
|
|
12165
|
+
// {<pre>/*/<rest>,<pre>/<p>/<rest>} -> <pre>/*/<rest>
|
|
12166
|
+
// {<pre>/<rest>,<pre>/<rest>} -> <pre>/<rest>
|
|
12167
|
+
// {<pre>/**/<rest>,<pre>/<rest>} -> <pre>/**/<rest>
|
|
12168
|
+
//
|
|
12169
|
+
// {<pre>/**/<rest>,<pre>/**/<p>/<rest>} -> <pre>/**/<rest>
|
|
12170
|
+
// ^-- not valid because ** doens't follow symlinks
|
|
12171
|
+
secondPhasePreProcess(globParts) {
|
|
12172
|
+
for (let i = 0; i < globParts.length - 1; i++) {
|
|
12173
|
+
for (let j = i + 1; j < globParts.length; j++) {
|
|
12174
|
+
const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes);
|
|
12175
|
+
if (matched) {
|
|
12176
|
+
globParts[i] = [];
|
|
12177
|
+
globParts[j] = matched;
|
|
12178
|
+
break;
|
|
12179
|
+
}
|
|
12180
|
+
}
|
|
12181
|
+
}
|
|
12182
|
+
return globParts.filter((gs) => gs.length);
|
|
12183
|
+
}
|
|
12184
|
+
partsMatch(a, b, emptyGSMatch = false) {
|
|
12185
|
+
let ai = 0;
|
|
12186
|
+
let bi = 0;
|
|
12187
|
+
let result = [];
|
|
12188
|
+
let which = "";
|
|
12189
|
+
while (ai < a.length && bi < b.length) {
|
|
12190
|
+
if (a[ai] === b[bi]) {
|
|
12191
|
+
result.push(which === "b" ? b[bi] : a[ai]);
|
|
12192
|
+
ai++;
|
|
12193
|
+
bi++;
|
|
12194
|
+
} else if (emptyGSMatch && a[ai] === "**" && b[bi] === a[ai + 1]) {
|
|
12195
|
+
result.push(a[ai]);
|
|
12196
|
+
ai++;
|
|
12197
|
+
} else if (emptyGSMatch && b[bi] === "**" && a[ai] === b[bi + 1]) {
|
|
12198
|
+
result.push(b[bi]);
|
|
12199
|
+
bi++;
|
|
12200
|
+
} else if (a[ai] === "*" && b[bi] && (this.options.dot || !b[bi].startsWith(".")) && b[bi] !== "**") {
|
|
12201
|
+
if (which === "b")
|
|
12202
|
+
return false;
|
|
12203
|
+
which = "a";
|
|
12204
|
+
result.push(a[ai]);
|
|
12205
|
+
ai++;
|
|
12206
|
+
bi++;
|
|
12207
|
+
} else if (b[bi] === "*" && a[ai] && (this.options.dot || !a[ai].startsWith(".")) && a[ai] !== "**") {
|
|
12208
|
+
if (which === "a")
|
|
12209
|
+
return false;
|
|
12210
|
+
which = "b";
|
|
12211
|
+
result.push(b[bi]);
|
|
12212
|
+
ai++;
|
|
12213
|
+
bi++;
|
|
12214
|
+
} else {
|
|
12215
|
+
return false;
|
|
12216
|
+
}
|
|
12217
|
+
}
|
|
12218
|
+
return a.length === b.length && result;
|
|
12219
|
+
}
|
|
12220
|
+
parseNegate() {
|
|
12221
|
+
if (this.nonegate)
|
|
12222
|
+
return;
|
|
12223
|
+
const pattern = this.pattern;
|
|
12224
|
+
let negate = false;
|
|
12225
|
+
let negateOffset = 0;
|
|
12226
|
+
for (let i = 0; i < pattern.length && pattern.charAt(i) === "!"; i++) {
|
|
12227
|
+
negate = !negate;
|
|
12228
|
+
negateOffset++;
|
|
12229
|
+
}
|
|
12230
|
+
if (negateOffset)
|
|
12231
|
+
this.pattern = pattern.slice(negateOffset);
|
|
12232
|
+
this.negate = negate;
|
|
12233
|
+
}
|
|
12234
|
+
// set partial to true to test if, for example,
|
|
12235
|
+
// "/a/b" matches the start of "/*/b/*/d"
|
|
12236
|
+
// Partial means, if you run out of file before you run
|
|
12237
|
+
// out of pattern, then that's fine, as long as all
|
|
12238
|
+
// the parts match.
|
|
12239
|
+
matchOne(file, pattern, partial = false) {
|
|
12240
|
+
let fileStartIndex = 0;
|
|
12241
|
+
let patternStartIndex = 0;
|
|
12242
|
+
if (this.isWindows) {
|
|
12243
|
+
const fileDrive = typeof file[0] === "string" && /^[a-z]:$/i.test(file[0]);
|
|
12244
|
+
const fileUNC = !fileDrive && file[0] === "" && file[1] === "" && file[2] === "?" && /^[a-z]:$/i.test(file[3]);
|
|
12245
|
+
const patternDrive = typeof pattern[0] === "string" && /^[a-z]:$/i.test(pattern[0]);
|
|
12246
|
+
const patternUNC = !patternDrive && pattern[0] === "" && pattern[1] === "" && pattern[2] === "?" && typeof pattern[3] === "string" && /^[a-z]:$/i.test(pattern[3]);
|
|
12247
|
+
const fdi = fileUNC ? 3 : fileDrive ? 0 : void 0;
|
|
12248
|
+
const pdi = patternUNC ? 3 : patternDrive ? 0 : void 0;
|
|
12249
|
+
if (typeof fdi === "number" && typeof pdi === "number") {
|
|
12250
|
+
const [fd, pd] = [
|
|
12251
|
+
file[fdi],
|
|
12252
|
+
pattern[pdi]
|
|
12253
|
+
];
|
|
12254
|
+
if (fd.toLowerCase() === pd.toLowerCase()) {
|
|
12255
|
+
pattern[pdi] = fd;
|
|
12256
|
+
patternStartIndex = pdi;
|
|
12257
|
+
fileStartIndex = fdi;
|
|
12258
|
+
}
|
|
12259
|
+
}
|
|
12260
|
+
}
|
|
12261
|
+
const { optimizationLevel = 1 } = this.options;
|
|
12262
|
+
if (optimizationLevel >= 2) {
|
|
12263
|
+
file = this.levelTwoFileOptimize(file);
|
|
12264
|
+
}
|
|
12265
|
+
if (pattern.includes(GLOBSTAR)) {
|
|
12266
|
+
return this.#matchGlobstar(file, pattern, partial, fileStartIndex, patternStartIndex);
|
|
12267
|
+
}
|
|
12268
|
+
return this.#matchOne(file, pattern, partial, fileStartIndex, patternStartIndex);
|
|
12269
|
+
}
|
|
12270
|
+
#matchGlobstar(file, pattern, partial, fileIndex, patternIndex) {
|
|
12271
|
+
const firstgs = pattern.indexOf(GLOBSTAR, patternIndex);
|
|
12272
|
+
const lastgs = pattern.lastIndexOf(GLOBSTAR);
|
|
12273
|
+
const [head, body, tail] = partial ? [
|
|
12274
|
+
pattern.slice(patternIndex, firstgs),
|
|
12275
|
+
pattern.slice(firstgs + 1),
|
|
12276
|
+
[]
|
|
12277
|
+
] : [
|
|
12278
|
+
pattern.slice(patternIndex, firstgs),
|
|
12279
|
+
pattern.slice(firstgs + 1, lastgs),
|
|
12280
|
+
pattern.slice(lastgs + 1)
|
|
12281
|
+
];
|
|
12282
|
+
if (head.length) {
|
|
12283
|
+
const fileHead = file.slice(fileIndex, fileIndex + head.length);
|
|
12284
|
+
if (!this.#matchOne(fileHead, head, partial, 0, 0))
|
|
12285
|
+
return false;
|
|
12286
|
+
fileIndex += head.length;
|
|
12287
|
+
}
|
|
12288
|
+
let fileTailMatch = 0;
|
|
12289
|
+
if (tail.length) {
|
|
12290
|
+
if (tail.length + fileIndex > file.length)
|
|
12291
|
+
return false;
|
|
12292
|
+
let tailStart = file.length - tail.length;
|
|
12293
|
+
if (this.#matchOne(file, tail, partial, tailStart, 0)) {
|
|
12294
|
+
fileTailMatch = tail.length;
|
|
12295
|
+
} else {
|
|
12296
|
+
if (file[file.length - 1] !== "" || fileIndex + tail.length === file.length) {
|
|
12297
|
+
return false;
|
|
12298
|
+
}
|
|
12299
|
+
tailStart--;
|
|
12300
|
+
if (!this.#matchOne(file, tail, partial, tailStart, 0))
|
|
12301
|
+
return false;
|
|
12302
|
+
fileTailMatch = tail.length + 1;
|
|
12303
|
+
}
|
|
12304
|
+
}
|
|
12305
|
+
if (!body.length) {
|
|
12306
|
+
let sawSome = !!fileTailMatch;
|
|
12307
|
+
for (let i2 = fileIndex; i2 < file.length - fileTailMatch; i2++) {
|
|
12308
|
+
const f = String(file[i2]);
|
|
12309
|
+
sawSome = true;
|
|
12310
|
+
if (f === "." || f === ".." || !this.options.dot && f.startsWith(".")) {
|
|
12311
|
+
return false;
|
|
12312
|
+
}
|
|
12313
|
+
}
|
|
12314
|
+
return partial || sawSome;
|
|
12315
|
+
}
|
|
12316
|
+
const bodySegments = [[[], 0]];
|
|
12317
|
+
let currentBody = bodySegments[0];
|
|
12318
|
+
let nonGsParts = 0;
|
|
12319
|
+
const nonGsPartsSums = [0];
|
|
12320
|
+
for (const b of body) {
|
|
12321
|
+
if (b === GLOBSTAR) {
|
|
12322
|
+
nonGsPartsSums.push(nonGsParts);
|
|
12323
|
+
currentBody = [[], 0];
|
|
12324
|
+
bodySegments.push(currentBody);
|
|
12325
|
+
} else {
|
|
12326
|
+
currentBody[0].push(b);
|
|
12327
|
+
nonGsParts++;
|
|
12328
|
+
}
|
|
12329
|
+
}
|
|
12330
|
+
let i = bodySegments.length - 1;
|
|
12331
|
+
const fileLength = file.length - fileTailMatch;
|
|
12332
|
+
for (const b of bodySegments) {
|
|
12333
|
+
b[1] = fileLength - (nonGsPartsSums[i--] + b[0].length);
|
|
12334
|
+
}
|
|
12335
|
+
return !!this.#matchGlobStarBodySections(file, bodySegments, fileIndex, 0, partial, 0, !!fileTailMatch);
|
|
12336
|
+
}
|
|
12337
|
+
#matchGlobStarBodySections(file, bodySegments, fileIndex, bodyIndex, partial, globStarDepth, sawTail) {
|
|
12338
|
+
const bs = bodySegments[bodyIndex];
|
|
12339
|
+
if (!bs) {
|
|
12340
|
+
for (let i = fileIndex; i < file.length; i++) {
|
|
12341
|
+
sawTail = true;
|
|
12342
|
+
const f = file[i];
|
|
12343
|
+
if (f === "." || f === ".." || !this.options.dot && f.startsWith(".")) {
|
|
12344
|
+
return false;
|
|
12345
|
+
}
|
|
12346
|
+
}
|
|
12347
|
+
return sawTail;
|
|
12348
|
+
}
|
|
12349
|
+
const [body, after] = bs;
|
|
12350
|
+
while (fileIndex <= after) {
|
|
12351
|
+
const m = this.#matchOne(file.slice(0, fileIndex + body.length), body, partial, fileIndex, 0);
|
|
12352
|
+
if (m && globStarDepth < this.maxGlobstarRecursion) {
|
|
12353
|
+
const sub = this.#matchGlobStarBodySections(file, bodySegments, fileIndex + body.length, bodyIndex + 1, partial, globStarDepth + 1, sawTail);
|
|
12354
|
+
if (sub !== false)
|
|
12355
|
+
return sub;
|
|
12356
|
+
}
|
|
12357
|
+
const f = file[fileIndex];
|
|
12358
|
+
if (f === "." || f === ".." || !this.options.dot && f.startsWith(".")) {
|
|
12359
|
+
return false;
|
|
12360
|
+
}
|
|
12361
|
+
fileIndex++;
|
|
12362
|
+
}
|
|
12363
|
+
return partial || null;
|
|
12364
|
+
}
|
|
12365
|
+
#matchOne(file, pattern, partial, fileIndex, patternIndex) {
|
|
12366
|
+
let fi;
|
|
12367
|
+
let pi;
|
|
12368
|
+
let pl;
|
|
12369
|
+
let fl;
|
|
12370
|
+
for (fi = fileIndex, pi = patternIndex, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
|
|
12371
|
+
this.debug("matchOne loop");
|
|
12372
|
+
let p = pattern[pi];
|
|
12373
|
+
let f = file[fi];
|
|
12374
|
+
this.debug(pattern, p, f);
|
|
12375
|
+
if (p === false || p === GLOBSTAR)
|
|
12376
|
+
return false;
|
|
12377
|
+
let hit;
|
|
12378
|
+
if (typeof p === "string") {
|
|
12379
|
+
hit = f === p;
|
|
12380
|
+
this.debug("string match", p, f, hit);
|
|
12381
|
+
} else {
|
|
12382
|
+
hit = p.test(f);
|
|
12383
|
+
this.debug("pattern match", p, f, hit);
|
|
12384
|
+
}
|
|
12385
|
+
if (!hit)
|
|
12386
|
+
return false;
|
|
12387
|
+
}
|
|
12388
|
+
if (fi === fl && pi === pl) {
|
|
12389
|
+
return true;
|
|
12390
|
+
} else if (fi === fl) {
|
|
12391
|
+
return partial;
|
|
12392
|
+
} else if (pi === pl) {
|
|
12393
|
+
return fi === fl - 1 && file[fi] === "";
|
|
12394
|
+
} else {
|
|
12395
|
+
throw new Error("wtf?");
|
|
12396
|
+
}
|
|
12397
|
+
}
|
|
12398
|
+
braceExpand() {
|
|
12399
|
+
return braceExpand(this.pattern, this.options);
|
|
12400
|
+
}
|
|
12401
|
+
parse(pattern) {
|
|
12402
|
+
assertValidPattern(pattern);
|
|
12403
|
+
const options = this.options;
|
|
12404
|
+
if (pattern === "**")
|
|
12405
|
+
return GLOBSTAR;
|
|
12406
|
+
if (pattern === "")
|
|
12407
|
+
return "";
|
|
12408
|
+
let m;
|
|
12409
|
+
let fastTest = null;
|
|
12410
|
+
if (m = pattern.match(starRE)) {
|
|
12411
|
+
fastTest = options.dot ? starTestDot : starTest;
|
|
12412
|
+
} else if (m = pattern.match(starDotExtRE)) {
|
|
12413
|
+
fastTest = (options.nocase ? options.dot ? starDotExtTestNocaseDot : starDotExtTestNocase : options.dot ? starDotExtTestDot : starDotExtTest)(m[1]);
|
|
12414
|
+
} else if (m = pattern.match(qmarksRE)) {
|
|
12415
|
+
fastTest = (options.nocase ? options.dot ? qmarksTestNocaseDot : qmarksTestNocase : options.dot ? qmarksTestDot : qmarksTest)(m);
|
|
12416
|
+
} else if (m = pattern.match(starDotStarRE)) {
|
|
12417
|
+
fastTest = options.dot ? starDotStarTestDot : starDotStarTest;
|
|
12418
|
+
} else if (m = pattern.match(dotStarRE)) {
|
|
12419
|
+
fastTest = dotStarTest;
|
|
12420
|
+
}
|
|
12421
|
+
const re = AST.fromGlob(pattern, this.options).toMMPattern();
|
|
12422
|
+
if (fastTest && typeof re === "object") {
|
|
12423
|
+
Reflect.defineProperty(re, "test", { value: fastTest });
|
|
12424
|
+
}
|
|
12425
|
+
return re;
|
|
12426
|
+
}
|
|
12427
|
+
makeRe() {
|
|
12428
|
+
if (this.regexp || this.regexp === false)
|
|
12429
|
+
return this.regexp;
|
|
12430
|
+
const set = this.set;
|
|
12431
|
+
if (!set.length) {
|
|
12432
|
+
this.regexp = false;
|
|
12433
|
+
return this.regexp;
|
|
12434
|
+
}
|
|
12435
|
+
const options = this.options;
|
|
12436
|
+
const twoStar = options.noglobstar ? star2 : options.dot ? twoStarDot : twoStarNoDot;
|
|
12437
|
+
const flags = new Set(options.nocase ? ["i"] : []);
|
|
12438
|
+
let re = set.map((pattern) => {
|
|
12439
|
+
const pp = pattern.map((p) => {
|
|
12440
|
+
if (p instanceof RegExp) {
|
|
12441
|
+
for (const f of p.flags.split(""))
|
|
12442
|
+
flags.add(f);
|
|
12443
|
+
}
|
|
12444
|
+
return typeof p === "string" ? regExpEscape2(p) : p === GLOBSTAR ? GLOBSTAR : p._src;
|
|
12445
|
+
});
|
|
12446
|
+
pp.forEach((p, i) => {
|
|
12447
|
+
const next = pp[i + 1];
|
|
12448
|
+
const prev = pp[i - 1];
|
|
12449
|
+
if (p !== GLOBSTAR || prev === GLOBSTAR) {
|
|
12450
|
+
return;
|
|
12451
|
+
}
|
|
12452
|
+
if (prev === void 0) {
|
|
12453
|
+
if (next !== void 0 && next !== GLOBSTAR) {
|
|
12454
|
+
pp[i + 1] = "(?:\\/|" + twoStar + "\\/)?" + next;
|
|
12455
|
+
} else {
|
|
12456
|
+
pp[i] = twoStar;
|
|
12457
|
+
}
|
|
12458
|
+
} else if (next === void 0) {
|
|
12459
|
+
pp[i - 1] = prev + "(?:\\/|" + twoStar + ")?";
|
|
12460
|
+
} else if (next !== GLOBSTAR) {
|
|
12461
|
+
pp[i - 1] = prev + "(?:\\/|\\/" + twoStar + "\\/)" + next;
|
|
12462
|
+
pp[i + 1] = GLOBSTAR;
|
|
12463
|
+
}
|
|
12464
|
+
});
|
|
12465
|
+
return pp.filter((p) => p !== GLOBSTAR).join("/");
|
|
12466
|
+
}).join("|");
|
|
12467
|
+
const [open2, close] = set.length > 1 ? ["(?:", ")"] : ["", ""];
|
|
12468
|
+
re = "^" + open2 + re + close + "$";
|
|
12469
|
+
if (this.negate)
|
|
12470
|
+
re = "^(?!" + re + ").+$";
|
|
12471
|
+
try {
|
|
12472
|
+
this.regexp = new RegExp(re, [...flags].join(""));
|
|
12473
|
+
} catch (ex) {
|
|
12474
|
+
this.regexp = false;
|
|
12475
|
+
}
|
|
12476
|
+
return this.regexp;
|
|
12477
|
+
}
|
|
12478
|
+
slashSplit(p) {
|
|
12479
|
+
if (this.preserveMultipleSlashes) {
|
|
12480
|
+
return p.split("/");
|
|
12481
|
+
} else if (this.isWindows && /^\/\/[^\/]+/.test(p)) {
|
|
12482
|
+
return ["", ...p.split(/\/+/)];
|
|
12483
|
+
} else {
|
|
12484
|
+
return p.split(/\/+/);
|
|
12485
|
+
}
|
|
12486
|
+
}
|
|
12487
|
+
match(f, partial = this.partial) {
|
|
12488
|
+
this.debug("match", f, this.pattern);
|
|
12489
|
+
if (this.comment) {
|
|
12490
|
+
return false;
|
|
12491
|
+
}
|
|
12492
|
+
if (this.empty) {
|
|
12493
|
+
return f === "";
|
|
12494
|
+
}
|
|
12495
|
+
if (f === "/" && partial) {
|
|
12496
|
+
return true;
|
|
12497
|
+
}
|
|
12498
|
+
const options = this.options;
|
|
12499
|
+
if (this.isWindows) {
|
|
12500
|
+
f = f.split("\\").join("/");
|
|
12501
|
+
}
|
|
12502
|
+
const ff = this.slashSplit(f);
|
|
12503
|
+
this.debug(this.pattern, "split", ff);
|
|
12504
|
+
const set = this.set;
|
|
12505
|
+
this.debug(this.pattern, "set", set);
|
|
12506
|
+
let filename = ff[ff.length - 1];
|
|
12507
|
+
if (!filename) {
|
|
12508
|
+
for (let i = ff.length - 2; !filename && i >= 0; i--) {
|
|
12509
|
+
filename = ff[i];
|
|
12510
|
+
}
|
|
12511
|
+
}
|
|
12512
|
+
for (let i = 0; i < set.length; i++) {
|
|
12513
|
+
const pattern = set[i];
|
|
12514
|
+
let file = ff;
|
|
12515
|
+
if (options.matchBase && pattern.length === 1) {
|
|
12516
|
+
file = [filename];
|
|
12517
|
+
}
|
|
12518
|
+
const hit = this.matchOne(file, pattern, partial);
|
|
12519
|
+
if (hit) {
|
|
12520
|
+
if (options.flipNegate) {
|
|
12521
|
+
return true;
|
|
12522
|
+
}
|
|
12523
|
+
return !this.negate;
|
|
12524
|
+
}
|
|
12525
|
+
}
|
|
12526
|
+
if (options.flipNegate) {
|
|
12527
|
+
return false;
|
|
12528
|
+
}
|
|
12529
|
+
return this.negate;
|
|
12530
|
+
}
|
|
12531
|
+
static defaults(def) {
|
|
12532
|
+
return minimatch.defaults(def).Minimatch;
|
|
12533
|
+
}
|
|
12534
|
+
};
|
|
12535
|
+
minimatch.AST = AST;
|
|
12536
|
+
minimatch.Minimatch = Minimatch;
|
|
12537
|
+
minimatch.escape = escape;
|
|
12538
|
+
minimatch.unescape = unescape;
|
|
12539
|
+
|
|
12540
|
+
// ../../packages/flint-server/dist/index.js
|
|
12541
|
+
import { parse as parseYaml } from "yaml";
|
|
12542
|
+
import { existsSync as existsSync10, watch as watch3 } from "fs";
|
|
12543
|
+
import { stat as stat22 } from "fs/promises";
|
|
12544
|
+
import path22 from "path";
|
|
12545
|
+
import { mkdir as mkdir5, readFile as readFile22, writeFile as writeFile3 } from "fs/promises";
|
|
12546
|
+
import { homedir as homedir6 } from "os";
|
|
12547
|
+
import { join as join11, resolve as resolve7 } from "path";
|
|
12548
|
+
import { existsSync as existsSync23 } from "fs";
|
|
12549
|
+
import { stat as stat32, readFile as readFile32 } from "fs/promises";
|
|
12550
|
+
import path32 from "path";
|
|
12551
|
+
import { existsSync as existsSync33 } from "fs";
|
|
12552
|
+
import { spawn as spawn22 } from "child_process";
|
|
12553
|
+
import { readFile as readFile42 } from "fs/promises";
|
|
12554
|
+
import path42 from "path";
|
|
12555
|
+
import { readdir as readdir2 } from "fs/promises";
|
|
12556
|
+
import path5 from "path";
|
|
12557
|
+
import { readdir as readdir22 } from "fs/promises";
|
|
12558
|
+
import { join as join23 } from "path";
|
|
12559
|
+
import { mkdir as mkdir22, readFile as readFile52, rename as rename2, writeFile as writeFile22, readdir as readdir3 } from "fs/promises";
|
|
12560
|
+
import path6 from "path";
|
|
12561
|
+
import { randomUUID as randomUUID22 } from "crypto";
|
|
12562
|
+
import { writeFile as writeFile32, mkdir as mkdir32, readdir as readdir4, readFile as readFile62, stat as stat42 } from "fs/promises";
|
|
12563
|
+
import { join as join33 } from "path";
|
|
12564
|
+
var DEFAULT_EVENT_LOG_SIZE = 200;
|
|
12565
|
+
function computeRuntimeId(flintPath) {
|
|
12566
|
+
const resolved = path4.resolve(flintPath);
|
|
12567
|
+
return createHash2("sha1").update(resolved).digest("hex").slice(0, 10);
|
|
12568
|
+
}
|
|
12569
|
+
function createRuntime(options) {
|
|
12570
|
+
return new FlintRuntimeImpl(options);
|
|
12571
|
+
}
|
|
12572
|
+
var FlintRuntimeImpl = class {
|
|
12573
|
+
id;
|
|
12574
|
+
flintPath;
|
|
12575
|
+
hooksPath;
|
|
12576
|
+
logger;
|
|
12577
|
+
eventLogSize;
|
|
12578
|
+
emitter = new EventEmitter();
|
|
12579
|
+
watcher = null;
|
|
12580
|
+
hooksConfig = { hooks: {} };
|
|
12581
|
+
eventLog = [];
|
|
12582
|
+
frontmatterCache = /* @__PURE__ */ new Map();
|
|
12583
|
+
sessionCache = /* @__PURE__ */ new Map();
|
|
12584
|
+
startedAt = null;
|
|
12585
|
+
constructor(options) {
|
|
12586
|
+
this.flintPath = path4.resolve(options.flintPath);
|
|
12587
|
+
this.hooksPath = options.hooksPath ? path4.resolve(options.hooksPath) : path4.join(this.flintPath, "flint-hooks.toml");
|
|
12588
|
+
this.id = computeRuntimeId(this.flintPath);
|
|
12589
|
+
this.eventLogSize = options.eventLogSize ?? DEFAULT_EVENT_LOG_SIZE;
|
|
12590
|
+
this.logger = options.logger ?? {
|
|
12591
|
+
debug: (...args) => console.debug("[flint-runtime]", ...args),
|
|
12592
|
+
info: (...args) => console.info("[flint-runtime]", ...args),
|
|
12593
|
+
warn: (...args) => console.warn("[flint-runtime]", ...args),
|
|
12594
|
+
error: (...args) => console.error("[flint-runtime]", ...args)
|
|
12595
|
+
};
|
|
12596
|
+
}
|
|
12597
|
+
on(event, handler) {
|
|
12598
|
+
this.emitter.on(event, handler);
|
|
12599
|
+
}
|
|
12600
|
+
off(event, handler) {
|
|
12601
|
+
this.emitter.off(event, handler);
|
|
12602
|
+
}
|
|
12603
|
+
async start() {
|
|
12604
|
+
if (this.watcher) {
|
|
12605
|
+
return;
|
|
12606
|
+
}
|
|
12607
|
+
await this.reloadHooks();
|
|
12608
|
+
await this.seedCaches();
|
|
12609
|
+
const relativeHooksPath = path4.relative(this.flintPath, this.hooksPath);
|
|
12610
|
+
const watchPatterns = [
|
|
12611
|
+
"Mesh/**/*.md",
|
|
12612
|
+
".flint/sessions/*.json",
|
|
12613
|
+
relativeHooksPath || "flint-hooks.toml"
|
|
12614
|
+
];
|
|
12615
|
+
this.watcher = chokidar.watch(watchPatterns, {
|
|
12616
|
+
cwd: this.flintPath,
|
|
12617
|
+
ignoreInitial: true,
|
|
12618
|
+
awaitWriteFinish: {
|
|
12619
|
+
stabilityThreshold: 200,
|
|
12620
|
+
pollInterval: 50
|
|
12621
|
+
}
|
|
12622
|
+
});
|
|
12623
|
+
this.watcher.on("add", (filePath) => this.handleWatchEvent("add", filePath));
|
|
12624
|
+
this.watcher.on("change", (filePath) => this.handleWatchEvent("change", filePath));
|
|
12625
|
+
this.watcher.on("unlink", (filePath) => this.handleWatchEvent("unlink", filePath));
|
|
12626
|
+
this.startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
12627
|
+
await this.emitEvent("RuntimeStart", {
|
|
12628
|
+
startedAt: this.startedAt
|
|
12629
|
+
});
|
|
12630
|
+
}
|
|
12631
|
+
async stop() {
|
|
12632
|
+
if (!this.watcher) {
|
|
12633
|
+
return;
|
|
12634
|
+
}
|
|
12635
|
+
await this.emitEvent("RuntimeStop", {
|
|
12636
|
+
stoppedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
12637
|
+
});
|
|
12638
|
+
await this.watcher.close();
|
|
12639
|
+
this.watcher = null;
|
|
12640
|
+
}
|
|
12641
|
+
async reloadHooks() {
|
|
12642
|
+
this.hooksConfig = await loadHooksConfig(this.hooksPath, this.logger);
|
|
12643
|
+
}
|
|
12644
|
+
getStatus() {
|
|
12645
|
+
return {
|
|
12646
|
+
id: this.id,
|
|
12647
|
+
flintPath: this.flintPath,
|
|
12648
|
+
hooksPath: this.hooksPath,
|
|
12649
|
+
startedAt: this.startedAt,
|
|
12650
|
+
watching: this.watcher !== null,
|
|
12651
|
+
hookCount: countHooks(this.hooksConfig)
|
|
12652
|
+
};
|
|
12653
|
+
}
|
|
12654
|
+
getEventLog() {
|
|
12655
|
+
return [...this.eventLog];
|
|
12656
|
+
}
|
|
12657
|
+
async seedCaches() {
|
|
12658
|
+
const meshFiles = await glob("Mesh/**/*.md", {
|
|
12659
|
+
cwd: this.flintPath,
|
|
12660
|
+
nodir: true
|
|
12661
|
+
});
|
|
12662
|
+
await Promise.all(
|
|
12663
|
+
meshFiles.map(async (filePath) => {
|
|
12664
|
+
const snapshot = await this.readFrontmatterSnapshot(filePath);
|
|
12665
|
+
if (snapshot) {
|
|
12666
|
+
this.frontmatterCache.set(filePath, snapshot);
|
|
12667
|
+
}
|
|
12668
|
+
})
|
|
12669
|
+
);
|
|
12670
|
+
const sessionFiles = await glob(".flint/sessions/*.json", {
|
|
12671
|
+
cwd: this.flintPath,
|
|
12672
|
+
nodir: true
|
|
12673
|
+
});
|
|
12674
|
+
await Promise.all(
|
|
12675
|
+
sessionFiles.map(async (filePath) => {
|
|
12676
|
+
const snapshot = await this.readSessionSnapshot(filePath);
|
|
12677
|
+
if (snapshot) {
|
|
12678
|
+
const sessionId = path4.basename(filePath, ".json");
|
|
12679
|
+
this.sessionCache.set(sessionId, snapshot);
|
|
12680
|
+
}
|
|
12681
|
+
})
|
|
12682
|
+
);
|
|
12683
|
+
}
|
|
12684
|
+
async handleWatchEvent(event, filePath) {
|
|
12685
|
+
const normalized = normalizePath(filePath);
|
|
12686
|
+
if (normalized === normalizePath(path4.relative(this.flintPath, this.hooksPath))) {
|
|
12687
|
+
if (event === "change") {
|
|
12688
|
+
this.logger.info?.("Reloading hooks config");
|
|
12689
|
+
await this.reloadHooks();
|
|
12690
|
+
}
|
|
12691
|
+
return;
|
|
12692
|
+
}
|
|
12693
|
+
if (normalized.startsWith("Mesh/")) {
|
|
12694
|
+
if (event === "unlink") {
|
|
12695
|
+
this.frontmatterCache.delete(normalized);
|
|
12696
|
+
return;
|
|
12697
|
+
}
|
|
12698
|
+
await this.handleMeshFileChange(normalized);
|
|
12699
|
+
return;
|
|
12700
|
+
}
|
|
12701
|
+
if (normalized.startsWith(".flint/sessions/")) {
|
|
12702
|
+
if (event === "unlink") {
|
|
12703
|
+
const sessionId = path4.basename(normalized, ".json");
|
|
12704
|
+
this.sessionCache.delete(sessionId);
|
|
12705
|
+
return;
|
|
12706
|
+
}
|
|
12707
|
+
await this.handleSessionFileChange(normalized);
|
|
12708
|
+
return;
|
|
12709
|
+
}
|
|
12710
|
+
}
|
|
12711
|
+
async handleMeshFileChange(relativePath) {
|
|
12712
|
+
const snapshot = await this.readFrontmatterSnapshot(relativePath);
|
|
12713
|
+
if (!snapshot) {
|
|
12714
|
+
return;
|
|
12715
|
+
}
|
|
12716
|
+
const previous = this.frontmatterCache.get(relativePath);
|
|
12717
|
+
this.frontmatterCache.set(relativePath, snapshot);
|
|
12718
|
+
await this.emitEvent("FileChanged", {
|
|
12719
|
+
path: relativePath,
|
|
12720
|
+
absolutePath: path4.join(this.flintPath, relativePath),
|
|
12721
|
+
frontmatter: snapshot,
|
|
12722
|
+
previousFrontmatter: previous ?? null
|
|
12723
|
+
});
|
|
12724
|
+
if (!previous) {
|
|
12725
|
+
return;
|
|
12726
|
+
}
|
|
12727
|
+
if (previous.status !== snapshot.status) {
|
|
12728
|
+
await this.emitEvent("StatusChanged", {
|
|
12729
|
+
path: relativePath,
|
|
12730
|
+
absolutePath: path4.join(this.flintPath, relativePath),
|
|
12731
|
+
field: "status",
|
|
12732
|
+
from: previous.status ?? null,
|
|
12733
|
+
to: snapshot.status ?? null,
|
|
12734
|
+
tags: snapshot.tags
|
|
12735
|
+
});
|
|
12736
|
+
}
|
|
12737
|
+
const addedTags = snapshot.tags.filter((tag) => !previous.tags.includes(tag));
|
|
12738
|
+
const removedTags = previous.tags.filter((tag) => !snapshot.tags.includes(tag));
|
|
12739
|
+
for (const tag of addedTags) {
|
|
12740
|
+
await this.emitEvent("TagAdded", {
|
|
12741
|
+
path: relativePath,
|
|
12742
|
+
absolutePath: path4.join(this.flintPath, relativePath),
|
|
12743
|
+
tag,
|
|
12744
|
+
tags: snapshot.tags
|
|
12745
|
+
});
|
|
12746
|
+
}
|
|
12747
|
+
for (const tag of removedTags) {
|
|
12748
|
+
await this.emitEvent("TagRemoved", {
|
|
12749
|
+
path: relativePath,
|
|
12750
|
+
absolutePath: path4.join(this.flintPath, relativePath),
|
|
12751
|
+
tag,
|
|
12752
|
+
tags: snapshot.tags
|
|
12753
|
+
});
|
|
12754
|
+
}
|
|
12755
|
+
}
|
|
12756
|
+
async handleSessionFileChange(relativePath) {
|
|
12757
|
+
const snapshot = await this.readSessionSnapshot(relativePath);
|
|
12758
|
+
if (!snapshot) {
|
|
12759
|
+
return;
|
|
12760
|
+
}
|
|
12761
|
+
const sessionId = path4.basename(relativePath, ".json");
|
|
12762
|
+
const previous = this.sessionCache.get(sessionId);
|
|
12763
|
+
this.sessionCache.set(sessionId, snapshot);
|
|
12764
|
+
if (!previous && snapshot.status === "active") {
|
|
12765
|
+
await this.emitEvent("AgentStart", {
|
|
12766
|
+
sessionId,
|
|
12767
|
+
status: snapshot.status,
|
|
12768
|
+
model: snapshot.model,
|
|
12769
|
+
goal: snapshot.goal
|
|
12770
|
+
});
|
|
12771
|
+
return;
|
|
12772
|
+
}
|
|
12773
|
+
if (previous?.status !== snapshot.status) {
|
|
12774
|
+
if (snapshot.status === "active") {
|
|
12775
|
+
await this.emitEvent("AgentStart", {
|
|
12776
|
+
sessionId,
|
|
12777
|
+
status: snapshot.status,
|
|
12778
|
+
model: snapshot.model,
|
|
12779
|
+
goal: snapshot.goal
|
|
12780
|
+
});
|
|
12781
|
+
} else if (snapshot.status) {
|
|
12782
|
+
await this.emitEvent("AgentComplete", {
|
|
12783
|
+
sessionId,
|
|
12784
|
+
status: snapshot.status,
|
|
12785
|
+
model: snapshot.model,
|
|
12786
|
+
goal: snapshot.goal
|
|
12787
|
+
});
|
|
12788
|
+
}
|
|
12789
|
+
}
|
|
12790
|
+
}
|
|
12791
|
+
async emitEvent(type, payload) {
|
|
12792
|
+
const event = {
|
|
12793
|
+
id: randomUUID3(),
|
|
12794
|
+
type,
|
|
12795
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12796
|
+
payload
|
|
12797
|
+
};
|
|
12798
|
+
this.eventLog.push(event);
|
|
12799
|
+
if (this.eventLog.length > this.eventLogSize) {
|
|
12800
|
+
this.eventLog.shift();
|
|
12801
|
+
}
|
|
12802
|
+
this.emitter.emit(type, event);
|
|
12803
|
+
await this.runHooks(type, event);
|
|
12804
|
+
}
|
|
12805
|
+
async runHooks(type, event) {
|
|
12806
|
+
const hooks = (this.hooksConfig.hooks ?? {})[type] ?? [];
|
|
12807
|
+
if (!hooks.length) {
|
|
12808
|
+
return;
|
|
12809
|
+
}
|
|
12810
|
+
for (const hook of hooks) {
|
|
12811
|
+
if (!hookMatches(type, hook, event.payload)) {
|
|
12812
|
+
continue;
|
|
12813
|
+
}
|
|
12814
|
+
try {
|
|
12815
|
+
await executeHook({
|
|
12816
|
+
hook,
|
|
12817
|
+
event,
|
|
12818
|
+
flintPath: this.flintPath,
|
|
12819
|
+
logger: this.logger
|
|
12820
|
+
});
|
|
12821
|
+
} catch (error3) {
|
|
12822
|
+
this.logger.error?.("Hook execution failed", error3);
|
|
12823
|
+
}
|
|
12824
|
+
}
|
|
12825
|
+
}
|
|
12826
|
+
async readFrontmatterSnapshot(relativePath) {
|
|
12827
|
+
const absolutePath = path4.join(this.flintPath, relativePath);
|
|
12828
|
+
const content = await safeReadFile(absolutePath);
|
|
12829
|
+
if (!content) {
|
|
12830
|
+
return null;
|
|
12831
|
+
}
|
|
12832
|
+
const { frontmatter } = parseFrontmatter(content);
|
|
12833
|
+
const tags = extractTags(frontmatter);
|
|
12834
|
+
const status = frontmatter?.status ? String(frontmatter.status) : void 0;
|
|
12835
|
+
return { status, tags };
|
|
12836
|
+
}
|
|
12837
|
+
async readSessionSnapshot(relativePath) {
|
|
12838
|
+
const absolutePath = path4.join(this.flintPath, relativePath);
|
|
12839
|
+
const content = await safeReadFile(absolutePath);
|
|
12840
|
+
if (!content) {
|
|
12841
|
+
return null;
|
|
12842
|
+
}
|
|
12843
|
+
try {
|
|
12844
|
+
const parsed = JSON.parse(content);
|
|
12845
|
+
return {
|
|
12846
|
+
status: typeof parsed.status === "string" ? parsed.status : void 0,
|
|
12847
|
+
model: typeof parsed.model === "string" ? parsed.model : void 0,
|
|
12848
|
+
goal: typeof parsed.goal === "string" ? parsed.goal : void 0
|
|
12849
|
+
};
|
|
12850
|
+
} catch {
|
|
12851
|
+
return null;
|
|
12852
|
+
}
|
|
12853
|
+
}
|
|
12854
|
+
};
|
|
12855
|
+
function normalizePath(filePath) {
|
|
12856
|
+
return filePath.replace(/\\/g, "/");
|
|
12857
|
+
}
|
|
12858
|
+
async function safeReadFile(filePath) {
|
|
12859
|
+
try {
|
|
12860
|
+
const fileStats = await stat4(filePath);
|
|
12861
|
+
if (!fileStats.isFile()) {
|
|
12862
|
+
return null;
|
|
12863
|
+
}
|
|
12864
|
+
return await readFile6(filePath, "utf-8");
|
|
12865
|
+
} catch {
|
|
12866
|
+
return null;
|
|
12867
|
+
}
|
|
12868
|
+
}
|
|
12869
|
+
function parseFrontmatter(content) {
|
|
12870
|
+
const match2 = content.match(/^---\n([\s\S]*?)\n---\n?/);
|
|
12871
|
+
if (!match2) {
|
|
12872
|
+
return { frontmatter: null, body: content };
|
|
12873
|
+
}
|
|
12874
|
+
const raw = match2[1] ?? "";
|
|
12875
|
+
let frontmatter = {};
|
|
12876
|
+
try {
|
|
12877
|
+
const parsed = parseYaml(raw);
|
|
12878
|
+
if (parsed && typeof parsed === "object") {
|
|
12879
|
+
frontmatter = parsed;
|
|
12880
|
+
}
|
|
12881
|
+
} catch {
|
|
12882
|
+
frontmatter = {};
|
|
12883
|
+
}
|
|
12884
|
+
const body = content.slice(match2[0].length);
|
|
12885
|
+
return { frontmatter, body };
|
|
12886
|
+
}
|
|
12887
|
+
function extractTags(frontmatter) {
|
|
12888
|
+
if (!frontmatter || frontmatter.tags === void 0) {
|
|
12889
|
+
return [];
|
|
12890
|
+
}
|
|
12891
|
+
const tags = frontmatter.tags;
|
|
12892
|
+
if (Array.isArray(tags)) {
|
|
12893
|
+
return tags.map((tag) => String(tag));
|
|
12894
|
+
}
|
|
12895
|
+
if (typeof tags === "string") {
|
|
12896
|
+
return [tags];
|
|
12897
|
+
}
|
|
12898
|
+
return [];
|
|
12899
|
+
}
|
|
12900
|
+
async function loadHooksConfig(hooksPath, logger) {
|
|
12901
|
+
try {
|
|
12902
|
+
const content = await readFile6(hooksPath, "utf-8");
|
|
12903
|
+
const parsed = parse(content);
|
|
12904
|
+
if (parsed && typeof parsed === "object") {
|
|
12905
|
+
return parsed;
|
|
12906
|
+
}
|
|
12907
|
+
} catch (error3) {
|
|
12908
|
+
if (error3.code !== "ENOENT") {
|
|
12909
|
+
logger.warn?.("Failed to read hooks config", error3);
|
|
12910
|
+
}
|
|
12911
|
+
}
|
|
12912
|
+
return { hooks: {} };
|
|
12913
|
+
}
|
|
12914
|
+
function countHooks(config) {
|
|
12915
|
+
const hooks = config.hooks ?? {};
|
|
12916
|
+
return Object.values(hooks).reduce((count, entries) => count + entries.length, 0);
|
|
12917
|
+
}
|
|
12918
|
+
function hookMatches(type, hook, payload) {
|
|
12919
|
+
const matcher = hook.matcher;
|
|
12920
|
+
if (!matcher) {
|
|
12921
|
+
return true;
|
|
12922
|
+
}
|
|
12923
|
+
if (typeof matcher === "string") {
|
|
12924
|
+
if (type === "FileChanged") {
|
|
12925
|
+
const targetPath = typeof payload.path === "string" ? payload.path : "";
|
|
12926
|
+
return minimatch(targetPath, matcher, { dot: true });
|
|
12927
|
+
}
|
|
12928
|
+
return true;
|
|
12929
|
+
}
|
|
12930
|
+
if (matcher.tag) {
|
|
12931
|
+
const tags = Array.isArray(payload.tags) ? payload.tags.map(String) : [];
|
|
12932
|
+
if (!tags.includes(matcher.tag)) {
|
|
12933
|
+
return false;
|
|
12934
|
+
}
|
|
12935
|
+
}
|
|
12936
|
+
const fieldValue = typeof payload.field === "string" ? payload.field : void 0;
|
|
12937
|
+
if (matcher.field && matcher.field !== fieldValue) {
|
|
12938
|
+
return false;
|
|
12939
|
+
}
|
|
12940
|
+
const fromValue = typeof payload.from === "string" ? payload.from : void 0;
|
|
12941
|
+
if (matcher.from && matcher.from !== fromValue) {
|
|
12942
|
+
return false;
|
|
12943
|
+
}
|
|
12944
|
+
const toValue = typeof payload.to === "string" ? payload.to : void 0;
|
|
12945
|
+
if (matcher.to && matcher.to !== toValue) {
|
|
12946
|
+
return false;
|
|
12947
|
+
}
|
|
12948
|
+
return true;
|
|
12949
|
+
}
|
|
12950
|
+
async function executeHook(options) {
|
|
12951
|
+
const { hook, event, flintPath, logger } = options;
|
|
12952
|
+
const command = resolveHookCommand(hook.command, flintPath);
|
|
12953
|
+
logger.debug?.("Running hook", hook.command);
|
|
12954
|
+
await new Promise((resolve22, reject) => {
|
|
12955
|
+
const envPathEntries = [
|
|
12956
|
+
path4.join(flintPath, "node_modules", ".bin"),
|
|
12957
|
+
path4.join(process.cwd(), "node_modules", ".bin"),
|
|
12958
|
+
process.env.PATH
|
|
12959
|
+
].filter(Boolean);
|
|
12960
|
+
const child = spawn5(command, {
|
|
12961
|
+
cwd: flintPath,
|
|
12962
|
+
env: {
|
|
12963
|
+
...process.env,
|
|
12964
|
+
PATH: envPathEntries.join(path4.delimiter)
|
|
12965
|
+
},
|
|
12966
|
+
shell: true,
|
|
12967
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
12968
|
+
});
|
|
12969
|
+
let stdout = "";
|
|
12970
|
+
let stderr = "";
|
|
12971
|
+
child.stdout?.on("data", (data) => {
|
|
12972
|
+
stdout += String(data);
|
|
12973
|
+
});
|
|
12974
|
+
child.stderr?.on("data", (data) => {
|
|
12975
|
+
stderr += String(data);
|
|
12976
|
+
});
|
|
12977
|
+
const timeoutMs = hook.timeout ? hook.timeout * 1e3 : void 0;
|
|
12978
|
+
let timeoutId = null;
|
|
12979
|
+
if (timeoutMs) {
|
|
12980
|
+
timeoutId = setTimeout(() => {
|
|
12981
|
+
child.kill("SIGKILL");
|
|
12982
|
+
reject(new Error(`Hook timed out after ${hook.timeout}s: ${hook.command}`));
|
|
12983
|
+
}, timeoutMs);
|
|
12984
|
+
}
|
|
12985
|
+
child.on("error", (error3) => {
|
|
12986
|
+
if (timeoutId) {
|
|
12987
|
+
clearTimeout(timeoutId);
|
|
12988
|
+
}
|
|
12989
|
+
reject(error3);
|
|
12990
|
+
});
|
|
12991
|
+
child.on("close", (code) => {
|
|
12992
|
+
if (timeoutId) {
|
|
12993
|
+
clearTimeout(timeoutId);
|
|
12994
|
+
}
|
|
12995
|
+
if (code === 0) {
|
|
12996
|
+
if (stdout.trim()) {
|
|
12997
|
+
logger.info?.(`Hook output: ${stdout.trim()}`);
|
|
12998
|
+
}
|
|
12999
|
+
resolve22();
|
|
13000
|
+
return;
|
|
13001
|
+
}
|
|
13002
|
+
if (code === 2) {
|
|
13003
|
+
logger.warn?.(`Hook blocked: ${hook.command}`);
|
|
13004
|
+
if (stderr.trim()) {
|
|
13005
|
+
logger.warn?.(stderr.trim());
|
|
13006
|
+
}
|
|
13007
|
+
resolve22();
|
|
13008
|
+
return;
|
|
13009
|
+
}
|
|
13010
|
+
const error3 = new Error(`Hook failed (${code ?? "unknown"}): ${hook.command}`);
|
|
13011
|
+
if (stderr.trim()) {
|
|
13012
|
+
logger.error?.(stderr.trim());
|
|
13013
|
+
}
|
|
13014
|
+
reject(error3);
|
|
13015
|
+
});
|
|
13016
|
+
child.stdin?.write(JSON.stringify({
|
|
13017
|
+
event,
|
|
13018
|
+
flint: { path: flintPath }
|
|
13019
|
+
}));
|
|
13020
|
+
child.stdin?.end();
|
|
13021
|
+
});
|
|
13022
|
+
}
|
|
13023
|
+
function resolveHookCommand(command, flintPath) {
|
|
13024
|
+
const trimmed = command.trim();
|
|
13025
|
+
if (!trimmed) {
|
|
13026
|
+
return trimmed;
|
|
13027
|
+
}
|
|
13028
|
+
const parts = trimmed.split(/\s+/);
|
|
13029
|
+
const target = parts[0] ?? "";
|
|
13030
|
+
const rest = parts.slice(1).join(" ");
|
|
13031
|
+
const extension = path4.extname(target);
|
|
13032
|
+
if (!extension) {
|
|
13033
|
+
return trimmed;
|
|
13034
|
+
}
|
|
13035
|
+
const resolvedTarget = path4.isAbsolute(target) ? target : path4.join(flintPath, target);
|
|
13036
|
+
const quotedTarget = quoteIfNeeded(resolvedTarget);
|
|
13037
|
+
const suffix = rest ? ` ${rest}` : "";
|
|
13038
|
+
if (extension === ".ts") {
|
|
13039
|
+
return `tsx ${quotedTarget}${suffix}`;
|
|
13040
|
+
}
|
|
13041
|
+
if (extension === ".py") {
|
|
13042
|
+
return `python3 ${quotedTarget}${suffix}`;
|
|
13043
|
+
}
|
|
13044
|
+
if (extension === ".sh") {
|
|
13045
|
+
return `bash ${quotedTarget}${suffix}`;
|
|
13046
|
+
}
|
|
13047
|
+
return trimmed;
|
|
13048
|
+
}
|
|
13049
|
+
function quoteIfNeeded(value) {
|
|
13050
|
+
if (value.includes(" ")) {
|
|
13051
|
+
return `"${value.replace(/"/g, '\\"')}"`;
|
|
13052
|
+
}
|
|
13053
|
+
return value;
|
|
13054
|
+
}
|
|
13055
|
+
function sendApiError(reply, status, error3, message, extra = {}) {
|
|
13056
|
+
return reply.code(status).send({ error: error3, message, ...extra });
|
|
13057
|
+
}
|
|
13058
|
+
var CONTENT_TYPES = {
|
|
13059
|
+
".css": "text/css; charset=utf-8",
|
|
13060
|
+
".html": "text/html; charset=utf-8",
|
|
13061
|
+
".js": "application/javascript; charset=utf-8",
|
|
13062
|
+
".json": "application/json; charset=utf-8",
|
|
13063
|
+
".map": "application/json; charset=utf-8",
|
|
13064
|
+
".mjs": "application/javascript; charset=utf-8",
|
|
13065
|
+
".png": "image/png",
|
|
13066
|
+
".svg": "image/svg+xml",
|
|
13067
|
+
".tsx": "text/plain; charset=utf-8",
|
|
13068
|
+
".txt": "text/plain; charset=utf-8",
|
|
13069
|
+
".woff": "font/woff",
|
|
13070
|
+
".woff2": "font/woff2"
|
|
13071
|
+
};
|
|
13072
|
+
function contentTypeFor(filePath) {
|
|
13073
|
+
return CONTENT_TYPES[path22.extname(filePath).toLowerCase()] ?? "application/octet-stream";
|
|
13074
|
+
}
|
|
13075
|
+
function isImmutableAsset(filePath) {
|
|
13076
|
+
return /\.[a-f0-9]{8,}\./i.test(path22.basename(filePath));
|
|
13077
|
+
}
|
|
13078
|
+
async function resolveFlintPath4(inputPath) {
|
|
13079
|
+
const resolved = path22.resolve(inputPath);
|
|
13080
|
+
const flintToml = path22.join(resolved, "flint.toml");
|
|
13081
|
+
const flintState = path22.join(resolved, ".flint");
|
|
13082
|
+
const hasConfig = await exists3(flintToml);
|
|
13083
|
+
const hasState = await exists3(flintState);
|
|
13084
|
+
if (!hasConfig && !hasState) {
|
|
13085
|
+
throw new Error(`Not a Flint workspace: ${resolved}`);
|
|
13086
|
+
}
|
|
13087
|
+
return resolved;
|
|
13088
|
+
}
|
|
13089
|
+
async function exists3(targetPath) {
|
|
13090
|
+
try {
|
|
13091
|
+
await stat22(targetPath);
|
|
13092
|
+
return true;
|
|
13093
|
+
} catch {
|
|
13094
|
+
return false;
|
|
13095
|
+
}
|
|
13096
|
+
}
|
|
13097
|
+
function toError(error3, fallbackMessage) {
|
|
13098
|
+
if (error3 instanceof Error) {
|
|
13099
|
+
return error3;
|
|
13100
|
+
}
|
|
13101
|
+
return new Error(typeof error3 === "string" ? error3 : fallbackMessage);
|
|
13102
|
+
}
|
|
13103
|
+
function isUnsupportedRecursiveWatchError(error3) {
|
|
13104
|
+
const code = typeof error3 === "object" && error3 !== null && "code" in error3 ? String(error3.code ?? "") : "";
|
|
13105
|
+
return code === "ERR_FEATURE_UNAVAILABLE_ON_PLATFORM" || code === "ENOSYS" || code === "ENOTSUP";
|
|
13106
|
+
}
|
|
13107
|
+
function createResilientWatcher({
|
|
13108
|
+
label,
|
|
13109
|
+
targetPath,
|
|
13110
|
+
recursive = false,
|
|
13111
|
+
retryMs = 1e3,
|
|
13112
|
+
onChange
|
|
13113
|
+
}) {
|
|
13114
|
+
let watcher = null;
|
|
13115
|
+
let retryTimer = null;
|
|
13116
|
+
let closed = false;
|
|
13117
|
+
const scheduleRestart = () => {
|
|
13118
|
+
if (closed || retryTimer) {
|
|
13119
|
+
return;
|
|
13120
|
+
}
|
|
13121
|
+
retryTimer = setTimeout(() => {
|
|
13122
|
+
retryTimer = null;
|
|
13123
|
+
start();
|
|
13124
|
+
}, retryMs);
|
|
13125
|
+
retryTimer.unref?.();
|
|
13126
|
+
};
|
|
13127
|
+
const handleWatchError = (error3) => {
|
|
13128
|
+
const resolved = toError(error3, `${label} watcher failed`);
|
|
13129
|
+
const unsupported = recursive && isUnsupportedRecursiveWatchError(error3);
|
|
13130
|
+
watcher?.close();
|
|
13131
|
+
watcher = null;
|
|
13132
|
+
if (unsupported) {
|
|
13133
|
+
console.warn(`[flint-server] ${label} watcher disabled: recursive fs.watch is not supported on this platform.`);
|
|
13134
|
+
return;
|
|
13135
|
+
}
|
|
13136
|
+
console.warn(`[flint-server] ${label} watcher error: ${resolved.message}. Retrying.`);
|
|
13137
|
+
scheduleRestart();
|
|
13138
|
+
};
|
|
13139
|
+
const start = () => {
|
|
13140
|
+
if (closed) {
|
|
13141
|
+
return;
|
|
13142
|
+
}
|
|
13143
|
+
if (!existsSync10(targetPath)) {
|
|
13144
|
+
scheduleRestart();
|
|
13145
|
+
return;
|
|
13146
|
+
}
|
|
13147
|
+
try {
|
|
13148
|
+
watcher = watch3(targetPath, { recursive }, (_eventType, filename) => {
|
|
13149
|
+
onChange(filename);
|
|
13150
|
+
});
|
|
13151
|
+
watcher.on("error", handleWatchError);
|
|
13152
|
+
} catch (error3) {
|
|
13153
|
+
handleWatchError(error3);
|
|
13154
|
+
}
|
|
13155
|
+
};
|
|
13156
|
+
start();
|
|
13157
|
+
return {
|
|
13158
|
+
close() {
|
|
13159
|
+
closed = true;
|
|
13160
|
+
if (retryTimer) {
|
|
13161
|
+
clearTimeout(retryTimer);
|
|
13162
|
+
retryTimer = null;
|
|
13163
|
+
}
|
|
13164
|
+
watcher?.close();
|
|
13165
|
+
watcher = null;
|
|
13166
|
+
}
|
|
13167
|
+
};
|
|
13168
|
+
}
|
|
13169
|
+
var RuntimeManager = class {
|
|
13170
|
+
runtimes = /* @__PURE__ */ new Map();
|
|
13171
|
+
async startRuntime(flintPath) {
|
|
13172
|
+
const resolved = await resolveFlintPath4(flintPath);
|
|
13173
|
+
const runtimeId = computeRuntimeId(resolved);
|
|
13174
|
+
const existing = this.runtimes.get(runtimeId);
|
|
13175
|
+
if (existing) {
|
|
13176
|
+
return existing.getStatus();
|
|
13177
|
+
}
|
|
13178
|
+
const runtime2 = createRuntime({ flintPath: resolved });
|
|
13179
|
+
await runtime2.start();
|
|
13180
|
+
this.runtimes.set(runtimeId, runtime2);
|
|
13181
|
+
return runtime2.getStatus();
|
|
13182
|
+
}
|
|
13183
|
+
listRuntimes() {
|
|
13184
|
+
return Array.from(this.runtimes.values()).map((runtime2) => runtime2.getStatus());
|
|
13185
|
+
}
|
|
13186
|
+
getRuntime(id) {
|
|
13187
|
+
return this.runtimes.get(id);
|
|
13188
|
+
}
|
|
13189
|
+
async stopRuntime(id) {
|
|
13190
|
+
const runtime2 = this.runtimes.get(id);
|
|
13191
|
+
if (!runtime2) {
|
|
13192
|
+
return false;
|
|
13193
|
+
}
|
|
13194
|
+
await runtime2.stop();
|
|
13195
|
+
this.runtimes.delete(id);
|
|
13196
|
+
return true;
|
|
13197
|
+
}
|
|
13198
|
+
async stopAll() {
|
|
13199
|
+
const entries = Array.from(this.runtimes.entries());
|
|
13200
|
+
await Promise.all(entries.map(async ([id, runtime2]) => {
|
|
13201
|
+
await runtime2.stop();
|
|
13202
|
+
this.runtimes.delete(id);
|
|
13203
|
+
}));
|
|
13204
|
+
}
|
|
13205
|
+
};
|
|
13206
|
+
var REGISTRY_PATH = join11(homedir6(), ".nuucognition", "servers.json");
|
|
13207
|
+
function getRegistryDir() {
|
|
13208
|
+
return join11(homedir6(), ".nuucognition");
|
|
13209
|
+
}
|
|
13210
|
+
async function readServerRegistry() {
|
|
13211
|
+
try {
|
|
13212
|
+
const content = await readFile22(REGISTRY_PATH, "utf-8");
|
|
13213
|
+
const data = JSON.parse(content);
|
|
13214
|
+
return data.servers ?? [];
|
|
13215
|
+
} catch (error3) {
|
|
13216
|
+
if (error3.code === "ENOENT") {
|
|
13217
|
+
return [];
|
|
13218
|
+
}
|
|
13219
|
+
return [];
|
|
13220
|
+
}
|
|
13221
|
+
}
|
|
13222
|
+
async function writeServerRegistry(servers) {
|
|
13223
|
+
await mkdir5(getRegistryDir(), { recursive: true });
|
|
13224
|
+
const data = { version: 1, servers };
|
|
13225
|
+
const content = JSON.stringify(data, null, 2);
|
|
13226
|
+
await writeFile3(REGISTRY_PATH, content, "utf-8");
|
|
13227
|
+
const verification = await readFile22(REGISTRY_PATH, "utf-8");
|
|
13228
|
+
const verified = JSON.parse(verification);
|
|
13229
|
+
if (verified.servers.length !== servers.length) {
|
|
13230
|
+
await writeFile3(REGISTRY_PATH, content, "utf-8");
|
|
13231
|
+
}
|
|
13232
|
+
}
|
|
13233
|
+
async function registerServer(entry) {
|
|
10972
13234
|
const servers = await readServerRegistry();
|
|
10973
13235
|
const resolvedPath = resolve7(entry.flintPath);
|
|
10974
13236
|
const filtered = servers.filter((s) => resolve7(s.flintPath) !== resolvedPath);
|
|
@@ -11092,26 +13354,39 @@ function registerPlatesRoutes(app, ctx) {
|
|
|
11092
13354
|
...id ? { id } : {}
|
|
11093
13355
|
});
|
|
11094
13356
|
}
|
|
13357
|
+
function toPlateSummary(plate) {
|
|
13358
|
+
return {
|
|
13359
|
+
name: plate.manifest.name,
|
|
13360
|
+
title: plate.manifest.title,
|
|
13361
|
+
version: plate.manifest.version ?? "0.1.0",
|
|
13362
|
+
description: plate.manifest.description,
|
|
13363
|
+
icon: plate.manifest.icon,
|
|
13364
|
+
shard: plate.manifest.shard,
|
|
13365
|
+
handles: (plate.manifest.handles ?? []).map((handle) => ({
|
|
13366
|
+
tag: handle.tag,
|
|
13367
|
+
default: handle.default === true
|
|
13368
|
+
})),
|
|
13369
|
+
actions: (plate.manifest.actions ?? []).map((action) => ({
|
|
13370
|
+
id: action.id,
|
|
13371
|
+
label: action.label,
|
|
13372
|
+
description: action.description,
|
|
13373
|
+
icon: action.icon
|
|
13374
|
+
})),
|
|
13375
|
+
built: plate.built,
|
|
13376
|
+
stale: plate.stale,
|
|
13377
|
+
tools: (plate.manifest.tools ?? []).map((tool) => ({
|
|
13378
|
+
name: tool.name,
|
|
13379
|
+
description: tool.description
|
|
13380
|
+
}))
|
|
13381
|
+
};
|
|
13382
|
+
}
|
|
11095
13383
|
app.get("/api/plates", async (_request, reply) => {
|
|
11096
13384
|
if (!ctx.flintPath) {
|
|
11097
13385
|
return sendApiError(reply, 500, "not_found", "No Flint workspace configured");
|
|
11098
13386
|
}
|
|
11099
13387
|
try {
|
|
11100
13388
|
const plates = await listPlates(ctx.flintPath);
|
|
11101
|
-
return plates.map((plate) => (
|
|
11102
|
-
name: plate.manifest.name,
|
|
11103
|
-
title: plate.manifest.title,
|
|
11104
|
-
version: plate.manifest.version ?? "0.1.0",
|
|
11105
|
-
description: plate.manifest.description,
|
|
11106
|
-
icon: plate.manifest.icon,
|
|
11107
|
-
shard: plate.manifest.shard,
|
|
11108
|
-
built: plate.built,
|
|
11109
|
-
stale: plate.stale,
|
|
11110
|
-
tools: (plate.manifest.tools ?? []).map((tool) => ({
|
|
11111
|
-
name: tool.name,
|
|
11112
|
-
description: tool.description
|
|
11113
|
-
}))
|
|
11114
|
-
}));
|
|
13389
|
+
return plates.map((plate) => toPlateSummary(plate));
|
|
11115
13390
|
} catch (error3) {
|
|
11116
13391
|
const message = error3 instanceof Error ? error3.message : String(error3);
|
|
11117
13392
|
return sendApiError(reply, 500, "validation_error", message);
|
|
@@ -11125,20 +13400,7 @@ function registerPlatesRoutes(app, ctx) {
|
|
|
11125
13400
|
if (!plate) {
|
|
11126
13401
|
return sendApiError(reply, 404, "not_found", `Plate "${request.params.name}" was not found`);
|
|
11127
13402
|
}
|
|
11128
|
-
return
|
|
11129
|
-
name: plate.manifest.name,
|
|
11130
|
-
title: plate.manifest.title,
|
|
11131
|
-
version: plate.manifest.version ?? "0.1.0",
|
|
11132
|
-
description: plate.manifest.description,
|
|
11133
|
-
icon: plate.manifest.icon,
|
|
11134
|
-
shard: plate.manifest.shard,
|
|
11135
|
-
built: plate.built,
|
|
11136
|
-
stale: plate.stale,
|
|
11137
|
-
tools: (plate.manifest.tools ?? []).map((tool) => ({
|
|
11138
|
-
name: tool.name,
|
|
11139
|
-
description: tool.description
|
|
11140
|
-
}))
|
|
11141
|
-
};
|
|
13403
|
+
return toPlateSummary(plate);
|
|
11142
13404
|
});
|
|
11143
13405
|
async function servePlateAsset(plateName, requestedPath, reply) {
|
|
11144
13406
|
if (!ctx.flintPath) {
|
|
@@ -11148,18 +13410,18 @@ function registerPlatesRoutes(app, ctx) {
|
|
|
11148
13410
|
if (!plate) {
|
|
11149
13411
|
return sendApiError(reply, 404, "not_found", `Plate "${plateName}" was not found`);
|
|
11150
13412
|
}
|
|
11151
|
-
const entryPath =
|
|
11152
|
-
const distRoot =
|
|
11153
|
-
if (!await
|
|
13413
|
+
const entryPath = path32.resolve(plate.path, plate.manifest.entry);
|
|
13414
|
+
const distRoot = path32.dirname(entryPath);
|
|
13415
|
+
if (!await stat32(distRoot).catch(() => null)) {
|
|
11154
13416
|
return sendApiError(reply, 404, "plate_not_built", `Plate "${plate.manifest.name}" has not been built`, {
|
|
11155
13417
|
plate: plate.manifest.name
|
|
11156
13418
|
});
|
|
11157
13419
|
}
|
|
11158
|
-
const targetPath = requestedPath && requestedPath.length > 0 ?
|
|
11159
|
-
if (!targetPath.startsWith(distRoot) || !await
|
|
13420
|
+
const targetPath = requestedPath && requestedPath.length > 0 ? path32.resolve(distRoot, requestedPath) : entryPath;
|
|
13421
|
+
if (!targetPath.startsWith(distRoot) || !await stat32(targetPath).catch(() => null)) {
|
|
11160
13422
|
return sendApiError(reply, 404, "not_found", `Asset "${requestedPath ?? "/"}" was not found`);
|
|
11161
13423
|
}
|
|
11162
|
-
const content = await
|
|
13424
|
+
const content = await readFile32(targetPath);
|
|
11163
13425
|
reply.header("Content-Type", contentTypeFor(targetPath));
|
|
11164
13426
|
reply.header("Cache-Control", isImmutableAsset(targetPath) ? "public, max-age=31536000, immutable" : "no-store");
|
|
11165
13427
|
return reply.send(content);
|
|
@@ -11237,7 +13499,7 @@ function registerPlatesRoutes(app, ctx) {
|
|
|
11237
13499
|
template: request.body.template,
|
|
11238
13500
|
data: request.body.data
|
|
11239
13501
|
});
|
|
11240
|
-
const absolutePath =
|
|
13502
|
+
const absolutePath = path32.join(ctx.flintPath, artifact.path);
|
|
11241
13503
|
suppressPath(absolutePath);
|
|
11242
13504
|
trackArtifactPath(absolutePath);
|
|
11243
13505
|
broadcastArtifactEvent("artifact.created", artifact);
|
|
@@ -11260,7 +13522,7 @@ function registerPlatesRoutes(app, ctx) {
|
|
|
11260
13522
|
if (!artifact) {
|
|
11261
13523
|
return sendApiError(reply, 404, "not_found", `Artifact "${request.params.id}" was not found`);
|
|
11262
13524
|
}
|
|
11263
|
-
trackArtifactPath(
|
|
13525
|
+
trackArtifactPath(path32.join(ctx.flintPath, artifact.path));
|
|
11264
13526
|
broadcastArtifactEvent("artifact.updated", artifact);
|
|
11265
13527
|
return artifact;
|
|
11266
13528
|
});
|
|
@@ -11302,7 +13564,7 @@ function registerPlatesRoutes(app, ctx) {
|
|
|
11302
13564
|
return sendApiError(reply, 404, "not_found", `Artifact "${request.params.id}" was not found`);
|
|
11303
13565
|
}
|
|
11304
13566
|
if (ctx.flintPath) {
|
|
11305
|
-
const newPath =
|
|
13567
|
+
const newPath = path32.join(ctx.flintPath, result.artifact.path);
|
|
11306
13568
|
suppressPath(newPath);
|
|
11307
13569
|
trackArtifactPath(newPath);
|
|
11308
13570
|
}
|
|
@@ -11361,13 +13623,13 @@ function registerPlatesRoutes(app, ctx) {
|
|
|
11361
13623
|
const fileDebounceTimers = /* @__PURE__ */ new Map();
|
|
11362
13624
|
const SKIP_DIRS = /* @__PURE__ */ new Set(["Agents", "Archive", "node_modules", ".git"]);
|
|
11363
13625
|
function shouldSkipPath(relativePath) {
|
|
11364
|
-
const parts = relativePath.split(
|
|
13626
|
+
const parts = relativePath.split(path32.sep);
|
|
11365
13627
|
return parts.some((p) => SKIP_DIRS.has(p));
|
|
11366
13628
|
}
|
|
11367
13629
|
const handleFileChange = (baseDir, filename) => {
|
|
11368
13630
|
if (!filename || !ctx.flintPath) return;
|
|
11369
13631
|
if (!filename.endsWith(".md")) return;
|
|
11370
|
-
const absolutePath =
|
|
13632
|
+
const absolutePath = path32.join(baseDir, filename);
|
|
11371
13633
|
if (shouldSkipPath(filename)) return;
|
|
11372
13634
|
if (suppressedPaths.has(absolutePath)) return;
|
|
11373
13635
|
const existing = fileDebounceTimers.get(absolutePath);
|
|
@@ -11383,7 +13645,7 @@ function registerPlatesRoutes(app, ctx) {
|
|
|
11383
13645
|
trackArtifactPath(absolutePath);
|
|
11384
13646
|
broadcastArtifactEvent(event, artifact);
|
|
11385
13647
|
} else {
|
|
11386
|
-
const relPath =
|
|
13648
|
+
const relPath = path32.relative(ctx.flintPath, absolutePath).replace(/\\/g, "/");
|
|
11387
13649
|
untrackArtifactPath(absolutePath);
|
|
11388
13650
|
broadcastArtifactDeletion(relPath);
|
|
11389
13651
|
}
|
|
@@ -11392,11 +13654,11 @@ function registerPlatesRoutes(app, ctx) {
|
|
|
11392
13654
|
}, 50));
|
|
11393
13655
|
};
|
|
11394
13656
|
if (ctx.flintPath) {
|
|
11395
|
-
const meshDir =
|
|
11396
|
-
const shardsDir =
|
|
13657
|
+
const meshDir = path32.join(ctx.flintPath, "Mesh");
|
|
13658
|
+
const shardsDir = path32.join(ctx.flintPath, "Shards");
|
|
11397
13659
|
void queryArtifacts(ctx.flintPath, { includeShards: true, limit: 1e4 }).then((result) => {
|
|
11398
13660
|
for (const artifact of result.items) {
|
|
11399
|
-
trackArtifactPath(
|
|
13661
|
+
trackArtifactPath(path32.join(ctx.flintPath, artifact.path));
|
|
11400
13662
|
}
|
|
11401
13663
|
}).catch(() => {
|
|
11402
13664
|
});
|
|
@@ -11522,7 +13784,7 @@ async function readSessionTranscript(session, cwd) {
|
|
|
11522
13784
|
if (!transcriptPath) {
|
|
11523
13785
|
return { entries: [], turns: [], usage: null };
|
|
11524
13786
|
}
|
|
11525
|
-
const content = await
|
|
13787
|
+
const content = await readFile42(transcriptPath, "utf-8").catch(() => null);
|
|
11526
13788
|
if (content == null) {
|
|
11527
13789
|
return { entries: [], turns: [], usage: null };
|
|
11528
13790
|
}
|
|
@@ -11817,7 +14079,7 @@ function registerOrbhRoutes(app, ctx, options) {
|
|
|
11817
14079
|
prompt: prompt6,
|
|
11818
14080
|
extraArgs: session.runtime === "claude" ? ["--chrome"] : []
|
|
11819
14081
|
});
|
|
11820
|
-
const child =
|
|
14082
|
+
const child = spawn22(harness.name, args, {
|
|
11821
14083
|
cwd: ctx.flintPath,
|
|
11822
14084
|
detached: true,
|
|
11823
14085
|
stdio: ["ignore", "ignore", "pipe"],
|
|
@@ -12233,7 +14495,7 @@ async function buildFlintIdentity(ctx) {
|
|
|
12233
14495
|
]);
|
|
12234
14496
|
const sessions = ctx.orbhSessionsDir ? listSessions2(ctx.orbhSessionsDir) : [];
|
|
12235
14497
|
const activeSessions = sessions.filter((session) => ACTIVE_SESSION_STATUSES.has(session.status)).length;
|
|
12236
|
-
const name = config?.flint?.name ?? registryEntry?.name ??
|
|
14498
|
+
const name = config?.flint?.name ?? registryEntry?.name ?? path42.basename(ctx.flintPath);
|
|
12237
14499
|
return {
|
|
12238
14500
|
name,
|
|
12239
14501
|
flintId: flintJson?.id ?? null,
|
|
@@ -12290,12 +14552,12 @@ function registerWorkspaceRoutes(app, ctx) {
|
|
|
12290
14552
|
return;
|
|
12291
14553
|
}
|
|
12292
14554
|
for (const entry of entries) {
|
|
12293
|
-
const fullPath =
|
|
14555
|
+
const fullPath = path5.join(dir, entry.name);
|
|
12294
14556
|
if (entry.isDirectory()) {
|
|
12295
14557
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist") continue;
|
|
12296
14558
|
await walk(fullPath);
|
|
12297
14559
|
} else if (entry.name.endsWith(".md")) {
|
|
12298
|
-
allFiles.push(
|
|
14560
|
+
allFiles.push(path5.relative(ctx.flintPath, fullPath));
|
|
12299
14561
|
}
|
|
12300
14562
|
}
|
|
12301
14563
|
}
|
|
@@ -12449,16 +14711,16 @@ function registerShardsRoutes(app, ctx) {
|
|
|
12449
14711
|
return sendApiError(reply, 500, "no_workspace", "No Flint workspace configured");
|
|
12450
14712
|
}
|
|
12451
14713
|
const installed = await getInstalledShardsWithVersions(ctx.flintPath);
|
|
12452
|
-
const
|
|
12453
|
-
if (!
|
|
14714
|
+
const match2 = resolveInstalledShardInfo(installed, request.params.identifier);
|
|
14715
|
+
if (!match2) {
|
|
12454
14716
|
return sendApiError(reply, 404, "not_found", `Shard "${request.params.identifier}" not found`);
|
|
12455
14717
|
}
|
|
12456
14718
|
const allResults = await checkShardHealth(ctx.flintPath);
|
|
12457
14719
|
const shardResults = allResults.filter(
|
|
12458
|
-
(r) => r.check.includes(
|
|
14720
|
+
(r) => r.check.includes(match2.folderName) || r.check.includes(match2.name)
|
|
12459
14721
|
);
|
|
12460
14722
|
return {
|
|
12461
|
-
shard:
|
|
14723
|
+
shard: match2.name,
|
|
12462
14724
|
results: shardResults.map((r) => ({
|
|
12463
14725
|
check: r.check,
|
|
12464
14726
|
status: r.status,
|
|
@@ -12492,14 +14754,14 @@ function registerShardsRoutes(app, ctx) {
|
|
|
12492
14754
|
return sendApiError(reply, 500, "no_workspace", "No Flint workspace configured");
|
|
12493
14755
|
}
|
|
12494
14756
|
const installed = await getInstalledShardsWithVersions(ctx.flintPath);
|
|
12495
|
-
const
|
|
12496
|
-
if (!
|
|
14757
|
+
const match2 = resolveInstalledShardInfo(installed, request.params.identifier);
|
|
14758
|
+
if (!match2) {
|
|
12497
14759
|
return sendApiError(reply, 404, "not_found", `Shard "${request.params.identifier}" not found`);
|
|
12498
14760
|
}
|
|
12499
14761
|
try {
|
|
12500
|
-
const results = await healShard(ctx.flintPath,
|
|
14762
|
+
const results = await healShard(ctx.flintPath, match2.folderName);
|
|
12501
14763
|
return {
|
|
12502
|
-
shard:
|
|
14764
|
+
shard: match2.name,
|
|
12503
14765
|
repairs: results.map((r) => ({
|
|
12504
14766
|
check: r.check,
|
|
12505
14767
|
status: r.status,
|
|
@@ -12533,6 +14795,152 @@ function registerShardsRoutes(app, ctx) {
|
|
|
12533
14795
|
}
|
|
12534
14796
|
});
|
|
12535
14797
|
}
|
|
14798
|
+
function steelDir(flintPath) {
|
|
14799
|
+
return path6.join(flintPath, ".steel");
|
|
14800
|
+
}
|
|
14801
|
+
function preferencesPath(flintPath) {
|
|
14802
|
+
return path6.join(steelDir(flintPath), "preferences.json");
|
|
14803
|
+
}
|
|
14804
|
+
function plateStateDir(flintPath, plateName) {
|
|
14805
|
+
return path6.join(steelDir(flintPath), "plates", plateName);
|
|
14806
|
+
}
|
|
14807
|
+
function plateStatePath(flintPath, plateName, key) {
|
|
14808
|
+
return path6.join(plateStateDir(flintPath, plateName), `${key}.json`);
|
|
14809
|
+
}
|
|
14810
|
+
function plateBoardsDir(flintPath, plateName) {
|
|
14811
|
+
return path6.join(plateStateDir(flintPath, plateName), "boards");
|
|
14812
|
+
}
|
|
14813
|
+
function plateBoardPath(flintPath, plateName, board) {
|
|
14814
|
+
return path6.join(plateBoardsDir(flintPath, plateName), `${board}.json`);
|
|
14815
|
+
}
|
|
14816
|
+
async function readJsonFile(filePath) {
|
|
14817
|
+
try {
|
|
14818
|
+
const raw = await readFile52(filePath, "utf-8");
|
|
14819
|
+
return JSON.parse(raw);
|
|
14820
|
+
} catch {
|
|
14821
|
+
return null;
|
|
14822
|
+
}
|
|
14823
|
+
}
|
|
14824
|
+
async function writeJsonFile(filePath, data) {
|
|
14825
|
+
await mkdir22(path6.dirname(filePath), { recursive: true });
|
|
14826
|
+
const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
|
|
14827
|
+
await writeFile22(tempPath, JSON.stringify(data, null, 2), "utf-8");
|
|
14828
|
+
await rename2(tempPath, filePath);
|
|
14829
|
+
}
|
|
14830
|
+
function registerSteelRoutes(app, ctx) {
|
|
14831
|
+
app.get("/api/steel/preferences", async (_request, reply) => {
|
|
14832
|
+
if (!ctx.flintPath) {
|
|
14833
|
+
return sendApiError(reply, 500, "no_workspace", "No Flint workspace configured");
|
|
14834
|
+
}
|
|
14835
|
+
const prefs = await readJsonFile(preferencesPath(ctx.flintPath));
|
|
14836
|
+
return prefs ?? {};
|
|
14837
|
+
});
|
|
14838
|
+
app.put("/api/steel/preferences", async (request, reply) => {
|
|
14839
|
+
if (!ctx.flintPath) {
|
|
14840
|
+
return sendApiError(reply, 500, "no_workspace", "No Flint workspace configured");
|
|
14841
|
+
}
|
|
14842
|
+
const body = request.body;
|
|
14843
|
+
await writeJsonFile(preferencesPath(ctx.flintPath), {
|
|
14844
|
+
...body,
|
|
14845
|
+
updated: (/* @__PURE__ */ new Date()).toISOString()
|
|
14846
|
+
});
|
|
14847
|
+
return { ok: true };
|
|
14848
|
+
});
|
|
14849
|
+
app.get(
|
|
14850
|
+
"/api/steel/plates/:name/state/:key",
|
|
14851
|
+
async (request, reply) => {
|
|
14852
|
+
if (!ctx.flintPath) {
|
|
14853
|
+
return sendApiError(reply, 500, "no_workspace", "No Flint workspace configured");
|
|
14854
|
+
}
|
|
14855
|
+
const { name, key } = request.params;
|
|
14856
|
+
const data = await readJsonFile(plateStatePath(ctx.flintPath, name, key));
|
|
14857
|
+
return data ?? {};
|
|
14858
|
+
}
|
|
14859
|
+
);
|
|
14860
|
+
app.put(
|
|
14861
|
+
"/api/steel/plates/:name/state/:key",
|
|
14862
|
+
async (request, reply) => {
|
|
14863
|
+
if (!ctx.flintPath) {
|
|
14864
|
+
return sendApiError(reply, 500, "no_workspace", "No Flint workspace configured");
|
|
14865
|
+
}
|
|
14866
|
+
const { name, key } = request.params;
|
|
14867
|
+
const body = request.body;
|
|
14868
|
+
await writeJsonFile(plateStatePath(ctx.flintPath, name, key), {
|
|
14869
|
+
...body,
|
|
14870
|
+
updated: (/* @__PURE__ */ new Date()).toISOString()
|
|
14871
|
+
});
|
|
14872
|
+
return { ok: true };
|
|
14873
|
+
}
|
|
14874
|
+
);
|
|
14875
|
+
app.get(
|
|
14876
|
+
"/api/steel/plates/:name/state",
|
|
14877
|
+
async (request, reply) => {
|
|
14878
|
+
if (!ctx.flintPath) {
|
|
14879
|
+
return sendApiError(reply, 500, "no_workspace", "No Flint workspace configured");
|
|
14880
|
+
}
|
|
14881
|
+
const { name } = request.params;
|
|
14882
|
+
const dir = plateStateDir(ctx.flintPath, name);
|
|
14883
|
+
if (!await exists3(dir)) return {};
|
|
14884
|
+
const entries = {};
|
|
14885
|
+
try {
|
|
14886
|
+
const files = await readdir3(dir, { withFileTypes: true });
|
|
14887
|
+
for (const file of files) {
|
|
14888
|
+
if (!file.isFile() || !file.name.endsWith(".json")) continue;
|
|
14889
|
+
const key = file.name.replace(/\.json$/, "");
|
|
14890
|
+
entries[key] = await readJsonFile(path6.join(dir, file.name));
|
|
14891
|
+
}
|
|
14892
|
+
} catch {
|
|
14893
|
+
}
|
|
14894
|
+
return entries;
|
|
14895
|
+
}
|
|
14896
|
+
);
|
|
14897
|
+
app.get(
|
|
14898
|
+
"/api/steel/plates/:name/boards",
|
|
14899
|
+
async (request, reply) => {
|
|
14900
|
+
if (!ctx.flintPath) {
|
|
14901
|
+
return sendApiError(reply, 500, "no_workspace", "No Flint workspace configured");
|
|
14902
|
+
}
|
|
14903
|
+
const { name } = request.params;
|
|
14904
|
+
const dir = plateBoardsDir(ctx.flintPath, name);
|
|
14905
|
+
if (!await exists3(dir)) return [];
|
|
14906
|
+
try {
|
|
14907
|
+
const files = await readdir3(dir);
|
|
14908
|
+
return files.filter((f) => f.endsWith(".json")).map((f) => f.replace(/\.json$/, ""));
|
|
14909
|
+
} catch {
|
|
14910
|
+
return [];
|
|
14911
|
+
}
|
|
14912
|
+
}
|
|
14913
|
+
);
|
|
14914
|
+
app.get(
|
|
14915
|
+
"/api/steel/plates/:name/boards/:board",
|
|
14916
|
+
async (request, reply) => {
|
|
14917
|
+
if (!ctx.flintPath) {
|
|
14918
|
+
return sendApiError(reply, 500, "no_workspace", "No Flint workspace configured");
|
|
14919
|
+
}
|
|
14920
|
+
const { name, board } = request.params;
|
|
14921
|
+
const data = await readJsonFile(plateBoardPath(ctx.flintPath, name, board));
|
|
14922
|
+
if (!data) {
|
|
14923
|
+
return sendApiError(reply, 404, "not_found", `Board config '${board}' not found for plate '${name}'`);
|
|
14924
|
+
}
|
|
14925
|
+
return data;
|
|
14926
|
+
}
|
|
14927
|
+
);
|
|
14928
|
+
app.put(
|
|
14929
|
+
"/api/steel/plates/:name/boards/:board",
|
|
14930
|
+
async (request, reply) => {
|
|
14931
|
+
if (!ctx.flintPath) {
|
|
14932
|
+
return sendApiError(reply, 500, "no_workspace", "No Flint workspace configured");
|
|
14933
|
+
}
|
|
14934
|
+
const { name, board } = request.params;
|
|
14935
|
+
const body = request.body;
|
|
14936
|
+
await writeJsonFile(plateBoardPath(ctx.flintPath, name, board), {
|
|
14937
|
+
...body,
|
|
14938
|
+
updated: (/* @__PURE__ */ new Date()).toISOString()
|
|
14939
|
+
});
|
|
14940
|
+
return { ok: true };
|
|
14941
|
+
}
|
|
14942
|
+
);
|
|
14943
|
+
}
|
|
12536
14944
|
var MAX_ENTRIES = 1e3;
|
|
12537
14945
|
var nextId = 1;
|
|
12538
14946
|
var buffer = [];
|
|
@@ -12542,29 +14950,29 @@ function pushEntry(entry) {
|
|
|
12542
14950
|
}
|
|
12543
14951
|
buffer.push(entry);
|
|
12544
14952
|
}
|
|
12545
|
-
function getLogEntries(
|
|
14953
|
+
function getLogEntries(filter2) {
|
|
12546
14954
|
let result = buffer;
|
|
12547
|
-
if (
|
|
12548
|
-
const method =
|
|
14955
|
+
if (filter2?.method) {
|
|
14956
|
+
const method = filter2.method.toUpperCase();
|
|
12549
14957
|
result = result.filter((entry) => entry.method === method);
|
|
12550
14958
|
}
|
|
12551
|
-
if (
|
|
12552
|
-
const minStatus =
|
|
14959
|
+
if (filter2?.minStatus != null) {
|
|
14960
|
+
const minStatus = filter2.minStatus;
|
|
12553
14961
|
result = result.filter((entry) => entry.statusCode >= minStatus);
|
|
12554
14962
|
}
|
|
12555
|
-
if (
|
|
12556
|
-
const maxStatus =
|
|
14963
|
+
if (filter2?.maxStatus != null) {
|
|
14964
|
+
const maxStatus = filter2.maxStatus;
|
|
12557
14965
|
result = result.filter((entry) => entry.statusCode <= maxStatus);
|
|
12558
14966
|
}
|
|
12559
|
-
if (
|
|
12560
|
-
const pattern =
|
|
14967
|
+
if (filter2?.pathPattern) {
|
|
14968
|
+
const pattern = filter2.pathPattern.toLowerCase();
|
|
12561
14969
|
result = result.filter((entry) => entry.path.toLowerCase().includes(pattern));
|
|
12562
14970
|
}
|
|
12563
|
-
if (
|
|
12564
|
-
result = result.filter((entry) => entry.timestamp >=
|
|
14971
|
+
if (filter2?.since) {
|
|
14972
|
+
result = result.filter((entry) => entry.timestamp >= filter2.since);
|
|
12565
14973
|
}
|
|
12566
|
-
if (
|
|
12567
|
-
result = result.slice(-
|
|
14974
|
+
if (filter2?.limit && filter2.limit > 0) {
|
|
14975
|
+
result = result.slice(-filter2.limit);
|
|
12568
14976
|
}
|
|
12569
14977
|
return result;
|
|
12570
14978
|
}
|
|
@@ -12573,8 +14981,8 @@ var EXCLUDED_PATHS = [
|
|
|
12573
14981
|
"/events/stream",
|
|
12574
14982
|
"/health"
|
|
12575
14983
|
];
|
|
12576
|
-
function shouldLog(
|
|
12577
|
-
return !EXCLUDED_PATHS.some((entry) =>
|
|
14984
|
+
function shouldLog(path82) {
|
|
14985
|
+
return !EXCLUDED_PATHS.some((entry) => path82 === entry || path82.startsWith(`${entry}?`));
|
|
12578
14986
|
}
|
|
12579
14987
|
var INTERESTING_REQUEST_HEADERS = [
|
|
12580
14988
|
"accept",
|
|
@@ -12621,14 +15029,14 @@ function registerLogsRoutes(app, ctx) {
|
|
|
12621
15029
|
return;
|
|
12622
15030
|
}
|
|
12623
15031
|
const queryIndex = fullUrl.indexOf("?");
|
|
12624
|
-
const
|
|
15032
|
+
const path82 = queryIndex >= 0 ? fullUrl.slice(0, queryIndex) : fullUrl;
|
|
12625
15033
|
const queryString = queryIndex >= 0 ? fullUrl.slice(queryIndex + 1) : null;
|
|
12626
15034
|
const entry = {
|
|
12627
15035
|
id: nextId++,
|
|
12628
15036
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12629
15037
|
method: request.method,
|
|
12630
15038
|
url: fullUrl,
|
|
12631
|
-
path:
|
|
15039
|
+
path: path82,
|
|
12632
15040
|
queryString,
|
|
12633
15041
|
statusCode: reply.statusCode,
|
|
12634
15042
|
responseTimeMs: Math.round(reply.elapsedTime * 100) / 100,
|
|
@@ -12899,7 +15307,7 @@ function registerEventStreamRoutes(app, ctx) {
|
|
|
12899
15307
|
const raw = reply.raw;
|
|
12900
15308
|
raw.writeHead(200, buildSseHeaders(request));
|
|
12901
15309
|
const subscriber = {
|
|
12902
|
-
id:
|
|
15310
|
+
id: randomUUID22(),
|
|
12903
15311
|
raw,
|
|
12904
15312
|
channels: new Set(channels),
|
|
12905
15313
|
sessionIds,
|
|
@@ -13020,17 +15428,17 @@ var LiveTranscriptWriter = class {
|
|
|
13020
15428
|
const agentsDir = join33(this.flintPath, "Mesh", "Agents");
|
|
13021
15429
|
let runtimeDirs;
|
|
13022
15430
|
try {
|
|
13023
|
-
runtimeDirs = await
|
|
15431
|
+
runtimeDirs = await readdir4(agentsDir);
|
|
13024
15432
|
} catch {
|
|
13025
15433
|
return;
|
|
13026
15434
|
}
|
|
13027
15435
|
for (const dir of runtimeDirs) {
|
|
13028
15436
|
const dirPath = join33(agentsDir, dir);
|
|
13029
|
-
const dirStat = await
|
|
15437
|
+
const dirStat = await stat42(dirPath).catch(() => null);
|
|
13030
15438
|
if (!dirStat?.isDirectory()) continue;
|
|
13031
15439
|
let files;
|
|
13032
15440
|
try {
|
|
13033
|
-
files = await
|
|
15441
|
+
files = await readdir4(dirPath);
|
|
13034
15442
|
} catch {
|
|
13035
15443
|
continue;
|
|
13036
15444
|
}
|
|
@@ -13039,7 +15447,7 @@ var LiveTranscriptWriter = class {
|
|
|
13039
15447
|
const filePath = join33(dirPath, file);
|
|
13040
15448
|
let content;
|
|
13041
15449
|
try {
|
|
13042
|
-
content = await
|
|
15450
|
+
content = await readFile62(filePath, "utf-8");
|
|
13043
15451
|
} catch {
|
|
13044
15452
|
continue;
|
|
13045
15453
|
}
|
|
@@ -13057,7 +15465,7 @@ var LiveTranscriptWriter = class {
|
|
|
13057
15465
|
const finalStatus = session?.status ?? "unknown";
|
|
13058
15466
|
const statusUpdated = updatedContent.replace(/^status: .+$/m, `status: ${finalStatus}`);
|
|
13059
15467
|
this.suppress(filePath);
|
|
13060
|
-
await
|
|
15468
|
+
await writeFile32(filePath, statusUpdated, "utf-8").catch(() => {
|
|
13061
15469
|
});
|
|
13062
15470
|
console.log(`[flint-server] finalized orphaned live transcript: ${file}`);
|
|
13063
15471
|
}
|
|
@@ -13108,12 +15516,12 @@ var LiveTranscriptWriter = class {
|
|
|
13108
15516
|
const outputDir = join33(this.flintPath, "Mesh", "Agents", dir);
|
|
13109
15517
|
const outputPath = join33(outputDir, `${sessionId}.md`);
|
|
13110
15518
|
try {
|
|
13111
|
-
await
|
|
15519
|
+
await mkdir32(outputDir, { recursive: true });
|
|
13112
15520
|
const frontmatter = buildLiveFrontmatter(session, live);
|
|
13113
15521
|
const body = formatTranscriptMarkdown(entries);
|
|
13114
15522
|
const markdown = frontmatter + body;
|
|
13115
15523
|
this.suppress(outputPath);
|
|
13116
|
-
await
|
|
15524
|
+
await writeFile32(outputPath, markdown, "utf-8");
|
|
13117
15525
|
this.writtenPaths.add(outputPath);
|
|
13118
15526
|
} catch (error3) {
|
|
13119
15527
|
console.warn(
|
|
@@ -13159,9 +15567,9 @@ async function shutdownPairedSteelHost(steelUrl) {
|
|
|
13159
15567
|
async function startFlintServer(options = {}) {
|
|
13160
15568
|
const host = "127.0.0.1";
|
|
13161
15569
|
const port = options.port ?? 13040;
|
|
13162
|
-
const flintPath = options.flintPath ?
|
|
15570
|
+
const flintPath = options.flintPath ? path7.resolve(options.flintPath) : void 0;
|
|
13163
15571
|
const runtimeManager = new RuntimeManager();
|
|
13164
|
-
const orbhSessionsDir = flintPath ?
|
|
15572
|
+
const orbhSessionsDir = flintPath ? path7.join(flintPath, ".flint", "sessions") : null;
|
|
13165
15573
|
const channelRegistry = new ChannelRegistry();
|
|
13166
15574
|
const app = Fastify({
|
|
13167
15575
|
logger: options.logger ?? false,
|
|
@@ -13185,10 +15593,10 @@ async function startFlintServer(options = {}) {
|
|
|
13185
15593
|
suppressedPaths,
|
|
13186
15594
|
suppressPath
|
|
13187
15595
|
};
|
|
13188
|
-
const __dirname4 =
|
|
13189
|
-
const dashboardDist =
|
|
15596
|
+
const __dirname4 = path7.dirname(fileURLToPath2(import.meta.url));
|
|
15597
|
+
const dashboardDist = path7.resolve(__dirname4, "..", "..", "..", "apps", "flint-dashboard", "dist");
|
|
13190
15598
|
try {
|
|
13191
|
-
await
|
|
15599
|
+
await stat5(dashboardDist);
|
|
13192
15600
|
await app.register(fastifyStatic, {
|
|
13193
15601
|
root: dashboardDist,
|
|
13194
15602
|
prefix: "/",
|
|
@@ -13218,6 +15626,7 @@ async function startFlintServer(options = {}) {
|
|
|
13218
15626
|
registerIdentityRoutes(app, ctx);
|
|
13219
15627
|
registerDashboardRoutes(app, ctx);
|
|
13220
15628
|
registerShardsRoutes(app, ctx);
|
|
15629
|
+
registerSteelRoutes(app, ctx);
|
|
13221
15630
|
registerWorkspaceRoutes(app, ctx);
|
|
13222
15631
|
let liveTranscriptWriter = null;
|
|
13223
15632
|
if (flintPath) {
|
|
@@ -13254,7 +15663,7 @@ async function startFlintServer(options = {}) {
|
|
|
13254
15663
|
readFlintToml(flintPath)
|
|
13255
15664
|
]);
|
|
13256
15665
|
registryFlintId = flintJson?.id ?? null;
|
|
13257
|
-
registryName = config?.flint?.name ??
|
|
15666
|
+
registryName = config?.flint?.name ?? path7.basename(flintPath);
|
|
13258
15667
|
} catch {
|
|
13259
15668
|
}
|
|
13260
15669
|
await registerServer({
|
|
@@ -13275,7 +15684,7 @@ async function startFlintServer(options = {}) {
|
|
|
13275
15684
|
console.log(`[flint-server] ${needsBuild.length} plate(s) need building...`);
|
|
13276
15685
|
for (const plate of needsBuild) {
|
|
13277
15686
|
try {
|
|
13278
|
-
const nodeModulesExists = await
|
|
15687
|
+
const nodeModulesExists = await stat5(join43(plate.path, "node_modules")).then(() => true, () => false);
|
|
13279
15688
|
if (!nodeModulesExists) {
|
|
13280
15689
|
console.log(`[flint-server] installing deps for ${plate.manifest.title}...`);
|
|
13281
15690
|
const installResult = await installPlateDeps(flintPath, plate.manifest.name);
|
|
@@ -13413,12 +15822,12 @@ serverCommand.command("dev").description("Start the server in dev mode with auto
|
|
|
13413
15822
|
let serverPkgDir;
|
|
13414
15823
|
try {
|
|
13415
15824
|
const serverPkgJson = require2.resolve(`${FLINT_SERVER_PACKAGE}/package.json`);
|
|
13416
|
-
serverPkgDir =
|
|
15825
|
+
serverPkgDir = path8.dirname(serverPkgJson);
|
|
13417
15826
|
} catch {
|
|
13418
15827
|
console.error(pc25.red("Error: flint-server package not found."));
|
|
13419
15828
|
process.exit(1);
|
|
13420
15829
|
}
|
|
13421
|
-
const devEntry =
|
|
15830
|
+
const devEntry = path8.join(serverPkgDir, "src", "dev.ts");
|
|
13422
15831
|
try {
|
|
13423
15832
|
await stat6(devEntry);
|
|
13424
15833
|
} catch {
|
|
@@ -13536,11 +15945,11 @@ serverCommand.command("list").description("List all running Flint servers from t
|
|
|
13536
15945
|
// src/commands/runtime.ts
|
|
13537
15946
|
import { Command as Command23 } from "commander";
|
|
13538
15947
|
import pc26 from "picocolors";
|
|
13539
|
-
import
|
|
15948
|
+
import path9 from "path";
|
|
13540
15949
|
var runtimeCommand = new Command23("runtime").description("Manage Flint runtimes");
|
|
13541
15950
|
runtimeCommand.command("start [flintPath]").description("Start runtime for a Flint").option("--server <url>", "Server URL", "http://127.0.0.1:13040").action(async (flintPath, options) => {
|
|
13542
15951
|
const serverUrl = options.server;
|
|
13543
|
-
const resolvedPath = flintPath ?
|
|
15952
|
+
const resolvedPath = flintPath ? path9.resolve(flintPath) : await findFlintRoot(process.cwd());
|
|
13544
15953
|
if (!resolvedPath) {
|
|
13545
15954
|
console.error(pc26.red("Error: Not inside a Flint workspace. Provide a path or cd into one."));
|
|
13546
15955
|
process.exit(1);
|
|
@@ -13572,7 +15981,7 @@ runtimeCommand.command("stop [runtimeId]").description("Stop a running runtime")
|
|
|
13572
15981
|
let id = runtimeId;
|
|
13573
15982
|
try {
|
|
13574
15983
|
if (!id) {
|
|
13575
|
-
const lookupPath = options.path ?
|
|
15984
|
+
const lookupPath = options.path ? path9.resolve(options.path) : await findFlintRoot(process.cwd());
|
|
13576
15985
|
if (!lookupPath) {
|
|
13577
15986
|
console.error(pc26.red("Error: Provide a runtime ID or Flint path."));
|
|
13578
15987
|
process.exit(1);
|
|
@@ -13583,10 +15992,10 @@ runtimeCommand.command("stop [runtimeId]").description("Stop a running runtime")
|
|
|
13583
15992
|
process.exit(1);
|
|
13584
15993
|
}
|
|
13585
15994
|
const payload = await listResponse.json();
|
|
13586
|
-
const
|
|
15995
|
+
const match2 = (payload.runtimes ?? []).find(
|
|
13587
15996
|
(runtime2) => runtime2.flintPath === lookupPath
|
|
13588
15997
|
);
|
|
13589
|
-
id =
|
|
15998
|
+
id = match2?.id;
|
|
13590
15999
|
}
|
|
13591
16000
|
if (!id) {
|
|
13592
16001
|
console.error(pc26.red("Error: Runtime not found."));
|
|
@@ -13706,23 +16115,23 @@ async function exportSession(flintPath, sessionId) {
|
|
|
13706
16115
|
}
|
|
13707
16116
|
|
|
13708
16117
|
// src/commands/export-codex-session.ts
|
|
13709
|
-
import { writeFile as writeFile5, mkdir as mkdir7, readFile as readFile8, readdir as
|
|
16118
|
+
import { writeFile as writeFile5, mkdir as mkdir7, readFile as readFile8, readdir as readdir5, stat as stat8 } from "fs/promises";
|
|
13710
16119
|
import { join as join13 } from "path";
|
|
13711
16120
|
import { homedir as homedir8 } from "os";
|
|
13712
16121
|
import pc28 from "picocolors";
|
|
13713
16122
|
async function findCodexTranscript(sessionId, startedAfter) {
|
|
13714
16123
|
const sessionsDir = join13(homedir8(), ".codex", "sessions");
|
|
13715
16124
|
try {
|
|
13716
|
-
const years = await
|
|
16125
|
+
const years = await readdir5(sessionsDir);
|
|
13717
16126
|
for (const year of years.reverse()) {
|
|
13718
16127
|
const yearDir = join13(sessionsDir, year);
|
|
13719
|
-
const months = await
|
|
16128
|
+
const months = await readdir5(yearDir).catch(() => []);
|
|
13720
16129
|
for (const month of months.reverse()) {
|
|
13721
16130
|
const monthDir = join13(yearDir, month);
|
|
13722
|
-
const days = await
|
|
16131
|
+
const days = await readdir5(monthDir).catch(() => []);
|
|
13723
16132
|
for (const day of days.reverse()) {
|
|
13724
16133
|
const dayDir = join13(monthDir, day);
|
|
13725
|
-
const files = await
|
|
16134
|
+
const files = await readdir5(dayDir).catch(() => []);
|
|
13726
16135
|
for (const file of files) {
|
|
13727
16136
|
if (!file.endsWith(".jsonl")) continue;
|
|
13728
16137
|
if (file.includes(sessionId)) {
|
|
@@ -14189,8 +16598,8 @@ import { readdirSync as readdirSync6, existsSync as existsSync12, statSync as st
|
|
|
14189
16598
|
import { join as join15, basename as basename5 } from "path";
|
|
14190
16599
|
function extractNumberFromFile(filename, typeName) {
|
|
14191
16600
|
const regex = new RegExp(`^\\(${typeName}\\)\\s+(\\d+)`, "i");
|
|
14192
|
-
const
|
|
14193
|
-
return
|
|
16601
|
+
const match2 = filename.match(regex);
|
|
16602
|
+
return match2 ? parseInt(match2[1], 10) : null;
|
|
14194
16603
|
}
|
|
14195
16604
|
function collectFilesRecursively(dirPath) {
|
|
14196
16605
|
const files = [];
|
|
@@ -14585,9 +16994,9 @@ import pc35 from "picocolors";
|
|
|
14585
16994
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
14586
16995
|
import { copyFile as copyFile2, mkdir as mkdir8, writeFile as writeFile6, unlink as unlink2, stat as stat10 } from "fs/promises";
|
|
14587
16996
|
import { join as join17, basename as basename6, resolve as resolve10 } from "path";
|
|
14588
|
-
async function exists4(
|
|
16997
|
+
async function exists4(path10) {
|
|
14589
16998
|
try {
|
|
14590
|
-
await stat10(
|
|
16999
|
+
await stat10(path10);
|
|
14591
17000
|
return true;
|
|
14592
17001
|
} catch {
|
|
14593
17002
|
return false;
|
|
@@ -14664,7 +17073,7 @@ var sendCommand = new Command30("send").description("Send files to another Flint
|
|
|
14664
17073
|
console.log();
|
|
14665
17074
|
let sourceFlintName = "Unknown";
|
|
14666
17075
|
try {
|
|
14667
|
-
const { readFlintToml: readFlintToml3 } = await import("./dist-
|
|
17076
|
+
const { readFlintToml: readFlintToml3 } = await import("./dist-EAYA2DAP.js");
|
|
14668
17077
|
const toml = await readFlintToml3(flintPath);
|
|
14669
17078
|
if (toml?.flint?.name) {
|
|
14670
17079
|
sourceFlintName = toml.flint.name;
|
|
@@ -14930,8 +17339,8 @@ async function validateEntries(entries) {
|
|
|
14930
17339
|
continue;
|
|
14931
17340
|
}
|
|
14932
17341
|
seenPaths.set(entry.path, entry);
|
|
14933
|
-
const
|
|
14934
|
-
if (!
|
|
17342
|
+
const exists6 = await checkPathExists(entry.path);
|
|
17343
|
+
if (!exists6) {
|
|
14935
17344
|
issues.push({
|
|
14936
17345
|
type: "broken_path",
|
|
14937
17346
|
entry,
|
|
@@ -16994,14 +19403,141 @@ orbCommand.command("respond").description("Answer a pending question on a sessio
|
|
|
16994
19403
|
}
|
|
16995
19404
|
});
|
|
16996
19405
|
|
|
19406
|
+
// src/commands/steel.ts
|
|
19407
|
+
import { Command as Command37 } from "commander";
|
|
19408
|
+
import pc42 from "picocolors";
|
|
19409
|
+
import { readFile as readFile9, readdir as readdir6, rm as rm5 } from "fs/promises";
|
|
19410
|
+
import { join as join19 } from "path";
|
|
19411
|
+
async function exists5(path10) {
|
|
19412
|
+
try {
|
|
19413
|
+
const { stat: stat11 } = await import("fs/promises");
|
|
19414
|
+
await stat11(path10);
|
|
19415
|
+
return true;
|
|
19416
|
+
} catch {
|
|
19417
|
+
return false;
|
|
19418
|
+
}
|
|
19419
|
+
}
|
|
19420
|
+
async function readJsonFile2(filePath) {
|
|
19421
|
+
try {
|
|
19422
|
+
const raw = await readFile9(filePath, "utf-8");
|
|
19423
|
+
return JSON.parse(raw);
|
|
19424
|
+
} catch {
|
|
19425
|
+
return null;
|
|
19426
|
+
}
|
|
19427
|
+
}
|
|
19428
|
+
var steelCommand = new Command37("steel").description("Manage Steel UI state (.steel/ directory)").addCommand(
|
|
19429
|
+
new Command37("preferences").description("Show Steel preferences").option("-p, --path <dir>", "Path to flint (default: auto-detect)").option("--reset", "Clear all Steel preferences").action(async (options) => {
|
|
19430
|
+
try {
|
|
19431
|
+
const flintPath = options.path || await findFlintRoot(process.cwd());
|
|
19432
|
+
if (!flintPath) {
|
|
19433
|
+
console.error(pc42.red("Error: Not inside a Flint. Use --path or cd into a Flint."));
|
|
19434
|
+
process.exit(1);
|
|
19435
|
+
}
|
|
19436
|
+
const prefsPath = join19(flintPath, ".steel", "preferences.json");
|
|
19437
|
+
if (options.reset) {
|
|
19438
|
+
if (await exists5(prefsPath)) {
|
|
19439
|
+
await rm5(prefsPath);
|
|
19440
|
+
console.log(pc42.green("Steel preferences cleared."));
|
|
19441
|
+
} else {
|
|
19442
|
+
console.log(pc42.dim("No preferences file found."));
|
|
19443
|
+
}
|
|
19444
|
+
return;
|
|
19445
|
+
}
|
|
19446
|
+
const prefs = await readJsonFile2(prefsPath);
|
|
19447
|
+
if (!prefs) {
|
|
19448
|
+
console.log(pc42.dim("No Steel preferences set."));
|
|
19449
|
+
return;
|
|
19450
|
+
}
|
|
19451
|
+
console.log(JSON.stringify(prefs, null, 2));
|
|
19452
|
+
} catch (err) {
|
|
19453
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
19454
|
+
console.error(pc42.red(`Error: ${message}`));
|
|
19455
|
+
process.exit(1);
|
|
19456
|
+
}
|
|
19457
|
+
})
|
|
19458
|
+
).addCommand(
|
|
19459
|
+
new Command37("state").description("Show plate state").argument("<plate-name>", "Name of the plate").option("-p, --path <dir>", "Path to flint (default: auto-detect)").option("--reset", "Clear all state for this plate").action(async (plateName, options) => {
|
|
19460
|
+
try {
|
|
19461
|
+
const flintPath = options.path || await findFlintRoot(process.cwd());
|
|
19462
|
+
if (!flintPath) {
|
|
19463
|
+
console.error(pc42.red("Error: Not inside a Flint. Use --path or cd into a Flint."));
|
|
19464
|
+
process.exit(1);
|
|
19465
|
+
}
|
|
19466
|
+
const plateDir = join19(flintPath, ".steel", "plates", plateName);
|
|
19467
|
+
if (options.reset) {
|
|
19468
|
+
if (await exists5(plateDir)) {
|
|
19469
|
+
await rm5(plateDir, { recursive: true });
|
|
19470
|
+
console.log(pc42.green(`State cleared for plate: ${plateName}`));
|
|
19471
|
+
} else {
|
|
19472
|
+
console.log(pc42.dim(`No state found for plate: ${plateName}`));
|
|
19473
|
+
}
|
|
19474
|
+
return;
|
|
19475
|
+
}
|
|
19476
|
+
if (!await exists5(plateDir)) {
|
|
19477
|
+
console.log(pc42.dim(`No state found for plate: ${plateName}`));
|
|
19478
|
+
return;
|
|
19479
|
+
}
|
|
19480
|
+
const files = await readdir6(plateDir, { withFileTypes: true });
|
|
19481
|
+
const stateFiles = files.filter((f) => f.isFile() && f.name.endsWith(".json"));
|
|
19482
|
+
if (stateFiles.length === 0) {
|
|
19483
|
+
console.log(pc42.dim(`No state files for plate: ${plateName}`));
|
|
19484
|
+
return;
|
|
19485
|
+
}
|
|
19486
|
+
console.log(pc42.bold(`Plate state: ${plateName}`));
|
|
19487
|
+
console.log();
|
|
19488
|
+
for (const file of stateFiles) {
|
|
19489
|
+
const key = file.name.replace(/\.json$/, "");
|
|
19490
|
+
const data = await readJsonFile2(join19(plateDir, file.name));
|
|
19491
|
+
console.log(`${pc42.cyan(key)}:`);
|
|
19492
|
+
console.log(JSON.stringify(data, null, 2));
|
|
19493
|
+
console.log();
|
|
19494
|
+
}
|
|
19495
|
+
} catch (err) {
|
|
19496
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
19497
|
+
console.error(pc42.red(`Error: ${message}`));
|
|
19498
|
+
process.exit(1);
|
|
19499
|
+
}
|
|
19500
|
+
})
|
|
19501
|
+
).addCommand(
|
|
19502
|
+
new Command37("boards").description("List board/view configs for a plate").argument("<plate-name>", "Name of the plate").option("-p, --path <dir>", "Path to flint (default: auto-detect)").action(async (plateName, options) => {
|
|
19503
|
+
try {
|
|
19504
|
+
const flintPath = options.path || await findFlintRoot(process.cwd());
|
|
19505
|
+
if (!flintPath) {
|
|
19506
|
+
console.error(pc42.red("Error: Not inside a Flint. Use --path or cd into a Flint."));
|
|
19507
|
+
process.exit(1);
|
|
19508
|
+
}
|
|
19509
|
+
const boardsDir = join19(flintPath, ".steel", "plates", plateName, "boards");
|
|
19510
|
+
if (!await exists5(boardsDir)) {
|
|
19511
|
+
console.log(pc42.dim(`No board configs found for plate: ${plateName}`));
|
|
19512
|
+
return;
|
|
19513
|
+
}
|
|
19514
|
+
const files = await readdir6(boardsDir);
|
|
19515
|
+
const configs = files.filter((f) => f.endsWith(".json"));
|
|
19516
|
+
if (configs.length === 0) {
|
|
19517
|
+
console.log(pc42.dim(`No board configs found for plate: ${plateName}`));
|
|
19518
|
+
return;
|
|
19519
|
+
}
|
|
19520
|
+
console.log(pc42.bold(`Board configs: ${plateName}`));
|
|
19521
|
+
for (const file of configs) {
|
|
19522
|
+
const name = file.replace(/\.json$/, "");
|
|
19523
|
+
console.log(` ${pc42.cyan(name)}`);
|
|
19524
|
+
}
|
|
19525
|
+
} catch (err) {
|
|
19526
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
19527
|
+
console.error(pc42.red(`Error: ${message}`));
|
|
19528
|
+
process.exit(1);
|
|
19529
|
+
}
|
|
19530
|
+
})
|
|
19531
|
+
);
|
|
19532
|
+
|
|
16997
19533
|
// src/index.ts
|
|
16998
19534
|
var __dirname3 = dirname4(fileURLToPath4(import.meta.url));
|
|
16999
|
-
var pkg = JSON.parse(readFileSync11(
|
|
19535
|
+
var pkg = JSON.parse(readFileSync11(join20(__dirname3, "..", "package.json"), "utf-8"));
|
|
17000
19536
|
var runtime = resolveRuntimeSync({ cliname: "flint" });
|
|
17001
19537
|
var devAvailable = runtime.mode === "dev";
|
|
17002
19538
|
var newDir = getConfigDir("flint");
|
|
17003
|
-
var oldDir =
|
|
17004
|
-
var intermediateDir =
|
|
19539
|
+
var oldDir = join20(homedir11(), ".flint");
|
|
19540
|
+
var intermediateDir = join20(homedir11(), ".nuucognition", ".flint");
|
|
17005
19541
|
function migrateDir(sourceDir, label) {
|
|
17006
19542
|
if (!existsSync15(sourceDir)) return false;
|
|
17007
19543
|
try {
|
|
@@ -17011,15 +19547,15 @@ function migrateDir(sourceDir, label) {
|
|
|
17011
19547
|
mkdirSync5(newDir, { recursive: true });
|
|
17012
19548
|
let migrated = 0;
|
|
17013
19549
|
for (const entry of filesToMigrate) {
|
|
17014
|
-
const src =
|
|
17015
|
-
const dest =
|
|
19550
|
+
const src = join20(sourceDir, entry);
|
|
19551
|
+
const dest = join20(newDir, entry);
|
|
17016
19552
|
if (!existsSync15(dest)) {
|
|
17017
19553
|
cpSync(src, dest, { recursive: true });
|
|
17018
19554
|
migrated++;
|
|
17019
19555
|
}
|
|
17020
19556
|
}
|
|
17021
19557
|
if (migrated > 0) {
|
|
17022
|
-
console.log(
|
|
19558
|
+
console.log(pc43.yellow(`Migrated ${migrated} item(s) from ${label} to ~/.nuucognition/flint/`));
|
|
17023
19559
|
}
|
|
17024
19560
|
return migrated > 0;
|
|
17025
19561
|
} catch {
|
|
@@ -17055,7 +19591,7 @@ var authConfig = {
|
|
|
17055
19591
|
defaultEnv: devAvailable ? "dev" : "prod",
|
|
17056
19592
|
devAvailable
|
|
17057
19593
|
};
|
|
17058
|
-
var program = new
|
|
19594
|
+
var program = new Command38();
|
|
17059
19595
|
program.name("flint").description("Flint cognitive workspace CLI").version(pkg.version).enablePositionalOptions().option("--verbose", "Show stack traces for errors");
|
|
17060
19596
|
program.addCommand(createLoginCommand(authConfig));
|
|
17061
19597
|
program.addCommand(createLogoutCommand(authConfig));
|
|
@@ -17095,6 +19631,7 @@ var COMMAND_MAP = [
|
|
|
17095
19631
|
{ featureId: "code", command: codeCommand },
|
|
17096
19632
|
{ featureId: "tinderbox", command: tinderboxCommand },
|
|
17097
19633
|
{ featureId: "orb", command: orbCommand },
|
|
19634
|
+
{ featureId: "steel", command: steelCommand },
|
|
17098
19635
|
// Dev commands
|
|
17099
19636
|
{ featureId: "runtime", command: runtimeCommand }
|
|
17100
19637
|
];
|
|
@@ -17109,11 +19646,11 @@ program.on("command:*", (operands) => {
|
|
|
17109
19646
|
if (feature && !isFeatureEnabled(FEATURES, cmdName, runtime)) {
|
|
17110
19647
|
error(`Feature '${cmdName}' requires dev mode.`);
|
|
17111
19648
|
console.log("");
|
|
17112
|
-
console.log(
|
|
19649
|
+
console.log(pc43.dim("Dev features are only available when running the dev binary."));
|
|
17113
19650
|
process.exit(1);
|
|
17114
19651
|
}
|
|
17115
19652
|
error(`Unknown command: ${cmdName}`);
|
|
17116
|
-
console.log(
|
|
19653
|
+
console.log(pc43.dim(`Run 'flint --help' for available commands`));
|
|
17117
19654
|
process.exit(1);
|
|
17118
19655
|
});
|
|
17119
19656
|
await program.parseAsync(process.argv);
|