cngkit 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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.1.0";
7446
+ var packageVersion = "1.1.1";
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;
@@ -7512,6 +7512,426 @@ function browserOpenCommand(url2) {
7512
7512
  return { command: "xdg-open", args: [url2] };
7513
7513
  }
7514
7514
 
7515
+ // src/help-specs.ts
7516
+ var commandList = [
7517
+ "`cngkit login` - open Curly.ng login.",
7518
+ "`cngkit share [room-code]` - start a live repo sync room.",
7519
+ "`cngkit join <room-code>` - join a live repo sync room.",
7520
+ "`cngkit scrub [path]` - scan for secrets and optionally mask them inline.",
7521
+ "`cngkit knowledges ...` - read the hosted Harness catalog."
7522
+ ].join("\n");
7523
+ var knowledgesCommandList = [
7524
+ "`status` - print remote catalog state.",
7525
+ "`audiences` - list valid audience filters.",
7526
+ "`search <query>` - semantic search over Cloudflare Vectorize-backed records.",
7527
+ "`list [query]` - list known subskills.",
7528
+ "`files [query]` - list uploaded catalog files.",
7529
+ "`read <file-path>` - Claude-style file read.",
7530
+ "`grep <pattern>` - Claude-style content search.",
7531
+ "`glob [pattern]` - Claude-style file discovery."
7532
+ ].join("\n");
7533
+ var helpTopics = [
7534
+ {
7535
+ title: "cngkit",
7536
+ aliases: ["", "overview", "help"],
7537
+ body: `# cngkit
7538
+
7539
+ Curly.ng operator CLI for backend-connected repo sync, secret scrubbing, and Harness knowledges access.
7540
+
7541
+ ## Usage
7542
+
7543
+ \`\`\`bash
7544
+ cngkit <command> [options]
7545
+ \`\`\`
7546
+
7547
+ ## Commands
7548
+
7549
+ ${commandList}
7550
+
7551
+ ## Progressive Help
7552
+
7553
+ \`\`\`bash
7554
+ cngkit <command> --help
7555
+ cngkit knowledges --help
7556
+ cngkit knowledges <subcommand> --help
7557
+ \`\`\`
7558
+
7559
+ The CLI intentionally prints plain Markdown or line-oriented text with no color-only state, tables that require terminal width, or hidden interactive prompts. Add \`--json\` to read-only knowledges commands when another agent or tool needs structured backend data.
7560
+
7561
+ ## Backend
7562
+
7563
+ Default API: \`https://curly.ng\`
7564
+
7565
+ Override with:
7566
+
7567
+ \`\`\`bash
7568
+ cngkit --api-base-url <url> ...
7569
+ CNGKIT_API_BASE_URL=<url> cngkit ...
7570
+ \`\`\`
7571
+ `
7572
+ },
7573
+ {
7574
+ title: "login",
7575
+ aliases: ["login"],
7576
+ body: `# cngkit login
7577
+
7578
+ Open Curly.ng login in a browser. In headless environments, print the URL so an agent can surface it to the operator.
7579
+
7580
+ ## Usage
7581
+
7582
+ \`\`\`bash
7583
+ cngkit login
7584
+ \`\`\`
7585
+
7586
+ ## Output Contract
7587
+
7588
+ - First line names the login URL being opened.
7589
+ - If no local browser opener exists, the CLI prints a direct URL.
7590
+ - No credentials are printed or persisted by this command.
7591
+ `
7592
+ },
7593
+ {
7594
+ title: "share",
7595
+ aliases: ["share", "sync", "repo-sync"],
7596
+ body: `# cngkit share
7597
+
7598
+ Start a real-time repository sync room from the current directory.
7599
+
7600
+ ## Usage
7601
+
7602
+ \`\`\`bash
7603
+ cngkit share [room-code]
7604
+ \`\`\`
7605
+
7606
+ ## Backend Contract
7607
+
7608
+ - Connects to \`/api/cng/sync/:roomCode\` on the configured Curly backend.
7609
+ - Uses WebSocket transport backed by the \`CngSyncRoom\` Durable Object.
7610
+ - Sends an initial snapshot, then file and delete events.
7611
+ - Last received change wins.
7612
+
7613
+ ## Filesystem Contract
7614
+
7615
+ - Preserves \`.git/\`.
7616
+ - Preserves files ignored by the repo's \`.gitignore\`.
7617
+ - Sends regular files as base64 payloads in the sync protocol.
7618
+
7619
+ ## Output Contract
7620
+
7621
+ - Prints room code, repo root, peer id, backend health, and concise sync events.
7622
+ - Keeps running until the socket closes or the process receives a termination signal.
7623
+ `
7624
+ },
7625
+ {
7626
+ title: "join",
7627
+ aliases: ["join"],
7628
+ body: `# cngkit join
7629
+
7630
+ Join an existing real-time repository sync room in the current directory.
7631
+
7632
+ ## Usage
7633
+
7634
+ \`\`\`bash
7635
+ cngkit join <room-code>
7636
+ \`\`\`
7637
+
7638
+ ## Backend Contract
7639
+
7640
+ Same transport and filesystem contract as \`cngkit share\`. The supplied room code selects the Durable Object room.
7641
+
7642
+ ## Output Contract
7643
+
7644
+ - Prints backend health, room code, repo root, peer id, and concise sync events.
7645
+ - Missing room code exits with a usage error.
7646
+ `
7647
+ },
7648
+ {
7649
+ title: "scrub",
7650
+ aliases: ["scrub"],
7651
+ body: `# cngkit scrub
7652
+
7653
+ Scan a file or directory for secrets with TruffleHog. Report-only is the default. Inline masking requires \`--yes\`.
7654
+
7655
+ ## Usage
7656
+
7657
+ \`\`\`bash
7658
+ cngkit scrub [path]
7659
+ cngkit scrub [path] --yes
7660
+ \`\`\`
7661
+
7662
+ ## Requirements
7663
+
7664
+ - \`trufflehog\` must be available on \`PATH\`.
7665
+
7666
+ ## Safety Contract
7667
+
7668
+ - Default mode does not rewrite files.
7669
+ - \`--yes\` rewrites detected secret values inline with \`[CNGKIT_SECRET:<detector>:<verified|unverified>]\` placeholders.
7670
+ - \`--mask\` is accepted as a compatibility alias, but still requires \`--yes\`.
7671
+ - Raw and redacted secret values are never printed in the report.
7672
+ `
7673
+ },
7674
+ {
7675
+ title: "knowledges",
7676
+ aliases: ["knowledges", "knowledge"],
7677
+ body: `# cngkit knowledges
7678
+
7679
+ Read the hosted Harness knowledges catalog from the Curly backend. These commands are read-only and use the generated \`@cng/client\` SDK against public backend routes.
7680
+
7681
+ ## Usage
7682
+
7683
+ \`\`\`bash
7684
+ cngkit knowledges <subcommand> [options]
7685
+ \`\`\`
7686
+
7687
+ ## Subcommands
7688
+
7689
+ ${knowledgesCommandList}
7690
+
7691
+ ## Progressive Help
7692
+
7693
+ \`\`\`bash
7694
+ cngkit knowledges read --help
7695
+ cngkit knowledges grep --help
7696
+ cngkit knowledges glob --help
7697
+ \`\`\`
7698
+
7699
+ ## AI-Friendly Output
7700
+
7701
+ - Default output is line-oriented and intended to be directly usable by agents.
7702
+ - \`read\` prints file content with no wrapper before any truncation note.
7703
+ - \`grep --output-mode content\` prints \`path:line\` blocks.
7704
+ - \`grep --output-mode files_with_matches\` and \`glob\` print one path per line.
7705
+ - \`--json\` prints the typed backend data payload for machine consumption.
7706
+ `
7707
+ },
7708
+ {
7709
+ title: "knowledges status",
7710
+ aliases: ["knowledges-status", "status"],
7711
+ body: `# cngkit knowledges status
7712
+
7713
+ Print remote Harness catalog state from \`GET /api/harness/knowledges/catalog\`.
7714
+
7715
+ ## Usage
7716
+
7717
+ \`\`\`bash
7718
+ cngkit knowledges status [--json]
7719
+ \`\`\`
7720
+
7721
+ ## Output Contract
7722
+
7723
+ - Text mode prints catalog name, file count, blob count, Vectorize binding, and latest run when present.
7724
+ - \`--json\` prints the backend data payload.
7725
+ `
7726
+ },
7727
+ {
7728
+ title: "knowledges audiences",
7729
+ aliases: ["knowledges-audiences", "audiences"],
7730
+ body: `# cngkit knowledges audiences
7731
+
7732
+ List valid audience filters from \`GET /api/harness/knowledges/audiences\`.
7733
+
7734
+ ## Usage
7735
+
7736
+ \`\`\`bash
7737
+ cngkit knowledges audiences [--json]
7738
+ \`\`\`
7739
+
7740
+ Use this before \`cngkit knowledges files --audience <id>\`.
7741
+ `
7742
+ },
7743
+ {
7744
+ title: "knowledges search",
7745
+ aliases: ["knowledges-search", "search"],
7746
+ body: `# cngkit knowledges search
7747
+
7748
+ Run semantic search against the Cloudflare Vectorize-backed Harness index.
7749
+
7750
+ ## Usage
7751
+
7752
+ \`\`\`bash
7753
+ cngkit knowledges search <query> [--limit <n>] [--json]
7754
+ \`\`\`
7755
+
7756
+ ## Defaults
7757
+
7758
+ - \`--limit\`: \`5\`
7759
+
7760
+ ## Example
7761
+
7762
+ \`\`\`bash
7763
+ cngkit knowledges search "cloudflare backend" --limit 3
7764
+ \`\`\`
7765
+ `
7766
+ },
7767
+ {
7768
+ title: "knowledges list",
7769
+ aliases: ["knowledges-list", "list"],
7770
+ body: `# cngkit knowledges list
7771
+
7772
+ List known subskills from \`GET /api/harness/knowledges/subskills\`, optionally filtered locally by query.
7773
+
7774
+ ## Usage
7775
+
7776
+ \`\`\`bash
7777
+ cngkit knowledges list [query] [--limit <n>] [--json]
7778
+ \`\`\`
7779
+
7780
+ ## Defaults
7781
+
7782
+ - \`--limit\`: \`25\`
7783
+ `
7784
+ },
7785
+ {
7786
+ title: "knowledges files",
7787
+ aliases: ["knowledges-files", "files"],
7788
+ body: `# cngkit knowledges files
7789
+
7790
+ List uploaded catalog files from \`GET /api/harness/knowledges/files\`.
7791
+
7792
+ ## Usage
7793
+
7794
+ \`\`\`bash
7795
+ cngkit knowledges files [query] [--audience <id>] [--limit <n>] [--json]
7796
+ \`\`\`
7797
+
7798
+ ## Defaults
7799
+
7800
+ - \`--limit\`: \`25\`
7801
+ - \`--audience\`: omitted
7802
+
7803
+ Run \`cngkit knowledges audiences\` to discover supported audience ids.
7804
+ `
7805
+ },
7806
+ {
7807
+ title: "knowledges read",
7808
+ aliases: ["knowledges-read", "read"],
7809
+ body: `# cngkit knowledges read
7810
+
7811
+ Claude-style read tool for hosted Harness catalog files. Backed by \`GET /api/harness/filesystem/read\` and \`HarnessReadQuerySchema\`.
7812
+
7813
+ ## Usage
7814
+
7815
+ \`\`\`bash
7816
+ cngkit knowledges read <file-path> [--offset <n>] [--limit <n>] [--json]
7817
+ \`\`\`
7818
+
7819
+ ## Inputs
7820
+
7821
+ - \`file-path\`: normalized catalog path. Shorthand paths such as \`/libraries/lib-cloudflare/SUBSKILL.md\` are expanded to \`skills/knowledges/subskills/libraries/lib-cloudflare/SUBSKILL.md\`.
7822
+ - \`--offset\`: zero-based starting line. Default: \`0\`.
7823
+ - \`--limit\`: maximum lines. Default in CLI: \`200\`. Backend max: \`2000\`.
7824
+
7825
+ ## Output Contract
7826
+
7827
+ - Text mode prints only the returned file content first.
7828
+ - If truncated, a final bracketed truncation note is printed after the content.
7829
+ - \`--json\` prints \`{ file_path, content, total_lines, offset, limit, truncated }\`.
7830
+
7831
+ ## Example
7832
+
7833
+ \`\`\`bash
7834
+ cngkit knowledges read /libraries/lib-cloudflare/SUBSKILL.md --limit 80
7835
+ \`\`\`
7836
+ `
7837
+ },
7838
+ {
7839
+ title: "knowledges grep",
7840
+ aliases: ["knowledges-grep", "grep"],
7841
+ body: `# cngkit knowledges grep
7842
+
7843
+ Claude-style grep tool for hosted Harness catalog files. Backed by \`GET /api/harness/filesystem/grep\` and \`HarnessGrepQuerySchema\`.
7844
+
7845
+ ## Usage
7846
+
7847
+ \`\`\`bash
7848
+ cngkit knowledges grep <pattern> [--path <path>] [--include <glob>] [--output-mode <mode>] [--context <n>] [--case-insensitive] [--json]
7849
+ \`\`\`
7850
+
7851
+ ## Inputs
7852
+
7853
+ - \`pattern\`: JavaScript regular expression source.
7854
+ - \`--path\`: catalog path prefix. Default: \`/\`.
7855
+ - \`--include\`: filename include filter. Default: \`*\`.
7856
+ - \`--output-mode\`: \`content\`, \`files_with_matches\`, or \`count\`. Default: \`content\`.
7857
+ - \`--context\`: context lines around content matches. Default: \`0\`. Backend max: \`20\`.
7858
+ - \`--case-insensitive\`: maps to backend \`case_insensitive=true\`.
7859
+
7860
+ ## Output Contract
7861
+
7862
+ - \`content\`: prints blocks as \`file_path:line_number\`, optional context lines, then \`> matching line\`.
7863
+ - \`files_with_matches\`: prints one matching file path per line.
7864
+ - \`count\`: prints \`file_path: match_count\` lines.
7865
+ - \`--json\` prints the typed backend response union.
7866
+
7867
+ ## Examples
7868
+
7869
+ \`\`\`bash
7870
+ cngkit knowledges grep Cloudflare --path /libraries/lib-cloudflare --output-mode files_with_matches
7871
+ cngkit knowledges grep "Vectorize|D1" --path /libraries/lib-cloudflare --context 2
7872
+ \`\`\`
7873
+ `
7874
+ },
7875
+ {
7876
+ title: "knowledges glob",
7877
+ aliases: ["knowledges-glob", "glob"],
7878
+ body: `# cngkit knowledges glob
7879
+
7880
+ Claude-style glob tool for hosted Harness catalog files. Backed by \`GET /api/harness/filesystem/glob\` and \`HarnessGlobQuerySchema\`.
7881
+
7882
+ ## Usage
7883
+
7884
+ \`\`\`bash
7885
+ cngkit knowledges glob [pattern] [--path <path>] [--json]
7886
+ \`\`\`
7887
+
7888
+ ## Inputs
7889
+
7890
+ - \`pattern\`: supported glob pattern. CLI default: \`**/*.md\`.
7891
+ - \`--path\`: catalog path prefix. Default: \`/\`.
7892
+
7893
+ ## Supported Patterns
7894
+
7895
+ - \`**/*.md\`
7896
+ - \`**/*.SUBSKILL.md\`
7897
+ - \`**/SKILL.md\`
7898
+ - \`*.md\`
7899
+ - \`*.SUBSKILL.md\`
7900
+ - \`SKILL.md\`
7901
+
7902
+ ## Output Contract
7903
+
7904
+ - Text mode prints one file path per line.
7905
+ - If truncated, a final bracketed truncation note is printed.
7906
+ - \`--json\` prints \`{ files, total_files, truncated }\`.
7907
+
7908
+ ## Example
7909
+
7910
+ \`\`\`bash
7911
+ cngkit knowledges glob "**/*.md" --path /libraries/lib-cloudflare
7912
+ \`\`\`
7913
+ `
7914
+ }
7915
+ ];
7916
+ var helpTopicByAlias = /* @__PURE__ */ new Map();
7917
+ for (const topic of helpTopics) {
7918
+ for (const alias of topic.aliases) {
7919
+ helpTopicByAlias.set(alias, topic);
7920
+ }
7921
+ }
7922
+ function formatCngkitHelp(topicName) {
7923
+ const normalizedTopicName = normalizeHelpTopicName(topicName);
7924
+ return (helpTopicByAlias.get(normalizedTopicName) ?? helpTopicByAlias.get(""))?.body.trim() ?? "";
7925
+ }
7926
+ function formatKnowledgesHelp(topicName) {
7927
+ const normalizedTopicName = normalizeHelpTopicName(topicName);
7928
+ const topicKey = normalizedTopicName ? `knowledges-${normalizedTopicName}` : "knowledges";
7929
+ return formatCngkitHelp(topicKey);
7930
+ }
7931
+ function normalizeHelpTopicName(value) {
7932
+ return value?.trim().toLowerCase().replace(/\s+/g, "-") ?? "";
7933
+ }
7934
+
7515
7935
  // src/scrub/masker.ts
