// Select this ticket's hunks without altering concurrent worktree/index changes. import { spawnSync } from 'node:child_process' import { mkdtempSync, readFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' const paths=['CONTEXT.md','public/cockpit/models/pipes/README.md','tools/pipe-models/README.md', 'src/modules/cockpit/domain/pipeDiameterDisplay.js','src/modules/cockpit/domain/pipeModels.js','src/modules/cockpit/domain/pipeNetwork.js','src/modules/cockpit/domain/pipeVisual.js','src/modules/cockpit/services/cesiumPipeModels.js', '.scratch/cockpit-real-data-wayfinding/issues/32-32.md', ...['t32-adapter-behavior','t32-color-layer','t32-diameter-fill','t32-pipe-model-plan','t32-visibility-style','t32-network-level','t32-pipe-view-mode','t32-view-layer-flow','t32-visual-default','t32-cesium-bundle-loader','t32-use-cesium-bundle','t32-view-live-diagnosis'].map(n=>`.scratch/cockpit-real-data-wayfinding/verify/${n}.mjs`), '.scratch/cockpit-real-data-wayfinding/verify/artifacts/t32/view-mode-network-level-fix.md', '.scratch/cockpit-real-data-wayfinding/verify/artifacts/t32/view-mode-live-diagnosis.json'] const shared=['src/modules/cockpit/services/cesiumPipeLayer.js','src/modules/cockpit/services/mapService.js','src/modules/cockpit/components/MapInfoPanel.vue'] function git(args,{input,env=process.env}={}){const r=spawnSync('git',args,{input,env,encoding:'utf8'});if(r.status!==0)throw Error(r.stderr||r.stdout);return r.stdout} function once(text,a,b){if(text.split(a).length!==2)throw Error('Ambiguous anchor: '+a.slice(0,70));return text.replace(a,b)} const head=git(['rev-parse','HEAD']).trim(),other=git(['diff','--cached','--name-only']).trim().split('\n').filter(Boolean) if(other.some(p=>paths.includes(p)||shared.includes(p)))throw Error('Concurrent staged overlap; inspect first') const env={...process.env,GIT_INDEX_FILE:join(mkdtempSync(join(tmpdir(),'t32-level-index-')),'index')} git(['read-tree',head],{env});git(['add','--',...paths],{env}) for(const p of shared){ let s=git(['show',head+':'+p]).replace(/\r\n/g,'\n'),current=readFileSync(p,'utf8').replace(/\r\n/g,'\n') if(p.endsWith('cesiumPipeLayer.js')){ s=once(s,'const layerVersions = new WeakMap()','const layerVersions = new WeakMap()\nconst pipeViewModes = new WeakMap()') s=once(s,'颜色统一由行业/备注决定','颜色统一由行业/networkLevel决定') s=once(s,'// Pending/failed objects keep guides; ready pipes retain only distant guides and show close-up volume.','// Ground keeps guides at all distances; only ready pipeline-view models use distant guides.') s=once(s,'createCesiumPipeModels(viewer, { source, onChange: onModelChange })',"createCesiumPipeModels(viewer, { source, onChange: onModelChange, viewMode:pipeViewModes.get(viewer)||'ground' })") const start=current.indexOf('/** View state is retained'),end=current.indexOf('/** 引导态/退出驾驶舱',start) if(start<0||end