agentfootprint 7.12.0 → 7.13.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.
Files changed (94) hide show
  1. package/dist/core/Agent.js +39 -5
  2. package/dist/core/Agent.js.map +1 -1
  3. package/dist/core/agent/AgentBuilder.js +59 -1
  4. package/dist/core/agent/AgentBuilder.js.map +1 -1
  5. package/dist/core/agent/buildAgentChart.js +6 -0
  6. package/dist/core/agent/buildAgentChart.js.map +1 -1
  7. package/dist/core/agent/buildDynamicAgentChart.js +14 -0
  8. package/dist/core/agent/buildDynamicAgentChart.js.map +1 -1
  9. package/dist/core/agent/stages/callLLM.js +10 -4
  10. package/dist/core/agent/stages/callLLM.js.map +1 -1
  11. package/dist/core/agent/stages/seed.js +16 -0
  12. package/dist/core/agent/stages/seed.js.map +1 -1
  13. package/dist/core/slots/buildSystemPromptSlot.js +2 -1
  14. package/dist/core/slots/buildSystemPromptSlot.js.map +1 -1
  15. package/dist/esm/core/Agent.d.ts +7 -3
  16. package/dist/esm/core/Agent.js +39 -5
  17. package/dist/esm/core/Agent.js.map +1 -1
  18. package/dist/esm/core/agent/AgentBuilder.d.ts +48 -1
  19. package/dist/esm/core/agent/AgentBuilder.js +59 -1
  20. package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
  21. package/dist/esm/core/agent/buildAgentChart.js +6 -0
  22. package/dist/esm/core/agent/buildAgentChart.js.map +1 -1
  23. package/dist/esm/core/agent/buildDynamicAgentChart.js +14 -0
  24. package/dist/esm/core/agent/buildDynamicAgentChart.js.map +1 -1
  25. package/dist/esm/core/agent/stages/callLLM.d.ts +9 -0
  26. package/dist/esm/core/agent/stages/callLLM.js +10 -4
  27. package/dist/esm/core/agent/stages/callLLM.js.map +1 -1
  28. package/dist/esm/core/agent/stages/seed.d.ts +10 -1
  29. package/dist/esm/core/agent/stages/seed.js +16 -0
  30. package/dist/esm/core/agent/stages/seed.js.map +1 -1
  31. package/dist/esm/core/agent/types.d.ts +44 -0
  32. package/dist/esm/core/slots/buildSystemPromptSlot.d.ts +19 -4
  33. package/dist/esm/core/slots/buildSystemPromptSlot.js +2 -1
  34. package/dist/esm/core/slots/buildSystemPromptSlot.js.map +1 -1
  35. package/dist/esm/lib/injection-engine/index.d.ts +1 -0
  36. package/dist/esm/lib/injection-engine/index.js +4 -0
  37. package/dist/esm/lib/injection-engine/index.js.map +1 -1
  38. package/dist/esm/lib/injection-engine/skillsFromDir.d.ts +80 -0
  39. package/dist/esm/lib/injection-engine/skillsFromDir.js +243 -0
  40. package/dist/esm/lib/injection-engine/skillsFromDir.js.map +1 -0
  41. package/dist/esm/lib/mcp/index.d.ts +6 -5
  42. package/dist/esm/lib/mcp/index.js +5 -4
  43. package/dist/esm/lib/mcp/index.js.map +1 -1
  44. package/dist/esm/lib/mcp/mcpClient.js +21 -9
  45. package/dist/esm/lib/mcp/mcpClient.js.map +1 -1
  46. package/dist/esm/lib/mcp/mcpServe.d.ts +70 -0
  47. package/dist/esm/lib/mcp/mcpServe.js +374 -0
  48. package/dist/esm/lib/mcp/mcpServe.js.map +1 -0
  49. package/dist/esm/lib/mcp/types.d.ts +130 -17
  50. package/dist/esm/lib/mcp/types.js +10 -10
  51. package/dist/esm/tool-providers/index.d.ts +8 -2
  52. package/dist/esm/tool-providers/index.js +7 -1
  53. package/dist/esm/tool-providers/index.js.map +1 -1
  54. package/dist/lib/injection-engine/index.js +6 -1
  55. package/dist/lib/injection-engine/index.js.map +1 -1
  56. package/dist/lib/injection-engine/skillsFromDir.js +270 -0
  57. package/dist/lib/injection-engine/skillsFromDir.js.map +1 -0
  58. package/dist/lib/mcp/index.js +7 -5
  59. package/dist/lib/mcp/index.js.map +1 -1
  60. package/dist/lib/mcp/mcpClient.js +21 -9
  61. package/dist/lib/mcp/mcpClient.js.map +1 -1
  62. package/dist/lib/mcp/mcpServe.js +401 -0
  63. package/dist/lib/mcp/mcpServe.js.map +1 -0
  64. package/dist/lib/mcp/types.js +10 -10
  65. package/dist/tool-providers/index.js +8 -1
  66. package/dist/tool-providers/index.js.map +1 -1
  67. package/dist/types/core/Agent.d.ts +7 -3
  68. package/dist/types/core/Agent.d.ts.map +1 -1
  69. package/dist/types/core/agent/AgentBuilder.d.ts +48 -1
  70. package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
  71. package/dist/types/core/agent/buildAgentChart.d.ts.map +1 -1
  72. package/dist/types/core/agent/buildDynamicAgentChart.d.ts.map +1 -1
  73. package/dist/types/core/agent/stages/callLLM.d.ts +9 -0
  74. package/dist/types/core/agent/stages/callLLM.d.ts.map +1 -1
  75. package/dist/types/core/agent/stages/seed.d.ts +10 -1
  76. package/dist/types/core/agent/stages/seed.d.ts.map +1 -1
  77. package/dist/types/core/agent/types.d.ts +44 -0
  78. package/dist/types/core/agent/types.d.ts.map +1 -1
  79. package/dist/types/core/slots/buildSystemPromptSlot.d.ts +19 -4
  80. package/dist/types/core/slots/buildSystemPromptSlot.d.ts.map +1 -1
  81. package/dist/types/lib/injection-engine/index.d.ts +1 -0
  82. package/dist/types/lib/injection-engine/index.d.ts.map +1 -1
  83. package/dist/types/lib/injection-engine/skillsFromDir.d.ts +81 -0
  84. package/dist/types/lib/injection-engine/skillsFromDir.d.ts.map +1 -0
  85. package/dist/types/lib/mcp/index.d.ts +6 -5
  86. package/dist/types/lib/mcp/index.d.ts.map +1 -1
  87. package/dist/types/lib/mcp/mcpClient.d.ts.map +1 -1
  88. package/dist/types/lib/mcp/mcpServe.d.ts +71 -0
  89. package/dist/types/lib/mcp/mcpServe.d.ts.map +1 -0
  90. package/dist/types/lib/mcp/types.d.ts +130 -17
  91. package/dist/types/lib/mcp/types.d.ts.map +1 -1
  92. package/dist/types/tool-providers/index.d.ts +8 -2
  93. package/dist/types/tool-providers/index.d.ts.map +1 -1
  94. package/package.json +2 -1
