@nzpr/kb 0.1.10 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -10
- package/lib/cli-common.js +5 -3
- package/lib/cli.js +27 -144
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -169,14 +169,7 @@ export KB_EMBEDDING_API_KEY=...
|
|
|
169
169
|
|
|
170
170
|
If `KB_EMBEDDING_MODE` is omitted, the CLI uses local hash embeddings for development.
|
|
171
171
|
|
|
172
|
-
Publishing
|
|
173
|
-
|
|
174
|
-
```bash
|
|
175
|
-
export KB_GITHUB_REPO=owner/repo
|
|
176
|
-
export GITHUB_TOKEN=...
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
Publishing is allowed when the provided `GITHUB_TOKEN` can read `KB_GITHUB_REPO`. Normal readers do not need GitHub credentials.
|
|
172
|
+
Publishing uses the local docs directory and the database only. It does not need GitHub credentials.
|
|
180
173
|
|
|
181
174
|
When `kb init-repo` is given `--repo`, it uses the same token to:
|
|
182
175
|
|
|
@@ -194,8 +187,6 @@ If you run `kb init-repo` without the repo or database inputs, it still scaffold
|
|
|
194
187
|
|
|
195
188
|
```bash
|
|
196
189
|
export KB_DATABASE_URL=postgresql://kb:kb@localhost:5432/kb
|
|
197
|
-
export KB_GITHUB_REPO=owner/repo
|
|
198
|
-
export GITHUB_TOKEN=...
|
|
199
190
|
docker compose -f docker-compose.pgvector.yml up -d
|
|
200
191
|
kb publish --docs-root ./docs
|
|
201
192
|
kb catalog --json
|
package/lib/cli-common.js
CHANGED
|
@@ -67,7 +67,9 @@ optional GitHub API override:
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
export function publishHelp() {
|
|
70
|
-
return `
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
return `publish runtime:
|
|
71
|
+
KB_DATABASE_URL=postgresql://USER:PASSWORD@HOST:5432/DB
|
|
72
|
+
|
|
73
|
+
publish reads local docs and writes to the database.
|
|
74
|
+
GitHub credentials are not required.`;
|
|
73
75
|
}
|
package/lib/cli.js
CHANGED
|
@@ -102,9 +102,7 @@ export async function main(argv) {
|
|
|
102
102
|
console.log("no files created");
|
|
103
103
|
}
|
|
104
104
|
printInitRepoStatus(result);
|
|
105
|
-
printRepoConfiguration(result.configuration);
|
|
106
105
|
printInitRepoNextStep(result);
|
|
107
|
-
printInitRepoChecklist(result);
|
|
108
106
|
return result.ok ? 0 : 1;
|
|
109
107
|
}
|
|
110
108
|
case "search": {
|
|
@@ -167,14 +165,6 @@ export async function main(argv) {
|
|
|
167
165
|
return 0;
|
|
168
166
|
}
|
|
169
167
|
case "publish": {
|
|
170
|
-
const repo = flags.repo ?? resolveGitHubRepository();
|
|
171
|
-
const apiBaseUrl = resolveGitHubApiBaseUrl();
|
|
172
|
-
const token = process.env.GITHUB_TOKEN ?? null;
|
|
173
|
-
await requirePublishAccess({
|
|
174
|
-
repo,
|
|
175
|
-
token,
|
|
176
|
-
apiBaseUrl
|
|
177
|
-
});
|
|
178
168
|
const knowledgeRoot = flags["knowledge-root"]
|
|
179
169
|
? path.resolve(flags["knowledge-root"])
|
|
180
170
|
: tryResolveKnowledgeRoot();
|
|
@@ -280,7 +270,7 @@ function printCommandHelp(command) {
|
|
|
280
270
|
ask: `usage: kb ask <question> [options]\n\n${databaseHelp()}\n --limit N`,
|
|
281
271
|
list: `usage: kb list\n\n${databaseHelp()}`,
|
|
282
272
|
catalog: `usage: kb catalog [--json]\n\n${databaseHelp()}`,
|
|
283
|
-
publish: `usage: kb publish [--docs-root PATH] [--knowledge-root PATH]
|
|
273
|
+
publish: `usage: kb publish [--docs-root PATH] [--knowledge-root PATH]\n\n${databaseHelp()}\n\n${publishHelp()}`,
|
|
284
274
|
doctor: `usage: kb doctor [--knowledge-root PATH] [--docs-root PATH]\n\n${databaseHelp()}`
|
|
285
275
|
};
|
|
286
276
|
console.log(commandHelp[command] ?? `unknown command: ${command}`);
|
|
@@ -294,68 +284,8 @@ function requireDatabaseUrl() {
|
|
|
294
284
|
return databaseUrl;
|
|
295
285
|
}
|
|
296
286
|
|
|
297
|
-
async function requirePublishAccess({ repo, token, apiBaseUrl }) {
|
|
298
|
-
if (!repo) {
|
|
299
|
-
throw new Error("KB_GITHUB_REPO or --repo OWNER/REPO is required to publish knowledge");
|
|
300
|
-
}
|
|
301
|
-
if (!token) {
|
|
302
|
-
throw new Error("GITHUB_TOKEN is required to publish knowledge");
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
const response = await fetch(`${apiBaseUrl.replace(/\/$/, "")}/repos/${repo}`, {
|
|
306
|
-
headers: {
|
|
307
|
-
accept: "application/vnd.github+json",
|
|
308
|
-
authorization: `Bearer ${token}`,
|
|
309
|
-
"user-agent": "@nzpr/kb"
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
if (!response.ok) {
|
|
314
|
-
const errorText = await response.text().catch(() => "");
|
|
315
|
-
throw new Error(
|
|
316
|
-
`failed to verify GitHub repo access: ${response.status} ${response.statusText}${errorText ? ` - ${errorText}` : ""}`
|
|
317
|
-
);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
const payload = await response.json();
|
|
321
|
-
const permissions = payload?.permissions ?? null;
|
|
322
|
-
if (!permissions) {
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
if (permissions.admin || permissions.maintain || permissions.push || permissions.triage || permissions.pull) {
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
throw new Error(`GITHUB_TOKEN does not have repository access to ${repo}`);
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
function printRepoConfiguration(configuration) {
|
|
332
|
-
console.log("");
|
|
333
|
-
console.log("configuration reference:");
|
|
334
|
-
console.log("");
|
|
335
|
-
console.log("required secrets:");
|
|
336
|
-
for (const entry of configuration.requiredSecrets) {
|
|
337
|
-
console.log(` ${entry.name} - ${entry.purpose}`);
|
|
338
|
-
}
|
|
339
|
-
console.log("");
|
|
340
|
-
console.log("optional secrets:");
|
|
341
|
-
for (const entry of configuration.optionalSecrets) {
|
|
342
|
-
console.log(` ${entry.name} - ${entry.purpose}`);
|
|
343
|
-
}
|
|
344
|
-
console.log("");
|
|
345
|
-
console.log("optional variables:");
|
|
346
|
-
for (const entry of configuration.optionalVariables) {
|
|
347
|
-
console.log(` ${entry.name}=${entry.value} - ${entry.purpose}`);
|
|
348
|
-
}
|
|
349
|
-
console.log("");
|
|
350
|
-
console.log("publish workflow auth:");
|
|
351
|
-
console.log(" KB_GITHUB_REPO is set automatically to github.repository in the scaffolded workflow");
|
|
352
|
-
console.log(" GITHUB_TOKEN is provided automatically by GitHub Actions and only needs repository read access for publish");
|
|
353
|
-
console.log(" the token used for kb init-repo itself must have admin access if you want the CLI to configure repo Actions settings")
|
|
354
|
-
}
|
|
355
|
-
|
|
356
287
|
function printInitRepoStatus(result) {
|
|
357
288
|
console.log("");
|
|
358
|
-
console.log("what happened:");
|
|
359
289
|
printInitRepoScaffoldStatus(result);
|
|
360
290
|
printInitRepoDatabaseStatus(result.database);
|
|
361
291
|
printInitRepoGitHubStatus(result.github);
|
|
@@ -364,118 +294,71 @@ function printInitRepoStatus(result) {
|
|
|
364
294
|
function printInitRepoScaffoldStatus(result) {
|
|
365
295
|
const reusedOnly = !result.created.length && result.skipped.length > 0;
|
|
366
296
|
if (reusedOnly) {
|
|
367
|
-
console.log(`
|
|
297
|
+
console.log(`scaffold: reused existing files in ${result.root}`);
|
|
368
298
|
} else if (result.created.length) {
|
|
369
|
-
console.log(`
|
|
299
|
+
console.log(`scaffold: created or updated files in ${result.root}`);
|
|
370
300
|
} else {
|
|
371
|
-
console.log(`
|
|
301
|
+
console.log(`scaffold: nothing changed in ${result.root}`);
|
|
372
302
|
}
|
|
373
|
-
console.log(`
|
|
374
|
-
console.log(` files: created=${result.created.length} kept=${result.skipped.length}`);
|
|
303
|
+
console.log(`docs: ${result.docsRootRelative}/`);
|
|
375
304
|
}
|
|
376
305
|
|
|
377
306
|
function printInitRepoDatabaseStatus(database) {
|
|
378
307
|
if (database.status === "verified") {
|
|
379
|
-
console.log(
|
|
380
|
-
` database: verified ${database.database} current=${database.currentVersion} applied=${database.appliedCount}`
|
|
381
|
-
);
|
|
308
|
+
console.log(`database: ok ${database.database} current=${database.currentVersion} applied=${database.appliedCount}`);
|
|
382
309
|
return;
|
|
383
310
|
}
|
|
384
311
|
if (database.status === "failed") {
|
|
385
|
-
|
|
386
|
-
console.log(` database: attempted verification${target}`);
|
|
387
|
-
console.log(` database result: failed - ${formatCliError(new Error(database.error))}`);
|
|
388
|
-
console.log(" database effect: no schema changes were confirmed");
|
|
312
|
+
console.log(`database: failed - ${formatCliError(new Error(database.error))}`);
|
|
389
313
|
return;
|
|
390
314
|
}
|
|
391
|
-
|
|
392
|
-
console.log(` database: pending verification for ${database.target}`);
|
|
393
|
-
}
|
|
394
|
-
console.log(` database result: pending - ${database.message}`);
|
|
315
|
+
console.log("database: skipped");
|
|
395
316
|
}
|
|
396
317
|
|
|
397
318
|
function printInitRepoGitHubStatus(github) {
|
|
398
319
|
if (github.status === "configured") {
|
|
399
|
-
console.log(`
|
|
320
|
+
console.log(`github: ok ${github.repo}`);
|
|
400
321
|
if (github.actions) {
|
|
401
322
|
console.log(
|
|
402
|
-
`
|
|
323
|
+
`github actions: enabled=${github.actions.enabled} workflow_permissions=${github.actions.defaultWorkflowPermissions} pr_creation=${github.actions.canApprovePullRequestReviews}`
|
|
403
324
|
);
|
|
404
325
|
}
|
|
405
|
-
console.log(` github labels: ${github.labels.join(", ")}`);
|
|
406
|
-
if (github.secrets.length) {
|
|
407
|
-
console.log(` github secrets: ${github.secrets.join(", ")}`);
|
|
408
|
-
}
|
|
409
|
-
if (github.variables.length) {
|
|
410
|
-
console.log(` github variables: ${github.variables.join(", ")}`);
|
|
411
|
-
}
|
|
412
326
|
return;
|
|
413
327
|
}
|
|
414
328
|
if (github.status === "failed") {
|
|
415
|
-
|
|
416
|
-
console.log(` github: attempted repo bootstrap${repo}`);
|
|
417
|
-
console.log(` github result: failed - ${github.error}`);
|
|
329
|
+
console.log(`github: failed - ${github.error}`);
|
|
418
330
|
return;
|
|
419
331
|
}
|
|
420
|
-
|
|
421
|
-
console.log(` github: pending bootstrap for ${github.repo}`);
|
|
422
|
-
}
|
|
423
|
-
console.log(` github result: ${github.status} - ${github.message}`);
|
|
332
|
+
console.log("github: skipped");
|
|
424
333
|
}
|
|
425
334
|
|
|
426
335
|
function printInitRepoNextStep(result) {
|
|
427
|
-
const failures = [];
|
|
428
|
-
if (result.database.status === "failed") {
|
|
429
|
-
failures.push("database verification failed");
|
|
430
|
-
}
|
|
431
|
-
if (result.github.status === "failed") {
|
|
432
|
-
failures.push("GitHub bootstrap failed");
|
|
433
|
-
}
|
|
434
|
-
|
|
435
336
|
if (!result.ok) {
|
|
436
337
|
console.log("");
|
|
437
|
-
console.log(
|
|
438
|
-
|
|
439
|
-
|
|
338
|
+
console.log("next:");
|
|
339
|
+
if (result.database.status === "failed") {
|
|
340
|
+
console.log(" fix the database connection and rerun kb init-repo");
|
|
341
|
+
}
|
|
342
|
+
if (result.github.status === "failed") {
|
|
343
|
+
console.log(" fix GitHub access or repo settings and rerun kb init-repo");
|
|
344
|
+
}
|
|
440
345
|
return;
|
|
441
346
|
}
|
|
442
347
|
if (result.database.status === "verified" && result.github.status === "configured") {
|
|
443
348
|
console.log("");
|
|
444
|
-
console.log("next:
|
|
349
|
+
console.log("next:");
|
|
350
|
+
console.log(" create a knowledge proposal with kb create");
|
|
351
|
+
console.log(" add kb-approved to open the PR");
|
|
352
|
+
console.log(" merge the PR and let publish sync the database");
|
|
445
353
|
return;
|
|
446
354
|
}
|
|
447
355
|
console.log("");
|
|
448
|
-
console.log(
|
|
449
|
-
"next: rerun kb init-repo with the missing repo or database inputs when you are ready, or commit the scaffold now and finish remote setup later"
|
|
450
|
-
);
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
function printInitRepoChecklist(result) {
|
|
454
|
-
console.log("");
|
|
455
|
-
console.log("next steps:");
|
|
456
|
-
const steps = [];
|
|
457
|
-
if (result.created.length || result.skipped.length) {
|
|
458
|
-
steps.push(`commit and push the scaffolded knowledge repo files, including ${result.docsRootRelative}/`);
|
|
459
|
-
}
|
|
356
|
+
console.log("next:");
|
|
460
357
|
if (result.github.status !== "configured") {
|
|
461
|
-
|
|
358
|
+
console.log(" rerun init-repo with --repo and admin GitHub access");
|
|
462
359
|
}
|
|
463
360
|
if (result.database.status !== "verified") {
|
|
464
|
-
|
|
465
|
-
}
|
|
466
|
-
steps.push("use kb create to open a proposal issue for the first knowledge entry");
|
|
467
|
-
steps.push("review the issue, add kb-approved, merge the generated PR, and let publish sync the live KB");
|
|
468
|
-
steps.forEach((step, index) => {
|
|
469
|
-
console.log(` ${index + 1}. ${step}`);
|
|
470
|
-
});
|
|
471
|
-
console.log("");
|
|
472
|
-
console.log("changes in this run:");
|
|
473
|
-
if (result.created.length) {
|
|
474
|
-
console.log(` created files: ${result.created.join(", ")}`);
|
|
475
|
-
} else {
|
|
476
|
-
console.log(" created files: none");
|
|
477
|
-
}
|
|
478
|
-
if (result.skipped.length) {
|
|
479
|
-
console.log(` kept existing files: ${result.skipped.join(", ")}`);
|
|
361
|
+
console.log(" rerun init-repo with a reachable --database-url");
|
|
480
362
|
}
|
|
363
|
+
console.log(" after that, create a knowledge proposal with kb create");
|
|
481
364
|
}
|