From d5f484eb7e624d04d46a5c9bce178daecbc61a06 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov <7889985+andreybavt@users.noreply.github.com> Date: Tue, 12 May 2026 11:21:37 +0200 Subject: [PATCH] fix: standardize KTX environment variables --- .../orbit-relationship-verification/README.md | 2 +- .../memory-agent.service.ingest.test.ts | 24 ++++++++++++ .../src/memory/memory-agent.service.ts | 2 +- scripts/relationship-orbit-verification.mjs | 4 +- .../relationship-orbit-verification.test.mjs | 37 +++++++++++++++++++ 5 files changed, 65 insertions(+), 4 deletions(-) diff --git a/examples/orbit-relationship-verification/README.md b/examples/orbit-relationship-verification/README.md index 245411b6..126488a2 100644 --- a/examples/orbit-relationship-verification/README.md +++ b/examples/orbit-relationship-verification/README.md @@ -29,5 +29,5 @@ examples/orbit-relationship-verification/reports/orbit-verification.md Use a real local Orbit project by overriding the project directory: ```bash -KTX_ORBIT_PROJECT_DIR=/path/to/orbit-project pnpm run relationships:verify-orbit +KTX_PROJECT_DIR=/path/to/orbit-project pnpm run relationships:verify-orbit ``` diff --git a/packages/context/src/memory/memory-agent.service.ingest.test.ts b/packages/context/src/memory/memory-agent.service.ingest.test.ts index 710ba956..6375e494 100644 --- a/packages/context/src/memory/memory-agent.service.ingest.test.ts +++ b/packages/context/src/memory/memory-agent.service.ingest.test.ts @@ -37,6 +37,7 @@ interface BuiltMocks { agentRunner: any; slValidator: any; toolsetFactory: any; + logger: any; } const buildMocks = (overrides: Partial = {}): BuiltMocks => { @@ -131,6 +132,7 @@ const buildMocks = (overrides: Partial = {}): BuiltMocks => { getAllTools: vi.fn().mockReturnValue([]), }), }, + logger: { log: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() }, }; return { ...defaults, ...overrides }; @@ -179,6 +181,7 @@ const buildService = (mocks: BuiltMocks): MemoryAgentService => telemetry: { trackMemoryIngestion: mocks.eventTracker.trackEvent, }, + logger: mocks.logger, }); const baseInput = { @@ -238,6 +241,27 @@ describe('MemoryAgentService.ingest — session-branch orchestration', () => { expect(result.commitHash).toBe('cafebabe'); }); + it('logs prompt debug output when KTX_MEMORY_AGENT_DEBUG_PROMPTS is enabled', async () => { + const previousDebugPrompts = process.env.KTX_MEMORY_AGENT_DEBUG_PROMPTS; + const mocks = buildMocks(); + const svc = buildService(mocks); + + try { + process.env.KTX_MEMORY_AGENT_DEBUG_PROMPTS = '1'; + + await svc.ingest(baseInput); + + expect(mocks.logger.debug).toHaveBeenCalledWith(expect.stringContaining('[memory-agent prompt-debug] system=')); + expect(mocks.logger.debug).toHaveBeenCalledWith(expect.stringContaining('[memory-agent prompt-debug] user=')); + } finally { + if (previousDebugPrompts === undefined) { + delete process.env.KTX_MEMORY_AGENT_DEBUG_PROMPTS; + } else { + process.env.KTX_MEMORY_AGENT_DEBUG_PROMPTS = previousDebugPrompts; + } + } + }); + it('empty path: squash returns no touched paths → no enqueue, cleanup(empty), commitHash=null', async () => { const mocks = buildMocks(); mocks.gitService.squashMergeIntoMain.mockResolvedValue({ diff --git a/packages/context/src/memory/memory-agent.service.ts b/packages/context/src/memory/memory-agent.service.ts index fd1f0a6c..6f239053 100644 --- a/packages/context/src/memory/memory-agent.service.ts +++ b/packages/context/src/memory/memory-agent.service.ts @@ -192,7 +192,7 @@ export class MemoryAgentService { `[memory-agent] chat=${chatId} running (sourceType=${sourceType}, hasSL=${hasSL}, budget=${stepBudget}, model=${modelName})${signalsSuffix}${dialectSuffix}`, ); - if (process.env.MEMORY_AGENT_DEBUG_PROMPTS === '1') { + if (process.env.KTX_MEMORY_AGENT_DEBUG_PROMPTS === '1') { this.logger.debug(`[memory-agent prompt-debug] system=${systemPrompt}`); this.logger.debug(`[memory-agent prompt-debug] user=${prompt}`); } diff --git a/scripts/relationship-orbit-verification.mjs b/scripts/relationship-orbit-verification.mjs index 1c24a4e9..d1c97f56 100644 --- a/scripts/relationship-orbit-verification.mjs +++ b/scripts/relationship-orbit-verification.mjs @@ -62,7 +62,7 @@ function firstNonEmptyLine(...values) { function parseArgs(argv) { const options = { connectionId: process.env.KTX_ORBIT_CONNECTION_ID ?? 'orbit', - projectDir: process.env.KTX_ORBIT_PROJECT_DIR ?? defaultProjectDir, + projectDir: process.env.KTX_PROJECT_DIR ?? defaultProjectDir, reportPath: defaultReportPath, }; @@ -242,7 +242,7 @@ function orbitVerificationEnv(projectDir) { export async function runOrbitVerification(options = {}) { const connectionId = options.connectionId ?? process.env.KTX_ORBIT_CONNECTION_ID ?? 'orbit'; - const projectDir = options.projectDir ?? process.env.KTX_ORBIT_PROJECT_DIR ?? defaultProjectDir; + const projectDir = options.projectDir ?? process.env.KTX_PROJECT_DIR ?? defaultProjectDir; const reportPath = options.reportPath ?? defaultReportPath; const rootDir = options.rootDir ?? ktxRootDir; const runner = options.runWorkspaceKtx ?? runWorkspaceKtx; diff --git a/scripts/relationship-orbit-verification.test.mjs b/scripts/relationship-orbit-verification.test.mjs index c7cdaffc..017b2518 100644 --- a/scripts/relationship-orbit-verification.test.mjs +++ b/scripts/relationship-orbit-verification.test.mjs @@ -115,6 +115,43 @@ describe('relationship Orbit verification helper', () => { assert.match(writes[0].content, new RegExp(defaultProjectDir.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))); }); + it('uses KTX_PROJECT_DIR for the Orbit verification project override', async () => { + const previousProjectDir = process.env.KTX_PROJECT_DIR; + const calls = []; + + try { + process.env.KTX_PROJECT_DIR = '/tmp/orbit-project-from-env'; + + const result = await runOrbitVerification({ + reportPath: '/tmp/orbit-report.md', + now: () => new Date('2026-05-07T10:00:00.000Z'), + mkdir: async () => {}, + writeFile: async () => {}, + runWorkspaceKtx: async (argv, options) => { + calls.push(argv); + if (argv[2] === 'report') { + options.stdout.write(successReportJson()); + return 0; + } + options.stdout.write('KTX scan completed\nRun: scan-orbit-1\nConnection: orbit\n'); + return 0; + }, + }); + + assert.equal(result.projectDir, '/tmp/orbit-project-from-env'); + assert.deepEqual(calls, [ + ['dev', 'scan', 'orbit', '--enrich', '--project-dir', '/tmp/orbit-project-from-env'], + ['dev', 'scan', 'report', '--json', '--project-dir', '/tmp/orbit-project-from-env', 'scan-orbit-1'], + ]); + } finally { + if (previousProjectDir === undefined) { + delete process.env.KTX_PROJECT_DIR; + } else { + process.env.KTX_PROJECT_DIR = previousProjectDir; + } + } + }); + it('extracts the run id from human scan output', () => { assert.equal(extractRunId(`KTX scan completed\nStatus: done\nRun: scan-orbit-1\nConnection: orbit\n`), 'scan-orbit-1'); assert.equal(extractRunId('KTX scan completed without a run line\n'), null);