@kindgi/cli 0.1.2 → 0.1.4-rc.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.
Files changed (153) hide show
  1. package/README.md +77 -10
  2. package/dist/build/containerfile.d.ts +1 -1
  3. package/dist/build/containerfile.d.ts.map +1 -1
  4. package/dist/build/containerfile.js +16 -2
  5. package/dist/build/containerfile.js.map +1 -1
  6. package/dist/build/defaults.d.ts.map +1 -1
  7. package/dist/build/defaults.js +2 -0
  8. package/dist/build/defaults.js.map +1 -1
  9. package/dist/build/host-install.d.ts +8 -0
  10. package/dist/build/host-install.d.ts.map +1 -1
  11. package/dist/build/host-install.js.map +1 -1
  12. package/dist/build/runners.d.ts +5 -0
  13. package/dist/build/runners.d.ts.map +1 -1
  14. package/dist/commands/agents.d.ts.map +1 -1
  15. package/dist/commands/agents.js +63 -2
  16. package/dist/commands/agents.js.map +1 -1
  17. package/dist/commands/blocks.d.ts +3 -0
  18. package/dist/commands/blocks.d.ts.map +1 -0
  19. package/dist/commands/blocks.js +186 -0
  20. package/dist/commands/blocks.js.map +1 -0
  21. package/dist/commands/build.d.ts.map +1 -1
  22. package/dist/commands/build.js +35 -3
  23. package/dist/commands/build.js.map +1 -1
  24. package/dist/commands/dev.d.ts.map +1 -1
  25. package/dist/commands/dev.js +241 -40
  26. package/dist/commands/dev.js.map +1 -1
  27. package/dist/commands/env.js +1 -1
  28. package/dist/commands/env.js.map +1 -1
  29. package/dist/commands/eval-runs.d.ts +20 -0
  30. package/dist/commands/eval-runs.d.ts.map +1 -0
  31. package/dist/commands/eval-runs.js +227 -0
  32. package/dist/commands/eval-runs.js.map +1 -0
  33. package/dist/commands/eval-suites.d.ts +3 -0
  34. package/dist/commands/eval-suites.d.ts.map +1 -0
  35. package/dist/commands/eval-suites.js +177 -0
  36. package/dist/commands/eval-suites.js.map +1 -0
  37. package/dist/commands/helpers.d.ts +2 -0
  38. package/dist/commands/helpers.d.ts.map +1 -1
  39. package/dist/commands/helpers.js +6 -0
  40. package/dist/commands/helpers.js.map +1 -1
  41. package/dist/commands/index.d.ts.map +1 -1
  42. package/dist/commands/index.js +10 -0
  43. package/dist/commands/index.js.map +1 -1
  44. package/dist/commands/init.d.ts.map +1 -1
  45. package/dist/commands/init.js +39 -1
  46. package/dist/commands/init.js.map +1 -1
  47. package/dist/commands/judge-classes.d.ts +3 -0
  48. package/dist/commands/judge-classes.d.ts.map +1 -0
  49. package/dist/commands/judge-classes.js +136 -0
  50. package/dist/commands/judge-classes.js.map +1 -0
  51. package/dist/commands/judgments.d.ts +3 -0
  52. package/dist/commands/judgments.d.ts.map +1 -0
  53. package/dist/commands/judgments.js +159 -0
  54. package/dist/commands/judgments.js.map +1 -0
  55. package/dist/commands/providers.d.ts.map +1 -1
  56. package/dist/commands/providers.js +10 -1
  57. package/dist/commands/providers.js.map +1 -1
  58. package/dist/commands/runs.d.ts.map +1 -1
  59. package/dist/commands/runs.js +44 -8
  60. package/dist/commands/runs.js.map +1 -1
  61. package/dist/context.d.ts +9 -0
  62. package/dist/context.d.ts.map +1 -1
  63. package/dist/context.js +1 -0
  64. package/dist/context.js.map +1 -1
  65. package/dist/deploy/post.d.ts.map +1 -1
  66. package/dist/deploy/post.js +4 -0
  67. package/dist/deploy/post.js.map +1 -1
  68. package/dist/deploy/response.d.ts +9 -1
  69. package/dist/deploy/response.d.ts.map +1 -1
  70. package/dist/deploy/response.js +76 -7
  71. package/dist/deploy/response.js.map +1 -1
  72. package/dist/deploy/runners.d.ts +27 -0
  73. package/dist/deploy/runners.d.ts.map +1 -1
  74. package/dist/dev/bundler.d.ts +21 -0
  75. package/dist/dev/bundler.d.ts.map +1 -1
  76. package/dist/dev/bundler.js +46 -18
  77. package/dist/dev/bundler.js.map +1 -1
  78. package/dist/dev/defaults.d.ts +20 -3
  79. package/dist/dev/defaults.d.ts.map +1 -1
  80. package/dist/dev/defaults.js +48 -12
  81. package/dist/dev/defaults.js.map +1 -1
  82. package/dist/dev/project-database.d.ts +68 -0
  83. package/dist/dev/project-database.d.ts.map +1 -0
  84. package/dist/dev/project-database.js +142 -0
  85. package/dist/dev/project-database.js.map +1 -0
  86. package/dist/dev/project.d.ts +59 -0
  87. package/dist/dev/project.d.ts.map +1 -0
  88. package/dist/dev/project.js +182 -0
  89. package/dist/dev/project.js.map +1 -0
  90. package/dist/dev/providers.d.ts +126 -0
  91. package/dist/dev/providers.d.ts.map +1 -0
  92. package/dist/dev/providers.js +456 -0
  93. package/dist/dev/providers.js.map +1 -0
  94. package/dist/dev/python-builder.d.ts +6 -0
  95. package/dist/dev/python-builder.d.ts.map +1 -1
  96. package/dist/dev/python-builder.js +30 -5
  97. package/dist/dev/python-builder.js.map +1 -1
  98. package/dist/dev/runners.d.ts +22 -0
  99. package/dist/dev/runners.d.ts.map +1 -1
  100. package/dist/dev/runtime-container.d.ts +21 -0
  101. package/dist/dev/runtime-container.d.ts.map +1 -1
  102. package/dist/dev/runtime-container.js +142 -15
  103. package/dist/dev/runtime-container.js.map +1 -1
  104. package/dist/dev/runtime-image.d.ts +1 -1
  105. package/dist/dev/runtime-image.d.ts.map +1 -1
  106. package/dist/dev/runtime-image.js +1 -1
  107. package/dist/dev/runtime-image.js.map +1 -1
  108. package/dist/dev/scan-backstop.d.ts +38 -0
  109. package/dist/dev/scan-backstop.d.ts.map +1 -0
  110. package/dist/dev/scan-backstop.js +104 -0
  111. package/dist/dev/scan-backstop.js.map +1 -0
  112. package/dist/env/pack-env-plan.d.ts +7 -1
  113. package/dist/env/pack-env-plan.d.ts.map +1 -1
  114. package/dist/env/pack-env-plan.js +9 -3
  115. package/dist/env/pack-env-plan.js.map +1 -1
  116. package/dist/init/dependency-specs.d.ts +5 -0
  117. package/dist/init/dependency-specs.d.ts.map +1 -1
  118. package/dist/init/dependency-specs.js +16 -4
  119. package/dist/init/dependency-specs.js.map +1 -1
  120. package/dist/main.d.ts +2 -0
  121. package/dist/main.d.ts.map +1 -1
  122. package/dist/main.js +1 -0
  123. package/dist/main.js.map +1 -1
  124. package/dist/package-manager.d.ts +26 -0
  125. package/dist/package-manager.d.ts.map +1 -1
  126. package/dist/package-manager.js +66 -6
  127. package/dist/package-manager.js.map +1 -1
  128. package/dist/providers/preset-loader.d.ts +5 -0
  129. package/dist/providers/preset-loader.d.ts.map +1 -1
  130. package/dist/providers/preset-loader.js +9 -1
  131. package/dist/providers/preset-loader.js.map +1 -1
  132. package/dist/providers/presets/gemini.json +2 -1
  133. package/dist/runs/follow.d.ts +25 -0
  134. package/dist/runs/follow.d.ts.map +1 -0
  135. package/dist/runs/follow.js +48 -0
  136. package/dist/runs/follow.js.map +1 -0
  137. package/dist/sdk-skills/kindgi-authoring-agents/SKILL.md +1 -1
  138. package/dist/sdk-skills/kindgi-authoring-flows/SKILL.md +1 -1
  139. package/dist/sdk-skills/kindgi-authoring-guardrails/SKILL.md +1 -1
  140. package/dist/sdk-skills/kindgi-authoring-mcp-servers/SKILL.md +1 -1
  141. package/dist/sdk-skills/kindgi-authoring-providers/SKILL.md +41 -6
  142. package/dist/sdk-skills/kindgi-authoring-tools/SKILL.md +3 -2
  143. package/dist/sdk-skills/kindgi-framework-feedback/SKILL.md +1 -1
  144. package/dist/sdk-skills/kindgi-getting-started/SKILL.md +38 -6
  145. package/dist/sdk-skills/kindgi-python-authoring-agents/SKILL.md +1 -1
  146. package/dist/sdk-skills/kindgi-python-authoring-flows/SKILL.md +1 -1
  147. package/dist/sdk-skills/kindgi-python-authoring-guardrails/SKILL.md +1 -1
  148. package/dist/sdk-skills/kindgi-python-authoring-tools/SKILL.md +5 -1
  149. package/dist/sdk-skills/kindgi-python-getting-started/SKILL.md +44 -6
  150. package/dist/templates/minimal/AGENTS.md +4 -3
  151. package/dist/templates/python/AGENTS.md +5 -4
  152. package/dist/templates/sample/AGENTS.md +4 -3
  153. package/package.json +10 -10
