@prestack/thread 0.1.20 → 0.1.22
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/CHANGELOG.md +193 -0
- package/dist/core/attach.js +21 -0
- package/dist/core/descend.d.ts +2 -0
- package/dist/core/descend.js +18 -3
- package/dist/core/generators/commit.js +55 -3
- package/dist/core/generators/dev.d.ts +1 -0
- package/dist/core/generators/dev.js +68 -0
- package/dist/core/rows.d.ts +5 -0
- package/dist/core/rows.js +45 -0
- package/dist/core/tree.d.ts +1 -0
- package/dist/core/tree.js +7 -1
- package/dist/derivation/generators/build.d.ts +3 -1
- package/dist/derivation/generators/build.js +103 -22
- package/dist/derivation/generators/release.js +74 -26
- package/dist/derivation/release.js +3 -3
- package/dist/integrations/cli.d.ts +3 -9
- package/dist/integrations/cli.js +96 -36
- package/dist/integrations/declared.d.ts +8 -0
- package/dist/integrations/declared.js +22 -0
- package/dist/integrations/pglite.js +13 -3
- package/dist/integrations/target.d.ts +4 -1
- package/dist/integrations/target.js +20 -6
- package/dist/integrity/attach.js +1 -5
- package/dist/integrity/generators/publish.js +2 -1
- package/dist/integrity/slopnators/sl_stale_path.js +10 -0
- package/dist/integrity/slopnators/sl_unlisted_program.js +2 -2
- package/dist/operations/access.js +3 -2
- package/dist/operations/capabilities.d.ts +2 -0
- package/dist/operations/capabilities.js +2 -0
- package/dist/operations/generators/capability.js +234 -24
- package/dist/operations/generators/compile.d.ts +21 -0
- package/dist/operations/generators/compile.js +151 -51
- package/dist/operations/generators/permits.d.ts +2 -1
- package/dist/operations/generators/permits.js +52 -47
- package/dist/operations/generators/seed.d.ts +3 -0
- package/dist/operations/generators/seed.js +25 -3
- package/dist/operations/nodes.d.ts +2 -2
- package/package.json +1 -1
- package/dist/core/actor.ts +0 -21
- package/dist/core/attach.ts +0 -613
- package/dist/core/chain.ts +0 -145
- package/dist/core/condition.ts +0 -227
- package/dist/core/descend.ts +0 -1173
- package/dist/core/errors/catalogue.ts +0 -314
- package/dist/core/errors/classes.ts +0 -51
- package/dist/core/errors/error.ts +0 -152
- package/dist/core/errors/namespaces.ts +0 -19
- package/dist/core/finding.ts +0 -37
- package/dist/core/generators/commit.ts +0 -157
- package/dist/core/init.ts +0 -222
- package/dist/core/invoked.ts +0 -52
- package/dist/core/round.ts +0 -74
- package/dist/core/rows.ts +0 -459
- package/dist/core/scope.ts +0 -20
- package/dist/core/thread.ts +0 -29
- package/dist/core/tree.ts +0 -90
- package/dist/core/types.ts +0 -351
- package/dist/derivation/attach.ts +0 -57
- package/dist/derivation/generators/build.ts +0 -371
- package/dist/derivation/generators/check.ts +0 -118
- package/dist/derivation/generators/determinism.ts +0 -145
- package/dist/derivation/generators/release.ts +0 -236
- package/dist/derivation/release.ts +0 -43
- package/dist/integrations/attach.ts +0 -187
- package/dist/integrations/cli.ts +0 -615
- package/dist/integrations/disk.ts +0 -466
- package/dist/integrations/generators/read.ts +0 -127
- package/dist/integrations/generators/vault.ts +0 -210
- package/dist/integrations/https.ts +0 -216
- package/dist/integrations/pglite.ts +0 -206
- package/dist/integrations/secret.ts +0 -54
- package/dist/integrations/target.ts +0 -656
- package/dist/integrations/vault.ts +0 -148
- package/dist/integrity/attach.ts +0 -150
- package/dist/integrity/check-threads.ts +0 -166
- package/dist/integrity/constraint.ts +0 -1246
- package/dist/integrity/generators/compiler.ts +0 -138
- package/dist/integrity/generators/gate.ts +0 -227
- package/dist/integrity/generators/issues.ts +0 -160
- package/dist/integrity/generators/publish.ts +0 -232
- package/dist/integrity/generators/trial.ts +0 -359
- package/dist/integrity/lint.ts +0 -214
- package/dist/integrity/lsp/bin.ts +0 -44
- package/dist/integrity/lsp/diagnostics.ts +0 -92
- package/dist/integrity/lsp/findings.ts +0 -63
- package/dist/integrity/lsp/lint.ts +0 -124
- package/dist/integrity/lsp/protocol.ts +0 -78
- package/dist/integrity/lsp/server.ts +0 -224
- package/dist/integrity/slopnator.ts +0 -324
- package/dist/integrity/slopnators/sl_broken_lineage.ts +0 -38
- package/dist/integrity/slopnators/sl_declared_elsewhere.ts +0 -60
- package/dist/integrity/slopnators/sl_derived_drift.ts +0 -101
- package/dist/integrity/slopnators/sl_door_in_a_node.ts +0 -250
- package/dist/integrity/slopnators/sl_hardcoded_style.ts +0 -55
- package/dist/integrity/slopnators/sl_inert_island.ts +0 -84
- package/dist/integrity/slopnators/sl_inert_slopnator.ts +0 -93
- package/dist/integrity/slopnators/sl_missing_row.ts +0 -140
- package/dist/integrity/slopnators/sl_no_barrel.ts +0 -48
- package/dist/integrity/slopnators/sl_no_child_process.ts +0 -100
- package/dist/integrity/slopnators/sl_no_comment.ts +0 -43
- package/dist/integrity/slopnators/sl_no_dispatch_bypass.ts +0 -276
- package/dist/integrity/slopnators/sl_no_import_cycle.ts +0 -66
- package/dist/integrity/slopnators/sl_no_such_command.ts +0 -81
- package/dist/integrity/slopnators/sl_only_takes_a_literal.ts +0 -63
- package/dist/integrity/slopnators/sl_outside_an_operation.ts +0 -25
- package/dist/integrity/slopnators/sl_screen_holds_only_declared.ts +0 -70
- package/dist/integrity/slopnators/sl_secret_literal.ts +0 -68
- package/dist/integrity/slopnators/sl_stale_path.ts +0 -178
- package/dist/integrity/slopnators/sl_twice_meant.ts +0 -57
- package/dist/integrity/slopnators/sl_twice_parented.ts +0 -82
- package/dist/integrity/slopnators/sl_undeclared_crossing.ts +0 -481
- package/dist/integrity/slopnators/sl_undeclared_destination.ts +0 -113
- package/dist/integrity/slopnators/sl_undeclared_element.ts +0 -44
- package/dist/integrity/slopnators/sl_undeclared_list.ts +0 -358
- package/dist/integrity/slopnators/sl_undeclared_node.ts +0 -75
- package/dist/integrity/slopnators/sl_undeclared_operation.ts +0 -257
- package/dist/integrity/slopnators/sl_undeclared_variant.ts +0 -152
- package/dist/integrity/slopnators/sl_undeclared_webhook.ts +0 -108
- package/dist/integrity/slopnators/sl_underived_route.ts +0 -72
- package/dist/integrity/slopnators/sl_undescribed.ts +0 -65
- package/dist/integrity/slopnators/sl_ungoverned_island.ts +0 -60
- package/dist/integrity/slopnators/sl_unlisted_program.ts +0 -46
- package/dist/integrity/slopnators/sl_unnamed_island.ts +0 -41
- package/dist/integrity/slopnators/sl_unpaired_member.ts +0 -139
- package/dist/integrity/slopnators/sl_unpaired_slopnator.ts +0 -71
- package/dist/integrity/slopnators/sl_unprefixed_member.ts +0 -110
- package/dist/integrity/slopnators/sl_unthreaded.ts +0 -421
- package/dist/integrity/slopnators/sl_untranslated_key.ts +0 -140
- package/dist/integrity/slopnators/sl_unvaulted_secret.ts +0 -132
- package/dist/integrity/slopnators/sl_unversioned.ts +0 -52
- package/dist/integrity/sweep.ts +0 -395
- package/dist/knowledge/attach.ts +0 -327
- package/dist/knowledge/generators/docsgen.ts +0 -186
- package/dist/knowledge/generators/glossary.ts +0 -73
- package/dist/knowledge/glossary.ts +0 -6
- package/dist/operations/access.ts +0 -131
- package/dist/operations/attach.ts +0 -408
- package/dist/operations/capabilities.ts +0 -88
- package/dist/operations/dispatch.ts +0 -294
- package/dist/operations/error-results.ts +0 -31
- package/dist/operations/generators/capability.ts +0 -1054
- package/dist/operations/generators/compile.ts +0 -701
- package/dist/operations/generators/permits.ts +0 -224
- package/dist/operations/generators/seed.ts +0 -359
- package/dist/operations/generators/trial.ts +0 -666
- package/dist/operations/nodes.ts +0 -53
- package/dist/operations/operations.ts +0 -91
- package/dist/operations/result.ts +0 -28
package/dist/integrations/cli.js
CHANGED
|
@@ -6,11 +6,10 @@ import { allowedNodeEnvironmentFlags, env, execPath, kill, pid, stderr, stdout }
|
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { CHANNEL, FOLDER, across, attached, createFileSync, existsSync, here, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from '../integrations/disk.js';
|
|
8
8
|
import { VAULT_DIR } from '../integrations/vault.js';
|
|
9
|
-
import {
|
|
9
|
+
import { LOCKFILES, ORDERS, PACKAGER, REACH, managerOf, programOf, unlisted } from '../integrations/target.js';
|
|
10
10
|
import { BESIDE, CLI } from '../core/invoked.js';
|
|
11
|
-
import { valuesIn } from '../core/rows.js';
|
|
12
11
|
import { THING } from '../core/scope.js';
|
|
13
|
-
import { findTree
|
|
12
|
+
import { findTree } from '../core/tree.js';
|
|
14
13
|
const answered = (went) => ({
|
|
15
14
|
there: went.error === undefined,
|
|
16
15
|
ok: went.status === 0,
|
|
@@ -141,7 +140,7 @@ export function claims(root, runs) {
|
|
|
141
140
|
return { by: { pid: 0, runs: '', since: Date.now() } };
|
|
142
141
|
}
|
|
143
142
|
export function programFor(name, at) {
|
|
144
|
-
const found = programOf(name, at, existsSync);
|
|
143
|
+
const found = programOf(name, at, existsSync, (path) => readFileSync(path, 'utf8'));
|
|
145
144
|
if (found === undefined)
|
|
146
145
|
throw new Error(unlisted(name));
|
|
147
146
|
return found;
|
|
@@ -246,6 +245,63 @@ const READS = new Set(Object.entries(ORDERS).filter(([order, answer]) => order =
|
|
|
246
245
|
function kept(one, asked, held) {
|
|
247
246
|
if (READS.has(asked.order) && held.answered !== 'refused')
|
|
248
247
|
one.known.set(told(asked), held);
|
|
248
|
+
if (asked.order !== 'write' || held.answered !== ORDERS.write)
|
|
249
|
+
return;
|
|
250
|
+
one.known.set(told({ order: 'read', at: asked.at }), { answered: 'read', said: asked.said ?? '' });
|
|
251
|
+
one.known.set(told({ order: 'kind', at: asked.at }), { answered: 'kind', found: 'file' });
|
|
252
|
+
}
|
|
253
|
+
const CHANGES = new Set(['write', 'remove']);
|
|
254
|
+
const within = (at, under) => under === '' || at === under || at.startsWith(under + '/');
|
|
255
|
+
function forgets(one, asked) {
|
|
256
|
+
if (!CHANGES.has(asked.order)) {
|
|
257
|
+
one.known.clear();
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
for (const key of [...one.known.keys()]) {
|
|
261
|
+
const [order = '', at = ''] = JSON.parse(key);
|
|
262
|
+
if (order === 'real' || within(at, asked.at) || within(asked.at, at))
|
|
263
|
+
one.known.delete(key);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const AHEAD = 32;
|
|
267
|
+
const upOf = (at) => (at.includes('/') ? at.slice(0, at.lastIndexOf('/')) : '');
|
|
268
|
+
const nameOf = (at) => at.slice(at.lastIndexOf('/') + 1);
|
|
269
|
+
const inside = (at, name) => (at === '' ? name : at + '/' + name);
|
|
270
|
+
function listedAt(one, at) {
|
|
271
|
+
const held = one.known.get(told({ order: 'list', at }))?.found;
|
|
272
|
+
return Array.isArray(held) ? held : [];
|
|
273
|
+
}
|
|
274
|
+
function realOf(one, at) {
|
|
275
|
+
const held = one.known.get(told({ order: 'real', at }));
|
|
276
|
+
if (held !== undefined || at === '')
|
|
277
|
+
return held;
|
|
278
|
+
const entry = listedAt(one, upOf(at)).find((each) => each.name === nameOf(at));
|
|
279
|
+
if (entry === undefined || entry.kind === 'other')
|
|
280
|
+
return undefined;
|
|
281
|
+
const above = realOf(one, upOf(at));
|
|
282
|
+
return typeof above?.at === 'string' ? { answered: 'real', at: above.at + '/' + nameOf(at) } : undefined;
|
|
283
|
+
}
|
|
284
|
+
function aheadOf(one, asked) {
|
|
285
|
+
if (asked.order === 'real')
|
|
286
|
+
return asked.at === '' || one.known.has(told({ order: 'real', at: '' })) ? [] : [{ order: 'real', at: '', ahead: true }];
|
|
287
|
+
const name = nameOf(asked.at);
|
|
288
|
+
const dot = name.indexOf('.');
|
|
289
|
+
const reading = asked.order === 'read' && dot > 0 && asked.at.split('/').includes(INSTALLED);
|
|
290
|
+
if (!reading && asked.order !== 'stat')
|
|
291
|
+
return [];
|
|
292
|
+
const suffix = reading ? name.slice(dot) : '';
|
|
293
|
+
const up = upOf(asked.at);
|
|
294
|
+
const found = [];
|
|
295
|
+
for (const each of listedAt(one, up)) {
|
|
296
|
+
if (found.length === AHEAD)
|
|
297
|
+
break;
|
|
298
|
+
if (each.kind !== 'file' || each.name === name || !each.name.endsWith(suffix))
|
|
299
|
+
continue;
|
|
300
|
+
const order = { order: asked.order, at: inside(up, each.name), ahead: true };
|
|
301
|
+
if (!one.known.has(told(order)))
|
|
302
|
+
found.push(order);
|
|
303
|
+
}
|
|
304
|
+
return found;
|
|
249
305
|
}
|
|
250
306
|
const plainly = (one) => one.order + ' ' + (one.at === '' ? '.' : one.at);
|
|
251
307
|
const outside = (root, at) => {
|
|
@@ -299,11 +355,22 @@ function watching(one) {
|
|
|
299
355
|
reply(one.dir, short, known);
|
|
300
356
|
continue;
|
|
301
357
|
}
|
|
358
|
+
const derived = asked.order === 'real' ? realOf(one, asked.at) : undefined;
|
|
359
|
+
if (derived !== undefined) {
|
|
360
|
+
reply(one.dir, short, derived);
|
|
361
|
+
kept(one, asked, derived);
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
302
364
|
if (!READS.has(asked.order))
|
|
303
|
-
one
|
|
365
|
+
forgets(one, asked);
|
|
304
366
|
const due = one.replaying.shift();
|
|
305
367
|
if (due !== undefined) {
|
|
306
368
|
if (told(due.order) === told(asked)) {
|
|
369
|
+
while (one.replaying[0]?.order.ahead === true) {
|
|
370
|
+
const extra = one.replaying.shift();
|
|
371
|
+
if (extra !== undefined)
|
|
372
|
+
kept(one, extra.order, extra.answered);
|
|
373
|
+
}
|
|
307
374
|
reply(one.dir, short, due.answered);
|
|
308
375
|
kept(one, asked, due.answered);
|
|
309
376
|
continue;
|
|
@@ -318,7 +385,8 @@ function watching(one) {
|
|
|
318
385
|
}
|
|
319
386
|
one.pending = short;
|
|
320
387
|
one.asking = asked;
|
|
321
|
-
|
|
388
|
+
one.ahead = aheadOf(one, asked);
|
|
389
|
+
hand(one, still(one, [asked, ...one.ahead]));
|
|
322
390
|
}
|
|
323
391
|
}, TICK);
|
|
324
392
|
}
|
|
@@ -346,11 +414,11 @@ function next(one, within) {
|
|
|
346
414
|
}, Math.max(1_000, within - MARGIN));
|
|
347
415
|
});
|
|
348
416
|
}
|
|
349
|
-
function begun(from, word, args, root, hears, called, recording = []) {
|
|
417
|
+
function begun(from, word, args, root, hears, called, recording = [], stash) {
|
|
350
418
|
const of = called ?? randomBytes(6).toString('hex');
|
|
351
419
|
const dir = join(tmpdir(), SERVED, randomBytes(6).toString('hex'));
|
|
352
420
|
writeFileSync(join(dir, 'channel'), '', 'utf8');
|
|
353
|
-
const one = { of, dir, root, out: '', err: '', why: '', pending: '', waiting: [], parked: [], replaying: [...recording], handed: recording.length, known: new Map() };
|
|
421
|
+
const one = { of, dir, root, out: '', err: '', why: '', pending: '', waiting: [], parked: [], replaying: [...recording], handed: recording.length, known: new Map(), ahead: [], ...(stash === undefined ? {} : { stash }) };
|
|
354
422
|
const child = spawn(execPath, [...from.words, word, ...args], {
|
|
355
423
|
cwd: from.own,
|
|
356
424
|
shell: false,
|
|
@@ -381,6 +449,7 @@ function counted(one, held) {
|
|
|
381
449
|
one.last = held;
|
|
382
450
|
return held;
|
|
383
451
|
}
|
|
452
|
+
const stashing = (one, held) => (one.stash === undefined ? held : { ...held, stashed: one.stash });
|
|
384
453
|
async function served(word, args, within, how) {
|
|
385
454
|
const of = how?.of;
|
|
386
455
|
if (of !== undefined) {
|
|
@@ -395,20 +464,26 @@ async function served(word, args, within, how) {
|
|
|
395
464
|
const from = startable();
|
|
396
465
|
if (typeof from === 'string')
|
|
397
466
|
return nowhere(from);
|
|
398
|
-
const again = begun(from, word, args, root, how?.hears, of, recording);
|
|
399
|
-
return counted(again, await next(again, within));
|
|
467
|
+
const again = begun(from, word, args, root, how?.hears, of, recording, how?.stash);
|
|
468
|
+
return stashing(again, counted(again, await next(again, within)));
|
|
400
469
|
}
|
|
401
470
|
const answering = how?.answering;
|
|
402
471
|
if (answering !== undefined && answering < one.handed && one.last !== undefined)
|
|
403
|
-
return one.last;
|
|
404
|
-
const given =
|
|
472
|
+
return stashing(one, one.last);
|
|
473
|
+
const [given, ...rest] = how?.answered ?? [];
|
|
405
474
|
if (one.pending !== '' && given !== undefined) {
|
|
475
|
+
one.ahead.forEach((order, index) => {
|
|
476
|
+
const held = rest[index];
|
|
477
|
+
if (held !== undefined)
|
|
478
|
+
kept(one, order, held);
|
|
479
|
+
});
|
|
480
|
+
one.ahead = [];
|
|
406
481
|
reply(one.dir, one.pending, given);
|
|
407
482
|
if (one.asking !== undefined)
|
|
408
483
|
kept(one, one.asking, given);
|
|
409
484
|
one.pending = '';
|
|
410
485
|
}
|
|
411
|
-
return counted(one, await next(one, within));
|
|
486
|
+
return stashing(one, counted(one, await next(one, within)));
|
|
412
487
|
}
|
|
413
488
|
const root = how?.at ?? '';
|
|
414
489
|
if (root === '')
|
|
@@ -416,8 +491,8 @@ async function served(word, args, within, how) {
|
|
|
416
491
|
const from = startable();
|
|
417
492
|
if (typeof from === 'string')
|
|
418
493
|
return nowhere(from);
|
|
419
|
-
const fresh = begun(from, word, args, root, how?.hears);
|
|
420
|
-
return counted(fresh, await next(fresh, within));
|
|
494
|
+
const fresh = begun(from, word, args, root, how?.hears, undefined, [], how?.stash);
|
|
495
|
+
return stashing(fresh, counted(fresh, await next(fresh, within)));
|
|
421
496
|
}
|
|
422
497
|
export function running(name, subcommands, at) {
|
|
423
498
|
const out = {};
|
|
@@ -427,31 +502,15 @@ export function running(name, subcommands, at) {
|
|
|
427
502
|
? async (args, shows, within, how) => served(word, args, within, how)
|
|
428
503
|
: async (args, shows, within, how) => {
|
|
429
504
|
const where = how?.at ?? at;
|
|
430
|
-
const program = programFor(name, where);
|
|
505
|
+
const [program = '', ...lead] = programFor(name, where);
|
|
431
506
|
if ((shows ?? false) !== false)
|
|
432
|
-
return handed(where, program, [word, ...args], shows ?? false, within, how?.hears);
|
|
433
|
-
return await started(program, [word, ...args], { at: where, ...(within === undefined ? {} : { within }), ...(how?.hears === undefined ? {} : { hears: how.hears }) });
|
|
507
|
+
return handed(where, program, [...lead, word, ...args], shows ?? false, within, how?.hears);
|
|
508
|
+
return await started(program, [...lead, word, ...args], { at: where, ...(within === undefined ? {} : { within }), ...(how?.hears === undefined ? {} : { hears: how.hears }) });
|
|
434
509
|
};
|
|
435
510
|
}
|
|
436
511
|
return out;
|
|
437
512
|
}
|
|
438
|
-
|
|
439
|
-
const path = inTree(findTree(at), 'targets.ts');
|
|
440
|
-
return existsSync(path) ? valuesIn(readFileSync(path, 'utf8')) : {};
|
|
441
|
-
}
|
|
442
|
-
export function expansions(at) {
|
|
443
|
-
const held = sheet(at);
|
|
444
|
-
return (held.TARGETS ?? [])
|
|
445
|
-
.filter((one) => one.id.startsWith(REACH.cli))
|
|
446
|
-
.map((one) => ({ program: one.id.slice(REACH.cli.length), target: one, calls: (held.CALLS ?? []).filter((each) => each.of === one.id) }));
|
|
447
|
-
}
|
|
448
|
-
export function calls(target, at) {
|
|
449
|
-
const named = {};
|
|
450
|
-
for (const one of sheet(at).CALLS ?? [])
|
|
451
|
-
if (one.of === target)
|
|
452
|
-
named[one.id.replace(CALL_PREFIX, '')] = one.path;
|
|
453
|
-
return running(target.replace(REACH.cli, ''), named, at);
|
|
454
|
-
}
|
|
513
|
+
export { calls, expansions } from '../integrations/declared.js';
|
|
455
514
|
export { LOCKFILES };
|
|
456
515
|
export const manager = (into) => managerOf(into, existsSync);
|
|
457
516
|
const ADDS = { pnpm: 'add', yarn: 'add', bun: 'add', npm: 'install' };
|
|
@@ -489,7 +548,8 @@ export function installing(at) {
|
|
|
489
548
|
if (attached())
|
|
490
549
|
return here().fetch(at);
|
|
491
550
|
const tool = manager(at);
|
|
492
|
-
const
|
|
551
|
+
const [program = '', ...lead] = programFor(PACKAGER, at);
|
|
552
|
+
const ran = starts(program, [...lead, 'install'], { at });
|
|
493
553
|
const said = (ran.out + ran.err).trim();
|
|
494
554
|
if (!ran.there) {
|
|
495
555
|
throw new Error(tool + ' is what the lockfile in ' + at + ' picks, and it is not on this machine, so nothing here can fetch ' +
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Call, type Running, type Target } from '../integrations/target.ts';
|
|
2
|
+
export interface Expansion {
|
|
3
|
+
readonly program: string;
|
|
4
|
+
readonly target: Target;
|
|
5
|
+
readonly calls: readonly Call[];
|
|
6
|
+
}
|
|
7
|
+
export declare function expansions(at: string): readonly Expansion[];
|
|
8
|
+
export declare function calls(target: string, at: string): Running;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { running } from '../integrations/cli.js';
|
|
2
|
+
import { existsSync, readFileSync } from '../integrations/disk.js';
|
|
3
|
+
import { CALL_PREFIX, REACH } from '../integrations/target.js';
|
|
4
|
+
import { valuesIn } from '../core/rows.js';
|
|
5
|
+
import { findTree, inTree } from '../core/tree.js';
|
|
6
|
+
function sheet(at) {
|
|
7
|
+
const path = inTree(findTree(at), 'targets.ts');
|
|
8
|
+
return existsSync(path) ? valuesIn(readFileSync(path, 'utf8')) : {};
|
|
9
|
+
}
|
|
10
|
+
export function expansions(at) {
|
|
11
|
+
const held = sheet(at);
|
|
12
|
+
return (held.TARGETS ?? [])
|
|
13
|
+
.filter((one) => one.id.startsWith(REACH.cli))
|
|
14
|
+
.map((one) => ({ program: one.id.slice(REACH.cli.length), target: one, calls: (held.CALLS ?? []).filter((each) => each.of === one.id) }));
|
|
15
|
+
}
|
|
16
|
+
export function calls(target, at) {
|
|
17
|
+
const named = {};
|
|
18
|
+
for (const one of sheet(at).CALLS ?? [])
|
|
19
|
+
if (one.of === target)
|
|
20
|
+
named[one.id.replace(CALL_PREFIX, '')] = one.path;
|
|
21
|
+
return running(target.replace(REACH.cli, ''), named, at);
|
|
22
|
+
}
|
|
@@ -52,14 +52,24 @@ export async function shapeOf(sql) {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
export function standing(held) {
|
|
55
|
-
const store = storing({ ...held, at: 'memory://'
|
|
55
|
+
const store = storing({ ...held, at: 'memory://' });
|
|
56
56
|
const keeps = Object.keys(held.tables);
|
|
57
57
|
return {
|
|
58
58
|
keeps,
|
|
59
59
|
store,
|
|
60
60
|
async seed(actor, rows) {
|
|
61
|
-
for (const one of rows)
|
|
61
|
+
for (const one of rows) {
|
|
62
|
+
const by = held.address[one.entity];
|
|
63
|
+
const key = by === undefined ? undefined : one.row[by];
|
|
64
|
+
if (by !== undefined && (typeof key === 'string' || typeof key === 'number')) {
|
|
65
|
+
const there = await store.list(actor, one.entity, { where: { [by]: key }, limit: 1 });
|
|
66
|
+
if (there.length > 0) {
|
|
67
|
+
await store.update(actor, one.entity, key, one.row);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
62
71
|
await store.insert(actor, one.entity, one.row);
|
|
72
|
+
}
|
|
63
73
|
},
|
|
64
74
|
async taken(actor) {
|
|
65
75
|
const found = {};
|
|
@@ -83,7 +93,7 @@ export function storing(held) {
|
|
|
83
93
|
const found = held.address[entity];
|
|
84
94
|
if (found === undefined) {
|
|
85
95
|
throw new Error(entity + ' declares nothing that identifies one of its rows, so a row of it cannot be addressed here. ' +
|
|
86
|
-
'
|
|
96
|
+
'Name the value that does: give `thread edit ' + entity + ' --must` its invariants again with one more, unique over that value alone.');
|
|
87
97
|
}
|
|
88
98
|
return found;
|
|
89
99
|
};
|
|
@@ -68,6 +68,7 @@ export interface Order {
|
|
|
68
68
|
readonly said?: string;
|
|
69
69
|
readonly mode?: number;
|
|
70
70
|
readonly words?: readonly string[];
|
|
71
|
+
readonly ahead?: boolean;
|
|
71
72
|
}
|
|
72
73
|
export interface Answer {
|
|
73
74
|
readonly answered: string;
|
|
@@ -87,6 +88,7 @@ export interface How {
|
|
|
87
88
|
readonly answered?: readonly Answer[];
|
|
88
89
|
readonly recording?: readonly Recorded[];
|
|
89
90
|
readonly answering?: number;
|
|
91
|
+
readonly stash?: unknown;
|
|
90
92
|
}
|
|
91
93
|
export interface Ran {
|
|
92
94
|
readonly there: boolean;
|
|
@@ -99,6 +101,7 @@ export interface Ran {
|
|
|
99
101
|
readonly of?: string;
|
|
100
102
|
readonly asks?: readonly Order[];
|
|
101
103
|
readonly lost?: string;
|
|
104
|
+
readonly stashed?: unknown;
|
|
102
105
|
}
|
|
103
106
|
export type Running<C extends string = string> = Readonly<Record<C, (args: readonly string[], shows?: boolean | 'errors' | 'tee', within?: number, how?: How) => Promise<Ran>>>;
|
|
104
107
|
export type Calling<C extends string = string> = {
|
|
@@ -178,7 +181,7 @@ export declare const unreachable: (targets: readonly Target[]) => readonly strin
|
|
|
178
181
|
export declare const LOCKFILES: Readonly<Record<string, string>>;
|
|
179
182
|
export declare const PACKAGER = "packager";
|
|
180
183
|
export declare const managerOf: (at: string, there: (path: string) => boolean) => string;
|
|
181
|
-
export declare function programOf(name: string, at: string, there: (path: string) => boolean): string | undefined;
|
|
184
|
+
export declare function programOf(name: string, at: string, there: (path: string) => boolean, read: (path: string) => string): readonly string[] | undefined;
|
|
182
185
|
export declare const unlisted: (name: string) => string;
|
|
183
186
|
export declare function misnamed(target: string, name: string): string | undefined;
|
|
184
187
|
export declare function misaccepted(targets: readonly Target[], entities: readonly string[], calls: readonly Call[]): readonly string[];
|
|
@@ -143,17 +143,31 @@ export const PACKAGER = 'packager';
|
|
|
143
143
|
const NAMED = ['git', 'thread'];
|
|
144
144
|
const RUNTIME = 'node';
|
|
145
145
|
export const managerOf = (at, there) => Object.entries(LOCKFILES).find(([lock]) => there(join(at, lock)))?.[1] ?? 'npm';
|
|
146
|
-
export function programOf(name, at, there) {
|
|
146
|
+
export function programOf(name, at, there, read) {
|
|
147
147
|
if (NAMED.includes(name))
|
|
148
|
-
return name;
|
|
148
|
+
return [name];
|
|
149
149
|
if (name === RUNTIME)
|
|
150
|
-
return execPath;
|
|
150
|
+
return [execPath];
|
|
151
151
|
if (name === PACKAGER)
|
|
152
|
-
return managerOf(at, there);
|
|
152
|
+
return [managerOf(at, there)];
|
|
153
153
|
const installed = join(at, 'node_modules', '.bin', name);
|
|
154
|
-
|
|
154
|
+
if (there(installed))
|
|
155
|
+
return [installed];
|
|
156
|
+
const shipped = join(at, 'node_modules', name);
|
|
157
|
+
const manifest = join(shipped, 'package.json');
|
|
158
|
+
if (!there(manifest))
|
|
159
|
+
return undefined;
|
|
160
|
+
let bin;
|
|
161
|
+
try {
|
|
162
|
+
bin = JSON.parse(read(manifest)).bin;
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
const entry = typeof bin === 'string' ? bin : typeof bin === 'object' && bin !== null ? bin[name] : undefined;
|
|
168
|
+
return typeof entry === 'string' ? [execPath, join(shipped, entry)] : undefined;
|
|
155
169
|
}
|
|
156
|
-
export const unlisted = (name) => '`' + REACH.cli + name + '` names ' + name + ', and nothing lists a program by that name: it is not under node_modules/.bin, so this tree did not install it; it is not git, node or thread; and it is not `' + PACKAGER + '`, the word for whichever package manager the lockfile picks. A program the tree did not install is whatever the machine happens to have, and a target on that is a shell by another name. Add the package that provides it and declare the target again, or ask for it through a declared call on `' + REACH.cli + PACKAGER + '`';
|
|
170
|
+
export const unlisted = (name) => '`' + REACH.cli + name + '` names ' + name + ', and nothing lists a program by that name: it is not linked under node_modules/.bin, and no package installed here under that name names it as its program, so this tree did not install it; it is not git, node or thread; and it is not `' + PACKAGER + '`, the word for whichever package manager the lockfile picks. A program the tree did not install is whatever the machine happens to have, and a target on that is a shell by another name. Add the package that provides it and declare the target again, or ask for it through a declared call on `' + REACH.cli + PACKAGER + '`';
|
|
157
171
|
const SHAPED = {
|
|
158
172
|
cli: /^-{0,2}[A-Za-z][A-Za-z0-9-]*$/,
|
|
159
173
|
};
|
package/dist/integrity/attach.js
CHANGED
|
@@ -116,11 +116,7 @@ export const ATTACH = {
|
|
|
116
116
|
{ file: 'rules.ts', source: RULES_SOURCE },
|
|
117
117
|
{ file: 'gate.ts', source: GATE_SOURCE },
|
|
118
118
|
],
|
|
119
|
-
ignores: ['.thread/', '
|
|
120
|
-
scripts: {
|
|
121
|
-
build: 'next build',
|
|
122
|
-
start: 'next start',
|
|
123
|
-
},
|
|
119
|
+
ignores: ['.thread/', 'node_modules/', 'tsconfig.tsbuildinfo'],
|
|
124
120
|
needs: {
|
|
125
121
|
'@types/node': '^24.0.0',
|
|
126
122
|
typescript: '^6.0.0',
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { starts } from '../../integrations/cli.js';
|
|
2
|
+
import { calls } from '../../integrations/declared.js';
|
|
2
3
|
import { existsSync, readFileSync } from '../../integrations/disk.js';
|
|
3
4
|
import { valuesIn } from '../../core/rows.js';
|
|
4
5
|
import { join } from 'node:path';
|
|
@@ -76,6 +76,9 @@ export const slopnator = {
|
|
|
76
76
|
return false;
|
|
77
77
|
if (derived().has(path))
|
|
78
78
|
return false;
|
|
79
|
+
const folder = path.slice(0, path.lastIndexOf('/'));
|
|
80
|
+
if (statSync(resolve(ROOT, folder), { throwIfNoEntry: false })?.isDirectory() !== true)
|
|
81
|
+
return false;
|
|
79
82
|
return `\`${value}\` is not on disk`;
|
|
80
83
|
},
|
|
81
84
|
proves: {
|
|
@@ -152,6 +155,13 @@ export const slopnator = {
|
|
|
152
155
|
],
|
|
153
156
|
at: 'probe.tsx',
|
|
154
157
|
},
|
|
158
|
+
{
|
|
159
|
+
files: [
|
|
160
|
+
{ at: 'docs/_probe_there.md', source: 'there\n' },
|
|
161
|
+
{ at: 'probe.tsx', source: "const at = 'docs/elsewhere/entry.ts'\n" },
|
|
162
|
+
],
|
|
163
|
+
at: 'probe.tsx',
|
|
164
|
+
},
|
|
155
165
|
"const at = 'threads/'",
|
|
156
166
|
"const said = 'a sentence about packages/core/integrity/src/constraint.ts and nothing else'",
|
|
157
167
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ROOT } from '../../core/descend.js';
|
|
2
2
|
import { valuesIn } from '../../core/rows.js';
|
|
3
|
-
import { kind } from '../../integrations/disk.js';
|
|
3
|
+
import { kind, readFileSync } from '../../integrations/disk.js';
|
|
4
4
|
import { REACH, programOf, unlisted } from '../../integrations/target.js';
|
|
5
5
|
const TARGETS = 'TARGETS';
|
|
6
6
|
const there = (path) => kind(path) === 'file';
|
|
@@ -20,7 +20,7 @@ export const slopnator = {
|
|
|
20
20
|
if (typeof one.id !== 'string' || !one.id.startsWith(REACH.cli))
|
|
21
21
|
continue;
|
|
22
22
|
const name = one.id.slice(REACH.cli.length);
|
|
23
|
-
if (programOf(name, ROOT, there) === undefined)
|
|
23
|
+
if (programOf(name, ROOT, there, (path) => readFileSync(path, 'utf8')) === undefined)
|
|
24
24
|
found.push(unlisted(name));
|
|
25
25
|
}
|
|
26
26
|
return found.length === 0 ? false : found.join('. ');
|
|
@@ -17,8 +17,9 @@ export function undeclared(answered, offers, which) {
|
|
|
17
17
|
return (`this app declares no ${which === 'roles' ? 'role' : 'entitlement'} called ${stray.map((one) => `\`${one}\``).join(', ')} — ` +
|
|
18
18
|
(offers.length === 0
|
|
19
19
|
? `it declares none at all. A ${which === 'roles' ? 'role' : 'entitlement'} is one of the words the value an ` +
|
|
20
|
-
'entity names as saying what a caller may do is held to. Declare them
|
|
21
|
-
'
|
|
20
|
+
'entity names as saying what a caller may do is held to. Declare them on that entity: give ' +
|
|
21
|
+
'`thread edit <entity> --holds` its values again with that one in the `choice` format and its options stated, ' +
|
|
22
|
+
`and name it as \`${which}\` in \`thread edit <entity> --actor\``
|
|
22
23
|
: `it declares ${offers.map((one) => `\`${one}\``).join(', ')}`));
|
|
23
24
|
}
|
|
24
25
|
export const keyIn = (one) => (one.must ?? []).flatMap((each) => (each.unique?.length === 1 ? [each.unique[0]] : []))[0];
|
|
@@ -9,6 +9,8 @@ export interface Defaults extends Threaded {
|
|
|
9
9
|
readonly live?: readonly Surface[];
|
|
10
10
|
}
|
|
11
11
|
export declare const CAPABILITIES_AT = "operations/_capabilities.json";
|
|
12
|
+
export declare const SERVER_AT = "_generated/server/entry.ts";
|
|
13
|
+
export declare const SERVER_OUT = "_generated/server/server.mjs";
|
|
12
14
|
export declare const CLIENT_AT = "operations/_client.ts";
|
|
13
15
|
export declare const DISPATCHING_AT = "app/_generated/dispatching.ts";
|
|
14
16
|
export declare const COMPILED = "app/_generated/compiled";
|
|
@@ -9,6 +9,8 @@ export const MEANS = {
|
|
|
9
9
|
export const DEFAULTS_AT = '_threads/defaults.ts';
|
|
10
10
|
export const UNSTATED = ['cli'];
|
|
11
11
|
export const CAPABILITIES_AT = 'operations/_capabilities.json';
|
|
12
|
+
export const SERVER_AT = '_generated/server/entry.ts';
|
|
13
|
+
export const SERVER_OUT = '_generated/server/server.mjs';
|
|
12
14
|
export const CLIENT_AT = 'operations/_client.ts';
|
|
13
15
|
export const DISPATCHING_AT = 'app/_generated/dispatching.ts';
|
|
14
16
|
export const COMPILED = 'app/_generated/compiled';
|