7516
7936
  var import_promises = __toESM(require("fs/promises"), 1);
7517
7937
  var import_node_path = __toESM(require("path"), 1);
@@ -24298,6 +24718,10 @@ async function waitForSessionClose(socket, watcher) {
24298
24718
  // src/commands.ts
24299
24719
  async function runKnowledgesCommand(args, options, output, dependencies) {
24300
24720
  const [subcommand, ...subcommandArgs] = args ?? [];
24721
+ if (subcommand === void 0 || subcommand === "help") {
24722
+ output.info(formatKnowledgesHelp(subcommandArgs[0]));
24723
+ return;
24724
+ }
24301
24725
  switch (subcommand) {
24302
24726
  case "status":
24303
24727
  return runKnowStatusCommand(options, output, dependencies);
@@ -24692,6 +25116,34 @@ function handleFatalError(error51) {
24692
25116
  consoleOutput.error(formatError2(error51));
24693
25117
  import_node_process5.default.exitCode = 1;
24694
25118
  }
25119
+ function printMarkdownHelpIfRequested(argv) {
25120
+ const commandName = argv[2];
25121
+ if (commandName === void 0 || commandName === "--help" || commandName === "-h") {
25122
+ consoleOutput.info(formatCngkitHelp());
25123
+ return true;
25124
+ }
25125
+ if (commandName === "help") {
25126
+ const [topicName, subtopicName] = argv.slice(3);
25127
+ const topic = topicName === "knowledges" && subtopicName ? `knowledges-${subtopicName}` : topicName;
25128
+ consoleOutput.info(formatCngkitHelp(topic));
25129
+ return true;
25130
+ }
25131
+ const commandArgs = argv.slice(3);
25132
+ const helpIndex = commandArgs.findIndex((argument) => argument === "--help" || argument === "-h");
25133
+ if (helpIndex < 0) {
25134
+ return false;
25135
+ }
25136
+ if (commandName === "knowledges") {
25137
+ const topic = commandArgs.find((argument, index) => index !== helpIndex && !argument.startsWith("-"));
25138
+ consoleOutput.info(formatKnowledgesHelp(topic));
25139
+ return true;
25140
+ }
25141
+ consoleOutput.info(formatCngkitHelp(commandName));
25142
+ return true;
25143
+ }
25144
+ if (printMarkdownHelpIfRequested(import_node_process5.default.argv)) {
25145
+ import_node_process5.default.exit(0);
25146
+ }
24695
25147
  cli.option(
24696
25148
  "--api-base-url <url>",
24697
25149
  "Curly API base URL. Default: CNGKIT_API_BASE_URL or https://curly.ng"