11#!/usr/bin/env node
22
33import assert from "node:assert/strict" ;
4- import { spawn } from "node:child_process" ;
4+ import { spawn , spawnSync } from "node:child_process" ;
55import {
66 access ,
77 mkdir ,
@@ -81,13 +81,17 @@ async function directorySkill(root, entry, name, description) {
8181 return filePath ;
8282}
8383
84- async function loadPackage ( nodeModules , packageName ) {
84+ async function packageEntryPath ( nodeModules , packageName ) {
8585 const packageRoot = path . join ( nodeModules , ...packageName . split ( "/" ) ) ;
8686 const manifest = JSON . parse ( await readFile ( path . join ( packageRoot , "package.json" ) , "utf8" ) ) ;
8787 if ( packageName . startsWith ( "@deepseek-ai/dsh-" ) ) {
8888 assert . equal ( manifest . version , DSH_NATIVE_VERSION , `${ packageName } must remain pinned` ) ;
8989 }
90- return import ( pathToFileURL ( path . join ( packageRoot , manifest . main ?? "lib/index.js" ) ) ) ;
90+ return path . join ( packageRoot , manifest . main ?? "lib/index.js" ) ;
91+ }
92+
93+ async function loadPackage ( nodeModules , packageName ) {
94+ return import ( pathToFileURL ( await packageEntryPath ( nodeModules , packageName ) ) ) ;
9195}
9296
9397async function createFixture ( scratch ) {
@@ -100,8 +104,18 @@ async function createFixture(scratch) {
100104 const customTwo = path . join ( scratch , "custom-two" ) ;
101105 const bundled = path . join ( scratch , "bundled" ) ;
102106 const external = path . join ( scratch , "external targets" ) ;
107+ const budgetRepository = path . join ( scratch , "budget repo" ) ;
108+ const budgetCwd = path . join ( budgetRepository , "nested" ) ;
109+ const normalizationRepository = path . join ( scratch , "normalization repo" ) ;
110+ const normalizationCwd = path . join ( normalizationRepository , "workspace" ) ;
111+ const syntheticHome = path . join ( scratch , "synthetic home" ) ;
103112 await mkdir ( path . join ( repository , ".git" ) , { recursive : true } ) ;
104113 await mkdir ( cwd , { recursive : true } ) ;
114+ await mkdir ( path . join ( budgetRepository , ".git" ) , { recursive : true } ) ;
115+ await mkdir ( budgetCwd , { recursive : true } ) ;
116+ await mkdir ( path . join ( normalizationRepository , ".git" ) , { recursive : true } ) ;
117+ await mkdir ( normalizationCwd , { recursive : true } ) ;
118+ await mkdir ( syntheticHome , { recursive : true } ) ;
105119
106120 await directorySkill ( path . join ( repository , ".dsh" , "skills" ) , "alpha" , "alpha" , "project dsh" ) ;
107121 await write ( path . join ( repository , ".dsh" , "skills" , "flat.md" ) , skill ( "flat-skill" , "flat" ) ) ;
@@ -152,6 +166,8 @@ async function createFixture(scratch) {
152166 await write ( path . join ( workspace , "CLAUDE.md" ) , " SAME API INSTRUCTION \n" ) ;
153167 await write ( path . join ( workspace , "AGENTS.local.md" ) , "API LOCAL INSTRUCTION" ) ;
154168 await write ( path . join ( cwd , "AGENTS.md" ) , "🙂" . repeat ( 2_000 ) ) ;
169+ await write ( path . join ( budgetRepository , "AGENTS.md" ) , `ROOT${ " " . repeat ( 400 ) } ` ) ;
170+ await write ( path . join ( budgetCwd , "AGENTS.md" ) , `LEAF${ " " . repeat ( 400 ) } ` ) ;
155171
156172 return {
157173 repository,
@@ -164,9 +180,68 @@ async function createFixture(scratch) {
164180 bundled,
165181 external,
166182 symlinkCases,
183+ budgetRepository,
184+ budgetCwd,
185+ normalizationCwd,
186+ syntheticHome,
167187 } ;
168188}
169189
190+ async function probeHomeNormalization ( nodeModules , fixture ) {
191+ const nativeHomePath = await packageEntryPath ( nodeModules , "@deepseek-ai/dsh-home-paths" ) ;
192+ const cases = [
193+ { label : "blank environment" , envDshHome : "" } ,
194+ { label : "whitespace environment" , envDshHome : " " } ,
195+ { label : "forward-slash environment tilde" , envDshHome : "~/dsh-test" } ,
196+ { label : "backslash environment tilde" , envDshHome : "~\\dsh-test" } ,
197+ { label : "explicit backslash tilde" , envDshHome : "~/environment-home" , explicitDshHome : "~\\dsh-test" } ,
198+ { label : "explicit blank" , envDshHome : "~/environment-home" , explicitDshHome : "" } ,
199+ ] ;
200+ const script = [
201+ `const NativeHome = await import(${ JSON . stringify ( pathToFileURL ( nativeHomePath ) . href ) } );` ,
202+ `const BetterHarness = await import(${ JSON . stringify ( pathToFileURL ( AGENT_CUSTOMIZE_PATH ) . href ) } );` ,
203+ `const cases = ${ JSON . stringify ( cases ) } ;` ,
204+ `const baseOptions = ${ JSON . stringify ( {
205+ provider : "dsh" ,
206+ workspace : fixture . normalizationCwd ,
207+ cwd : fixture . normalizationCwd ,
208+ dshAgentsHome : path . join ( fixture . syntheticHome , ".agents" ) ,
209+ includeUserHome : false ,
210+ } ) } ;`,
211+ "const results = [];" ,
212+ "for (const current of cases) {" ,
213+ " process.env.DSH_HOME = current.envDshHome;" ,
214+ " const configured = Object.hasOwn(current, 'explicitDshHome') ? current.explicitDshHome : undefined;" ,
215+ " const native = NativeHome.resolveDshHome(configured, process.env);" ,
216+ " const options = { ...baseOptions };" ,
217+ " if (Object.hasOwn(current, 'explicitDshHome')) options.dshHome = current.explicitDshHome;" ,
218+ " const inventory = await BetterHarness.collectAgentCustomizeInventory(options);" ,
219+ " results.push({ label: current.label, native, betterHarness: inventory.dshHome });" ,
220+ "}" ,
221+ "process.stdout.write(JSON.stringify({ cwd: process.cwd(), results }));" ,
222+ ] . join ( "\n" ) ;
223+ const result = spawnSync ( process . execPath , [ "--input-type=module" , "--eval" , script ] , {
224+ cwd : fixture . normalizationCwd ,
225+ encoding : "utf8" ,
226+ env : {
227+ ...process . env ,
228+ HOME : fixture . syntheticHome ,
229+ USERPROFILE : fixture . syntheticHome ,
230+ } ,
231+ } ) ;
232+ assert . equal ( result . status , 0 , result . stderr ) ;
233+ const probe = JSON . parse ( result . stdout ) ;
234+ assert . deepEqual ( probe . results . map ( ( entry ) => entry . native ) , [
235+ path . join ( fixture . syntheticHome , ".dsh" ) ,
236+ path . join ( fixture . syntheticHome , ".dsh" ) ,
237+ path . join ( fixture . syntheticHome , "dsh-test" ) ,
238+ path . join ( fixture . syntheticHome , "dsh-test" ) ,
239+ path . join ( fixture . syntheticHome , "dsh-test" ) ,
240+ probe . cwd ,
241+ ] ) ;
242+ return probe ;
243+ }
244+
170245async function verifyNativeOwners ( nodeModules , fixture ) {
171246 const { Context } = await loadPackage ( nodeModules , "@deepseek-ai/cordis" ) ;
172247 const { default : SkillRegistry } = await loadPackage ( nodeModules , "@deepseek-ai/dsh-skill" ) ;
@@ -252,18 +327,34 @@ async function verifyNativeOwners(nodeModules, fixture) {
252327 assert . ok ( budgeted . omitted . length > 0 || budgeted . truncated . length > 0 ) ;
253328 assert . doesNotMatch ( budgeted . text , / � / u) ;
254329
330+ const whitespaceBudgeted = await Instructions . loadBaselineInstructions ( {
331+ cwd : fixture . budgetCwd ,
332+ maxSourceBytes : 1_048_576 ,
333+ maxBytes : 512 ,
334+ } ) ;
335+ assert . ok ( whitespaceBudgeted ) ;
336+ assert . equal ( Buffer . byteLength ( `ROOT${ " " . repeat ( 400 ) } ` , "utf8" ) , 404 ) ;
337+ assert . equal ( Buffer . byteLength ( `LEAF${ " " . repeat ( 400 ) } ` , "utf8" ) , 404 ) ;
338+ const whitespaceBudgetRules = [ "AGENTS.md" , path . join ( "nested" , "AGENTS.md" ) ] . filter ( ( displayPath ) => (
339+ whitespaceBudgeted . text . includes ( `Instructions from: ${ displayPath } ` )
340+ ) ) ;
341+ assert . deepEqual ( whitespaceBudgetRules , [ path . join ( "nested" , "AGENTS.md" ) ] ) ;
342+ assert . ok ( whitespaceBudgeted . omitted . length > 0 ) ;
343+ assert . ok ( whitespaceBudgeted . truncated . length > 0 ) ;
344+
255345 return {
256346 skillNames,
257347 instructionCandidates : discovered . map ( ( file ) => file . displayPath ) ,
258348 deduplicatedApiClaude : ! full . text . includes ( `Instructions from: ${ path . join ( "packages" , "api" , "CLAUDE.md" ) } ` ) ,
259349 sourceLimit : "verified" ,
260350 aggregateBudget : "verified" ,
351+ whitespaceBudgetRules,
261352 utf8 : "verified" ,
262353 symlinkCases : fixture . symlinkCases ,
263354 } ;
264355}
265356
266- async function compareBetterHarness ( fixture , native ) {
357+ async function compareBetterHarness ( fixture , native , homeNormalization ) {
267358 try {
268359 await access ( AGENT_CUSTOMIZE_PATH ) ;
269360 } catch {
@@ -326,6 +417,28 @@ async function compareBetterHarness(fixture, native) {
326417 assert . ok ( budgeted . diagnostics . instructionDecisions . some ( ( entry ) => (
327418 entry . reason === "budget-omitted" || entry . reason === "budget-truncated"
328419 ) ) ) ;
420+
421+ const whitespaceBudgeted = await collectAgentCustomizeInventory ( {
422+ provider : "dsh" ,
423+ workspace : fixture . budgetCwd ,
424+ cwd : fixture . budgetCwd ,
425+ maxBytes : 512 ,
426+ maxSourceBytes : 1_048_576 ,
427+ } ) ;
428+ assert . deepEqual (
429+ whitespaceBudgeted . manage . rules . map ( ( entry ) => entry . name ) ,
430+ native . whitespaceBudgetRules ,
431+ ) ;
432+ assert . ok ( whitespaceBudgeted . diagnostics . instructionDecisions . some ( ( entry ) => (
433+ entry . path === "AGENTS.md" && entry . reason === "budget-omitted"
434+ ) ) ) ;
435+ assert . ok ( whitespaceBudgeted . diagnostics . instructionDecisions . some ( ( entry ) => (
436+ entry . path === path . join ( "nested" , "AGENTS.md" ) && entry . reason === "budget-truncated"
437+ ) ) ) ;
438+ assert . doesNotMatch ( JSON . stringify ( whitespaceBudgeted ) , / R O O T | L E A F / u) ;
439+ for ( const entry of homeNormalization . results ) {
440+ assert . equal ( entry . betterHarness , entry . native , entry . label ) ;
441+ }
329442 assert . doesNotMatch ( JSON . stringify ( optedIn ) , / N A T I V E P R I V A T E S K I L L B O D Y | N A T I V E I N S T R U C T I O N | S A M E A P I I N S T R U C T I O N / u) ;
330443}
331444
@@ -345,16 +458,18 @@ try {
345458 scratch = await mkdtemp ( path . join ( os . tmpdir ( ) , "better-harness-dsh-assets-smoke-" ) ) ;
346459 const fixture = await createFixture ( scratch ) ;
347460 const native = await verifyNativeOwners ( installation , fixture ) ;
461+ const homeNormalization = await probeHomeNormalization ( installation , fixture ) ;
348462 process . stdout . write ( `${ JSON . stringify ( {
349463 phase : "native-dsh" ,
350464 status : "pass" ,
351465 dshVersion : DSH_NATIVE_VERSION ,
352466 sourceSha : DSH_NATIVE_SOURCE_SHA ,
353467 credentialUsed : false ,
354468 platform : process . platform ,
469+ homeNormalization : "verified" ,
355470 ...native ,
356471 } ) } \n`) ;
357- await compareBetterHarness ( fixture , native ) ;
472+ await compareBetterHarness ( fixture , native , homeNormalization ) ;
358473 process . stdout . write ( `${ JSON . stringify ( { phase : "better-harness-comparison" , status : "pass" } ) } \n` ) ;
359474} finally {
360475 if ( scratch ) await rm ( scratch , { recursive : true , force : true } ) ;
0 commit comments