@gitroll/tacitt-cli 0.6.12 → 0.6.14
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/{agent-setup-B12VbvN_.mjs → agent-setup-CEPQfjBv.mjs} +2 -2
- package/dist/agent-setup-worker.mjs +5 -5
- package/dist/cli.mjs +10 -10
- package/dist/codex-title-worker.mjs +1 -1
- package/dist/configured-preview-worker.mjs +5 -5
- package/dist/configured-session-worker.mjs +5 -5
- package/dist/{frame-B3He21G8.mjs → frame-CRm99088.mjs} +1 -1
- package/dist/{heap-Blrat--4.mjs → heap-Bh9tySJp.mjs} +12 -7
- package/dist/inspection-worker.mjs +4 -4
- package/dist/{job-CBuIMTQ0.mjs → job-CsWKWcM4.mjs} +135 -36
- package/dist/{locate-D-ZaHpI0.mjs → locate-CP2t26j2.mjs} +449 -244
- package/dist/{model-DR9odhWP.mjs → model-ChHuVKoB.mjs} +1 -1
- package/dist/operation-executor.mjs +3 -3
- package/dist/preview-worker.mjs +1 -1
- package/dist/privacy-validator.mjs +1 -1
- package/dist/{query-BYDcNKy2.mjs → query-D28k3XOr.mjs} +6044 -5706
- package/dist/{run-DQ9xyKSt.mjs → run-CiJmV__5.mjs} +6 -6
- package/dist/{src-Do-qzuMn.mjs → src-B3il9x5F.mjs} +617 -545
- package/dist/{src-CKQlTA2Z.mjs → src-CWMrGXJK.mjs} +180 -30
- package/dist/{src-DeNJ8vOD.mjs → src-CmvEJj46.mjs} +1806 -1690
- package/dist/store-database-worker.mjs +1 -1
- package/dist/web/assets/index-XdWDOC5H.js +172 -0
- package/dist/web/index.html +1 -1
- package/package.json +1 -1
- package/skills/tacitt/INDEX.md +1 -1
- package/skills/tacitt/SKILL.md +5 -3
- package/skills/tacitt/references/INDEX.md +2 -2
- package/skills/tacitt/references/b-method.md +4 -2
- package/skills/tacitt/references/bootstrap.md +1 -1
- package/skills/tacitt/references/commands.md +23 -4
- package/skills/tacitt/references/journey.md +5 -3
- package/skills/tacitt/references/parallel-review.md +22 -9
- package/skills/tacitt/references/remote-workers.md +6 -2
- package/skills/tacitt/scripts/INDEX.md +5 -5
- package/skills/tacitt/scripts/answer.mjs +12 -1
- package/skills/tacitt/scripts/describe.mjs +3 -2
- package/skills/tacitt/scripts/journey-classification-tasks.mjs +2 -0
- package/skills/tacitt/scripts/journey-classification.mjs +1 -0
- package/skills/tacitt/scripts/journey-scan-timing.mjs +3 -2
- package/skills/tacitt/scripts/journey-state.d.mts +3 -0
- package/skills/tacitt/scripts/journey-state.mjs +8 -1
- package/skills/tacitt/scripts/journey.mjs +31 -1
- package/skills/tacitt/scripts/privacy-validator.mjs +160 -40
- package/skills/tacitt/scripts/review.d.mts +1 -0
- package/skills/tacitt/scripts/review.mjs +296 -35
- package/dist/web/assets/index-BgDdPL1c.js +0 -172
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { a as isRecord, i as errorCode, n as checkDiscoveryAbort, o as unresolvedMetadata, r as discoveryBounds, t as DiscoveryWarnings } from "./model-
|
|
4
|
-
import { c as previewLimits, d as checkOpenSource, f as checkSource, h as openSource, i as pageFits, l as previewSourceVersion, m as noSymlinks, p as fileSnapshot, r as previewHeapLimits, s as previewMessageSchema, u as createZstdFrameCheck } from "./run-
|
|
1
|
+
import { $n as retainedMainTextNodes, Cr as processingSite, Fn as walkNativeFields, Hn as parseNativeRecord, Jn as nativeField, Xn as nativeText, Yn as nativeItems, ar as defaultLimits, br as declaredVersion, hn as sourceSnapshotId, mn as observeSource, qn as nativeBoolean, yr as ProcessingError } from "./locate-CP2t26j2.mjs";
|
|
2
|
+
import { Hr as nativeAdapterVersions, it as reviewInventory, ji as gitMetadataBudgetBytes } from "./src-B3il9x5F.mjs";
|
|
3
|
+
import { a as isRecord, i as errorCode, n as checkDiscoveryAbort, o as unresolvedMetadata, r as discoveryBounds, t as DiscoveryWarnings } from "./model-ChHuVKoB.mjs";
|
|
4
|
+
import { c as previewLimits, d as checkOpenSource, f as checkSource, h as openSource, i as pageFits, l as previewSourceVersion, m as noSymlinks, p as fileSnapshot, r as previewHeapLimits, s as previewMessageSchema, u as createZstdFrameCheck } from "./run-CiJmV__5.mjs";
|
|
5
5
|
import { a as titleHintLimits, n as titleHeapLimits, o as titleInputSchema, r as decodeTitleError, s as titleReplySchema } from "./heap-1FYhGds4.mjs";
|
|
6
6
|
import { constants } from "node:fs";
|
|
7
|
-
import { lstat, open, opendir, readFile, readdir, realpath, stat } from "node:fs/promises";
|
|
7
|
+
import { access, constants as constants$1, lstat, open, opendir, readFile, readdir, realpath, stat } from "node:fs/promises";
|
|
8
8
|
import { execFile } from "node:child_process";
|
|
9
9
|
import { basename, dirname, isAbsolute, join, normalize, posix, relative, resolve, sep, win32 } from "node:path";
|
|
10
10
|
import { PassThrough, Readable } from "node:stream";
|
|
11
11
|
import { createHash, randomUUID } from "node:crypto";
|
|
12
12
|
import { homedir, platform, tmpdir } from "node:os";
|
|
13
13
|
import { pipeline } from "node:stream/promises";
|
|
14
|
-
import { constants as constants$
|
|
14
|
+
import { constants as constants$2, createZstdDecompress } from "node:zlib";
|
|
15
15
|
import { Worker } from "node:worker_threads";
|
|
16
16
|
import { setFlagsFromString } from "node:v8";
|
|
17
17
|
import { parse, quote } from "shell-quote";
|
|
@@ -4215,7 +4215,8 @@ function seedEnvironment(input) {
|
|
|
4215
4215
|
return env;
|
|
4216
4216
|
}
|
|
4217
4217
|
function gitCommands(env, limits, signal, budget) {
|
|
4218
|
-
|
|
4218
|
+
/** Runs one command within the limits; settles with its exit status and output. */
|
|
4219
|
+
const run = async (args, directory) => {
|
|
4219
4220
|
checkSeedAbort(signal);
|
|
4220
4221
|
if (budget.remaining < 1) throw new ProcessingError("PROCESSING_LIMIT");
|
|
4221
4222
|
return await new Promise((resolve, reject) => {
|
|
@@ -4239,15 +4240,158 @@ function gitCommands(env, limits, signal, budget) {
|
|
|
4239
4240
|
budget.remaining -= bytes;
|
|
4240
4241
|
if (signal.aborted) return reject(new ProcessingError("PROCESSING_CANCELED"));
|
|
4241
4242
|
if (budget.remaining < 0 || bytes > limits.maxCommandBytes || error?.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER" || error?.killed) return reject(new ProcessingError("PROCESSING_LIMIT"));
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
}
|
|
4243
|
+
resolve({
|
|
4244
|
+
error,
|
|
4245
|
+
stdout,
|
|
4246
|
+
stderr
|
|
4247
|
+
});
|
|
4248
4248
|
});
|
|
4249
4249
|
});
|
|
4250
4250
|
};
|
|
4251
|
+
const failed = (args, code) => new ProcessingError("PROCESSING_FAILED", gitExitSite(args[0], code));
|
|
4252
|
+
const command = async (args, directory = tmpdir(), allowMissing = false) => {
|
|
4253
|
+
const { error, stdout } = await run(args, directory);
|
|
4254
|
+
if (error !== null && !(allowMissing && error.code === 1)) throw failed(args, error.code);
|
|
4255
|
+
try {
|
|
4256
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(stdout);
|
|
4257
|
+
} catch {
|
|
4258
|
+
throw new ProcessingError("PROCESSING_FAILED");
|
|
4259
|
+
}
|
|
4260
|
+
};
|
|
4261
|
+
/**
|
|
4262
|
+
* True only when `cat-file -e` reports a well-formed object ID absent without any error
|
|
4263
|
+
* (exit 1, empty stderr) with lazy fetching off, and the object store proves it absent.
|
|
4264
|
+
* Git also answers exit 1 for an unreadable object directory, so an unproven absence
|
|
4265
|
+
* fails closed instead of skipping the ref.
|
|
4266
|
+
*/
|
|
4267
|
+
const objectMissing = async (objectId, directory) => {
|
|
4268
|
+
if (!objectIdPattern.test(objectId) || env["GIT_NO_LAZY_FETCH"] !== "1") throw new ProcessingError("PROCESSING_FAILED");
|
|
4269
|
+
const args = [
|
|
4270
|
+
"cat-file",
|
|
4271
|
+
"-e",
|
|
4272
|
+
"--end-of-options",
|
|
4273
|
+
objectId
|
|
4274
|
+
];
|
|
4275
|
+
const { error, stderr } = await run(args, directory);
|
|
4276
|
+
if (error === null) return false;
|
|
4277
|
+
if (error.code !== 1 || stderr.byteLength !== 0) throw failed(args, error.code);
|
|
4278
|
+
if (!await provablyAbsent(resolve(directory, (await command([
|
|
4279
|
+
"rev-parse",
|
|
4280
|
+
"--git-path",
|
|
4281
|
+
"objects"
|
|
4282
|
+
], directory)).trimEnd()), objectId)) throw failed(args, error.code);
|
|
4283
|
+
return true;
|
|
4284
|
+
};
|
|
4285
|
+
return Object.assign(command, { objectMissing });
|
|
4286
|
+
}
|
|
4287
|
+
/**
|
|
4288
|
+
* The local object store cannot hold `objectId`: no alternates, its loose path is reached
|
|
4289
|
+
* and absent (ENOENT, so every directory on the way is searchable), and every pack file
|
|
4290
|
+
* is readable, so Git's own pack lookup was complete.
|
|
4291
|
+
*/
|
|
4292
|
+
async function provablyAbsent(objects, objectId) {
|
|
4293
|
+
const absent = async (path) => {
|
|
4294
|
+
try {
|
|
4295
|
+
await lstat(path);
|
|
4296
|
+
return false;
|
|
4297
|
+
} catch (error) {
|
|
4298
|
+
return errorCode(error) === "ENOENT";
|
|
4299
|
+
}
|
|
4300
|
+
};
|
|
4301
|
+
if (!await absent(join(objects, "info", "alternates"))) return false;
|
|
4302
|
+
if (!await absent(join(objects, objectId.slice(0, 2), objectId.slice(2)))) return false;
|
|
4303
|
+
let packs;
|
|
4304
|
+
try {
|
|
4305
|
+
packs = await readdir(join(objects, "pack"));
|
|
4306
|
+
} catch (error) {
|
|
4307
|
+
return errorCode(error) === "ENOENT";
|
|
4308
|
+
}
|
|
4309
|
+
try {
|
|
4310
|
+
for (const pack of packs) await access(join(objects, "pack", pack), constants$1.R_OK);
|
|
4311
|
+
} catch {
|
|
4312
|
+
return false;
|
|
4313
|
+
}
|
|
4314
|
+
return true;
|
|
4315
|
+
}
|
|
4316
|
+
/** A full SHA-1 or SHA-256 object ID as `for-each-ref` and `rev-parse` print it. */
|
|
4317
|
+
const objectIdPattern = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/u;
|
|
4318
|
+
const gitSiteCommands = /* @__PURE__ */ new Set([
|
|
4319
|
+
"show-ref",
|
|
4320
|
+
"log",
|
|
4321
|
+
"config",
|
|
4322
|
+
"for-each-ref",
|
|
4323
|
+
"rev-parse",
|
|
4324
|
+
"cat-file"
|
|
4325
|
+
]);
|
|
4326
|
+
/** Only fixed, known command names and process exit statuses may reach safe diagnostics. */
|
|
4327
|
+
function gitExitSite(command, code) {
|
|
4328
|
+
if (!gitSiteCommands.has(command ?? "") || typeof code !== "number" || !Number.isInteger(code) || code < 1 || code > 255) return {};
|
|
4329
|
+
return { site: `git-${command}-exit-${code}` };
|
|
4330
|
+
}
|
|
4331
|
+
//#endregion
|
|
4332
|
+
//#region packages/harnesses/src/export/git/refs.ts
|
|
4333
|
+
/** `show-ref` or `log` exited 128, as a ref to a missing object makes them. */
|
|
4334
|
+
function missingObjectExit(error) {
|
|
4335
|
+
return error instanceof ProcessingError && error.code === "PROCESSING_FAILED" && /^git-(?:show-ref|log)-exit-128$/u.test(error.site ?? "");
|
|
4336
|
+
}
|
|
4337
|
+
/**
|
|
4338
|
+
* `show-ref --head`, or, when it exits 128 or `enumerate` is set, every ref with a present
|
|
4339
|
+
* tip (ADR 2026-11-15-skip-missing-object-refs). A 128 exit that no missing tip explains
|
|
4340
|
+
* still fails closed.
|
|
4341
|
+
*/
|
|
4342
|
+
async function readRefs(command, directory, enumerate = false) {
|
|
4343
|
+
if (enumerate) return await enumerateRefs(command, directory);
|
|
4344
|
+
try {
|
|
4345
|
+
return {
|
|
4346
|
+
text: await command(["show-ref", "--head"], directory, true),
|
|
4347
|
+
skipped: []
|
|
4348
|
+
};
|
|
4349
|
+
} catch (error) {
|
|
4350
|
+
if (!missingObjectExit(error)) throw error;
|
|
4351
|
+
const refs = await enumerateRefs(command, directory);
|
|
4352
|
+
if (!refs.skipped.length) throw error;
|
|
4353
|
+
return refs;
|
|
4354
|
+
}
|
|
4355
|
+
}
|
|
4356
|
+
/** Every author reachable from the refs that were not skipped, HEAD included. */
|
|
4357
|
+
async function readAuthors(command, directory, refs) {
|
|
4358
|
+
return await command([
|
|
4359
|
+
"log",
|
|
4360
|
+
...refs.skipped.map((name) => `--exclude=${name}`),
|
|
4361
|
+
"--all",
|
|
4362
|
+
"--no-mailmap",
|
|
4363
|
+
"--no-show-signature",
|
|
4364
|
+
"--format=%an",
|
|
4365
|
+
"-z"
|
|
4366
|
+
], directory);
|
|
4367
|
+
}
|
|
4368
|
+
/** `for-each-ref` lists a ref whose object is missing; `cat-file -e` decides each tip. */
|
|
4369
|
+
async function enumerateRefs(command, directory) {
|
|
4370
|
+
const head = await command([
|
|
4371
|
+
"rev-parse",
|
|
4372
|
+
"--verify",
|
|
4373
|
+
"--quiet",
|
|
4374
|
+
"HEAD"
|
|
4375
|
+
], directory, true);
|
|
4376
|
+
const listed = await command(["for-each-ref", "--format=%(objectname) %(refname)"], directory);
|
|
4377
|
+
const lines = [...head ? [`${head.trimEnd()} HEAD`] : [], ...listed.split("\n")];
|
|
4378
|
+
if (lines.pop() !== "") throw new ProcessingError("PROCESSING_FAILED");
|
|
4379
|
+
const refs = lines.map((line) => {
|
|
4380
|
+
const space = line.indexOf(" ");
|
|
4381
|
+
const id = line.slice(0, space);
|
|
4382
|
+
const name = line.slice(space + 1);
|
|
4383
|
+
if (space < 0 || !objectIdPattern.test(id) || !name) throw new ProcessingError("PROCESSING_FAILED");
|
|
4384
|
+
return {
|
|
4385
|
+
id,
|
|
4386
|
+
name
|
|
4387
|
+
};
|
|
4388
|
+
});
|
|
4389
|
+
const missing = /* @__PURE__ */ new Map();
|
|
4390
|
+
for (const { id } of refs) if (!missing.has(id)) missing.set(id, await command.objectMissing(id, directory));
|
|
4391
|
+
return {
|
|
4392
|
+
text: refs.filter(({ id }) => !missing.get(id)).map(({ id, name }) => `${id} ${name}\n`).join(""),
|
|
4393
|
+
skipped: refs.filter(({ id }) => missing.get(id)).map(({ name }) => name)
|
|
4394
|
+
};
|
|
4251
4395
|
}
|
|
4252
4396
|
//#endregion
|
|
4253
4397
|
//#region packages/harnesses/src/git/config.ts
|
|
@@ -4363,14 +4507,14 @@ async function selectedRepositories(roots, limits, signal, budget) {
|
|
|
4363
4507
|
}
|
|
4364
4508
|
//#endregion
|
|
4365
4509
|
//#region packages/harnesses/src/export/git/state.ts
|
|
4366
|
-
/** Pin local shallow boundaries
|
|
4367
|
-
async function localHistoryState(repository, refs, budget, signal) {
|
|
4510
|
+
/** Pin refs, local shallow boundaries and the skipped-ref count without requiring unfetched history. */
|
|
4511
|
+
async function localHistoryState(repository, refs, budget, signal, skipped = 0) {
|
|
4368
4512
|
checkSeedAbort(signal);
|
|
4369
4513
|
const shared = await gitText(join(repository.gitDirectory, "commondir"), 16384, budget);
|
|
4370
4514
|
const common = shared === null ? repository.gitDirectory : resolve(repository.gitDirectory, shared.trim());
|
|
4371
4515
|
const shallow = await gitText(join(common, "shallow"), budget.remaining, budget);
|
|
4372
4516
|
checkSeedAbort(signal);
|
|
4373
|
-
return createHash("sha256").update(`${Buffer.byteLength(refs)}:`).update(refs).update(shallow === null ? "absent" : `present:${shallow}`).digest("hex");
|
|
4517
|
+
return createHash("sha256").update(`${Buffer.byteLength(refs)}:`).update(refs).update(shallow === null ? "absent" : `present:${shallow}`).update(skipped ? `skipped:${skipped}` : "").digest("hex");
|
|
4374
4518
|
}
|
|
4375
4519
|
//#endregion
|
|
4376
4520
|
//#region packages/harnesses/src/export/git/index.ts
|
|
@@ -4411,19 +4555,24 @@ function createGitNameSeedProvider(options = {}) {
|
|
|
4411
4555
|
checkSeedAbort(signal);
|
|
4412
4556
|
const scoped = await readNameConfig(command, repository.directory, limits, budget, signal);
|
|
4413
4557
|
collect(scoped.names);
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4558
|
+
let refs = await readRefs(command, repository.directory);
|
|
4559
|
+
let authors;
|
|
4560
|
+
try {
|
|
4561
|
+
authors = await readAuthors(command, repository.directory, refs);
|
|
4562
|
+
} catch (error) {
|
|
4563
|
+
if (refs.skipped.length || !missingObjectExit(error)) throw error;
|
|
4564
|
+
refs = await readRefs(command, repository.directory, true);
|
|
4565
|
+
if (!refs.skipped.length) throw error;
|
|
4566
|
+
authors = await readAuthors(command, repository.directory, refs);
|
|
4567
|
+
}
|
|
4568
|
+
const enumerate = refs.skipped.length > 0;
|
|
4569
|
+
const before = await localHistoryState(repository, refs.text, budget, signal, refs.skipped.length);
|
|
4570
|
+
const afterRefs = await readRefs(command, repository.directory, enumerate);
|
|
4571
|
+
if (before !== await localHistoryState(repository, afterRefs.text, budget, signal, afterRefs.skipped.length)) throw new ProcessingError("PROCESSING_FAILED");
|
|
4424
4572
|
originals.set(repository.directory, {
|
|
4425
4573
|
history: before,
|
|
4426
|
-
config: scoped.fingerprint
|
|
4574
|
+
config: scoped.fingerprint,
|
|
4575
|
+
enumerate
|
|
4427
4576
|
});
|
|
4428
4577
|
collect(authors.split("\0"));
|
|
4429
4578
|
snapshots.push(Object.freeze({
|
|
@@ -4436,9 +4585,10 @@ function createGitNameSeedProvider(options = {}) {
|
|
|
4436
4585
|
}));
|
|
4437
4586
|
}
|
|
4438
4587
|
for (const repository of repositories) {
|
|
4439
|
-
const history = await localHistoryState(repository, await command(["show-ref", "--head"], repository.directory, true), budget, signal);
|
|
4440
|
-
const scoped = await readNameConfig(command, repository.directory, limits, budget, signal);
|
|
4441
4588
|
const original = originals.get(repository.directory);
|
|
4589
|
+
const refs = await readRefs(command, repository.directory, original?.enumerate);
|
|
4590
|
+
const history = await localHistoryState(repository, refs.text, budget, signal, refs.skipped.length);
|
|
4591
|
+
const scoped = await readNameConfig(command, repository.directory, limits, budget, signal);
|
|
4442
4592
|
if (original?.history !== history || original.config !== scoped.fingerprint) throw new ProcessingError("PROCESSING_FAILED");
|
|
4443
4593
|
}
|
|
4444
4594
|
if (config.fingerprint !== (await readNameConfig(command, void 0, limits, budget, signal, true)).fingerprint) throw new ProcessingError("PROCESSING_FAILED");
|
|
@@ -4682,7 +4832,7 @@ async function metadataStream(part, harness, options) {
|
|
|
4682
4832
|
});
|
|
4683
4833
|
const decoded = part.representation === "jsonl.zst" ? createZstdDecompress({
|
|
4684
4834
|
chunkSize: Math.min(discoveryBounds.chunkBytes, headLimit),
|
|
4685
|
-
params: { [constants$
|
|
4835
|
+
params: { [constants$2.ZSTD_d_windowLogMax]: previewLimits.zstdWindowLogMax }
|
|
4686
4836
|
}) : new PassThrough({ highWaterMark: chunkBytes });
|
|
4687
4837
|
let streamError;
|
|
4688
4838
|
const cancellation = new AbortController();
|