kozou 0.1.1 → 0.2.1
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 +72 -1
- package/dist/cli.js +31 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/codegen.d.ts +8 -0
- package/dist/commands/codegen.d.ts.map +1 -0
- package/dist/commands/codegen.js +55 -0
- package/dist/commands/codegen.js.map +1 -0
- package/dist/commands/dev-runtime.d.ts +17 -1
- package/dist/commands/dev-runtime.d.ts.map +1 -1
- package/dist/commands/dev-runtime.js +76 -3
- package/dist/commands/dev-runtime.js.map +1 -1
- package/dist/commands/dev.d.ts +4 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +88 -6
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/docs.d.ts +8 -0
- package/dist/commands/docs.d.ts.map +1 -0
- package/dist/commands/docs.js +44 -0
- package/dist/commands/docs.js.map +1 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +94 -1
- package/dist/config.js.map +1 -1
- package/dist/docs.d.ts +3 -0
- package/dist/docs.d.ts.map +1 -0
- package/dist/docs.js +204 -0
- package/dist/docs.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -12
- package/dist/index.js.map +1 -1
- package/dist/templates/docker-compose.yml +1 -1
- package/dist/templates/env.example +9 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +15 -0
- package/dist/version.js.map +1 -0
- package/package.json +12 -8
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ npx -p kozou create-kozou my-project
|
|
|
21
21
|
|
|
22
22
|
The package publishes through `./dist/`. `bin` exposes two entries:
|
|
23
23
|
|
|
24
|
-
- `kozou` - the main multi-command CLI (`inspect` / `mcp` / `dev`)
|
|
24
|
+
- `kozou` - the main multi-command CLI (`inspect` / `docs` / `mcp` / `dev`)
|
|
25
25
|
- `create-kozou` - scaffolds a project directory with
|
|
26
26
|
`docker-compose.yml`, `kozou.config.yaml`, `ui-hints.yaml`,
|
|
27
27
|
`env.example`, and a starter migration
|
|
@@ -38,6 +38,16 @@ DATABASE_URL=postgres://kozou:kozou@localhost:5432/kozou \
|
|
|
38
38
|
kozou inspect --format yaml > schema.yaml
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
+
### `kozou docs`
|
|
42
|
+
|
|
43
|
+
Generates a single Markdown schema document from the database DDL +
|
|
44
|
+
`COMMENT` metadata to stdout (or `--output <path>`):
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
DATABASE_URL=postgres://kozou:kozou@localhost:5432/kozou \
|
|
48
|
+
kozou docs --output schema.md
|
|
49
|
+
```
|
|
50
|
+
|
|
41
51
|
### `kozou mcp --stdio`
|
|
42
52
|
|
|
43
53
|
Starts an MCP server over stdio so Claude Code / other AI agents
|
|
@@ -105,6 +115,67 @@ The full schema also accepts `server.ui.{port,host}`,
|
|
|
105
115
|
`create-kozou` writes. `${VAR}` and `${VAR:-default}` are
|
|
106
116
|
expanded from the process environment at load time.
|
|
107
117
|
|
|
118
|
+
### Authentication (experimental, `--adapter api`)
|
|
119
|
+
|
|
120
|
+
> **Experimental, optional companion.** The in-house `@kozou/api` backend is
|
|
121
|
+
> published to npm as an experimental preview (the API and wire format may
|
|
122
|
+
> change without notice). It is **not** bundled with the `kozou` CLI, so
|
|
123
|
+
> install it alongside `kozou` (`npm install kozou @kozou/api`) — or run from
|
|
124
|
+
> a source/workspace checkout. Without it, `kozou dev --adapter api` exits
|
|
125
|
+
> with an explicit error telling you to install it. The default `kozou dev`
|
|
126
|
+
> (PostgREST adapter) is unaffected.
|
|
127
|
+
|
|
128
|
+
By default the in-house `@kozou/api` backend (`kozou dev --adapter api`)
|
|
129
|
+
runs **unauthenticated** on loopback. Add an `auth` section to require a
|
|
130
|
+
signed JWT on every API request: kozou verifies the token, then runs each
|
|
131
|
+
request under `SET LOCAL ROLE <role-from-claim>` with the claims published
|
|
132
|
+
to PostgreSQL, so **your own row-level-security policies** decide what each
|
|
133
|
+
request can read and write.
|
|
134
|
+
|
|
135
|
+
```yaml
|
|
136
|
+
auth:
|
|
137
|
+
jwt:
|
|
138
|
+
secret: ${KOZOU_JWT_SECRET} # HS256 — or publicKey (RS256), or jwksUri
|
|
139
|
+
# publicKey: ${KOZOU_JWT_PUBLIC_KEY}
|
|
140
|
+
# jwksUri: https://your-idp/.well-known/jwks.json # Auth0 / Clerk / Supabase
|
|
141
|
+
algorithms: [HS256]
|
|
142
|
+
issuer: my-issuer # optional
|
|
143
|
+
audience: my-api # optional
|
|
144
|
+
roleClaim: role # claim naming the DB role (default: role)
|
|
145
|
+
allowedRoles: [app_reader, app_admin] # only these roles may be assumed
|
|
146
|
+
defaultRole: app_reader # role when the token omits roleClaim
|
|
147
|
+
anonRole: web_anon # role for requests with no token (else 401)
|
|
148
|
+
ui:
|
|
149
|
+
role: app_admin # role the bundled Admin UI runs as (HS256)
|
|
150
|
+
# token: ${KOZOU_ADAPTER_TOKEN} # RS256 / external IdP: supply a token instead
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Provide exactly one of `jwt.secret` (HS256), `jwt.publicKey` (RS256), or
|
|
154
|
+
`jwt.jwksUri` (a provider's remote JWKS endpoint — keys are selected by `kid`,
|
|
155
|
+
cached, and refreshed on rotation).
|
|
156
|
+
|
|
157
|
+
With no `auth:` block, the section is built instead from
|
|
158
|
+
`KOZOU_JWT_SECRET` / `KOZOU_JWT_PUBLIC_KEY` / `KOZOU_JWT_JWKS_URI` /
|
|
159
|
+
`KOZOU_JWT_ALGORITHMS` / `KOZOU_JWT_ISSUER` / `KOZOU_JWT_AUDIENCE` /
|
|
160
|
+
`KOZOU_JWT_ROLE_CLAIM` / `KOZOU_JWT_ALLOWED_ROLES` / `KOZOU_JWT_DEFAULT_ROLE` /
|
|
161
|
+
`KOZOU_JWT_ANON_ROLE` / `KOZOU_UI_ROLE` / `KOZOU_ADAPTER_TOKEN` (algorithms
|
|
162
|
+
and roles are comma-separated). A role outside `allowedRoles` gets `403`. A request with
|
|
163
|
+
no token gets `401` unless `anonRole` is set, in which case it runs under
|
|
164
|
+
that role and your RLS policies decide what it sees (a present but invalid
|
|
165
|
+
token is always `401`). The login role of `database.url` must be `GRANT`ed
|
|
166
|
+
membership in every allowed role, and in `anonRole` when set.
|
|
167
|
+
|
|
168
|
+
#### The bundled Admin UI
|
|
169
|
+
|
|
170
|
+
The Admin UI calls `@kozou/api` server-side, so when `auth` is on it must
|
|
171
|
+
send a token too. Under **HS256** the CLI mints one for the UI claiming
|
|
172
|
+
`auth.ui.role` (or, if unset, no role — the API then applies `defaultRole`);
|
|
173
|
+
set `auth.ui.role` to the role the console should run as. Under **RS256**
|
|
174
|
+
or an external identity provider the CLI cannot mint, so supply a
|
|
175
|
+
ready-made token via `auth.ui.token` (or the `KOZOU_ADAPTER_TOKEN` env);
|
|
176
|
+
without it the UI is rejected with `401` and the CLI logs how to fix it.
|
|
177
|
+
The minted role must satisfy `allowedRoles` or the UI gets `403`.
|
|
178
|
+
|
|
108
179
|
## License
|
|
109
180
|
|
|
110
181
|
Apache 2.0. See [LICENSE](../../LICENSE) at the repository root.
|
package/dist/cli.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
// Kozou v0.1 design spec §9.1 via commander.
|
|
4
4
|
import { Command } from 'commander';
|
|
5
5
|
import { inspectCommand } from './commands/inspect.js';
|
|
6
|
+
import { codegenCommand } from './commands/codegen.js';
|
|
7
|
+
import { docsCommand } from './commands/docs.js';
|
|
6
8
|
import { mcpCommand } from './commands/mcp.js';
|
|
7
9
|
import { devCommand } from './commands/dev.js';
|
|
8
10
|
import { PACKAGE_VERSION } from './index.js';
|
|
@@ -23,6 +25,28 @@ program
|
|
|
23
25
|
config: flags.config,
|
|
24
26
|
});
|
|
25
27
|
});
|
|
28
|
+
program
|
|
29
|
+
.command('codegen')
|
|
30
|
+
.description('Generate TypeScript row types from the database schema (experimental).')
|
|
31
|
+
.option('--output <path>', 'output file (- for stdout)', '-')
|
|
32
|
+
.option('--config <path>', 'path to kozou.config.yaml')
|
|
33
|
+
.action(async (flags) => {
|
|
34
|
+
await codegenCommand({
|
|
35
|
+
output: flags.output,
|
|
36
|
+
config: flags.config,
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
program
|
|
40
|
+
.command('docs')
|
|
41
|
+
.description('Generate a Markdown schema document from the database DDL + COMMENT.')
|
|
42
|
+
.option('--output <path>', 'output file (- for stdout)', '-')
|
|
43
|
+
.option('--config <path>', 'path to kozou.config.yaml')
|
|
44
|
+
.action(async (flags) => {
|
|
45
|
+
await docsCommand({
|
|
46
|
+
output: flags.output,
|
|
47
|
+
config: flags.config,
|
|
48
|
+
});
|
|
49
|
+
});
|
|
26
50
|
program
|
|
27
51
|
.command('mcp')
|
|
28
52
|
.description('Run the MCP server (--stdio default, or --http).')
|
|
@@ -44,8 +68,14 @@ program
|
|
|
44
68
|
.command('dev')
|
|
45
69
|
.description('Run the bundled Admin UI + MCP HTTP dev server.')
|
|
46
70
|
.option('--config <path>', 'path to kozou.config.yaml')
|
|
71
|
+
.option('--adapter <kind>', 'set to "api" for the experimental in-house @kozou/api backend (default: the bundled REST adapter)')
|
|
72
|
+
.option('--api-port <n>', 'port for the in-house @kozou/api server (with --adapter api)', (raw) => parseInt(raw, 10))
|
|
47
73
|
.action(async (flags) => {
|
|
48
|
-
await devCommand({
|
|
74
|
+
await devCommand({
|
|
75
|
+
config: flags.config,
|
|
76
|
+
adapter: flags.adapter,
|
|
77
|
+
apiPort: flags.apiPort,
|
|
78
|
+
});
|
|
49
79
|
});
|
|
50
80
|
program.parseAsync(process.argv).catch((err) => {
|
|
51
81
|
process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,gEAAgE;AAChE,6CAA6C;AAE7C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type CodegenOptions = {
|
|
2
|
+
/** Output destination. '-' = stdout (default), otherwise a file path. */
|
|
3
|
+
output?: string;
|
|
4
|
+
/** Path to kozou.config.yaml. Default: ./kozou.config.yaml. */
|
|
5
|
+
config?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function codegenCommand(opts?: CodegenOptions): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=codegen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/commands/codegen.ts"],"names":[],"mappings":"AAsBA,MAAM,MAAM,cAAc,GAAG;IAC3B,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAsB,cAAc,CAAC,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC7E"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// `kozou codegen` command implementation.
|
|
2
|
+
//
|
|
3
|
+
// Pipeline (mirrors `kozou inspect`):
|
|
4
|
+
// 1. Load the kozou.config.yaml (or fall back to defaults).
|
|
5
|
+
// 2. Introspect the target Postgres schema (@kozou/introspect).
|
|
6
|
+
// 3. Optionally load UI hints (@kozou/core.loadUIHints).
|
|
7
|
+
// 4. Build a SchemaContext (@kozou/core.buildSchemaContext).
|
|
8
|
+
// 5. Emit TypeScript row types (@kozou/codegen) and write them out.
|
|
9
|
+
//
|
|
10
|
+
// @kozou/codegen is an experimental, optional companion package — not bundled
|
|
11
|
+
// with the kozou CLI — so it is imported dynamically; when it is neither
|
|
12
|
+
// installed alongside kozou nor resolvable from a workspace checkout, the user
|
|
13
|
+
// gets a clear error (mirrors the `--adapter api` handling in dev.ts).
|
|
14
|
+
import { writeFile } from 'node:fs/promises';
|
|
15
|
+
import { buildSchemaContext, loadUIHints } from '@kozou/core';
|
|
16
|
+
import { introspect } from '@kozou/introspect';
|
|
17
|
+
import { loadConfig } from '../config.js';
|
|
18
|
+
const PREFIX = '[kozou codegen]';
|
|
19
|
+
export async function codegenCommand(opts = {}) {
|
|
20
|
+
const output = opts.output ?? '-';
|
|
21
|
+
let codegenModule;
|
|
22
|
+
try {
|
|
23
|
+
codegenModule = await import('@kozou/codegen');
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
throw new Error(`${PREFIX} needs the experimental @kozou/codegen package, which is not ` +
|
|
27
|
+
'bundled with the kozou CLI. Install it alongside kozou (npm install ' +
|
|
28
|
+
'@kozou/codegen), or run kozou from a source / workspace checkout.');
|
|
29
|
+
}
|
|
30
|
+
const config = await loadConfig({ path: opts.config });
|
|
31
|
+
const raw = await introspect({
|
|
32
|
+
connection: config.database.url,
|
|
33
|
+
schemas: config.database.schemas,
|
|
34
|
+
});
|
|
35
|
+
let uiHints;
|
|
36
|
+
if (config.uiHints.path !== null && config.uiHints.path !== '') {
|
|
37
|
+
try {
|
|
38
|
+
uiHints = await loadUIHints(config.uiHints.path);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
// UI hints are optional; warn but continue without them.
|
|
42
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
43
|
+
process.stderr.write(`${PREFIX} could not load UI hints: ${message}\n`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const ctx = await buildSchemaContext({ raw, uiHints });
|
|
47
|
+
const serialized = codegenModule.emitRowTypes(ctx);
|
|
48
|
+
const payload = serialized.endsWith('\n') ? serialized : serialized + '\n';
|
|
49
|
+
if (output === '-') {
|
|
50
|
+
process.stdout.write(payload);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
await writeFile(output, payload, 'utf8');
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=codegen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegen.js","sourceRoot":"","sources":["../../src/commands/codegen.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,EAAE;AACF,sCAAsC;AACtC,8DAA8D;AAC9D,kEAAkE;AAClE,2DAA2D;AAC3D,+DAA+D;AAC/D,sEAAsE;AACtE,EAAE;AACF,8EAA8E;AAC9E,yEAAyE;AACzE,+EAA+E;AAC/E,uEAAuE;AAEvE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE9D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,MAAM,GAAG,iBAAiB,CAAC;AASjC,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAuB,EAAE;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC;IAElC,IAAI,aAA8C,CAAC;IACnD,IAAI,CAAC;QACH,aAAa,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,+DAA+D;YACtE,sEAAsE;YACtE,mEAAmE,CACtE,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAEvD,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG;QAC/B,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO;KACjC,CAAC,CAAC;IAEH,IAAI,OAA4B,CAAC;IACjC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC;QAC/D,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,yDAAyD;YACzD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,6BAA6B,OAAO,IAAI,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,aAAa,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC;IAE3E,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,OAAO;IACT,CAAC;IACD,MAAM,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
import type { KozouConfig } from '../config.js';
|
|
2
2
|
export declare function resolveAdminUiEntry(): string;
|
|
3
3
|
export declare function resolveOrigin(config: KozouConfig, env: NodeJS.ProcessEnv): string;
|
|
4
|
-
export declare function buildAdminUiEnv(config: KozouConfig, origin: string, baseEnv: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
4
|
+
export declare function buildAdminUiEnv(config: KozouConfig, origin: string, baseEnv: NodeJS.ProcessEnv, apiAdapterUrl?: string, apiToken?: string): NodeJS.ProcessEnv;
|
|
5
|
+
export type ServiceTokenMinter = {
|
|
6
|
+
signServiceToken(opts: {
|
|
7
|
+
secret: string;
|
|
8
|
+
roleClaim?: string;
|
|
9
|
+
role?: string;
|
|
10
|
+
issuer?: string;
|
|
11
|
+
audience?: string | string[];
|
|
12
|
+
}): Promise<string>;
|
|
13
|
+
};
|
|
14
|
+
export type AdminUiTokenResult = {
|
|
15
|
+
/** Bearer token the Admin UI should send, when one could be obtained. */
|
|
16
|
+
token?: string;
|
|
17
|
+
/** Operator-facing reason the UI will be rejected, when no usable token. */
|
|
18
|
+
warning?: string;
|
|
19
|
+
};
|
|
20
|
+
export declare function resolveAdminUiToken(config: KozouConfig, minter: ServiceTokenMinter, env: NodeJS.ProcessEnv): Promise<AdminUiTokenResult>;
|
|
5
21
|
//# sourceMappingURL=dev-runtime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-runtime.d.ts","sourceRoot":"","sources":["../../src/commands/dev-runtime.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAOhD,wBAAgB,mBAAmB,IAAI,MAAM,CAI5C;AAMD,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAEjF;
|
|
1
|
+
{"version":3,"file":"dev-runtime.d.ts","sourceRoot":"","sources":["../../src/commands/dev-runtime.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAOhD,wBAAgB,mBAAmB,IAAI,MAAM,CAI5C;AAMD,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAEjF;AAWD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,CAAC,UAAU,EAC1B,aAAa,CAAC,EAAE,MAAM,EACtB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAAC,UAAU,CAsBnB;AAID,MAAM,MAAM,kBAAkB,GAAG;IAC/B,gBAAgB,CAAC,IAAI,EAAE;QACrB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;KAC9B,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAWF,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,kBAAkB,EAC1B,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,OAAO,CAAC,kBAAkB,CAAC,CA8B7B"}
|
|
@@ -24,15 +24,88 @@ export function resolveOrigin(config, env) {
|
|
|
24
24
|
}
|
|
25
25
|
// Build the child-process environment for the Admin UI server. Keeping
|
|
26
26
|
// it pure makes the wiring unit-testable without spawning anything.
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
//
|
|
28
|
+
// When `apiAdapterUrl` is given (`kozou dev --adapter api`), the UI is
|
|
29
|
+
// pointed at the in-house @kozou/api server via KOZOU_ADAPTER_KIND=api;
|
|
30
|
+
// otherwise it uses the default REST adapter URL from config. On the api
|
|
31
|
+
// path `apiToken` (when present) is exposed as KOZOU_ADAPTER_TOKEN so the
|
|
32
|
+
// UI attaches it as a Bearer token; any inherited value is cleared so a
|
|
33
|
+
// stray env var cannot leak in.
|
|
34
|
+
export function buildAdminUiEnv(config, origin, baseEnv, apiAdapterUrl, apiToken) {
|
|
35
|
+
const adapter = apiAdapterUrl !== undefined
|
|
36
|
+
? { KOZOU_ADAPTER_KIND: 'api', KOZOU_ADAPTER_URL: apiAdapterUrl }
|
|
37
|
+
: { KOZOU_ADAPTER_URL: config.adapter.url };
|
|
38
|
+
const env = {
|
|
29
39
|
...baseEnv,
|
|
30
40
|
DATABASE_URL: config.database.url,
|
|
31
|
-
|
|
41
|
+
...adapter,
|
|
32
42
|
PORT: String(config.server.ui.port),
|
|
33
43
|
HOST: config.server.ui.host,
|
|
34
44
|
ORIGIN: origin,
|
|
35
45
|
NODE_ENV: 'production',
|
|
36
46
|
};
|
|
47
|
+
if (apiAdapterUrl !== undefined) {
|
|
48
|
+
if (apiToken !== undefined && apiToken.length > 0) {
|
|
49
|
+
env.KOZOU_ADAPTER_TOKEN = apiToken;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
delete env.KOZOU_ADAPTER_TOKEN;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return env;
|
|
56
|
+
}
|
|
57
|
+
// Decide what token (if any) the bundled Admin UI should send to @kozou/api,
|
|
58
|
+
// given the resolved config. Pure except for the injected minter:
|
|
59
|
+
// (a) an explicit token (auth.ui.token / KOZOU_ADAPTER_TOKEN) is passed
|
|
60
|
+
// through — the path for RS256 / an external IdP, where the CLI cannot
|
|
61
|
+
// mint;
|
|
62
|
+
// (b) otherwise, with an HS256 secret, the CLI mints a token claiming the
|
|
63
|
+
// configured role (auth.ui.role; absent -> the API's defaultRole);
|
|
64
|
+
// (c) otherwise (an RS256 key with no supplied token) no token is returned
|
|
65
|
+
// and a warning explains how to supply one.
|
|
66
|
+
export async function resolveAdminUiToken(config, minter, env) {
|
|
67
|
+
const auth = config.auth;
|
|
68
|
+
if (auth === undefined)
|
|
69
|
+
return {}; // no auth -> the UI sends no token (unchanged)
|
|
70
|
+
const supplied = auth.ui?.token ?? env.KOZOU_ADAPTER_TOKEN;
|
|
71
|
+
if (supplied !== undefined && supplied.length > 0) {
|
|
72
|
+
return { token: supplied };
|
|
73
|
+
}
|
|
74
|
+
const secret = auth.jwt.secret;
|
|
75
|
+
if (secret !== undefined && secret.length > 0) {
|
|
76
|
+
const role = auth.ui?.role;
|
|
77
|
+
const token = await minter.signServiceToken({
|
|
78
|
+
secret,
|
|
79
|
+
roleClaim: auth.roleClaim,
|
|
80
|
+
role,
|
|
81
|
+
issuer: auth.jwt.issuer,
|
|
82
|
+
audience: auth.jwt.audience,
|
|
83
|
+
});
|
|
84
|
+
const warning = mintedRoleWarning(auth, role);
|
|
85
|
+
return warning !== undefined ? { token, warning } : { token };
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
warning: 'auth uses an RS256 public key, so the CLI cannot mint a token for the ' +
|
|
89
|
+
'bundled Admin UI; it will be rejected with 401. Set auth.ui.token (or ' +
|
|
90
|
+
'KOZOU_ADAPTER_TOKEN) to a token from your identity provider, or use an ' +
|
|
91
|
+
'HS256 secret so the CLI can mint one.',
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
// A minted Admin UI token will be rejected with 403 unless the API can
|
|
95
|
+
// resolve an allowed role for it. Surface that as a warning at startup
|
|
96
|
+
// rather than letting the UI fail opaquely.
|
|
97
|
+
function mintedRoleWarning(auth, role) {
|
|
98
|
+
const effective = role !== undefined && role.length > 0 ? role : auth.defaultRole;
|
|
99
|
+
if (effective === undefined || effective.length === 0) {
|
|
100
|
+
return 'auth.ui.role is unset and no defaultRole is configured, so the ' +
|
|
101
|
+
'minted Admin UI token carries no role and the API will reject it with ' +
|
|
102
|
+
'403. Set auth.ui.role to the role the Admin UI should assume.';
|
|
103
|
+
}
|
|
104
|
+
if (auth.allowedRoles !== undefined && !auth.allowedRoles.includes(effective)) {
|
|
105
|
+
return `the Admin UI token's role "${effective}" is not in allowedRoles, so ` +
|
|
106
|
+
'the API will reject it with 403. Add it to allowedRoles or change ' +
|
|
107
|
+
'auth.ui.role.';
|
|
108
|
+
}
|
|
109
|
+
return undefined;
|
|
37
110
|
}
|
|
38
111
|
//# sourceMappingURL=dev-runtime.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-runtime.js","sourceRoot":"","sources":["../../src/commands/dev-runtime.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,EAAE;AACF,kEAAkE;AAClE,wEAAwE;AACxE,wCAAwC;AAExC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAI1C,mEAAmE;AACnE,wEAAwE;AACxE,yEAAyE;AACzE,yEAAyE;AACzE,eAAe;AACf,MAAM,UAAU,mBAAmB;IACjC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC;IACrE,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;AACzD,CAAC;AAED,sEAAsE;AACtE,yEAAyE;AACzE,wEAAwE;AACxE,gDAAgD;AAChD,MAAM,UAAU,aAAa,CAAC,MAAmB,EAAE,GAAsB;IACvE,OAAO,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,YAAY,IAAI,oBAAoB,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;AACvF,CAAC;AAED,uEAAuE;AACvE,oEAAoE;AACpE,MAAM,UAAU,eAAe,CAC7B,MAAmB,EACnB,MAAc,EACd,OAA0B;
|
|
1
|
+
{"version":3,"file":"dev-runtime.js","sourceRoot":"","sources":["../../src/commands/dev-runtime.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/dev.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export type DevOptions = {
|
|
2
2
|
config?: string;
|
|
3
|
+
/** Set to 'api' for the experimental in-house @kozou/api backend; omit for the default REST adapter. */
|
|
4
|
+
adapter?: string;
|
|
5
|
+
/** Port for the in-house @kozou/api server (used when adapter === 'api'). */
|
|
6
|
+
apiPort?: number;
|
|
3
7
|
};
|
|
4
8
|
export declare function devCommand(opts?: DevOptions): Promise<void>;
|
|
5
9
|
//# sourceMappingURL=dev.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAgCA,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wGAAwG;IACxG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AA6EF,wBAAsB,UAAU,CAAC,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA+GrE"}
|
package/dist/commands/dev.js
CHANGED
|
@@ -19,8 +19,64 @@ import { spawn } from 'node:child_process';
|
|
|
19
19
|
import { existsSync } from 'node:fs';
|
|
20
20
|
import { SchemaCache, startHttpServer, isLoopbackHost } from '@kozou/mcp';
|
|
21
21
|
import { loadConfig } from '../config.js';
|
|
22
|
-
import {
|
|
22
|
+
import { PACKAGE_VERSION } from '../version.js';
|
|
23
|
+
import { buildAdminUiEnv, resolveAdminUiEntry, resolveAdminUiToken, resolveOrigin, } from './dev-runtime.js';
|
|
23
24
|
const PREFIX = '[kozou dev]';
|
|
25
|
+
// The in-house @kozou/api server is reached only by the Admin UI's
|
|
26
|
+
// server-side fetch (same host), so bind it to loopback — no need to
|
|
27
|
+
// expose it to the browser or the network.
|
|
28
|
+
const API_HOST = '127.0.0.1';
|
|
29
|
+
const DEFAULT_API_PORT = 3335;
|
|
30
|
+
// Start the in-house @kozou/api server in-process: introspect the
|
|
31
|
+
// configured database, build its SchemaContext, and serve it over a pg
|
|
32
|
+
// pool. @kozou/api is an experimental, optional companion package — not
|
|
33
|
+
// bundled with the kozou CLI — so it is imported dynamically; when it is
|
|
34
|
+
// neither installed alongside kozou nor resolvable from a workspace
|
|
35
|
+
// checkout, the user gets a clear error.
|
|
36
|
+
async function startInhouseApi(config, port) {
|
|
37
|
+
let apiModule;
|
|
38
|
+
try {
|
|
39
|
+
apiModule = await import('@kozou/api');
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
throw new Error(`${PREFIX} --adapter api needs the experimental @kozou/api package, which is ` +
|
|
43
|
+
'not bundled with the kozou CLI. Install it alongside kozou (npm install ' +
|
|
44
|
+
'@kozou/api), run kozou from a source / workspace checkout, or drop ' +
|
|
45
|
+
'--adapter api to use the default REST adapter.');
|
|
46
|
+
}
|
|
47
|
+
const { introspect } = await import('@kozou/introspect');
|
|
48
|
+
const { buildSchemaContext } = await import('@kozou/core');
|
|
49
|
+
const { default: pg } = await import('pg');
|
|
50
|
+
const raw = await introspect({
|
|
51
|
+
connection: config.database.url,
|
|
52
|
+
schemas: config.database.schemas,
|
|
53
|
+
});
|
|
54
|
+
const schema = await buildSchemaContext({ raw });
|
|
55
|
+
const pool = new pg.Pool({ connectionString: config.database.url });
|
|
56
|
+
const server = await apiModule.startApiServer({
|
|
57
|
+
schema,
|
|
58
|
+
db: { query: (text, values) => pool.query(text, values) },
|
|
59
|
+
// When `auth` is configured the API verifies a JWT and runs each request
|
|
60
|
+
// under SET LOCAL ROLE, which needs a dedicated client per request — pass
|
|
61
|
+
// the pool. With no `auth`, the pool is unused and the API stays
|
|
62
|
+
// unauthenticated (loopback-only), exactly as before.
|
|
63
|
+
pool,
|
|
64
|
+
auth: config.auth,
|
|
65
|
+
host: API_HOST,
|
|
66
|
+
port,
|
|
67
|
+
// Advertise the kozou CLI version in the API's `GET /` and OpenAPI
|
|
68
|
+
// `info.version`; without this it falls back to the package default.
|
|
69
|
+
version: PACKAGE_VERSION,
|
|
70
|
+
logPrefix: `${PREFIX} api`,
|
|
71
|
+
});
|
|
72
|
+
return {
|
|
73
|
+
url: `http://${API_HOST}:${server.port}`,
|
|
74
|
+
close: async () => {
|
|
75
|
+
await server.close();
|
|
76
|
+
await pool.end();
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
24
80
|
function warnIfPublic(label, host) {
|
|
25
81
|
if (isLoopbackHost(host))
|
|
26
82
|
return;
|
|
@@ -30,6 +86,10 @@ function warnIfPublic(label, host) {
|
|
|
30
86
|
`${PREFIX} avoid it on an untrusted network or put an auth proxy in front.\n`);
|
|
31
87
|
}
|
|
32
88
|
export async function devCommand(opts = {}) {
|
|
89
|
+
if (opts.adapter !== undefined && opts.adapter !== 'api') {
|
|
90
|
+
throw new Error(`${PREFIX} unknown --adapter "${opts.adapter}" ` +
|
|
91
|
+
'(the only supported value is "api"; omit it for the default REST adapter).');
|
|
92
|
+
}
|
|
33
93
|
const config = await loadConfig({ path: opts.config });
|
|
34
94
|
const adminUiEntry = resolveAdminUiEntry();
|
|
35
95
|
if (!existsSync(adminUiEntry)) {
|
|
@@ -37,6 +97,27 @@ export async function devCommand(opts = {}) {
|
|
|
37
97
|
'Reinstall @kozou/svelte-ui (its `build/` output ships in the package), ' +
|
|
38
98
|
'or in a workspace checkout run `pnpm --filter @kozou/svelte-ui run build`.');
|
|
39
99
|
}
|
|
100
|
+
// Optional in-house @kozou/api backend (--adapter api), started before
|
|
101
|
+
// the other servers so its URL can be wired into the UI environment.
|
|
102
|
+
const api = opts.adapter === 'api'
|
|
103
|
+
? await startInhouseApi(config, opts.apiPort ?? DEFAULT_API_PORT)
|
|
104
|
+
: null;
|
|
105
|
+
if (api) {
|
|
106
|
+
process.stderr.write(`${PREFIX} in-house @kozou/api on ${api.url}\n`);
|
|
107
|
+
}
|
|
108
|
+
// When the in-house API enforces auth, resolve the token the bundled Admin
|
|
109
|
+
// UI presents to it: a minted HS256 token, a supplied RS256 / external one,
|
|
110
|
+
// or none (with a warning) when neither is available. @kozou/api is already
|
|
111
|
+
// imported (startInhouseApi succeeded), so this dynamic import is cached.
|
|
112
|
+
let apiToken;
|
|
113
|
+
if (api && config.auth) {
|
|
114
|
+
const apiModule = await import('@kozou/api');
|
|
115
|
+
const resolved = await resolveAdminUiToken(config, apiModule, process.env);
|
|
116
|
+
if (resolved.warning) {
|
|
117
|
+
process.stderr.write(`${PREFIX} WARNING: ${resolved.warning}\n`);
|
|
118
|
+
}
|
|
119
|
+
apiToken = resolved.token;
|
|
120
|
+
}
|
|
40
121
|
const cache = new SchemaCache({
|
|
41
122
|
connection: config.database.url,
|
|
42
123
|
schemas: config.database.schemas,
|
|
@@ -53,15 +134,16 @@ export async function devCommand(opts = {}) {
|
|
|
53
134
|
warnIfPublic('Admin UI', config.server.ui.host);
|
|
54
135
|
const origin = resolveOrigin(config, process.env);
|
|
55
136
|
const child = spawn('node', [adminUiEntry], {
|
|
56
|
-
env: buildAdminUiEnv(config, origin, process.env),
|
|
137
|
+
env: buildAdminUiEnv(config, origin, process.env, api?.url, apiToken),
|
|
57
138
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
58
139
|
});
|
|
59
140
|
child.stdout?.on('data', (b) => process.stdout.write(`${PREFIX} ui | ${b}`));
|
|
60
141
|
child.stderr?.on('data', (b) => process.stderr.write(`${PREFIX} ui | ${b}`));
|
|
61
142
|
process.stderr.write(`${PREFIX} Admin UI on http://${config.server.ui.host}:${config.server.ui.port}` +
|
|
62
143
|
` (origin ${origin})\n`);
|
|
63
|
-
// 3. Lifecycle: tear
|
|
64
|
-
// let the CLI exit) only once everything has stopped.
|
|
144
|
+
// 3. Lifecycle: tear everything down together. Resolve the promise (and
|
|
145
|
+
// thus let the CLI exit) only once everything has stopped.
|
|
146
|
+
const closeBackends = () => Promise.allSettled([mcp.close(), api ? api.close() : Promise.resolve()]);
|
|
65
147
|
await new Promise((resolve) => {
|
|
66
148
|
let shuttingDown = false;
|
|
67
149
|
const shutdown = (reason) => {
|
|
@@ -72,7 +154,7 @@ export async function devCommand(opts = {}) {
|
|
|
72
154
|
if (child.exitCode === null && child.signalCode === null) {
|
|
73
155
|
child.kill('SIGTERM');
|
|
74
156
|
}
|
|
75
|
-
void
|
|
157
|
+
void closeBackends().finally(() => resolve());
|
|
76
158
|
};
|
|
77
159
|
process.on('SIGINT', () => shutdown('SIGINT received'));
|
|
78
160
|
process.on('SIGTERM', () => shutdown('SIGTERM received'));
|
|
@@ -84,7 +166,7 @@ export async function devCommand(opts = {}) {
|
|
|
84
166
|
process.stderr.write(`${PREFIX} Admin UI exited (code=${code ?? 'null'}, signal=${signal ?? 'null'})\n`);
|
|
85
167
|
process.exitCode = code ?? 1;
|
|
86
168
|
shuttingDown = true;
|
|
87
|
-
void
|
|
169
|
+
void closeBackends().finally(() => resolve());
|
|
88
170
|
});
|
|
89
171
|
child.on('error', (err) => {
|
|
90
172
|
process.stderr.write(`${PREFIX} failed to spawn Admin UI: ${err.message}\n`);
|
package/dist/commands/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,sEAAsE;AACtE,wEAAwE;AACxE,uEAAuE;AACvE,iEAAiE;AACjE,sEAAsE;AACtE,mCAAmC;AACnC,EAAE;AACF,uEAAuE;AACvE,sEAAsE;AACtE,8CAA8C;AAC9C,EAAE;AACF,wEAAwE;AACxE,wEAAwE;AACxE,oEAAoE;AACpE,oEAAoE;AAEpE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE1E,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type DocsOptions = {
|
|
2
|
+
/** Output destination. '-' = stdout (default), otherwise a file path. */
|
|
3
|
+
output?: string;
|
|
4
|
+
/** Path to kozou.config.yaml. Default: ./kozou.config.yaml. */
|
|
5
|
+
config?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function docsCommand(opts?: DocsOptions): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=docs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/commands/docs.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,WAAW,GAAG;IACxB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAsB,WAAW,CAAC,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BvE"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// `kozou docs` command implementation.
|
|
2
|
+
//
|
|
3
|
+
// Pipeline (mirrors `kozou inspect`):
|
|
4
|
+
// 1. Load the kozou.config.yaml (or fall back to defaults).
|
|
5
|
+
// 2. Introspect the target Postgres schema (@kozou/introspect).
|
|
6
|
+
// 3. Optionally load UI hints (@kozou/core.loadUIHints).
|
|
7
|
+
// 4. Build a SchemaContext (@kozou/core.buildSchemaContext).
|
|
8
|
+
// 5. Render a Markdown schema document and write it out.
|
|
9
|
+
//
|
|
10
|
+
// See product_architecture_v3 §3.4 (the "docs" emit target).
|
|
11
|
+
import { writeFile } from 'node:fs/promises';
|
|
12
|
+
import { buildSchemaContext, loadUIHints } from '@kozou/core';
|
|
13
|
+
import { introspect } from '@kozou/introspect';
|
|
14
|
+
import { loadConfig } from '../config.js';
|
|
15
|
+
import { emitMarkdown } from '../docs.js';
|
|
16
|
+
const PREFIX = '[kozou docs]';
|
|
17
|
+
export async function docsCommand(opts = {}) {
|
|
18
|
+
const output = opts.output ?? '-';
|
|
19
|
+
const config = await loadConfig({ path: opts.config });
|
|
20
|
+
const raw = await introspect({
|
|
21
|
+
connection: config.database.url,
|
|
22
|
+
schemas: config.database.schemas,
|
|
23
|
+
});
|
|
24
|
+
let uiHints;
|
|
25
|
+
if (config.uiHints.path !== null && config.uiHints.path !== '') {
|
|
26
|
+
try {
|
|
27
|
+
uiHints = await loadUIHints(config.uiHints.path);
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
// UI hints are optional; warn but continue without them.
|
|
31
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
32
|
+
process.stderr.write(`${PREFIX} could not load UI hints: ${message}\n`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const ctx = await buildSchemaContext({ raw, uiHints });
|
|
36
|
+
const serialized = emitMarkdown(ctx);
|
|
37
|
+
const payload = serialized.endsWith('\n') ? serialized : serialized + '\n';
|
|
38
|
+
if (output === '-') {
|
|
39
|
+
process.stdout.write(payload);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
await writeFile(output, payload, 'utf8');
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=docs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../../src/commands/docs.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,EAAE;AACF,sCAAsC;AACtC,8DAA8D;AAC9D,kEAAkE;AAClE,2DAA2D;AAC3D,+DAA+D;AAC/D,2DAA2D;AAC3D,EAAE;AACF,6DAA6D;AAE7D,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE9D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,MAAM,GAAG,cAAc,CAAC;AAS9B,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAoB,EAAE;IACtD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC;IAElC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAEvD,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG;QAC/B,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO;KACjC,CAAC,CAAC;IAEH,IAAI,OAA4B,CAAC;IACjC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC;QAC/D,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,yDAAyD;YACzD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,6BAA6B,OAAO,IAAI,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC;IAE3E,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,OAAO;IACT,CAAC;IACD,MAAM,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC"}
|
package/dist/config.d.ts
CHANGED
|
@@ -27,6 +27,28 @@ declare const configSchema: z.ZodObject<{
|
|
|
27
27
|
cache: z.ZodPrefault<z.ZodObject<{
|
|
28
28
|
ttlMs: z.ZodDefault<z.ZodNumber>;
|
|
29
29
|
}, z.core.$strip>>;
|
|
30
|
+
auth: z.ZodOptional<z.ZodObject<{
|
|
31
|
+
jwt: z.ZodObject<{
|
|
32
|
+
secret: z.ZodOptional<z.ZodString>;
|
|
33
|
+
publicKey: z.ZodOptional<z.ZodString>;
|
|
34
|
+
jwksUri: z.ZodOptional<z.ZodString>;
|
|
35
|
+
algorithms: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
36
|
+
HS256: "HS256";
|
|
37
|
+
RS256: "RS256";
|
|
38
|
+
}>>>;
|
|
39
|
+
issuer: z.ZodOptional<z.ZodString>;
|
|
40
|
+
audience: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
41
|
+
}, z.core.$strip>;
|
|
42
|
+
roleClaim: z.ZodOptional<z.ZodString>;
|
|
43
|
+
allowedRoles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
44
|
+
defaultRole: z.ZodOptional<z.ZodString>;
|
|
45
|
+
anonRole: z.ZodOptional<z.ZodString>;
|
|
46
|
+
claimsGuc: z.ZodOptional<z.ZodString>;
|
|
47
|
+
ui: z.ZodOptional<z.ZodObject<{
|
|
48
|
+
role: z.ZodOptional<z.ZodString>;
|
|
49
|
+
token: z.ZodOptional<z.ZodString>;
|
|
50
|
+
}, z.core.$strip>>;
|
|
51
|
+
}, z.core.$strip>>;
|
|
30
52
|
}, z.core.$strip>;
|
|
31
53
|
export type KozouConfig = z.infer<typeof configSchema>;
|
|
32
54
|
export type KozouConfigIssue = {
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA+
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA+FxB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAOhB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAIvD,MAAM,MAAM,gBAAgB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjE,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;gBACrB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,gBAAgB,EAAE;CAMjF;AAMD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,+EAA+E;IAC/E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AA4GF,wBAAsB,UAAU,CAAC,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,WAAW,CAAC,CA6CnF"}
|
package/dist/config.js
CHANGED
|
@@ -66,12 +66,42 @@ const databaseSchema = z.object({
|
|
|
66
66
|
url: z.string().min(1, 'database.url is required (set DATABASE_URL or kozou.config.yaml)'),
|
|
67
67
|
schemas: z.array(z.string().min(1)).default(['public']),
|
|
68
68
|
});
|
|
69
|
+
// Opt-in JWT auth for the in-house @kozou/api backend (`kozou dev --adapter
|
|
70
|
+
// api`). Absent -> the API stays unauthenticated and loopback-only. The
|
|
71
|
+
// "exactly one of secret / publicKey" rule is enforced by @kozou/api at
|
|
72
|
+
// server start, so it is intentionally not duplicated here.
|
|
73
|
+
const jwtAuthSchema = z.object({
|
|
74
|
+
secret: z.string().min(1).optional(),
|
|
75
|
+
publicKey: z.string().min(1).optional(),
|
|
76
|
+
jwksUri: z.string().min(1).optional(),
|
|
77
|
+
algorithms: z.array(z.enum(['HS256', 'RS256'])).optional(),
|
|
78
|
+
issuer: z.string().min(1).optional(),
|
|
79
|
+
audience: z.union([z.string().min(1), z.array(z.string().min(1))]).optional(),
|
|
80
|
+
});
|
|
81
|
+
// How the bundled Admin UI authenticates to @kozou/api when auth is on. This
|
|
82
|
+
// is a CLI-only concern (not part of @kozou/api's AuthConfig): under HS256 the
|
|
83
|
+
// CLI mints a token claiming `role`; for RS256 / an external IdP it cannot
|
|
84
|
+
// mint, so `token` carries a ready-made one through to the UI instead.
|
|
85
|
+
const authUiSchema = z.object({
|
|
86
|
+
role: z.string().min(1).optional(),
|
|
87
|
+
token: z.string().min(1).optional(),
|
|
88
|
+
});
|
|
89
|
+
const authSchema = z.object({
|
|
90
|
+
jwt: jwtAuthSchema,
|
|
91
|
+
roleClaim: z.string().min(1).optional(),
|
|
92
|
+
allowedRoles: z.array(z.string().min(1)).optional(),
|
|
93
|
+
defaultRole: z.string().min(1).optional(),
|
|
94
|
+
anonRole: z.string().min(1).optional(),
|
|
95
|
+
claimsGuc: z.string().min(1).optional(),
|
|
96
|
+
ui: authUiSchema.optional(),
|
|
97
|
+
});
|
|
69
98
|
const configSchema = z.object({
|
|
70
99
|
database: databaseSchema,
|
|
71
100
|
server: serverSchema,
|
|
72
101
|
adapter: adapterSchema,
|
|
73
102
|
uiHints: uiHintsSchema,
|
|
74
103
|
cache: cacheSchema,
|
|
104
|
+
auth: authSchema.optional(),
|
|
75
105
|
});
|
|
76
106
|
export class KozouConfigError extends Error {
|
|
77
107
|
issues;
|
|
@@ -140,6 +170,67 @@ function injectDatabaseUrlFromEnv(raw, env) {
|
|
|
140
170
|
}
|
|
141
171
|
return obj;
|
|
142
172
|
}
|
|
173
|
+
function splitList(value) {
|
|
174
|
+
if (value === undefined)
|
|
175
|
+
return undefined;
|
|
176
|
+
const items = value
|
|
177
|
+
.split(',')
|
|
178
|
+
.map((s) => s.trim())
|
|
179
|
+
.filter((s) => s.length > 0);
|
|
180
|
+
return items.length > 0 ? items : undefined;
|
|
181
|
+
}
|
|
182
|
+
// Build the optional `auth` section from KOZOU_JWT_* env vars when the config
|
|
183
|
+
// file did not declare one. Runs AFTER ${VAR} expansion so an env-provided
|
|
184
|
+
// secret / key is taken verbatim and is never re-scanned for placeholders.
|
|
185
|
+
function injectAuthFromEnv(raw, env) {
|
|
186
|
+
if (raw === null || typeof raw !== 'object')
|
|
187
|
+
return raw;
|
|
188
|
+
const obj = raw;
|
|
189
|
+
if (obj.auth !== undefined)
|
|
190
|
+
return obj; // an explicit config section wins
|
|
191
|
+
const secret = env.KOZOU_JWT_SECRET;
|
|
192
|
+
const publicKey = env.KOZOU_JWT_PUBLIC_KEY;
|
|
193
|
+
const jwksUri = env.KOZOU_JWT_JWKS_URI;
|
|
194
|
+
if (!secret && !publicKey && !jwksUri)
|
|
195
|
+
return obj; // no auth env -> stay unauthenticated
|
|
196
|
+
const jwt = {};
|
|
197
|
+
if (secret)
|
|
198
|
+
jwt.secret = secret;
|
|
199
|
+
if (publicKey)
|
|
200
|
+
jwt.publicKey = publicKey;
|
|
201
|
+
if (jwksUri)
|
|
202
|
+
jwt.jwksUri = jwksUri;
|
|
203
|
+
const algorithms = splitList(env.KOZOU_JWT_ALGORITHMS);
|
|
204
|
+
if (algorithms)
|
|
205
|
+
jwt.algorithms = algorithms;
|
|
206
|
+
if (env.KOZOU_JWT_ISSUER)
|
|
207
|
+
jwt.issuer = env.KOZOU_JWT_ISSUER;
|
|
208
|
+
if (env.KOZOU_JWT_AUDIENCE)
|
|
209
|
+
jwt.audience = env.KOZOU_JWT_AUDIENCE;
|
|
210
|
+
const auth = { jwt };
|
|
211
|
+
if (env.KOZOU_JWT_ROLE_CLAIM)
|
|
212
|
+
auth.roleClaim = env.KOZOU_JWT_ROLE_CLAIM;
|
|
213
|
+
const allowedRoles = splitList(env.KOZOU_JWT_ALLOWED_ROLES);
|
|
214
|
+
if (allowedRoles)
|
|
215
|
+
auth.allowedRoles = allowedRoles;
|
|
216
|
+
if (env.KOZOU_JWT_DEFAULT_ROLE)
|
|
217
|
+
auth.defaultRole = env.KOZOU_JWT_DEFAULT_ROLE;
|
|
218
|
+
if (env.KOZOU_JWT_ANON_ROLE)
|
|
219
|
+
auth.anonRole = env.KOZOU_JWT_ANON_ROLE;
|
|
220
|
+
if (env.KOZOU_JWT_CLAIMS_GUC)
|
|
221
|
+
auth.claimsGuc = env.KOZOU_JWT_CLAIMS_GUC;
|
|
222
|
+
// How the bundled Admin UI authenticates: KOZOU_UI_ROLE names the role the
|
|
223
|
+
// CLI mints an HS256 token for; KOZOU_ADAPTER_TOKEN supplies a ready-made
|
|
224
|
+
// token (RS256 / external IdP, where the CLI cannot mint).
|
|
225
|
+
const ui = {};
|
|
226
|
+
if (env.KOZOU_UI_ROLE)
|
|
227
|
+
ui.role = env.KOZOU_UI_ROLE;
|
|
228
|
+
if (env.KOZOU_ADAPTER_TOKEN)
|
|
229
|
+
ui.token = env.KOZOU_ADAPTER_TOKEN;
|
|
230
|
+
if (Object.keys(ui).length > 0)
|
|
231
|
+
auth.ui = ui;
|
|
232
|
+
return { ...obj, auth };
|
|
233
|
+
}
|
|
143
234
|
export async function loadConfig(opts = {}) {
|
|
144
235
|
const env = opts.env ?? process.env;
|
|
145
236
|
const requestedPath = opts.path ?? DEFAULT_CONFIG_PATH;
|
|
@@ -162,8 +253,10 @@ export async function loadConfig(opts = {}) {
|
|
|
162
253
|
// Fall back to DATABASE_URL env if database.url is not set in the file.
|
|
163
254
|
const withDbDefault = injectDatabaseUrlFromEnv(raw, env);
|
|
164
255
|
const expanded = expandEnvVars(withDbDefault, env);
|
|
256
|
+
// Build `auth` from KOZOU_JWT_* env after expansion (env secrets verbatim).
|
|
257
|
+
const withAuth = injectAuthFromEnv(expanded, env);
|
|
165
258
|
try {
|
|
166
|
-
return configSchema.parse(
|
|
259
|
+
return configSchema.parse(withAuth);
|
|
167
260
|
}
|
|
168
261
|
catch (err) {
|
|
169
262
|
if (err instanceof z.ZodError) {
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/docs.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,aAAa,EAMd,MAAM,aAAa,CAAC;AAIrB,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CA+B1D"}
|
package/dist/docs.js
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// Render a human-readable Markdown document from a SchemaContext.
|
|
2
|
+
//
|
|
3
|
+
// This is the "docs" emit target (product_architecture_v3 §3.4): alongside the
|
|
4
|
+
// Admin UI, MCP context, REST API, and TypeScript types, Kozou turns the same
|
|
5
|
+
// DDL + COMMENT into a schema document a person can read, commit, and publish.
|
|
6
|
+
//
|
|
7
|
+
// Pure function — no I/O — so the `kozou docs` CLI (and tests) drive it
|
|
8
|
+
// directly. Content mirrors what the MCP `describe_table` / `describe_view` /
|
|
9
|
+
// `get_concept_context` tools surface, formatted for human reading.
|
|
10
|
+
const BANNER = '> Generated by `kozou docs` from PostgreSQL DDL + COMMENT. Do not edit by hand.';
|
|
11
|
+
export function emitMarkdown(schema) {
|
|
12
|
+
// 1:1 view -> concept, used to surface @example: queries on views.
|
|
13
|
+
const examplesByView = new Map();
|
|
14
|
+
for (const c of schema.concepts)
|
|
15
|
+
examplesByView.set(c.name, c.exampleQueries);
|
|
16
|
+
const sections = ['# Database schema', BANNER];
|
|
17
|
+
const sourceSchemas = schema.meta.sourceSchemas;
|
|
18
|
+
if (sourceSchemas.length > 0) {
|
|
19
|
+
sections.push(`Source schemas: ${sourceSchemas.map(code).join(', ')}.`);
|
|
20
|
+
}
|
|
21
|
+
sections.push(renderContents(schema));
|
|
22
|
+
if (schema.tables.length > 0) {
|
|
23
|
+
sections.push('## Tables');
|
|
24
|
+
for (const t of schema.tables)
|
|
25
|
+
sections.push(renderTable(t));
|
|
26
|
+
}
|
|
27
|
+
if (schema.views.length > 0) {
|
|
28
|
+
sections.push('## Views');
|
|
29
|
+
for (const v of schema.views)
|
|
30
|
+
sections.push(renderView(v, examplesByView.get(v.name) ?? []));
|
|
31
|
+
}
|
|
32
|
+
if (schema.enums.length > 0) {
|
|
33
|
+
sections.push('## Enums');
|
|
34
|
+
for (const e of schema.enums)
|
|
35
|
+
sections.push(renderEnum(e));
|
|
36
|
+
}
|
|
37
|
+
if (schema.tables.length === 0 && schema.views.length === 0 && schema.enums.length === 0) {
|
|
38
|
+
sections.push('_No tables, views, or enums were found in the introspected schema._');
|
|
39
|
+
}
|
|
40
|
+
return sections.join('\n\n') + '\n';
|
|
41
|
+
}
|
|
42
|
+
function renderContents(schema) {
|
|
43
|
+
const lines = ['## Contents'];
|
|
44
|
+
const group = (title, items) => {
|
|
45
|
+
if (items.length === 0)
|
|
46
|
+
return;
|
|
47
|
+
lines.push('', `**${title}**`, '');
|
|
48
|
+
for (const it of items)
|
|
49
|
+
lines.push(`- [${escapeInline(it.label)}](#${it.anchor})`);
|
|
50
|
+
};
|
|
51
|
+
group('Tables', schema.tables.map((t) => ({ label: t.label, anchor: tableAnchor(t) })));
|
|
52
|
+
group('Views', schema.views.map((v) => ({ label: v.label, anchor: viewAnchor(v) })));
|
|
53
|
+
group('Enums', schema.enums.map((e) => ({ label: `${e.schema}.${e.name}`, anchor: enumAnchor(e) })));
|
|
54
|
+
return lines.join('\n');
|
|
55
|
+
}
|
|
56
|
+
function renderTable(t) {
|
|
57
|
+
const out = [
|
|
58
|
+
`<a id="${tableAnchor(t)}"></a>`,
|
|
59
|
+
`### ${escapeInline(t.label)} (${code(t.qualifiedName)})`,
|
|
60
|
+
];
|
|
61
|
+
pushProse(out, t.description);
|
|
62
|
+
pushAiNotes(out, t.aiDescription);
|
|
63
|
+
pushPolicies(out, t.policy ?? []);
|
|
64
|
+
out.push(renderColumnsTable(t.columns, t.relations));
|
|
65
|
+
return out.join('\n\n');
|
|
66
|
+
}
|
|
67
|
+
function renderView(v, examples) {
|
|
68
|
+
const out = [
|
|
69
|
+
`<a id="${viewAnchor(v)}"></a>`,
|
|
70
|
+
`### ${escapeInline(v.label)} (${code(v.qualifiedName)})`,
|
|
71
|
+
];
|
|
72
|
+
pushProse(out, v.description);
|
|
73
|
+
pushAiNotes(out, v.aiDescription);
|
|
74
|
+
pushPolicies(out, v.policy ?? []);
|
|
75
|
+
if (v.underlyingTables.length > 0) {
|
|
76
|
+
const tables = v.underlyingTables.map((u) => code(`${u.schema}.${u.name}`)).join(', ');
|
|
77
|
+
out.push(`**Underlying tables:** ${tables}`);
|
|
78
|
+
}
|
|
79
|
+
out.push(renderColumnsTable(v.columns, []));
|
|
80
|
+
for (const ex of examples) {
|
|
81
|
+
out.push(`**Example query — ${escapeInline(ex.description)}**`);
|
|
82
|
+
out.push(fencedSql(ex.sql));
|
|
83
|
+
}
|
|
84
|
+
out.push('**Definition**');
|
|
85
|
+
out.push(fencedSql(v.rawView.definition));
|
|
86
|
+
return out.join('\n\n');
|
|
87
|
+
}
|
|
88
|
+
function renderEnum(e) {
|
|
89
|
+
const out = [
|
|
90
|
+
`<a id="${enumAnchor(e)}"></a>`,
|
|
91
|
+
`### ${code(`${e.schema}.${e.name}`)}`,
|
|
92
|
+
];
|
|
93
|
+
out.push(e.values.map((val) => `- ${code(val)}`).join('\n'));
|
|
94
|
+
return out.join('\n\n');
|
|
95
|
+
}
|
|
96
|
+
function renderColumnsTable(columns, relations) {
|
|
97
|
+
const fkByField = new Map();
|
|
98
|
+
for (const rel of relations)
|
|
99
|
+
fkByField.set(rel.field, rel);
|
|
100
|
+
const header = '| Column | Type | Null | Default | Key | Description |';
|
|
101
|
+
const divider = '| --- | --- | --- | --- | --- | --- |';
|
|
102
|
+
const rows = columns.map((c) => {
|
|
103
|
+
const key = columnKey(c, fkByField.get(c.name));
|
|
104
|
+
const def = c.defaultExpr ? code(c.defaultExpr) : '';
|
|
105
|
+
const desc = columnDescription(c);
|
|
106
|
+
return `| ${code(c.name)} | ${escapeCell(c.dataType)} | ${c.nullable ? 'yes' : 'no'} | ${def} | ${key} | ${desc} |`;
|
|
107
|
+
});
|
|
108
|
+
return [header, divider, ...rows].join('\n');
|
|
109
|
+
}
|
|
110
|
+
function columnKey(column, fk) {
|
|
111
|
+
const parts = [];
|
|
112
|
+
if (column.isPrimaryKey)
|
|
113
|
+
parts.push('PK');
|
|
114
|
+
if (fk) {
|
|
115
|
+
const ref = fk.references;
|
|
116
|
+
parts.push(`FK → ${escapeCell(`${ref.schema}.${ref.table}.${ref.column}`)}`);
|
|
117
|
+
}
|
|
118
|
+
else if (column.isForeignKey) {
|
|
119
|
+
parts.push('FK');
|
|
120
|
+
}
|
|
121
|
+
return parts.join(', ');
|
|
122
|
+
}
|
|
123
|
+
/** A one-line, table-cell-safe description: cleaned of tag lines, with the
|
|
124
|
+
* enum domain appended when present. */
|
|
125
|
+
function columnDescription(column) {
|
|
126
|
+
const prose = cleanProse(column.description);
|
|
127
|
+
const parts = [];
|
|
128
|
+
if (prose)
|
|
129
|
+
parts.push(escapeCell(prose));
|
|
130
|
+
if (column.enumValues && column.enumValues.length > 0) {
|
|
131
|
+
parts.push(`One of: ${column.enumValues.map(code).join(', ')}.`);
|
|
132
|
+
}
|
|
133
|
+
return parts.join(' ');
|
|
134
|
+
}
|
|
135
|
+
function pushProse(out, description) {
|
|
136
|
+
const prose = cleanProse(description);
|
|
137
|
+
if (prose)
|
|
138
|
+
out.push(prose);
|
|
139
|
+
}
|
|
140
|
+
function pushAiNotes(out, aiDescription) {
|
|
141
|
+
if (!aiDescription)
|
|
142
|
+
return;
|
|
143
|
+
const quoted = aiDescription
|
|
144
|
+
.split('\n')
|
|
145
|
+
.map((line) => `> ${line}`)
|
|
146
|
+
.join('\n');
|
|
147
|
+
out.push(`**AI notes:**\n\n${quoted}`);
|
|
148
|
+
}
|
|
149
|
+
function pushPolicies(out, policies) {
|
|
150
|
+
if (policies.length === 0)
|
|
151
|
+
return;
|
|
152
|
+
const list = policies.map((p) => `- ${escapeInline(p)}`).join('\n');
|
|
153
|
+
out.push(`**Policies:**\n\n${list}`);
|
|
154
|
+
}
|
|
155
|
+
/** Drop `@ai:` / `@policy:` / other tag lines from a COMMENT body, leaving the
|
|
156
|
+
* human prose. Tag lines are surfaced separately as structured sections. */
|
|
157
|
+
function cleanProse(description) {
|
|
158
|
+
if (description === null)
|
|
159
|
+
return null;
|
|
160
|
+
const kept = description.split('\n').filter((line) => !line.trim().startsWith('@'));
|
|
161
|
+
const text = kept.join('\n').trim();
|
|
162
|
+
return text === '' ? null : text;
|
|
163
|
+
}
|
|
164
|
+
function fencedSql(sql) {
|
|
165
|
+
return ['```sql', sql.trim(), '```'].join('\n');
|
|
166
|
+
}
|
|
167
|
+
function code(value) {
|
|
168
|
+
return `\`${value}\``;
|
|
169
|
+
}
|
|
170
|
+
/** Escape a value for inline Markdown text (outside a table cell). */
|
|
171
|
+
function escapeInline(value) {
|
|
172
|
+
return value.replace(/\s+/g, ' ').trim();
|
|
173
|
+
}
|
|
174
|
+
/** Collapse whitespace and escape a value so it is safe inside a Markdown
|
|
175
|
+
* table cell. The backslash is escaped first so a pre-existing `\` cannot
|
|
176
|
+
* swallow the escape we add for the pipe. All regexes are linear (single,
|
|
177
|
+
* unanchored) — no ReDoS. */
|
|
178
|
+
function escapeCell(value) {
|
|
179
|
+
return value
|
|
180
|
+
.replace(/\s+/g, ' ')
|
|
181
|
+
.trim()
|
|
182
|
+
.replace(/\\/g, '\\\\')
|
|
183
|
+
.replace(/\|/g, '\\|');
|
|
184
|
+
}
|
|
185
|
+
function tableAnchor(t) {
|
|
186
|
+
return `table-${slug(t.qualifiedName)}`;
|
|
187
|
+
}
|
|
188
|
+
function viewAnchor(v) {
|
|
189
|
+
return `view-${slug(v.qualifiedName)}`;
|
|
190
|
+
}
|
|
191
|
+
function enumAnchor(e) {
|
|
192
|
+
return `enum-${slug(`${e.schema}.${e.name}`)}`;
|
|
193
|
+
}
|
|
194
|
+
/** A deterministic, renderer-independent anchor slug. Paired with an explicit
|
|
195
|
+
* `<a id>` so the table-of-contents links resolve regardless of how a given
|
|
196
|
+
* Markdown renderer auto-slugs headings. */
|
|
197
|
+
function slug(value) {
|
|
198
|
+
return value
|
|
199
|
+
.toLowerCase()
|
|
200
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
201
|
+
.replace(/^-+/, '')
|
|
202
|
+
.replace(/-+$/, '');
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=docs.js.map
|
package/dist/docs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { PACKAGE_VERSION } from './version.js';
|
|
2
2
|
export { loadConfig, KozouConfigError } from './config.js';
|
|
3
3
|
export type { KozouConfig, KozouConfigIssue, LoadConfigOptions } from './config.js';
|
|
4
4
|
export { inspectCommand } from './commands/inspect.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC3D,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEpF,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxE,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,18 +2,11 @@
|
|
|
2
2
|
// commands programmatically. The bin entry points live in cli.ts and
|
|
3
3
|
// create-kozou.ts; this module re-exports the underlying primitives so
|
|
4
4
|
// integrators can build their own glue if they need to.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
// so a release bump in package.json can never drift from this constant.
|
|
11
|
-
// `../package.json` resolves to packages/kozou/package.json from the
|
|
12
|
-
// compiled dist/index.js, and npm always ships package.json in the
|
|
13
|
-
// published tarball.
|
|
14
|
-
const require = createRequire(import.meta.url);
|
|
15
|
-
const pkg = JSON.parse(readFileSync(require.resolve('../package.json'), 'utf8'));
|
|
16
|
-
export const PACKAGE_VERSION = pkg.version;
|
|
5
|
+
// `package.json` is the single source of truth for the version; it is
|
|
6
|
+
// read in ./version.js (its own module so command modules can import the
|
|
7
|
+
// version without pulling in this barrel's command re-exports, which
|
|
8
|
+
// would create an import cycle).
|
|
9
|
+
export { PACKAGE_VERSION } from './version.js';
|
|
17
10
|
export { loadConfig, KozouConfigError } from './config.js';
|
|
18
11
|
export { inspectCommand } from './commands/inspect.js';
|
|
19
12
|
export { mcpCommand } from './commands/mcp.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,qEAAqE;AACrE,uEAAuE;AACvE,wDAAwD;AAExD,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,qEAAqE;AACrE,uEAAuE;AACvE,wDAAwD;AAExD,sEAAsE;AACtE,yEAAyE;AACzE,qEAAqE;AACrE,iCAAiC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG3D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG/C,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -43,7 +43,7 @@ services:
|
|
|
43
43
|
# `kozou dev` spawns the bundled @kozou/svelte-ui Admin UI and the
|
|
44
44
|
# MCP HTTP server (Kozou v0.1 spec §9.1). Both bind 0.0.0.0 inside
|
|
45
45
|
# the container so the port mappings below reach your host.
|
|
46
|
-
image: ghcr.io/kozou-dev/kozou:v0.
|
|
46
|
+
image: ghcr.io/kozou-dev/kozou:v0.2.1
|
|
47
47
|
command: ["dev"]
|
|
48
48
|
environment:
|
|
49
49
|
DATABASE_URL: postgres://${POSTGRES_USER:-kozou}:${POSTGRES_PASSWORD:-kozou}@postgres:5432/${POSTGRES_DB:-kozou}
|
|
@@ -10,8 +10,16 @@ POSTGRES_PORT=5432
|
|
|
10
10
|
DATABASE_URL=postgres://kozou:change-me@postgres:5432/kozou
|
|
11
11
|
KOZOU_ADAPTER_URL=http://postgrest:3000
|
|
12
12
|
|
|
13
|
-
# Public URL you open the Admin UI on (v0.
|
|
13
|
+
# Public URL you open the Admin UI on (v0.2.1). The bundled SvelteKit
|
|
14
14
|
# (adapter-node) server needs this to accept form submissions over plain
|
|
15
15
|
# http — without it, create / edit / delete are rejected with a 403
|
|
16
16
|
# "Cross-site POST forbidden". Override if you serve the UI elsewhere.
|
|
17
17
|
KOZOU_ORIGIN=http://localhost:3333
|
|
18
|
+
|
|
19
|
+
# JWT auth for the experimental in-house API (`kozou dev --adapter api`).
|
|
20
|
+
# Leave unset to keep it unauthenticated and loopback-only (the default).
|
|
21
|
+
# KOZOU_JWT_SECRET=your-hs256-secret # HS256 — or KOZOU_JWT_PUBLIC_KEY / KOZOU_JWT_JWKS_URI
|
|
22
|
+
# KOZOU_JWT_JWKS_URI=https://your-idp/.well-known/jwks.json # Auth0 / Clerk / Supabase
|
|
23
|
+
# KOZOU_JWT_ANON_ROLE=web_anon # role for requests with no token (else 401)
|
|
24
|
+
# KOZOU_UI_ROLE=app_admin # role the bundled Admin UI runs as (HS256)
|
|
25
|
+
# KOZOU_ADAPTER_TOKEN= # RS256 / external IdP: a ready-made UI token
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,eAAe,QAAc,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// The kozou package version, read from package.json at module load so a
|
|
2
|
+
// release bump in package.json can never drift from this constant.
|
|
3
|
+
// `../package.json` resolves to packages/kozou/package.json from the
|
|
4
|
+
// compiled dist/version.js, and npm always ships package.json in the
|
|
5
|
+
// published tarball.
|
|
6
|
+
//
|
|
7
|
+
// Kept in its own module (rather than in index.ts) so command modules can
|
|
8
|
+
// read the version without importing the package barrel `./index.js`,
|
|
9
|
+
// which re-exports the commands and would create an import cycle.
|
|
10
|
+
import { readFileSync } from 'node:fs';
|
|
11
|
+
import { createRequire } from 'node:module';
|
|
12
|
+
const require = createRequire(import.meta.url);
|
|
13
|
+
const pkg = JSON.parse(readFileSync(require.resolve('../package.json'), 'utf8'));
|
|
14
|
+
export const PACKAGE_VERSION = pkg.version;
|
|
15
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,mEAAmE;AACnE,qEAAqE;AACrE,qEAAqE;AACrE,qBAAqB;AACrB,EAAE;AACF,0EAA0E;AAC1E,sEAAsE;AACtE,kEAAkE;AAElE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,CAE9E,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAC,OAAO,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kozou",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Kozou CLI: scaffolding, schema introspection, and MCP server entry points. See Kozou v0.1 design spec §9.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -35,26 +35,30 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"commander": "^14.0.0",
|
|
38
|
+
"pg": "^8.13.0",
|
|
38
39
|
"yaml": "^2.9.0",
|
|
39
40
|
"zod": "^4.4.3",
|
|
40
|
-
"@kozou/core": "0.
|
|
41
|
-
"@kozou/introspect": "0.
|
|
42
|
-
"@kozou/mcp": "0.
|
|
43
|
-
"@kozou/svelte-ui": "0.
|
|
41
|
+
"@kozou/core": "0.2.1",
|
|
42
|
+
"@kozou/introspect": "0.2.1",
|
|
43
|
+
"@kozou/mcp": "0.2.1",
|
|
44
|
+
"@kozou/svelte-ui": "0.2.1"
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
46
47
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
47
48
|
"@playwright/test": "^1.50.0",
|
|
48
49
|
"@testcontainers/postgresql": "^12.0.0",
|
|
49
50
|
"@types/pg": "^8.11.10",
|
|
50
|
-
"pg": "^8.13.0",
|
|
51
51
|
"testcontainers": "^12.0.0",
|
|
52
|
-
"tsx": "^4.19.0"
|
|
52
|
+
"tsx": "^4.19.0",
|
|
53
|
+
"@kozou/api": "0.2.1",
|
|
54
|
+
"@kozou/codegen": "0.2.1"
|
|
53
55
|
},
|
|
54
56
|
"scripts": {
|
|
55
57
|
"typecheck": "tsc --noEmit",
|
|
56
58
|
"build": "tsc && node scripts/copy-templates.mjs",
|
|
57
59
|
"test": "vitest run --coverage",
|
|
58
|
-
"test:e2e": "playwright test"
|
|
60
|
+
"test:e2e": "playwright test",
|
|
61
|
+
"test:e2e:api": "playwright test --config playwright.kozou-api.config.ts",
|
|
62
|
+
"test:e2e:api:auth": "playwright test --config playwright.kozou-api-auth.config.ts"
|
|
59
63
|
}
|
|
60
64
|
}
|