@mcoda/codali 0.1.107 → 0.1.109

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.
Files changed (149) hide show
  1. package/dist/agents/AgentInventory.d.ts +56 -0
  2. package/dist/agents/AgentInventory.d.ts.map +1 -0
  3. package/dist/agents/AgentInventory.js +131 -0
  4. package/dist/agents/RoleResolution.d.ts +49 -0
  5. package/dist/agents/RoleResolution.d.ts.map +1 -0
  6. package/dist/agents/RoleResolution.js +166 -0
  7. package/dist/api/ChatCompletionsAdapter.d.ts +76 -0
  8. package/dist/api/ChatCompletionsAdapter.d.ts.map +1 -0
  9. package/dist/api/ChatCompletionsAdapter.js +54 -0
  10. package/dist/api/CodaliApi.d.ts +78 -0
  11. package/dist/api/CodaliApi.d.ts.map +1 -0
  12. package/dist/api/CodaliApi.js +273 -0
  13. package/dist/api/CodaliServer.d.ts +42 -0
  14. package/dist/api/CodaliServer.d.ts.map +1 -0
  15. package/dist/api/CodaliServer.js +118 -0
  16. package/dist/cli/AskCommand.d.ts +66 -0
  17. package/dist/cli/AskCommand.d.ts.map +1 -0
  18. package/dist/cli/AskCommand.js +536 -0
  19. package/dist/cli/AuthCommand.d.ts +19 -0
  20. package/dist/cli/AuthCommand.d.ts.map +1 -0
  21. package/dist/cli/AuthCommand.js +161 -0
  22. package/dist/cli/ServeCommand.d.ts +5 -0
  23. package/dist/cli/ServeCommand.d.ts.map +1 -0
  24. package/dist/cli/ServeCommand.js +87 -0
  25. package/dist/cli/ToolsCommand.d.ts +22 -0
  26. package/dist/cli/ToolsCommand.d.ts.map +1 -0
  27. package/dist/cli/ToolsCommand.js +208 -0
  28. package/dist/cli.d.ts.map +1 -1
  29. package/dist/cli.js +29 -1
  30. package/dist/connectors/http/HttpToolDefinition.d.ts +74 -0
  31. package/dist/connectors/http/HttpToolDefinition.d.ts.map +1 -0
  32. package/dist/connectors/http/HttpToolDefinition.js +190 -0
  33. package/dist/connectors/http/HttpToolSource.d.ts +18 -0
  34. package/dist/connectors/http/HttpToolSource.d.ts.map +1 -0
  35. package/dist/connectors/http/HttpToolSource.js +29 -0
  36. package/dist/connectors/mcp/McpClient.d.ts +132 -0
  37. package/dist/connectors/mcp/McpClient.d.ts.map +1 -0
  38. package/dist/connectors/mcp/McpClient.js +215 -0
  39. package/dist/connectors/mcp/McpServerRegistry.d.ts +75 -0
  40. package/dist/connectors/mcp/McpServerRegistry.d.ts.map +1 -0
  41. package/dist/connectors/mcp/McpServerRegistry.js +180 -0
  42. package/dist/connectors/mcp/McpToolAdapter.d.ts +48 -0
  43. package/dist/connectors/mcp/McpToolAdapter.d.ts.map +1 -0
  44. package/dist/connectors/mcp/McpToolAdapter.js +101 -0
  45. package/dist/connectors/mcp/McpToolSource.d.ts +27 -0
  46. package/dist/connectors/mcp/McpToolSource.d.ts.map +1 -0
  47. package/dist/connectors/mcp/McpToolSource.js +33 -0
  48. package/dist/connectors/media/ImageGenerationTool.d.ts +43 -0
  49. package/dist/connectors/media/ImageGenerationTool.d.ts.map +1 -0
  50. package/dist/connectors/media/ImageGenerationTool.js +122 -0
  51. package/dist/connectors/oauth/DeviceCodeAuth.d.ts +74 -0
  52. package/dist/connectors/oauth/DeviceCodeAuth.d.ts.map +1 -0
  53. package/dist/connectors/oauth/DeviceCodeAuth.js +153 -0
  54. package/dist/docdex/DocdexClient.d.ts +2 -0
  55. package/dist/docdex/DocdexClient.d.ts.map +1 -1
  56. package/dist/docdex/DocdexClient.js +4 -0
  57. package/dist/gateway/CodaliGateway.d.ts +51 -3
  58. package/dist/gateway/CodaliGateway.d.ts.map +1 -1
  59. package/dist/gateway/CodaliGateway.js +226 -2
  60. package/dist/gateway/CodaliGatewayTypes.d.ts +34 -0
  61. package/dist/gateway/CodaliGatewayTypes.d.ts.map +1 -1
  62. package/dist/gateway/EvidenceNormalizer.d.ts.map +1 -1
  63. package/dist/gateway/EvidenceNormalizer.js +90 -1
  64. package/dist/gateway/Finalizer.d.ts +50 -0
  65. package/dist/gateway/Finalizer.d.ts.map +1 -0
  66. package/dist/gateway/Finalizer.js +79 -0
  67. package/dist/gateway/GatewayPlanner.d.ts +13 -0
  68. package/dist/gateway/GatewayPlanner.d.ts.map +1 -1
  69. package/dist/gateway/GatewayPlanner.js +81 -16
  70. package/dist/gateway/GatewayStateMachine.d.ts.map +1 -1
  71. package/dist/gateway/GatewayStateMachine.js +6 -0
  72. package/dist/gateway/GatewayTracer.d.ts +93 -0
  73. package/dist/gateway/GatewayTracer.d.ts.map +1 -0
  74. package/dist/gateway/GatewayTracer.js +214 -0
  75. package/dist/gateway/LocalGatewayProvider.d.ts +46 -0
  76. package/dist/gateway/LocalGatewayProvider.d.ts.map +1 -0
  77. package/dist/gateway/LocalGatewayProvider.js +161 -0
  78. package/dist/gateway/LocalGatewayTaskRunner.d.ts +79 -0
  79. package/dist/gateway/LocalGatewayTaskRunner.d.ts.map +1 -0
  80. package/dist/gateway/LocalGatewayTaskRunner.js +354 -0
  81. package/dist/gateway/RelevanceJudge.d.ts +14 -0
  82. package/dist/gateway/RelevanceJudge.d.ts.map +1 -0
  83. package/dist/gateway/RelevanceJudge.js +87 -0
  84. package/dist/gateway/ResponseSchema.d.ts +32 -0
  85. package/dist/gateway/ResponseSchema.d.ts.map +1 -0
  86. package/dist/gateway/ResponseSchema.js +120 -0
  87. package/dist/gateway/TemporalContext.d.ts +36 -0
  88. package/dist/gateway/TemporalContext.d.ts.map +1 -0
  89. package/dist/gateway/TemporalContext.js +115 -0
  90. package/dist/gateway/ToolCapabilityCompiler.d.ts +5 -0
  91. package/dist/gateway/ToolCapabilityCompiler.d.ts.map +1 -1
  92. package/dist/gateway/ToolCapabilityCompiler.js +27 -2
  93. package/dist/gateway/ToolDescriptorSource.d.ts +6 -0
  94. package/dist/gateway/ToolDescriptorSource.d.ts.map +1 -0
  95. package/dist/gateway/ToolDescriptorSource.js +30 -0
  96. package/dist/gateway/ToolExposure.d.ts +36 -0
  97. package/dist/gateway/ToolExposure.d.ts.map +1 -0
  98. package/dist/gateway/ToolExposure.js +154 -0
  99. package/dist/index.d.ts +57 -0
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +45 -0
  102. package/dist/providers/ClaudeCliProvider.d.ts +2 -0
  103. package/dist/providers/ClaudeCliProvider.d.ts.map +1 -1
  104. package/dist/providers/ClaudeCliProvider.js +2 -0
  105. package/dist/providers/CodexCliProvider.d.ts +2 -0
  106. package/dist/providers/CodexCliProvider.d.ts.map +1 -1
  107. package/dist/providers/CodexCliProvider.js +2 -0
  108. package/dist/providers/MswarmWorkerProvider.d.ts +2 -0
  109. package/dist/providers/MswarmWorkerProvider.d.ts.map +1 -1
  110. package/dist/providers/MswarmWorkerProvider.js +2 -0
  111. package/dist/providers/OllamaRemoteProvider.d.ts +2 -0
  112. package/dist/providers/OllamaRemoteProvider.d.ts.map +1 -1
  113. package/dist/providers/OllamaRemoteProvider.js +2 -0
  114. package/dist/providers/OpenAiCompatibleProvider.d.ts +2 -0
  115. package/dist/providers/OpenAiCompatibleProvider.d.ts.map +1 -1
  116. package/dist/providers/OpenAiCompatibleProvider.js +2 -0
  117. package/dist/providers/ProviderTypes.d.ts +13 -0
  118. package/dist/providers/ProviderTypes.d.ts.map +1 -1
  119. package/dist/providers/ProviderTypes.js +1 -1
  120. package/dist/runcontext/CredentialFile.d.ts +12 -0
  121. package/dist/runcontext/CredentialFile.d.ts.map +1 -0
  122. package/dist/runcontext/CredentialFile.js +81 -0
  123. package/dist/runcontext/RunContextResolver.d.ts +126 -0
  124. package/dist/runcontext/RunContextResolver.d.ts.map +1 -0
  125. package/dist/runcontext/RunContextResolver.js +389 -0
  126. package/dist/storage/CodaliDatasetPrivacyEngine.d.ts +1 -1
  127. package/dist/storage/CodaliDatasetPrivacyEngine.d.ts.map +1 -1
  128. package/dist/storage/CodaliDatasetPrivacyEngine.js +12 -0
  129. package/dist/tools/ToolRegistry.d.ts +14 -1
  130. package/dist/tools/ToolRegistry.d.ts.map +1 -1
  131. package/dist/tools/ToolRegistry.js +38 -1
  132. package/dist/tools/ToolTypes.d.ts +35 -0
  133. package/dist/tools/ToolTypes.d.ts.map +1 -1
  134. package/dist/tools/ToolTypes.js +21 -0
  135. package/dist/tools/TruncateResult.d.ts +29 -0
  136. package/dist/tools/TruncateResult.d.ts.map +1 -0
  137. package/dist/tools/TruncateResult.js +91 -0
  138. package/dist/tools/diff/DiffTool.d.ts.map +1 -1
  139. package/dist/tools/diff/DiffTool.js +2 -0
  140. package/dist/tools/docdex/DocdexTools.d.ts +21 -1
  141. package/dist/tools/docdex/DocdexTools.d.ts.map +1 -1
  142. package/dist/tools/docdex/DocdexTools.js +108 -16
  143. package/dist/tools/filesystem/FileTools.d.ts.map +1 -1
  144. package/dist/tools/filesystem/FileTools.js +8 -0
  145. package/dist/tools/search/SearchTool.d.ts.map +1 -1
  146. package/dist/tools/search/SearchTool.js +3 -1
  147. package/dist/tools/shell/ShellTool.d.ts.map +1 -1
  148. package/dist/tools/shell/ShellTool.js +2 -0
  149. package/package.json +4 -3
