veryfront 0.1.215 → 0.1.217
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/README.md +1 -1
- package/esm/cli/commands/extension/command-help.d.ts +3 -0
- package/esm/cli/commands/extension/command-help.d.ts.map +1 -0
- package/esm/cli/commands/extension/command-help.js +16 -0
- package/esm/cli/commands/extension/handler.d.ts +3 -0
- package/esm/cli/commands/extension/handler.d.ts.map +1 -0
- package/esm/cli/commands/extension/handler.js +36 -0
- package/esm/cli/commands/extension/init-command.d.ts +19 -0
- package/esm/cli/commands/extension/init-command.d.ts.map +1 -0
- package/esm/cli/commands/extension/init-command.js +122 -0
- package/esm/cli/commands/extension/validate-command.d.ts +13 -0
- package/esm/cli/commands/extension/validate-command.d.ts.map +1 -0
- package/esm/cli/commands/extension/validate-command.js +62 -0
- package/esm/cli/commands/generate/integration-generator-helpers.d.ts +35 -0
- package/esm/cli/commands/generate/integration-generator-helpers.d.ts.map +1 -0
- package/esm/cli/commands/generate/integration-generator-helpers.js +123 -0
- package/esm/cli/commands/generate/integration-generator.d.ts +1 -2
- package/esm/cli/commands/generate/integration-generator.d.ts.map +1 -1
- package/esm/cli/commands/generate/integration-generator.js +1 -123
- package/esm/cli/commands/knowledge/command-helpers.d.ts +48 -0
- package/esm/cli/commands/knowledge/command-helpers.d.ts.map +1 -0
- package/esm/cli/commands/knowledge/command-helpers.js +216 -0
- package/esm/cli/commands/knowledge/command.d.ts +12 -17
- package/esm/cli/commands/knowledge/command.d.ts.map +1 -1
- package/esm/cli/commands/knowledge/command.js +26 -214
- package/esm/cli/help/command-definitions.d.ts.map +1 -1
- package/esm/cli/help/command-definitions.js +2 -0
- package/esm/cli/mcp/remote-file-tool-helpers.d.ts +5 -0
- package/esm/cli/mcp/remote-file-tool-helpers.d.ts.map +1 -0
- package/esm/cli/mcp/remote-file-tool-helpers.js +22 -0
- package/esm/cli/mcp/remote-file-tools.d.ts.map +1 -1
- package/esm/cli/mcp/remote-file-tools.js +1 -22
- package/esm/cli/router.d.ts.map +1 -1
- package/esm/cli/router.js +2 -0
- package/esm/cli/templates/integration-loader-helpers.d.ts +8 -0
- package/esm/cli/templates/integration-loader-helpers.d.ts.map +1 -0
- package/esm/cli/templates/integration-loader-helpers.js +29 -0
- package/esm/cli/templates/integration-loader.d.ts.map +1 -1
- package/esm/cli/templates/integration-loader.js +5 -21
- package/esm/cli/templates/manifest.d.ts +1 -0
- package/esm/cli/templates/manifest.js +2 -1
- package/esm/deno.d.ts +3 -0
- package/esm/deno.js +5 -2
- package/esm/src/agent/runtime/index.d.ts.map +1 -1
- package/esm/src/agent/runtime/index.js +48 -90
- package/esm/src/chat/ag-ui-helpers.d.ts +17 -0
- package/esm/src/chat/ag-ui-helpers.d.ts.map +1 -0
- package/esm/src/chat/ag-ui-helpers.js +111 -0
- package/esm/src/chat/ag-ui.d.ts.map +1 -1
- package/esm/src/chat/ag-ui.js +1 -111
- package/esm/src/config/schemas/config.schema.d.ts +1 -0
- package/esm/src/config/schemas/config.schema.d.ts.map +1 -1
- package/esm/src/config/schemas/config.schema.js +11 -0
- package/esm/src/config/schemas/index.d.ts +11 -1
- package/esm/src/config/schemas/index.d.ts.map +1 -1
- package/esm/src/errors/error-registry-helpers.d.ts +6 -0
- package/esm/src/errors/error-registry-helpers.d.ts.map +1 -0
- package/esm/src/errors/error-registry-helpers.js +9 -0
- package/esm/src/errors/error-registry.d.ts.map +1 -1
- package/esm/src/errors/error-registry.js +4 -3
- package/esm/src/extensions/capabilities.d.ts +20 -0
- package/esm/src/extensions/capabilities.d.ts.map +1 -0
- package/esm/src/extensions/capabilities.js +77 -0
- package/esm/src/extensions/contracts.d.ts +10 -0
- package/esm/src/extensions/contracts.d.ts.map +1 -0
- package/esm/src/extensions/contracts.js +28 -0
- package/esm/src/extensions/discovery.d.ts +48 -0
- package/esm/src/extensions/discovery.d.ts.map +1 -0
- package/esm/src/extensions/discovery.js +179 -0
- package/esm/src/extensions/errors.d.ts +10 -0
- package/esm/src/extensions/errors.d.ts.map +1 -0
- package/esm/src/extensions/errors.js +34 -0
- package/esm/src/extensions/factory-loader.d.ts +29 -0
- package/esm/src/extensions/factory-loader.d.ts.map +1 -0
- package/esm/src/extensions/factory-loader.js +63 -0
- package/esm/src/extensions/index.d.ts +37 -0
- package/esm/src/extensions/index.d.ts.map +1 -0
- package/esm/src/extensions/index.js +41 -0
- package/esm/src/extensions/interfaces/ai-model-provider.d.ts +94 -0
- package/esm/src/extensions/interfaces/ai-model-provider.d.ts.map +1 -0
- package/esm/src/extensions/interfaces/ai-model-provider.js +8 -0
- package/esm/src/extensions/interfaces/auth-provider.d.ts +49 -0
- package/esm/src/extensions/interfaces/auth-provider.d.ts.map +1 -0
- package/esm/src/extensions/interfaces/auth-provider.js +8 -0
- package/esm/src/extensions/interfaces/bundler.d.ts +118 -0
- package/esm/src/extensions/interfaces/bundler.d.ts.map +1 -0
- package/esm/src/extensions/interfaces/bundler.js +8 -0
- package/esm/src/extensions/interfaces/cache-store.d.ts +27 -0
- package/esm/src/extensions/interfaces/cache-store.d.ts.map +1 -0
- package/esm/src/extensions/interfaces/cache-store.js +8 -0
- package/esm/src/extensions/interfaces/code-parser.d.ts +76 -0
- package/esm/src/extensions/interfaces/code-parser.d.ts.map +1 -0
- package/esm/src/extensions/interfaces/code-parser.js +8 -0
- package/esm/src/extensions/interfaces/content-transformer.d.ts +40 -0
- package/esm/src/extensions/interfaces/content-transformer.d.ts.map +1 -0
- package/esm/src/extensions/interfaces/content-transformer.js +8 -0
- package/esm/src/extensions/interfaces/css-processor.d.ts +38 -0
- package/esm/src/extensions/interfaces/css-processor.d.ts.map +1 -0
- package/esm/src/extensions/interfaces/css-processor.js +8 -0
- package/esm/src/extensions/interfaces/database-client.d.ts +31 -0
- package/esm/src/extensions/interfaces/database-client.d.ts.map +1 -0
- package/esm/src/extensions/interfaces/database-client.js +8 -0
- package/esm/src/extensions/interfaces/embedding-provider.d.ts +37 -0
- package/esm/src/extensions/interfaces/embedding-provider.d.ts.map +1 -0
- package/esm/src/extensions/interfaces/embedding-provider.js +8 -0
- package/esm/src/extensions/interfaces/index.d.ts +21 -0
- package/esm/src/extensions/interfaces/index.d.ts.map +1 -0
- package/esm/src/extensions/interfaces/index.js +9 -0
- package/esm/src/extensions/interfaces/node-compat.d.ts +25 -0
- package/esm/src/extensions/interfaces/node-compat.d.ts.map +1 -0
- package/esm/src/extensions/interfaces/node-compat.js +8 -0
- package/esm/src/extensions/interfaces/schema-validator.d.ts +46 -0
- package/esm/src/extensions/interfaces/schema-validator.d.ts.map +1 -0
- package/esm/src/extensions/interfaces/schema-validator.js +8 -0
- package/esm/src/extensions/interfaces/tracing-exporter.d.ts +44 -0
- package/esm/src/extensions/interfaces/tracing-exporter.d.ts.map +1 -0
- package/esm/src/extensions/interfaces/tracing-exporter.js +8 -0
- package/esm/src/extensions/loader.d.ts +33 -0
- package/esm/src/extensions/loader.d.ts.map +1 -0
- package/esm/src/extensions/loader.js +209 -0
- package/esm/src/extensions/orchestrate.d.ts +54 -0
- package/esm/src/extensions/orchestrate.d.ts.map +1 -0
- package/esm/src/extensions/orchestrate.js +116 -0
- package/esm/src/extensions/recommendations.d.ts +7 -0
- package/esm/src/extensions/recommendations.d.ts.map +1 -0
- package/esm/src/extensions/recommendations.js +22 -0
- package/esm/src/extensions/types.d.ts +47 -0
- package/esm/src/extensions/types.d.ts.map +1 -0
- package/esm/src/extensions/types.js +6 -0
- package/esm/src/extensions/validation.d.ts +44 -0
- package/esm/src/extensions/validation.d.ts.map +1 -0
- package/esm/src/extensions/validation.js +115 -0
- package/esm/src/html/styles-builder/plugin-loader.d.ts.map +1 -1
- package/esm/src/html/styles-builder/plugin-loader.js +23 -0
- package/esm/src/html/styles-builder/tailwind-plugin-allowlist.d.ts +29 -0
- package/esm/src/html/styles-builder/tailwind-plugin-allowlist.d.ts.map +1 -0
- package/esm/src/html/styles-builder/tailwind-plugin-allowlist.js +48 -0
- package/esm/src/modules/react-loader/ssr-module-loader/loader-helpers.d.ts +15 -0
- package/esm/src/modules/react-loader/ssr-module-loader/loader-helpers.d.ts.map +1 -0
- package/esm/src/modules/react-loader/ssr-module-loader/loader-helpers.js +22 -0
- package/esm/src/modules/react-loader/ssr-module-loader/loader.d.ts +0 -2
- package/esm/src/modules/react-loader/ssr-module-loader/loader.d.ts.map +1 -1
- package/esm/src/modules/react-loader/ssr-module-loader/loader.js +4 -24
- package/esm/src/platform/adapters/fs/veryfront/adapter-helpers.d.ts +19 -0
- package/esm/src/platform/adapters/fs/veryfront/adapter-helpers.d.ts.map +1 -0
- package/esm/src/platform/adapters/fs/veryfront/adapter-helpers.js +26 -0
- package/esm/src/platform/adapters/fs/veryfront/adapter.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/adapter.js +4 -20
- package/esm/src/platform/adapters/fs/veryfront/read-operations-helpers.d.ts +1 -0
- package/esm/src/platform/adapters/fs/veryfront/read-operations-helpers.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/read-operations-helpers.js +3 -0
- package/esm/src/platform/adapters/fs/veryfront/read-operations.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/read-operations.js +4 -7
- package/esm/src/platform/adapters/fs/veryfront/websocket-manager-helpers.d.ts +28 -0
- package/esm/src/platform/adapters/fs/veryfront/websocket-manager-helpers.d.ts.map +1 -0
- package/esm/src/platform/adapters/fs/veryfront/websocket-manager-helpers.js +41 -0
- package/esm/src/platform/adapters/fs/veryfront/websocket-manager.d.ts +1 -4
- package/esm/src/platform/adapters/fs/veryfront/websocket-manager.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/websocket-manager.js +7 -40
- package/esm/src/platform/compat/process/command.d.ts +31 -0
- package/esm/src/platform/compat/process/command.d.ts.map +1 -0
- package/esm/src/platform/compat/process/command.js +193 -0
- package/esm/src/platform/compat/process/env.d.ts +31 -0
- package/esm/src/platform/compat/process/env.d.ts.map +1 -0
- package/esm/src/platform/compat/process/env.js +175 -0
- package/esm/src/platform/compat/process/lifecycle.d.ts +98 -0
- package/esm/src/platform/compat/process/lifecycle.d.ts.map +1 -0
- package/esm/src/platform/compat/process/lifecycle.js +305 -0
- package/esm/src/platform/compat/process/runtime-process.d.ts +10 -0
- package/esm/src/platform/compat/process/runtime-process.d.ts.map +1 -0
- package/esm/src/platform/compat/process/runtime-process.js +24 -0
- package/esm/src/platform/compat/process.d.ts +4 -165
- package/esm/src/platform/compat/process.d.ts.map +1 -1
- package/esm/src/platform/compat/process.js +4 -682
- package/esm/src/platform/index.d.ts +1 -1
- package/esm/src/platform/index.d.ts.map +1 -1
- package/esm/src/provider/runtime-loader/provider-endpoints.d.ts +8 -0
- package/esm/src/provider/runtime-loader/provider-endpoints.d.ts.map +1 -0
- package/esm/src/provider/runtime-loader/provider-endpoints.js +27 -0
- package/esm/src/provider/runtime-loader/provider-request-init.d.ts +32 -0
- package/esm/src/provider/runtime-loader/provider-request-init.d.ts.map +1 -0
- package/esm/src/provider/runtime-loader/provider-request-init.js +67 -0
- package/esm/src/provider/runtime-loader/tool-input-status.d.ts +17 -0
- package/esm/src/provider/runtime-loader/tool-input-status.d.ts.map +1 -0
- package/esm/src/provider/runtime-loader/tool-input-status.js +155 -0
- package/esm/src/provider/runtime-loader.d.ts +2 -3
- package/esm/src/provider/runtime-loader.d.ts.map +1 -1
- package/esm/src/provider/runtime-loader.js +92 -291
- package/esm/src/proxy/handler.d.ts.map +1 -1
- package/esm/src/proxy/handler.js +14 -0
- package/esm/src/rendering/orchestrator/pipeline-helpers.d.ts +8 -0
- package/esm/src/rendering/orchestrator/pipeline-helpers.d.ts.map +1 -0
- package/esm/src/rendering/orchestrator/pipeline-helpers.js +20 -0
- package/esm/src/rendering/orchestrator/pipeline.d.ts +0 -3
- package/esm/src/rendering/orchestrator/pipeline.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/pipeline.js +4 -22
- package/esm/src/routing/api/module-loader/loader-helpers.d.ts +10 -0
- package/esm/src/routing/api/module-loader/loader-helpers.d.ts.map +1 -0
- package/esm/src/routing/api/module-loader/loader-helpers.js +62 -0
- package/esm/src/routing/api/module-loader/loader.d.ts +1 -1
- package/esm/src/routing/api/module-loader/loader.d.ts.map +1 -1
- package/esm/src/routing/api/module-loader/loader.js +2 -60
- package/esm/src/server/bootstrap.d.ts +22 -2
- package/esm/src/server/bootstrap.d.ts.map +1 -1
- package/esm/src/server/bootstrap.js +67 -5
- package/esm/src/server/dev-ui/manifest.d.ts +2 -0
- package/esm/src/server/dev-ui/manifest.js +3 -1
- package/esm/src/server/handlers/request/api/project-discovery.d.ts.map +1 -1
- package/esm/src/server/handlers/request/api/project-discovery.js +14 -8
- package/esm/src/server/production-server.js +1 -1
- package/esm/src/server/services/rsc/endpoints/rsc-bundles.generated.d.ts.map +1 -1
- package/esm/src/server/services/rsc/endpoints/rsc-bundles.generated.js +2 -2
- package/esm/src/server/utils/domain-parser.d.ts.map +1 -1
- package/esm/src/server/utils/domain-parser.js +4 -0
- package/esm/src/studio/bridge/bridge-bundle.generated.d.ts.map +1 -1
- package/esm/src/studio/bridge/bridge-bundle.generated.js +1 -1
- package/esm/src/tool/index.d.ts +1 -1
- package/esm/src/tool/index.d.ts.map +1 -1
- package/esm/src/tool/types.d.ts +20 -0
- package/esm/src/tool/types.d.ts.map +1 -1
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +7 -1
- package/src/cli/commands/extension/command-help.ts +18 -0
- package/src/cli/commands/extension/handler.ts +41 -0
- package/src/cli/commands/extension/init-command.ts +140 -0
- package/src/cli/commands/extension/validate-command.ts +78 -0
- package/src/cli/commands/generate/integration-generator-helpers.ts +185 -0
- package/src/cli/commands/generate/integration-generator.ts +12 -168
- package/src/cli/commands/knowledge/command-helpers.ts +295 -0
- package/src/cli/commands/knowledge/command.ts +34 -261
- package/src/cli/help/command-definitions.ts +2 -0
- package/src/cli/mcp/remote-file-tool-helpers.ts +27 -0
- package/src/cli/mcp/remote-file-tools.ts +6 -28
- package/src/cli/router.ts +2 -0
- package/src/cli/templates/integration-loader-helpers.ts +49 -0
- package/src/cli/templates/integration-loader.ts +10 -28
- package/src/cli/templates/manifest.js +2 -1
- package/src/deno.js +5 -2
- package/src/src/agent/runtime/index.ts +77 -94
- package/src/src/chat/ag-ui-helpers.ts +139 -0
- package/src/src/chat/ag-ui.ts +11 -139
- package/src/src/config/schemas/config.schema.ts +11 -0
- package/src/src/config/schemas/index.ts +15 -1
- package/src/src/errors/error-registry-helpers.ts +23 -0
- package/src/src/errors/error-registry.ts +8 -3
- package/src/src/extensions/capabilities.ts +97 -0
- package/src/src/extensions/contracts.ts +36 -0
- package/src/src/extensions/discovery.ts +221 -0
- package/src/src/extensions/errors.ts +39 -0
- package/src/src/extensions/factory-loader.ts +76 -0
- package/src/src/extensions/index.ts +79 -0
- package/src/src/extensions/interfaces/ai-model-provider.ts +100 -0
- package/src/src/extensions/interfaces/auth-provider.ts +52 -0
- package/src/src/extensions/interfaces/bundler.ts +116 -0
- package/src/src/extensions/interfaces/cache-store.ts +27 -0
- package/src/src/extensions/interfaces/code-parser.ts +84 -0
- package/src/src/extensions/interfaces/content-transformer.ts +38 -0
- package/src/src/extensions/interfaces/css-processor.ts +40 -0
- package/src/src/extensions/interfaces/database-client.ts +35 -0
- package/src/src/extensions/interfaces/embedding-provider.ts +39 -0
- package/src/src/extensions/interfaces/index.ts +81 -0
- package/src/src/extensions/interfaces/node-compat.ts +25 -0
- package/src/src/extensions/interfaces/schema-validator.ts +51 -0
- package/src/src/extensions/interfaces/tracing-exporter.ts +42 -0
- package/src/src/extensions/loader.ts +245 -0
- package/src/src/extensions/orchestrate.ts +184 -0
- package/src/src/extensions/recommendations.ts +24 -0
- package/src/src/extensions/types.ts +57 -0
- package/src/src/extensions/validation.ts +147 -0
- package/src/src/html/styles-builder/plugin-loader.ts +32 -0
- package/src/src/html/styles-builder/tailwind-plugin-allowlist.ts +51 -0
- package/src/src/modules/react-loader/ssr-module-loader/loader-helpers.ts +37 -0
- package/src/src/modules/react-loader/ssr-module-loader/loader.ts +8 -39
- package/src/src/platform/adapters/fs/veryfront/adapter-helpers.ts +43 -0
- package/src/src/platform/adapters/fs/veryfront/adapter.ts +8 -22
- package/src/src/platform/adapters/fs/veryfront/read-operations-helpers.ts +4 -0
- package/src/src/platform/adapters/fs/veryfront/read-operations.ts +4 -7
- package/src/src/platform/adapters/fs/veryfront/websocket-manager-helpers.ts +73 -0
- package/src/src/platform/adapters/fs/veryfront/websocket-manager.ts +29 -44
- package/src/src/platform/compat/process/command.ts +297 -0
- package/src/src/platform/compat/process/env.ts +227 -0
- package/src/src/platform/compat/process/lifecycle.ts +330 -0
- package/src/src/platform/compat/process/runtime-process.ts +27 -0
- package/src/src/platform/compat/process.ts +37 -870
- package/src/src/platform/index.ts +1 -0
- package/src/src/provider/runtime-loader/provider-endpoints.ts +50 -0
- package/src/src/provider/runtime-loader/provider-request-init.ts +101 -0
- package/src/src/provider/runtime-loader/tool-input-status.ts +210 -0
- package/src/src/provider/runtime-loader.ts +113 -368
- package/src/src/proxy/handler.ts +16 -0
- package/src/src/rendering/orchestrator/pipeline-helpers.ts +35 -0
- package/src/src/rendering/orchestrator/pipeline.ts +8 -35
- package/src/src/routing/api/module-loader/loader-helpers.ts +68 -0
- package/src/src/routing/api/module-loader/loader.ts +8 -65
- package/src/src/server/bootstrap.ts +88 -7
- package/src/src/server/dev-ui/manifest.js +3 -1
- package/src/src/server/handlers/request/api/project-discovery.ts +19 -8
- package/src/src/server/production-server.ts +1 -1
- package/src/src/server/services/rsc/endpoints/rsc-bundles.generated.ts +2 -2
- package/src/src/server/utils/domain-parser.ts +4 -0
- package/src/src/studio/bridge/bridge-bundle.generated.ts +1 -1
- package/src/src/tool/index.ts +1 -0
- package/src/src/tool/types.ts +21 -0
- package/src/src/utils/version-constant.ts +1 -1
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability audit logging and Deno permission mapping.
|
|
3
|
+
*
|
|
4
|
+
* @module extensions/capabilities
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Capability, ExtensionLogger } from "./types.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Format capabilities as human-readable strings for logging.
|
|
11
|
+
*/
|
|
12
|
+
export function formatCapabilities(capabilities: Capability[]): string[] {
|
|
13
|
+
return capabilities.map((cap) => {
|
|
14
|
+
if (cap.type === "contract") {
|
|
15
|
+
return `contract: ${cap.name as string}`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const { type, ...rest } = cap;
|
|
19
|
+
const extras = Object.keys(rest);
|
|
20
|
+
if (extras.length === 0) return type;
|
|
21
|
+
|
|
22
|
+
const details = extras
|
|
23
|
+
.map((key) => `${key}: ${JSON.stringify(rest[key])}`)
|
|
24
|
+
.join(", ");
|
|
25
|
+
return `${type} (${details})`;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface PermissionMapping {
|
|
30
|
+
flag: string;
|
|
31
|
+
scopeKey?: string;
|
|
32
|
+
/** Resolve scopes from the full capability (overrides scopeKey when present). */
|
|
33
|
+
resolveScopes?: (cap: Capability) => string[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const DENO_PERMISSION_MAP: Record<string, PermissionMapping> = {
|
|
37
|
+
"fs:read": { flag: "--allow-read", scopeKey: "paths" },
|
|
38
|
+
"fs:write": { flag: "--allow-write", scopeKey: "paths" },
|
|
39
|
+
"net:outbound": { flag: "--allow-net", scopeKey: "hosts" },
|
|
40
|
+
"net:listen": {
|
|
41
|
+
flag: "--allow-net",
|
|
42
|
+
resolveScopes: (cap) => {
|
|
43
|
+
const ports = cap.ports as (string | number)[] | undefined;
|
|
44
|
+
if (!ports || ports.length === 0) return [];
|
|
45
|
+
const host = (cap.host as string) || "localhost";
|
|
46
|
+
return ports.map((p) => `${host}:${p}`);
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
"env:read": { flag: "--allow-env", scopeKey: "keys" },
|
|
50
|
+
"process:spawn": { flag: "--allow-run", scopeKey: "commands" },
|
|
51
|
+
"native:ffi": { flag: "--allow-ffi" },
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Map capabilities to Deno CLI permission flags.
|
|
56
|
+
* Skips non-system capabilities (e.g., "contract").
|
|
57
|
+
*/
|
|
58
|
+
export function mapToDenoPermissions(capabilities: Capability[]): string[] {
|
|
59
|
+
const seen = new Set<string>();
|
|
60
|
+
const flags: string[] = [];
|
|
61
|
+
|
|
62
|
+
for (const cap of capabilities) {
|
|
63
|
+
const mapping = DENO_PERMISSION_MAP[cap.type];
|
|
64
|
+
if (!mapping) continue;
|
|
65
|
+
|
|
66
|
+
let flag = mapping.flag;
|
|
67
|
+
const scopes = mapping.resolveScopes
|
|
68
|
+
? mapping.resolveScopes(cap)
|
|
69
|
+
: mapping.scopeKey
|
|
70
|
+
? (cap[mapping.scopeKey] as string[] | undefined) ?? []
|
|
71
|
+
: [];
|
|
72
|
+
if (scopes.length > 0) {
|
|
73
|
+
flag = `${flag}=${scopes.join(",")}`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!seen.has(flag)) {
|
|
77
|
+
seen.add(flag);
|
|
78
|
+
flags.push(flag);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return flags;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Log capabilities for a named extension at startup.
|
|
87
|
+
*/
|
|
88
|
+
export function auditCapabilities(
|
|
89
|
+
extensionName: string,
|
|
90
|
+
capabilities: Capability[],
|
|
91
|
+
logger: ExtensionLogger,
|
|
92
|
+
): void {
|
|
93
|
+
if (capabilities.length === 0) return;
|
|
94
|
+
|
|
95
|
+
const lines = formatCapabilities(capabilities);
|
|
96
|
+
logger.info(`Extension "${extensionName}" declares capabilities:`, ...lines);
|
|
97
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract registry — runtime resolution of extension-provided implementations.
|
|
3
|
+
*
|
|
4
|
+
* @module extensions/contracts
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { MISSING_EXTENSION_ERROR } from "./errors.js";
|
|
8
|
+
import { getRecommendation } from "./recommendations.js";
|
|
9
|
+
|
|
10
|
+
const contracts = new Map<string, unknown>();
|
|
11
|
+
|
|
12
|
+
export function resolve<T>(name: string): T {
|
|
13
|
+
const impl = contracts.get(name);
|
|
14
|
+
if (impl === undefined) {
|
|
15
|
+
const recommendation = getRecommendation(name);
|
|
16
|
+
throw MISSING_EXTENSION_ERROR.create({
|
|
17
|
+
message: `Missing extension for contract "${name}"${
|
|
18
|
+
recommendation ? `. Recommended: ${recommendation}` : ""
|
|
19
|
+
}`,
|
|
20
|
+
detail: recommendation ? `Install it with: deno add ${recommendation}` : undefined,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
return impl as T;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function tryResolve<T>(name: string): T | undefined {
|
|
27
|
+
return contracts.get(name) as T | undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function register<T>(name: string, impl: T): void {
|
|
31
|
+
contracts.set(name, impl);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function reset(): void {
|
|
35
|
+
contracts.clear();
|
|
36
|
+
}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-source extension discovery.
|
|
3
|
+
*
|
|
4
|
+
* Discovers extensions from four sources with priority:
|
|
5
|
+
* config > package > project > local-file
|
|
6
|
+
*
|
|
7
|
+
* @module extensions/discovery
|
|
8
|
+
*/
|
|
9
|
+
import * as dntShim from "../../_dnt.shims.js";
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
import { join } from "../../deps/jsr.io/@std/path/1.1.4/mod.js";
|
|
13
|
+
import type { Capability, ResolvedExtension } from "./types.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Metadata extracted from a package.json that declares itself
|
|
17
|
+
* as a veryfront extension.
|
|
18
|
+
*/
|
|
19
|
+
export interface PackageMetadata {
|
|
20
|
+
isExtension: true;
|
|
21
|
+
capabilities: Capability[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function isCapability(value: unknown): value is Capability {
|
|
25
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const cap = value as Record<string, unknown>;
|
|
29
|
+
return typeof cap.type === "string" && cap.type.length > 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Parse veryfront extension metadata from a package.json-like object.
|
|
34
|
+
*
|
|
35
|
+
* Returns `PackageMetadata` when the package declares
|
|
36
|
+
* `veryfront.extension: true`, otherwise `undefined`. Malformed capability
|
|
37
|
+
* entries are filtered out; the caller receives only valid shapes.
|
|
38
|
+
*/
|
|
39
|
+
export function parsePackageMetadata(
|
|
40
|
+
pkg: Record<string, unknown>,
|
|
41
|
+
): PackageMetadata | undefined {
|
|
42
|
+
const vf = pkg.veryfront;
|
|
43
|
+
if (
|
|
44
|
+
vf === null || vf === undefined || typeof vf !== "object" ||
|
|
45
|
+
Array.isArray(vf)
|
|
46
|
+
) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const meta = vf as Record<string, unknown>;
|
|
51
|
+
if (meta.extension !== true) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const capabilities: Capability[] = Array.isArray(meta.capabilities)
|
|
56
|
+
? meta.capabilities.filter(isCapability)
|
|
57
|
+
: [];
|
|
58
|
+
|
|
59
|
+
return { isExtension: true, capabilities };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Merge extensions from all four sources in priority order.
|
|
64
|
+
*
|
|
65
|
+
* Priority (highest first): config > package > project > local-file.
|
|
66
|
+
* Duplicates are resolved by keeping the highest-priority entry.
|
|
67
|
+
* Disable directives (`{ name, enabled: false }`) remove matching
|
|
68
|
+
* extensions regardless of source.
|
|
69
|
+
*/
|
|
70
|
+
export function mergeExtensions(
|
|
71
|
+
config: ResolvedExtension[],
|
|
72
|
+
packages: ResolvedExtension[],
|
|
73
|
+
project: ResolvedExtension[],
|
|
74
|
+
local: ResolvedExtension[],
|
|
75
|
+
disableDirectives?: Array<{ name: string; enabled: false }>,
|
|
76
|
+
): ResolvedExtension[] {
|
|
77
|
+
const disabledNames = new Set(
|
|
78
|
+
(disableDirectives ?? []).map((d) => d.name),
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const seen = new Map<string, ResolvedExtension>();
|
|
82
|
+
|
|
83
|
+
// Process sources in priority order -- first write wins.
|
|
84
|
+
const ordered: ResolvedExtension[] = [
|
|
85
|
+
...config,
|
|
86
|
+
...packages,
|
|
87
|
+
...project,
|
|
88
|
+
...local,
|
|
89
|
+
];
|
|
90
|
+
|
|
91
|
+
for (const resolved of ordered) {
|
|
92
|
+
const name = resolved.extension.name;
|
|
93
|
+
if (disabledNames.has(name)) continue;
|
|
94
|
+
if (!seen.has(name)) {
|
|
95
|
+
seen.set(name, resolved);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return [...seen.values()];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
// Filesystem discovery helpers
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
|
|
106
|
+
async function readDir(path: string): Promise<dntShim.Deno.DirEntry[]> {
|
|
107
|
+
try {
|
|
108
|
+
const entries: dntShim.Deno.DirEntry[] = [];
|
|
109
|
+
for await (const entry of dntShim.Deno.readDir(path)) {
|
|
110
|
+
entries.push(entry);
|
|
111
|
+
}
|
|
112
|
+
return entries;
|
|
113
|
+
} catch (err) {
|
|
114
|
+
if (err instanceof dntShim.Deno.errors.NotFound) return [];
|
|
115
|
+
throw err;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function fileExists(path: string): Promise<boolean> {
|
|
120
|
+
try {
|
|
121
|
+
await dntShim.Deno.stat(path);
|
|
122
|
+
return true;
|
|
123
|
+
} catch (err) {
|
|
124
|
+
if (err instanceof dntShim.Deno.errors.NotFound) return false;
|
|
125
|
+
throw err;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Scan `node_modules` (including `@scoped` packages) for packages
|
|
131
|
+
* that declare veryfront extension metadata in their `package.json`.
|
|
132
|
+
*/
|
|
133
|
+
export async function discoverPackageExtensions(
|
|
134
|
+
baseDir: string,
|
|
135
|
+
): Promise<Array<{ packageName: string; metadata: PackageMetadata }>> {
|
|
136
|
+
const nmDir = join(baseDir, "node_modules");
|
|
137
|
+
const results: Array<{ packageName: string; metadata: PackageMetadata }> = [];
|
|
138
|
+
const entries = await readDir(nmDir);
|
|
139
|
+
|
|
140
|
+
for (const entry of entries) {
|
|
141
|
+
// Accept symlinks so pnpm-style node_modules layouts are discovered.
|
|
142
|
+
if (!entry.isDirectory && !entry.isSymlink) continue;
|
|
143
|
+
|
|
144
|
+
if (entry.name.startsWith("@")) {
|
|
145
|
+
// Scoped packages -- iterate one level deeper.
|
|
146
|
+
const scopeDir = join(nmDir, entry.name);
|
|
147
|
+
const scopeEntries = await readDir(scopeDir);
|
|
148
|
+
for (const scopeEntry of scopeEntries) {
|
|
149
|
+
if (!scopeEntry.isDirectory && !scopeEntry.isSymlink) continue;
|
|
150
|
+
const pkgName = `${entry.name}/${scopeEntry.name}`;
|
|
151
|
+
const meta = await tryReadPackageMeta(
|
|
152
|
+
join(scopeDir, scopeEntry.name),
|
|
153
|
+
);
|
|
154
|
+
if (meta) results.push({ packageName: pkgName, metadata: meta });
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
const meta = await tryReadPackageMeta(join(nmDir, entry.name));
|
|
158
|
+
if (meta) results.push({ packageName: entry.name, metadata: meta });
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return results;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async function tryReadPackageMeta(
|
|
166
|
+
pkgDir: string,
|
|
167
|
+
): Promise<PackageMetadata | undefined> {
|
|
168
|
+
let raw: string;
|
|
169
|
+
try {
|
|
170
|
+
raw = await dntShim.Deno.readTextFile(join(pkgDir, "package.json"));
|
|
171
|
+
} catch (err) {
|
|
172
|
+
if (err instanceof dntShim.Deno.errors.NotFound) return undefined;
|
|
173
|
+
throw err;
|
|
174
|
+
}
|
|
175
|
+
try {
|
|
176
|
+
const pkg = JSON.parse(raw) as Record<string, unknown>;
|
|
177
|
+
return parsePackageMetadata(pkg);
|
|
178
|
+
} catch {
|
|
179
|
+
// Malformed JSON -- treat as non-extension package.
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Discover project extensions living under `extensions/` in the project root.
|
|
186
|
+
*
|
|
187
|
+
* Looks for `extensions/<name>/src/index.ts` and `extensions/<name>/index.ts`.
|
|
188
|
+
*/
|
|
189
|
+
export async function discoverProjectExtensions(
|
|
190
|
+
baseDir: string,
|
|
191
|
+
): Promise<string[]> {
|
|
192
|
+
const extDir = join(baseDir, "extensions");
|
|
193
|
+
const entries = await readDir(extDir);
|
|
194
|
+
const results: string[] = [];
|
|
195
|
+
|
|
196
|
+
for (const entry of entries) {
|
|
197
|
+
if (!entry.isDirectory) continue;
|
|
198
|
+
const srcIndex = join(extDir, entry.name, "src", "index.ts");
|
|
199
|
+
const rootIndex = join(extDir, entry.name, "index.ts");
|
|
200
|
+
|
|
201
|
+
if (await fileExists(srcIndex)) {
|
|
202
|
+
results.push(srcIndex);
|
|
203
|
+
} else if (await fileExists(rootIndex)) {
|
|
204
|
+
results.push(rootIndex);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return results;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Find `*.extension.ts` files in the project root.
|
|
213
|
+
*/
|
|
214
|
+
export async function discoverLocalExtensions(
|
|
215
|
+
baseDir: string,
|
|
216
|
+
): Promise<string[]> {
|
|
217
|
+
const entries = await readDir(baseDir);
|
|
218
|
+
return entries
|
|
219
|
+
.filter((e) => !e.isDirectory && e.name.endsWith(".extension.ts"))
|
|
220
|
+
.map((e) => join(baseDir, e.name));
|
|
221
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension system error definitions.
|
|
3
|
+
*
|
|
4
|
+
* @module extensions/errors
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { defineError } from "../errors/index.js";
|
|
8
|
+
|
|
9
|
+
export const MISSING_EXTENSION_ERROR = defineError({
|
|
10
|
+
slug: "missing-extension",
|
|
11
|
+
category: "RUNTIME",
|
|
12
|
+
status: 500,
|
|
13
|
+
title: "Required extension not found",
|
|
14
|
+
suggestion: "Install the missing extension package and add it to your configuration",
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export const EXTENSION_VALIDATION_ERROR = defineError({
|
|
18
|
+
slug: "extension-validation",
|
|
19
|
+
category: "CONFIG",
|
|
20
|
+
status: 422,
|
|
21
|
+
title: "Extension validation failed",
|
|
22
|
+
suggestion: "Check that the extension exports a valid name, version, and capabilities array",
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export const CIRCULAR_DEPENDENCY_ERROR = defineError({
|
|
26
|
+
slug: "extension-circular-dependency",
|
|
27
|
+
category: "CONFIG",
|
|
28
|
+
status: 422,
|
|
29
|
+
title: "Circular dependency detected between extensions",
|
|
30
|
+
suggestion: "Review the 'extends' fields in your extensions to break the cycle",
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export const EXTENSION_CONFLICT_ERROR = defineError({
|
|
34
|
+
slug: "extension-conflict",
|
|
35
|
+
category: "CONFIG",
|
|
36
|
+
status: 409,
|
|
37
|
+
title: "Conflicting extensions detected",
|
|
38
|
+
suggestion: "Remove or disable one of the conflicting extensions in your configuration",
|
|
39
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic factory loader.
|
|
3
|
+
*
|
|
4
|
+
* Loads an extension factory from a filesystem path by dynamic import,
|
|
5
|
+
* invokes it, and wraps the result as a `ResolvedExtension`.
|
|
6
|
+
*
|
|
7
|
+
* @module extensions/factory-loader
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { isAbsolute, toFileUrl } from "../../deps/jsr.io/@std/path/1.1.4/mod.js";
|
|
11
|
+
import { EXTENSION_VALIDATION_ERROR } from "./errors.js";
|
|
12
|
+
import type { Extension, ExtensionFactory, ExtensionSource, ResolvedExtension } from "./types.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Dynamically import an extension factory from `path` and resolve it.
|
|
16
|
+
*
|
|
17
|
+
* `path` may be either an absolute filesystem path (for project and
|
|
18
|
+
* local-file sources) or a bare module specifier (for `package` source).
|
|
19
|
+
* Absolute paths are converted to `file://` URLs; bare specifiers are
|
|
20
|
+
* passed through so the runtime's module resolver can find them.
|
|
21
|
+
*
|
|
22
|
+
* The module must `export default` an `ExtensionFactory` (a function that
|
|
23
|
+
* returns an `Extension`). On any error — missing default export, default
|
|
24
|
+
* export that is not a function, factory throw, or import failure — this
|
|
25
|
+
* throws `EXTENSION_VALIDATION_ERROR` with a `detail` field that names the
|
|
26
|
+
* path and what went wrong.
|
|
27
|
+
*
|
|
28
|
+
* @param path Absolute filesystem path or bare module specifier.
|
|
29
|
+
* @param source Where the extension was discovered (drives merge priority).
|
|
30
|
+
* @param config Optional config forwarded to the factory.
|
|
31
|
+
*/
|
|
32
|
+
export async function loadExtensionFactory(
|
|
33
|
+
path: string,
|
|
34
|
+
source: ExtensionSource,
|
|
35
|
+
config?: unknown,
|
|
36
|
+
): Promise<ResolvedExtension> {
|
|
37
|
+
const specifier = isAbsolute(path) ? toFileUrl(path).href : path;
|
|
38
|
+
let mod: { default?: unknown };
|
|
39
|
+
try {
|
|
40
|
+
mod = await import(specifier);
|
|
41
|
+
} catch (err) {
|
|
42
|
+
throw EXTENSION_VALIDATION_ERROR.create({
|
|
43
|
+
detail: `Failed to import extension at "${path}": ${
|
|
44
|
+
err instanceof Error ? err.message : String(err)
|
|
45
|
+
}`,
|
|
46
|
+
cause: err,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const factory = mod.default;
|
|
51
|
+
if (factory === undefined || factory === null) {
|
|
52
|
+
throw EXTENSION_VALIDATION_ERROR.create({
|
|
53
|
+
detail: `Extension at "${path}" has no default export`,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (typeof factory !== "function") {
|
|
58
|
+
throw EXTENSION_VALIDATION_ERROR.create({
|
|
59
|
+
detail: `Extension at "${path}" default export is not a function (got ${typeof factory})`,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let extension: Extension;
|
|
64
|
+
try {
|
|
65
|
+
extension = (factory as ExtensionFactory)(config);
|
|
66
|
+
} catch (err) {
|
|
67
|
+
throw EXTENSION_VALIDATION_ERROR.create({
|
|
68
|
+
detail: `Extension factory at "${path}" threw during invocation: ${
|
|
69
|
+
err instanceof Error ? err.message : String(err)
|
|
70
|
+
}`,
|
|
71
|
+
cause: err,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return { extension, source, origin: path };
|
|
76
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public extension API surface.
|
|
3
|
+
*
|
|
4
|
+
* Types used when authoring extensions (the scaffold template generated by
|
|
5
|
+
* `veryfront extension init` imports from this module), plus the runtime
|
|
6
|
+
* helpers consumers need to load, validate, and orchestrate extensions.
|
|
7
|
+
*
|
|
8
|
+
* @module extensions
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { orchestrateExtensions } from "veryfront/extensions";
|
|
12
|
+
*
|
|
13
|
+
* const loader = await orchestrateExtensions({
|
|
14
|
+
* projectDir: Deno.cwd(),
|
|
15
|
+
* config,
|
|
16
|
+
* logger,
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Later, on shutdown:
|
|
20
|
+
* await loader.teardownAll();
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
// Core types
|
|
25
|
+
import "../../_dnt.polyfills.js";
|
|
26
|
+
|
|
27
|
+
export type {
|
|
28
|
+
Capability,
|
|
29
|
+
Extension,
|
|
30
|
+
ExtensionConfigEntry,
|
|
31
|
+
ExtensionContext,
|
|
32
|
+
ExtensionFactory,
|
|
33
|
+
ExtensionLogger,
|
|
34
|
+
ExtensionSource,
|
|
35
|
+
ResolvedExtension,
|
|
36
|
+
} from "./types.js";
|
|
37
|
+
|
|
38
|
+
// Contract registry — resolve/tryResolve are the consumer-facing API.
|
|
39
|
+
// register()/reset() are internal primitives (used by ExtensionLoader and
|
|
40
|
+
// tests) and are intentionally not exported here.
|
|
41
|
+
export { resolve, tryResolve } from "./contracts.js";
|
|
42
|
+
|
|
43
|
+
// Discovery
|
|
44
|
+
export type { PackageMetadata } from "./discovery.js";
|
|
45
|
+
export {
|
|
46
|
+
discoverLocalExtensions,
|
|
47
|
+
discoverPackageExtensions,
|
|
48
|
+
discoverProjectExtensions,
|
|
49
|
+
mergeExtensions,
|
|
50
|
+
parsePackageMetadata,
|
|
51
|
+
} from "./discovery.js";
|
|
52
|
+
|
|
53
|
+
// Loader
|
|
54
|
+
export { ExtensionLoader } from "./loader.js";
|
|
55
|
+
|
|
56
|
+
// Factory loader (dynamic-import of an extension factory)
|
|
57
|
+
export { loadExtensionFactory } from "./factory-loader.js";
|
|
58
|
+
|
|
59
|
+
// Orchestrator (discover → load → merge → setup)
|
|
60
|
+
export type { OrchestrateOptions } from "./orchestrate.js";
|
|
61
|
+
export { orchestrateExtensions } from "./orchestrate.js";
|
|
62
|
+
|
|
63
|
+
// Validation
|
|
64
|
+
export type { ConflictInfo } from "./validation.js";
|
|
65
|
+
export { detectConflicts, validateExtension } from "./validation.js";
|
|
66
|
+
|
|
67
|
+
// Capabilities
|
|
68
|
+
export { auditCapabilities, formatCapabilities, mapToDenoPermissions } from "./capabilities.js";
|
|
69
|
+
|
|
70
|
+
// Recommendations
|
|
71
|
+
export { getRecommendation } from "./recommendations.js";
|
|
72
|
+
|
|
73
|
+
// Errors
|
|
74
|
+
export {
|
|
75
|
+
CIRCULAR_DEPENDENCY_ERROR,
|
|
76
|
+
EXTENSION_CONFLICT_ERROR,
|
|
77
|
+
EXTENSION_VALIDATION_ERROR,
|
|
78
|
+
MISSING_EXTENSION_ERROR,
|
|
79
|
+
} from "./errors.js";
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract interface for AI/LLM model providers.
|
|
3
|
+
*
|
|
4
|
+
* Default implementation: `@veryfront/ext-openai`
|
|
5
|
+
*
|
|
6
|
+
* @module extensions/interfaces/ai-model-provider
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** A single part of a multi-modal message (text or image). */
|
|
10
|
+
export interface ContentPart {
|
|
11
|
+
/** Part type. */
|
|
12
|
+
type: "text" | "image";
|
|
13
|
+
/** Text content (when `type` is `"text"`). */
|
|
14
|
+
text?: string;
|
|
15
|
+
/** Image URL or base64 data (when `type` is `"image"`). */
|
|
16
|
+
imageUrl?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** A chat message in a conversation. */
|
|
20
|
+
export interface ChatMessage {
|
|
21
|
+
/** Message role. */
|
|
22
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
23
|
+
/** Simple text content. */
|
|
24
|
+
content?: string;
|
|
25
|
+
/** Multi-modal content parts (used instead of `content`). */
|
|
26
|
+
parts?: ContentPart[];
|
|
27
|
+
/** Tool call ID this message responds to (for `tool` role). */
|
|
28
|
+
toolCallId?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Definition of a tool the model may invoke. */
|
|
32
|
+
export interface ToolDefinition {
|
|
33
|
+
/** Tool name. */
|
|
34
|
+
name: string;
|
|
35
|
+
/** Human-readable description of what the tool does. */
|
|
36
|
+
description: string;
|
|
37
|
+
/** JSON Schema describing the tool's parameters. */
|
|
38
|
+
parameters: Record<string, unknown>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Options passed to {@link AIModelProvider.complete} and {@link AIModelProvider.stream}. */
|
|
42
|
+
export interface CompletionOptions {
|
|
43
|
+
/** Model identifier (e.g. `"gpt-4o"`, `"claude-sonnet-4-20250514"`). */
|
|
44
|
+
model: string;
|
|
45
|
+
/** Conversation messages. */
|
|
46
|
+
messages: ChatMessage[];
|
|
47
|
+
/** Sampling temperature. */
|
|
48
|
+
temperature?: number;
|
|
49
|
+
/** Maximum tokens to generate. */
|
|
50
|
+
maxTokens?: number;
|
|
51
|
+
/** Available tools for function calling. */
|
|
52
|
+
tools?: ToolDefinition[];
|
|
53
|
+
/** Additional provider-specific options. */
|
|
54
|
+
[key: string]: unknown;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Result returned from {@link AIModelProvider.complete}. */
|
|
58
|
+
export interface CompletionResult {
|
|
59
|
+
/** Generated text content. */
|
|
60
|
+
content: string;
|
|
61
|
+
/** Tool calls requested by the model, if any. */
|
|
62
|
+
toolCalls?: Array<{
|
|
63
|
+
id: string;
|
|
64
|
+
name: string;
|
|
65
|
+
arguments: string;
|
|
66
|
+
}>;
|
|
67
|
+
/** Token usage statistics. */
|
|
68
|
+
usage?: {
|
|
69
|
+
promptTokens: number;
|
|
70
|
+
completionTokens: number;
|
|
71
|
+
totalTokens: number;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** A chunk emitted during streaming completion. */
|
|
76
|
+
export interface StreamChunk {
|
|
77
|
+
/** Incremental text delta. */
|
|
78
|
+
content?: string;
|
|
79
|
+
/** Incremental tool call delta. */
|
|
80
|
+
toolCallDelta?: {
|
|
81
|
+
id?: string;
|
|
82
|
+
name?: string;
|
|
83
|
+
arguments?: string;
|
|
84
|
+
};
|
|
85
|
+
/** Whether this is the final chunk. */
|
|
86
|
+
done: boolean;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* AIModelProvider contract interface.
|
|
91
|
+
*
|
|
92
|
+
* Implementations provide chat completion and streaming capabilities
|
|
93
|
+
* against large language models.
|
|
94
|
+
*/
|
|
95
|
+
export interface AIModelProvider {
|
|
96
|
+
/** Generate a complete response for the given conversation. */
|
|
97
|
+
complete(options: CompletionOptions): Promise<CompletionResult>;
|
|
98
|
+
/** Stream a response token-by-token. */
|
|
99
|
+
stream(options: CompletionOptions): AsyncIterable<StreamChunk>;
|
|
100
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract interface for authentication token providers.
|
|
3
|
+
*
|
|
4
|
+
* Default implementation: `@veryfront/ext-jwt`
|
|
5
|
+
*
|
|
6
|
+
* @module extensions/interfaces/auth-provider
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** Payload data stored within a signed token. */
|
|
10
|
+
export interface TokenPayload {
|
|
11
|
+
/** Subject identifier (typically a user ID). */
|
|
12
|
+
sub: string;
|
|
13
|
+
/** Expiration time as a Unix timestamp (seconds). */
|
|
14
|
+
exp?: number;
|
|
15
|
+
/** Issued-at time as a Unix timestamp (seconds). */
|
|
16
|
+
iat?: number;
|
|
17
|
+
/** Additional claims. */
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Options for signing a token. */
|
|
22
|
+
export interface SignOptions {
|
|
23
|
+
/** Token lifetime (e.g. `"1h"`, `"7d"`, or seconds as a number). */
|
|
24
|
+
expiresIn?: string | number;
|
|
25
|
+
/** Signing algorithm (e.g. `"HS256"`, `"RS256"`). */
|
|
26
|
+
algorithm?: string;
|
|
27
|
+
/** Additional implementation-specific options. */
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Options for verifying a token. */
|
|
32
|
+
export interface VerifyOptions {
|
|
33
|
+
/** Expected algorithms to accept. */
|
|
34
|
+
algorithms?: string[];
|
|
35
|
+
/** Additional implementation-specific options. */
|
|
36
|
+
[key: string]: unknown;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* AuthProvider contract interface.
|
|
41
|
+
*
|
|
42
|
+
* Implementations sign, verify, and decode authentication tokens
|
|
43
|
+
* (e.g. JWTs) for request authentication.
|
|
44
|
+
*/
|
|
45
|
+
export interface AuthProvider {
|
|
46
|
+
/** Sign a payload into a token string. */
|
|
47
|
+
sign(payload: TokenPayload, options?: SignOptions): Promise<string>;
|
|
48
|
+
/** Verify a token and return its decoded payload. Throws on invalid tokens. */
|
|
49
|
+
verify(token: string, options?: VerifyOptions): Promise<TokenPayload>;
|
|
50
|
+
/** Decode a token without verifying its signature. */
|
|
51
|
+
decode(token: string): TokenPayload | undefined;
|
|
52
|
+
}
|