cngkit 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -2
- package/dist/cli.cjs +310 -1
- package/dist/cli.cjs.map +1 -1
- package/package.json +15 -16
package/README.md
CHANGED
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
# cngkit
|
|
2
2
|
|
|
3
|
-
Opinionated Curly.ng CLI kit for repo sync and website tooling.
|
|
3
|
+
Opinionated Curly.ng CLI kit for repo sync, Harness knowledges, and website tooling.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
npx cngkit
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
The
|
|
9
|
+
The CLI provides a real-time repository sync room and a terminal front door to
|
|
10
|
+
the Cloudflare-backed Harness knowledges catalog:
|
|
10
11
|
|
|
11
12
|
- `cngkit share` starts a room from the current directory.
|
|
12
13
|
- `cngkit join <room-code>` joins another machine to that room.
|
|
13
14
|
- `cngkit login` opens Curly.ng login in a browser, or prints the URL in headless environments.
|
|
14
15
|
- `cngkit scrub [path]` scans a file or directory with TruffleHog and prints a redacted report.
|
|
15
16
|
- `cngkit scrub [path] --yes` rewrites detected secret values inline with `CNGKIT_SECRET` placeholders.
|
|
17
|
+
- `cngkit knowledges status` prints the remote catalog state.
|
|
18
|
+
- `cngkit knowledges audiences` lists available audience filters.
|
|
19
|
+
- `cngkit knowledges search <query>` runs semantic search against Cloudflare Vectorize.
|
|
20
|
+
- `cngkit knowledges list [query]` lists known subskills.
|
|
21
|
+
- `cngkit knowledges files [query]` lists uploaded catalog files.
|
|
22
|
+
- `cngkit knowledges read <file-path>` reads a catalog file excerpt.
|
|
23
|
+
- `cngkit knowledges grep <pattern>` searches catalog file contents.
|
|
24
|
+
- `cngkit knowledges glob [pattern]` lists catalog files by supported glob pattern.
|
|
16
25
|
- `.git/` and files ignored by the repo's `.gitignore` are not synced.
|
|
17
26
|
- Later changes override earlier changes for the MVP conflict rule.
|
|
18
27
|
|
|
@@ -24,6 +33,25 @@ brew install trufflehog
|
|
|
24
33
|
|
|
25
34
|
Inline masking is intentionally gated behind `--yes` because it rewrites files in place.
|
|
26
35
|
|
|
36
|
+
## Harness Knowledges
|
|
37
|
+
|
|
38
|
+
The `knowledges` command group reads the Cloudflare-backed Harness catalog from the
|
|
39
|
+
Curly API. These commands are read-only:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
cngkit knowledges status
|
|
43
|
+
cngkit knowledges audiences
|
|
44
|
+
cngkit knowledges search "cloudflare backend" --limit 3
|
|
45
|
+
cngkit knowledges files "vector search" --audience builders
|
|
46
|
+
cngkit knowledges read /libraries/lib-cloudflare/SUBSKILL.md --limit 80
|
|
47
|
+
cngkit knowledges grep Cloudflare --path /libraries/lib-cloudflare --output-mode files_with_matches
|
|
48
|
+
cngkit knowledges glob "**/*.md" --path /libraries/lib-cloudflare
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Add `--json` to any `knowledges` command when another tool should consume the
|
|
52
|
+
raw API response. `grep` also accepts `--output-mode <content|files_with_matches|count>`,
|
|
53
|
+
`--include <glob>`, `--context <n>`, and `--case-insensitive`.
|
|
54
|
+
|
|
27
55
|
This package is mostly personal tooling for Curly.ng. It is intentionally opinionated,
|
|
28
56
|
small, and practical rather than a general synchronization platform.
|
|
29
57
|
|
package/dist/cli.cjs
CHANGED
|
@@ -7443,7 +7443,7 @@ var logging;
|
|
|
7443
7443
|
// src/config.ts
|
|
7444
7444
|
var import_node_crypto = require("crypto");
|
|
7445
7445
|
var import_node_process = __toESM(require("process"), 1);
|
|
7446
|
-
var packageVersion = "1.
|
|
7446
|
+
var packageVersion = "1.1.0";
|
|
7447
7447
|
var defaultApiBaseUrl = "https://curly.ng";
|
|
7448
7448
|
function resolveApiBaseUrl(options) {
|
|
7449
7449
|
return options.apiBaseUrl ?? import_node_process.default.env.CNGKIT_API_BASE_URL ?? defaultApiBaseUrl;
|
|
@@ -24296,6 +24296,31 @@ async function waitForSessionClose(socket, watcher) {
|
|
|
24296
24296
|
}
|
|
24297
24297
|
|
|
24298
24298
|
// src/commands.ts
|
|
24299
|
+
async function runKnowledgesCommand(args, options, output, dependencies) {
|
|
24300
|
+
const [subcommand, ...subcommandArgs] = args ?? [];
|
|
24301
|
+
switch (subcommand) {
|
|
24302
|
+
case "status":
|
|
24303
|
+
return runKnowStatusCommand(options, output, dependencies);
|
|
24304
|
+
case "audiences":
|
|
24305
|
+
return runKnowAudiencesCommand(options, output, dependencies);
|
|
24306
|
+
case "search":
|
|
24307
|
+
return runKnowSearchCommand(optionalJoinedArgument(subcommandArgs), options, output, dependencies);
|
|
24308
|
+
case "list":
|
|
24309
|
+
return runKnowListCommand(optionalJoinedArgument(subcommandArgs), options, output, dependencies);
|
|
24310
|
+
case "files":
|
|
24311
|
+
return runKnowFilesCommand(optionalJoinedArgument(subcommandArgs), options, output, dependencies);
|
|
24312
|
+
case "read":
|
|
24313
|
+
return runKnowReadCommand(subcommandArgs[0], options, output, dependencies);
|
|
24314
|
+
case "grep":
|
|
24315
|
+
return runKnowGrepCommand(optionalJoinedArgument(subcommandArgs), options, output, dependencies);
|
|
24316
|
+
case "glob":
|
|
24317
|
+
return runKnowGlobCommand(optionalJoinedArgument(subcommandArgs), options, output, dependencies);
|
|
24318
|
+
default:
|
|
24319
|
+
throw new Error(
|
|
24320
|
+
"Missing knowledges command. Usage: cngkit knowledges <status|audiences|search|list|files|read|grep|glob>"
|
|
24321
|
+
);
|
|
24322
|
+
}
|
|
24323
|
+
}
|
|
24299
24324
|
async function runLoginCommand(options, output) {
|
|
24300
24325
|
const loginUrl = new URL("/login", resolveApiBaseUrl(options));
|
|
24301
24326
|
const loginUrlString = loginUrl.toString();
|
|
@@ -24344,6 +24369,172 @@ async function runScrubCommand(targetPath, options, output, dependencies) {
|
|
|
24344
24369
|
output.info(`Skipped ${result.skippedFindings} finding(s) outside the scrub root.`);
|
|
24345
24370
|
}
|
|
24346
24371
|
}
|
|
24372
|
+
async function runKnowStatusCommand(options, output, dependencies) {
|
|
24373
|
+
const api = dependencies?.api ?? createKnowledgesApi(options);
|
|
24374
|
+
const response = await api.getCatalog();
|
|
24375
|
+
if (options.json) {
|
|
24376
|
+
output.info(formatJson(response.data));
|
|
24377
|
+
return;
|
|
24378
|
+
}
|
|
24379
|
+
const latestRun = response.data.latestRun;
|
|
24380
|
+
const lines = [
|
|
24381
|
+
`Catalog: ${response.data.name}`,
|
|
24382
|
+
`Files: ${response.data.files}`,
|
|
24383
|
+
`Blobs: ${response.data.blobs}`,
|
|
24384
|
+
`Vectorize: ${response.data.vectorize.index} (${response.data.vectorize.binding})`
|
|
24385
|
+
];
|
|
24386
|
+
if (latestRun) {
|
|
24387
|
+
lines.push(`Latest run: ${latestRun.status} (${latestRun.id})`);
|
|
24388
|
+
if (latestRun.updated_at) {
|
|
24389
|
+
lines.push(`Updated: ${latestRun.updated_at}`);
|
|
24390
|
+
}
|
|
24391
|
+
} else {
|
|
24392
|
+
lines.push("Latest run: none");
|
|
24393
|
+
}
|
|
24394
|
+
output.info(lines.join("\n"));
|
|
24395
|
+
}
|
|
24396
|
+
async function runKnowAudiencesCommand(options, output, dependencies) {
|
|
24397
|
+
const api = dependencies?.api ?? createKnowledgesApi(options);
|
|
24398
|
+
const response = await api.listAudiences();
|
|
24399
|
+
if (options.json) {
|
|
24400
|
+
output.info(formatJson(response.data));
|
|
24401
|
+
return;
|
|
24402
|
+
}
|
|
24403
|
+
const lines = response.data.audiences.flatMap((audience) => [
|
|
24404
|
+
`${audience.id} - ${audience.label}`,
|
|
24405
|
+
` ${singleLine(audience.help)}`
|
|
24406
|
+
]);
|
|
24407
|
+
output.info(lines.length > 0 ? lines.join("\n") : "No audiences available.");
|
|
24408
|
+
}
|
|
24409
|
+
async function runKnowSearchCommand(query, options, output, dependencies) {
|
|
24410
|
+
if (!query) {
|
|
24411
|
+
throw new Error("Missing search query. Usage: cngkit knowledges search <query>");
|
|
24412
|
+
}
|
|
24413
|
+
const api = dependencies?.api ?? createKnowledgesApi(options);
|
|
24414
|
+
const response = await api.search(query, coerceLimit(options.limit, 5));
|
|
24415
|
+
if (options.json) {
|
|
24416
|
+
output.info(formatJson(response.data));
|
|
24417
|
+
return;
|
|
24418
|
+
}
|
|
24419
|
+
const lines = response.data.results.flatMap((result, index) => [
|
|
24420
|
+
`${index + 1}. ${result.title} (${result.subskillName})`,
|
|
24421
|
+
` score ${result.score.toFixed(3)} | ${result.path}`,
|
|
24422
|
+
` ${singleLine(result.description || result.contentPreview)}`
|
|
24423
|
+
]);
|
|
24424
|
+
output.info(lines.length > 0 ? lines.join("\n") : `No results for "${query}".`);
|
|
24425
|
+
}
|
|
24426
|
+
async function runKnowListCommand(query, options, output, dependencies) {
|
|
24427
|
+
const api = dependencies?.api ?? createKnowledgesApi(options);
|
|
24428
|
+
const response = await api.listSubskills();
|
|
24429
|
+
const limit = coerceLimit(options.limit, 25);
|
|
24430
|
+
const normalizedQuery = query?.toLowerCase();
|
|
24431
|
+
const subskills = response.data.subskills.filter((subskill) => {
|
|
24432
|
+
if (!normalizedQuery) {
|
|
24433
|
+
return true;
|
|
24434
|
+
}
|
|
24435
|
+
return [subskill.name, subskill.title, subskill.description, subskill.type].join(" ").toLowerCase().includes(normalizedQuery);
|
|
24436
|
+
}).slice(0, limit);
|
|
24437
|
+
if (options.json) {
|
|
24438
|
+
output.info(formatJson({ subskills, total: subskills.length }));
|
|
24439
|
+
return;
|
|
24440
|
+
}
|
|
24441
|
+
const lines = subskills.flatMap((subskill) => [
|
|
24442
|
+
`${subskill.name} [${subskill.type}]`,
|
|
24443
|
+
` ${subskill.title} | files ${subskill.fileCount} | rating ${subskill.rating}`,
|
|
24444
|
+
` ${singleLine(subskill.description)}`
|
|
24445
|
+
]);
|
|
24446
|
+
output.info(lines.length > 0 ? lines.join("\n") : "No matching subskills.");
|
|
24447
|
+
}
|
|
24448
|
+
async function runKnowFilesCommand(query, options, output, dependencies) {
|
|
24449
|
+
const api = dependencies?.api ?? createKnowledgesApi(options);
|
|
24450
|
+
const response = await api.listFiles({
|
|
24451
|
+
query,
|
|
24452
|
+
audience: normalizeAudienceId(options.audience),
|
|
24453
|
+
limit: coerceLimit(options.limit, 25)
|
|
24454
|
+
});
|
|
24455
|
+
if (options.json) {
|
|
24456
|
+
output.info(formatJson(response.data));
|
|
24457
|
+
return;
|
|
24458
|
+
}
|
|
24459
|
+
const lines = response.data.files.map((file2) => {
|
|
24460
|
+
const title = file2.display_title ?? file2.title ?? file2.subskill_name ?? "Untitled";
|
|
24461
|
+
return `${file2.path}
|
|
24462
|
+
${title}`;
|
|
24463
|
+
});
|
|
24464
|
+
output.info(lines.length > 0 ? lines.join("\n") : "No matching files.");
|
|
24465
|
+
}
|
|
24466
|
+
async function runKnowReadCommand(filePath, options, output, dependencies) {
|
|
24467
|
+
if (!filePath) {
|
|
24468
|
+
throw new Error("Missing file_path. Usage: cngkit knowledges read <file_path>");
|
|
24469
|
+
}
|
|
24470
|
+
const api = dependencies?.api ?? createKnowledgesApi(options);
|
|
24471
|
+
const response = await api.read({
|
|
24472
|
+
filePath: normalizeCatalogPath(filePath),
|
|
24473
|
+
offset: coerceOptionalNumber(options.offset),
|
|
24474
|
+
limit: coerceLimit(options.limit, 200, 2e3)
|
|
24475
|
+
});
|
|
24476
|
+
if (options.json) {
|
|
24477
|
+
output.info(formatJson(response.data));
|
|
24478
|
+
return;
|
|
24479
|
+
}
|
|
24480
|
+
output.info(response.data.content);
|
|
24481
|
+
if (response.data.truncated) {
|
|
24482
|
+
output.info(
|
|
24483
|
+
`[truncated: showing ${response.data.limit} lines from offset ${response.data.offset} of ${response.data.total_lines}]`
|
|
24484
|
+
);
|
|
24485
|
+
}
|
|
24486
|
+
}
|
|
24487
|
+
async function runKnowGrepCommand(pattern, options, output, dependencies) {
|
|
24488
|
+
if (!pattern) {
|
|
24489
|
+
throw new Error("Missing pattern. Usage: cngkit knowledges grep <pattern>");
|
|
24490
|
+
}
|
|
24491
|
+
const api = dependencies?.api ?? createKnowledgesApi(options);
|
|
24492
|
+
const response = await api.grep({
|
|
24493
|
+
pattern,
|
|
24494
|
+
path: normalizeCatalogPath(options.path ?? "/"),
|
|
24495
|
+
include: options.include ?? "*",
|
|
24496
|
+
mode: normalizeGrepMode(options.outputMode),
|
|
24497
|
+
context: coerceLimit(options.context, 0, 20),
|
|
24498
|
+
ignoreCase: options.caseInsensitive === true
|
|
24499
|
+
});
|
|
24500
|
+
if (options.json) {
|
|
24501
|
+
output.info(formatJson(response.data));
|
|
24502
|
+
return;
|
|
24503
|
+
}
|
|
24504
|
+
if (response.data.mode === "files_with_matches") {
|
|
24505
|
+
output.info(
|
|
24506
|
+
response.data.files.length > 0 ? response.data.files.join("\n") : `No files matched "${pattern}".`
|
|
24507
|
+
);
|
|
24508
|
+
return;
|
|
24509
|
+
}
|
|
24510
|
+
if (response.data.mode === "count") {
|
|
24511
|
+
const lines2 = response.data.counts.map((count) => `${count.file_path}: ${count.match_count}`);
|
|
24512
|
+
output.info(lines2.length > 0 ? lines2.join("\n") : `No matches for "${pattern}".`);
|
|
24513
|
+
return;
|
|
24514
|
+
}
|
|
24515
|
+
const lines = response.data.matches.flatMap((match) => [
|
|
24516
|
+
`${match.file_path}:${match.line_number}`,
|
|
24517
|
+
...match.context_before.map((line) => ` ${line}`),
|
|
24518
|
+
`> ${match.line}`,
|
|
24519
|
+
...match.context_after.map((line) => ` ${line}`)
|
|
24520
|
+
]);
|
|
24521
|
+
output.info(lines.length > 0 ? lines.join("\n") : `No matches for "${pattern}".`);
|
|
24522
|
+
}
|
|
24523
|
+
async function runKnowGlobCommand(pattern, options, output, dependencies) {
|
|
24524
|
+
const api = dependencies?.api ?? createKnowledgesApi(options);
|
|
24525
|
+
const response = await api.glob({
|
|
24526
|
+
pattern: pattern ?? "**/*.md",
|
|
24527
|
+
path: normalizeCatalogPath(options.path ?? "/")
|
|
24528
|
+
});
|
|
24529
|
+
if (options.json) {
|
|
24530
|
+
output.info(formatJson(response.data));
|
|
24531
|
+
return;
|
|
24532
|
+
}
|
|
24533
|
+
output.info(response.data.files.length > 0 ? response.data.files.join("\n") : "No matching files.");
|
|
24534
|
+
if (response.data.truncated) {
|
|
24535
|
+
output.info(`[truncated: ${response.data.total_files} total files]`);
|
|
24536
|
+
}
|
|
24537
|
+
}
|
|
24347
24538
|
async function printBackendStatus(options, output) {
|
|
24348
24539
|
const health = await readBackendHealth(options);
|
|
24349
24540
|
output.info(health.ok ? `API: ${health.service} ready` : `API: unavailable (${health.message})`);
|
|
@@ -24366,6 +24557,121 @@ function formatScrubReport(findings) {
|
|
|
24366
24557
|
}
|
|
24367
24558
|
return lines.join("\n");
|
|
24368
24559
|
}
|
|
24560
|
+
function createKnowledgesApi(options) {
|
|
24561
|
+
const client = createCngApiClient(options);
|
|
24562
|
+
return {
|
|
24563
|
+
getCatalog: () => client.harnessKnowledges.getHarnessKnowledgesCatalog(),
|
|
24564
|
+
listAudiences: () => client.harnessKnowledges.listHarnessKnowledgesAudiences(),
|
|
24565
|
+
search: (query, limit) => client.harnessKnowledges.searchHarnessKnowledges({
|
|
24566
|
+
q: query,
|
|
24567
|
+
limit
|
|
24568
|
+
}),
|
|
24569
|
+
listSubskills: () => client.harnessKnowledges.listHarnessKnowledgesSubskills(),
|
|
24570
|
+
listFiles: ({ query, audience, limit }) => client.harnessKnowledges.listHarnessSubskillAssets({
|
|
24571
|
+
...query ? { q: query } : {},
|
|
24572
|
+
...audience ? { audience } : {},
|
|
24573
|
+
limit
|
|
24574
|
+
}),
|
|
24575
|
+
read: ({ filePath, offset, limit }) => client.harnessFilesystem.getHarnessFilesystemRead({
|
|
24576
|
+
file_path: filePath,
|
|
24577
|
+
offset,
|
|
24578
|
+
limit
|
|
24579
|
+
}),
|
|
24580
|
+
grep: ({ pattern, path: path5, include, mode, context, ignoreCase }) => client.harnessFilesystem.getHarnessFilesystemGrep({
|
|
24581
|
+
pattern,
|
|
24582
|
+
path: path5,
|
|
24583
|
+
include,
|
|
24584
|
+
output_mode: mode,
|
|
24585
|
+
context,
|
|
24586
|
+
case_insensitive: ignoreCase ? "true" : void 0
|
|
24587
|
+
}),
|
|
24588
|
+
glob: ({ pattern, path: path5 }) => client.harnessFilesystem.getHarnessFilesystemGlob({
|
|
24589
|
+
pattern,
|
|
24590
|
+
path: path5
|
|
24591
|
+
})
|
|
24592
|
+
};
|
|
24593
|
+
}
|
|
24594
|
+
function coerceLimit(value, defaultValue, maxValue = 100) {
|
|
24595
|
+
const normalizedValue = coerceOptionalNumber(value);
|
|
24596
|
+
if (normalizedValue === void 0 || Number.isNaN(normalizedValue)) {
|
|
24597
|
+
return defaultValue;
|
|
24598
|
+
}
|
|
24599
|
+
return Math.max(defaultValue === 0 ? 0 : 1, Math.min(maxValue, Math.trunc(normalizedValue)));
|
|
24600
|
+
}
|
|
24601
|
+
function coerceOptionalNumber(value) {
|
|
24602
|
+
if (value === void 0 || value === "") {
|
|
24603
|
+
return void 0;
|
|
24604
|
+
}
|
|
24605
|
+
return Number(value);
|
|
24606
|
+
}
|
|
24607
|
+
function normalizeAudienceId(value) {
|
|
24608
|
+
if (value === void 0) {
|
|
24609
|
+
return void 0;
|
|
24610
|
+
}
|
|
24611
|
+
switch (value) {
|
|
24612
|
+
case "all":
|
|
24613
|
+
case "operators":
|
|
24614
|
+
case "builders":
|
|
24615
|
+
case "researchers":
|
|
24616
|
+
case "agent-makers":
|
|
24617
|
+
return value;
|
|
24618
|
+
default:
|
|
24619
|
+
throw new Error(
|
|
24620
|
+
`Unknown audience "${value}". Run cngkit knowledges audiences to see supported values.`
|
|
24621
|
+
);
|
|
24622
|
+
}
|
|
24623
|
+
}
|
|
24624
|
+
function normalizeGrepMode(value) {
|
|
24625
|
+
if (value === void 0) {
|
|
24626
|
+
return "content";
|
|
24627
|
+
}
|
|
24628
|
+
switch (value) {
|
|
24629
|
+
case "content":
|
|
24630
|
+
case "files_with_matches":
|
|
24631
|
+
case "count":
|
|
24632
|
+
return value;
|
|
24633
|
+
default:
|
|
24634
|
+
throw new Error("Unknown grep mode. Use one of: content, files_with_matches, count.");
|
|
24635
|
+
}
|
|
24636
|
+
}
|
|
24637
|
+
function singleLine(value) {
|
|
24638
|
+
return value.replace(/\s+/g, " ").trim();
|
|
24639
|
+
}
|
|
24640
|
+
function formatJson(value) {
|
|
24641
|
+
return JSON.stringify(value, null, 2);
|
|
24642
|
+
}
|
|
24643
|
+
function optionalJoinedArgument(values) {
|
|
24644
|
+
return values.length > 0 ? values.join(" ") : void 0;
|
|
24645
|
+
}
|
|
24646
|
+
function normalizeCatalogPath(value) {
|
|
24647
|
+
const trimmed = value.trim();
|
|
24648
|
+
if (trimmed === "/" || trimmed === "") {
|
|
24649
|
+
return "/";
|
|
24650
|
+
}
|
|
24651
|
+
const relativePath = trimmed.replace(/^\/+/, "");
|
|
24652
|
+
if (relativePath.startsWith("skills/knowledges/")) {
|
|
24653
|
+
return relativePath;
|
|
24654
|
+
}
|
|
24655
|
+
const [firstSegment, ...restSegments] = relativePath.split("/");
|
|
24656
|
+
if (!firstSegment || restSegments.length === 0) {
|
|
24657
|
+
return relativePath;
|
|
24658
|
+
}
|
|
24659
|
+
switch (firstSegment) {
|
|
24660
|
+
case "concepts":
|
|
24661
|
+
case "domains":
|
|
24662
|
+
case "formats":
|
|
24663
|
+
case "languages":
|
|
24664
|
+
case "libraries":
|
|
24665
|
+
case "patterns":
|
|
24666
|
+
case "platforms":
|
|
24667
|
+
case "procedures":
|
|
24668
|
+
case "protocols":
|
|
24669
|
+
case "tools":
|
|
24670
|
+
return `skills/knowledges/subskills/${firstSegment}/${restSegments.join("/")}`;
|
|
24671
|
+
default:
|
|
24672
|
+
return relativePath;
|
|
24673
|
+
}
|
|
24674
|
+
}
|
|
24369
24675
|
|
|
24370
24676
|
// src/output.ts
|
|
24371
24677
|
var consoleOutput = {
|
|
@@ -24402,6 +24708,9 @@ cli.command("join <room-code>", "Join a real-time repo sync room in the current
|
|
|
24402
24708
|
cli.command("scrub [path]", "Scan for secrets with TruffleHog and optionally mask them inline").option("--mask", "Compatibility alias for inline scrubbing; --yes is still required").option("--yes", "Confirm and run inline scrubbing").action((targetPath, options) => {
|
|
24403
24709
|
void runScrubCommand(targetPath, options, consoleOutput).catch(handleFatalError);
|
|
24404
24710
|
});
|
|
24711
|
+
cli.command("knowledges [...args]", "Use the Cloudflare-backed Harness knowledges catalog").option("--limit <n>", "Maximum results").option("--audience <id>", "Audience filter").option("--offset <n>", "Starting line offset").option("--path <path>", "Catalog path prefix").option("--include <glob>", "Filename include filter").option("--output-mode <mode>", "Output mode: content, files_with_matches, count").option("--context <n>", "Context lines around content matches").option("--case-insensitive", "Case-insensitive search").option("--json", "Print raw JSON").action((args, options) => {
|
|
24712
|
+
void runKnowledgesCommand(args, options, consoleOutput).catch(handleFatalError);
|
|
24713
|
+
});
|
|
24405
24714
|
try {
|
|
24406
24715
|
cli.parse(import_node_process5.default.argv);
|
|
24407
24716
|
} catch (error51) {
|