@@ -1,11 +1,14 @@
1
1
  /**
2
- * MCP — Model Context Protocol client integration.
2
+ * MCP — Model Context Protocol, in both directions.
3
3
  *
4
4
  * MCP (https://modelcontextprotocol.io) is an open standard for
5
- * connecting LLMs to external tools and data sources. agentfootprint's
6
- * MCP adapter is **client-only** — it consumes MCP servers and exposes
7
- * their tools as agentfootprint `Tool[]` so consumers can plug them
8
- * straight into `agent.tool(...)`.
5
+ * connecting LLMs to external tools and data sources. This module
6
+ * bridges it both ways:
7
+ *
8
+ * - `mcpClient(opts)` — consume an MCP server; its tools become
9
+ * agentfootprint `Tool[]` you can hand to `agent.tools(...)`.
10
+ * - `mcpServe(tools, opts)` — the other direction: expose your own
11
+ * `Tool[]` AS an MCP server, so any MCP client can call them.
9
12
  *
10
13
  * Pattern: Adapter (GoF) — translates MCP wire format ↔ agentfootprint
11
14
  * `Tool` interface. The MCP SDK does the protocol work; we
@@ -14,11 +17,8 @@
14
17
  * inline alternative for non-MCP tools).
15
18
  * Emits: N/A directly — wrapped tools emit the standard
16
19
  * `agentfootprint.stream.tool_start` / `tool_end` events
17
- * when the agent calls them.
18
- *
19
- * Server-side support (exposing an agent or LLMCall as an MCP tool)
20
- * is a separate concern not yet shipped. This module covers the
21
- * 80% case: pulling an existing MCP server's tools INTO an agent.
20
+ * when the agent calls them. `mcpServe` runs OUTSIDE any
21
+ * agent run, so it emits nothing at all.
22
22
  */
23
23
  import type { Tool } from '../../core/tools.js';
24
24
  /**
@@ -32,7 +32,13 @@ export interface McpStdioTransport {
32
32
  readonly command: string;
33
33
  /** CLI args passed to the executable. */
34
34
  readonly args?: readonly string[];
35
- /** Optional env vars set on the subprocess. */
35
+ /**
36
+ * Environment for the subprocess. Passed to the SDK as-is, and the SDK
37
+ * treats it as the WHOLE environment: set this and the child no longer
38
+ * inherits the safe default set (`PATH`, `HOME`, …). Omit it unless you
39
+ * mean to replace the environment; to merely add a variable, include the
40
+ * ones the child still needs.
41
+ */
36
42
  readonly env?: Readonly<Record<string, string>>;
37
43
  /** Working directory for the subprocess. */
38
44
  readonly cwd?: string;
@@ -107,22 +113,29 @@ export interface McpClient {
107
113
  * a lazy peer-dep)
108
114
  *
109
115
  * The real SDK exports a richer surface; we narrow to what's needed.
116
+ *
117
+ * Argument POSITION matters here and is easy to get wrong: the SDK keeps
118
+ * per-request options (`signal`, `timeout`) in a SEPARATE trailing
119
+ * argument, never inside the JSON-RPC params. A `signal` smuggled into
120
+ * the params object is serialized onto the wire as `{}` and silently
121
+ * fails to cancel anything, so these signatures mirror the SDK's own
122
+ * shape rather than a flattened convenience version of it.
110
123
  */
