apcore-js 0.5.0 → 0.7.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/README.md +1 -1
- package/dist/acl.d.ts +27 -0
- package/dist/acl.d.ts.map +1 -0
- package/dist/acl.js +175 -0
- package/dist/acl.js.map +1 -0
- package/dist/approval.d.ts +85 -0
- package/dist/approval.d.ts.map +1 -0
- package/dist/approval.js +73 -0
- package/dist/approval.js.map +1 -0
- package/dist/async-task.d.ts +90 -0
- package/dist/async-task.d.ts.map +1 -0
- package/dist/async-task.js +215 -0
- package/dist/async-task.js.map +1 -0
- package/dist/bindings.d.ts +12 -0
- package/dist/bindings.d.ts.map +1 -0
- package/dist/bindings.js +185 -0
- package/dist/bindings.js.map +1 -0
- package/dist/cancel.d.ts +14 -0
- package/dist/cancel.d.ts.map +1 -0
- package/dist/cancel.js +27 -0
- package/dist/cancel.js.map +1 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +23 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +50 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +87 -0
- package/dist/context.js.map +1 -0
- package/dist/decorator.d.ts +57 -0
- package/dist/decorator.d.ts.map +1 -0
- package/dist/decorator.js +74 -0
- package/dist/decorator.js.map +1 -0
- package/dist/errors.d.ts +204 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +364 -0
- package/dist/errors.js.map +1 -0
- package/dist/executor.d.ts +82 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +489 -0
- package/dist/executor.js.map +1 -0
- package/dist/extensions.d.ts +58 -0
- package/dist/extensions.d.ts.map +1 -0
- package/dist/extensions.js +239 -0
- package/dist/extensions.js.map +1 -0
- package/{src/index.ts → dist/index.d.ts} +6 -63
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/adapters.d.ts +18 -0
- package/dist/middleware/adapters.d.ts.map +1 -0
- package/dist/middleware/adapters.js +25 -0
- package/dist/middleware/adapters.js.map +1 -0
- package/dist/middleware/base.d.ts +10 -0
- package/dist/middleware/base.d.ts.map +1 -0
- package/dist/middleware/base.js +15 -0
- package/dist/middleware/base.js.map +1 -0
- package/{src/middleware/index.ts → dist/middleware/index.d.ts} +1 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +5 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/logging.d.ts +25 -0
- package/dist/middleware/logging.d.ts.map +1 -0
- package/dist/middleware/logging.js +64 -0
- package/dist/middleware/logging.js.map +1 -0
- package/dist/middleware/manager.d.ts +21 -0
- package/dist/middleware/manager.d.ts.map +1 -0
- package/dist/middleware/manager.js +77 -0
- package/dist/middleware/manager.js.map +1 -0
- package/dist/module.d.ts +31 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +12 -0
- package/dist/module.js.map +1 -0
- package/dist/observability/context-logger.d.ts +54 -0
- package/dist/observability/context-logger.d.ts.map +1 -0
- package/dist/observability/context-logger.js +151 -0
- package/dist/observability/context-logger.js.map +1 -0
- package/{src/observability/index.ts → dist/observability/index.d.ts} +1 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +4 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/metrics.d.ts +30 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/metrics.js +177 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/observability/tracing.d.ts +62 -0
- package/dist/observability/tracing.d.ts.map +1 -0
- package/dist/observability/tracing.js +184 -0
- package/dist/observability/tracing.js.map +1 -0
- package/dist/registry/dependencies.d.ts +6 -0
- package/dist/registry/dependencies.d.ts.map +1 -0
- package/dist/registry/dependencies.js +83 -0
- package/dist/registry/dependencies.js.map +1 -0
- package/dist/registry/entry-point.d.ts +6 -0
- package/dist/registry/entry-point.d.ts.map +1 -0
- package/dist/registry/entry-point.js +55 -0
- package/dist/registry/entry-point.js.map +1 -0
- package/{src/registry/index.ts → dist/registry/index.d.ts} +1 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +8 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/metadata.d.ts +9 -0
- package/dist/registry/metadata.d.ts.map +1 -0
- package/dist/registry/metadata.js +105 -0
- package/dist/registry/metadata.js.map +1 -0
- package/dist/registry/registry.d.ts +102 -0
- package/dist/registry/registry.d.ts.map +1 -0
- package/dist/registry/registry.js +534 -0
- package/dist/registry/registry.js.map +1 -0
- package/dist/registry/scanner.d.ts +7 -0
- package/dist/registry/scanner.d.ts.map +1 -0
- package/dist/registry/scanner.js +164 -0
- package/dist/registry/scanner.js.map +1 -0
- package/dist/registry/schema-export.d.ts +9 -0
- package/dist/registry/schema-export.d.ts.map +1 -0
- package/dist/registry/schema-export.js +132 -0
- package/dist/registry/schema-export.js.map +1 -0
- package/dist/registry/types.d.ts +29 -0
- package/dist/registry/types.d.ts.map +1 -0
- package/dist/registry/types.js +5 -0
- package/dist/registry/types.js.map +1 -0
- package/dist/registry/validation.d.ts +9 -0
- package/dist/registry/validation.d.ts.map +1 -0
- package/dist/registry/validation.js +33 -0
- package/dist/registry/validation.js.map +1 -0
- package/dist/schema/annotations.d.ts +8 -0
- package/dist/schema/annotations.d.ts.map +1 -0
- package/dist/schema/annotations.js +52 -0
- package/dist/schema/annotations.js.map +1 -0
- package/dist/schema/exporter.d.ts +13 -0
- package/dist/schema/exporter.d.ts.map +1 -0
- package/dist/schema/exporter.js +71 -0
- package/dist/schema/exporter.js.map +1 -0
- package/dist/schema/index.d.ts +9 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/{src/schema/index.ts → dist/schema/index.js} +1 -7
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/loader.d.ts +30 -0
- package/dist/schema/loader.d.ts.map +1 -0
- package/dist/schema/loader.js +260 -0
- package/dist/schema/loader.js.map +1 -0
- package/dist/schema/ref-resolver.d.ts +19 -0
- package/dist/schema/ref-resolver.d.ts.map +1 -0
- package/dist/schema/ref-resolver.js +212 -0
- package/dist/schema/ref-resolver.js.map +1 -0
- package/dist/schema/strict.d.ts +7 -0
- package/dist/schema/strict.d.ts.map +1 -0
- package/dist/schema/strict.js +127 -0
- package/dist/schema/strict.js.map +1 -0
- package/dist/schema/types.d.ts +53 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/types.js +31 -0
- package/dist/schema/types.js.map +1 -0
- package/dist/schema/validator.d.ts +16 -0
- package/dist/schema/validator.d.ts.map +1 -0
- package/dist/schema/validator.js +71 -0
- package/dist/schema/validator.js.map +1 -0
- package/dist/trace-context.d.ts +35 -0
- package/dist/trace-context.d.ts.map +1 -0
- package/dist/trace-context.js +86 -0
- package/dist/trace-context.js.map +1 -0
- package/dist/utils/index.d.ts +11 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +32 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/pattern.d.ts +5 -0
- package/dist/utils/pattern.d.ts.map +1 -0
- package/dist/utils/pattern.js +31 -0
- package/dist/utils/pattern.js.map +1 -0
- package/package.json +24 -3
- package/.claude/settings.local.json +0 -12
- package/.github/workflows/ci.yml +0 -39
- package/.gitmessage +0 -60
- package/.pre-commit-config.yaml +0 -28
- package/CHANGELOG.md +0 -214
- package/CLAUDE.md +0 -68
- package/apcore-logo.svg +0 -79
- package/planning/acl-system/overview.md +0 -54
- package/planning/acl-system/plan.md +0 -92
- package/planning/acl-system/state.json +0 -76
- package/planning/acl-system/tasks/acl-core.md +0 -226
- package/planning/acl-system/tasks/acl-rule.md +0 -92
- package/planning/acl-system/tasks/conditional-rules.md +0 -259
- package/planning/acl-system/tasks/pattern-matching.md +0 -152
- package/planning/acl-system/tasks/yaml-loading.md +0 -271
- package/planning/core-executor/overview.md +0 -53
- package/planning/core-executor/plan.md +0 -88
- package/planning/core-executor/state.json +0 -76
- package/planning/core-executor/tasks/async-support.md +0 -106
- package/planning/core-executor/tasks/execution-pipeline.md +0 -113
- package/planning/core-executor/tasks/redaction.md +0 -85
- package/planning/core-executor/tasks/safety-checks.md +0 -65
- package/planning/core-executor/tasks/setup.md +0 -75
- package/planning/decorator-bindings/overview.md +0 -62
- package/planning/decorator-bindings/plan.md +0 -104
- package/planning/decorator-bindings/state.json +0 -87
- package/planning/decorator-bindings/tasks/binding-directory.md +0 -79
- package/planning/decorator-bindings/tasks/binding-loader.md +0 -148
- package/planning/decorator-bindings/tasks/explicit-schemas.md +0 -85
- package/planning/decorator-bindings/tasks/function-module.md +0 -127
- package/planning/decorator-bindings/tasks/module-factory.md +0 -89
- package/planning/decorator-bindings/tasks/schema-modes.md +0 -142
- package/planning/middleware-system/overview.md +0 -48
- package/planning/middleware-system/plan.md +0 -102
- package/planning/middleware-system/state.json +0 -65
- package/planning/middleware-system/tasks/adapters.md +0 -170
- package/planning/middleware-system/tasks/base.md +0 -115
- package/planning/middleware-system/tasks/logging-middleware.md +0 -304
- package/planning/middleware-system/tasks/manager.md +0 -313
- package/planning/observability/overview.md +0 -53
- package/planning/observability/plan.md +0 -119
- package/planning/observability/state.json +0 -98
- package/planning/observability/tasks/context-logger.md +0 -201
- package/planning/observability/tasks/exporters.md +0 -121
- package/planning/observability/tasks/metrics-collector.md +0 -162
- package/planning/observability/tasks/metrics-middleware.md +0 -141
- package/planning/observability/tasks/obs-logging-middleware.md +0 -179
- package/planning/observability/tasks/span-model.md +0 -120
- package/planning/observability/tasks/tracing-middleware.md +0 -179
- package/planning/overview.md +0 -81
- package/planning/registry-system/overview.md +0 -57
- package/planning/registry-system/plan.md +0 -114
- package/planning/registry-system/state.json +0 -109
- package/planning/registry-system/tasks/dependencies.md +0 -157
- package/planning/registry-system/tasks/entry-point.md +0 -148
- package/planning/registry-system/tasks/metadata.md +0 -198
- package/planning/registry-system/tasks/registry-core.md +0 -323
- package/planning/registry-system/tasks/scanner.md +0 -172
- package/planning/registry-system/tasks/schema-export.md +0 -261
- package/planning/registry-system/tasks/types.md +0 -124
- package/planning/registry-system/tasks/validation.md +0 -177
- package/planning/schema-system/overview.md +0 -56
- package/planning/schema-system/plan.md +0 -121
- package/planning/schema-system/state.json +0 -98
- package/planning/schema-system/tasks/exporter.md +0 -153
- package/planning/schema-system/tasks/loader.md +0 -106
- package/planning/schema-system/tasks/ref-resolver.md +0 -133
- package/planning/schema-system/tasks/strict-mode.md +0 -140
- package/planning/schema-system/tasks/typebox-generation.md +0 -133
- package/planning/schema-system/tasks/types-and-annotations.md +0 -160
- package/planning/schema-system/tasks/validator.md +0 -149
- package/src/acl.ts +0 -200
- package/src/async-task.ts +0 -267
- package/src/bindings.ts +0 -207
- package/src/cancel.ts +0 -32
- package/src/config.ts +0 -24
- package/src/context.ts +0 -160
- package/src/decorator.ts +0 -110
- package/src/errors.ts +0 -429
- package/src/executor.ts +0 -493
- package/src/extensions.ts +0 -265
- package/src/middleware/adapters.ts +0 -54
- package/src/middleware/base.ts +0 -33
- package/src/middleware/logging.ts +0 -103
- package/src/middleware/manager.ts +0 -105
- package/src/module.ts +0 -43
- package/src/observability/context-logger.ts +0 -203
- package/src/observability/metrics.ts +0 -214
- package/src/observability/tracing.ts +0 -252
- package/src/registry/dependencies.ts +0 -99
- package/src/registry/entry-point.ts +0 -64
- package/src/registry/metadata.ts +0 -111
- package/src/registry/registry.ts +0 -580
- package/src/registry/scanner.ts +0 -168
- package/src/registry/schema-export.ts +0 -181
- package/src/registry/types.ts +0 -32
- package/src/registry/validation.ts +0 -38
- package/src/schema/annotations.ts +0 -68
- package/src/schema/exporter.ts +0 -90
- package/src/schema/loader.ts +0 -273
- package/src/schema/ref-resolver.ts +0 -244
- package/src/schema/strict.ts +0 -136
- package/src/schema/types.ts +0 -73
- package/src/schema/validator.ts +0 -82
- package/src/trace-context.ts +0 -102
- package/src/utils/index.ts +0 -5
- package/src/utils/pattern.ts +0 -30
- package/tests/async-task.test.ts +0 -335
- package/tests/helpers.ts +0 -30
- package/tests/integration/test-acl-safety.test.ts +0 -269
- package/tests/integration/test-binding-executor.test.ts +0 -194
- package/tests/integration/test-e2e-flow.test.ts +0 -117
- package/tests/integration/test-error-propagation.test.ts +0 -259
- package/tests/integration/test-middleware-chain.test.ts +0 -120
- package/tests/integration/test-observability-integration.test.ts +0 -438
- package/tests/observability/test-context-logger.test.ts +0 -123
- package/tests/observability/test-metrics.test.ts +0 -186
- package/tests/observability/test-tracing.test.ts +0 -303
- package/tests/registry/test-dependencies.test.ts +0 -70
- package/tests/registry/test-entry-point.test.ts +0 -133
- package/tests/registry/test-metadata.test.ts +0 -265
- package/tests/registry/test-registry.test.ts +0 -1397
- package/tests/registry/test-scanner.test.ts +0 -257
- package/tests/registry/test-schema-export.test.ts +0 -355
- package/tests/registry/test-validation.test.ts +0 -75
- package/tests/schema/test-annotations.test.ts +0 -137
- package/tests/schema/test-exporter.test.ts +0 -172
- package/tests/schema/test-loader.test.ts +0 -461
- package/tests/schema/test-ref-resolver.test.ts +0 -530
- package/tests/schema/test-strict.test.ts +0 -348
- package/tests/schema/test-validator.test.ts +0 -64
- package/tests/test-acl.test.ts +0 -423
- package/tests/test-bindings.test.ts +0 -227
- package/tests/test-cancel.test.ts +0 -71
- package/tests/test-config.test.ts +0 -76
- package/tests/test-context.test.ts +0 -266
- package/tests/test-decorator.test.ts +0 -173
- package/tests/test-errors.test.ts +0 -647
- package/tests/test-executor-stream.test.ts +0 -208
- package/tests/test-executor.test.ts +0 -252
- package/tests/test-extensions.test.ts +0 -310
- package/tests/test-logging-middleware.test.ts +0 -150
- package/tests/test-middleware-manager.test.ts +0 -185
- package/tests/test-middleware.test.ts +0 -86
- package/tests/test-trace-context.test.ts +0 -251
- package/tests/utils/test-pattern.test.ts +0 -109
- package/tsconfig.build.json +0 -8
- package/tsconfig.json +0 -20
- package/vitest.config.ts +0 -18
package/src/registry/scanner.ts
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Directory scanner for discovering TypeScript/JavaScript extension modules.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { readdirSync, statSync, lstatSync, realpathSync } from 'node:fs';
|
|
6
|
-
import { resolve, relative, join, extname, basename, sep } from 'node:path';
|
|
7
|
-
import { ConfigError, ConfigNotFoundError } from '../errors.js';
|
|
8
|
-
import type { DiscoveredModule } from './types.js';
|
|
9
|
-
|
|
10
|
-
const SKIP_DIR_NAMES = new Set(['node_modules', '__pycache__']);
|
|
11
|
-
const VALID_EXTENSIONS = new Set(['.ts', '.js']);
|
|
12
|
-
const SKIP_SUFFIXES = ['.d.ts', '.test.ts', '.test.js', '.spec.ts', '.spec.js'];
|
|
13
|
-
|
|
14
|
-
function existsAndIsDir(p: string): boolean {
|
|
15
|
-
try {
|
|
16
|
-
return statSync(p).isDirectory();
|
|
17
|
-
} catch {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function scanExtensions(
|
|
23
|
-
root: string,
|
|
24
|
-
maxDepth: number = 8,
|
|
25
|
-
followSymlinks: boolean = false,
|
|
26
|
-
): DiscoveredModule[] {
|
|
27
|
-
const rootResolved = resolve(root);
|
|
28
|
-
if (!existsAndIsDir(rootResolved)) {
|
|
29
|
-
throw new ConfigNotFoundError(rootResolved);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const visitedRealPaths = new Set([realpathSync(rootResolved)]);
|
|
33
|
-
const results: DiscoveredModule[] = [];
|
|
34
|
-
const seenIds = new Map<string, string>();
|
|
35
|
-
const seenIdsLower = new Map<string, string>();
|
|
36
|
-
|
|
37
|
-
function scanDir(dirPath: string, depth: number): void {
|
|
38
|
-
if (depth > maxDepth) {
|
|
39
|
-
console.warn(`[apcore:scanner] Max depth ${maxDepth} exceeded at: ${dirPath}`);
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
let entries: string[];
|
|
44
|
-
try {
|
|
45
|
-
entries = readdirSync(dirPath);
|
|
46
|
-
} catch {
|
|
47
|
-
console.warn(`[apcore:scanner] Cannot read directory: ${dirPath}`);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
for (const name of entries) {
|
|
52
|
-
if (name.startsWith('.') || name.startsWith('_')) continue;
|
|
53
|
-
if (SKIP_DIR_NAMES.has(name)) continue;
|
|
54
|
-
|
|
55
|
-
const entryPath = join(dirPath, name);
|
|
56
|
-
let lstat;
|
|
57
|
-
try {
|
|
58
|
-
lstat = lstatSync(entryPath);
|
|
59
|
-
} catch {
|
|
60
|
-
console.warn(`[apcore:scanner] Cannot stat entry: ${entryPath}`);
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const isSymlink = lstat.isSymbolicLink();
|
|
65
|
-
let isDir: boolean;
|
|
66
|
-
let isFile: boolean;
|
|
67
|
-
|
|
68
|
-
if (isSymlink) {
|
|
69
|
-
if (!followSymlinks) continue;
|
|
70
|
-
const real = realpathSync(entryPath);
|
|
71
|
-
if (visitedRealPaths.has(real)) continue;
|
|
72
|
-
visitedRealPaths.add(real);
|
|
73
|
-
// Resolve the symlink target to check if it's a dir or file
|
|
74
|
-
let targetStat;
|
|
75
|
-
try {
|
|
76
|
-
targetStat = statSync(entryPath);
|
|
77
|
-
} catch {
|
|
78
|
-
console.warn(`[apcore:scanner] Cannot resolve symlink target: ${entryPath}`);
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
isDir = targetStat.isDirectory();
|
|
82
|
-
isFile = targetStat.isFile();
|
|
83
|
-
} else {
|
|
84
|
-
isDir = lstat.isDirectory();
|
|
85
|
-
isFile = lstat.isFile();
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (isDir) {
|
|
89
|
-
scanDir(entryPath, depth + 1);
|
|
90
|
-
} else if (isFile) {
|
|
91
|
-
const ext = extname(name);
|
|
92
|
-
if (!VALID_EXTENSIONS.has(ext)) continue;
|
|
93
|
-
if (SKIP_SUFFIXES.some((s) => name.endsWith(s))) continue;
|
|
94
|
-
|
|
95
|
-
const rel = relative(rootResolved, entryPath);
|
|
96
|
-
const canonicalId = rel
|
|
97
|
-
.replace(new RegExp(`\\${sep}`, 'g'), '.')
|
|
98
|
-
.replace(/\.(ts|js)$/, '');
|
|
99
|
-
|
|
100
|
-
if (seenIds.has(canonicalId)) {
|
|
101
|
-
console.warn(`[apcore:scanner] Duplicate module ID '${canonicalId}', skipping: ${entryPath}`);
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const lowerId = canonicalId.toLowerCase();
|
|
106
|
-
if (seenIdsLower.has(lowerId) && seenIdsLower.get(lowerId) !== canonicalId) {
|
|
107
|
-
console.warn(`[apcore:scanner] Case collision: '${canonicalId}' vs '${seenIdsLower.get(lowerId)}'`);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Check for companion metadata file
|
|
111
|
-
const stem = basename(entryPath, ext);
|
|
112
|
-
const metaPath = join(dirPath, stem + '_meta.yaml');
|
|
113
|
-
let metaPathResult: string | null = null;
|
|
114
|
-
try {
|
|
115
|
-
if (statSync(metaPath).isFile()) metaPathResult = metaPath;
|
|
116
|
-
} catch {
|
|
117
|
-
// no meta file
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
seenIds.set(canonicalId, entryPath);
|
|
121
|
-
seenIdsLower.set(lowerId, canonicalId);
|
|
122
|
-
results.push({
|
|
123
|
-
filePath: entryPath,
|
|
124
|
-
canonicalId,
|
|
125
|
-
metaPath: metaPathResult,
|
|
126
|
-
namespace: null,
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
scanDir(rootResolved, 1);
|
|
133
|
-
return results;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export function scanMultiRoot(
|
|
137
|
-
roots: Array<Record<string, unknown>>,
|
|
138
|
-
maxDepth: number = 8,
|
|
139
|
-
followSymlinks: boolean = false,
|
|
140
|
-
): DiscoveredModule[] {
|
|
141
|
-
const allResults: DiscoveredModule[] = [];
|
|
142
|
-
const seenNamespaces = new Set<string>();
|
|
143
|
-
|
|
144
|
-
const resolved: Array<[string, string]> = [];
|
|
145
|
-
for (const entry of roots) {
|
|
146
|
-
const rootPath = entry['root'] as string;
|
|
147
|
-
const namespace = (entry['namespace'] as string) || basename(rootPath);
|
|
148
|
-
if (seenNamespaces.has(namespace)) {
|
|
149
|
-
throw new ConfigError(`Duplicate namespace: '${namespace}'`);
|
|
150
|
-
}
|
|
151
|
-
seenNamespaces.add(namespace);
|
|
152
|
-
resolved.push([rootPath, namespace]);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
for (const [rootPath, namespace] of resolved) {
|
|
156
|
-
const modules = scanExtensions(rootPath, maxDepth, followSymlinks);
|
|
157
|
-
for (const m of modules) {
|
|
158
|
-
allResults.push({
|
|
159
|
-
filePath: m.filePath,
|
|
160
|
-
canonicalId: `${namespace}.${m.canonicalId}`,
|
|
161
|
-
metaPath: m.metaPath,
|
|
162
|
-
namespace,
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return allResults;
|
|
168
|
-
}
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Schema query and export functions for the registry system.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type { TSchema } from '@sinclair/typebox';
|
|
6
|
-
import yaml from 'js-yaml';
|
|
7
|
-
import type { ModuleAnnotations, ModuleExample } from '../module.js';
|
|
8
|
-
import { InvalidInputError, ModuleNotFoundError } from '../errors.js';
|
|
9
|
-
import { deepCopy } from '../utils/index.js';
|
|
10
|
-
import { SchemaExporter } from '../schema/exporter.js';
|
|
11
|
-
import { stripExtensions, toStrictSchema } from '../schema/strict.js';
|
|
12
|
-
import { ExportProfile, type SchemaDefinition } from '../schema/types.js';
|
|
13
|
-
import type { Registry } from './registry.js';
|
|
14
|
-
|
|
15
|
-
export function getSchema(registry: Registry, moduleId: string): Record<string, unknown> | null {
|
|
16
|
-
const module = registry.get(moduleId);
|
|
17
|
-
if (module === null) return null;
|
|
18
|
-
|
|
19
|
-
const mod = module as Record<string, unknown>;
|
|
20
|
-
|
|
21
|
-
// TypeBox schemas are already JSON Schema
|
|
22
|
-
const inputSchemaDict = mod['inputSchema'] as Record<string, unknown> ?? {};
|
|
23
|
-
const outputSchemaDict = mod['outputSchema'] as Record<string, unknown> ?? {};
|
|
24
|
-
|
|
25
|
-
const annotations = mod['annotations'] as ModuleAnnotations | undefined;
|
|
26
|
-
let annotationsDict: Record<string, unknown> | null = null;
|
|
27
|
-
if (annotations) {
|
|
28
|
-
annotationsDict = { ...annotations };
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const examplesRaw = (mod['examples'] as ModuleExample[] | undefined) ?? [];
|
|
32
|
-
const examplesList = examplesRaw.map((ex) => ({ ...ex }));
|
|
33
|
-
|
|
34
|
-
return {
|
|
35
|
-
module_id: moduleId,
|
|
36
|
-
name: (mod['name'] as string) ?? null,
|
|
37
|
-
description: (mod['description'] as string) ?? '',
|
|
38
|
-
version: (mod['version'] as string) ?? '1.0.0',
|
|
39
|
-
tags: [...((mod['tags'] as string[]) ?? [])],
|
|
40
|
-
input_schema: inputSchemaDict,
|
|
41
|
-
output_schema: outputSchemaDict,
|
|
42
|
-
annotations: annotationsDict,
|
|
43
|
-
examples: examplesList,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function exportSchema(
|
|
48
|
-
registry: Registry,
|
|
49
|
-
moduleId: string,
|
|
50
|
-
format: string = 'json',
|
|
51
|
-
strict: boolean = false,
|
|
52
|
-
compact: boolean = false,
|
|
53
|
-
profile?: string | null,
|
|
54
|
-
): string {
|
|
55
|
-
const schemaDict = getSchema(registry, moduleId);
|
|
56
|
-
if (schemaDict === null) {
|
|
57
|
-
throw new ModuleNotFoundError(moduleId);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (profile != null) {
|
|
61
|
-
return exportWithProfile(registry, moduleId, schemaDict, profile, format);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const result = deepCopy(schemaDict);
|
|
65
|
-
|
|
66
|
-
if (strict) {
|
|
67
|
-
result['input_schema'] = toStrictSchema(result['input_schema'] as Record<string, unknown>);
|
|
68
|
-
result['output_schema'] = toStrictSchema(result['output_schema'] as Record<string, unknown>);
|
|
69
|
-
} else if (compact) {
|
|
70
|
-
applyCompact(result);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return serialize(result, format);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export function getAllSchemas(registry: Registry): Record<string, Record<string, unknown>> {
|
|
77
|
-
const result: Record<string, Record<string, unknown>> = {};
|
|
78
|
-
for (const moduleId of registry.moduleIds) {
|
|
79
|
-
const schema = getSchema(registry, moduleId);
|
|
80
|
-
if (schema !== null) {
|
|
81
|
-
result[moduleId] = schema;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return result;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export function exportAllSchemas(
|
|
88
|
-
registry: Registry,
|
|
89
|
-
format: string = 'json',
|
|
90
|
-
strict: boolean = false,
|
|
91
|
-
compact: boolean = false,
|
|
92
|
-
profile?: string | null,
|
|
93
|
-
): string {
|
|
94
|
-
const allSchemas = getAllSchemas(registry);
|
|
95
|
-
|
|
96
|
-
if (strict || compact) {
|
|
97
|
-
for (const [moduleId, schema] of Object.entries(allSchemas)) {
|
|
98
|
-
const result = deepCopy(schema);
|
|
99
|
-
if (strict) {
|
|
100
|
-
result['input_schema'] = toStrictSchema(result['input_schema'] as Record<string, unknown>);
|
|
101
|
-
result['output_schema'] = toStrictSchema(result['output_schema'] as Record<string, unknown>);
|
|
102
|
-
} else if (compact) {
|
|
103
|
-
applyCompact(result);
|
|
104
|
-
}
|
|
105
|
-
allSchemas[moduleId] = result;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return serialize(allSchemas, format);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function exportWithProfile(
|
|
113
|
-
registry: Registry,
|
|
114
|
-
moduleId: string,
|
|
115
|
-
schemaDict: Record<string, unknown>,
|
|
116
|
-
profile: string,
|
|
117
|
-
format: string,
|
|
118
|
-
): string {
|
|
119
|
-
const schemaDef: SchemaDefinition = {
|
|
120
|
-
moduleId,
|
|
121
|
-
description: schemaDict['description'] as string,
|
|
122
|
-
inputSchema: schemaDict['input_schema'] as Record<string, unknown>,
|
|
123
|
-
outputSchema: schemaDict['output_schema'] as Record<string, unknown>,
|
|
124
|
-
definitions: {},
|
|
125
|
-
version: (schemaDict['version'] as string) ?? '1.0.0',
|
|
126
|
-
};
|
|
127
|
-
const module = registry.get(moduleId);
|
|
128
|
-
const annotations = module ? (module as Record<string, unknown>)['annotations'] as ModuleAnnotations | undefined : undefined;
|
|
129
|
-
const examples = module ? ((module as Record<string, unknown>)['examples'] as ModuleExample[]) ?? [] : [];
|
|
130
|
-
const name = module ? (module as Record<string, unknown>)['name'] as string | undefined : undefined;
|
|
131
|
-
|
|
132
|
-
const validProfiles = new Set(Object.values(ExportProfile));
|
|
133
|
-
if (!validProfiles.has(profile as ExportProfile)) {
|
|
134
|
-
throw new InvalidInputError(
|
|
135
|
-
`Invalid export profile: '${profile}'. Must be one of: ${[...validProfiles].join(', ')}`,
|
|
136
|
-
);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const exported = new SchemaExporter().export(
|
|
140
|
-
schemaDef,
|
|
141
|
-
profile as ExportProfile,
|
|
142
|
-
annotations,
|
|
143
|
-
examples,
|
|
144
|
-
name,
|
|
145
|
-
);
|
|
146
|
-
return serialize(exported, format);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
function applyCompact(schemaDict: Record<string, unknown>): void {
|
|
150
|
-
const desc = schemaDict['description'] as string;
|
|
151
|
-
if (desc) {
|
|
152
|
-
schemaDict['description'] = truncateDescription(desc);
|
|
153
|
-
}
|
|
154
|
-
stripExtensions(schemaDict['input_schema'] as Record<string, unknown> ?? {});
|
|
155
|
-
stripExtensions(schemaDict['output_schema'] as Record<string, unknown> ?? {});
|
|
156
|
-
delete schemaDict['documentation'];
|
|
157
|
-
delete schemaDict['examples'];
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function truncateDescription(description: string): string {
|
|
161
|
-
const dotSpace = description.indexOf('. ');
|
|
162
|
-
const newline = description.indexOf('\n');
|
|
163
|
-
|
|
164
|
-
const candidates: number[] = [];
|
|
165
|
-
if (dotSpace >= 0) candidates.push(dotSpace + 1);
|
|
166
|
-
if (newline >= 0) candidates.push(newline);
|
|
167
|
-
|
|
168
|
-
if (candidates.length > 0) {
|
|
169
|
-
const cut = Math.min(...candidates);
|
|
170
|
-
return description.slice(0, cut).trimEnd();
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return description;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
function serialize(data: unknown, format: string): string {
|
|
177
|
-
if (format === 'yaml') {
|
|
178
|
-
return yaml.dump(data, { flowLevel: -1 });
|
|
179
|
-
}
|
|
180
|
-
return JSON.stringify(data, null, 2);
|
|
181
|
-
}
|
package/src/registry/types.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Registry types: ModuleDescriptor, DiscoveredModule, DependencyInfo.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type { ModuleAnnotations, ModuleExample } from '../module.js';
|
|
6
|
-
|
|
7
|
-
export interface ModuleDescriptor {
|
|
8
|
-
moduleId: string;
|
|
9
|
-
name: string | null;
|
|
10
|
-
description: string;
|
|
11
|
-
documentation: string | null;
|
|
12
|
-
inputSchema: Record<string, unknown>;
|
|
13
|
-
outputSchema: Record<string, unknown>;
|
|
14
|
-
version: string;
|
|
15
|
-
tags: string[];
|
|
16
|
-
annotations: ModuleAnnotations | null;
|
|
17
|
-
examples: ModuleExample[];
|
|
18
|
-
metadata: Record<string, unknown>;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface DiscoveredModule {
|
|
22
|
-
filePath: string;
|
|
23
|
-
canonicalId: string;
|
|
24
|
-
metaPath: string | null;
|
|
25
|
-
namespace: string | null;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface DependencyInfo {
|
|
29
|
-
moduleId: string;
|
|
30
|
-
version: string | null;
|
|
31
|
-
optional: boolean;
|
|
32
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Module validation for the registry system.
|
|
3
|
-
*
|
|
4
|
-
* In TypeScript, modules use TypeBox TSchema (which are plain objects) instead of
|
|
5
|
-
* Pydantic BaseModel classes. Duck-type checks validate that the module has
|
|
6
|
-
* inputSchema, outputSchema, description, and execute.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
export function validateModule(moduleOrClass: unknown): string[] {
|
|
10
|
-
const errors: string[] = [];
|
|
11
|
-
const obj = moduleOrClass as Record<string, unknown>;
|
|
12
|
-
|
|
13
|
-
// Check inputSchema
|
|
14
|
-
const inputSchema = obj['inputSchema'] ?? (obj.constructor as unknown as Record<string, unknown>)?.['inputSchema'];
|
|
15
|
-
if (inputSchema == null || typeof inputSchema !== 'object') {
|
|
16
|
-
errors.push('Missing or invalid inputSchema: must be a TSchema object');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Check outputSchema
|
|
20
|
-
const outputSchema = obj['outputSchema'] ?? (obj.constructor as unknown as Record<string, unknown>)?.['outputSchema'];
|
|
21
|
-
if (outputSchema == null || typeof outputSchema !== 'object') {
|
|
22
|
-
errors.push('Missing or invalid outputSchema: must be a TSchema object');
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Check description
|
|
26
|
-
const description = obj['description'];
|
|
27
|
-
if (!description || typeof description !== 'string') {
|
|
28
|
-
errors.push('Missing or empty description');
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Check execute
|
|
32
|
-
const execute = obj['execute'];
|
|
33
|
-
if (execute == null || typeof execute !== 'function') {
|
|
34
|
-
errors.push('Missing execute method');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return errors;
|
|
38
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Annotation conflict resolution — merge YAML and code metadata.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type { ModuleAnnotations, ModuleExample } from '../module.js';
|
|
6
|
-
import { DEFAULT_ANNOTATIONS } from '../module.js';
|
|
7
|
-
|
|
8
|
-
const ANNOTATION_FIELDS: ReadonlyArray<keyof ModuleAnnotations> = [
|
|
9
|
-
'readonly',
|
|
10
|
-
'destructive',
|
|
11
|
-
'idempotent',
|
|
12
|
-
'requiresApproval',
|
|
13
|
-
'openWorld',
|
|
14
|
-
'streaming',
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
export function mergeAnnotations(
|
|
18
|
-
yamlAnnotations: Record<string, unknown> | null | undefined,
|
|
19
|
-
codeAnnotations: ModuleAnnotations | null | undefined,
|
|
20
|
-
): ModuleAnnotations {
|
|
21
|
-
const values: Record<string, unknown> = {};
|
|
22
|
-
for (const f of ANNOTATION_FIELDS) {
|
|
23
|
-
values[f] = DEFAULT_ANNOTATIONS[f];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (codeAnnotations != null) {
|
|
27
|
-
for (const f of ANNOTATION_FIELDS) {
|
|
28
|
-
values[f] = codeAnnotations[f];
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (yamlAnnotations != null) {
|
|
33
|
-
for (const [key, val] of Object.entries(yamlAnnotations)) {
|
|
34
|
-
if ((ANNOTATION_FIELDS as readonly string[]).includes(key)) {
|
|
35
|
-
values[key] = val;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return values as unknown as ModuleAnnotations;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export function mergeExamples(
|
|
44
|
-
yamlExamples: Array<Record<string, unknown>> | null | undefined,
|
|
45
|
-
codeExamples: ModuleExample[] | null | undefined,
|
|
46
|
-
): ModuleExample[] {
|
|
47
|
-
if (yamlExamples != null) {
|
|
48
|
-
return yamlExamples.map((d) => ({
|
|
49
|
-
title: d['title'] as string,
|
|
50
|
-
inputs: (d['inputs'] as Record<string, unknown>) ?? {},
|
|
51
|
-
output: (d['output'] as Record<string, unknown>) ?? {},
|
|
52
|
-
description: d['description'] as string | undefined,
|
|
53
|
-
}));
|
|
54
|
-
}
|
|
55
|
-
if (codeExamples != null) return codeExamples;
|
|
56
|
-
return [];
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export function mergeMetadata(
|
|
60
|
-
yamlMetadata: Record<string, unknown> | null | undefined,
|
|
61
|
-
codeMetadata: Record<string, unknown> | null | undefined,
|
|
62
|
-
): Record<string, unknown> {
|
|
63
|
-
const result = codeMetadata != null ? { ...codeMetadata } : {};
|
|
64
|
-
if (yamlMetadata != null) {
|
|
65
|
-
Object.assign(result, yamlMetadata);
|
|
66
|
-
}
|
|
67
|
-
return result;
|
|
68
|
-
}
|
package/src/schema/exporter.ts
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SchemaExporter — converts schemas to platform-specific export formats.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type { ModuleAnnotations, ModuleExample } from '../module.js';
|
|
6
|
-
import { deepCopy } from '../utils/index.js';
|
|
7
|
-
import { applyLlmDescriptions, stripExtensions, toStrictSchema } from './strict.js';
|
|
8
|
-
import { ExportProfile, type SchemaDefinition } from './types.js';
|
|
9
|
-
|
|
10
|
-
export class SchemaExporter {
|
|
11
|
-
export(
|
|
12
|
-
schemaDef: SchemaDefinition,
|
|
13
|
-
profile: ExportProfile,
|
|
14
|
-
annotations?: ModuleAnnotations | null,
|
|
15
|
-
examples?: ModuleExample[] | null,
|
|
16
|
-
name?: string | null,
|
|
17
|
-
): Record<string, unknown> {
|
|
18
|
-
if (profile === ExportProfile.MCP) {
|
|
19
|
-
return this.exportMcp(schemaDef, annotations, name);
|
|
20
|
-
}
|
|
21
|
-
if (profile === ExportProfile.OpenAI) {
|
|
22
|
-
return this.exportOpenai(schemaDef);
|
|
23
|
-
}
|
|
24
|
-
if (profile === ExportProfile.Anthropic) {
|
|
25
|
-
return this.exportAnthropic(schemaDef, examples);
|
|
26
|
-
}
|
|
27
|
-
return this.exportGeneric(schemaDef);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
exportMcp(
|
|
31
|
-
schemaDef: SchemaDefinition,
|
|
32
|
-
annotations?: ModuleAnnotations | null,
|
|
33
|
-
name?: string | null,
|
|
34
|
-
): Record<string, unknown> {
|
|
35
|
-
return {
|
|
36
|
-
name: name ?? schemaDef.moduleId,
|
|
37
|
-
description: schemaDef.description,
|
|
38
|
-
inputSchema: schemaDef.inputSchema,
|
|
39
|
-
annotations: {
|
|
40
|
-
readOnlyHint: annotations?.readonly ?? false,
|
|
41
|
-
destructiveHint: annotations?.destructive ?? false,
|
|
42
|
-
idempotentHint: annotations?.idempotent ?? false,
|
|
43
|
-
openWorldHint: annotations?.openWorld ?? true,
|
|
44
|
-
},
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
exportOpenai(schemaDef: SchemaDefinition): Record<string, unknown> {
|
|
49
|
-
const schema = deepCopy(schemaDef.inputSchema);
|
|
50
|
-
applyLlmDescriptions(schema);
|
|
51
|
-
const strictSchema = toStrictSchema(schema);
|
|
52
|
-
return {
|
|
53
|
-
type: 'function',
|
|
54
|
-
function: {
|
|
55
|
-
name: schemaDef.moduleId.replace(/\./g, '_'),
|
|
56
|
-
description: schemaDef.description,
|
|
57
|
-
parameters: strictSchema,
|
|
58
|
-
strict: true,
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
exportAnthropic(
|
|
64
|
-
schemaDef: SchemaDefinition,
|
|
65
|
-
examples?: ModuleExample[] | null,
|
|
66
|
-
): Record<string, unknown> {
|
|
67
|
-
const schema = deepCopy(schemaDef.inputSchema);
|
|
68
|
-
applyLlmDescriptions(schema);
|
|
69
|
-
stripExtensions(schema);
|
|
70
|
-
const result: Record<string, unknown> = {
|
|
71
|
-
name: schemaDef.moduleId.replace(/\./g, '_'),
|
|
72
|
-
description: schemaDef.description,
|
|
73
|
-
input_schema: schema,
|
|
74
|
-
};
|
|
75
|
-
if (examples && examples.length > 0) {
|
|
76
|
-
result['input_examples'] = examples.map((ex) => ex.inputs);
|
|
77
|
-
}
|
|
78
|
-
return result;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
exportGeneric(schemaDef: SchemaDefinition): Record<string, unknown> {
|
|
82
|
-
return {
|
|
83
|
-
module_id: schemaDef.moduleId,
|
|
84
|
-
description: schemaDef.description,
|
|
85
|
-
input_schema: schemaDef.inputSchema,
|
|
86
|
-
output_schema: schemaDef.outputSchema,
|
|
87
|
-
definitions: schemaDef.definitions,
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
}
|