Merge remote-tracking branch 'origin/master' into worktree/acp-automation-protocol
# Conflicts: # packages/support/acp-snapshot/README.md
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
import { cp, mkdtemp, readFile, readdir, rm } from 'node:fs/promises'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { existsSync, realpathSync } from 'node:fs'
|
||||
import { createHash } from 'node:crypto'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { basename, dirname, join, delimiter } from 'node:path'
|
||||
@@ -115,6 +115,8 @@ export interface RunResult {
|
||||
sessionId?: string
|
||||
/** The generated cwd the session ran in (the bash workspace). */
|
||||
cwd: string
|
||||
/** Filesystem-resolved spellings of {@link cwd} that child processes may report. */
|
||||
cwdAliases: string[]
|
||||
/**
|
||||
* Every persisted session log harvested after the run, ordered primary-first:
|
||||
* the top-level (parent) session — the one with no `parentSession` — then each
|
||||
@@ -198,6 +200,7 @@ export function snapshotSpillRoot(
|
||||
*/
|
||||
export async function runScenario(input: InputScript, opts: RunOptions): Promise<RunResult> {
|
||||
const cwd = await mkdtemp(join(opts.workspaceParent ?? tmpdir(), 'acp-snap-cwd-'))
|
||||
const cwdAliases = [...new Set([realpathSync(cwd), realpathSync.native(cwd)])]
|
||||
const sessionsRoot = await mkdtemp(join(tmpdir(), 'acp-snap-sessions-'))
|
||||
// Fixed path length: spill-policy budgets the preview against the REAL path
|
||||
// before stdout normalization, so tmpdir() length differences churn expected outputs.
|
||||
@@ -294,6 +297,7 @@ export async function runScenario(input: InputScript, opts: RunOptions): Promise
|
||||
rawStdout: launched.rawStdout(),
|
||||
stderr: launched.stderr(),
|
||||
cwd,
|
||||
cwdAliases,
|
||||
...sessionId !== undefined ? { sessionId } : {},
|
||||
sessionLogs,
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@ export interface NormalizeContext {
|
||||
sessionIds: string[]
|
||||
/** The generated cwd the run used — replaced with `{{cwd}}`. */
|
||||
cwd: string
|
||||
/** Other filesystem spellings of the same cwd (for example Windows short and long paths). */
|
||||
cwdAliases?: readonly string[]
|
||||
}
|
||||
|
||||
/** How cwd-rooted path separators are represented after the cwd is tokenized. */
|
||||
@@ -59,9 +61,13 @@ export interface NormalizeOptions {
|
||||
/** Replace cwd, session ids, and any stray UUID with stable tokens in a string. */
|
||||
function scrubString(value: string, ctx: NormalizeContext, cwdPathMode: CwdPathMode): string {
|
||||
let out = value
|
||||
// cwd first (longest, most specific), then explicit session ids, then any
|
||||
// residual UUID (covers ids that appear in places we didn't enumerate).
|
||||
out = out.split(ctx.cwd).join(CWD)
|
||||
// Filesystem APIs can report one directory with several spellings. Replace
|
||||
// every known spelling longest-first so a shorter alias cannot corrupt a
|
||||
// longer one before it is tokenized.
|
||||
const cwdSpellings = [...new Set([ctx.cwd, ...ctx.cwdAliases ?? []])]
|
||||
.filter(spelling => spelling.length > 0)
|
||||
.sort((left, right) => right.length - left.length)
|
||||
for (const spelling of cwdSpellings) out = out.split(spelling).join(CWD)
|
||||
out = out.split(`/private${CWD}`).join(CWD)
|
||||
if (cwdPathMode === 'canonical') {
|
||||
// Restrict separator conversion to paths rooted at the cwd token. A global
|
||||
|
||||
@@ -632,6 +632,7 @@ export function defineAcpSnapshotSuite(options: SnapshotSuiteOptions): void {
|
||||
...result.sessionLogs.map(l => l.id),
|
||||
],
|
||||
cwd: result.cwd,
|
||||
cwdAliases: result.cwdAliases,
|
||||
}
|
||||
|
||||
// Record writes live model fixtures; keyless refresh writes every comparable replayed
|
||||
|
||||
Reference in New Issue
Block a user