111
124
  export interface McpSdkClient {
112
- connect(transport: unknown): Promise<void>;
113
- listTools(): Promise<{
125
+ connect(transport: unknown, options?: McpRequestOptions): Promise<void>;
126
+ listTools(params?: undefined, options?: McpRequestOptions): Promise<{
114
127
  readonly tools: ReadonlyArray<{
115
128
  readonly name: string;
116
129
  readonly description?: string;
117
130
  readonly inputSchema: Readonly<Record<string, unknown>>;
118
131
  }>;
119
132
  }>;
120
- callTool(args: {
133
+ callTool(params: {
121
134
  readonly name: string;
122
135
  readonly arguments?: Readonly<Record<string, unknown>>;
123
- /** Forwarded from `McpClientOptions.signal` so consumers can cancel hung tool calls. */
124
- readonly signal?: AbortSignal;
125
- }): Promise<{
136
+ },
137
+ /** The SDK's result schema. We always want its default, so we pass `undefined`. */
138
+ resultSchema?: undefined, options?: McpRequestOptions): Promise<{
126
139
  readonly content: ReadonlyArray<{
127
140
  readonly type: string;
128
141
  readonly text?: string;
@@ -131,3 +144,103 @@ export interface McpSdkClient {
131
144
  }>;
132
145
  close(): Promise<void>;
133
146
  }
147
+ /**
148
+ * The SDK's trailing per-request options argument, narrowed to the one
149
+ * field we forward from {@link McpClientOptions.signal}.
150
+ */
151
+ export interface McpRequestOptions {
152
+ readonly signal?: AbortSignal;
153
+ }
154
+ /**
155
+ * `stdio` transport — the server speaks MCP over its own stdin/stdout.
156
+ * This is how a desktop MCP host launches a server: it spawns your
157
+ * process and talks down the pipe. The default.
158
+ *
159
+ * One consequence worth stating out loud: stdout belongs to the
160
+ * protocol. Anything else your process prints there corrupts the
161
+ * stream, so log to stderr.
162
+ */
163
+ export interface McpStdioServeTransport {
164
+ readonly transport: 'stdio';
165
+ }
166
+ /**
167
+ * `http` transport — the server listens on a port and speaks MCP over
168
+ * Streamable HTTP. Stateless (no session ids): every request is
169
+ * self-contained, which is what makes it safe to run several replicas
170
+ * behind a load balancer.
171
+ */
172
+ export interface McpHttpServeTransport {
173
+ readonly transport: 'http';
174
+ /** TCP port to listen on. */
175
+ readonly port: number;
176
+ /** Interface to bind. Defaults to Node's own default (all interfaces). */
177
+ readonly host?: string;
178
+ /** URL path the MCP endpoint answers on. Default `'/mcp'`. */
179
+ readonly path?: string;
180
+ }
181
+ export type McpServeTransport = McpStdioServeTransport | McpHttpServeTransport;
182
+ export interface McpServeOptions {
183
+ /**
184
+ * Server name reported to clients on connect. Surfaces in the
185
+ * client's server list. Default `'agentfootprint'`.
186
+ */
187
+ readonly name?: string;
188
+ /** Server version reported to clients. Default `'0.0.0'`. */
189
+ readonly version?: string;
190
+ /** Transport configuration. Default `{ transport: 'stdio' }`. */
191
+ readonly transport?: McpServeTransport;
192
+ /**
193
+ * Credential provider for served tools that declare `needs`. The
194
+ * credential is resolved BEFORE `execute` and injected as
195
+ * `ctx.credential`, exactly as the Agent's tool-call stage does it.
196
+ *
197
+ * Serving a `needs`-declaring tool without this is refused at
198
+ * construction: the tool would run with `ctx.credential` undefined
199
+ * and fail somewhere further in, or worse, not fail at all.
200
+ */
201
+ readonly credentials?: import('../../identity/types.js').CredentialProvider;
202
+ /**
203
+ * @internal Pre-built SDK server for tests. Skips SDK import +
204
+ * transport construction. Mirrors `McpClientOptions._client`.
205
+ */
206
+ readonly _server?: McpSdkServer;
207
+ }
208
+ /**
209
+ * What `mcpServe(...)` returns. The server is already listening by the
210
+ * time you hold this; `close()` is the only thing left to do.
211
+ */
212
+ export interface McpServeHandle {
213
+ /** Server name from options (or the default). */
214
+ readonly name: string;
215
+ /** Names of the tools being served, in the order clients will list them. */
216
+ readonly toolNames: readonly string[];
217
+ /**
218
+ * Stop serving: closes the transport (and, for `http`, the listening
219
+ * socket) and then the MCP server. Idempotent — calling it twice is
220
+ * not an error, so a shutdown hook and an explicit close can coexist.
221
+ */
222
+ close(): Promise<void>;
223
+ }
224
+ /**
225
+ * Minimal structural type for the parts of the MCP SDK's low-level
226
+ * `Server` we touch. Defined locally for the same two reasons as
227
+ * {@link McpSdkClient}: test injection via `McpServeOptions._server`,
228
+ * and no hard import on the lazy peer-dep.
229
+ */
230
+ export interface McpSdkServer {
231
+ setRequestHandler(schema: unknown, handler: (request: McpCallToolRequest, extra: {
232
+ readonly signal?: AbortSignal;
233
+ }) => unknown): void;
234
+ connect(transport: unknown): Promise<void>;
235
+ close(): Promise<void>;
236
+ }
237
+ /**
238
+ * The shape `tools/call` requests arrive in. `tools/list` requests carry
239
+ * no params we read, so one request type covers both handlers.
240
+ */
241
+ export interface McpCallToolRequest {
242
+ readonly params?: {
243
+ readonly name?: string;
244
+ readonly arguments?: unknown;
245
+ };
246
+ }
@@ -1,11 +1,14 @@
1
1
  /**
2
- * MCP — Model Context Protocol client integration.
2
+ * MCP — Model Context Protocol, in both directions.
3
3
  *
4
4
  * MCP (https://modelcontextprotocol.io) is an open standard for
5
- * connecting LLMs to external tools and data sources. agentfootprint's
6
- * MCP adapter is **client-only** — it consumes MCP servers and exposes
7
- * their tools as agentfootprint `Tool[]` so consumers can plug them
8
- * straight into `agent.tool(...)`.
5
+ * connecting LLMs to external tools and data sources. This module
6
+ * bridges it both ways:
7
+ *
8
+ * - `mcpClient(opts)` — consume an MCP server; its tools become
9
+ * agentfootprint `Tool[]` you can hand to `agent.tools(...)`.
10
+ * - `mcpServe(tools, opts)` — the other direction: expose your own
11
+ * `Tool[]` AS an MCP server, so any MCP client can call them.
9
12
  *
10
13
  * Pattern: Adapter (GoF) — translates MCP wire format ↔ agentfootprint
11
14
  * `Tool` interface. The MCP SDK does the protocol work; we
@@ -14,11 +17,8 @@
14
17
  * inline alternative for non-MCP tools).
15
18
  * Emits: N/A directly — wrapped tools emit the standard
16
19
  * `agentfootprint.stream.tool_start` / `tool_end` events
17
- * when the agent calls them.
18
- *
19
- * Server-side support (exposing an agent or LLMCall as an MCP tool)
20
- * is a separate concern not yet shipped. This module covers the
21
- * 80% case: pulling an existing MCP server's tools INTO an agent.
20
+ * when the agent calls them. `mcpServe` runs OUTSIDE any
21
+ * agent run, so it emits nothing at all.
22
22
  */
23
23
  export {};
24
24
  //# sourceMappingURL=types.js.map
@@ -13,6 +13,12 @@
13
13
  * - `mcpClient(opts)` — connect to an MCP server (real)
14
14
  * - `mockMcpClient({ tools })` — in-memory MCP source for dev / tests
15
15
  *
16
+ * 3. Tool sink — the other direction
17
+ * - `mcpServe(tools, opts)` — expose your own `Tool[]` AS an MCP
18
+ * server, so any MCP client can call them. The served tool is the
19
+ * SAME object you pass in, so whatever governance you composed
20
+ * around it still runs.
21
+ *
16
22
  * Compose freely. The dispatch layer is decorator-shaped (mirroring
17
23
  * `withRetry` / `withFallback` over LLMProvider). Tool sources produce
18
24
  * `Tool[]` that flow into a `staticTools(arr)` provider, which can
@@ -37,5 +43,5 @@ export { staticTools } from './staticTools.js';
37
43
  export { gatedTools } from './gatedTools.js';
38
44
  export { skillScopedTools } from './skillScopedTools.js';
39
45
  export type { ToolProvider, ToolDispatchContext, ToolGatePredicate } from './types.js';
40
- export { mcpClient, mockMcpClient } from '../lib/mcp/index.js';
41
- export type { McpClient, McpClientOptions, McpSdkClient, McpTransport, McpStdioTransport, McpHttpTransport, MockMcpClientOptions, MockMcpTool, } from '../lib/mcp/index.js';
46
+ export { mcpClient, mcpServe, mockMcpClient } from '../lib/mcp/index.js';
47
+ export type { McpClient, McpClientOptions, McpSdkClient, McpTransport, McpStdioTransport, McpHttpTransport, MockMcpClientOptions, MockMcpTool, McpServeOptions, McpServeHandle, McpServeTransport, McpStdioServeTransport, McpHttpServeTransport, McpSdkServer, } from '../lib/mcp/index.js';
@@ -13,6 +13,12 @@
13
13
  * - `mcpClient(opts)` — connect to an MCP server (real)
14
14
  * - `mockMcpClient({ tools })` — in-memory MCP source for dev / tests
15
15
  *
16
+ * 3. Tool sink — the other direction
17
+ * - `mcpServe(tools, opts)` — expose your own `Tool[]` AS an MCP
18
+ * server, so any MCP client can call them. The served tool is the
19
+ * SAME object you pass in, so whatever governance you composed
20
+ * around it still runs.
21
+ *
16
22
  * Compose freely. The dispatch layer is decorator-shaped (mirroring
17
23
  * `withRetry` / `withFallback` over LLMProvider). Tool sources produce
18
24
  * `Tool[]` that flow into a `staticTools(arr)` provider, which can
@@ -39,5 +45,5 @@ export { skillScopedTools } from './skillScopedTools.js';
39
45
  // Re-export tool sources from the MCP module so consumers find them in
40
46
  // one place. This subpath is the ONLY place `mcpClient` is public — the
41
47
  // top-level barrel does not re-export it.
42
- export { mcpClient, mockMcpClient } from '../lib/mcp/index.js';
48
+ export { mcpClient, mcpServe, mockMcpClient } from '../lib/mcp/index.js';
43
49
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tool-providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,uEAAuE;AACvE,wEAAwE;AACxE,0CAA0C;AAC1C,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tool-providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,uEAAuE;AACvE,wEAAwE;AACxE,0CAA0C;AAC1C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
@@ -7,7 +7,7 @@
7
7
  * factories. See `README.md` in this folder for the full concept.
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.skillToolNames = exports.checkSkillContracts = exports.checkSkillContract = exports.rankEntries = exports.embeddingScorer = exports.keywordScorer = exports.SKILL_GRAPH_METADATA_KEY = exports.decideSkill = exports.skillGraph = exports.defineInjection = exports.defineFact = exports.defineSteering = exports.buildReadSkillTool = exports.buildListSkillsTool = exports.SkillRegistry = exports.resolveSurfaceMode = exports.defineSkill = exports.defineRelevanceHint = exports.defineInstruction = exports.buildInjectionEngineSubflow = exports.evaluateInjections = exports.projectActiveInjection = void 0;
10
+ exports.skillToolNames = exports.checkSkillContracts = exports.checkSkillContract = exports.rankEntries = exports.embeddingScorer = exports.keywordScorer = exports.SKILL_GRAPH_METADATA_KEY = exports.decideSkill = exports.skillGraph = exports.defineInjection = exports.defineFact = exports.defineSteering = exports.buildReadSkillTool = exports.buildListSkillsTool = exports.skillsFromDir = exports.SkillRegistry = exports.resolveSurfaceMode = exports.defineSkill = exports.defineRelevanceHint = exports.defineInstruction = exports.buildInjectionEngineSubflow = exports.evaluateInjections = exports.projectActiveInjection = void 0;
11
11
  // POJO projection — used by slot subflows + advanced consumers
12
12
  var types_js_1 = require("./types.js");
13
13
  Object.defineProperty(exports, "projectActiveInjection", { enumerable: true, get: function () { return types_js_1.projectActiveInjection; } });
@@ -26,6 +26,11 @@ Object.defineProperty(exports, "defineSkill", { enumerable: true, get: function
26
26
  Object.defineProperty(exports, "resolveSurfaceMode", { enumerable: true, get: function () { return defineSkill_js_1.resolveSurfaceMode; } });
27
27
  var SkillRegistry_js_1 = require("./SkillRegistry.js");
28
28
  Object.defineProperty(exports, "SkillRegistry", { enumerable: true, get: function () { return SkillRegistry_js_1.SkillRegistry; } });
29
+ // File-authored skills — a loader over `defineSkill`, not a second mechanism.
30
+ // Node-only (reads the filesystem); node:fs is imported lazily inside the call
31
+ // so this barrel stays safe to import from a browser bundle.
32
+ var skillsFromDir_js_1 = require("./skillsFromDir.js");
33
+ Object.defineProperty(exports, "skillsFromDir", { enumerable: true, get: function () { return skillsFromDir_js_1.skillsFromDir; } });
29
34
  // Skill-tool builders — used by SkillRegistry.toTools() and the Agent's
30
35
  // auto-attach path. Exported so consumers building custom tool wiring
31
36
  // (e.g., gatedTools chains) can compose the same `list_skills` /
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/injection-engine/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAYH,+DAA+D;AAC/D,uCAAoD;AAA3C,kHAAA,sBAAsB,OAAA;AAE/B,SAAS;AACT,+CAAoD;AAA3C,kHAAA,kBAAkB,OAAA;AAC3B,mFAG0C;AAFxC,6IAAA,2BAA2B,OAAA;AAI7B,gFAAgF;AAChF,yEAAoG;AAA3F,yHAAA,iBAAiB,OAAA;AAC1B,6EAAoG;AAA3F,6HAAA,mBAAmB,OAAA;AAE5B,6DAOoC;AANlC,6GAAA,WAAW,OAAA;AACX,oHAAA,kBAAkB,OAAA;AAOpB,uDAA8E;AAArE,iHAAA,aAAa,OAAA;AAEtB,wEAAwE;AACxE,sEAAsE;AACtE,iEAAiE;AACjE,+BAA+B;AAC/B,iDAA8F;AAArF,oHAAA,mBAAmB,OAAA;AAAE,mHAAA,kBAAkB,OAAA;AAEhD,mEAA2F;AAAlF,mHAAA,cAAc,OAAA;AAEvB,2DAA+E;AAAtE,2GAAA,UAAU,OAAA;AAEnB,6EAA6E;AAC7E,0EAA0E;AAC1E,qDAAqD;AACrD,qEAIwC;AAHtC,qHAAA,eAAe,OAAA;AAKjB,4EAA4E;AAC5E,8EAA8E;AAC9E,iDAuByB;AAtBvB,2GAAA,UAAU,OAAA;AACV,4GAAA,WAAW,OAAA;AACX,yHAAA,wBAAwB,OAAA;AAqB1B,mDAO0B;AANxB,+GAAA,aAAa,OAAA;AACb,iHAAA,eAAe,OAAA;AACf,6GAAA,WAAW,OAAA;AAKb,uDAA6F;AAApF,sHAAA,kBAAkB,OAAA;AAAE,uHAAA,mBAAmB,OAAA;AAAE,kHAAA,cAAc,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/injection-engine/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAYH,+DAA+D;AAC/D,uCAAoD;AAA3C,kHAAA,sBAAsB,OAAA;AAE/B,SAAS;AACT,+CAAoD;AAA3C,kHAAA,kBAAkB,OAAA;AAC3B,mFAG0C;AAFxC,6IAAA,2BAA2B,OAAA;AAI7B,gFAAgF;AAChF,yEAAoG;AAA3F,yHAAA,iBAAiB,OAAA;AAC1B,6EAAoG;AAA3F,6HAAA,mBAAmB,OAAA;AAE5B,6DAOoC;AANlC,6GAAA,WAAW,OAAA;AACX,oHAAA,kBAAkB,OAAA;AAOpB,uDAA8E;AAArE,iHAAA,aAAa,OAAA;AAEtB,8EAA8E;AAC9E,+EAA+E;AAC/E,6DAA6D;AAC7D,uDAA8E;AAArE,iHAAA,aAAa,OAAA;AAEtB,wEAAwE;AACxE,sEAAsE;AACtE,iEAAiE;AACjE,+BAA+B;AAC/B,iDAA8F;AAArF,oHAAA,mBAAmB,OAAA;AAAE,mHAAA,kBAAkB,OAAA;AAEhD,mEAA2F;AAAlF,mHAAA,cAAc,OAAA;AAEvB,2DAA+E;AAAtE,2GAAA,UAAU,OAAA;AAEnB,6EAA6E;AAC7E,0EAA0E;AAC1E,qDAAqD;AACrD,qEAIwC;AAHtC,qHAAA,eAAe,OAAA;AAKjB,4EAA4E;AAC5E,8EAA8E;AAC9E,iDAuByB;AAtBvB,2GAAA,UAAU,OAAA;AACV,4GAAA,WAAW,OAAA;AACX,yHAAA,wBAAwB,OAAA;AAqB1B,mDAO0B;AANxB,+GAAA,aAAa,OAAA;AACb,iHAAA,eAAe,OAAA;AACf,6GAAA,WAAW,OAAA;AAKb,uDAA6F;AAApF,sHAAA,kBAAkB,OAAA;AAAE,uHAAA,mBAAmB,OAAA;AAAE,kHAAA,cAAc,OAAA"}
@@ -0,0 +1,270 @@
1
+ "use strict";
2
+ /**
3
+ * skillsFromDir — load Skills that were AUTHORED AS FILES.
4
+ *
5
+ * The just-in-time half of skills already ships: `defineSkill` produces an
6
+ * Injection whose `description` is all the model sees until it calls
7
+ * `read_skill(<id>)`, at which point the body enters the context. What did not
8
+ * ship was the other half — a way to keep those bodies where prose belongs, in
9
+ * files, next to the code they describe, reviewable in a diff.
10
+ *
11
+ * This is that loader, and nothing more. It reads a directory of `SKILL.md`
12
+ * files and hands each one to `defineSkill`. The progressive disclosure, the
13
+ * activation tool, the slot routing — all unchanged, all upstream of here.
14
+ *
15
+ * skills/
16
+ * billing/SKILL.md
17
+ * refunds/SKILL.md
18
+ *
19
+ * ---
20
+ * name: billing
21
+ * description: Use for refunds, charges and billing questions.
22
+ * ---
23
+ * When handling billing: confirm identity first, then …
24
+ *
25
+ * const skills = await skillsFromDir('./skills');
26
+ * const agent = Agent.create({ provider, model }).skills({ list: () => skills }).build();
27
+ *
28
+ * The frontmatter is the disclosure stub (`name` + `description` — what the
29
+ * model reads when deciding), and everything after the closing fence is the
30
+ * body (what it reads after deciding). That is the same file convention Claude
31
+ * Code made familiar, so a skill folder is portable between the two.
32
+ *
33
+ * ── Why authorship is decided here, at load time ─────────────────────────────
34
+ * A Skill body is *instructions to a model*. Where it came from is therefore a
35
+ * security property, not a convenience: content fetched at run time from
36
+ * somewhere else is content someone else can change after you reviewed it.
37
+ * This loader accepts a local directory and nothing else — a URL is refused BY
38
+ * NAME rather than fetched — because "these files are mine" is a claim you can
39
+ * only make about a path on your own disk at build time. Each file is read
40
+ * ONCE, here; a later edit does not reach a run already in flight.
41
+ *
42
+ * Node-only. `node:fs/promises` and `node:path` are imported lazily inside the
43
+ * call, the same gating `lib/tool-lint/cli.ts` uses: this module is reachable
44
+ * from the `agentfootprint/injection-engine` barrel, and a TOP-LEVEL node:fs
45
+ * import detonates a browser bundle at module-eval even when nothing calls it.
46
+ */
47
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
48
+ if (k2 === undefined) k2 = k;
49
+ var desc = Object.getOwnPropertyDescriptor(m, k);
50
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
51
+ desc = { enumerable: true, get: function() { return m[k]; } };
52
+ }
53
+ Object.defineProperty(o, k2, desc);
54
+ }) : (function(o, m, k, k2) {
55
+ if (k2 === undefined) k2 = k;
56
+ o[k2] = m[k];
57
+ }));
58
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
59
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
60
+ }) : function(o, v) {
61
+ o["default"] = v;
62
+ });
63
+ var __importStar = (this && this.__importStar) || function (mod) {
64
+ if (mod && mod.__esModule) return mod;
65
+ var result = {};
66
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
67
+ __setModuleDefault(result, mod);
68
+ return result;
69
+ };
70
+ Object.defineProperty(exports, "__esModule", { value: true });
71
+ exports.skillsFromDir = void 0;
72
+ const defineSkill_js_1 = require("./factories/defineSkill.js");
73
+ /** The file name every skill folder is expected to use. */
74
+ const SKILL_FILE = 'SKILL.md';
75
+ /**
76
+ * Skill ids ride into `read_skill`'s `enum` and into the skill-graph's node
77
+ * ids. The house tool-name charset keeps them quotable in a prompt, comparable
78
+ * as plain strings, and safe as an object key.
79
+ */
80
+ const SKILL_NAME_RE = /^[a-zA-Z0-9_-]{1,64}$/;
81
+ /** Anything of the form `scheme://…` — http, https, s3, git+ssh, file, … */
82
+ const URL_LIKE_RE = /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//;
83
+ /**
84
+ * Load every `SKILL.md` under `dir` as a Skill Injection.
85
+ *
86
+ * Two layouts are accepted, and they can be mixed:
87
+ * - `dir/<anything>/SKILL.md` — one folder per skill (the portable layout,
88
+ * and the one to prefer: the folder can hold the skill's other assets).
89
+ * - `dir/SKILL.md` — the directory IS one skill.
90
+ *
91
+ * The returned array is sorted by skill name, so a chart built from it is
92
+ * stable regardless of the order the filesystem happened to hand back.
93
+ *
94
+ * @param dir - A local filesystem path. A URL (or any `scheme://` string, or a
95
+ * UNC network path) is refused by name — see the module header for why.
96
+ * @param opts - Applied uniformly to every loaded skill.
97
+ *
98
+ * @throws when `dir` is not a local path, does not exist, is not a directory,
99
+ * or contains no `SKILL.md` at all; when a file's frontmatter is malformed
100
+ * (the message names the file); or when two files claim the same skill name
101
+ * (the message names both).
102
+ */
103
+ async function skillsFromDir(dir, opts = {}) {
104
+ assertLocalDirectoryArgument(dir);
105
+ // Lazy node imports (browser-compat) — see module header.
106
+ const { readdir, readFile, stat } = await Promise.resolve().then(() => __importStar(require('node:fs/promises')));
107
+ const { join } = await Promise.resolve().then(() => __importStar(require('node:path')));
108
+ let isDirectory = false;
109
+ try {
110
+ isDirectory = (await stat(dir)).isDirectory();
111
+ }
112
+ catch {
113
+ throw new Error(`skillsFromDir: '${dir}' does not exist. Pass the directory that holds your ` +
114
+ `${SKILL_FILE} folders.`);
115
+ }
116
+ if (!isDirectory) {
117
+ throw new Error(`skillsFromDir: '${dir}' is a file, not a directory. Pass the directory that holds ` +
118
+ `your ${SKILL_FILE} folders.`);
119
+ }
120
+ const entries = await readdir(dir, { withFileTypes: true });
121
+ const files = [];
122
+ // `dir/SKILL.md` — the whole directory is one skill.
123
+ if (entries.some((e) => e.isFile() && e.name === SKILL_FILE)) {
124
+ files.push(join(dir, SKILL_FILE));
125
+ }
126
+ // `dir/<folder>/SKILL.md` — the portable layout.
127
+ for (const entry of entries) {
128
+ if (!entry.isDirectory())
129
+ continue;
130
+ const candidate = join(dir, entry.name, SKILL_FILE);
131
+ try {
132
+ if ((await stat(candidate)).isFile())
133
+ files.push(candidate);
134
+ }
135
+ catch {
136
+ // A subdirectory without a SKILL.md is not an error — a skill folder can
137
+ // sit next to assets, fixtures, or anything else the author keeps here.
138
+ }
139
+ }
140
+ if (files.length === 0) {
141
+ throw new Error(`skillsFromDir: no ${SKILL_FILE} found under '${dir}'. Expected '${dir}/<skill>/${SKILL_FILE}' ` +
142
+ `or '${dir}/${SKILL_FILE}'.`);
143
+ }
144
+ const parsed = [];
145
+ for (const file of files.sort()) {
146
+ parsed.push(parseSkillFile(await readFile(file, 'utf8'), file));
147
+ }
148
+ // Collisions are refused naming BOTH files: with only the id in the message
149
+ // you would know a duplicate exists and still have to go find the pair.
150
+ const byName = new Map();
151
+ for (const skill of parsed) {
152
+ const clash = byName.get(skill.name);
153
+ if (clash) {
154
+ throw new Error(`skillsFromDir: two files claim the skill name '${skill.name}' — '${clash.file}' and ` +
155
+ `'${skill.file}'. Skill ids must be unique (read_skill dispatches by id); rename one.`);
156
+ }
157
+ byName.set(skill.name, skill);
158
+ }
159
+ return parsed
160
+ .slice()
161
+ .sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0))
162
+ .map((skill) => (0, defineSkill_js_1.defineSkill)({
163
+ id: skill.name,
164
+ description: skill.description,
165
+ body: skill.body,
166
+ ...(opts.viaToolName !== undefined && { viaToolName: opts.viaToolName }),
167
+ ...(opts.surfaceMode !== undefined && { surfaceMode: opts.surfaceMode }),
168
+ }));
169
+ }
170
+ exports.skillsFromDir = skillsFromDir;
171
+ // ─── Authorship guard ──────────────────────────────────────────────
172
+ /**
173
+ * Refuse anything that is not a local path, BY NAME. The message quotes what
174
+ * was passed, because the whole point is that the reader can see the thing
175
+ * that was rejected.
176
+ */
177
+ function assertLocalDirectoryArgument(dir) {
178
+ if (typeof dir !== 'string' || dir.trim().length === 0) {
179
+ throw new Error(`skillsFromDir: expected a local directory path, got ${JSON.stringify(dir)}.`);
180
+ }
181
+ const scheme = URL_LIKE_RE.exec(dir);
182
+ if (scheme) {
183
+ throw new Error(`skillsFromDir: '${dir}' is a ${scheme[0].slice(0, -3)} URL, not a local directory. ` +
184
+ `Skill bodies are instructions to a model, so this loader only reads files you own ` +
185
+ `at build time — fetch remote content yourself, review it, and pass defineSkill(...) ` +
186
+ `the result.`);
187
+ }
188
+ if (dir.startsWith('\\\\')) {
189
+ throw new Error(`skillsFromDir: '${dir}' is a network (UNC) path, not a local directory. ` +
190
+ `Skill bodies are instructions to a model, so this loader only reads files you own ` +
191
+ `at build time.`);
192
+ }
193
+ }
194
+ // ─── Frontmatter ───────────────────────────────────────────────────
195
+ /**
196
+ * Parse one `SKILL.md`. Every refusal names the file — a loader that says
197
+ * "malformed frontmatter" over a directory of forty files has told you nothing.
198
+ *
199
+ * The grammar is deliberately small: an opening `---` line, `key: value` lines
200
+ * (`#` comments and blank lines skipped, single/double quotes stripped), a
201
+ * closing `---` line, then the body. Keys other than `name` and `description`
202
+ * are IGNORED rather than rejected, so a file carrying extra frontmatter for
203
+ * another tool still loads here.
204
+ */
205
+ function parseSkillFile(raw, file) {
206
+ // Strip a UTF-8 BOM — an editor artifact, not the author's intent.
207
+ const text = raw.charCodeAt(0) === 0xfeff ? raw.slice(1) : raw;
208
+ const lines = text.split(/\r?\n/);
209
+ if (lines[0]?.trim() !== '---') {
210
+ throw new Error(`skillsFromDir: '${file}' does not start with a '---' frontmatter block. ` +
211
+ `Expected:\n---\nname: my-skill\ndescription: When to use it.\n---\n<the body>`);
212
+ }
213
+ const closingIndex = lines.findIndex((line, i) => i > 0 && line.trim() === '---');
214
+ if (closingIndex === -1) {
215
+ throw new Error(`skillsFromDir: '${file}' opens a '---' frontmatter block that is never closed. ` +
216
+ `Add a '---' line after the last frontmatter key.`);
217
+ }
218
+ const fields = new Map();
219
+ for (let i = 1; i < closingIndex; i++) {
220
+ const line = lines[i] ?? '';
221
+ if (line.trim().length === 0 || line.trimStart().startsWith('#'))
222
+ continue;
223
+ const separator = line.indexOf(':');
224
+ if (separator === -1) {
225
+ throw new Error(`skillsFromDir: '${file}' frontmatter line ${i + 1} is not 'key: value' — got ` +
226
+ `${JSON.stringify(line)}.`);
227
+ }
228
+ const key = line.slice(0, separator).trim();
229
+ if (key.length === 0) {
230
+ throw new Error(`skillsFromDir: '${file}' frontmatter line ${i + 1} has an empty key — got ` +
231
+ `${JSON.stringify(line)}.`);
232
+ }
233
+ fields.set(key, unquote(line.slice(separator + 1).trim()));
234
+ }
235
+ const name = fields.get('name') ?? '';
236
+ const description = fields.get('description') ?? '';
237
+ const body = lines
238
+ .slice(closingIndex + 1)
239
+ .join('\n')
240
+ .trim();
241
+ if (name.length === 0) {
242
+ throw new Error(`skillsFromDir: '${file}' frontmatter is missing 'name'. It becomes the skill id the ` +
243
+ `model passes to read_skill.`);
244
+ }
245
+ if (!SKILL_NAME_RE.test(name)) {
246
+ throw new Error(`skillsFromDir: '${file}' frontmatter name '${name}' must match ` +
247
+ `/^[a-zA-Z0-9_-]{1,64}$/ — it is the id the model passes to read_skill.`);
248
+ }
249
+ if (description.length === 0) {
250
+ throw new Error(`skillsFromDir: '${file}' frontmatter is missing 'description'. It is the ONLY thing ` +
251
+ `the model reads when deciding whether to open this skill.`);
252
+ }
253
+ if (body.length === 0) {
254
+ throw new Error(`skillsFromDir: '${file}' has no body after the closing '---'. The body is what the ` +
255
+ `model reads once it activates the skill.`);
256
+ }
257
+ return { name, description, body, file };
258
+ }
259
+ /** Strip one layer of matching single or double quotes from a YAML-ish scalar. */
260
+ function unquote(value) {
261
+ if (value.length >= 2) {
262
+ const first = value[0];
263
+ const last = value[value.length - 1];
264
+ if ((first === '"' && last === '"') || (first === "'" && last === "'")) {
265
+ return value.slice(1, -1);
266
+ }
267
+ }
268
+ return value;
269
+ }
270
+ //# sourceMappingURL=skillsFromDir.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skillsFromDir.js","sourceRoot":"","sources":["../../../src/lib/injection-engine/skillsFromDir.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mockMcpClient = exports.mcpClient = void 0;
3
+ exports.mockMcpClient = exports.mcpServe = exports.mcpClient = void 0;
4
4
  /**
5
- * MCP — Model Context Protocol client integration. Connect to an MCP
6
- * server, register its tools on your Agent. Server-side support is
7
- * separate (consumer exposes their agent as an MCP tool — different
8
- * use case, not yet shipped).
5
+ * MCP — Model Context Protocol, both directions. `mcpClient` connects to
6
+ * someone else's MCP server and registers its tools on your Agent;
7
+ * `mcpServe` exposes your own tools AS an MCP server so any MCP client
8
+ * can call them.
9
9
  */
10
10
  var mcpClient_js_1 = require("./mcpClient.js");
11
11
  Object.defineProperty(exports, "mcpClient", { enumerable: true, get: function () { return mcpClient_js_1.mcpClient; } });
12
+ var mcpServe_js_1 = require("./mcpServe.js");
13
+ Object.defineProperty(exports, "mcpServe", { enumerable: true, get: function () { return mcpServe_js_1.mcpServe; } });
12
14
  var mockMcpClient_js_1 = require("./mockMcpClient.js");
13
15
  Object.defineProperty(exports, "mockMcpClient", { enumerable: true, get: function () { return mockMcpClient_js_1.mockMcpClient; } });
14
16
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/mcp/index.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,+CAA2C;AAAlC,yGAAA,SAAS,OAAA;AAClB,uDAAgG;AAAvF,iHAAA,aAAa,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/mcp/index.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,+CAA2C;AAAlC,yGAAA,SAAS,OAAA;AAClB,6CAAyC;AAAhC,uGAAA,QAAQ,OAAA;AACjB,uDAAgG;AAAvF,iHAAA,aAAa,OAAA"}