@adhd/apigen-cli 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.
@@ -0,0 +1 @@
1
+ export declare function apigenCli(): string;
@@ -0,0 +1,4 @@
1
+ import { OutputPlugin } from '@adhd/apigen-core';
2
+ import { Command } from 'commander';
3
+
4
+ export declare function registerGenerateRegistryCommand(program: Command, plugins: Record<string, OutputPlugin>): void;
@@ -0,0 +1,6 @@
1
+ import { ExportMode, OutputPlugin } from '@adhd/apigen-core';
2
+ import { Command } from 'commander';
3
+
4
+ /** Resolve the --export flag value to an ExportMode. */
5
+ export declare function resolveExportMode(exportFlag: string | undefined): ExportMode;
6
+ export declare function registerGenerateCommand(program: Command, plugins: Record<string, OutputPlugin>): void;
@@ -0,0 +1,4 @@
1
+ import { OutputPlugin } from '@adhd/apigen-core';
2
+ import { Command } from 'commander';
3
+
4
+ export declare function registerRunRegistryCommand(program: Command, plugins: Record<string, OutputPlugin>): void;
@@ -0,0 +1,4 @@
1
+ import { OutputPlugin } from '@adhd/apigen-core';
2
+ import { Command } from 'commander';
3
+
4
+ export declare function registerRunCommand(program: Command, plugins: Record<string, OutputPlugin>): void;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Dynamically import a (possibly TypeScript) source module, registering the tsx
3
+ * ESM loader for the duration of the import so that `.ts` entry files resolve in
4
+ * a plain `node` process. The loader is unregistered afterward so no global hook
5
+ * leaks into the rest of the run.
6
+ *
7
+ * Under a transpiling test runner (vitest) tsx registration is a harmless no-op,
8
+ * so this same path works in-repo and standalone.
9
+ *
10
+ * @param absSource - Absolute path to the source file to import.
11
+ * @param tsconfig - Optional tsconfig.json path to drive tsx's transpilation.
12
+ * @returns The imported module namespace.
13
+ */
14
+ export declare function importSource(absSource: string, tsconfig?: string): Promise<Record<string, unknown>>;
@@ -0,0 +1,16 @@
1
+ import { Logger } from '@adhd/apigen-runtime';
2
+ import { Command } from 'commander';
3
+
4
+ export interface LoggingFlags {
5
+ logLevel?: string;
6
+ logFormat?: string;
7
+ logFile?: string;
8
+ }
9
+ /** Add program-level logging options. Env vars provide fallbacks at build time. */
10
+ export declare function addLoggingOptions(program: Command): Command;
11
+ /**
12
+ * Build the shared CLI logger from program-level flags, falling back to env
13
+ * vars (`APIGEN_LOG_LEVEL`, `APIGEN_LOG_FORMAT`, `APIGEN_LOG_FILE`). Flags win
14
+ * over env. Logs target stderr (or `--log-file`) — never stdout.
15
+ */
16
+ export declare function buildCliLogger(program: Command): Logger;
@@ -0,0 +1,153 @@
1
+ import { ProjectionConfig } from '@adhd/apigen-naming';
2
+ import { Operation, Descriptor, ComposedSchemas, ExportMode, Logger, OutputPlugin } from '@adhd/apigen-core';
3
+
4
+ /**
5
+ * A single source entry passed to the orchestrator.
6
+ *
7
+ * `file` is an absolute path. Language detection is performed here — for now
8
+ * `.ts` / `.tsx` / `.mts` / `.cts` → `'ts'`; everything else is unsupported
9
+ * and will throw.
10
+ */
11
+ export interface SourceEntry {
12
+ /** Absolute path to the source file. */
13
+ file: string;
14
+ /**
15
+ * Export mode for this source. Defaults to `{ type: 'named' }` when omitted.
16
+ * Per-source because a single `run` may compose multiple differently-shaped
17
+ * sources.
18
+ */
19
+ exportMode?: ExportMode;
20
+ /**
21
+ * Namespace override for this source. When omitted, namespace is resolved
22
+ * from the nearest tsconfig folder (same logic as v1).
23
+ */
24
+ namespace?: string;
25
+ /** Explicit tsconfig.json path. Resolved per source file when omitted. */
26
+ tsconfig?: string;
27
+ }
28
+ /**
29
+ * Projection-override config (Tenet 1).
30
+ *
31
+ * Accepted from `--opt http.verb.<id>=GET` pairs or an `apigen.config` file.
32
+ * Overrides are NEVER written to source.
33
+ */
34
+ export interface OverrideConfig extends ProjectionConfig {
35
+ }
36
+ /** Options passed to the v2 orchestrator. */
37
+ export interface OrchestratorOptions {
38
+ /** Source files to extract and merge. Must be non-empty. */
39
+ sources: SourceEntry[];
40
+ /**
41
+ * Plugin ids supplied via `--use <plugin>` (layer / mount / envelope
42
+ * plugins). Validated but not dispatched in v1 — wired through for v2.x.
43
+ */
44
+ usePlugins?: string[];
45
+ /** Projection-override config (Tenet 1). */
46
+ overrides?: OverrideConfig;
47
+ /** Shared logger. */
48
+ logger?: Logger;
49
+ }
50
+ /** The unified canonical descriptor built by the orchestrator. */
51
+ export interface OrchestratorDescriptor {
52
+ /** All extracted + merged operations (tagged by `host`). */
53
+ operations: Operation[];
54
+ /**
55
+ * Per-source composed schemas, keyed by the source's resolved namespace.
56
+ * The v1 `PluginInput.packages` is built from these.
57
+ */
58
+ packageSchemas: Map<string, {
59
+ id: string;
60
+ schemas: ComposedSchemas;
61
+ importPath: string;
62
+ }>;
63
+ }
64
+ /** Result returned by `orchestrateGenerate`. */
65
+ export interface GenerateResult {
66
+ descriptor: OrchestratorDescriptor;
67
+ pluginOutput: Awaited<ReturnType<OutputPlugin['generate']>>;
68
+ }
69
+ /** Supported host languages (only 'ts' in v1). */
70
+ export type HostLang = 'ts';
71
+ /**
72
+ * Detects the host language from a file path extension.
73
+ *
74
+ * @throws if the extension is not a recognised TypeScript extension.
75
+ */
76
+ export declare function detectLang(filePath: string): HostLang;
77
+ /**
78
+ * Parses `--opt` key=value pairs into an {@link OverrideConfig}.
79
+ *
80
+ * Recognises:
81
+ * `http.verb.<operationId>=GET` → config.http.verb[operationId] = 'GET'
82
+ *
83
+ * Unknown keys are silently ignored (forward-compatible).
84
+ *
85
+ * @param pairs - Raw `key=value` strings from `--opt`.
86
+ */
87
+ export declare function parseOverrides(pairs: string[]): OverrideConfig;
88
+ /**
89
+ * Loads an `apigen.config` JSON file and merges it with CLI overrides.
90
+ *
91
+ * CLI overrides win over the file. The file is optional; when absent this is
92
+ * a no-op.
93
+ *
94
+ * @param configPath - Optional explicit path. When omitted, looks for
95
+ * `apigen.config.json` in the current working directory.
96
+ * @param cliOverrides - Already-parsed CLI overrides (win over file).
97
+ */
98
+ export declare function loadOverrideConfig(configPath: string | undefined, cliOverrides: OverrideConfig): OverrideConfig;
99
+ /**
100
+ * Merge multiple per-source `Operation[]` arrays into one unified list.
101
+ *
102
+ * Operations are tagged by `host` from the extractor. No deduplication — two
103
+ * distinct sources may export the same name in different namespaces; the
104
+ * collision check enforces uniqueness across transports.
105
+ *
106
+ * @param perSourceOps - Arrays produced by {@link extractSource} per file.
107
+ */
108
+ export declare function mergeOperations(perSourceOps: Operation[][]): Operation[];
109
+ /**
110
+ * Build the unified `OrchestratorDescriptor` from a set of source entries.
111
+ *
112
+ * Steps:
113
+ * 1. Detect language per source.
114
+ * 2. Extract canonical `Operation[]` per source (v2 extract).
115
+ * 3. Merge into one list.
116
+ * 4. Run the collision check (SPEC §5 uniqueness invariant).
117
+ * 5. Build per-source `ComposedSchemas` for the v1 plugin surface.
118
+ *
119
+ * @param opts - Orchestrator options.
120
+ */
121
+ export declare function buildDescriptor(opts: OrchestratorOptions): Promise<OrchestratorDescriptor>;
122
+ /**
123
+ * Run the v2 orchestrator in **generate** mode.
124
+ *
125
+ * Builds the unified descriptor, then invokes the selected plugin's `generate`
126
+ * method with the merged package set.
127
+ *
128
+ * @param opts - Orchestrator options.
129
+ * @param plugin - The selected output plugin (`--type`).
130
+ * @param outputDir - Absolute path to the output directory.
131
+ * @param pluginOpts - Plugin-level options (`--opt` key=value pairs, already parsed).
132
+ */
133
+ export declare function orchestrateGenerate(opts: OrchestratorOptions, plugin: OutputPlugin, outputDir: string, pluginOpts?: Record<string, unknown>): Promise<GenerateResult>;
134
+ /**
135
+ * Run the v2 orchestrator in **run** (server) mode.
136
+ *
137
+ * Builds the unified descriptor, then invokes the selected plugin's `run`
138
+ * method with the merged package set + live function tables.
139
+ *
140
+ * @param opts - Orchestrator options.
141
+ * @param plugin - The selected output plugin (`--type`).
142
+ * @param buildFnTables - Async function that imports each source and returns
143
+ * `(fns, createClient)` for that source. Injected by
144
+ * the command layer so the orchestrator stays testable
145
+ * without live imports.
146
+ * @param signal - Abort signal forwarded from the process SIGINT handler.
147
+ * @param pluginOpts - Plugin-level options.
148
+ */
149
+ export declare function orchestrateRun(opts: OrchestratorOptions, plugin: OutputPlugin, buildFnTables: (entry: SourceEntry) => Promise<{
150
+ fns: Record<string, (...args: unknown[]) => unknown>;
151
+ createClient: (envelope: Record<string, unknown>) => Promise<object>;
152
+ }>, signal: AbortSignal, pluginOpts?: Record<string, unknown>): Promise<void>;
153
+ export type { Descriptor };
@@ -0,0 +1,22 @@
1
+ import { ComposedSchemas, ExportMode, Logger } from '@adhd/apigen-core';
2
+
3
+ export interface PipelineOptions {
4
+ sourceFile: string;
5
+ exportMode?: ExportMode;
6
+ middlewares?: Array<{
7
+ id: string;
8
+ envelope?: Record<string, unknown>;
9
+ }>;
10
+ overrides?: Record<string, Record<string, boolean>>;
11
+ namespace?: string;
12
+ /** Explicit --tsconfig flag; when omitted, the nearest/builtin config is resolved from sourceFile. */
13
+ tsconfig?: string;
14
+ /** Optional shared logger; when present the pipeline logs schema extraction. */
15
+ logger?: Logger;
16
+ }
17
+ export interface PipelineResult {
18
+ schemas: ComposedSchemas;
19
+ createClient: (envelope: Record<string, unknown>) => Promise<object>;
20
+ }
21
+ /** Run the generate + compose pipeline for a single source file. */
22
+ export declare function runPipeline(opts: PipelineOptions): Promise<PipelineResult>;
@@ -0,0 +1,12 @@
1
+ export interface PackageMeta {
2
+ id: string;
3
+ dir: string;
4
+ importPath: string;
5
+ tags: string[];
6
+ }
7
+ /** Discover packages in a directory, filtered by tag. Reads package.json for tags/keywords. */
8
+ export declare function discoverPackages(opts: {
9
+ packagesDir: string;
10
+ includeTags?: string[];
11
+ excludeTags?: string[];
12
+ }): PackageMeta[];
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Resolve the tsconfig that should drive schema generation for `sourceFile`.
3
+ *
4
+ * Precedence: explicit `--tsconfig` (absolute) → nearest `tsconfig.json` walking
5
+ * up from the source's directory → shipped builtin default.
6
+ *
7
+ * @param sourceFile - Absolute path to the TypeScript source file.
8
+ * @param explicit - Optional `--tsconfig` flag value (resolved against cwd).
9
+ * @returns Absolute path to a real tsconfig.json file.
10
+ */
11
+ export declare function resolveTsconfig(sourceFile: string, explicit?: string): string;
12
+ /**
13
+ * Resolve the package namespace (id) for a source file.
14
+ *
15
+ * Precedence: explicit `--namespace` → the folder name CONTAINING the tsconfig
16
+ * (the `--tsconfig` dir if given, else the nearest `tsconfig.json` walking up) →
17
+ * the source file's parent folder name (when no project tsconfig is found).
18
+ *
19
+ * @param sourceFile - Path to the TypeScript source file.
20
+ * @param opts.namespace - Optional explicit `--namespace` override.
21
+ * @param opts.tsconfig - Optional explicit `--tsconfig` value.
22
+ */
23
+ export declare function resolveNamespace(sourceFile: string, opts?: {
24
+ namespace?: string;
25
+ tsconfig?: string;
26
+ }): string;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Emit resolution scaffolding (`package.json`, `tsconfig.json`, `node_modules`
3
+ * symlink) into `outputDir` for the given `pluginId`, so the generated entrypoint
4
+ * runs from an arbitrary directory. Idempotent: never clobbers existing files.
5
+ *
6
+ * @param outputDir - The `--out-dir` the generated files were written to.
7
+ * @param pluginId - The plugin id (`mcp`, `cli`, …) — selects the dep set.
8
+ * @returns The names of the scaffolding files written (for logging).
9
+ */
10
+ export declare function emitResolutionScaffolding(outputDir: string, pluginId: string, opts?: {
11
+ linkWorkspace?: boolean;
12
+ }): string[];
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@adhd/apigen-cli",
3
+ "version": "0.1.0",
4
+ "bin": {
5
+ "apigen-cli": "./index.js"
6
+ },
7
+ "dependencies": {
8
+ "commander": "^14.0.3",
9
+ "ts-morph": "^23.0.0",
10
+ "ts-json-schema-generator": "^2.3.0",
11
+ "tsx": "^4.22.4",
12
+ "@modelcontextprotocol/sdk": "1.29.0",
13
+ "fastify": "^4.0.0",
14
+ "express": "^5.2.1",
15
+ "pino": "10.3.1",
16
+ "pino-pretty": "13.1.3",
17
+ "pino-http": "11.0.0",
18
+ "@adhd/apigen-core": "^0.1.0",
19
+ "@adhd/apigen-runtime": "^0.1.0",
20
+ "@adhd/apigen-plugin-mcp": "^0.1.0",
21
+ "@adhd/apigen-plugin-jsonschema": "^0.1.0",
22
+ "@adhd/apigen-plugin-api-fastify": "^0.1.0",
23
+ "@adhd/apigen-plugin-api-express": "^0.1.0",
24
+ "@adhd/apigen-plugin-cli-output": "^0.1.0"
25
+ },
26
+ "main": "./index.js",
27
+ "module": "./index.mjs",
28
+ "typings": "./index.d.ts",
29
+ "publishConfig": {
30
+ "access": "public"
31
+ }
32
+ }