@@ -0,0 +1,126 @@
1
+ import type { McpServerDefinition } from "../connectors/mcp/McpClient.js";
2
+ import type { HttpConnectorDefinition } from "../connectors/http/HttpToolDefinition.js";
3
+ /**
4
+ * The one seam through which Codali learns what a request is allowed to touch.
5
+ *
6
+ * Codali is meant to serve many products, and a multi-tenant product like
7
+ * okacam has a different tool set, different credentials, and different limits
8
+ * for every tenant. So the tool configuration is never read from a file at run
9
+ * time — it is *resolved* per request.
10
+ *
11
+ * A config file is simply one implementation of this interface, used by the
12
+ * local CLI and single-tenant deployments. An embedded product implements its
13
+ * own, or passes a `RunContext` directly on the request; either way the host
14
+ * supplies the context, and Codali never calls back into the product to fetch
15
+ * it. That callback would create a circular dependency
16
+ * (product -> codali -> product) plus the caching, invalidation, and
17
+ * failure-mode machinery that comes with it, and the authenticated host already
18
+ * holds this data.
19
+ */
20
+ export interface RunContextRepo {
21
+ root?: string;
22
+ repoId?: string;
23
+ }
24
+ export interface RunContextDocdex {
25
+ baseUrl?: string;
26
+ apiKey?: string;
27
+ repoRoot?: string;
28
+ repoId?: string;
29
+ allowedOperations?: string[];
30
+ }
31
+ export interface RunContextTenant {
32
+ id?: string;
33
+ slug?: string;
34
+ realm?: string;
35
+ }
36
+ export interface RunContextLimits {
37
+ maxRounds?: number;
38
+ maxToolCalls?: number;
39
+ maxModelCalls?: number;
40
+ deadlineMs?: number;
41
+ }
42
+ export interface RunContextAgentRoles {
43
+ /** Routes, plans, assesses completeness, repairs. Runs on every question. */
44
+ orchestrator?: string;
45
+ /** Makes the tool calls. Defaults to the orchestrator when unset. */
46
+ worker?: string;
47
+ /** Produces multi-source answers. */
48
+ synthesizer?: string;
49
+ /** Generates images and other media. */
50
+ media?: string;
51
+ }
52
+ export interface RunContext {
53
+ tenant?: RunContextTenant;
54
+ repo?: RunContextRepo;
55
+ docdex?: RunContextDocdex;
56
+ agentRoles?: RunContextAgentRoles;
57
+ limits?: RunContextLimits;
58
+ /**
59
+ * MCP servers this run may connect to.
60
+ *
61
+ * Only ever populated from user/host config or a host-supplied context —
62
+ * never from repository config. See {@link scrubRepoConfig}.
63
+ */
64
+ mcpServers?: McpServerDefinition[];
65
+ /**
66
+ * Hand-declared HTTP connectors. Same trust rules as MCP servers: trusted
67
+ * layers only, never repository config.
68
+ */
69
+ httpConnectors?: HttpConnectorDefinition[];
70
+ /** Tool names permitted for this run. Absent means "registry default". */
71
+ allowedTools?: string[];
72
+ deniedTools?: string[];
73
+ /** Non-fatal problems encountered while resolving, surfaced in the trace. */
74
+ warnings?: string[];
75
+ }
76
+ export interface RunContextResolveInput {
77
+ workspaceRoot: string;
78
+ tenant?: RunContextTenant;
79
+ /** Context supplied directly by an embedding host, taking precedence. */
80
+ provided?: RunContext;
81
+ }
82
+ export interface RunContextResolver {
83
+ readonly id: string;
84
+ resolve(input: RunContextResolveInput): Promise<RunContext>;
85
+ }
86
+ export interface RepoConfigScrubResult {
87
+ value: Record<string, unknown>;
88
+ rejectedKeys: string[];
89
+ }
90
+ /**
91
+ * Strips forbidden keys from a repository config, recording what was dropped.
92
+ * Rejection is loud rather than silent: the keys land in run warnings so a
93
+ * repository that tries to widen its own permissions is visible.
94
+ */
95
+ export declare const scrubRepoConfig: (config: Record<string, unknown>, pathPrefix?: string) => RepoConfigScrubResult;
96
+ /**
97
+ * Merges a narrower context over a broader one. Allow-lists intersect and
98
+ * deny-lists union, so a later layer can only ever restrict what an earlier one
99
+ * permitted — never widen it.
100
+ */
101
+ export declare const mergeRunContexts: (base: RunContext, override: RunContext) => RunContext;
102
+ export interface LocalConfigResolverOptions {
103
+ /** Overridden in tests; defaults to `~/.codali`. */
104
+ userConfigDir?: string;
105
+ }
106
+ /**
107
+ * Resolves run context from trusted user config, then applies the repository's
108
+ * narrowing config on top. Used by the CLI and any single-tenant deployment.
109
+ */
110
+ export declare class LocalConfigRunContextResolver implements RunContextResolver {
111
+ private readonly options;
112
+ readonly id = "local_config";
113
+ constructor(options?: LocalConfigResolverOptions);
114
+ resolve(input: RunContextResolveInput): Promise<RunContext>;
115
+ }
116
+ /**
117
+ * Uses context handed over by an embedding host. This is the okacam path: the
118
+ * product resolves the tenant's tools and credentials from its own database and
119
+ * passes them on the request.
120
+ */
121
+ export declare class ProvidedRunContextResolver implements RunContextResolver {
122
+ readonly id = "provided";
123
+ resolve(input: RunContextResolveInput): Promise<RunContext>;
124
+ }
125
+ export declare const resolveRunContext: (input: RunContextResolveInput, resolver?: RunContextResolver) => Promise<RunContext>;
126
+ //# sourceMappingURL=RunContextResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RunContextResolver.d.ts","sourceRoot":"","sources":["../../src/runcontext/RunContextResolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,389 @@
1
+ import { homedir } from "node:os";
2
+ import path from "node:path";
3
+ import { readFile } from "node:fs/promises";
4
+ import { existsSync } from "node:fs";
5
+ import { resolveCredential } from "./CredentialFile.js";
6
+ /**
7
+ * Keys a repository-level config file is forbidden to set.
8
+ *
9
+ * A checked-out repository is untrusted input. If `.codali/config.toml` could
10
+ * define an MCP server command, a base URL, or a credential reference, then
11
+ * cloning a repository and running `codali ask` inside it would be enough to
12
+ * execute an arbitrary binary or redirect traffic to an attacker's endpoint.
13
+ *
14
+ * The boundary is therefore: user/host config may define what runs and where
15
+ * it connects; repository config may only *narrow* what is already permitted,
16
+ * identify the repository, and set harmless presentation defaults.
17
+ */
18
+ const REPO_FORBIDDEN_KEYS = new Set([
19
+ "command",
20
+ "args",
21
+ "env",
22
+ "url",
23
+ "base_url",
24
+ "baseurl",
25
+ "api_key",
26
+ "apikey",
27
+ "token",
28
+ "secret",
29
+ "credential",
30
+ "credentials",
31
+ "password",
32
+ "headers",
33
+ // Every reader below accepts both snake_case and camelCase, so both spellings
34
+ // must be forbidden. Listing only one is a hole, not a style preference.
35
+ "mcp_servers",
36
+ "mcpservers",
37
+ "api_connectors",
38
+ "apiconnectors",
39
+ "http_connectors",
40
+ "httpconnectors",
41
+ "agents",
42
+ "agent_roles",
43
+ "agentroles",
44
+ "docdex",
45
+ ]);
46
+ /**
47
+ * Strips forbidden keys from a repository config, recording what was dropped.
48
+ * Rejection is loud rather than silent: the keys land in run warnings so a
49
+ * repository that tries to widen its own permissions is visible.
50
+ */
51
+ export const scrubRepoConfig = (config, pathPrefix = "") => {
52
+ const value = {};
53
+ const rejectedKeys = [];
54
+ for (const [key, entry] of Object.entries(config)) {
55
+ const qualified = pathPrefix ? `${pathPrefix}.${key}` : key;
56
+ if (REPO_FORBIDDEN_KEYS.has(key.toLowerCase())) {
57
+ rejectedKeys.push(qualified);
58
+ continue;
59
+ }
60
+ if (entry && typeof entry === "object" && !Array.isArray(entry)) {
61
+ const nested = scrubRepoConfig(entry, qualified);
62
+ value[key] = nested.value;
63
+ rejectedKeys.push(...nested.rejectedKeys);
64
+ continue;
65
+ }
66
+ value[key] = entry;
67
+ }
68
+ return { value, rejectedKeys };
69
+ };
70
+ const readJsonFile = async (filePath) => {
71
+ if (!existsSync(filePath))
72
+ return undefined;
73
+ try {
74
+ const raw = await readFile(filePath, "utf8");
75
+ const parsed = JSON.parse(raw);
76
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed)
77
+ ? parsed
78
+ : undefined;
79
+ }
80
+ catch {
81
+ return undefined;
82
+ }
83
+ };
84
+ const asStringArray = (value) => Array.isArray(value)
85
+ ? value.filter((entry) => typeof entry === "string")
86
+ : undefined;
87
+ const asString = (value) => typeof value === "string" && value.trim() ? value.trim() : undefined;
88
+ const asNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
89
+ const readAgentRoles = (value) => {
90
+ if (!value || typeof value !== "object")
91
+ return undefined;
92
+ const record = value;
93
+ const roles = {
94
+ orchestrator: asString(record.orchestrator),
95
+ worker: asString(record.worker),
96
+ synthesizer: asString(record.synthesizer),
97
+ media: asString(record.media),
98
+ };
99
+ return Object.values(roles).some(Boolean) ? roles : undefined;
100
+ };
101
+ const readLimits = (value) => {
102
+ if (!value || typeof value !== "object")
103
+ return undefined;
104
+ const record = value;
105
+ const limits = {
106
+ maxRounds: asNumber(record.maxRounds ?? record.max_rounds),
107
+ maxToolCalls: asNumber(record.maxToolCalls ?? record.max_tool_calls),
108
+ maxModelCalls: asNumber(record.maxModelCalls ?? record.max_model_calls),
109
+ deadlineMs: asNumber(record.deadlineMs ?? record.deadline_ms),
110
+ };
111
+ return Object.values(limits).some((entry) => entry !== undefined) ? limits : undefined;
112
+ };
113
+ /**
114
+ * Reads MCP server definitions from a *trusted* config layer. Never called on
115
+ * repository config: `scrubRepoConfig` removes the keys first.
116
+ */
117
+ const readMcpServers = (value) => {
118
+ if (!Array.isArray(value))
119
+ return undefined;
120
+ const servers = [];
121
+ for (const entry of value) {
122
+ if (!entry || typeof entry !== "object")
123
+ continue;
124
+ const record = entry;
125
+ const name = asString(record.name);
126
+ if (!name)
127
+ continue;
128
+ const transport = asString(record.transport) ?? (record.command ? "stdio" : "http");
129
+ const common = {
130
+ name,
131
+ enabled: typeof record.enabled === "boolean" ? record.enabled : undefined,
132
+ readOnly: record.readOnly === true || record.read_only === true,
133
+ timeoutMs: asNumber(record.timeoutMs ?? record.timeout_ms),
134
+ allowTools: asStringArray(record.allowTools ?? record.allow_tools),
135
+ denyTools: asStringArray(record.denyTools ?? record.deny_tools),
136
+ };
137
+ if (transport === "stdio") {
138
+ const command = asString(record.command);
139
+ if (!command)
140
+ continue;
141
+ servers.push({
142
+ ...common,
143
+ transport: "stdio",
144
+ command,
145
+ args: asStringArray(record.args),
146
+ cwd: asString(record.cwd),
147
+ env: resolveEnvRefs(record.env),
148
+ });
149
+ continue;
150
+ }
151
+ const url = asString(record.url);
152
+ if (!url)
153
+ continue;
154
+ servers.push({
155
+ ...common,
156
+ transport: "http",
157
+ url,
158
+ headers: resolveEnvRefs(record.headers),
159
+ });
160
+ }
161
+ return servers.length > 0 ? servers : undefined;
162
+ };
163
+ /**
164
+ * Reads HTTP connector declarations from a *trusted* config layer. Credentials
165
+ * are resolved through the same `env:` indirection as MCP servers, so a config
166
+ * file never has to hold a literal secret.
167
+ */
168
+ const readHttpConnectors = (value) => {
169
+ if (!Array.isArray(value))
170
+ return undefined;
171
+ const connectors = [];
172
+ for (const entry of value) {
173
+ if (!entry || typeof entry !== "object")
174
+ continue;
175
+ const record = entry;
176
+ const name = asString(record.name);
177
+ // Base URLs resolve `env:` references too. A site hostname is not secret,
178
+ // but keeping every connector detail in one credentials file beats
179
+ // splitting it across two places for no reason.
180
+ const baseUrl = resolveEnvRef(record.baseUrl ?? record.base_url);
181
+ if (!name || !baseUrl || !Array.isArray(record.tools))
182
+ continue;
183
+ const tools = record.tools
184
+ .filter((tool) => Boolean(tool && typeof tool === "object"))
185
+ .map((tool) => ({
186
+ id: asString(tool.id) ?? "",
187
+ description: asString(tool.description) ?? "",
188
+ method: (asString(tool.method) ?? "GET").toUpperCase(),
189
+ urlTemplate: asString(tool.urlTemplate ?? tool.url_template) ?? "",
190
+ inputSchema: tool.inputSchema,
191
+ responseSelector: asString(tool.responseSelector ?? tool.response_selector),
192
+ maxResponseChars: asNumber(tool.maxResponseChars ?? tool.max_response_chars),
193
+ }))
194
+ .filter((tool) => tool.id && tool.urlTemplate);
195
+ if (tools.length === 0)
196
+ continue;
197
+ const authRecord = record.auth && typeof record.auth === "object"
198
+ ? record.auth
199
+ : undefined;
200
+ connectors.push({
201
+ name,
202
+ baseUrl,
203
+ enabled: typeof record.enabled === "boolean" ? record.enabled : undefined,
204
+ timeoutMs: asNumber(record.timeoutMs ?? record.timeout_ms),
205
+ headers: resolveEnvRefs(record.headers),
206
+ tools,
207
+ auth: authRecord
208
+ ? {
209
+ type: (asString(authRecord.type) ?? "none"),
210
+ token: resolveEnvRef(authRecord.token),
211
+ username: resolveEnvRef(authRecord.username),
212
+ password: resolveEnvRef(authRecord.password),
213
+ headerName: asString(authRecord.headerName ?? authRecord.header_name),
214
+ tokenUrl: resolveEnvRef(authRecord.tokenUrl ?? authRecord.token_url),
215
+ clientId: resolveEnvRef(authRecord.clientId ?? authRecord.client_id),
216
+ refreshToken: resolveEnvRef(authRecord.refreshToken ?? authRecord.refresh_token),
217
+ scope: asString(authRecord.scope),
218
+ }
219
+ : undefined,
220
+ });
221
+ }
222
+ return connectors.length > 0 ? connectors : undefined;
223
+ };
224
+ /**
225
+ * Substitutes `env:NAME` references, including when embedded in a larger
226
+ * string. Header values are the common case — `"Bearer env:GITHUB_TOKEN"` is
227
+ * what anyone would write, and requiring the reference to sit at the start of
228
+ * the value would silently transmit the literal text as a credential.
229
+ *
230
+ * An unresolvable reference yields `undefined` for the whole value rather than
231
+ * a half-substituted string: sending `Bearer env:GITHUB_TOKEN` to an API is
232
+ * worse than sending nothing, because the failure looks like a bad token
233
+ * instead of a missing one.
234
+ */
235
+ const ENV_REF_PATTERN = /env:([A-Za-z_][A-Za-z0-9_]*)/g;
236
+ const substituteEnvRefs = (value) => {
237
+ if (!value.includes("env:"))
238
+ return value;
239
+ let missing = false;
240
+ const output = value.replace(ENV_REF_PATTERN, (_match, name) => {
241
+ const resolved = resolveCredential(name);
242
+ if (resolved === undefined) {
243
+ missing = true;
244
+ return "";
245
+ }
246
+ return resolved;
247
+ });
248
+ return missing ? undefined : output;
249
+ };
250
+ const resolveEnvRef = (value) => {
251
+ if (typeof value !== "string")
252
+ return undefined;
253
+ return substituteEnvRefs(value);
254
+ };
255
+ /**
256
+ * Resolves `env:NAME` references so a config file never has to contain a
257
+ * literal secret. Local-CLI convenience only: an embedded multi-tenant host
258
+ * supplies credentials directly and must not be able to name host env vars.
259
+ */
260
+ const resolveEnvRefs = (value) => {
261
+ if (!value || typeof value !== "object" || Array.isArray(value))
262
+ return undefined;
263
+ const output = {};
264
+ for (const [key, entry] of Object.entries(value)) {
265
+ if (typeof entry !== "string")
266
+ continue;
267
+ // Resolved from the process environment first, then ~/.codali/.creds.
268
+ const resolved = substituteEnvRefs(entry);
269
+ if (resolved !== undefined)
270
+ output[key] = resolved;
271
+ }
272
+ return Object.keys(output).length > 0 ? output : undefined;
273
+ };
274
+ const contextFromConfig = (config) => ({
275
+ agentRoles: readAgentRoles(config.agents ?? config.agent_roles),
276
+ mcpServers: readMcpServers(config.mcpServers ?? config.mcp_servers),
277
+ httpConnectors: readHttpConnectors(config.httpConnectors ?? config.http_connectors),
278
+ limits: readLimits(config.limits),
279
+ allowedTools: asStringArray(config.allowedTools ?? config.allowed_tools),
280
+ deniedTools: asStringArray(config.deniedTools ?? config.denied_tools),
281
+ docdex: (() => {
282
+ const raw = config.docdex;
283
+ if (!raw || typeof raw !== "object")
284
+ return undefined;
285
+ const record = raw;
286
+ return {
287
+ baseUrl: asString(record.baseUrl ?? record.base_url),
288
+ apiKey: asString(record.apiKey ?? record.api_key),
289
+ repoRoot: asString(record.repoRoot ?? record.repo_root),
290
+ repoId: asString(record.repoId ?? record.repo_id),
291
+ allowedOperations: asStringArray(record.allowedOperations ?? record.allowed_operations),
292
+ };
293
+ })(),
294
+ });
295
+ /**
296
+ * Merges a narrower context over a broader one. Allow-lists intersect and
297
+ * deny-lists union, so a later layer can only ever restrict what an earlier one
298
+ * permitted — never widen it.
299
+ */
300
+ export const mergeRunContexts = (base, override) => {
301
+ const allowedTools = base.allowedTools && override.allowedTools
302
+ ? base.allowedTools.filter((tool) => override.allowedTools?.includes(tool))
303
+ : (override.allowedTools ?? base.allowedTools);
304
+ const deniedTools = [
305
+ ...new Set([...(base.deniedTools ?? []), ...(override.deniedTools ?? [])]),
306
+ ];
307
+ const minDefined = (a, b) => {
308
+ if (a === undefined)
309
+ return b;
310
+ if (b === undefined)
311
+ return a;
312
+ return Math.min(a, b);
313
+ };
314
+ return {
315
+ tenant: override.tenant ?? base.tenant,
316
+ repo: { ...base.repo, ...override.repo },
317
+ // Servers come from a trusted layer only; a narrower layer cannot add one.
318
+ mcpServers: override.mcpServers ?? base.mcpServers,
319
+ httpConnectors: override.httpConnectors ?? base.httpConnectors,
320
+ docdex: { ...base.docdex, ...override.docdex },
321
+ agentRoles: { ...base.agentRoles, ...override.agentRoles },
322
+ limits: {
323
+ maxRounds: minDefined(base.limits?.maxRounds, override.limits?.maxRounds),
324
+ maxToolCalls: minDefined(base.limits?.maxToolCalls, override.limits?.maxToolCalls),
325
+ maxModelCalls: minDefined(base.limits?.maxModelCalls, override.limits?.maxModelCalls),
326
+ deadlineMs: minDefined(base.limits?.deadlineMs, override.limits?.deadlineMs),
327
+ },
328
+ allowedTools,
329
+ deniedTools: deniedTools.length > 0 ? deniedTools : undefined,
330
+ warnings: [...(base.warnings ?? []), ...(override.warnings ?? [])],
331
+ };
332
+ };
333
+ /**
334
+ * Resolves run context from trusted user config, then applies the repository's
335
+ * narrowing config on top. Used by the CLI and any single-tenant deployment.
336
+ */
337
+ export class LocalConfigRunContextResolver {
338
+ constructor(options = {}) {
339
+ this.options = options;
340
+ this.id = "local_config";
341
+ }
342
+ async resolve(input) {
343
+ const warnings = [];
344
+ const userDir = this.options.userConfigDir ?? path.join(homedir(), ".codali");
345
+ const userConfig = await readJsonFile(path.join(userDir, "config.json"));
346
+ const base = userConfig ? contextFromConfig(userConfig) : {};
347
+ const repoConfigRaw = await readJsonFile(path.join(input.workspaceRoot, ".codali", "config.json"));
348
+ let repoContext = {};
349
+ if (repoConfigRaw) {
350
+ const scrubbed = scrubRepoConfig(repoConfigRaw);
351
+ if (scrubbed.rejectedKeys.length > 0) {
352
+ warnings.push(`repo_config_keys_rejected:${scrubbed.rejectedKeys.join(",")}`);
353
+ }
354
+ repoContext = contextFromConfig(scrubbed.value);
355
+ }
356
+ const merged = mergeRunContexts(base, repoContext);
357
+ return {
358
+ ...merged,
359
+ tenant: input.tenant ?? merged.tenant,
360
+ repo: { root: input.workspaceRoot, ...merged.repo },
361
+ warnings: [...(merged.warnings ?? []), ...warnings],
362
+ };
363
+ }
364
+ }
365
+ /**
366
+ * Uses context handed over by an embedding host. This is the okacam path: the
367
+ * product resolves the tenant's tools and credentials from its own database and
368
+ * passes them on the request.
369
+ */
370
+ export class ProvidedRunContextResolver {
371
+ constructor() {
372
+ this.id = "provided";
373
+ }
374
+ async resolve(input) {
375
+ if (!input.provided) {
376
+ throw new Error("ProvidedRunContextResolver requires a RunContext on the request.");
377
+ }
378
+ return {
379
+ ...input.provided,
380
+ repo: { root: input.workspaceRoot, ...input.provided.repo },
381
+ tenant: input.tenant ?? input.provided.tenant,
382
+ };
383
+ }
384
+ }
385
+ export const resolveRunContext = async (input, resolver) => {
386
+ const active = resolver ??
387
+ (input.provided ? new ProvidedRunContextResolver() : new LocalConfigRunContextResolver());
388
+ return active.resolve(input);
389
+ };
@@ -1,6 +1,6 @@
1
1
  import { type CodaliStorageObjectPrivacyFlags, type CodaliStorageObjectRef, type CodaliStorageObjectRetentionClass, type CodaliStoragePrivacyClassification, type CodaliStoragePrivacyMetadata } from "./CodaliStorageContracts.js";
