@decibelsystems/tools 2.1.4 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +160 -0
- package/README.md +1 -1
- package/dist/agentPresence.d.ts +80 -0
- package/dist/agentPresence.d.ts.map +1 -1
- package/dist/agentPresence.js +177 -0
- package/dist/agentPresence.js.map +1 -1
- package/dist/agentic/index.d.ts +18 -8
- package/dist/agentic/index.d.ts.map +1 -1
- package/dist/agentic/index.js +18 -144
- package/dist/agentic/index.js.map +1 -1
- package/dist/agentic/types.d.ts +106 -0
- package/dist/agentic/types.d.ts.map +1 -1
- package/dist/agentic/types.js +77 -1
- package/dist/agentic/types.js.map +1 -1
- package/dist/architectAdrs.d.ts +14 -2
- package/dist/architectAdrs.d.ts.map +1 -1
- package/dist/architectAdrs.js +9 -3
- package/dist/architectAdrs.js.map +1 -1
- package/dist/client/transports.d.ts.map +1 -1
- package/dist/client/transports.js +13 -3
- package/dist/client/transports.js.map +1 -1
- package/dist/daemon.d.ts +19 -0
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +181 -38
- package/dist/daemon.js.map +1 -1
- package/dist/daemonConfig.d.ts +30 -0
- package/dist/daemonConfig.d.ts.map +1 -1
- package/dist/daemonConfig.js +56 -9
- package/dist/daemonConfig.js.map +1 -1
- package/dist/decibelPaths.d.ts.map +1 -1
- package/dist/decibelPaths.js +39 -6
- package/dist/decibelPaths.js.map +1 -1
- package/dist/domain/issue.d.ts +77 -0
- package/dist/domain/issue.d.ts.map +1 -0
- package/dist/domain/issue.js +134 -0
- package/dist/domain/issue.js.map +1 -0
- package/dist/domain/issueCodec.d.ts +39 -0
- package/dist/domain/issueCodec.d.ts.map +1 -0
- package/dist/domain/issueCodec.js +298 -0
- package/dist/domain/issueCodec.js.map +1 -0
- package/dist/domain/issueRepository.d.ts +91 -0
- package/dist/domain/issueRepository.d.ts.map +1 -0
- package/dist/domain/issueRepository.js +257 -0
- package/dist/domain/issueRepository.js.map +1 -0
- package/dist/facades/definitions.d.ts +0 -1
- package/dist/facades/definitions.d.ts.map +1 -1
- package/dist/facades/definitions.js +94 -98
- package/dist/facades/definitions.js.map +1 -1
- package/dist/facades/index.d.ts +2 -1
- package/dist/facades/index.d.ts.map +1 -1
- package/dist/facades/index.js +1 -1
- package/dist/facades/index.js.map +1 -1
- package/dist/facades/types.d.ts +17 -0
- package/dist/facades/types.d.ts.map +1 -1
- package/dist/httpArgs.d.ts +11 -0
- package/dist/httpArgs.d.ts.map +1 -0
- package/dist/httpArgs.js +39 -0
- package/dist/httpArgs.js.map +1 -0
- package/dist/httpServer.d.ts +1 -12
- package/dist/httpServer.d.ts.map +1 -1
- package/dist/httpServer.js +173 -98
- package/dist/httpServer.js.map +1 -1
- package/dist/kernel.d.ts +55 -1
- package/dist/kernel.d.ts.map +1 -1
- package/dist/kernel.js +366 -31
- package/dist/kernel.js.map +1 -1
- package/dist/lib/agent-services/assumptions.d.ts.map +1 -1
- package/dist/lib/agent-services/assumptions.js +8 -2
- package/dist/lib/agent-services/assumptions.js.map +1 -1
- package/dist/lib/atomicWrite.d.ts +26 -0
- package/dist/lib/atomicWrite.d.ts.map +1 -0
- package/dist/lib/atomicWrite.js +73 -0
- package/dist/lib/atomicWrite.js.map +1 -0
- package/dist/lib/envelope.d.ts +31 -0
- package/dist/lib/envelope.d.ts.map +1 -0
- package/dist/lib/envelope.js +80 -0
- package/dist/lib/envelope.js.map +1 -0
- package/dist/lib/fileLock.d.ts +38 -0
- package/dist/lib/fileLock.d.ts.map +1 -0
- package/dist/lib/fileLock.js +124 -0
- package/dist/lib/fileLock.js.map +1 -0
- package/dist/lib/recordIdAllocator.d.ts +86 -0
- package/dist/lib/recordIdAllocator.d.ts.map +1 -0
- package/dist/lib/recordIdAllocator.js +161 -0
- package/dist/lib/recordIdAllocator.js.map +1 -0
- package/dist/license.js +3 -3
- package/dist/license.js.map +1 -1
- package/dist/projectRegistry.d.ts +65 -3
- package/dist/projectRegistry.d.ts.map +1 -1
- package/dist/projectRegistry.js +233 -33
- package/dist/projectRegistry.js.map +1 -1
- package/dist/runtime/circuitBreaker.d.ts +95 -0
- package/dist/runtime/circuitBreaker.d.ts.map +1 -0
- package/dist/runtime/circuitBreaker.js +178 -0
- package/dist/runtime/circuitBreaker.js.map +1 -0
- package/dist/runtime/ensureRuntime.d.ts +103 -0
- package/dist/runtime/ensureRuntime.d.ts.map +1 -0
- package/dist/runtime/ensureRuntime.js +281 -0
- package/dist/runtime/ensureRuntime.js.map +1 -0
- package/dist/runtime/extensions.d.ts +57 -0
- package/dist/runtime/extensions.d.ts.map +1 -0
- package/dist/runtime/extensions.js +216 -0
- package/dist/runtime/extensions.js.map +1 -0
- package/dist/runtime/localHttp.d.ts +24 -0
- package/dist/runtime/localHttp.d.ts.map +1 -0
- package/dist/runtime/localHttp.js +84 -0
- package/dist/runtime/localHttp.js.map +1 -0
- package/dist/runtime/projectResolution.d.ts +29 -0
- package/dist/runtime/projectResolution.d.ts.map +1 -0
- package/dist/runtime/projectResolution.js +67 -0
- package/dist/runtime/projectResolution.js.map +1 -0
- package/dist/runtime/protocol.d.ts +62 -0
- package/dist/runtime/protocol.d.ts.map +1 -0
- package/dist/runtime/protocol.js +74 -0
- package/dist/runtime/protocol.js.map +1 -0
- package/dist/sentinelIssues.d.ts +26 -2
- package/dist/sentinelIssues.d.ts.map +1 -1
- package/dist/sentinelIssues.js +163 -76
- package/dist/sentinelIssues.js.map +1 -1
- package/dist/server.js +65 -12
- package/dist/server.js.map +1 -1
- package/dist/setup.d.ts +83 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +445 -0
- package/dist/setup.js.map +1 -0
- package/dist/store/markdown.d.ts +14 -1
- package/dist/store/markdown.d.ts.map +1 -1
- package/dist/store/markdown.js +36 -3
- package/dist/store/markdown.js.map +1 -1
- package/dist/tools/agentic/index.d.ts.map +1 -1
- package/dist/tools/agentic/index.js +28 -2
- package/dist/tools/agentic/index.js.map +1 -1
- package/dist/tools/architect/index.d.ts.map +1 -1
- package/dist/tools/architect/index.js +7 -2
- package/dist/tools/architect/index.js.map +1 -1
- package/dist/tools/conductor/index.d.ts +9 -0
- package/dist/tools/conductor/index.d.ts.map +1 -0
- package/dist/tools/conductor/index.js +242 -0
- package/dist/tools/conductor/index.js.map +1 -0
- package/dist/tools/context.d.ts +10 -5
- package/dist/tools/context.d.ts.map +1 -1
- package/dist/tools/context.js +45 -18
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/coordinator/coordinator.d.ts.map +1 -1
- package/dist/tools/coordinator/coordinator.js +48 -19
- package/dist/tools/coordinator/coordinator.js.map +1 -1
- package/dist/tools/crit.d.ts +2 -1
- package/dist/tools/crit.d.ts.map +1 -1
- package/dist/tools/crit.js +19 -4
- package/dist/tools/crit.js.map +1 -1
- package/dist/tools/designer/index.d.ts.map +1 -1
- package/dist/tools/designer/index.js +4 -3
- package/dist/tools/designer/index.js.map +1 -1
- package/dist/tools/designer/lateral-tools.d.ts.map +1 -1
- package/dist/tools/designer/lateral-tools.js +4 -2
- package/dist/tools/designer/lateral-tools.js.map +1 -1
- package/dist/tools/designer.d.ts +2 -1
- package/dist/tools/designer.d.ts.map +1 -1
- package/dist/tools/designer.js +24 -12
- package/dist/tools/designer.js.map +1 -1
- package/dist/tools/dojo.d.ts +3 -2
- package/dist/tools/dojo.d.ts.map +1 -1
- package/dist/tools/dojo.js +64 -22
- package/dist/tools/dojo.js.map +1 -1
- package/dist/tools/dojoPolicy.js +1 -1
- package/dist/tools/dojoPolicy.js.map +1 -1
- package/dist/tools/friction.d.ts.map +1 -1
- package/dist/tools/friction.js +16 -6
- package/dist/tools/friction.js.map +1 -1
- package/dist/tools/guardian.d.ts +29 -7
- package/dist/tools/guardian.d.ts.map +1 -1
- package/dist/tools/guardian.js +90 -75
- package/dist/tools/guardian.js.map +1 -1
- package/dist/tools/hygiene/oracle-hygiene.d.ts.map +1 -1
- package/dist/tools/hygiene/oracle-hygiene.js +8 -2
- package/dist/tools/hygiene/oracle-hygiene.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +29 -18
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/learnings.d.ts +2 -1
- package/dist/tools/learnings.d.ts.map +1 -1
- package/dist/tools/learnings.js +31 -15
- package/dist/tools/learnings.js.map +1 -1
- package/dist/tools/oracle.d.ts.map +1 -1
- package/dist/tools/oracle.js +19 -6
- package/dist/tools/oracle.js.map +1 -1
- package/dist/tools/policy.d.ts +2 -1
- package/dist/tools/policy.d.ts.map +1 -1
- package/dist/tools/policy.js +28 -9
- package/dist/tools/policy.js.map +1 -1
- package/dist/tools/postoffice/index.d.ts +10 -0
- package/dist/tools/postoffice/index.d.ts.map +1 -0
- package/dist/tools/postoffice/index.js +218 -0
- package/dist/tools/postoffice/index.js.map +1 -0
- package/dist/tools/postoffice.d.ts +78 -0
- package/dist/tools/postoffice.d.ts.map +1 -0
- package/dist/tools/postoffice.js +199 -0
- package/dist/tools/postoffice.js.map +1 -0
- package/dist/tools/provenance.d.ts +7 -0
- package/dist/tools/provenance.d.ts.map +1 -1
- package/dist/tools/provenance.js +42 -16
- package/dist/tools/provenance.js.map +1 -1
- package/dist/tools/registry/index.d.ts.map +1 -1
- package/dist/tools/registry/index.js +41 -12
- package/dist/tools/registry/index.js.map +1 -1
- package/dist/tools/sentinel/index.d.ts +1 -0
- package/dist/tools/sentinel/index.d.ts.map +1 -1
- package/dist/tools/sentinel/index.js +88 -4
- package/dist/tools/sentinel/index.js.map +1 -1
- package/dist/tools/sentinel.d.ts +117 -1
- package/dist/tools/sentinel.d.ts.map +1 -1
- package/dist/tools/sentinel.js +761 -339
- package/dist/tools/sentinel.js.map +1 -1
- package/dist/tools/shared/index.d.ts +2 -1
- package/dist/tools/shared/index.d.ts.map +1 -1
- package/dist/tools/shared/index.js +2 -1
- package/dist/tools/shared/index.js.map +1 -1
- package/dist/tools/shared/response.d.ts +24 -0
- package/dist/tools/shared/response.d.ts.map +1 -1
- package/dist/tools/shared/response.js +61 -7
- package/dist/tools/shared/response.js.map +1 -1
- package/dist/tools/shared/storeRead.d.ts +153 -0
- package/dist/tools/shared/storeRead.d.ts.map +1 -0
- package/dist/tools/shared/storeRead.js +242 -0
- package/dist/tools/shared/storeRead.js.map +1 -0
- package/dist/tools/testSpec.d.ts +3 -2
- package/dist/tools/testSpec.d.ts.map +1 -1
- package/dist/tools/testSpec.js +51 -14
- package/dist/tools/testSpec.js.map +1 -1
- package/dist/tools/vector.d.ts +33 -1
- package/dist/tools/vector.d.ts.map +1 -1
- package/dist/tools/vector.js +31 -5
- package/dist/tools/vector.js.map +1 -1
- package/dist/tools/zoom/index.d.ts +15 -0
- package/dist/tools/zoom/index.d.ts.map +1 -0
- package/dist/tools/zoom/index.js +174 -0
- package/dist/tools/zoom/index.js.map +1 -0
- package/dist/tools/zoom.d.ts +234 -0
- package/dist/tools/zoom.d.ts.map +1 -0
- package/dist/tools/zoom.js +627 -0
- package/dist/tools/zoom.js.map +1 -0
- package/dist/transports/bridge.d.ts +1 -1
- package/dist/transports/bridge.d.ts.map +1 -1
- package/dist/transports/bridge.js +2 -0
- package/dist/transports/bridge.js.map +1 -1
- package/dist/transports/http.d.ts +1 -1
- package/dist/transports/http.d.ts.map +1 -1
- package/dist/transports/http.js +3 -1
- package/dist/transports/http.js.map +1 -1
- package/dist/transports/index.d.ts +1 -0
- package/dist/transports/index.d.ts.map +1 -1
- package/dist/transports/index.js +1 -0
- package/dist/transports/index.js.map +1 -1
- package/dist/transports/mcp.d.ts +1 -1
- package/dist/transports/mcp.d.ts.map +1 -1
- package/dist/transports/mcp.js +7 -3
- package/dist/transports/mcp.js.map +1 -1
- package/dist/transports/stdio.d.ts +1 -1
- package/dist/transports/stdio.d.ts.map +1 -1
- package/dist/transports/stdio.js +2 -0
- package/dist/transports/stdio.js.map +1 -1
- package/dist/transports/thinStdio.d.ts +22 -0
- package/dist/transports/thinStdio.d.ts.map +1 -0
- package/dist/transports/thinStdio.js +218 -0
- package/dist/transports/thinStdio.js.map +1 -0
- package/dist/transports/types.d.ts +8 -1
- package/dist/transports/types.d.ts.map +1 -1
- package/dist/types/agent-services.d.ts +7 -0
- package/dist/types/agent-services.d.ts.map +1 -1
- package/package.json +9 -4
- package/templates/com.decibel.daemon.plist +6 -1
- package/dist/tools/deck.d.ts +0 -11
- package/dist/tools/deck.d.ts.map +0 -1
- package/dist/tools/deck.js +0 -1656
- package/dist/tools/deck.js.map +0 -1
- package/dist/tools/mother.d.ts +0 -11
- package/dist/tools/mother.d.ts.map +0 -1
- package/dist/tools/mother.js +0 -503
- package/dist/tools/mother.js.map +0 -1
- package/dist/tools/registry.d.ts +0 -3
- package/dist/tools/registry.d.ts.map +0 -1
- package/dist/tools/registry.js +0 -189
- package/dist/tools/registry.js.map +0 -1
- package/dist/tools/senken.d.ts +0 -11
- package/dist/tools/senken.d.ts.map +0 -1
- package/dist/tools/senken.js +0 -482
- package/dist/tools/senken.js.map +0 -1
- package/dist/tools/terminal.d.ts +0 -17
- package/dist/tools/terminal.d.ts.map +0 -1
- package/dist/tools/terminal.js +0 -968
- package/dist/tools/terminal.js.map +0 -1
- package/dist/tools/toolsIndex.d.ts +0 -5
- package/dist/tools/toolsIndex.d.ts.map +0 -1
- package/dist/tools/toolsIndex.js +0 -37
- package/dist/tools/toolsIndex.js.map +0 -1
package/dist/httpServer.js
CHANGED
|
@@ -27,18 +27,21 @@
|
|
|
27
27
|
import { createServer } from 'http';
|
|
28
28
|
import { timingSafeEqual, randomBytes } from 'crypto';
|
|
29
29
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
30
|
-
import { readFileSync } from 'fs';
|
|
30
|
+
import { readFileSync, existsSync } from 'fs';
|
|
31
31
|
import { fileURLToPath } from 'url';
|
|
32
|
-
import { dirname, join } from 'path';
|
|
32
|
+
import { dirname, join, resolve } from 'path';
|
|
33
33
|
import { log } from './config.js';
|
|
34
34
|
import { writeLocalAgentSession } from './agentPresence.js';
|
|
35
35
|
import { drainCommands, setSessionToken, getSessionToken, dropSessionToken, ackOwnerOf, clearAckOwner, } from './agentInbox.js';
|
|
36
36
|
import { settleCommandFromAck, ORG_ID } from './agentCommands.js';
|
|
37
37
|
import { isSupabaseConfigured, getSupabaseServiceClient } from './lib/supabase.js';
|
|
38
38
|
import { shouldQueueForAgent, parseToolCall } from './httpQueueDetection.js';
|
|
39
|
+
import { getExtensionDiagnostics } from './kernel.js';
|
|
39
40
|
import { getLicenseValidator } from './license.js';
|
|
40
41
|
import { listProjects } from './projectRegistry.js';
|
|
41
42
|
import { setDaemonPort } from './daemon.js';
|
|
43
|
+
import { RUNTIME_PROTOCOL_VERSION } from './runtime/protocol.js';
|
|
44
|
+
import { wrapSuccess, wrapError, envelopeHttpStatus, } from './lib/envelope.js';
|
|
42
45
|
import { listEpics, listRepoIssues, isProjectResolutionError, } from './tools/sentinel.js';
|
|
43
46
|
import { voiceInboxAdd, } from './tools/voice.js';
|
|
44
47
|
import { generateImage, getImageStatus, meshyGenerate, getMeshyStatus, meshyDownload, tripoGenerate, getTripoStatus, tripoDownload, klingGenerateVideo, klingGenerateTextVideo, klingGenerateAvatar, getKlingStatus, listTasks, } from './tools/studio/index.js';
|
|
@@ -208,43 +211,6 @@ function formatUptime(ms) {
|
|
|
208
211
|
return `${minutes}m ${seconds % 60}s`;
|
|
209
212
|
return `${seconds}s`;
|
|
210
213
|
}
|
|
211
|
-
/**
|
|
212
|
-
* Wrap a successful result in status envelope
|
|
213
|
-
*/
|
|
214
|
-
function wrapSuccess(data) {
|
|
215
|
-
return { status: 'executed', ...data };
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Wrap an error in status envelope
|
|
219
|
-
*/
|
|
220
|
-
/**
|
|
221
|
-
* Sanitize error messages to prevent information disclosure.
|
|
222
|
-
* Removes absolute file paths and replaces with generic placeholders.
|
|
223
|
-
* Preserves URLs and relative paths.
|
|
224
|
-
*/
|
|
225
|
-
function sanitizeErrorMessage(message) {
|
|
226
|
-
let sanitized = message;
|
|
227
|
-
// Step 1: Preserve paths containing .decibel (keep the .decibel part, strip prefix)
|
|
228
|
-
// /home/user/project/.decibel/foo -> .decibel/foo
|
|
229
|
-
sanitized = sanitized.replace(/(?:\/[^\s:'"]+)?\/\.decibel\//g, '.decibel/');
|
|
230
|
-
sanitized = sanitized.replace(/(?:[A-Z]:\\[^\s:'"]+)?\\\.decibel\\/gi, '.decibel\\');
|
|
231
|
-
// Step 2: Remove absolute Unix paths (must start with / and have at least one more /)
|
|
232
|
-
// But exclude URLs (http://, https://, file://)
|
|
233
|
-
// Match: /home/user/file.txt, /var/log/app.log
|
|
234
|
-
// Don't match: http://example.com, ./relative/path
|
|
235
|
-
sanitized = sanitized.replace(/(?<!:)\/(?:home|Users|var|tmp|opt|usr|etc|media|mnt)\/[^\s:'"]+/g, '[path]');
|
|
236
|
-
// Step 3: Remove Windows absolute paths (C:\, D:\, etc.)
|
|
237
|
-
sanitized = sanitized.replace(/[A-Z]:\\[^\s:'"]+/gi, '[path]');
|
|
238
|
-
// Step 4: Sanitize any remaining usernames in paths that weren't caught
|
|
239
|
-
sanitized = sanitized.replace(/\/home\/[^\/\s]+\//g, '/home/[user]/');
|
|
240
|
-
sanitized = sanitized.replace(/\/Users\/[^\/\s]+\//g, '/Users/[user]/');
|
|
241
|
-
sanitized = sanitized.replace(/C:\\Users\\[^\\]+\\/gi, 'C:\\Users\\[user]\\');
|
|
242
|
-
return sanitized;
|
|
243
|
-
}
|
|
244
|
-
function wrapError(error, code) {
|
|
245
|
-
const sanitized = sanitizeErrorMessage(error);
|
|
246
|
-
return { status: 'error', error: sanitized, ...(code && { code }) };
|
|
247
|
-
}
|
|
248
214
|
/**
|
|
249
215
|
* Send JSON response with status envelope
|
|
250
216
|
*/
|
|
@@ -346,20 +312,30 @@ async function executeTool(tool, args, req, tierOverride) {
|
|
|
346
312
|
requestId: req.headers['x-request-id'],
|
|
347
313
|
tier: tierOverride,
|
|
348
314
|
allowedFacades,
|
|
349
|
-
|
|
315
|
+
transport: 'http',
|
|
316
|
+
} : tierOverride ? { tier: tierOverride, transport: 'http' } : { transport: 'http' };
|
|
350
317
|
const toolResult = await kernel.dispatch(tool, args, context);
|
|
351
318
|
const text = toolResult.content[0]?.text;
|
|
352
319
|
if (toolResult.isError) {
|
|
353
320
|
return wrapError(text || 'Tool execution failed', 'TOOL_ERROR');
|
|
354
321
|
}
|
|
355
|
-
// Parse
|
|
322
|
+
// Parse the tool's payload, or carry it as prose when it isn't JSON.
|
|
323
|
+
//
|
|
324
|
+
// The prose branch is legitimate — some tools return markdown — but it used
|
|
325
|
+
// to be indistinguishable from a data response that failed to parse. A
|
|
326
|
+
// caller expecting `events` got an object with no `events` key, `ok: true`,
|
|
327
|
+
// and no indication that anything unusual happened. That is how a
|
|
328
|
+
// concatenated feedback prompt (fixed in tools/shared/response.ts) turned
|
|
329
|
+
// one call in fifteen into a silent empty result for every HTTP consumer.
|
|
330
|
+
// `payload_format` makes the two cases tellable apart.
|
|
356
331
|
let result;
|
|
357
332
|
if (text) {
|
|
358
333
|
try {
|
|
359
334
|
result = JSON.parse(text);
|
|
360
335
|
}
|
|
361
336
|
catch {
|
|
362
|
-
|
|
337
|
+
log(`HTTP: tool ${tool} returned non-JSON text (${text.length} bytes) — carrying it as prose`);
|
|
338
|
+
result = { message: text, payload_format: 'text' };
|
|
363
339
|
}
|
|
364
340
|
}
|
|
365
341
|
else {
|
|
@@ -406,6 +382,7 @@ async function queueForAgent(facade, action, args, agentId, projectId) {
|
|
|
406
382
|
}
|
|
407
383
|
return {
|
|
408
384
|
status: 'queued',
|
|
385
|
+
ok: true,
|
|
409
386
|
queue_id: data.id,
|
|
410
387
|
message: 'Queued for local sync. Use agentic queue_status to check result.',
|
|
411
388
|
};
|
|
@@ -424,7 +401,7 @@ function getAvailableTools() {
|
|
|
424
401
|
* Get tools in OpenAI function calling format (facade-based)
|
|
425
402
|
*/
|
|
426
403
|
function getOpenAITools() {
|
|
427
|
-
return kernel.getMcpToolDefinitions('full').map(def => ({
|
|
404
|
+
return kernel.getMcpToolDefinitions('full', { transport: 'http' }).map(def => ({
|
|
428
405
|
type: 'function',
|
|
429
406
|
function: {
|
|
430
407
|
name: def.name,
|
|
@@ -630,6 +607,10 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
630
607
|
status: 'ok',
|
|
631
608
|
version: PKG.version,
|
|
632
609
|
api_version: 'v1',
|
|
610
|
+
// Wire-contract version, negotiated by ensureRuntime(). Distinct from
|
|
611
|
+
// `version` — a long-lived daemon can outlive the clients connecting to
|
|
612
|
+
// it, and most releases do not change the contract. See runtime/protocol.ts.
|
|
613
|
+
protocol_version: RUNTIME_PROTOCOL_VERSION,
|
|
633
614
|
uptime_ms: uptimeMs,
|
|
634
615
|
uptime_human: formatUptime(uptimeMs),
|
|
635
616
|
pid: process.pid,
|
|
@@ -642,6 +623,17 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
642
623
|
pro: licenseTier !== 'core',
|
|
643
624
|
license_tier: licenseTier,
|
|
644
625
|
supabase_configured: isSupabaseConfigured(),
|
|
626
|
+
// Facades whose dependency is failing. `{}` is the healthy case — a
|
|
627
|
+
// non-empty object means calls to those facades are being refused fast
|
|
628
|
+
// rather than left to time out. See runtime/circuitBreaker.ts.
|
|
629
|
+
circuits: kernel.circuitSnapshot(),
|
|
630
|
+
// Private facades loaded from the allowlist, and every entry refused.
|
|
631
|
+
// Reported because the alternative is silence: an extension that failed
|
|
632
|
+
// to load looks exactly like one that was never configured, and this
|
|
633
|
+
// daemon has already shipped one bug of that shape — a broken voice
|
|
634
|
+
// inbox that read as "0 messages" for five hours. See
|
|
635
|
+
// runtime/extensions.ts.
|
|
636
|
+
extensions: getExtensionDiagnostics(),
|
|
645
637
|
}));
|
|
646
638
|
return;
|
|
647
639
|
}
|
|
@@ -785,6 +777,23 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
785
777
|
// Simple REST Endpoints (for external AI agents)
|
|
786
778
|
// ========================================================================
|
|
787
779
|
// GET /tools - List available tools
|
|
780
|
+
// MCP tool definitions, verbatim — the shape a `tools/list` response needs.
|
|
781
|
+
//
|
|
782
|
+
// This is what lets a stdio client stop building its own kernel. /tools
|
|
783
|
+
// above is a human/OpenAI-shaped summary; this one is the exact array the
|
|
784
|
+
// MCP handler returns, so a thin adapter can serve tools/list by forwarding
|
|
785
|
+
// it rather than loading 195 tool modules to produce the same bytes.
|
|
786
|
+
if (path === '/mcp/tools' && req.method === 'GET') {
|
|
787
|
+
const tierParam = url.searchParams.get('tier');
|
|
788
|
+
const tier = (tierParam === 'compact' || tierParam === 'micro' ? tierParam : 'full');
|
|
789
|
+
sendJson(res, 200, wrapSuccess({
|
|
790
|
+
version: PKG.version,
|
|
791
|
+
protocol_version: RUNTIME_PROTOCOL_VERSION,
|
|
792
|
+
tier,
|
|
793
|
+
tools: kernel.getMcpToolDefinitions(tier, { transport: 'http' }),
|
|
794
|
+
}));
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
788
797
|
if (path === '/tools' && req.method === 'GET') {
|
|
789
798
|
sendJson(res, 200, wrapSuccess({
|
|
790
799
|
version: PKG.version,
|
|
@@ -1046,6 +1055,80 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1046
1055
|
res.on('error', cleanup);
|
|
1047
1056
|
return;
|
|
1048
1057
|
}
|
|
1058
|
+
// GET /conductor/stream — SSE live-tail of the conductor trace ledger (C3).
|
|
1059
|
+
// Pure live-from-now: history is conductor.trace's job. Optional ?session_id / ?project_id filter.
|
|
1060
|
+
if (path === '/conductor/stream' && req.method === 'GET') {
|
|
1061
|
+
const filterSession = url.searchParams.get('session_id');
|
|
1062
|
+
const filterProject = url.searchParams.get('project_id');
|
|
1063
|
+
// mirrors conductor/index.ts ledgerPath() — same file the runs append to
|
|
1064
|
+
const lp = process.env.CONDUCTOR_LEDGER
|
|
1065
|
+
|| join(process.env.CONDUCTOR_DIR || resolve(process.cwd(), '../decibel-orchestrator'), '.decibel/conductor/trace.jsonl');
|
|
1066
|
+
res.writeHead(200, {
|
|
1067
|
+
'Content-Type': 'text/event-stream',
|
|
1068
|
+
'Cache-Control': 'no-cache',
|
|
1069
|
+
'Connection': 'keep-alive',
|
|
1070
|
+
});
|
|
1071
|
+
res.write(': connected\n\n');
|
|
1072
|
+
let offset = 0;
|
|
1073
|
+
try {
|
|
1074
|
+
offset = existsSync(lp) ? readFileSync(lp, 'utf8').length : 0;
|
|
1075
|
+
}
|
|
1076
|
+
catch {
|
|
1077
|
+
offset = 0;
|
|
1078
|
+
}
|
|
1079
|
+
let buf = '';
|
|
1080
|
+
// ponytail: re-reads the whole JSONL per poll — fine at trace sizes; switch to
|
|
1081
|
+
// fd offset reads if the ledger grows large.
|
|
1082
|
+
const poll = setInterval(() => {
|
|
1083
|
+
if (res.writableEnded)
|
|
1084
|
+
return;
|
|
1085
|
+
let content = '';
|
|
1086
|
+
try {
|
|
1087
|
+
content = existsSync(lp) ? readFileSync(lp, 'utf8') : '';
|
|
1088
|
+
}
|
|
1089
|
+
catch {
|
|
1090
|
+
return;
|
|
1091
|
+
}
|
|
1092
|
+
if (content.length < offset) {
|
|
1093
|
+
offset = 0;
|
|
1094
|
+
buf = '';
|
|
1095
|
+
} // rotated/truncated
|
|
1096
|
+
if (content.length <= offset)
|
|
1097
|
+
return;
|
|
1098
|
+
buf += content.slice(offset);
|
|
1099
|
+
offset = content.length;
|
|
1100
|
+
let nl;
|
|
1101
|
+
while ((nl = buf.indexOf('\n')) >= 0) {
|
|
1102
|
+
const line = buf.slice(0, nl);
|
|
1103
|
+
buf = buf.slice(nl + 1);
|
|
1104
|
+
if (!line.trim())
|
|
1105
|
+
continue;
|
|
1106
|
+
let evt;
|
|
1107
|
+
try {
|
|
1108
|
+
evt = JSON.parse(line);
|
|
1109
|
+
}
|
|
1110
|
+
catch {
|
|
1111
|
+
continue;
|
|
1112
|
+
}
|
|
1113
|
+
if (filterSession && evt.request_id !== filterSession)
|
|
1114
|
+
continue;
|
|
1115
|
+
if (filterProject && evt.project_id !== filterProject)
|
|
1116
|
+
continue;
|
|
1117
|
+
if (!res.writableEnded)
|
|
1118
|
+
res.write(`data: ${JSON.stringify(evt)}\n\n`);
|
|
1119
|
+
}
|
|
1120
|
+
}, 300);
|
|
1121
|
+
activeSseConnections.add(res);
|
|
1122
|
+
log(`HTTP: /conductor/stream opened (${activeSseConnections.size} SSE connections)`);
|
|
1123
|
+
const cleanup = () => {
|
|
1124
|
+
clearInterval(poll);
|
|
1125
|
+
activeSseConnections.delete(res);
|
|
1126
|
+
log(`HTTP: /conductor/stream closed (${activeSseConnections.size} SSE connections)`);
|
|
1127
|
+
};
|
|
1128
|
+
res.on('close', cleanup);
|
|
1129
|
+
res.on('error', cleanup);
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1049
1132
|
// GET /facades - Facade registry for agent bootstrap
|
|
1050
1133
|
if (path === '/facades' && req.method === 'GET') {
|
|
1051
1134
|
const tier = (url.searchParams.get('tier') || 'full');
|
|
@@ -1077,7 +1160,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1077
1160
|
const tier = await resolveTier(req, configLicenseKey);
|
|
1078
1161
|
log(`HTTP: /call tool=${tool} tier=${tier}`);
|
|
1079
1162
|
const result = await executeTool(tool, args, req, tier);
|
|
1080
|
-
sendJson(res, result
|
|
1163
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1081
1164
|
}
|
|
1082
1165
|
catch (error) {
|
|
1083
1166
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1117,10 +1200,30 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1117
1200
|
requestId: req.headers['x-request-id'] || bodyContext.requestId,
|
|
1118
1201
|
allowedFacades: bodyContext.allowedFacades,
|
|
1119
1202
|
tier,
|
|
1203
|
+
// Set here, never read from the request: a caller that could name its
|
|
1204
|
+
// own transport could name 'stdio' and walk straight through the
|
|
1205
|
+
// local-only gate.
|
|
1206
|
+
transport: 'http',
|
|
1120
1207
|
};
|
|
1121
1208
|
log(`HTTP: /batch — ${calls.length} calls (agent=${context.agentId || 'anonymous'}, tier=${tier})`);
|
|
1122
1209
|
const results = await kernel.batch(calls, context);
|
|
1123
|
-
|
|
1210
|
+
// `ok` reflects STRUCTURAL validity: did every call name something this
|
|
1211
|
+
// runtime actually has. A call that ran and returned isError leaves ok
|
|
1212
|
+
// true — partial failure is a normal batch outcome and callers depend on
|
|
1213
|
+
// that. A call naming a facade that is not registered does not.
|
|
1214
|
+
//
|
|
1215
|
+
// The status stays 200 because the body still carries real results for
|
|
1216
|
+
// the other calls in the batch, and throwing those away behind a 4xx
|
|
1217
|
+
// would trade one silent failure for another.
|
|
1218
|
+
const unknown = results.filter(r => r.code === 'UNKNOWN_FACADE');
|
|
1219
|
+
if (unknown.length > 0) {
|
|
1220
|
+
log(`HTTP: /batch — ${unknown.length} unknown facade(s): ${unknown.map(r => r.facade).join(', ')}`);
|
|
1221
|
+
}
|
|
1222
|
+
sendJson(res, 200, {
|
|
1223
|
+
status: unknown.length > 0 ? 'error' : 'executed',
|
|
1224
|
+
ok: unknown.length === 0,
|
|
1225
|
+
results,
|
|
1226
|
+
});
|
|
1124
1227
|
}
|
|
1125
1228
|
catch (error) {
|
|
1126
1229
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1149,7 +1252,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1149
1252
|
const body = await parseBody(req);
|
|
1150
1253
|
log(`HTTP: /api/tools/${toolName}`);
|
|
1151
1254
|
const result = await executeTool(toolName, body);
|
|
1152
|
-
sendJson(res, result
|
|
1255
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1153
1256
|
}
|
|
1154
1257
|
catch (error) {
|
|
1155
1258
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1166,7 +1269,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1166
1269
|
const body = await parseBody(req);
|
|
1167
1270
|
log('HTTP: /dojo/wish');
|
|
1168
1271
|
const result = await executeTool('dojo_add_wish', body);
|
|
1169
|
-
sendJson(res, result
|
|
1272
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1170
1273
|
}
|
|
1171
1274
|
catch (error) {
|
|
1172
1275
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1180,7 +1283,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1180
1283
|
const body = await parseBody(req);
|
|
1181
1284
|
log('HTTP: /dojo/propose');
|
|
1182
1285
|
const result = await executeTool('dojo_create_proposal', body);
|
|
1183
|
-
sendJson(res, result
|
|
1286
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1184
1287
|
}
|
|
1185
1288
|
catch (error) {
|
|
1186
1289
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1194,7 +1297,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1194
1297
|
const body = await parseBody(req);
|
|
1195
1298
|
log('HTTP: /dojo/scaffold');
|
|
1196
1299
|
const result = await executeTool('dojo_scaffold_experiment', body);
|
|
1197
|
-
sendJson(res, result
|
|
1300
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1198
1301
|
}
|
|
1199
1302
|
catch (error) {
|
|
1200
1303
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1208,7 +1311,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1208
1311
|
const body = await parseBody(req);
|
|
1209
1312
|
log('HTTP: /dojo/run');
|
|
1210
1313
|
const result = await executeTool('dojo_run_experiment', body);
|
|
1211
|
-
sendJson(res, result
|
|
1314
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1212
1315
|
}
|
|
1213
1316
|
catch (error) {
|
|
1214
1317
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1222,7 +1325,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1222
1325
|
const body = await parseBody(req);
|
|
1223
1326
|
log('HTTP: /dojo/results');
|
|
1224
1327
|
const result = await executeTool('dojo_read_results', body);
|
|
1225
|
-
sendJson(res, result
|
|
1328
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1226
1329
|
}
|
|
1227
1330
|
catch (error) {
|
|
1228
1331
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1243,7 +1346,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1243
1346
|
}
|
|
1244
1347
|
log('HTTP: /dojo/list');
|
|
1245
1348
|
const result = await executeTool('dojo_list', body);
|
|
1246
|
-
sendJson(res, result
|
|
1349
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1247
1350
|
}
|
|
1248
1351
|
catch (error) {
|
|
1249
1352
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1263,7 +1366,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1263
1366
|
}
|
|
1264
1367
|
log('HTTP: /dojo/wishes');
|
|
1265
1368
|
const result = await executeTool('dojo_list_wishes', body);
|
|
1266
|
-
sendJson(res, result
|
|
1369
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1267
1370
|
}
|
|
1268
1371
|
catch (error) {
|
|
1269
1372
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1277,7 +1380,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1277
1380
|
const body = await parseBody(req);
|
|
1278
1381
|
log('HTTP: /dojo/can-graduate');
|
|
1279
1382
|
const result = await executeTool('dojo_can_graduate', body);
|
|
1280
|
-
sendJson(res, result
|
|
1383
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1281
1384
|
}
|
|
1282
1385
|
catch (error) {
|
|
1283
1386
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1291,7 +1394,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1291
1394
|
const body = await parseBody(req);
|
|
1292
1395
|
log('HTTP: /dojo/artifact');
|
|
1293
1396
|
const result = await executeTool('dojo_read_artifact', body);
|
|
1294
|
-
sendJson(res, result
|
|
1397
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1295
1398
|
}
|
|
1296
1399
|
catch (error) {
|
|
1297
1400
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1305,7 +1408,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1305
1408
|
const body = await parseBody(req);
|
|
1306
1409
|
log('HTTP: /dojo/bench');
|
|
1307
1410
|
const result = await executeTool('dojo_bench', body);
|
|
1308
|
-
sendJson(res, result
|
|
1411
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1309
1412
|
}
|
|
1310
1413
|
catch (error) {
|
|
1311
1414
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1322,7 +1425,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1322
1425
|
const body = await parseBody(req);
|
|
1323
1426
|
log('HTTP: /bench/run');
|
|
1324
1427
|
const result = await executeTool('decibel_bench', body);
|
|
1325
|
-
sendJson(res, result
|
|
1428
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1326
1429
|
}
|
|
1327
1430
|
catch (error) {
|
|
1328
1431
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1336,7 +1439,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1336
1439
|
const body = await parseBody(req);
|
|
1337
1440
|
log('HTTP: /bench/compare');
|
|
1338
1441
|
const result = await executeTool('decibel_bench_compare', body);
|
|
1339
|
-
sendJson(res, result
|
|
1442
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1340
1443
|
}
|
|
1341
1444
|
catch (error) {
|
|
1342
1445
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1353,7 +1456,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1353
1456
|
const body = await parseBody(req);
|
|
1354
1457
|
log('HTTP: /context/refresh');
|
|
1355
1458
|
const result = await executeTool('decibel_context_refresh', body);
|
|
1356
|
-
sendJson(res, result
|
|
1459
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1357
1460
|
}
|
|
1358
1461
|
catch (error) {
|
|
1359
1462
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1367,7 +1470,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1367
1470
|
const body = await parseBody(req);
|
|
1368
1471
|
log('HTTP: /context/pin');
|
|
1369
1472
|
const result = await executeTool('decibel_context_pin', body);
|
|
1370
|
-
sendJson(res, result
|
|
1473
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1371
1474
|
}
|
|
1372
1475
|
catch (error) {
|
|
1373
1476
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1381,7 +1484,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1381
1484
|
const body = await parseBody(req);
|
|
1382
1485
|
log('HTTP: /context/unpin');
|
|
1383
1486
|
const result = await executeTool('decibel_context_unpin', body);
|
|
1384
|
-
sendJson(res, result
|
|
1487
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1385
1488
|
}
|
|
1386
1489
|
catch (error) {
|
|
1387
1490
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1401,7 +1504,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1401
1504
|
}
|
|
1402
1505
|
log('HTTP: /context/list');
|
|
1403
1506
|
const result = await executeTool('decibel_context_list', body);
|
|
1404
|
-
sendJson(res, result
|
|
1507
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1405
1508
|
}
|
|
1406
1509
|
catch (error) {
|
|
1407
1510
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1415,7 +1518,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1415
1518
|
const body = await parseBody(req);
|
|
1416
1519
|
log('HTTP: /event/append');
|
|
1417
1520
|
const result = await executeTool('decibel_event_append', body);
|
|
1418
|
-
sendJson(res, result
|
|
1521
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1419
1522
|
}
|
|
1420
1523
|
catch (error) {
|
|
1421
1524
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1443,7 +1546,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1443
1546
|
}
|
|
1444
1547
|
log('HTTP: /event/search');
|
|
1445
1548
|
const result = await executeTool('decibel_event_search', body);
|
|
1446
|
-
sendJson(res, result
|
|
1549
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1447
1550
|
}
|
|
1448
1551
|
catch (error) {
|
|
1449
1552
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1457,7 +1560,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1457
1560
|
const body = await parseBody(req);
|
|
1458
1561
|
log('HTTP: /artifact/list');
|
|
1459
1562
|
const result = await executeTool('decibel_artifact_list', body);
|
|
1460
|
-
sendJson(res, result
|
|
1563
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1461
1564
|
}
|
|
1462
1565
|
catch (error) {
|
|
1463
1566
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1471,7 +1574,7 @@ export async function startHttpServer(server, kernelInstance, options) {
|
|
|
1471
1574
|
const body = await parseBody(req);
|
|
1472
1575
|
log('HTTP: /artifact/read');
|
|
1473
1576
|
const result = await executeTool('decibel_artifact_read', body);
|
|
1474
|
-
sendJson(res, result
|
|
1577
|
+
sendJson(res, envelopeHttpStatus(result), result);
|
|
1475
1578
|
}
|
|
1476
1579
|
catch (error) {
|
|
1477
1580
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -2129,36 +2232,8 @@ ${authToken ? '║ Auth: Bearer token required
|
|
|
2129
2232
|
},
|
|
2130
2233
|
};
|
|
2131
2234
|
}
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
export
|
|
2136
|
-
const httpMode = args.includes('--http');
|
|
2137
|
-
const portIndex = args.indexOf('--port');
|
|
2138
|
-
// --port flag wins; else honor PORT env (Render sets it); else leave undefined
|
|
2139
|
-
// so daemonConfig's default (4888) applies downstream instead of being
|
|
2140
|
-
// short-circuited by a baked-in default here. See server.ts port/host resolution.
|
|
2141
|
-
const port = portIndex !== -1
|
|
2142
|
-
? parseInt(args[portIndex + 1], 10)
|
|
2143
|
-
: process.env.PORT
|
|
2144
|
-
? parseInt(process.env.PORT, 10)
|
|
2145
|
-
: undefined;
|
|
2146
|
-
// SECURITY: Prefer env var for auth token (CLI args visible in ps/history)
|
|
2147
|
-
// Fall back to --auth-token for backwards compatibility
|
|
2148
|
-
const authIndex = args.indexOf('--auth-token');
|
|
2149
|
-
const authToken = process.env.DECIBEL_AUTH_TOKEN ||
|
|
2150
|
-
(authIndex !== -1 ? args[authIndex + 1] : undefined);
|
|
2151
|
-
const hostIndex = args.indexOf('--host');
|
|
2152
|
-
// --host flag wins; else leave undefined so daemonConfig host (127.0.0.1, daemon
|
|
2153
|
-
// mode) or the transport default applies instead of being short-circuited here.
|
|
2154
|
-
const host = hostIndex !== -1 ? args[hostIndex + 1] : undefined;
|
|
2155
|
-
// SSE/Connection tuning arguments
|
|
2156
|
-
const keepaliveIndex = args.indexOf('--sse-keepalive');
|
|
2157
|
-
const sseKeepaliveMs = keepaliveIndex !== -1 ? parseInt(args[keepaliveIndex + 1], 10) : undefined;
|
|
2158
|
-
const timeoutIndex = args.indexOf('--timeout');
|
|
2159
|
-
const timeoutMs = timeoutIndex !== -1 ? parseInt(args[timeoutIndex + 1], 10) : undefined;
|
|
2160
|
-
const retryIndex = args.indexOf('--sse-retry');
|
|
2161
|
-
const retryIntervalMs = retryIndex !== -1 ? parseInt(args[retryIndex + 1], 10) : undefined;
|
|
2162
|
-
return { httpMode, port, authToken, host, sseKeepaliveMs, timeoutMs, retryIntervalMs };
|
|
2163
|
-
}
|
|
2235
|
+
// parseHttpArgs moved to ./httpArgs.js so that argv parsing carries no
|
|
2236
|
+
// dependencies. Re-exported here because it has always been part of this
|
|
2237
|
+
// module's surface.
|
|
2238
|
+
export { parseHttpArgs } from './httpArgs.js';
|
|
2164
2239
|
//# sourceMappingURL=httpServer.js.map
|