vouchington-tooling 0.12.3 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -6
- package/dist/agent-harness-config/types.d.mts +4 -2
- package/dist/agent-harness-config/types.mjs +2 -1
- package/dist/agent-harness-identity/index.d.mts +26 -0
- package/dist/agent-harness-identity/index.mjs +30 -0
- package/dist/index.d.mts +3 -1
- package/dist/index.mjs +2 -1
- package/dist/pnpm-install/install-operations.mjs +4 -3
- package/dist/pnpm-install/pending-builds.d.mts +1 -0
- package/dist/pnpm-install/pending-builds.mjs +54 -10
- package/dist/pnpm-install/pnpm-install-fake-pnpm.test-helpers.mjs +13 -8
- package/dist/pnpm-install/pnpm-install-fixture.test-helpers.mjs +2 -1
- package/dist/retrospective-transcript/index.mjs +3 -3
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -71,14 +71,13 @@ vouchington stage-review-payload optional|required <source> <destination>
|
|
|
71
71
|
For persistent `pnpm-install`, v5 metadata tracks structural inputs separately from the
|
|
72
72
|
`--install-scripts` policy. A warm scripts-enabled tree can therefore toggle
|
|
73
73
|
`true → false → true` without forced reconciliation; a tree first installed with scripts disabled
|
|
74
|
-
uses
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
the root lifecycle hook; every other residual ID remains a hard failure. An isolated native-binary
|
|
74
|
+
uses two script-suppressed verification installs followed by `pnpm rebuild --pending --recursive`.
|
|
75
|
+
Before rebuilding, duplicate pending IDs are collapsed. After rebuilding, IDs proven absent from
|
|
76
|
+
the current workspace and installed virtual-store lockfiles are reported and removed; live
|
|
77
|
+
dependency and workspace-importer IDs are retained. Any residual ID after the generic rebuild remains a reported hard failure. An isolated native-binary
|
|
79
78
|
mismatch uses one strict forced install only when structural provenance
|
|
80
79
|
matches, workspace links are valid, and pnpm records empty `ignoredBuilds` and `pendingBuilds` ledgers;
|
|
81
|
-
otherwise it retains the script-free
|
|
80
|
+
otherwise it retains the two script-free reconciliation passes. Native and workspace-link health
|
|
82
81
|
are verified before its metadata stamp is refreshed.
|
|
83
82
|
The command emits a structured non-secret provenance diagnostic identifying changed structural
|
|
84
83
|
categories, the last script policy, script capability, and native-binary health.
|
|
@@ -153,6 +152,10 @@ import {
|
|
|
153
152
|
checkHarnessConfig,
|
|
154
153
|
dumpHarnessPolicy,
|
|
155
154
|
} from 'vouchington-tooling/agent-harness-config'
|
|
155
|
+
import {
|
|
156
|
+
inspectHarnessEnvironment,
|
|
157
|
+
selectHarnessSession,
|
|
158
|
+
} from 'vouchington-tooling/agent-harness-identity'
|
|
156
159
|
import {
|
|
157
160
|
readVitestReportAttempts,
|
|
158
161
|
writeVitestBlobManifest,
|
|
@@ -247,6 +250,10 @@ classifier stays available in plan mode; its defined sandbox profile still requi
|
|
|
247
250
|
`unrestricted` disables the sandbox. Repo checks surface user-level trust or mode prerequisites
|
|
248
251
|
instead of claiming that repo files alone activate them.
|
|
249
252
|
|
|
253
|
+
`agent-harness-identity` inspects the four harness environment signals without choosing a winner.
|
|
254
|
+
Callers supply their own precedence to `selectHarnessSession`, keeping product-specific identity
|
|
255
|
+
policy out of this package.
|
|
256
|
+
|
|
250
257
|
`checkWorkspaceGatesPolicy` rejects tracked test assertions that hard-code the exact version of a
|
|
251
258
|
dependency declared by a non-fixture package manifest. Assert dependency membership or placement,
|
|
252
259
|
or derive a configuration or documentation package spec from that manifest instead.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { HARNESS_IDS } from '../agent-harness-identity/index.mts';
|
|
2
|
+
import type { HarnessId } from '../agent-harness-identity/index.mts';
|
|
3
|
+
export { HARNESS_IDS };
|
|
4
|
+
export type { HarnessId };
|
|
3
5
|
export type ApplyTarget = {
|
|
4
6
|
readonly kind: 'global';
|
|
5
7
|
} | {
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import { HARNESS_IDS } from '../agent-harness-identity/index.mjs';
|
|
2
|
+
export { HARNESS_IDS };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare const HARNESS_IDS: readonly ['claude', 'codex', 'grok', 'cursor'];
|
|
2
|
+
export type HarnessId = (typeof HARNESS_IDS)[number];
|
|
3
|
+
export interface HarnessEnvironment {
|
|
4
|
+
readonly claude: {
|
|
5
|
+
readonly compatMode: boolean;
|
|
6
|
+
readonly sessionId?: string;
|
|
7
|
+
};
|
|
8
|
+
readonly codex: {
|
|
9
|
+
readonly sessionId?: string;
|
|
10
|
+
};
|
|
11
|
+
readonly cursor: {
|
|
12
|
+
readonly agentMarker: boolean;
|
|
13
|
+
readonly sessionId?: string;
|
|
14
|
+
};
|
|
15
|
+
readonly grok: {
|
|
16
|
+
readonly agentMarker: boolean;
|
|
17
|
+
readonly hookEvent: boolean;
|
|
18
|
+
readonly sessionId?: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export interface HarnessSessionIdentity {
|
|
22
|
+
readonly harness: HarnessId;
|
|
23
|
+
readonly sessionId: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function inspectHarnessEnvironment(env?: NodeJS.ProcessEnv): HarnessEnvironment;
|
|
26
|
+
export declare function selectHarnessSession(environment: HarnessEnvironment, precedence: readonly HarnessId[]): HarnessSessionIdentity | undefined;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const HARNESS_IDS = ['claude', 'codex', 'grok', 'cursor'];
|
|
2
|
+
function session(value) {
|
|
3
|
+
return value ? { sessionId: value } : {};
|
|
4
|
+
}
|
|
5
|
+
export function inspectHarnessEnvironment(env = process.env) {
|
|
6
|
+
return {
|
|
7
|
+
claude: {
|
|
8
|
+
compatMode: env.CLAUDECODE === '1',
|
|
9
|
+
...session(env.CLAUDE_CODE_SESSION_ID),
|
|
10
|
+
},
|
|
11
|
+
codex: session(env.CODEX_THREAD_ID),
|
|
12
|
+
cursor: {
|
|
13
|
+
agentMarker: Boolean(env.CURSOR_AGENT),
|
|
14
|
+
...session(env.CURSOR_SESSION_ID),
|
|
15
|
+
},
|
|
16
|
+
grok: {
|
|
17
|
+
agentMarker: Boolean(env.GROK_AGENT),
|
|
18
|
+
hookEvent: Boolean(env.GROK_HOOK_EVENT),
|
|
19
|
+
...session(env.GROK_SESSION_ID),
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function selectHarnessSession(environment, precedence) {
|
|
24
|
+
for (const harness of precedence) {
|
|
25
|
+
const sessionId = environment[harness].sessionId;
|
|
26
|
+
if (sessionId)
|
|
27
|
+
return { harness, sessionId };
|
|
28
|
+
}
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { linkSkill, readSkillManifest } from './skill-discovery/index.mts';
|
|
2
2
|
export type { LinkSkillOptions, LinkSkillResult, SkillManifest, SkillManifestEntry, } from './skill-discovery/index.mts';
|
|
3
|
+
export { HARNESS_IDS, inspectHarnessEnvironment, selectHarnessSession, } from './agent-harness-identity/index.mts';
|
|
4
|
+
export type { HarnessEnvironment, HarnessSessionIdentity } from './agent-harness-identity/index.mts';
|
|
3
5
|
export { codexChildren, codexIdentity, computeTranscriptFacts, formatTranscriptFacts, formatUnavailable, resolveTranscriptFile, runRetrospectiveTranscript, } from './retrospective-transcript/index.mts';
|
|
4
6
|
export type { ResolveOptions, TokenTotals, TranscriptFacts, } from './retrospective-transcript/index.mts';
|
|
5
7
|
export { runRetrospectiveFacts } from './retrospective-facts/index.mts';
|
|
@@ -13,7 +15,7 @@ export type { EphemeralListenerOptions, RunnerPortPolicy } from './runner-port-p
|
|
|
13
15
|
export { extractAlterTableAddColumnLocations, extractCreateIndexMetadata, extractCreateTableMetadata, extractDefaultFunction, extractDropIndexMetadata, extractFuncCallArgColumnNames, extractMigrationConstraintMetadata, initSqlAst, lineOfUtf8ByteOffset, MissingSqlAstParserError, parseSql, } from './sql-ast/index.mts';
|
|
14
16
|
export type { ForeignKey, SqlCreateIndexMetadata, SqlCreateTableColumn, SqlCreateTableMetadata, SqlDropIndexMetadata, SqlIndexParam, SqlMigrationConstraintMetadata, } from './sql-ast/index.mts';
|
|
15
17
|
export { dollarQuoteEnd, lineOf, maskSqlQuotedText, readDollarQuoteDelimiter, readStringLiteral, splitSqlStatements, sqlFragments, stripSqlComments, } from './sql-scanner/index.mts';
|
|
16
|
-
export { applyHarnessConfig, checkHarnessConfig, dumpHarnessPolicy, planHarnessConfig, DEFAULT_EXTRA_WRITABLE_ROOTS,
|
|
18
|
+
export { applyHarnessConfig, checkHarnessConfig, dumpHarnessPolicy, planHarnessConfig, DEFAULT_EXTRA_WRITABLE_ROOTS, } from './agent-harness-config/index.mts';
|
|
17
19
|
export type { ApplyTarget, FilePlan, FileResult, HarnessApplyResult, HarnessCheckResult, HarnessConfigOptions, HarnessId, HarnessPlan, HarnessPolicyDump, JsonPatch, KeyDrift, TomlPatch, TomlValue, } from './agent-harness-config/index.mts';
|
|
18
20
|
export { auditCiJobRuntime, parseWorkflowNameMatch } from './gha-runtime-audit/index.mts';
|
|
19
21
|
export type { GhApiExecutor, RuntimeAuditOptions, RuntimeAuditResult, RuntimeAuditWorkflowFilter, RuntimeJobResult, RuntimeSample, } from './gha-runtime-audit/index.mts';
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable max-lines -- package entry point enumerates the supported public API. */
|
|
2
2
|
export { linkSkill, readSkillManifest } from './skill-discovery/index.mjs';
|
|
3
|
+
export { HARNESS_IDS, inspectHarnessEnvironment, selectHarnessSession, } from './agent-harness-identity/index.mjs';
|
|
3
4
|
export { codexChildren, codexIdentity, computeTranscriptFacts, formatTranscriptFacts, formatUnavailable, resolveTranscriptFile, runRetrospectiveTranscript, } from './retrospective-transcript/index.mjs';
|
|
4
5
|
export { runRetrospectiveFacts } from './retrospective-facts/index.mjs';
|
|
5
6
|
export { appendJournal, assertSessionId, cleanupSnapshotPartitions, partitionSnapshot, probeBlackboard, readJournal, resolveBlackboardConnection, } from './agent-blackboard/index.mjs';
|
|
@@ -7,7 +8,7 @@ export { buildSessionFrictionReport, classifyFrictionObservation, FRICTION_LOG_M
|
|
|
7
8
|
export { EphemeralListenerAttemptsExhaustedError, isRunnerReservedPort, listenOnRunnerUnreservedEphemeralPort, loadRunnerPortPolicy, runnerPortPolicy, validateRunnerPortPolicy, } from './runner-port-policy/index.mjs';
|
|
8
9
|
export { extractAlterTableAddColumnLocations, extractCreateIndexMetadata, extractCreateTableMetadata, extractDefaultFunction, extractDropIndexMetadata, extractFuncCallArgColumnNames, extractMigrationConstraintMetadata, initSqlAst, lineOfUtf8ByteOffset, MissingSqlAstParserError, parseSql, } from './sql-ast/index.mjs';
|
|
9
10
|
export { dollarQuoteEnd, lineOf, maskSqlQuotedText, readDollarQuoteDelimiter, readStringLiteral, splitSqlStatements, sqlFragments, stripSqlComments, } from './sql-scanner/index.mjs';
|
|
10
|
-
export { applyHarnessConfig, checkHarnessConfig, dumpHarnessPolicy, planHarnessConfig, DEFAULT_EXTRA_WRITABLE_ROOTS,
|
|
11
|
+
export { applyHarnessConfig, checkHarnessConfig, dumpHarnessPolicy, planHarnessConfig, DEFAULT_EXTRA_WRITABLE_ROOTS, } from './agent-harness-config/index.mjs';
|
|
11
12
|
export { auditCiJobRuntime, parseWorkflowNameMatch } from './gha-runtime-audit/index.mjs';
|
|
12
13
|
export { checkGhaWorkspacePolicy } from './gha-workspace-policy/index.mjs';
|
|
13
14
|
export { requireUpToDate } from './require-up-to-date/index.mjs';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { scheduler } from 'node:timers/promises';
|
|
2
2
|
import { runPnpm } from './exec.mjs';
|
|
3
3
|
import { nativeBinariesMatchRuntime, repairedNativeBinariesMatchRuntime } from './native-health.mjs';
|
|
4
|
-
import { buildLedgersAllowNativeRepair, deduplicatePendingBuilds, pendingBuilds, } from './pending-builds.mjs';
|
|
4
|
+
import { buildLedgersAllowNativeRepair, deduplicatePendingBuilds, pendingBuilds, pruneStalePendingBuilds, } from './pending-builds.mjs';
|
|
5
5
|
import { INSTALL_TERMINATION_FAILED } from './process.mjs';
|
|
6
6
|
import { formatReleaseAgeFailure, isReleaseAgeViolation } from './release-age.mjs';
|
|
7
7
|
import { findWorkspaceLinkMismatches, forcedInstallArgs, logWorkspaceLinkMismatches, } from './support.mjs';
|
|
@@ -60,8 +60,9 @@ export async function finalizePendingBuilds(options, runCapture, phase) {
|
|
|
60
60
|
failPendingBuildLedger(phase, deduplicated);
|
|
61
61
|
await install(['rebuild', '--pending', '--recursive'], options, 'pending scripts rebuild');
|
|
62
62
|
const after = await pendingBuilds();
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
const finalState = after.kind === 'pending' ? await pruneStalePendingBuilds() : after;
|
|
64
|
+
if (finalState.kind !== 'clear')
|
|
65
|
+
failPendingBuildLedger(phase, finalState);
|
|
65
66
|
}
|
|
66
67
|
await verifyInstallHealth(runCapture, phase);
|
|
67
68
|
return options.installScripts ? { kind: 'clear' } : before;
|
|
@@ -8,4 +8,5 @@ export type PendingBuildState = {
|
|
|
8
8
|
};
|
|
9
9
|
export declare function pendingBuilds(): Promise<PendingBuildState>;
|
|
10
10
|
export declare function deduplicatePendingBuilds(): Promise<PendingBuildState>;
|
|
11
|
+
export declare function pruneStalePendingBuilds(): Promise<PendingBuildState>;
|
|
11
12
|
export declare function buildLedgersAllowNativeRepair(): Promise<boolean>;
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
2
3
|
import path from 'node:path';
|
|
3
4
|
import { parse, stringify } from 'yaml';
|
|
4
5
|
const modulesPath = () => path.join(process.cwd(), 'node_modules', '.modules.yaml');
|
|
6
|
+
function isRecord(value) {
|
|
7
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
8
|
+
}
|
|
5
9
|
async function buildLedgers() {
|
|
6
10
|
try {
|
|
7
11
|
const value = parse(await readFile(modulesPath(), 'utf8'));
|
|
8
|
-
if (
|
|
12
|
+
if (!isRecord(value))
|
|
9
13
|
return undefined;
|
|
10
14
|
// oxlint-disable-next-line no-mistakes/ts-no-const-aliases -- validate the parsed YAML object before reading its fields
|
|
11
15
|
const record = value;
|
|
@@ -29,21 +33,61 @@ async function buildLedgers() {
|
|
|
29
33
|
export async function pendingBuilds() {
|
|
30
34
|
return (await buildLedgers())?.pendingBuilds ?? { kind: 'unknown' };
|
|
31
35
|
}
|
|
36
|
+
async function lockfileBuildIds(lockfilePath) {
|
|
37
|
+
try {
|
|
38
|
+
const lockfile = parse(await readFile(lockfilePath, 'utf8'));
|
|
39
|
+
if (!isRecord(lockfile) || !isRecord(lockfile.importers) || !isRecord(lockfile.packages))
|
|
40
|
+
return undefined;
|
|
41
|
+
return new Set([...Object.keys(lockfile.importers), ...Object.keys(lockfile.packages)]);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async function currentBuildIds(record) {
|
|
48
|
+
if (typeof record.virtualStoreDir !== 'string')
|
|
49
|
+
return undefined;
|
|
50
|
+
const [wanted, installed] = await Promise.all([
|
|
51
|
+
lockfileBuildIds(path.join(process.cwd(), 'pnpm-lock.yaml')),
|
|
52
|
+
lockfileBuildIds(path.resolve(path.dirname(modulesPath()), record.virtualStoreDir, 'lock.yaml')),
|
|
53
|
+
]);
|
|
54
|
+
if (wanted === undefined || installed === undefined)
|
|
55
|
+
return undefined;
|
|
56
|
+
return new Set([...wanted, ...installed]);
|
|
57
|
+
}
|
|
58
|
+
async function rewritePendingBuilds(record, originalLength, ids) {
|
|
59
|
+
if (ids.length === originalLength)
|
|
60
|
+
return { ids: ids.toSorted(), kind: 'pending' };
|
|
61
|
+
const temporary = `${modulesPath()}.${randomUUID()}.tmp`;
|
|
62
|
+
try {
|
|
63
|
+
await writeFile(temporary, stringify({ ...record, pendingBuilds: ids }), { flag: 'wx' });
|
|
64
|
+
await rename(temporary, modulesPath());
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
await rm(temporary, { force: true });
|
|
68
|
+
return { kind: 'unknown' };
|
|
69
|
+
}
|
|
70
|
+
return pendingBuilds();
|
|
71
|
+
}
|
|
32
72
|
export async function deduplicatePendingBuilds() {
|
|
33
73
|
const ledgers = await buildLedgers();
|
|
34
74
|
if (ledgers === undefined || ledgers.pendingBuilds.kind !== 'pending')
|
|
35
75
|
return ledgers?.pendingBuilds ?? { kind: 'unknown' };
|
|
36
76
|
// `buildLedgers` has already verified every pending entry is a string.
|
|
37
77
|
const unique = [...new Set(ledgers.record.pendingBuilds)];
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
78
|
+
return rewritePendingBuilds(ledgers.record, ledgers.pendingBuilds.ids.length, unique);
|
|
79
|
+
}
|
|
80
|
+
export async function pruneStalePendingBuilds() {
|
|
81
|
+
const ledgers = await buildLedgers();
|
|
82
|
+
if (ledgers === undefined || ledgers.pendingBuilds.kind !== 'pending')
|
|
83
|
+
return ledgers?.pendingBuilds ?? { kind: 'unknown' };
|
|
84
|
+
const current = await currentBuildIds(ledgers.record);
|
|
85
|
+
if (current === undefined)
|
|
44
86
|
return { kind: 'unknown' };
|
|
45
|
-
|
|
46
|
-
|
|
87
|
+
const stale = ledgers.pendingBuilds.ids.filter((id) => !current.has(id));
|
|
88
|
+
if (stale.length > 0)
|
|
89
|
+
console.warn(`pending-build-ledger-pruned-stale IDs: ${JSON.stringify(stale)}`);
|
|
90
|
+
return rewritePendingBuilds(ledgers.record, ledgers.pendingBuilds.ids.length, ledgers.pendingBuilds.ids.filter((id) => current.has(id)));
|
|
47
91
|
}
|
|
48
92
|
export async function buildLedgersAllowNativeRepair() {
|
|
49
93
|
const ledgers = await buildLedgers();
|
|
@@ -15,6 +15,11 @@ calls=0
|
|
|
15
15
|
if [ -f "$PNPM_CALLS" ]; then calls="$(cat "$PNPM_CALLS")"; fi
|
|
16
16
|
calls=$((calls + 1))
|
|
17
17
|
printf '%s' "$calls" > "$PNPM_CALLS"
|
|
18
|
+
write_modules() {
|
|
19
|
+
mkdir -p "$PNPM_NODE_MODULES/.pnpm"
|
|
20
|
+
cp pnpm-lock.yaml "$PNPM_NODE_MODULES/.pnpm/lock.yaml"
|
|
21
|
+
printf 'virtualStoreDir: .pnpm\npendingBuilds: [%s]\n' "$1" > "$PNPM_NODE_MODULES/.modules.yaml"
|
|
22
|
+
}
|
|
18
23
|
print_release_age_violation() {
|
|
19
24
|
printf '%s\\n' '✗ Lockfile failed supply-chain policy check (1 entries in 0.1s)'
|
|
20
25
|
printf '%s\\n' '[ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION] 1 lockfile entries failed verification:'
|
|
@@ -31,36 +36,36 @@ fi
|
|
|
31
36
|
if [ -n "\${PNPM_SLEEP_SECONDS:-}" ]; then sleep "$PNPM_SLEEP_SECONDS"; fi
|
|
32
37
|
if [ "\${1:-}" != rebuild ] && [ "\${PNPM_INVALID_PENDING_BUILDS:-0}" = 1 ]; then
|
|
33
38
|
mkdir -p "$PNPM_NODE_MODULES"
|
|
34
|
-
printf '
|
|
39
|
+
printf 'virtualStoreDir: .pnpm\npendingBuilds: invalid\n' > "$PNPM_NODE_MODULES/.modules.yaml"
|
|
35
40
|
elif [ "\${1:-}" != rebuild ] && [ -n "\${PNPM_PENDING_BUILDS:-}" ]; then
|
|
36
41
|
mkdir -p "$PNPM_NODE_MODULES"
|
|
37
|
-
|
|
42
|
+
write_modules "$PNPM_PENDING_BUILDS"
|
|
38
43
|
elif [ ! -f "$PNPM_NODE_MODULES/.modules.yaml" ]; then
|
|
39
44
|
mkdir -p "$PNPM_NODE_MODULES"
|
|
40
|
-
|
|
45
|
+
write_modules ''
|
|
41
46
|
fi
|
|
42
47
|
case " $* " in
|
|
43
48
|
*' rebuild --pending --workspace-root '*)
|
|
44
|
-
|
|
49
|
+
write_modules "\${PNPM_WORKSPACE_ROOT_REBUILD_PENDING_BUILDS:-}"
|
|
45
50
|
;;
|
|
46
51
|
*' rebuild '*)
|
|
47
52
|
if [ "\${PNPM_REPAIR_NATIVE_ON_REBUILD:-0}" = 1 ]; then
|
|
48
53
|
cp "$PNPM_NATIVE_REPLACEMENT" "$PNPM_NATIVE_ADDON"
|
|
49
54
|
fi
|
|
50
55
|
if [ "\${PNPM_REBUILD_INVALID_LEDGER:-0}" = 1 ]; then
|
|
51
|
-
printf '
|
|
56
|
+
printf 'virtualStoreDir: .pnpm\npendingBuilds: invalid\n' > "$PNPM_NODE_MODULES/.modules.yaml"
|
|
52
57
|
elif [ "\${PNPM_REBUILD_REQUIRES_DEDUPED:-0}" = 1 ] && sed -n 's/.*\\[\\(.*\\)\\].*/\\1/p' "$PNPM_NODE_MODULES/.modules.yaml" | tr ',' '\\n' | sed 's/^ *//; s/ *$//' | sort | uniq -d | grep -q .; then
|
|
53
58
|
cp "$PNPM_NODE_MODULES/.modules.yaml" "$PNPM_NODE_MODULES/.modules.yaml.rebuild-left-pending"
|
|
54
59
|
elif [ -n "\${PNPM_REBUILD_PENDING_BUILDS:-}" ]; then
|
|
55
|
-
|
|
60
|
+
write_modules "$PNPM_REBUILD_PENDING_BUILDS"
|
|
56
61
|
else
|
|
57
|
-
|
|
62
|
+
write_modules ''
|
|
58
63
|
fi
|
|
59
64
|
if [ "\${PNPM_REBUILD_BREAK_LINK:-0}" = 1 ]; then rm -f "$PNPM_DEPENDENCY_LINK"; fi
|
|
60
65
|
;;
|
|
61
66
|
*' --force '*)
|
|
62
67
|
if [ -z "\${PNPM_PENDING_BUILDS:-}" ]; then
|
|
63
|
-
|
|
68
|
+
write_modules ''
|
|
64
69
|
fi
|
|
65
70
|
if [ "\${PNPM_DELETE_NATIVE:-0}" = 1 ]; then
|
|
66
71
|
rm -f "$PNPM_NATIVE_ADDON"
|
|
@@ -18,10 +18,11 @@ export async function makeFixture() {
|
|
|
18
18
|
const pnpmBin = join(root, 'bin');
|
|
19
19
|
const pnpmLog = join(root, 'pnpm.log');
|
|
20
20
|
const summary = join(root, 'summary.md');
|
|
21
|
+
const lockfile = 'lockfileVersion: 9\nimporters:\n .: {}\n backend: {}\n packages/consumer: {}\n packages/dependency: {}\npackages:\n dependency: {}\n';
|
|
21
22
|
await Promise.all([
|
|
22
23
|
writeJson(join(root, 'package.json'), { name: 'fixture-root', private: true }),
|
|
23
24
|
writeFile(join(root, 'pnpm-workspace.yaml'), 'packages:\n - packages/*\nminimumReleaseAge: 2880\n'),
|
|
24
|
-
writeFile(join(root, 'pnpm-lock.yaml'),
|
|
25
|
+
writeFile(join(root, 'pnpm-lock.yaml'), lockfile),
|
|
25
26
|
writeJson(join(consumer, 'package.json'), {
|
|
26
27
|
name: '@fixture/consumer',
|
|
27
28
|
dependencies: { '@fixture/dependency': 'workspace:^' },
|
|
@@ -2,6 +2,7 @@ import { existsSync, globSync } from 'node:fs';
|
|
|
2
2
|
import { readFile } from 'node:fs/promises';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { basename, dirname, join } from 'node:path';
|
|
5
|
+
import { inspectHarnessEnvironment, selectHarnessSession, } from '../agent-harness-identity/index.mjs';
|
|
5
6
|
import { codexChildren, codexIdentity, computeCodex } from './codex.mjs';
|
|
6
7
|
import { segmentCodex } from './codex-segment.mjs';
|
|
7
8
|
import { computeClaude } from './claude.mjs';
|
|
@@ -28,9 +29,8 @@ export function resolveTranscriptFile(options) {
|
|
|
28
29
|
}
|
|
29
30
|
const env = options.env ?? process.env;
|
|
30
31
|
const sessionId = options.sessionId ??
|
|
31
|
-
['
|
|
32
|
-
|
|
33
|
-
.find(Boolean);
|
|
32
|
+
selectHarnessSession(inspectHarnessEnvironment(env), ['codex', 'claude', 'cursor', 'grok'])
|
|
33
|
+
?.sessionId;
|
|
34
34
|
if (!sessionId)
|
|
35
35
|
return {
|
|
36
36
|
error: 'no session id (pass --session-id or set CODEX_THREAD_ID, CLAUDE_CODE_SESSION_ID, CURSOR_SESSION_ID, or GROK_SESSION_ID)',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vouchington-tooling",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Vouchington CLI and extractable tooling libraries.",
|
|
5
5
|
"homepage": "https://github.com/vouchington/vouchington-tooling/tree/main/packages/vouchington-tooling#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -33,6 +33,11 @@
|
|
|
33
33
|
"import": "./dist/index.mjs",
|
|
34
34
|
"default": "./dist/index.mjs"
|
|
35
35
|
},
|
|
36
|
+
"./agent-harness-identity": {
|
|
37
|
+
"types": "./dist/agent-harness-identity/index.d.mts",
|
|
38
|
+
"import": "./dist/agent-harness-identity/index.mjs",
|
|
39
|
+
"default": "./dist/agent-harness-identity/index.mjs"
|
|
40
|
+
},
|
|
36
41
|
"./skill-discovery": {
|
|
37
42
|
"types": "./dist/skill-discovery/index.d.mts",
|
|
38
43
|
"import": "./dist/skill-discovery/index.mjs",
|