@@ -0,0 +1,456 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ /**
4
+ * The model providers a pack declares in its config, kept in step by
5
+ * `kindgi dev`: `providers` in `kindgi.config.ts`, or
6
+ * `[[tool.kindgi.providers]]` in `pyproject.toml`.
7
+ *
8
+ * Each project (and each git worktree) has its own dev database, so a
9
+ * provider registered by hand has to be registered again per worktree,
10
+ * after every `--reset`, and on every teammate's machine. Declared here,
11
+ * `kindgi dev` registers them on boot.
12
+ *
13
+ * A declaration is a preset with the choices `providers register
14
+ * --preset` takes, or a full registration body (`spec`), as `--spec`
15
+ * takes it. A credential is always a secret's name, resolved in `local`
16
+ * (the pack's env files); a `spec` that carries one in `adapter_config`
17
+ * is refused.
18
+ *
19
+ * The reconcile reads the runtime's providers first, so a fresh or reset
20
+ * database is handled. A provider is this pack's only while it is as
21
+ * this pack registered it: `.kindgi/dev/providers.json` records, per dev
22
+ * database and tenant, a hash of what was declared and of what the
23
+ * runtime listed after registering it. Anything else in the runtime —
24
+ * registered by hand, by another pack of the project, or changed since —
25
+ * is never touched.
26
+ */
27
+ import { createHash } from 'node:crypto';
28
+ import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
29
+ import { dirname, join } from 'node:path';
30
+ import { LOCAL_ENV_NAME } from '@kindgi/secrets-dotenv';
31
+ import { stableStringify } from '../build/envelope.js';
32
+ import { presetRegistration } from '../providers/preset-loader.js';
33
+ const PRESET_KEYS = new Set([
34
+ 'preset',
35
+ 'models',
36
+ 'project',
37
+ 'secret',
38
+ 'maxOutputTokens',
39
+ ]);
40
+ /**
41
+ * `adapter_config` keys that hold a credential, compared lowercase with
42
+ * `-`/`_` dropped. A credential goes in `secret_ref`, by name.
43
+ */
44
+ const CREDENTIAL_KEYS = new Set([
45
+ 'apikey',
46
+ 'key',
47
+ 'token',
48
+ 'accesstoken',
49
+ 'bearertoken',
50
+ 'authtoken',
51
+ 'secret',
52
+ 'clientsecret',
53
+ 'password',
54
+ 'authorization',
55
+ 'credentials',
56
+ 'privatekey',
57
+ 'serviceaccountkey',
58
+ ]);
59
+ /**
60
+ * The config's `providers`, as registration bodies. `file` names the
61
+ * config in the messages (`kindgi.config.ts`, `pyproject.toml`).
62
+ */
63
+ export function declaredProviders(config, file, presets) {
64
+ const raw = config?.providers;
65
+ if (raw === undefined)
66
+ return { kind: 'ok', providers: [] };
67
+ const invalid = (message) => ({
68
+ kind: 'invalid',
69
+ message: `\`providers\` in ${file}: ${message}`,
70
+ });
71
+ if (!Array.isArray(raw)) {
72
+ return invalid('must be a list, each a `{ preset: … }` or a `{ spec: … }`.');
73
+ }
74
+ const out = [];
75
+ for (const [i, entry] of raw.entries()) {
76
+ const at = `entry ${i + 1}`;
77
+ if (!isRecord(entry))
78
+ return invalid(`${at} must be a \`{ preset: … }\` or a \`{ spec: … }\`.`);
79
+ if ('preset' in entry === 'spec' in entry) {
80
+ return invalid(`${at} must have one of \`preset\` or \`spec\`.`);
81
+ }
82
+ const built = 'preset' in entry ? fromPreset(entry, presets) : fromSpec(entry.spec);
83
+ if (built.kind === 'invalid')
84
+ return invalid(`${at}: ${built.message}`);
85
+ if (out.some((p) => p.id === built.provider.id)) {
86
+ return invalid(`${at}: provider "${built.provider.id}" is declared twice.`);
87
+ }
88
+ out.push(built.provider);
89
+ }
90
+ return { kind: 'ok', providers: out };
91
+ }
92
+ function fromPreset(entry, presets) {
93
+ const invalid = (message) => ({ kind: 'invalid', message });
94
+ const problem = presetEntryProblem(entry);
95
+ if (problem !== undefined)
96
+ return invalid(problem);
97
+ const { preset: name, models, project, secret, maxOutputTokens } = entry;
98
+ const preset = presets[name];
99
+ if (preset === undefined) {
100
+ return invalid(`no provider preset "${name}"; there are ${Object.keys(presets).join(', ')}.`);
101
+ }
102
+ const built = presetRegistration(preset, {
103
+ ...(models !== undefined && { models: models }),
104
+ ...(secret !== undefined && { secret: secret }),
105
+ envName: LOCAL_ENV_NAME,
106
+ settings: { project: project },
107
+ ...(maxOutputTokens !== undefined && { maxOutputTokens: maxOutputTokens }),
108
+ });
109
+ if (built.kind === 'err') {
110
+ // The preset's messages name the CLI flags (`--project=<…>`); the config names keys.
111
+ return invalid(built.message.replace(/--([a-z]+)=<…>/g, '`$1`'));
112
+ }
113
+ return { kind: 'ok', provider: { id: built.input.metadata.id, input: built.input } };
114
+ }
115
+ /** What's wrong with a preset entry's keys and values, before the preset is looked up. */
116
+ function presetEntryProblem(entry) {
117
+ const unknown = Object.keys(entry).filter((k) => !PRESET_KEYS.has(k));
118
+ if (unknown.length > 0) {
119
+ return `a preset takes ${[...PRESET_KEYS].map((k) => `\`${k}\``).join(', ')}; not ${unknown.map((k) => `\`${k}\``).join(', ')}.`;
120
+ }
121
+ const { preset: name, models, project, secret, maxOutputTokens } = entry;
122
+ if (typeof name !== 'string' || name === '')
123
+ return '`preset` must be a preset name.';
124
+ if (models !== undefined &&
125
+ (!Array.isArray(models) ||
126
+ models.length === 0 ||
127
+ !models.every((m) => typeof m === 'string' && m !== ''))) {
128
+ return '`models` must be a non-empty list of model names.';
129
+ }
130
+ for (const [key, value] of [
131
+ ['project', project],
132
+ ['secret', secret],
133
+ ]) {
134
+ if (value !== undefined && (typeof value !== 'string' || value === '')) {
135
+ return `\`${key}\` must be a non-empty string.`;
136
+ }
137
+ }
138
+ if (maxOutputTokens !== undefined &&
139
+ (typeof maxOutputTokens !== 'number' ||
140
+ !Number.isInteger(maxOutputTokens) ||
141
+ maxOutputTokens < 1)) {
142
+ return '`maxOutputTokens` must be a whole number of at least 1.';
143
+ }
144
+ return undefined;
145
+ }
146
+ function fromSpec(spec) {
147
+ const invalid = (message) => ({ kind: 'invalid', message });
148
+ if (!isRecord(spec)) {
149
+ return invalid('`spec` must be a registration body, as `providers register --spec` takes it.');
150
+ }
151
+ const metadata = spec.metadata;
152
+ if (!isRecord(metadata) || typeof metadata.id !== 'string' || metadata.id === '') {
153
+ return invalid('`spec.metadata.id` must name the provider.');
154
+ }
155
+ if (typeof spec.adapter_id !== 'string' || spec.adapter_id === '') {
156
+ return invalid('`spec.adapter_id` must name the adapter.');
157
+ }
158
+ const config = spec.adapter_config;
159
+ if (config !== undefined) {
160
+ if (!isRecord(config))
161
+ return invalid('`spec.adapter_config` must be an object.');
162
+ // Keys may be dotted (`extraBody.x`, one per request field): any part counts.
163
+ const credentials = Object.keys(config).filter((k) => k.split('.').some((part) => CREDENTIAL_KEYS.has(part.toLowerCase().replace(/[-_]/g, ''))));
164
+ if (credentials.length > 0) {
165
+ return invalid(`\`spec.adapter_config.${credentials[0]}\` looks like a credential. Credentials go in \`secret_ref\`, by name ({ name: "MY_API_KEY" }), with the value in the env files.`);
166
+ }
167
+ }
168
+ const ref = spec.secret_ref;
169
+ if (ref !== undefined && (!isRecord(ref) || typeof ref.name !== 'string' || ref.name === '')) {
170
+ return invalid('`spec.secret_ref` must be `{ name: "<SECRET_NAME>" }`.');
171
+ }
172
+ // Under `kindgi dev`, secrets resolve in `local`: the pack's env files.
173
+ const input = (ref === undefined
174
+ ? spec
175
+ : {
176
+ ...spec,
177
+ secret_ref: { envName: LOCAL_ENV_NAME, ...ref },
178
+ });
179
+ return { kind: 'ok', provider: { id: metadata.id, input } };
180
+ }
181
+ /** Where `kindgi dev` records which providers this pack registered. */
182
+ export function devProvidersRecordPath(packDir) {
183
+ return join(packDir, '.kindgi', 'dev', 'providers.json');
184
+ }
185
+ /**
186
+ * The record's key: the runtime (`DevProvidersTarget`; never credentials)
187
+ * and the tenant. Another runtime, or a new tenant, starts with nothing
188
+ * owned.
189
+ */
190
+ export function devProvidersKey(target, tenantId) {
191
+ if (target.kind === 'runtime')
192
+ return `runtime ${originOf(target.url)} tenant ${tenantId}`;
193
+ if (target.kind === 'bundled')
194
+ return `bundled ${target.database} tenant ${tenantId}`;
195
+ return `${databaseOf(target.url)} tenant ${tenantId}`;
196
+ }
197
+ function originOf(url) {
198
+ try {
199
+ return new URL(url).origin;
200
+ }
201
+ catch {
202
+ return url;
203
+ }
204
+ }
205
+ function databaseOf(databaseUrl) {
206
+ if (databaseUrl === undefined)
207
+ return 'unknown';
208
+ try {
209
+ const url = new URL(databaseUrl);
210
+ return `${url.hostname}:${url.port === '' ? '5432' : url.port}${url.pathname}`;
211
+ }
212
+ catch {
213
+ return createHash('sha256').update(databaseUrl).digest('hex').slice(0, 16);
214
+ }
215
+ }
216
+ /**
217
+ * Up to 0.1.3 the bundled Postgres's entries were keyed on its host and
218
+ * port (`127.0.0.1:<port>/<database> tenant <id>`, a loopback host), and the port changes
219
+ * when the container comes back. Moves such entries for this database and
220
+ * tenant to the `bundled` key, once: else the providers this pack
221
+ * registered would read as someone else's. A one-time migration of a
222
+ * local file: remove it after 0.1.5.
223
+ */
224
+ export async function adoptLegacyBundledEntries(path, database, tenantId) {
225
+ const file = await readRecordFile(path);
226
+ if (file === undefined)
227
+ return;
228
+ const key = devProvidersKey({ kind: 'bundled', database }, tenantId);
229
+ if (file.runtimes[key] !== undefined)
230
+ return;
231
+ const legacy = Object.keys(file.runtimes).filter((k) => isLegacyBundledKey(k, database, tenantId));
232
+ if (legacy.length === 0)
233
+ return;
234
+ const runtimes = { ...file.runtimes };
235
+ const adopted = {};
236
+ for (const k of legacy) {
237
+ Object.assign(adopted, runtimes[k]);
238
+ delete runtimes[k];
239
+ }
240
+ runtimes[key] = adopted;
241
+ await writeRecordFile(path, { v: 1, runtimes });
242
+ }
243
+ function isLegacyBundledKey(key, database, tenantId) {
244
+ const suffix = `/${database} tenant ${tenantId}`;
245
+ if (!key.endsWith(suffix))
246
+ return false;
247
+ // The bundled Postgres is on this machine; a database elsewhere was named.
248
+ return /^(127\.0\.0\.1|localhost|\[::1\]):\d+$/.test(key.slice(0, -suffix.length));
249
+ }
250
+ /** This pack's providers in that runtime and tenant; nothing when the record is missing or unreadable. */
251
+ export async function readOwnedProviders(path, key) {
252
+ const file = await readRecordFile(path);
253
+ return file?.runtimes[key] ?? {};
254
+ }
255
+ export async function writeOwnedProviders(path, key, owned) {
256
+ const file = await readRecordFile(path);
257
+ const runtimes = { ...(file?.runtimes ?? {}) };
258
+ if (Object.keys(owned).length === 0)
259
+ delete runtimes[key];
260
+ else
261
+ runtimes[key] = owned;
262
+ if (file === undefined && Object.keys(runtimes).length === 0)
263
+ return;
264
+ await writeRecordFile(path, { v: 1, runtimes });
265
+ }
266
+ async function writeRecordFile(path, next) {
267
+ await mkdir(dirname(path), { recursive: true });
268
+ const tmp = `${path}.${process.pid}.tmp`;
269
+ await writeFile(tmp, `${JSON.stringify(next, null, 2)}\n`, 'utf8');
270
+ await rename(tmp, path);
271
+ }
272
+ async function readRecordFile(path) {
273
+ let text;
274
+ try {
275
+ text = await readFile(path, 'utf8');
276
+ }
277
+ catch {
278
+ return undefined;
279
+ }
280
+ try {
281
+ const parsed = JSON.parse(text);
282
+ if (isRecord(parsed) && parsed.v === 1 && isRecord(parsed.runtimes)) {
283
+ return parsed;
284
+ }
285
+ }
286
+ catch {
287
+ // A record that can't be read owns nothing: providers are then left alone.
288
+ }
289
+ return undefined;
290
+ }
291
+ /** Bring the runtime's providers in step with the config's. Throws only when they can't be listed. */
292
+ export async function reconcileProviders(inputs) {
293
+ const runtime = new Map((await inputs.client.list()).map((p) => [p.id, p]));
294
+ const owned = {};
295
+ const outcomes = [];
296
+ const toRecord = [];
297
+ for (const provider of inputs.declared) {
298
+ const step = await reconcileDeclared(provider, runtime.get(provider.id), inputs);
299
+ outcomes.push(step.outcome);
300
+ if (step.keep !== undefined)
301
+ owned[provider.id] = step.keep;
302
+ if (step.registered)
303
+ toRecord.push(provider);
304
+ }
305
+ // This pack's providers its config no longer declares.
306
+ for (const [id, before] of Object.entries(inputs.owned)) {
307
+ if (inputs.declared.some((p) => p.id === id))
308
+ continue;
309
+ const step = await removeUndeclared(id, before, runtime.get(id), inputs.client);
310
+ if (step.outcome !== undefined)
311
+ outcomes.push(step.outcome);
312
+ if (step.keep !== undefined)
313
+ owned[id] = step.keep;
314
+ }
315
+ Object.assign(owned, await recordRegistered(toRecord, inputs.client));
316
+ return { outcomes, owned };
317
+ }
318
+ /**
319
+ * A provider this pack registered and its config no longer declares:
320
+ * unregistered when it is as this pack registered it, else left.
321
+ */
322
+ async function removeUndeclared(id, before, current, client) {
323
+ if (current === undefined)
324
+ return {};
325
+ if (hashOf(current) !== before.registered)
326
+ return { outcome: { id, kind: 'released' } };
327
+ try {
328
+ await client.unregister(id);
329
+ return { outcome: { id, kind: 'removed' } };
330
+ }
331
+ catch (err) {
332
+ return { outcome: { id, kind: 'failed', message: messageOf(err) }, keep: before };
333
+ }
334
+ }
335
+ /**
336
+ * The record entries for providers registered now, as the runtime lists
337
+ * them: that is what "still this pack's" is checked against. Not listed,
338
+ * they aren't recorded, and the next boot leaves them as they are.
339
+ */
340
+ async function recordRegistered(registered, client) {
341
+ if (registered.length === 0)
342
+ return {};
343
+ const after = await client.list().then((all) => new Map(all.map((p) => [p.id, p])), () => new Map());
344
+ const owned = {};
345
+ for (const provider of registered) {
346
+ const listed = after.get(provider.id);
347
+ if (listed !== undefined) {
348
+ owned[provider.id] = { declared: hashOf(provider.input), registered: hashOf(listed) };
349
+ }
350
+ }
351
+ return owned;
352
+ }
353
+ /** One declared provider against the runtime's `current`. */
354
+ async function reconcileDeclared(provider, current, inputs) {
355
+ const { id } = provider;
356
+ const before = inputs.owned[id];
357
+ // This pack's: registered by it, and as it registered it.
358
+ const mine = current !== undefined && before?.registered === hashOf(current) ? before : undefined;
359
+ if (current !== undefined && mine === undefined) {
360
+ return {
361
+ outcome: { id, kind: covers(provider.input.metadata, current) ? 'present' : 'conflict' },
362
+ };
363
+ }
364
+ const keep = mine !== undefined ? { keep: mine } : {};
365
+ if (mine !== undefined && mine.declared === hashOf(provider.input)) {
366
+ return { outcome: { id, kind: 'unchanged' }, ...keep };
367
+ }
368
+ const ref = provider.input.secret_ref;
369
+ if (ref !== undefined && ref.envName === LOCAL_ENV_NAME && !inputs.hasSecret(ref.name)) {
370
+ return { outcome: { id, kind: 'skipped', secret: ref.name }, ...keep };
371
+ }
372
+ // There's no update: a changed provider is unregistered, then registered.
373
+ try {
374
+ if (mine !== undefined)
375
+ await inputs.client.unregister(id);
376
+ }
377
+ catch (err) {
378
+ return { outcome: { id, kind: 'failed', message: messageOf(err) }, ...keep };
379
+ }
380
+ try {
381
+ await inputs.client.register(provider.input);
382
+ return {
383
+ outcome: { id, kind: mine !== undefined ? 'updated' : 'registered' },
384
+ registered: true,
385
+ };
386
+ }
387
+ catch (err) {
388
+ return { outcome: { id, kind: 'failed', message: messageOf(err) } };
389
+ }
390
+ }
391
+ /** The boot log's lines for a reconcile; none when the config declares nothing and nothing changed. */
392
+ export function describeReconcile(outcomes, inputs) {
393
+ if (outcomes.length === 0)
394
+ return [];
395
+ const unchanged = outcomes.filter((o) => o.kind === 'unchanged').map((o) => o.id);
396
+ if (unchanged.length === outcomes.length) {
397
+ return [`✓ Providers from ${inputs.file}: ${unchanged.join(', ')} (unchanged)`];
398
+ }
399
+ const unregister = (id) => `${inputs.kindgi('providers', 'unregister', id)}, then restart kindgi dev`;
400
+ const lines = [`Providers from ${inputs.file}:`];
401
+ if (unchanged.length > 0)
402
+ lines.push(` · ${unchanged.join(', ')}: unchanged`);
403
+ for (const o of outcomes) {
404
+ switch (o.kind) {
405
+ case 'unchanged':
406
+ break;
407
+ case 'registered':
408
+ lines.push(` ✓ ${o.id}: registered`);
409
+ break;
410
+ case 'updated':
411
+ lines.push(` ✓ ${o.id}: registered again (changed in ${inputs.file})`);
412
+ break;
413
+ case 'removed':
414
+ lines.push(` ✓ ${o.id}: unregistered (no longer in ${inputs.file})`);
415
+ break;
416
+ case 'present':
417
+ lines.push(` · ${o.id}: registered already, not from ${inputs.file}, with the same models (its adapter settings and key aren't listed to compare); left as it is. For the config's: ${unregister(o.id)}`);
418
+ break;
419
+ case 'conflict':
420
+ lines.push(` ⚠ ${o.id}: registered already, not from ${inputs.file}, with another region or models; left as it is. For the config's: ${unregister(o.id)}`);
421
+ break;
422
+ case 'released':
423
+ lines.push(` · ${o.id}: changed in the runtime since kindgi dev registered it; left as it is`);
424
+ break;
425
+ case 'skipped':
426
+ lines.push(` ⚠ ${o.id}: not registered: ${o.secret} is not in ${inputs.envFiles}. Set it (${inputs.kindgi('secrets', 'set', o.secret, `--env=${LOCAL_ENV_NAME}`, '--scope=tenant')}), then restart kindgi dev`);
427
+ break;
428
+ case 'failed':
429
+ lines.push(` ✗ ${o.id}: ${o.message}`);
430
+ break;
431
+ }
432
+ }
433
+ return lines;
434
+ }
435
+ function hashOf(value) {
436
+ return `sha256:${createHash('sha256').update(stableStringify(value)).digest('hex')}`;
437
+ }
438
+ /** Whether everything `expected` says, `actual` says too (the runtime may add defaults). */
439
+ function covers(expected, actual) {
440
+ if (Array.isArray(expected)) {
441
+ return (Array.isArray(actual) &&
442
+ expected.length === actual.length &&
443
+ expected.every((item, i) => covers(item, actual[i])));
444
+ }
445
+ if (isRecord(expected)) {
446
+ return isRecord(actual) && Object.entries(expected).every(([k, v]) => covers(v, actual[k]));
447
+ }
448
+ return expected === actual;
449
+ }
450
+ function messageOf(err) {
451
+ return err instanceof Error ? err.message : String(err);
452
+ }
453
+ function isRecord(value) {
454
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
455
+ }
456
+ //# sourceMappingURL=providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.js","sourceRoot":"","sources":["../../src/dev/providers.ts"],"names":[],"mappings":"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"}
@@ -7,9 +7,15 @@ export interface PythonPackBuilderOptions {
7
7
  /** The pack's environment. */
8
8
  readonly env: () => Promise<Readonly<Record<string, string>>>;
9
9
  readonly debounceMs?: number;
10
+ /** How often the sources are also scanned (`fs.watch` can miss events). */
11
+ readonly scanIntervalMs?: number;
10
12
  /** Test seam: `node:fs.watch`. */
11
13
  readonly watchFs?: typeof watch;
14
+ /** Test seam: what the sources are now (`pythonSourcesSignature`). */
15
+ readonly scanSources?: () => Promise<string>;
12
16
  }
