kozou 0.1.0 → 0.2.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 +85 -14
- package/dist/cli.js +37 -5
- 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 +54 -0
- package/dist/commands/codegen.js.map +1 -0
- package/dist/commands/dev-runtime.d.ts +21 -0
- package/dist/commands/dev-runtime.d.ts.map +1 -0
- package/dist/commands/dev-runtime.js +111 -0
- package/dist/commands/dev-runtime.js.map +1 -0
- package/dist/commands/dev.d.ts +5 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +168 -17
- 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/commands/mcp.d.ts +1 -0
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +12 -12
- package/dist/commands/mcp.js.map +1 -1
- package/dist/config.d.ts +39 -141
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +127 -10
- 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 +12 -1
- package/dist/index.js.map +1 -1
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +17 -6
- package/dist/scaffold.js.map +1 -1
- package/dist/templates/docker-compose.yml +27 -26
- package/dist/templates/env.example +14 -0
- package/package.json +19 -7
package/dist/config.js
CHANGED
|
@@ -4,62 +4,104 @@
|
|
|
4
4
|
// against the process environment, fills in defaults, and validates the
|
|
5
5
|
// result with zod. Every field has a default so kozou can run with only the
|
|
6
6
|
// DATABASE_URL environment variable set, per the Kozou v0.1 design spec §9.2.
|
|
7
|
+
//
|
|
8
|
+
// A literal `$$` escapes to a single `$`, so `$${VAR}` produces the literal
|
|
9
|
+
// text `${VAR}` instead of expanding it. Expansion is single-level by design:
|
|
10
|
+
// a value substituted from the environment is never re-scanned, so a secret
|
|
11
|
+
// that legitimately contains `${...}` (e.g. inside a DATABASE_URL password) is
|
|
12
|
+
// preserved rather than mistaken for a placeholder. See expandEnvVars below.
|
|
7
13
|
import { readFile } from 'node:fs/promises';
|
|
8
14
|
import { existsSync } from 'node:fs';
|
|
9
15
|
import { resolve, isAbsolute } from 'node:path';
|
|
10
16
|
import { parse as parseYAML } from 'yaml';
|
|
11
17
|
import { z } from 'zod';
|
|
12
18
|
// ---- Schema ---------------------------------------------------------------
|
|
19
|
+
// Nested sections use `.prefault({})` rather than `.default({})`: in zod 4
|
|
20
|
+
// `.default(v)` short-circuits to `v` as-is when the input is undefined (so
|
|
21
|
+
// it would need the fully-populated object), whereas `.prefault(v)` feeds
|
|
22
|
+
// `v` back through the schema so each field's own `.default(...)` still
|
|
23
|
+
// applies. `.prefault({})` therefore reproduces the zod 3 behaviour of
|
|
24
|
+
// "absent section -> object filled entirely from inner defaults".
|
|
13
25
|
const uiServerSchema = z
|
|
14
26
|
.object({
|
|
15
27
|
port: z.number().int().min(0).max(65_535).default(3333),
|
|
16
28
|
host: z.string().min(1).default('0.0.0.0'),
|
|
17
29
|
})
|
|
18
|
-
.
|
|
30
|
+
.prefault({});
|
|
19
31
|
const mcpHttpServerSchema = z
|
|
20
32
|
.object({
|
|
21
33
|
port: z.number().int().min(0).max(65_535).default(3334),
|
|
22
34
|
host: z.string().min(1).default('0.0.0.0'),
|
|
23
35
|
})
|
|
24
|
-
.
|
|
36
|
+
.prefault({});
|
|
25
37
|
const mcpServerSchema = z
|
|
26
38
|
.object({
|
|
27
39
|
http: mcpHttpServerSchema,
|
|
28
40
|
stdio: z.boolean().default(false),
|
|
29
41
|
})
|
|
30
|
-
.
|
|
42
|
+
.prefault({});
|
|
31
43
|
const serverSchema = z
|
|
32
44
|
.object({
|
|
33
45
|
ui: uiServerSchema,
|
|
34
46
|
mcp: mcpServerSchema,
|
|
35
47
|
})
|
|
36
|
-
.
|
|
48
|
+
.prefault({});
|
|
37
49
|
const adapterSchema = z
|
|
38
50
|
.object({
|
|
39
51
|
type: z.literal('postgrest').default('postgrest'),
|
|
40
52
|
url: z.string().min(1).default('http://postgrest:3000'),
|
|
41
53
|
})
|
|
42
|
-
.
|
|
54
|
+
.prefault({});
|
|
43
55
|
const uiHintsSchema = z
|
|
44
56
|
.object({
|
|
45
57
|
path: z.string().nullable().default(null),
|
|
46
58
|
})
|
|
47
|
-
.
|
|
59
|
+
.prefault({});
|
|
48
60
|
const cacheSchema = z
|
|
49
61
|
.object({
|
|
50
62
|
ttlMs: z.number().int().min(0).default(60_000),
|
|
51
63
|
})
|
|
52
|
-
.
|
|
64
|
+
.prefault({});
|
|
53
65
|
const databaseSchema = z.object({
|
|
54
66
|
url: z.string().min(1, 'database.url is required (set DATABASE_URL or kozou.config.yaml)'),
|
|
55
67
|
schemas: z.array(z.string().min(1)).default(['public']),
|
|
56
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
|
+
});
|
|
57
98
|
const configSchema = z.object({
|
|
58
99
|
database: databaseSchema,
|
|
59
100
|
server: serverSchema,
|
|
60
101
|
adapter: adapterSchema,
|
|
61
102
|
uiHints: uiHintsSchema,
|
|
62
103
|
cache: cacheSchema,
|
|
104
|
+
auth: authSchema.optional(),
|
|
63
105
|
});
|
|
64
106
|
export class KozouConfigError extends Error {
|
|
65
107
|
issues;
|
|
@@ -73,10 +115,22 @@ export class KozouConfigError extends Error {
|
|
|
73
115
|
}
|
|
74
116
|
// ---- Loader --------------------------------------------------------------
|
|
75
117
|
const DEFAULT_CONFIG_PATH = 'kozou.config.yaml';
|
|
76
|
-
|
|
118
|
+
// Matches either an escaped `$$` (which becomes a literal `$`) or a
|
|
119
|
+
// `${VAR}` / `${VAR:-default}` placeholder. `$$` is listed first so the
|
|
120
|
+
// alternation consumes it before the placeholder branch can see a stray `$`.
|
|
121
|
+
const ENV_TOKEN_RE = /\$\$|\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}/g;
|
|
77
122
|
function expandEnvVars(value, env) {
|
|
78
123
|
if (typeof value === 'string') {
|
|
79
|
-
return value.replace(
|
|
124
|
+
return value.replace(ENV_TOKEN_RE, (match, name, fallback) => {
|
|
125
|
+
// `$$` -> literal `$`. So `$${VAR}` yields the literal `${VAR}`:
|
|
126
|
+
// the trailing `{VAR}` is left untouched because it no longer has
|
|
127
|
+
// a `$` prefix to start a placeholder.
|
|
128
|
+
if (match === '$$')
|
|
129
|
+
return '$';
|
|
130
|
+
// Otherwise `match` is a `${...}` placeholder and `name` is its
|
|
131
|
+
// (always-present) variable name. The substituted value is taken
|
|
132
|
+
// verbatim and never re-scanned (single-level expansion), so a
|
|
133
|
+
// value containing `${...}` is preserved as-is.
|
|
80
134
|
const v = env[name];
|
|
81
135
|
if (v !== undefined)
|
|
82
136
|
return v;
|
|
@@ -116,6 +170,67 @@ function injectDatabaseUrlFromEnv(raw, env) {
|
|
|
116
170
|
}
|
|
117
171
|
return obj;
|
|
118
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
|
+
}
|
|
119
234
|
export async function loadConfig(opts = {}) {
|
|
120
235
|
const env = opts.env ?? process.env;
|
|
121
236
|
const requestedPath = opts.path ?? DEFAULT_CONFIG_PATH;
|
|
@@ -138,8 +253,10 @@ export async function loadConfig(opts = {}) {
|
|
|
138
253
|
// Fall back to DATABASE_URL env if database.url is not set in the file.
|
|
139
254
|
const withDbDefault = injectDatabaseUrlFromEnv(raw, env);
|
|
140
255
|
const expanded = expandEnvVars(withDbDefault, env);
|
|
256
|
+
// Build `auth` from KOZOU_JWT_* env after expansion (env secrets verbatim).
|
|
257
|
+
const withAuth = injectAuthFromEnv(expanded, env);
|
|
141
258
|
try {
|
|
142
|
-
return configSchema.parse(
|
|
259
|
+
return configSchema.parse(withAuth);
|
|
143
260
|
}
|
|
144
261
|
catch (err) {
|
|
145
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":"AAAA,4BAA4B;AAC5B,EAAE;AACF,4EAA4E;AAC5E,wEAAwE;AACxE,4EAA4E;AAC5E,8EAA8E;
|
|
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 declare const PACKAGE_VERSION
|
|
1
|
+
export declare const PACKAGE_VERSION: string;
|
|
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":"AAoBA,eAAO,MAAM,eAAe,QAAc,CAAC;AAE3C,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,7 +2,18 @@
|
|
|
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
|
-
|
|
5
|
+
import { readFileSync } from 'node:fs';
|
|
6
|
+
import { createRequire } from 'node:module';
|
|
7
|
+
// `package.json` is the single source of truth for the version. Read it
|
|
8
|
+
// at module load (the same createRequire idiom commands/dev-runtime.ts
|
|
9
|
+
// uses to resolve a sibling package) instead of hardcoding a copy here,
|
|
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;
|
|
6
17
|
export { loadConfig, KozouConfigError } from './config.js';
|
|
7
18
|
export { inspectCommand } from './commands/inspect.js';
|
|
8
19
|
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,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,qEAAqE;AACrE,uEAAuE;AACvE,wDAAwD;AAExD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,wEAAwE;AACxE,uEAAuE;AACvE,wEAAwE;AACxE,wEAAwE;AACxE,qEAAqE;AACrE,mEAAmE;AACnE,qBAAqB;AACrB,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;AAE3C,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"}
|
package/dist/scaffold.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,qBAAqB,GAAG;IAClC,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAyBD,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBpF"}
|
package/dist/scaffold.js
CHANGED
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
// stays a normal file because npm's tarball handling for dotfiles
|
|
7
7
|
// inside published packages can be surprising).
|
|
8
8
|
import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
|
|
9
|
-
import {
|
|
10
|
-
import { join } from 'node:path';
|
|
9
|
+
import { dirname, join } from 'node:path';
|
|
11
10
|
import { fileURLToPath } from 'node:url';
|
|
12
11
|
const DEFAULT_TEMPLATE_DIR = fileURLToPath(new URL('./templates', import.meta.url));
|
|
13
12
|
export class KozouScaffoldError extends Error {
|
|
@@ -44,11 +43,23 @@ export async function createKozouScaffold(opts) {
|
|
|
44
43
|
if (target === '') {
|
|
45
44
|
throw new KozouScaffoldError('create-kozou: target directory is required');
|
|
46
45
|
}
|
|
47
|
-
if (existsSync(target)) {
|
|
48
|
-
throw new KozouScaffoldError(`create-kozou: "${target}" already exists`);
|
|
49
|
-
}
|
|
50
46
|
const templatesDir = opts.templatesDir ?? DEFAULT_TEMPLATE_DIR;
|
|
51
|
-
|
|
47
|
+
// Create any missing parent directories, then create the target itself
|
|
48
|
+
// with a NON-recursive mkdir so an already-existing target fails
|
|
49
|
+
// atomically with EEXIST. A recursive mkdir silently succeeds on an
|
|
50
|
+
// existing directory, so the previous existsSync()-then-mkdir guard had
|
|
51
|
+
// a TOCTOU window (the target could be created between the check and the
|
|
52
|
+
// mkdir); letting mkdir own the "must not exist" check closes it.
|
|
53
|
+
await mkdir(dirname(target), { recursive: true });
|
|
54
|
+
try {
|
|
55
|
+
await mkdir(target);
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
if (err.code === 'EEXIST') {
|
|
59
|
+
throw new KozouScaffoldError(`create-kozou: "${target}" already exists`);
|
|
60
|
+
}
|
|
61
|
+
throw err;
|
|
62
|
+
}
|
|
52
63
|
await copyRecursive(templatesDir, target);
|
|
53
64
|
}
|
|
54
65
|
//# sourceMappingURL=scaffold.js.map
|
package/dist/scaffold.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,EAAE;AACF,uEAAuE;AACvE,sEAAsE;AACtE,uEAAuE;AACvE,kEAAkE;AAClE,gDAAgD;AAEhD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,EAAE;AACF,uEAAuE;AACvE,sEAAsE;AACtE,uEAAuE;AACvE,kEAAkE;AAClE,gDAAgD;AAEhD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,oBAAoB,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AASpF,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,IAAY;IACpD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC;QAC5B,mEAAmE;QACnE,+DAA+D;QAC/D,oCAAoC;QACpC,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACnD,UAAU,GAAG,cAAc,CAAC;QAC9B,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3C,MAAM,aAAa,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC5C,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YACnD,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAC7C,CAAC;QACD,4DAA4D;IAC9D,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAA2B;IACnE,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1C,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,kBAAkB,CAAC,4CAA4C,CAAC,CAAC;IAC7E,CAAC;IACD,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,oBAAoB,CAAC;IAC/D,uEAAuE;IACvE,iEAAiE;IACjE,oEAAoE;IACpE,wEAAwE;IACxE,yEAAyE;IACzE,kEAAkE;IAClE,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,MAAM,IAAI,kBAAkB,CAAC,kBAAkB,MAAM,kBAAkB,CAAC,CAAC;QAC3E,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,MAAM,aAAa,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;AAC5C,CAAC"}
|