hono-apcore 0.1.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/LICENSE +190 -0
- package/README.md +426 -0
- package/dist/a2a/apcore-a2a.service.d.ts +44 -0
- package/dist/a2a/apcore-a2a.service.d.ts.map +1 -0
- package/dist/a2a/apcore-a2a.service.js +82 -0
- package/dist/a2a/apcore-a2a.service.js.map +1 -0
- package/dist/a2a/index.d.ts +2 -0
- package/dist/a2a/index.d.ts.map +1 -0
- package/dist/a2a/index.js +2 -0
- package/dist/a2a/index.js.map +1 -0
- package/dist/bridge/binding-loader.d.ts +45 -0
- package/dist/bridge/binding-loader.d.ts.map +1 -0
- package/dist/bridge/binding-loader.js +84 -0
- package/dist/bridge/binding-loader.js.map +1 -0
- package/dist/bridge/index.d.ts +3 -0
- package/dist/bridge/index.d.ts.map +1 -0
- package/dist/bridge/index.js +2 -0
- package/dist/bridge/index.js.map +1 -0
- package/dist/cli/apcore-cli.service.d.ts +50 -0
- package/dist/cli/apcore-cli.service.d.ts.map +1 -0
- package/dist/cli/apcore-cli.service.js +76 -0
- package/dist/cli/apcore-cli.service.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +247 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +55 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +86 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts +27 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +27 -0
- package/dist/constants.js.map +1 -0
- package/dist/context/hono-context.factory.d.ts +61 -0
- package/dist/context/hono-context.factory.d.ts.map +1 -0
- package/dist/context/hono-context.factory.js +117 -0
- package/dist/context/hono-context.factory.js.map +1 -0
- package/dist/context/index.d.ts +3 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +2 -0
- package/dist/context/index.js.map +1 -0
- package/dist/core/apcore.d.ts +135 -0
- package/dist/core/apcore.d.ts.map +1 -0
- package/dist/core/apcore.js +257 -0
- package/dist/core/apcore.js.map +1 -0
- package/dist/core/executor.d.ts +32 -0
- package/dist/core/executor.d.ts.map +1 -0
- package/dist/core/executor.js +41 -0
- package/dist/core/executor.js.map +1 -0
- package/dist/core/middleware.d.ts +61 -0
- package/dist/core/middleware.d.ts.map +1 -0
- package/dist/core/middleware.js +51 -0
- package/dist/core/middleware.js.map +1 -0
- package/dist/core/registry.d.ts +79 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +218 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +71 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/apcore-mcp.service.d.ts +83 -0
- package/dist/mcp/apcore-mcp.service.d.ts.map +1 -0
- package/dist/mcp/apcore-mcp.service.js +189 -0
- package/dist/mcp/apcore-mcp.service.js.map +1 -0
- package/dist/mcp/index.d.ts +5 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +3 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/mount.d.ts +51 -0
- package/dist/mcp/mount.d.ts.map +1 -0
- package/dist/mcp/mount.js +95 -0
- package/dist/mcp/mount.js.map +1 -0
- package/dist/output/index.d.ts +3 -0
- package/dist/output/index.d.ts.map +1 -0
- package/dist/output/index.js +2 -0
- package/dist/output/index.js.map +1 -0
- package/dist/output/yaml-writer.d.ts +31 -0
- package/dist/output/yaml-writer.d.ts.map +1 -0
- package/dist/output/yaml-writer.js +49 -0
- package/dist/output/yaml-writer.js.map +1 -0
- package/dist/scanners/hono-route-scanner.d.ts +60 -0
- package/dist/scanners/hono-route-scanner.d.ts.map +1 -0
- package/dist/scanners/hono-route-scanner.js +217 -0
- package/dist/scanners/hono-route-scanner.js.map +1 -0
- package/dist/scanners/index.d.ts +3 -0
- package/dist/scanners/index.d.ts.map +1 -0
- package/dist/scanners/index.js +2 -0
- package/dist/scanners/index.js.map +1 -0
- package/dist/schema/adapters/json-schema.adapter.d.ts +23 -0
- package/dist/schema/adapters/json-schema.adapter.d.ts.map +1 -0
- package/dist/schema/adapters/json-schema.adapter.js +40 -0
- package/dist/schema/adapters/json-schema.adapter.js.map +1 -0
- package/dist/schema/adapters/schema-adapter.interface.d.ts +24 -0
- package/dist/schema/adapters/schema-adapter.interface.d.ts.map +1 -0
- package/dist/schema/adapters/schema-adapter.interface.js +2 -0
- package/dist/schema/adapters/schema-adapter.interface.js.map +1 -0
- package/dist/schema/adapters/typebox.adapter.d.ts +26 -0
- package/dist/schema/adapters/typebox.adapter.d.ts.map +1 -0
- package/dist/schema/adapters/typebox.adapter.js +39 -0
- package/dist/schema/adapters/typebox.adapter.js.map +1 -0
- package/dist/schema/adapters/zod.adapter.d.ts +17 -0
- package/dist/schema/adapters/zod.adapter.d.ts.map +1 -0
- package/dist/schema/adapters/zod.adapter.js +372 -0
- package/dist/schema/adapters/zod.adapter.js.map +1 -0
- package/dist/schema/index.d.ts +6 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +5 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/schema-extractor.d.ts +51 -0
- package/dist/schema/schema-extractor.d.ts.map +1 -0
- package/dist/schema/schema-extractor.js +89 -0
- package/dist/schema/schema-extractor.js.map +1 -0
- package/dist/tools/define-tool.d.ts +68 -0
- package/dist/tools/define-tool.d.ts.map +1 -0
- package/dist/tools/define-tool.js +122 -0
- package/dist/tools/define-tool.js.map +1 -0
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types.d.ts +246 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/id-generator.d.ts +52 -0
- package/dist/utils/id-generator.d.ts.map +1 -0
- package/dist/utils/id-generator.js +87 -0
- package/dist/utils/id-generator.js.map +1 -0
- package/dist/utils/module-factory.d.ts +34 -0
- package/dist/utils/module-factory.d.ts.map +1 -0
- package/dist/utils/module-factory.js +59 -0
- package/dist/utils/module-factory.js.map +1 -0
- package/package.json +109 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Context as ApcoreContext, TraceContext, createIdentity } from 'apcore-js';
|
|
2
|
+
function isHeaders(value) {
|
|
3
|
+
return (value !== null &&
|
|
4
|
+
typeof value === 'object' &&
|
|
5
|
+
typeof value.get === 'function' &&
|
|
6
|
+
typeof value.forEach === 'function');
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Reduce any {@link HeaderSource} to a `Headers` instance.
|
|
10
|
+
*
|
|
11
|
+
* `Headers` already matches header names case-insensitively, so downstream
|
|
12
|
+
* lookups need no normalisation of their own.
|
|
13
|
+
*/
|
|
14
|
+
export function toHeaders(source) {
|
|
15
|
+
if (isHeaders(source))
|
|
16
|
+
return source;
|
|
17
|
+
if (source instanceof Request)
|
|
18
|
+
return source.headers;
|
|
19
|
+
const req = source.req;
|
|
20
|
+
if (req?.raw instanceof Request)
|
|
21
|
+
return req.raw.headers;
|
|
22
|
+
const raw = source.headers;
|
|
23
|
+
if (isHeaders(raw))
|
|
24
|
+
return raw;
|
|
25
|
+
const headers = new Headers();
|
|
26
|
+
if (raw !== null && typeof raw === 'object') {
|
|
27
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
28
|
+
if (typeof value === 'string') {
|
|
29
|
+
headers.set(key, value);
|
|
30
|
+
}
|
|
31
|
+
else if (Array.isArray(value) && value.length > 0) {
|
|
32
|
+
headers.set(key, String(value[0]));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return headers;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Builds apcore `Context` objects from Hono requests.
|
|
40
|
+
*
|
|
41
|
+
* **Identity resolution**, in order:
|
|
42
|
+
* 1. `x-user-id` header
|
|
43
|
+
* 2. `Authorization: Bearer <token>` (identity id `"bearer"`)
|
|
44
|
+
* 3. `x-roles` alone — a demo shortcut for role-based ACL without auth
|
|
45
|
+
* 4. anonymous
|
|
46
|
+
*
|
|
47
|
+
* **W3C Trace Context** — a `traceparent` header supplies the trace id.
|
|
48
|
+
* Strict 32-hex validation and rejection of W3C-invalid ids happen inside
|
|
49
|
+
* `Context.create`, not here (PROTOCOL_SPEC §10.5).
|
|
50
|
+
*
|
|
51
|
+
* **Correlation id** — `x-correlation-id` (or `x-request-id`) is copied into
|
|
52
|
+
* `context.data["x-correlation-id"]` so existing log pipelines keep working.
|
|
53
|
+
*
|
|
54
|
+
* Pass a `resolveIdentity` override to plug in real authentication: whatever
|
|
55
|
+
* it returns wins over the header heuristics above.
|
|
56
|
+
*/
|
|
57
|
+
export class HonoContextFactory {
|
|
58
|
+
options;
|
|
59
|
+
constructor(options = {}) {
|
|
60
|
+
this.options = options;
|
|
61
|
+
}
|
|
62
|
+
/** Create an apcore `Context` from a Hono context, `Request`, or headers. */
|
|
63
|
+
createContext(source) {
|
|
64
|
+
const headers = toHeaders(source);
|
|
65
|
+
const identity = this.extractIdentity(headers);
|
|
66
|
+
const traceParent = this.extractTraceParent(headers);
|
|
67
|
+
const data = {
|
|
68
|
+
...this.extractData(headers),
|
|
69
|
+
...(this.options.data?.(headers) ?? {}),
|
|
70
|
+
};
|
|
71
|
+
return ApcoreContext.create(identity, traceParent, null, data);
|
|
72
|
+
}
|
|
73
|
+
extractTraceParent(headers) {
|
|
74
|
+
return TraceContext.extract(headers);
|
|
75
|
+
}
|
|
76
|
+
extractIdentity(headers) {
|
|
77
|
+
const custom = this.options.resolveIdentity?.(headers);
|
|
78
|
+
if (custom)
|
|
79
|
+
return custom;
|
|
80
|
+
const roles = this.extractRoles(headers);
|
|
81
|
+
const userId = headers.get('x-user-id');
|
|
82
|
+
if (userId) {
|
|
83
|
+
return createIdentity(userId, 'user', roles);
|
|
84
|
+
}
|
|
85
|
+
const auth = headers.get('authorization');
|
|
86
|
+
if (auth && auth.toLowerCase().startsWith('bearer ')) {
|
|
87
|
+
return createIdentity('bearer', 'api_key', roles);
|
|
88
|
+
}
|
|
89
|
+
// An `x-roles` header on its own still identifies a roled user — a demo
|
|
90
|
+
// shortcut for exercising role-based ACL without full authentication.
|
|
91
|
+
if (roles.length > 0) {
|
|
92
|
+
return createIdentity('u1', 'user', roles);
|
|
93
|
+
}
|
|
94
|
+
return createIdentity('anonymous', 'anonymous');
|
|
95
|
+
}
|
|
96
|
+
/** Parse the comma-separated `x-roles` header into a role list. */
|
|
97
|
+
extractRoles(headers) {
|
|
98
|
+
const raw = headers.get('x-roles');
|
|
99
|
+
if (!raw)
|
|
100
|
+
return [];
|
|
101
|
+
return raw
|
|
102
|
+
.split(',')
|
|
103
|
+
.map((role) => role.trim())
|
|
104
|
+
.filter((role) => role.length > 0);
|
|
105
|
+
}
|
|
106
|
+
extractData(headers) {
|
|
107
|
+
const data = {};
|
|
108
|
+
const correlationId = headers.get('x-correlation-id') ?? headers.get('x-request-id');
|
|
109
|
+
if (correlationId) {
|
|
110
|
+
data['x-correlation-id'] = correlationId;
|
|
111
|
+
}
|
|
112
|
+
return data;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/** Shared factory used by the default `apcore()` middleware. */
|
|
116
|
+
export const defaultContextFactory = new HonoContextFactory();
|
|
117
|
+
//# sourceMappingURL=hono-context.factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hono-context.factory.js","sourceRoot":"","sources":["../../src/context/hono-context.factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACjG,YAAY,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { ApcoreRegistry } from './registry.js';
|
|
2
|
+
import { ApcoreExecutor } from './executor.js';
|
|
3
|
+
import { ApcoreMcpService } from '../mcp/apcore-mcp.service.js';
|
|
4
|
+
import { ApcoreCliService } from '../cli/apcore-cli.service.js';
|
|
5
|
+
import { ApcoreA2aService } from '../a2a/apcore-a2a.service.js';
|
|
6
|
+
import { HonoContextFactory } from '../context/hono-context.factory.js';
|
|
7
|
+
import type { HonoAppLike } from '../scanners/hono-route-scanner.js';
|
|
8
|
+
import type { TargetResolver } from '../bridge/binding-loader.js';
|
|
9
|
+
import type { MountableApp } from '../mcp/mount.js';
|
|
10
|
+
import type { McpApp } from '../mcp/apcore-mcp.service.js';
|
|
11
|
+
import type { ApcoreSettings } from '../config.js';
|
|
12
|
+
import type { ApToolDefinition, HonoApcoreOptions, MountMcpOptions, RegisterMethodOptions, RegisterObjectOptions, RouteScanOptions } from '../types.js';
|
|
13
|
+
/**
|
|
14
|
+
* The single entry point for wiring apcore into a Hono app.
|
|
15
|
+
*
|
|
16
|
+
* Owns the apcore `Registry` and `Executor`, the tool/route registration
|
|
17
|
+
* surface, and the optional MCP, CLI, and A2A services. Everything else in
|
|
18
|
+
* this package hangs off an instance of this class.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const ap = createApcore({
|
|
23
|
+
* tools: [listTodos, addTodo],
|
|
24
|
+
* mcp: { explorer: true, allowExecute: true },
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* app.use('*', apcore(ap));
|
|
28
|
+
* await ap.init(app); // register tools, scan routes
|
|
29
|
+
* await ap.mountMcp(app); // serve MCP on the same port
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare class HonoApcore {
|
|
33
|
+
private readonly options;
|
|
34
|
+
/** Canonical `APCORE_*` settings, environment merged with `options.settings`. */
|
|
35
|
+
readonly settings: ApcoreSettings;
|
|
36
|
+
/** Registry wrapper — register and inspect modules. */
|
|
37
|
+
readonly registry: ApcoreRegistry;
|
|
38
|
+
/** Executor wrapper — `call()`, `stream()`, `validate()`. */
|
|
39
|
+
readonly executor: ApcoreExecutor;
|
|
40
|
+
/** Builds per-request apcore `Context` objects from Hono requests. */
|
|
41
|
+
readonly contextFactory: HonoContextFactory;
|
|
42
|
+
private readonly _mcp;
|
|
43
|
+
private readonly _cli;
|
|
44
|
+
private readonly _a2a;
|
|
45
|
+
private readonly scanner;
|
|
46
|
+
private initPromise;
|
|
47
|
+
constructor(options?: HonoApcoreOptions);
|
|
48
|
+
/**
|
|
49
|
+
* The route-scan options this instance would use: the `APCORE_*` settings
|
|
50
|
+
* with the constructor's `routes` block layered on top.
|
|
51
|
+
*
|
|
52
|
+
* The `hono-apcore` CLI reads this so `scan` against a configured entry
|
|
53
|
+
* produces the same module set the app itself registers.
|
|
54
|
+
*/
|
|
55
|
+
get routeOptions(): RouteScanOptions;
|
|
56
|
+
/** The MCP service, or `null` when `options.mcp` was omitted. */
|
|
57
|
+
get mcp(): ApcoreMcpService | null;
|
|
58
|
+
/** The CLI service, or `null` when `options.cli` was omitted. */
|
|
59
|
+
get cli(): ApcoreCliService | null;
|
|
60
|
+
/** The A2A service, or `null` when `options.a2a` was omitted. */
|
|
61
|
+
get a2a(): ApcoreA2aService | null;
|
|
62
|
+
/** Register one tool definition. Returns its module ID. */
|
|
63
|
+
registerTool(tool: ApToolDefinition): Promise<string>;
|
|
64
|
+
/** Register several tool definitions. Returns their module IDs. */
|
|
65
|
+
registerTools(tools: ApToolDefinition[]): Promise<string[]>;
|
|
66
|
+
/** Register a single method of a service object as a module. */
|
|
67
|
+
registerMethod(options: RegisterMethodOptions): Promise<string>;
|
|
68
|
+
/** Register several — or all — methods of a service object. */
|
|
69
|
+
registerObject(options: RegisterObjectOptions): Promise<string[]>;
|
|
70
|
+
/**
|
|
71
|
+
* Scan a Hono app's route table and register every matching route as a
|
|
72
|
+
* module that replays the route in-process via `app.request()`.
|
|
73
|
+
*
|
|
74
|
+
* Options are merged over the `routes` block from the constructor and the
|
|
75
|
+
* `APCORE_INCLUDE_PATHS` / `APCORE_EXCLUDE_PATHS` / `APCORE_MODULE_PREFIX`
|
|
76
|
+
* settings.
|
|
77
|
+
*
|
|
78
|
+
* @returns The module IDs that were registered.
|
|
79
|
+
*/
|
|
80
|
+
scanRoutes(app: HonoAppLike, options?: RouteScanOptions): Promise<string[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Load a YAML bindings file and register its entries.
|
|
83
|
+
*
|
|
84
|
+
* @param filePath - Path to the YAML file. Defaults to `options.bindings`.
|
|
85
|
+
* @param resolveTarget - Resolves each entry's `target` to a live handler.
|
|
86
|
+
*/
|
|
87
|
+
loadBindings(filePath?: string, resolveTarget?: TargetResolver): Promise<string[]>;
|
|
88
|
+
/**
|
|
89
|
+
* Discover extensions, register the configured tools and bindings, scan the
|
|
90
|
+
* app's routes, and start any surface configured to run standalone.
|
|
91
|
+
*
|
|
92
|
+
* Idempotent: repeat calls await the first one instead of registering twice.
|
|
93
|
+
* When `APCORE_ENABLED` is false, this resolves without doing anything.
|
|
94
|
+
*
|
|
95
|
+
* @param app - Hono app whose routes should be scanned. Omit to skip scanning.
|
|
96
|
+
* @param routeOptions - Route-scan overrides for this call.
|
|
97
|
+
*/
|
|
98
|
+
init(app?: HonoAppLike, routeOptions?: RouteScanOptions): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Await an in-flight {@link init}. Resolves immediately when init has not
|
|
101
|
+
* been called — the middleware uses it to avoid racing a slow startup.
|
|
102
|
+
*/
|
|
103
|
+
ready(): Promise<void>;
|
|
104
|
+
/** Layer the `APCORE_*` settings, the constructor options, and a per-call override. */
|
|
105
|
+
private mergeRouteOptions;
|
|
106
|
+
private runInit;
|
|
107
|
+
/**
|
|
108
|
+
* Mount the MCP endpoint into the Hono app so one port serves both HTTP and
|
|
109
|
+
* MCP. Node runtime only — see {@link mountMcp}.
|
|
110
|
+
*
|
|
111
|
+
* @throws {Error} When the instance was created without `options.mcp`.
|
|
112
|
+
*/
|
|
113
|
+
mountMcp(app: MountableApp, options?: MountMcpOptions): Promise<McpApp>;
|
|
114
|
+
/**
|
|
115
|
+
* Convert the registered modules to OpenAI-compatible tool definitions.
|
|
116
|
+
*
|
|
117
|
+
* @throws {Error} When the instance was created without `options.mcp`.
|
|
118
|
+
*/
|
|
119
|
+
toOpenaiTools(options?: {
|
|
120
|
+
embedAnnotations?: boolean;
|
|
121
|
+
strict?: boolean;
|
|
122
|
+
tags?: string[];
|
|
123
|
+
prefix?: string;
|
|
124
|
+
}): Promise<unknown[]>;
|
|
125
|
+
/** Shut down the MCP and A2A surfaces. */
|
|
126
|
+
close(): Promise<void>;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Create a {@link HonoApcore} instance.
|
|
130
|
+
*
|
|
131
|
+
* Sugar for `new HonoApcore(options)`, matching the `createX()` style the
|
|
132
|
+
* Hono ecosystem uses.
|
|
133
|
+
*/
|
|
134
|
+
export declare function createApcore(options?: HonoApcoreOptions): HonoApcore;
|
|
135
|
+
//# sourceMappingURL=apcore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apcore.d.ts","sourceRoot":"","sources":["../../src/core/apcore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { Executor, Registry } from 'apcore-js';
|
|
2
|
+
import { ApcoreRegistry } from './registry.js';
|
|
3
|
+
import { ApcoreExecutor } from './executor.js';
|
|
4
|
+
import { ApcoreMcpService } from '../mcp/apcore-mcp.service.js';
|
|
5
|
+
import { ApcoreCliService } from '../cli/apcore-cli.service.js';
|
|
6
|
+
import { ApcoreA2aService } from '../a2a/apcore-a2a.service.js';
|
|
7
|
+
import { HonoContextFactory } from '../context/hono-context.factory.js';
|
|
8
|
+
import { HonoRouteScanner } from '../scanners/hono-route-scanner.js';
|
|
9
|
+
import { ApBindingLoader } from '../bridge/binding-loader.js';
|
|
10
|
+
import { mountMcp as mountMcpEndpoint } from '../mcp/mount.js';
|
|
11
|
+
import { loadSettings, toMcpTransport } from '../config.js';
|
|
12
|
+
/**
|
|
13
|
+
* The single entry point for wiring apcore into a Hono app.
|
|
14
|
+
*
|
|
15
|
+
* Owns the apcore `Registry` and `Executor`, the tool/route registration
|
|
16
|
+
* surface, and the optional MCP, CLI, and A2A services. Everything else in
|
|
17
|
+
* this package hangs off an instance of this class.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const ap = createApcore({
|
|
22
|
+
* tools: [listTodos, addTodo],
|
|
23
|
+
* mcp: { explorer: true, allowExecute: true },
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* app.use('*', apcore(ap));
|
|
27
|
+
* await ap.init(app); // register tools, scan routes
|
|
28
|
+
* await ap.mountMcp(app); // serve MCP on the same port
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export class HonoApcore {
|
|
32
|
+
options;
|
|
33
|
+
/** Canonical `APCORE_*` settings, environment merged with `options.settings`. */
|
|
34
|
+
settings;
|
|
35
|
+
/** Registry wrapper — register and inspect modules. */
|
|
36
|
+
registry;
|
|
37
|
+
/** Executor wrapper — `call()`, `stream()`, `validate()`. */
|
|
38
|
+
executor;
|
|
39
|
+
/** Builds per-request apcore `Context` objects from Hono requests. */
|
|
40
|
+
contextFactory;
|
|
41
|
+
_mcp;
|
|
42
|
+
_cli;
|
|
43
|
+
_a2a;
|
|
44
|
+
scanner = new HonoRouteScanner();
|
|
45
|
+
initPromise = null;
|
|
46
|
+
constructor(options = {}) {
|
|
47
|
+
this.options = options;
|
|
48
|
+
this.settings = loadSettings(undefined, options.settings);
|
|
49
|
+
const registry = new Registry({ extensionsDir: options.extensionsDir ?? null });
|
|
50
|
+
const executor = new Executor({
|
|
51
|
+
registry,
|
|
52
|
+
acl: options.acl ?? null,
|
|
53
|
+
middlewares: options.middleware ?? null,
|
|
54
|
+
});
|
|
55
|
+
this.registry = new ApcoreRegistry(registry);
|
|
56
|
+
this.executor = new ApcoreExecutor(executor);
|
|
57
|
+
this.contextFactory = new HonoContextFactory();
|
|
58
|
+
this._mcp = options.mcp
|
|
59
|
+
? new ApcoreMcpService(this.registry, this.executor, {
|
|
60
|
+
...options.mcp,
|
|
61
|
+
// The APCORE_* settings supply the defaults; explicit config wins.
|
|
62
|
+
transport: options.mcp.transport ?? toMcpTransport(this.settings.transport),
|
|
63
|
+
host: options.mcp.host ?? this.settings.host,
|
|
64
|
+
port: options.mcp.port ?? this.settings.port,
|
|
65
|
+
})
|
|
66
|
+
: null;
|
|
67
|
+
this._cli = options.cli ? new ApcoreCliService(this.registry, options.cli) : null;
|
|
68
|
+
this._a2a = options.a2a
|
|
69
|
+
? new ApcoreA2aService(this.registry, this.executor, options.a2a)
|
|
70
|
+
: null;
|
|
71
|
+
}
|
|
72
|
+
// -------------------------------------------------------------------------
|
|
73
|
+
// Surfaces
|
|
74
|
+
// -------------------------------------------------------------------------
|
|
75
|
+
/**
|
|
76
|
+
* The route-scan options this instance would use: the `APCORE_*` settings
|
|
77
|
+
* with the constructor's `routes` block layered on top.
|
|
78
|
+
*
|
|
79
|
+
* The `hono-apcore` CLI reads this so `scan` against a configured entry
|
|
80
|
+
* produces the same module set the app itself registers.
|
|
81
|
+
*/
|
|
82
|
+
get routeOptions() {
|
|
83
|
+
return this.mergeRouteOptions();
|
|
84
|
+
}
|
|
85
|
+
/** The MCP service, or `null` when `options.mcp` was omitted. */
|
|
86
|
+
get mcp() {
|
|
87
|
+
return this._mcp;
|
|
88
|
+
}
|
|
89
|
+
/** The CLI service, or `null` when `options.cli` was omitted. */
|
|
90
|
+
get cli() {
|
|
91
|
+
return this._cli;
|
|
92
|
+
}
|
|
93
|
+
/** The A2A service, or `null` when `options.a2a` was omitted. */
|
|
94
|
+
get a2a() {
|
|
95
|
+
return this._a2a;
|
|
96
|
+
}
|
|
97
|
+
// -------------------------------------------------------------------------
|
|
98
|
+
// Registration
|
|
99
|
+
// -------------------------------------------------------------------------
|
|
100
|
+
/** Register one tool definition. Returns its module ID. */
|
|
101
|
+
registerTool(tool) {
|
|
102
|
+
return this.registry.registerTool(tool, { modulePrefix: this.settings.modulePrefix });
|
|
103
|
+
}
|
|
104
|
+
/** Register several tool definitions. Returns their module IDs. */
|
|
105
|
+
registerTools(tools) {
|
|
106
|
+
return this.registry.registerTools(tools, { modulePrefix: this.settings.modulePrefix });
|
|
107
|
+
}
|
|
108
|
+
/** Register a single method of a service object as a module. */
|
|
109
|
+
registerMethod(options) {
|
|
110
|
+
return this.registry.registerMethod(options);
|
|
111
|
+
}
|
|
112
|
+
/** Register several — or all — methods of a service object. */
|
|
113
|
+
registerObject(options) {
|
|
114
|
+
return this.registry.registerObject(options);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Scan a Hono app's route table and register every matching route as a
|
|
118
|
+
* module that replays the route in-process via `app.request()`.
|
|
119
|
+
*
|
|
120
|
+
* Options are merged over the `routes` block from the constructor and the
|
|
121
|
+
* `APCORE_INCLUDE_PATHS` / `APCORE_EXCLUDE_PATHS` / `APCORE_MODULE_PREFIX`
|
|
122
|
+
* settings.
|
|
123
|
+
*
|
|
124
|
+
* @returns The module IDs that were registered.
|
|
125
|
+
*/
|
|
126
|
+
async scanRoutes(app, options = {}) {
|
|
127
|
+
const merged = this.mergeRouteOptions(options);
|
|
128
|
+
const ids = [];
|
|
129
|
+
for (const { module, execute } of this.scanner.scanWithExecutors(app, merged)) {
|
|
130
|
+
try {
|
|
131
|
+
ids.push(await this.registry.registerScanned(module, execute));
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
// A path segment can collide with a reserved namespace ("internal",
|
|
135
|
+
// "system", ...) or otherwise fail §2.7 validation. Name the route so
|
|
136
|
+
// the fix is obvious instead of surfacing a bare module-ID error.
|
|
137
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
138
|
+
throw new Error(`Cannot register route ${module.target} as module "${module.moduleId}": ${reason}. ` +
|
|
139
|
+
'Give it an explicit id via routes.overrides, or drop it with routes.excludePaths.', { cause: err });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return ids;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Load a YAML bindings file and register its entries.
|
|
146
|
+
*
|
|
147
|
+
* @param filePath - Path to the YAML file. Defaults to `options.bindings`.
|
|
148
|
+
* @param resolveTarget - Resolves each entry's `target` to a live handler.
|
|
149
|
+
*/
|
|
150
|
+
async loadBindings(filePath, resolveTarget) {
|
|
151
|
+
const path = filePath ?? this.options.bindings;
|
|
152
|
+
if (!path)
|
|
153
|
+
return [];
|
|
154
|
+
return new ApBindingLoader(this.registry, resolveTarget).loadFromFile(path);
|
|
155
|
+
}
|
|
156
|
+
// -------------------------------------------------------------------------
|
|
157
|
+
// Lifecycle
|
|
158
|
+
// -------------------------------------------------------------------------
|
|
159
|
+
/**
|
|
160
|
+
* Discover extensions, register the configured tools and bindings, scan the
|
|
161
|
+
* app's routes, and start any surface configured to run standalone.
|
|
162
|
+
*
|
|
163
|
+
* Idempotent: repeat calls await the first one instead of registering twice.
|
|
164
|
+
* When `APCORE_ENABLED` is false, this resolves without doing anything.
|
|
165
|
+
*
|
|
166
|
+
* @param app - Hono app whose routes should be scanned. Omit to skip scanning.
|
|
167
|
+
* @param routeOptions - Route-scan overrides for this call.
|
|
168
|
+
*/
|
|
169
|
+
init(app, routeOptions) {
|
|
170
|
+
this.initPromise ??= this.runInit(app, routeOptions);
|
|
171
|
+
return this.initPromise;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Await an in-flight {@link init}. Resolves immediately when init has not
|
|
175
|
+
* been called — the middleware uses it to avoid racing a slow startup.
|
|
176
|
+
*/
|
|
177
|
+
async ready() {
|
|
178
|
+
await this.initPromise;
|
|
179
|
+
}
|
|
180
|
+
/** Layer the `APCORE_*` settings, the constructor options, and a per-call override. */
|
|
181
|
+
mergeRouteOptions(options = {}) {
|
|
182
|
+
return {
|
|
183
|
+
modulePrefix: this.settings.modulePrefix || undefined,
|
|
184
|
+
includePaths: this.settings.includePaths,
|
|
185
|
+
excludePaths: this.settings.excludePaths,
|
|
186
|
+
...this.options.routes,
|
|
187
|
+
...options,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
async runInit(app, routeOptions) {
|
|
191
|
+
if (!this.settings.enabled)
|
|
192
|
+
return;
|
|
193
|
+
if (this.options.extensionsDir) {
|
|
194
|
+
await this.registry.discover();
|
|
195
|
+
}
|
|
196
|
+
if (this.options.tools?.length) {
|
|
197
|
+
await this.registerTools(this.options.tools);
|
|
198
|
+
}
|
|
199
|
+
if (this.options.bindings) {
|
|
200
|
+
await this.loadBindings();
|
|
201
|
+
}
|
|
202
|
+
if (app) {
|
|
203
|
+
await this.scanRoutes(app, routeOptions);
|
|
204
|
+
}
|
|
205
|
+
// Surfaces start last, so every module is registered before a client can
|
|
206
|
+
// list the tools.
|
|
207
|
+
if (this._a2a && this.options.a2a?.port !== undefined) {
|
|
208
|
+
await this._a2a.start();
|
|
209
|
+
}
|
|
210
|
+
if (this._mcp && this.options.mcp?.transport) {
|
|
211
|
+
await this._mcp.start();
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Mount the MCP endpoint into the Hono app so one port serves both HTTP and
|
|
216
|
+
* MCP. Node runtime only — see {@link mountMcp}.
|
|
217
|
+
*
|
|
218
|
+
* @throws {Error} When the instance was created without `options.mcp`.
|
|
219
|
+
*/
|
|
220
|
+
async mountMcp(app, options = {}) {
|
|
221
|
+
if (!this._mcp) {
|
|
222
|
+
throw new Error('mountMcp() requires the MCP surface. Pass an `mcp` block to createApcore().');
|
|
223
|
+
}
|
|
224
|
+
return mountMcpEndpoint(app, this._mcp, {
|
|
225
|
+
explorer: this.options.mcp?.explorer,
|
|
226
|
+
explorerPrefix: this.options.mcp?.explorerPrefix,
|
|
227
|
+
allowExecute: this.options.mcp?.allowExecute,
|
|
228
|
+
...options,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Convert the registered modules to OpenAI-compatible tool definitions.
|
|
233
|
+
*
|
|
234
|
+
* @throws {Error} When the instance was created without `options.mcp`.
|
|
235
|
+
*/
|
|
236
|
+
async toOpenaiTools(options) {
|
|
237
|
+
if (!this._mcp) {
|
|
238
|
+
throw new Error('toOpenaiTools() requires the MCP surface. Pass an `mcp` block to createApcore().');
|
|
239
|
+
}
|
|
240
|
+
return this._mcp.toOpenaiTools(options);
|
|
241
|
+
}
|
|
242
|
+
/** Shut down the MCP and A2A surfaces. */
|
|
243
|
+
async close() {
|
|
244
|
+
await this._mcp?.stop();
|
|
245
|
+
this._a2a?.stop();
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Create a {@link HonoApcore} instance.
|
|
250
|
+
*
|
|
251
|
+
* Sugar for `new HonoApcore(options)`, matching the `createX()` style the
|
|
252
|
+
* Hono ecosystem uses.
|
|
253
|
+
*/
|
|
254
|
+
export function createApcore(options = {}) {
|
|
255
|
+
return new HonoApcore(options);
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=apcore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apcore.js","sourceRoot":"","sources":["../../src/core/apcore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Context, Executor, PreflightResult } from 'apcore-js';
|
|
2
|
+
/**
|
|
3
|
+
* Thin wrapper around the upstream apcore-js `Executor`.
|
|
4
|
+
*
|
|
5
|
+
* Every delegation normalises `null` / `undefined` inputs to `{}` so callers
|
|
6
|
+
* never have to think about nullability at the call site.
|
|
7
|
+
*/
|
|
8
|
+
export declare class ApcoreExecutor {
|
|
9
|
+
private readonly executor;
|
|
10
|
+
constructor(executor: Executor);
|
|
11
|
+
/** The underlying apcore-js `Executor`. */
|
|
12
|
+
get raw(): Executor;
|
|
13
|
+
/**
|
|
14
|
+
* Execute a module by ID.
|
|
15
|
+
*
|
|
16
|
+
* @param moduleId - Fully-qualified module identifier (e.g. `"todo.list"`).
|
|
17
|
+
* @param inputs - Key/value inputs; `null` / `undefined` become `{}`.
|
|
18
|
+
* @param context - Optional execution context (identity, trace, data).
|
|
19
|
+
*/
|
|
20
|
+
call(moduleId: string, inputs?: Record<string, unknown> | null, context?: Context | null): Promise<Record<string, unknown>>;
|
|
21
|
+
/**
|
|
22
|
+
* Stream execution results from a module, yielding each chunk produced by
|
|
23
|
+
* the upstream generator.
|
|
24
|
+
*/
|
|
25
|
+
stream(moduleId: string, inputs?: Record<string, unknown> | null, context?: Context | null): AsyncGenerator<Record<string, unknown>>;
|
|
26
|
+
/**
|
|
27
|
+
* Run preflight checks — schema, ACL, approval, call-chain — without
|
|
28
|
+
* executing the module.
|
|
29
|
+
*/
|
|
30
|
+
validate(moduleId: string, inputs?: Record<string, unknown> | null, context?: Context | null): Promise<PreflightResult>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/core/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEpE;;;;;GAKG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,QAAQ;IAE/C,2CAA2C;IAC3C,IAAI,GAAG,IAAI,QAAQ,CAElB;IAED;;;;;;OAMG;IACG,IAAI,CACR,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EACvC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAInC;;;OAGG;IACI,MAAM,CACX,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EACvC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,GACvB,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAI1C;;;OAGG;IACH,QAAQ,CACN,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EACvC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,GACvB,OAAO,CAAC,eAAe,CAAC;CAG5B"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin wrapper around the upstream apcore-js `Executor`.
|
|
3
|
+
*
|
|
4
|
+
* Every delegation normalises `null` / `undefined` inputs to `{}` so callers
|
|
5
|
+
* never have to think about nullability at the call site.
|
|
6
|
+
*/
|
|
7
|
+
export class ApcoreExecutor {
|
|
8
|
+
executor;
|
|
9
|
+
constructor(executor) {
|
|
10
|
+
this.executor = executor;
|
|
11
|
+
}
|
|
12
|
+
/** The underlying apcore-js `Executor`. */
|
|
13
|
+
get raw() {
|
|
14
|
+
return this.executor;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Execute a module by ID.
|
|
18
|
+
*
|
|
19
|
+
* @param moduleId - Fully-qualified module identifier (e.g. `"todo.list"`).
|
|
20
|
+
* @param inputs - Key/value inputs; `null` / `undefined` become `{}`.
|
|
21
|
+
* @param context - Optional execution context (identity, trace, data).
|
|
22
|
+
*/
|
|
23
|
+
async call(moduleId, inputs, context) {
|
|
24
|
+
return this.executor.call(moduleId, inputs ?? {}, context);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Stream execution results from a module, yielding each chunk produced by
|
|
28
|
+
* the upstream generator.
|
|
29
|
+
*/
|
|
30
|
+
async *stream(moduleId, inputs, context) {
|
|
31
|
+
yield* this.executor.stream(moduleId, inputs ?? {}, context);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Run preflight checks — schema, ACL, approval, call-chain — without
|
|
35
|
+
* executing the module.
|
|
36
|
+
*/
|
|
37
|
+
validate(moduleId, inputs, context) {
|
|
38
|
+
return this.executor.validate(moduleId, inputs ?? {}, context);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/core/executor.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,OAAO,cAAc;IACI;IAA7B,YAA6B,QAAkB;QAAlB,aAAQ,GAAR,QAAQ,CAAU;IAAG,CAAC;IAEnD,2CAA2C;IAC3C,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,CACR,QAAgB,EAChB,MAAuC,EACvC,OAAwB;QAExB,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;IAC7D,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,CAAC,MAAM,CACX,QAAgB,EAChB,MAAuC,EACvC,OAAwB;QAExB,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;IAC/D,CAAC;IAED;;;OAGG;IACH,QAAQ,CACN,QAAgB,EAChB,MAAuC,EACvC,OAAwB;QAExB,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;IACjE,CAAC;CACF"}
|