17
+ /** The sources a build reads, with their mtimes and sizes (`scan-backstop.ts`). */
18
+ export declare function pythonSourcesSignature(packDir: string): Promise<string>;
13
19
  /** Whether a change to `relPath` (relative to the pack root) is a change to the pack's code. */
14
20
  export declare function isPythonSourceChange(relPath: string): boolean;
15
21
  export declare function createPythonPackBuilder(options: PythonPackBuilderOptions): PackBuilder;
@@ -1 +1 @@
1
- {"version":3,"file":"python-builder.d.ts","sourceRoot":"","sources":["../../src/dev/python-builder.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAkB,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhD,OAAO,KAAK,EAAa,WAAW,EAAE,MAAM,cAAc,CAAC;AAgC3D,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IAChD,8BAA8B;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAC9D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,kCAAkC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACjC;AAED,gGAAgG;AAChG,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAM7D;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,wBAAwB,GAAG,WAAW,CAmEtF"}
1
+ {"version":3,"file":"python-builder.d.ts","sourceRoot":"","sources":["../../src/dev/python-builder.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAkB,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhD,OAAO,KAAK,EAAa,WAAW,EAAE,MAAM,cAAc,CAAC;AAsC3D,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IAChD,8BAA8B;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAC9D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,kCAAkC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IAChC,sEAAsE;IACtE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9C;AAED,mFAAmF;AACnF,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOvE;AAED,gGAAgG;AAChG,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAM7D;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,wBAAwB,GAAG,WAAW,CAiFtF"}
@@ -9,10 +9,12 @@
9
9
  * service and index in place, as a bundle error does.
10
10
  *
11
11
  * The watch covers any `.py` file under the pack root — shared modules
12
- * outside the discovery folders included — and `pyproject.toml`.
12
+ * outside the discovery folders included — and `pyproject.toml`, with a
13
+ * scan behind it (`scan-backstop.ts`): `fs.watch` can drop events.
13
14
  */
14
15
  import { spawn } from 'node:child_process';
15
16
  import { watch } from 'node:fs';
17
+ import { DEFAULT_SCAN_INTERVAL_MS, scanSignature, startScanBackstop, } from './scan-backstop.js';
16
18
  const SKIPPED_DIRS = ['__pycache__', 'node_modules', 'venv', 'site-packages'];
17
19
  const DEFAULT_DEBOUNCE_MS = 150;
18
20
  /**
@@ -41,6 +43,15 @@ for dirpath, dirnames, filenames in os.walk(root):
41
43
  errors.append({"file": rel, "line": 0, "col": 0, "message": f"{type(e).__name__}: {e}"})
42
44
  print(json.dumps(errors))
43
45
  `;
46
+ /** The sources a build reads, with their mtimes and sizes (`scan-backstop.ts`). */
47
+ export function pythonSourcesSignature(packDir) {
48
+ return scanSignature({
49
+ folders: [{ abs: packDir, rel: '' }],
50
+ includes: isPythonSourceChange,
51
+ // Exactly the folders `isPythonSourceChange` never counts.
52
+ skipDir: (name) => name.startsWith('.') || SKIPPED_DIRS.includes(name),
53
+ });
54
+ }
44
55
  /** Whether a change to `relPath` (relative to the pack root) is a change to the pack's code. */
45
56
  export function isPythonSourceChange(relPath) {
46
57
  const segments = relPath.split(/[\\/]/);
@@ -52,7 +63,9 @@ export function isPythonSourceChange(relPath) {
52
63
  }
53
64
  export function createPythonPackBuilder(options) {
54
65
  const watchFs = options.watchFs ?? watch;
66
+ const scan = options.scanSources ?? (() => pythonSourcesSignature(options.packDir));
55
67
  let watcher;
68
+ let backstop;
56
69
  let timer;
57
70
  async function build() {
58
71
  const [program, ...prefix] = options.python;
@@ -98,15 +111,25 @@ export function createPythonPackBuilder(options) {
98
111
  async watch(onBuild) {
99
112
  if (watcher !== undefined)
100
113
  return;
101
- watcher = watchFs(options.packDir, { recursive: true }, (_event, filename) => {
102
- if (filename === null || !isPythonSourceChange(filename.toString()))
103
- return;
114
+ const schedule = () => {
104
115
  if (timer !== undefined)
105
116
  clearTimeout(timer);
106
117
  timer = setTimeout(() => {
107
118
  timer = undefined;
108
- void build().then(onBuild);
119
+ // This build reads the sources as they are now: the scan then
120
+ // fires only for later changes.
121
+ void (backstop?.mark() ?? Promise.resolve()).then(build).then(onBuild);
109
122
  }, options.debounceMs ?? DEFAULT_DEBOUNCE_MS);
123
+ };
124
+ watcher = watchFs(options.packDir, { recursive: true }, (_event, filename) => {
125
+ if (filename === null || !isPythonSourceChange(filename.toString()))
126
+ return;
127
+ schedule();
128
+ });
129
+ backstop = await startScanBackstop({
130
+ scan,
131
+ intervalMs: options.scanIntervalMs ?? DEFAULT_SCAN_INTERVAL_MS,
132
+ onChange: schedule,
110
133
  });
111
134
  },
112
135
  // New or removed files need no entry list: the next build sees what is there.
@@ -114,6 +137,8 @@ export function createPythonPackBuilder(options) {
114
137
  async dispose() {
115
138
  if (timer !== undefined)
116
139
  clearTimeout(timer);
140
+ backstop?.stop();
141
+ backstop = undefined;
117
142
  watcher?.close();
118
143
  watcher = undefined;
119
144
  },
@@ -1 +1 @@
1
- {"version":3,"file":"python-builder.js","sourceRoot":"","sources":["../../src/dev/python-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"python-builder.js","sourceRoot":"","sources":["../../src/dev/python-builder.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,8 @@
7
7
  * `runIndexer` (`@kindgi/handler-runtime`), and an `fs.watch` bridge.
8
8
  */
9
9
  import type { PackServiceSupervisor, PackServiceSupervisorEvent } from '@kindgi/handler-runtime/pack-service';
10
+ import type { ProjectDatabases } from './project-database.js';
11
+ import type { ProjectOutcome } from './project.js';
10
12
  import type { PackCode } from './pack-code.js';
11
13
  /** The running Kindgi runtime `kindgi dev` talks to. */
12
14
  export interface RunningApiServer {
@@ -37,6 +39,11 @@ export interface RunningApiServer {
37
39
  export interface StartApiServerOptions {
38
40
  /** The host port the API is reached on (`127.0.0.1` only). */
39
41
  readonly port: number;
42
+ /**
43
+ * `kindgi dev`'s stop (Ctrl+C, SIGTERM): a wait for the runtime ends at
44
+ * once with `RuntimeStartStopped`, and a container it started is removed.
45
+ */
46
+ readonly signal?: AbortSignal;
40
47
  /** Postgres, as this machine reaches it. */
41
48
  readonly databaseUrl: string;
42
49
  readonly tenantId: string;
@@ -217,6 +224,12 @@ export interface StartedServicesHandle {
217
224
  readonly startedWith: 'docker compose' | 'docker';
218
225
  /** What the developer should know about this start: a flag that needs compose. */
219
226
  readonly notes?: readonly string[];
227
+ /**
228
+ * The project databases in this Postgres (`project-database.ts`): each
229
+ * project gets one, and the runtime connects to it. Absent: the shared
230
+ * `databaseUrl` is used as is.
231
+ */
232
+ readonly projectDatabases?: ProjectDatabases;
220
233
  }
221
234
  /**
222
235
  * Outcome of `startServices`. `kind: 'ok'` = started (with docker
@@ -308,5 +321,14 @@ export interface DevRunners {
308
321
  readonly startServices?: (options: {
309
322
  readonly recreate: boolean;
310
323
  }) => Promise<StartServicesResult>;
324
+ /** Resolve the project (default: `resolveDevProject`, with git). Tests pass their own. */
325
+ readonly resolveProject?: (input: {
326
+ readonly packDir: string;
327
+ readonly configured: unknown;
328
+ }) => Promise<ProjectOutcome>;
329
+ /** Whether there's a person at a terminal to ask (default: stdin and stderr are TTYs). */
330
+ readonly interactive?: () => boolean;
331
+ /** Ask a yes/no question (default: on the terminal). */
332
+ readonly confirm?: (question: string) => Promise<boolean>;
311
333
  }
312
334
  //# sourceMappingURL=runners.d.ts.map