/** * Starts a real local live-index server with a fake in-memory index and * registers it exactly like the extension does (instance file + per-project * endpoint + merged manifest). Used by the integration smoke test. * * Prints the agent home as its first stdout line, then stays alive. */ const { startLocalServer } = require("../out/agent/localServer.js"); const { writeInstance, writeManifest } = require("../out/agent/instances.js"); const { writeEndpoint, writeEndpointForProject } = require("../out/agent/endpoint.js"); const { mkdirSync, writeFileSync } = require("node:fs"); const { join } = require("node:path"); const PROJECT = process.env.RA3_PROJECT || "D:/Mods/Alpha"; const OTHER = "D:/Mods/Beta"; // The agent home is passed in, so the caller knows it without reading stdout. const home = process.argv[2]; if (!home) { console.error("usage: serve-fake-index.cjs "); process.exit(2); } function def(type, id, file, line) { return { type, id, file, line, origin: "project", stream: "static" }; } const unitFile = `${PROJECT}/Data/AthenaCannon.xml`; const unit = def("GameObject", "AthenaCannon", unitFile, 2); const weapon = def("WeaponTemplate", "AthenaCannonWeapon", `${PROJECT}/Data/Weapon.xml`, 88); const index = { projectDir: PROJECT, sdkDir: "", complete: true, phase: "art", stale: false, assets: new Map([ ["GameObject", new Map([["athenacannon", [unit]]])], ["WeaponTemplate", new Map([["athenacannonweapon", [weapon]]])], ]), assetsById: new Map([ ["athenacannon", [unit]], ["athenacannonweapon", [weapon]], ]), defines: new Map([["d", [{ name: "D", value: "1", file: unitFile, line: 1, origin: "project" }]]]), files: new Map(), streams: [{ name: "static", entry: `${PROJECT}/Data/Mod.xml`, files: new Set([unitFile.toLowerCase().replace(/\\/g, "/")]) }], manifests: new Map(), sourceCandidates: [], diagnostics: [], references: new Map([ [`GameObject\u0000athenacannon\u0000${unitFile}\u00002`, [{ file: `${PROJECT}/Data/Other.xml`, line: 3, start: 1, end: 2, kind: "attr" }]], ]), recordsHashes: new Map(), stats: { projectDir: PROJECT, sdkDir: "", phase: "art", complete: true, indexedFiles: 2, parsedFiles: 2, shallowScannedFiles: 0, deferredArtFiles: 0, shallowCacheHits: 0, recordsCacheHits: 0, resolveCacheHits: 0, resolveCalls: 0, snapshotHits: 0, snapshotFallbacks: 0, candidatesMs: 0, walkMs: 0, artScanMs: 0, assetCount: 2, referenceCount: 1, defineCount: 1, manifestFiles: 0, manifestAssetCount: 0, streams: 1, sourceCandidates: 0, elapsedMs: 1, }, }; (async () => { mkdirSync(home, { recursive: true }); const handle = await startLocalServer({ getIndex: (projectDir) => (!projectDir || projectDir === PROJECT ? index : null), listProjects: () => [PROJECT, OTHER], loadFile: async () => null, }); const endpoint = { instanceId: "smoke-1", url: `http://127.0.0.1:${handle.port}`, token: handle.token, projectDir: PROJECT, projects: [PROJECT, OTHER], processId: process.pid, updatedAt: new Date().toISOString(), }; await writeEndpointForProject(PROJECT, { ...endpoint, projectDir: PROJECT }, home); await writeEndpoint(endpoint, home); await writeInstance(endpoint, home); await writeManifest([endpoint], home); // Signal readiness through a file so the caller never has to parse stdout. writeFileSync(join(home, "READY"), `${handle.port}\n`); // Stay alive until killed. setInterval(() => {}, 1 << 30); })();