2
2
  export type CodaliDatasetPrivacyPurpose = "training" | "export" | "eval" | "replay" | "durable_persistence";
3
- export type CodaliDatasetSecretFindingKind = "sensitive_key" | "bearer_token" | "openai_api_key" | "cloud_access_key" | "github_token" | "jwt" | "private_key" | "env_secret_assignment";
3
+ export type CodaliDatasetSecretFindingKind = "sensitive_key" | "bearer_token" | "openai_api_key" | "cloud_access_key" | "github_token" | "jwt" | "private_key" | "env_secret_assignment" | "connector_api_key";
4
4
  export type CodaliDatasetEligibilityBlockerCode = "secrets_detected" | "privacy_training_not_allowed" | "privacy_export_not_allowed" | "object_training_not_allowed" | "object_export_not_allowed" | "object_eval_not_allowed" | "object_replay_not_allowed" | "retention_do_not_store" | "redaction_required" | "policy_override_requires_admin_audit" | "policy_override_not_requested" | "policy_override_hard_blocked";
5
5
  export interface CodaliDatasetSecretFinding {
6
6
  kind: CodaliDatasetSecretFindingKind;
@@ -1 +1 @@
1
- {"version":3,"file":"CodaliDatasetPrivacyEngine.d.ts","sourceRoot":"","sources":["../../src/storage/CodaliDatasetPrivacyEngine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CodaliDatasetPrivacyEngine.d.ts","sourceRoot":"","sources":["../../src/storage/CodaliDatasetPrivacyEngine.ts"],"names":[],"mappings":"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"}
@@ -30,6 +30,18 @@ const SECRET_VALUE_PATTERNS = [
30
30
  kind: "env_secret_assignment",
31
31
  pattern: /\b(?:API[_-]?KEY|TOKEN|SECRET|PASSWORD|PRIVATE[_-]?KEY)=["']?[^"'\s]{8,}["']?/gi,
32
32
  },
33
+ // Connector credentials. Added alongside the first MCP connector, because
34
+ // that is the point at which third-party secrets first flow through a run.
35
+ // The `sk-` rule above does not match underscore-delimited keys such as
36
+ // mswarm's `sk_prod_mswarm_...`, so those need their own rule.
37
+ {
38
+ kind: "connector_api_key",
39
+ pattern: /\bsk_[A-Za-z0-9]+_[A-Za-z0-9_]{8,}\b/g,
40
+ },
41
+ { kind: "connector_api_key", pattern: /\bglpat-[A-Za-z0-9_-]{16,}\b/g },
42
+ { kind: "connector_api_key", pattern: /\bxox[abprs]-[A-Za-z0-9-]{10,}\b/g },
43
+ { kind: "connector_api_key", pattern: /\bAIza[0-9A-Za-z_-]{30,}\b/g },
44
+ { kind: "connector_api_key", pattern: /\bnpm_[A-Za-z0-9]{30,}\b/g },
33
45
  ];
34
46
  const PERSONAL_KEY_PATTERNS = [
35
47
  /(^|[_-])(email|phone|ssn|person|user[_-]?id|requester)([_-]|$)/i,
@@ -1,9 +1,22 @@
1
- import { type ToolContext, type ToolDefinition, type ToolExecutionResult } from "./ToolTypes.js";
1
+ import { type ToolCapability, type ToolContext, type ToolDefinition, type ToolDescriptor, type ToolExecutionResult } from "./ToolTypes.js";
2
+ /**
3
+ * Projects a registered tool into its model-facing descriptor. Kept as a free
4
+ * function so connector adapters can reuse the same defaulting rules.
5
+ */
6
+ export declare const toolDescriptorFor: (tool: ToolDefinition) => ToolDescriptor;
2
7
  export declare class ToolRegistry {
3
8
  private tools;
4
9
  register(tool: ToolDefinition): void;
5
10
  list(): ToolDefinition[];
6
11
  describe(): Array<Pick<ToolDefinition, "name" | "description" | "inputSchema">>;
12
+ /**
13
+ * Model-facing view of the registry, optionally narrowed to a set of tool
14
+ * names. This is derived on every call rather than cached so the planner can
15
+ * never see a schema the executor would not honour.
16
+ */
17
+ catalog(names?: readonly string[]): ToolDescriptor[];
18
+ /** Capability -> tools, for the first stage of two-level tool exposure. */
19
+ capabilities(names?: readonly string[]): Map<ToolCapability, ToolDescriptor[]>;
7
20
  execute(name: string, args: unknown, context: ToolContext): Promise<ToolExecutionResult>;
8
21
  }
9
22
  //# sourceMappingURL=ToolRegistry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToolRegistry.d.ts","sourceRoot":"","sources":["../../src/tools/ToolRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,cAAc,EAGnB,KAAK,mBAAmB,EAGzB,MAAM,gBAAgB,CAAC;AA4QxB,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAqC;IAElD,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAOpC,IAAI,IAAI,cAAc,EAAE;IAIxB,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,aAAa,GAAG,aAAa,CAAC,CAAC;IAQzE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAkC/F"}
1
+ {"version":3,"file":"ToolRegistry.d.ts","sourceRoot":"","sources":["../../src/tools/ToolRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,cAAc,EAGnB,KAAK,mBAAmB,EAGzB,MAAM,gBAAgB,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,MAAM,cAAc,KAAG,cAOvD,CAAC;AA4QH,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAqC;IAElD,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAOpC,IAAI,IAAI,cAAc,EAAE;IAIxB,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,aAAa,GAAG,aAAa,CAAC,CAAC;IAQ/E;;;;OAIG;IACH,OAAO,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,cAAc,EAAE;IAOpD,2EAA2E;IAC3E,YAAY,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC,cAAc,EAAE,cAAc,EAAE,CAAC;IAaxE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAkC/F"}
@@ -1,4 +1,16 @@
1
- import { ToolExecutionError, toolErrorCategoryForCode, } from "./ToolTypes.js";
1
+ import { ToolExecutionError, toolCapabilityForName, toolErrorCategoryForCode, } from "./ToolTypes.js";
2
+ /**
3
+ * Projects a registered tool into its model-facing descriptor. Kept as a free
4
+ * function so connector adapters can reuse the same defaulting rules.
5
+ */
6
+ export const toolDescriptorFor = (tool) => ({
7
+ name: tool.name,
8
+ description: tool.description,
9
+ inputSchema: tool.inputSchema,
10
+ outputSchema: tool.outputSchema,
11
+ readOnly: tool.readOnly ?? false,
12
+ capability: tool.capability ?? toolCapabilityForName(tool.name),
13
+ });
2
14
  const isObject = (value) => {
3
15
  return typeof value === "object" && value !== null && !Array.isArray(value);
4
16
  };
@@ -262,6 +274,31 @@ export class ToolRegistry {
262
274
  inputSchema: tool.inputSchema,
263
275
  }));
264
276
  }
277
+ /**
278
+ * Model-facing view of the registry, optionally narrowed to a set of tool
279
+ * names. This is derived on every call rather than cached so the planner can
280
+ * never see a schema the executor would not honour.
281
+ */
282
+ catalog(names) {
283
+ const filter = names ? new Set(names) : undefined;
284
+ return this.list()
285
+ .filter((tool) => !filter || filter.has(tool.name))
286
+ .map((tool) => toolDescriptorFor(tool));
287
+ }
288
+ /** Capability -> tools, for the first stage of two-level tool exposure. */
289
+ capabilities(names) {
290
+ const grouped = new Map();
291
+ for (const descriptor of this.catalog(names)) {
292
+ const bucket = grouped.get(descriptor.capability);
293
+ if (bucket) {
294
+ bucket.push(descriptor);
295
+ }
296
+ else {
297
+ grouped.set(descriptor.capability, [descriptor]);
298
+ }
299
+ }
300
+ return grouped;
301
+ }
265
302
  async execute(name, args, context) {
266
303
  const tool = this.tools.get(name);
267
304
  if (!tool) {