cngkit 1.1.18 → 1.1.19
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 +86 -11
- package/dist/chunk-3A6GRNEV.js +1590 -0
- package/dist/chunk-3A6GRNEV.js.map +1 -0
- package/dist/{chunk-FJ34NVQ4.js → chunk-7SO75QXJ.js} +538 -68
- package/dist/chunk-7SO75QXJ.js.map +1 -0
- package/dist/chunk-DBA3BZXP.js +231 -0
- package/dist/chunk-DBA3BZXP.js.map +1 -0
- package/dist/{chunk-IB5B3BLY.js → chunk-GBONV6XP.js} +16 -4
- package/dist/chunk-GBONV6XP.js.map +1 -0
- package/dist/{chunk-C7HFDK4S.js → chunk-L6ZVQRSY.js} +207 -31
- package/dist/chunk-L6ZVQRSY.js.map +1 -0
- package/dist/{chunk-ZA4YOWPB.js → chunk-NGEWD4BW.js} +2 -1
- package/dist/chunk-TYDIBWZV.js +35 -0
- package/dist/chunk-TYDIBWZV.js.map +1 -0
- package/dist/{chunk-TWQDLZ6F.js → chunk-X4E7NAN4.js} +2 -2
- package/dist/cli.js +55 -14
- package/dist/cli.js.map +1 -1
- package/dist/commands/coderoom/index.js +6 -6
- package/dist/commands/coderoom/index.js.map +1 -1
- package/dist/commands/coderoom/join.js +5 -5
- package/dist/commands/coderoom/share.js +5 -5
- package/dist/commands/hookify/index.js +6 -6
- package/dist/commands/hookify/index.js.map +1 -1
- package/dist/commands/hookify/ingest.js +52 -13
- package/dist/commands/hookify/ingest.js.map +1 -1
- package/dist/commands/hooks/index.js +25 -0
- package/dist/commands/hooks/index.js.map +1 -0
- package/dist/commands/hooks/install.js +40 -0
- package/dist/commands/hooks/install.js.map +1 -0
- package/dist/commands/hooks/uninstall.js +40 -0
- package/dist/commands/hooks/uninstall.js.map +1 -0
- package/dist/commands/index.js +5 -5
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/knowledges/audiences.js +6 -6
- package/dist/commands/knowledges/cat.js +31 -0
- package/dist/commands/knowledges/cat.js.map +1 -0
- package/dist/commands/knowledges/files.js +6 -6
- package/dist/commands/knowledges/find.js +66 -0
- package/dist/commands/knowledges/find.js.map +1 -0
- package/dist/commands/knowledges/glob.js +6 -6
- package/dist/commands/knowledges/grep.js +6 -6
- package/dist/commands/knowledges/head.js +41 -0
- package/dist/commands/knowledges/head.js.map +1 -0
- package/dist/commands/knowledges/index.js +6 -6
- package/dist/commands/knowledges/index.js.map +1 -1
- package/dist/commands/knowledges/list.js +7 -7
- package/dist/commands/knowledges/list.js.map +1 -1
- package/dist/commands/knowledges/ls.js +16 -7
- package/dist/commands/knowledges/ls.js.map +1 -1
- package/dist/commands/knowledges/read.js +6 -6
- package/dist/commands/knowledges/realpath.js +31 -0
- package/dist/commands/knowledges/realpath.js.map +1 -0
- package/dist/commands/knowledges/search.js +6 -6
- package/dist/commands/knowledges/stat.js +31 -0
- package/dist/commands/knowledges/stat.js.map +1 -0
- package/dist/commands/knowledges/status.js +6 -6
- package/dist/commands/knowledges/tail.js +41 -0
- package/dist/commands/knowledges/tail.js.map +1 -0
- package/dist/commands/knowledges/tree.js +46 -0
- package/dist/commands/knowledges/tree.js.map +1 -0
- package/dist/commands/login.js +3 -3
- package/dist/commands/scrub.js +3 -3
- package/dist/commands/transcripts.js +6 -6
- package/dist/commands/transcripts.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-C7HFDK4S.js.map +0 -1
- package/dist/chunk-CBIVTEZP.js +0 -222
- package/dist/chunk-CBIVTEZP.js.map +0 -1
- package/dist/chunk-FJ34NVQ4.js.map +0 -1
- package/dist/chunk-IB5B3BLY.js.map +0 -1
- package/dist/chunk-KSW6QT5Q.js +0 -628
- package/dist/chunk-KSW6QT5Q.js.map +0 -1
- /package/dist/{chunk-ZA4YOWPB.js.map → chunk-NGEWD4BW.js.map} +0 -0
- /package/dist/{chunk-TWQDLZ6F.js.map → chunk-X4E7NAN4.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/features/coderoom/run-coderoom-command.ts","../src/features/coderoom/sync/client.ts","../src/features/coderoom/sync/files.ts","../src/features/coderoom/sync/paths.ts","../src/features/coderoom/sync/protocol.ts"],"sourcesContent":["import process from \"node:process\";\n\nimport { readBackendHealth } from \"../../shared/api-client.js\";\nimport { createRoomCode, resolveApiBaseUrl, type GlobalCommandOptions } from \"../../shared/config.js\";\nimport type { CommandOutput } from \"../../shared/output.js\";\nimport { startSyncSession, type SyncSessionRole } from \"./sync/client.js\";\n\nexport type CoderoomCommandOptions = GlobalCommandOptions;\n\nexport type ShareCommandOptions = GlobalCommandOptions;\n\nexport async function runCoderoomCommand(\n args: string[] | undefined,\n options: CoderoomCommandOptions,\n output: CommandOutput\n): Promise<void> {\n const [subcommand, ...subcommandArgs] = args ?? [];\n\n switch (subcommand) {\n case \"share\":\n return runShareCommand(subcommandArgs[0], options, output);\n case \"join\":\n return runJoinCommand(subcommandArgs[0], options, output);\n default:\n throw new Error(\"Missing coderoom command. Usage: cngkit coderoom <share|join>\");\n }\n}\n\nexport async function runShareCommand(\n roomCode: string | undefined,\n options: ShareCommandOptions,\n output: CommandOutput\n): Promise<void> {\n const syncRoomCode = roomCode ?? createRoomCode();\n\n output.success(`Share code: ${syncRoomCode}`);\n await printBackendStatus(options, output);\n await runSyncSession(\"share\", syncRoomCode, options, output);\n}\n\nexport async function runJoinCommand(\n roomCode: string | undefined,\n options: GlobalCommandOptions,\n output: CommandOutput\n): Promise<void> {\n if (!roomCode) {\n throw new Error(\"Missing room code. Usage: cngkit coderoom join <room-code>\");\n }\n\n await printBackendStatus(options, output);\n await runSyncSession(\"join\", roomCode, options, output);\n}\n\nasync function printBackendStatus(\n options: GlobalCommandOptions,\n output: CommandOutput\n): Promise<void> {\n const health = await readBackendHealth(options);\n if (health.ok) {\n output.success(`API: ${health.service} ready`);\n return;\n }\n\n output.warning(`API: unavailable (${health.message})`);\n}\n\nasync function runSyncSession(\n role: SyncSessionRole,\n roomCode: string,\n options: GlobalCommandOptions,\n output: CommandOutput\n): Promise<void> {\n await startSyncSession({\n apiBaseUrl: resolveApiBaseUrl(options),\n roomCode,\n role,\n cwd: process.cwd(),\n output,\n });\n}\n","import process from \"node:process\";\n\nimport chokidar, { type FSWatcher } from \"chokidar\";\nimport WebSocket, { type RawData } from \"ws\";\n\nimport { createPeerId } from \"../../../shared/config.js\";\nimport type { CommandOutput } from \"../../../shared/output.js\";\nimport {\n applyRemoteMessage,\n buildFileMessage,\n collectSnapshotMessages,\n createSuppressionTracker,\n type SuppressionTracker,\n} from \"./files.js\";\nimport {\n resolveRepoContext,\n shouldSyncRelativePath,\n toRepoRelativePath,\n type RepoContext,\n} from \"./paths.js\";\nimport { decodeSyncMessage, encodeSyncMessage, type SyncMessage } from \"./protocol.js\";\n\nexport type SyncSessionRole = \"share\" | \"join\";\n\nexport type StartSyncSessionOptions = {\n apiBaseUrl: string;\n roomCode: string;\n role: SyncSessionRole;\n cwd: string;\n output: CommandOutput;\n};\n\ntype WatcherContext = {\n repoContext: RepoContext;\n socket: WebSocket;\n peerId: string;\n suppressionTracker: SuppressionTracker;\n output: CommandOutput;\n};\n\nfunction createSyncWebSocketUrl(apiBaseUrl: string, roomCode: string): string {\n const url = new URL(apiBaseUrl);\n url.protocol = url.protocol === \"http:\" ? \"ws:\" : \"wss:\";\n url.pathname = `/api/cng/sync/${encodeURIComponent(roomCode)}`;\n url.search = \"\";\n url.hash = \"\";\n return url.toString();\n}\n\nfunction sendMessage(socket: WebSocket, message: SyncMessage): void {\n if (socket.readyState === WebSocket.OPEN) {\n socket.send(encodeSyncMessage(message));\n }\n}\n\nexport async function startSyncSession(options: StartSyncSessionOptions): Promise<void> {\n const repoContext = await resolveRepoContext(options.cwd);\n const peerId = createPeerId();\n const suppressionTracker = createSuppressionTracker();\n const webSocketUrl = createSyncWebSocketUrl(options.apiBaseUrl, options.roomCode);\n const socket = new WebSocket(webSocketUrl);\n\n options.output.success(`Room: ${options.roomCode}`);\n options.output.info(`Repo: ${repoContext.rootDir}`);\n options.output.muted(`Peer: ${peerId}`);\n\n const watcherContext: WatcherContext = {\n repoContext,\n socket,\n peerId,\n suppressionTracker,\n output: options.output,\n };\n const watcher = createRepoWatcher(watcherContext);\n\n socket.on(\"open\", () => {\n sendMessage(socket, {\n type: \"hello\",\n peerId,\n role: options.role,\n sentAt: Date.now(),\n });\n void sendInitialSnapshot(socket, repoContext, peerId, options.output);\n });\n\n socket.on(\"message\", (data) => {\n void handleRemoteMessage({\n data,\n repoContext,\n peerId,\n suppressionTracker,\n output: options.output,\n });\n });\n\n await waitForSessionClose(socket, watcher);\n}\n\nfunction createRepoWatcher(context: WatcherContext): FSWatcher {\n const watcher = chokidar.watch(context.repoContext.rootDir, {\n ignoreInitial: true,\n ignored: (candidatePath) => {\n const relativePath = toRepoRelativePath(context.repoContext.rootDir, candidatePath);\n return relativePath?.split(\"/\").includes(\".git\") ?? false;\n },\n });\n\n watcher.on(\"add\", (absolutePath) => {\n void sendLocalFileChange(context, absolutePath);\n });\n watcher.on(\"change\", (absolutePath) => {\n void sendLocalFileChange(context, absolutePath);\n });\n watcher.on(\"unlink\", (absolutePath) => {\n void sendLocalDelete(context, absolutePath);\n });\n\n return watcher;\n}\n\nasync function sendInitialSnapshot(\n socket: WebSocket,\n repoContext: RepoContext,\n peerId: string,\n output: CommandOutput\n): Promise<void> {\n let fileCount = 0;\n\n for await (const message of collectSnapshotMessages(repoContext, peerId)) {\n sendMessage(socket, message);\n fileCount += 1;\n }\n\n sendMessage(socket, {\n type: \"snapshot-complete\",\n peerId,\n sentAt: Date.now(),\n fileCount,\n });\n output.success(`sent snapshot ${fileCount} files`);\n}\n\nasync function sendLocalFileChange(context: WatcherContext, absolutePath: string): Promise<void> {\n const relativePath = toRepoRelativePath(context.repoContext.rootDir, absolutePath);\n if (!relativePath || context.suppressionTracker.isSuppressed(relativePath)) {\n return;\n }\n\n const message = await buildFileMessage(context.repoContext, context.peerId, relativePath);\n if (!message) {\n return;\n }\n\n sendMessage(context.socket, message);\n context.output.muted(`sent file ${relativePath}`);\n}\n\nasync function sendLocalDelete(context: WatcherContext, absolutePath: string): Promise<void> {\n const relativePath = toRepoRelativePath(context.repoContext.rootDir, absolutePath);\n if (!relativePath || context.suppressionTracker.isSuppressed(relativePath)) {\n return;\n }\n\n if (!(await shouldSyncRelativePath(context.repoContext, relativePath))) {\n return;\n }\n\n sendMessage(context.socket, {\n type: \"delete\",\n peerId: context.peerId,\n path: relativePath,\n mtimeMs: Date.now(),\n sentAt: Date.now(),\n });\n context.output.warning(`sent delete ${relativePath}`);\n}\n\nasync function handleRemoteMessage(options: {\n data: RawData;\n repoContext: RepoContext;\n peerId: string;\n suppressionTracker: SuppressionTracker;\n output: CommandOutput;\n}): Promise<void> {\n const decodedMessage = decodeSyncMessage(options.data.toString());\n if (!decodedMessage || decodedMessage.peerId === options.peerId) {\n return;\n }\n\n if (decodedMessage.type === \"hello\") {\n options.output.info(`peer joined ${decodedMessage.peerId}`);\n return;\n }\n\n if (decodedMessage.type === \"snapshot-complete\") {\n options.output.success(`peer snapshot complete ${decodedMessage.fileCount} files`);\n return;\n }\n\n await applyRemoteMessage(options.repoContext, decodedMessage, options.suppressionTracker);\n options.output.success(`applied ${decodedMessage.type} ${decodedMessage.path}`);\n}\n\nasync function waitForSessionClose(socket: WebSocket, watcher: FSWatcher): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n\n const closeSession = async (): Promise<void> => {\n await watcher.close();\n if (socket.readyState === WebSocket.OPEN || socket.readyState === WebSocket.CONNECTING) {\n socket.close();\n }\n };\n\n const finish = async (): Promise<void> => {\n if (settled) {\n return;\n }\n settled = true;\n process.off(\"SIGINT\", onSignal);\n process.off(\"SIGTERM\", onSignal);\n await closeSession();\n resolve();\n };\n\n const onSignal = (): void => {\n void finish();\n };\n\n socket.on(\"error\", async (error) => {\n if (settled) {\n return;\n }\n settled = true;\n process.off(\"SIGINT\", onSignal);\n process.off(\"SIGTERM\", onSignal);\n await closeSession();\n reject(error);\n });\n\n socket.on(\"close\", () => {\n void finish();\n });\n\n process.on(\"SIGINT\", onSignal);\n process.on(\"SIGTERM\", onSignal);\n });\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { SyncFileMutationMessage, SyncMessage } from \"./protocol.js\";\nimport {\n resolveRepoPath,\n shouldSyncRelativePath,\n toRepoRelativePath,\n type RepoContext,\n} from \"./paths.js\";\n\nexport type SuppressionTracker = {\n suppress(relativePath: string): void;\n isSuppressed(relativePath: string): boolean;\n};\n\nexport function createSuppressionTracker(windowMs = 1500): SuppressionTracker {\n const suppressedUntilByPath = new Map<string, number>();\n\n return {\n suppress(relativePath: string) {\n suppressedUntilByPath.set(relativePath, Date.now() + windowMs);\n },\n isSuppressed(relativePath: string) {\n const suppressedUntil = suppressedUntilByPath.get(relativePath);\n if (!suppressedUntil) {\n return false;\n }\n if (suppressedUntil < Date.now()) {\n suppressedUntilByPath.delete(relativePath);\n return false;\n }\n return true;\n },\n };\n}\n\nexport async function* collectSnapshotMessages(\n context: RepoContext,\n peerId: string\n): AsyncGenerator<SyncMessage> {\n yield* collectDirectorySnapshot(context, context.rootDir, peerId);\n}\n\nasync function* collectDirectorySnapshot(\n context: RepoContext,\n directoryPath: string,\n peerId: string\n): AsyncGenerator<SyncMessage> {\n const entries = await fs.opendir(directoryPath);\n\n for await (const entry of entries) {\n const absolutePath = path.join(directoryPath, entry.name);\n const relativePath = toRepoRelativePath(context.rootDir, absolutePath);\n\n if (!relativePath || !(await shouldSyncRelativePath(context, relativePath))) {\n continue;\n }\n\n if (entry.isDirectory()) {\n yield* collectDirectorySnapshot(context, absolutePath, peerId);\n continue;\n }\n\n if (!entry.isFile()) {\n continue;\n }\n\n const [content, stat] = await Promise.all([fs.readFile(absolutePath), fs.stat(absolutePath)]);\n yield {\n type: \"file\",\n peerId,\n path: relativePath,\n contentBase64: content.toString(\"base64\"),\n mtimeMs: stat.mtimeMs,\n sentAt: Date.now(),\n };\n }\n}\n\nexport async function buildFileMessage(\n context: RepoContext,\n peerId: string,\n relativePath: string\n): Promise<SyncMessage | undefined> {\n if (!(await shouldSyncRelativePath(context, relativePath))) {\n return undefined;\n }\n\n const absolutePath = resolveRepoPath(context.rootDir, relativePath);\n if (!absolutePath) {\n return undefined;\n }\n\n const stat = await fs.stat(absolutePath);\n if (!stat.isFile()) {\n return undefined;\n }\n\n const content = await fs.readFile(absolutePath);\n return {\n type: \"file\",\n peerId,\n path: relativePath,\n contentBase64: content.toString(\"base64\"),\n mtimeMs: stat.mtimeMs,\n sentAt: Date.now(),\n };\n}\n\nexport async function applyRemoteMessage(\n context: RepoContext,\n message: SyncFileMutationMessage,\n suppressionTracker: SuppressionTracker\n): Promise<void> {\n const absolutePath = resolveRepoPath(context.rootDir, message.path);\n if (!absolutePath || !(await shouldSyncRelativePath(context, message.path))) {\n return;\n }\n\n suppressionTracker.suppress(message.path);\n\n if (message.type === \"delete\") {\n await fs.rm(absolutePath, { force: true });\n return;\n }\n\n await fs.mkdir(path.dirname(absolutePath), { recursive: true });\n await fs.writeFile(absolutePath, Buffer.from(message.contentBase64, \"base64\"));\n}\n","import { execFile } from \"node:child_process\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nexport type RepoContext = {\n rootDir: string;\n};\n\nexport async function resolveRepoContext(cwd: string): Promise<RepoContext> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n cwd,\n });\n return { rootDir: path.resolve(stdout.trim()) };\n } catch {\n return { rootDir: path.resolve(cwd) };\n }\n}\n\nexport function toRepoRelativePath(rootDir: string, absolutePath: string): string | undefined {\n const relativePath = path.relative(rootDir, absolutePath);\n\n if (!relativePath || relativePath.startsWith(\"..\") || path.isAbsolute(relativePath)) {\n return undefined;\n }\n\n return relativePath.split(path.sep).join(\"/\");\n}\n\nexport function resolveRepoPath(rootDir: string, relativePath: string): string | undefined {\n if (!isSafeRelativePath(relativePath)) {\n return undefined;\n }\n\n const absolutePath = path.resolve(rootDir, relativePath);\n const normalizedRoot = `${path.resolve(rootDir)}${path.sep}`;\n\n if (absolutePath !== path.resolve(rootDir) && !absolutePath.startsWith(normalizedRoot)) {\n return undefined;\n }\n\n return absolutePath;\n}\n\nexport function isSafeRelativePath(relativePath: string): boolean {\n if (!relativePath || relativePath.startsWith(\"/\") || relativePath.includes(\"\\0\")) {\n return false;\n }\n\n const normalizedParts = relativePath.split(/[\\\\/]+/).filter(Boolean);\n if (normalizedParts.includes(\"..\")) {\n return false;\n }\n\n return normalizedParts[0] !== \".git\";\n}\n\nexport async function shouldSyncRelativePath(\n context: RepoContext,\n relativePath: string\n): Promise<boolean> {\n if (!isSafeRelativePath(relativePath)) {\n return false;\n }\n\n try {\n await execFileAsync(\"git\", [\"check-ignore\", \"--quiet\", \"--\", relativePath], {\n cwd: context.rootDir,\n });\n return false;\n } catch (error) {\n const exitCode =\n typeof error === \"object\" && error !== null && \"code\" in error ? error.code : undefined;\n return exitCode === 1;\n }\n}\n","import { z } from \"zod\";\n\nconst SyncBaseMessageSchema = z.object({\n peerId: z.string().min(1),\n sentAt: z.number().finite(),\n});\n\nexport const SyncHelloMessageSchema = SyncBaseMessageSchema.extend({\n type: z.literal(\"hello\"),\n role: z.union([z.literal(\"share\"), z.literal(\"join\")]),\n});\n\nexport const SyncFileMessageSchema = SyncBaseMessageSchema.extend({\n type: z.literal(\"file\"),\n path: z.string().min(1),\n contentBase64: z.string(),\n mtimeMs: z.number().finite(),\n});\n\nexport const SyncDeleteMessageSchema = SyncBaseMessageSchema.extend({\n type: z.literal(\"delete\"),\n path: z.string().min(1),\n mtimeMs: z.number().finite(),\n});\n\nexport const SyncSnapshotCompleteMessageSchema = SyncBaseMessageSchema.extend({\n type: z.literal(\"snapshot-complete\"),\n fileCount: z.number().int().nonnegative(),\n});\n\nexport const SyncMessageSchema = z.discriminatedUnion(\"type\", [\n SyncHelloMessageSchema,\n SyncFileMessageSchema,\n SyncDeleteMessageSchema,\n SyncSnapshotCompleteMessageSchema,\n]);\n\nexport type SyncMessage = z.infer<typeof SyncMessageSchema>;\nexport type SyncFileMutationMessage = Extract<SyncMessage, { type: \"file\" | \"delete\" }>;\n\nexport function encodeSyncMessage(message: SyncMessage): string {\n return JSON.stringify(SyncMessageSchema.parse(message));\n}\n\nexport function decodeSyncMessage(value: unknown): SyncMessage | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n try {\n return SyncMessageSchema.parse(JSON.parse(value));\n } catch {\n return undefined;\n }\n}\n"],"mappings":"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","names":["process","path","path","process"]}
|
package/dist/chunk-KSW6QT5Q.js
DELETED
|
@@ -1,628 +0,0 @@
|
|
|
1
|
-
// src/cli/help-specs.ts
|
|
2
|
-
var commandList = [
|
|
3
|
-
"- `cngkit login` - open Curly.ng login, or print the URL in headless shells.",
|
|
4
|
-
"- `cngkit coderoom ...` - share or join a live developer room for a working tree.",
|
|
5
|
-
"- `cngkit scrub [path]` - scan for secrets; rewrite only when `--yes` is passed.",
|
|
6
|
-
"- `cngkit transcripts ...` - list, read, and grep local Claude/Codex transcripts.",
|
|
7
|
-
"- `cngkit knowledges ...` - search and read the hosted Harness knowledge catalog.",
|
|
8
|
-
"- `cngkit hookify ...` - forward local hook events to Hookify."
|
|
9
|
-
].join("\n");
|
|
10
|
-
var coderoomCommandList = [
|
|
11
|
-
"- `share [room-code]` - start a live room from the current directory.",
|
|
12
|
-
"- `join <room-code>` - join another developer's live room from the current directory."
|
|
13
|
-
].join("\n");
|
|
14
|
-
var knowledgesCommandList = [
|
|
15
|
-
"- `status` - print remote catalog state.",
|
|
16
|
-
"- `audiences` - list valid audience filters.",
|
|
17
|
-
"- `search <query>` - search over Postgres-backed knowledges records.",
|
|
18
|
-
"- `list [query]` - list known subskills.",
|
|
19
|
-
"- `files [query]` - list uploaded catalog files.",
|
|
20
|
-
"- `read <file-path>` - Claude-style file read.",
|
|
21
|
-
"- `grep <pattern>` - Claude-style content search.",
|
|
22
|
-
"- `glob [pattern]` - Claude-style file discovery."
|
|
23
|
-
].join("\n");
|
|
24
|
-
var hookifyCommandList = [
|
|
25
|
-
"- `ingest` - read a raw hook payload from stdin and forward it to the backend."
|
|
26
|
-
].join("\n");
|
|
27
|
-
var helpTopics = [
|
|
28
|
-
{
|
|
29
|
-
title: "cngkit",
|
|
30
|
-
aliases: ["", "overview", "help"],
|
|
31
|
-
body: `# cngkit
|
|
32
|
-
|
|
33
|
-
Curly.ng operator CLI for shared code rooms, safe local cleanup, local agent transcripts, and hosted Harness knowledges.
|
|
34
|
-
|
|
35
|
-
## Run Now
|
|
36
|
-
|
|
37
|
-
\`\`\`bash
|
|
38
|
-
npx --yes cngkit@latest --help
|
|
39
|
-
npx --yes cngkit@latest knowledges search Cloudflare --limit 3
|
|
40
|
-
\`\`\`
|
|
41
|
-
|
|
42
|
-
## Installed Usage
|
|
43
|
-
|
|
44
|
-
\`\`\`bash
|
|
45
|
-
cngkit <command> [options]
|
|
46
|
-
\`\`\`
|
|
47
|
-
|
|
48
|
-
## Global Options
|
|
49
|
-
|
|
50
|
-
\`\`\`bash
|
|
51
|
-
cngkit --format text|json|markdown ...
|
|
52
|
-
cngkit --no-color ...
|
|
53
|
-
\`\`\`
|
|
54
|
-
|
|
55
|
-
## Commands
|
|
56
|
-
|
|
57
|
-
${commandList}
|
|
58
|
-
|
|
59
|
-
## Help Map
|
|
60
|
-
|
|
61
|
-
\`\`\`bash
|
|
62
|
-
cngkit help <topic>
|
|
63
|
-
cngkit <command> --help
|
|
64
|
-
cngkit coderoom --help
|
|
65
|
-
cngkit coderoom <subcommand> --help
|
|
66
|
-
cngkit transcripts --help
|
|
67
|
-
cngkit knowledges --help
|
|
68
|
-
cngkit knowledges <subcommand> --help
|
|
69
|
-
cngkit hookify --help
|
|
70
|
-
cngkit hookify ingest --help
|
|
71
|
-
\`\`\`
|
|
72
|
-
|
|
73
|
-
## AI And Scripts
|
|
74
|
-
|
|
75
|
-
- Help renders as structured terminal text by default, even in pipes.
|
|
76
|
-
- Use \`--format json\` or \`--json\` on read-only data commands for typed payloads.
|
|
77
|
-
- Use \`--format markdown\` only when raw Markdown source is intentional.
|
|
78
|
-
- Use \`--no-color\` or \`CNGKIT_COLOR=never\` for logs, screenshots, and strict plain text.
|
|
79
|
-
- Use \`npm_config_progress=false npx --yes cngkit@latest ...\` for clean one-shot npx captures.
|
|
80
|
-
|
|
81
|
-
## Backend
|
|
82
|
-
|
|
83
|
-
API: \`https://curly.ng\`
|
|
84
|
-
`
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
title: "login",
|
|
88
|
-
aliases: ["login"],
|
|
89
|
-
body: `# cngkit login
|
|
90
|
-
|
|
91
|
-
Open Curly.ng login in a browser. In headless shells, print the URL so an agent can show it to the operator.
|
|
92
|
-
|
|
93
|
-
## Usage
|
|
94
|
-
|
|
95
|
-
\`\`\`bash
|
|
96
|
-
npx --yes cngkit@latest login
|
|
97
|
-
cngkit login
|
|
98
|
-
\`\`\`
|
|
99
|
-
|
|
100
|
-
## Output
|
|
101
|
-
|
|
102
|
-
- First line names the login URL being opened.
|
|
103
|
-
- If no browser opener exists, the CLI prints a direct URL.
|
|
104
|
-
- No credentials are printed or persisted by this command.
|
|
105
|
-
`
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
title: "transcripts",
|
|
109
|
-
aliases: ["transcripts", "transcript"],
|
|
110
|
-
body: `# cngkit transcripts
|
|
111
|
-
|
|
112
|
-
Read local Claude and Codex transcript JSONL files.
|
|
113
|
-
|
|
114
|
-
This is local-only operator tooling. It does not call Curly.ng and it does not upload transcript content.
|
|
115
|
-
|
|
116
|
-
## Usage
|
|
117
|
-
|
|
118
|
-
\`\`\`bash
|
|
119
|
-
cngkit transcripts list [--source all|codex|claude] [--limit <n>] [--json|--format json]
|
|
120
|
-
cngkit transcripts read <path-or-session-id> [--source all|codex|claude] [--limit <n>] [--include-internal] [--json|--format json]
|
|
121
|
-
cngkit transcripts grep <query> [--source all|codex|claude] [--limit <n>] [--file-limit <n>] [--include-internal] [--json|--format json]
|
|
122
|
-
\`\`\`
|
|
123
|
-
|
|
124
|
-
## Sources
|
|
125
|
-
|
|
126
|
-
- \`~/.codex/sessions\`
|
|
127
|
-
- \`~/.codex/archived_sessions\`
|
|
128
|
-
- \`~/.claude/projects\`
|
|
129
|
-
- \`~/.claude/history.jsonl\`
|
|
130
|
-
|
|
131
|
-
## Defaults
|
|
132
|
-
|
|
133
|
-
- \`list\`: newest 12 transcript files.
|
|
134
|
-
- \`read\`: newest 80 user/assistant entries from the selected file.
|
|
135
|
-
- \`grep\`: first 80 matching user/assistant entries from the newest 60 files.
|
|
136
|
-
- \`--source\`: \`all\`.
|
|
137
|
-
|
|
138
|
-
## Output
|
|
139
|
-
|
|
140
|
-
- Text mode prints source, role, timestamp when available, and extracted message text.
|
|
141
|
-
- Internal developer/system payloads and hook/tool noise are skipped unless \`--include-internal\` is passed.
|
|
142
|
-
- Direct file paths, home-relative paths, and partial session ids are accepted by \`read\`.
|
|
143
|
-
`
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
title: "hookify",
|
|
147
|
-
aliases: ["hookify", "hooks"],
|
|
148
|
-
body: `# cngkit hookify
|
|
149
|
-
|
|
150
|
-
Forward local hook events to Hookify.
|
|
151
|
-
|
|
152
|
-
Hookify is the Curly.ng hook processing surface. The CLI stays small: it reads hook payloads locally, forwards raw stdin to the backend, prints the backend stdout, and exits with the backend exit code. If forwarding fails, it exits with code 0.
|
|
153
|
-
|
|
154
|
-
## Usage
|
|
155
|
-
|
|
156
|
-
\`\`\`bash
|
|
157
|
-
cngkit hookify <subcommand> [options]
|
|
158
|
-
\`\`\`
|
|
159
|
-
|
|
160
|
-
## Subcommands
|
|
161
|
-
|
|
162
|
-
${hookifyCommandList}
|
|
163
|
-
`
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
title: "hookify ingest",
|
|
167
|
-
aliases: ["hookify-ingest"],
|
|
168
|
-
body: `# cngkit hookify ingest
|
|
169
|
-
|
|
170
|
-
Read a raw hook payload from stdin and forward it to Hookify.
|
|
171
|
-
|
|
172
|
-
## Usage
|
|
173
|
-
|
|
174
|
-
\`\`\`bash
|
|
175
|
-
cngkit hookify ingest [--event <name>] [--async]
|
|
176
|
-
\`\`\`
|
|
177
|
-
|
|
178
|
-
## Behavior
|
|
179
|
-
|
|
180
|
-
- Reads stdin exactly as the hook provides it.
|
|
181
|
-
- Sends the payload to \`POST /api/hookify/ingest\` as \`application/octet-stream\`.
|
|
182
|
-
- Prints backend \`stdout\` without extra formatting.
|
|
183
|
-
- Writes backend \`stderr\` when present.
|
|
184
|
-
- Uses backend \`exitCode\` as the process exit code.
|
|
185
|
-
- Falls back to exit code \`0\` if the backend request fails.
|
|
186
|
-
|
|
187
|
-
## Example
|
|
188
|
-
|
|
189
|
-
\`\`\`bash
|
|
190
|
-
printf '{"hook":"PreToolUse"}' | cngkit hookify ingest --event PreToolUse
|
|
191
|
-
\`\`\`
|
|
192
|
-
`
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
title: "coderoom",
|
|
196
|
-
aliases: ["coderoom", "code-room", "repo-sync"],
|
|
197
|
-
body: `# cngkit coderoom
|
|
198
|
-
|
|
199
|
-
Create or join a temporary live room for sharing a working tree over the Curly backend.
|
|
200
|
-
|
|
201
|
-
## Usage
|
|
202
|
-
|
|
203
|
-
\`\`\`bash
|
|
204
|
-
cngkit coderoom <subcommand> [options]
|
|
205
|
-
\`\`\`
|
|
206
|
-
|
|
207
|
-
## Subcommands
|
|
208
|
-
|
|
209
|
-
${coderoomCommandList}
|
|
210
|
-
|
|
211
|
-
## Common Flow
|
|
212
|
-
|
|
213
|
-
\`\`\`bash
|
|
214
|
-
npx --yes cngkit@latest coderoom share
|
|
215
|
-
npx --yes cngkit@latest coderoom join <room-code>
|
|
216
|
-
\`\`\`
|
|
217
|
-
|
|
218
|
-
## Behavior
|
|
219
|
-
|
|
220
|
-
- Connects to \`/api/cng/sync/:roomCode\` on the configured Curly backend.
|
|
221
|
-
- Uses WebSocket transport backed by the \`CngSyncRoom\` Durable Object.
|
|
222
|
-
- Sends an initial snapshot, then file and delete events.
|
|
223
|
-
- Last received change wins.
|
|
224
|
-
- Current rooms are live relays, not durable cloud storage.
|
|
225
|
-
`
|
|
226
|
-
},
|
|
227
|
-
{
|
|
228
|
-
title: "coderoom share",
|
|
229
|
-
aliases: ["coderoom-share"],
|
|
230
|
-
body: `# cngkit coderoom share
|
|
231
|
-
|
|
232
|
-
Start a live repository sync room from the current directory.
|
|
233
|
-
|
|
234
|
-
## Usage
|
|
235
|
-
|
|
236
|
-
\`\`\`bash
|
|
237
|
-
cngkit coderoom share [room-code]
|
|
238
|
-
\`\`\`
|
|
239
|
-
|
|
240
|
-
## Behavior
|
|
241
|
-
|
|
242
|
-
- Connects to \`/api/cng/sync/:roomCode\` on the configured Curly backend.
|
|
243
|
-
- Uses WebSocket transport backed by the \`CngSyncRoom\` Durable Object.
|
|
244
|
-
- Sends an initial snapshot, then file and delete events.
|
|
245
|
-
- Last received change wins.
|
|
246
|
-
|
|
247
|
-
## Filesystem Contract
|
|
248
|
-
|
|
249
|
-
- Preserves \`.git/\`.
|
|
250
|
-
- Preserves files ignored by the repo's \`.gitignore\`.
|
|
251
|
-
- Sends regular files as base64 payloads in the sync protocol.
|
|
252
|
-
|
|
253
|
-
## Output
|
|
254
|
-
|
|
255
|
-
- Prints room code, repo root, peer id, backend health, and concise sync events.
|
|
256
|
-
- Keeps running until the socket closes or the process receives a termination signal.
|
|
257
|
-
`
|
|
258
|
-
},
|
|
259
|
-
{
|
|
260
|
-
title: "coderoom join",
|
|
261
|
-
aliases: ["coderoom-join"],
|
|
262
|
-
body: `# cngkit coderoom join
|
|
263
|
-
|
|
264
|
-
Join an existing live repository sync room from the current directory.
|
|
265
|
-
|
|
266
|
-
## Usage
|
|
267
|
-
|
|
268
|
-
\`\`\`bash
|
|
269
|
-
cngkit coderoom join <room-code>
|
|
270
|
-
\`\`\`
|
|
271
|
-
|
|
272
|
-
## Behavior
|
|
273
|
-
|
|
274
|
-
Same transport and filesystem contract as \`cngkit coderoom share\`. The supplied room code selects the Durable Object room.
|
|
275
|
-
|
|
276
|
-
## Output
|
|
277
|
-
|
|
278
|
-
- Prints backend health, room code, repo root, peer id, and concise sync events.
|
|
279
|
-
- Missing room code exits with a usage error.
|
|
280
|
-
`
|
|
281
|
-
},
|
|
282
|
-
{
|
|
283
|
-
title: "scrub",
|
|
284
|
-
aliases: ["scrub"],
|
|
285
|
-
body: `# cngkit scrub
|
|
286
|
-
|
|
287
|
-
Scan a file or directory for secrets with TruffleHog. Report-only is the default.
|
|
288
|
-
|
|
289
|
-
## Usage
|
|
290
|
-
|
|
291
|
-
\`\`\`bash
|
|
292
|
-
cngkit scrub [path]
|
|
293
|
-
cngkit scrub [path] --yes
|
|
294
|
-
\`\`\`
|
|
295
|
-
|
|
296
|
-
## Safety
|
|
297
|
-
|
|
298
|
-
- Default mode does not rewrite files.
|
|
299
|
-
- Inline masking rewrites files and requires \`--yes\`.
|
|
300
|
-
- Raw and redacted secret values are never printed.
|
|
301
|
-
|
|
302
|
-
## Requirements
|
|
303
|
-
|
|
304
|
-
- \`trufflehog\` must be available on \`PATH\`.
|
|
305
|
-
|
|
306
|
-
## Mask Format
|
|
307
|
-
|
|
308
|
-
\`\`\`text
|
|
309
|
-
[CNGKIT_SECRET:<detector>:<verified|unverified>]
|
|
310
|
-
\`\`\`
|
|
311
|
-
`
|
|
312
|
-
},
|
|
313
|
-
{
|
|
314
|
-
title: "knowledges",
|
|
315
|
-
aliases: ["knowledges", "knowledge"],
|
|
316
|
-
body: `# cngkit knowledges
|
|
317
|
-
|
|
318
|
-
Search and read the hosted Harness knowledges catalog from the Curly backend.
|
|
319
|
-
|
|
320
|
-
## Usage
|
|
321
|
-
|
|
322
|
-
\`\`\`bash
|
|
323
|
-
cngkit knowledges <subcommand> [options]
|
|
324
|
-
\`\`\`
|
|
325
|
-
|
|
326
|
-
## Subcommands
|
|
327
|
-
|
|
328
|
-
${knowledgesCommandList}
|
|
329
|
-
|
|
330
|
-
## Progressive Help
|
|
331
|
-
|
|
332
|
-
\`\`\`bash
|
|
333
|
-
cngkit help knowledges <subcommand>
|
|
334
|
-
cngkit knowledges <subcommand> --help
|
|
335
|
-
cngkit knowledges read --help
|
|
336
|
-
cngkit knowledges grep --help
|
|
337
|
-
cngkit knowledges glob --help
|
|
338
|
-
\`\`\`
|
|
339
|
-
|
|
340
|
-
## Common Examples
|
|
341
|
-
|
|
342
|
-
\`\`\`bash
|
|
343
|
-
npx --yes cngkit@latest knowledges search Cloudflare --limit 3
|
|
344
|
-
npx --yes cngkit@latest knowledges read /libraries/lib-cloudflare/SUBSKILL.md --limit 80
|
|
345
|
-
npx --yes cngkit@latest knowledges grep Cloudflare --path /libraries/lib-cloudflare --output-mode files_with_matches
|
|
346
|
-
npx --yes cngkit@latest knowledges glob "**/*.md" --path /libraries/lib-cloudflare
|
|
347
|
-
\`\`\`
|
|
348
|
-
|
|
349
|
-
## AI-Friendly Output
|
|
350
|
-
|
|
351
|
-
- Default output is structured text intended to be directly usable by people and agents.
|
|
352
|
-
- \`read\` renders Markdown files by default and prints exact source with \`--format markdown\`.
|
|
353
|
-
- \`grep --output-mode content\` prints \`path:line\` blocks.
|
|
354
|
-
- \`grep --output-mode files_with_matches\` and \`glob\` print one path per line.
|
|
355
|
-
- \`--format json\` and \`--json\` print typed backend payloads for machine consumption.
|
|
356
|
-
`
|
|
357
|
-
},
|
|
358
|
-
{
|
|
359
|
-
title: "knowledges status",
|
|
360
|
-
aliases: ["knowledges-status", "status"],
|
|
361
|
-
body: `# cngkit knowledges status
|
|
362
|
-
|
|
363
|
-
Print remote Harness catalog state.
|
|
364
|
-
|
|
365
|
-
## Usage
|
|
366
|
-
|
|
367
|
-
\`\`\`bash
|
|
368
|
-
cngkit knowledges status [--json|--format json]
|
|
369
|
-
\`\`\`
|
|
370
|
-
|
|
371
|
-
## Output
|
|
372
|
-
|
|
373
|
-
- Text mode prints catalog name, file count, blob count, database binding, and latest run when present.
|
|
374
|
-
- \`--format json\` and \`--json\` print the backend data payload.
|
|
375
|
-
`
|
|
376
|
-
},
|
|
377
|
-
{
|
|
378
|
-
title: "knowledges audiences",
|
|
379
|
-
aliases: ["knowledges-audiences", "audiences"],
|
|
380
|
-
body: `# cngkit knowledges audiences
|
|
381
|
-
|
|
382
|
-
List valid audience filters for catalog browsing.
|
|
383
|
-
|
|
384
|
-
## Usage
|
|
385
|
-
|
|
386
|
-
\`\`\`bash
|
|
387
|
-
cngkit knowledges audiences [--json|--format json]
|
|
388
|
-
\`\`\`
|
|
389
|
-
|
|
390
|
-
## Use When
|
|
391
|
-
|
|
392
|
-
Run this before \`cngkit knowledges files --audience <id>\`.
|
|
393
|
-
`
|
|
394
|
-
},
|
|
395
|
-
{
|
|
396
|
-
title: "knowledges search",
|
|
397
|
-
aliases: ["knowledges-search", "search"],
|
|
398
|
-
body: `# cngkit knowledges search
|
|
399
|
-
|
|
400
|
-
Search the hosted Harness index for relevant skills and subskills.
|
|
401
|
-
|
|
402
|
-
## Usage
|
|
403
|
-
|
|
404
|
-
\`\`\`bash
|
|
405
|
-
cngkit knowledges search <query> [--limit <n>] [--json|--format json]
|
|
406
|
-
\`\`\`
|
|
407
|
-
|
|
408
|
-
## Defaults
|
|
409
|
-
|
|
410
|
-
- \`--limit\`: \`5\`
|
|
411
|
-
|
|
412
|
-
## Example
|
|
413
|
-
|
|
414
|
-
\`\`\`bash
|
|
415
|
-
npx --yes cngkit@latest knowledges search Cloudflare --limit 3
|
|
416
|
-
\`\`\`
|
|
417
|
-
`
|
|
418
|
-
},
|
|
419
|
-
{
|
|
420
|
-
title: "knowledges list",
|
|
421
|
-
aliases: ["knowledges-list", "list"],
|
|
422
|
-
body: `# cngkit knowledges list
|
|
423
|
-
|
|
424
|
-
List hosted Harness subskills, optionally filtered by query.
|
|
425
|
-
|
|
426
|
-
## Usage
|
|
427
|
-
|
|
428
|
-
\`\`\`bash
|
|
429
|
-
cngkit knowledges list [query] [--limit <n>] [--json|--format json]
|
|
430
|
-
\`\`\`
|
|
431
|
-
|
|
432
|
-
## Defaults
|
|
433
|
-
|
|
434
|
-
- \`--limit\`: \`25\`
|
|
435
|
-
|
|
436
|
-
## Example
|
|
437
|
-
|
|
438
|
-
\`\`\`bash
|
|
439
|
-
cngkit knowledges list cloudflare --limit 10
|
|
440
|
-
\`\`\`
|
|
441
|
-
`
|
|
442
|
-
},
|
|
443
|
-
{
|
|
444
|
-
title: "knowledges files",
|
|
445
|
-
aliases: ["knowledges-files", "files"],
|
|
446
|
-
body: `# cngkit knowledges files
|
|
447
|
-
|
|
448
|
-
List uploaded Harness catalog files, optionally filtered by query or audience.
|
|
449
|
-
|
|
450
|
-
## Usage
|
|
451
|
-
|
|
452
|
-
\`\`\`bash
|
|
453
|
-
cngkit knowledges files [query] [--audience <id>] [--limit <n>] [--json|--format json]
|
|
454
|
-
\`\`\`
|
|
455
|
-
|
|
456
|
-
## Defaults
|
|
457
|
-
|
|
458
|
-
- \`--limit\`: \`25\`
|
|
459
|
-
- \`--audience\`: omitted
|
|
460
|
-
|
|
461
|
-
## Example
|
|
462
|
-
|
|
463
|
-
\`\`\`bash
|
|
464
|
-
cngkit knowledges files cloudflare --limit 10
|
|
465
|
-
cngkit knowledges files "vector search" --audience builders
|
|
466
|
-
\`\`\`
|
|
467
|
-
`
|
|
468
|
-
},
|
|
469
|
-
{
|
|
470
|
-
title: "knowledges read",
|
|
471
|
-
aliases: ["knowledges-read", "read"],
|
|
472
|
-
body: `# cngkit knowledges read
|
|
473
|
-
|
|
474
|
-
Read a hosted Harness catalog file by path.
|
|
475
|
-
|
|
476
|
-
## Usage
|
|
477
|
-
|
|
478
|
-
\`\`\`bash
|
|
479
|
-
cngkit knowledges read <file-path> [--offset <n>] [--limit <n>] [--json|--format json|--format markdown]
|
|
480
|
-
\`\`\`
|
|
481
|
-
|
|
482
|
-
## Inputs
|
|
483
|
-
|
|
484
|
-
- \`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\`.
|
|
485
|
-
- \`--offset\`: zero-based starting line. Default: \`0\`.
|
|
486
|
-
- \`--limit\`: maximum lines. Default in CLI: \`200\`. Backend max: \`2000\`.
|
|
487
|
-
|
|
488
|
-
## Output
|
|
489
|
-
|
|
490
|
-
- Text mode renders Markdown files for terminal reading.
|
|
491
|
-
- \`--format markdown\` prints the exact returned file content.
|
|
492
|
-
- If truncated, a final bracketed truncation note is printed after the content.
|
|
493
|
-
- \`--format json\` and \`--json\` print \`{ file_path, content, total_lines, offset, limit, truncated }\`.
|
|
494
|
-
|
|
495
|
-
## Example
|
|
496
|
-
|
|
497
|
-
\`\`\`bash
|
|
498
|
-
npx --yes cngkit@latest knowledges read /libraries/lib-cloudflare/SUBSKILL.md --limit 80
|
|
499
|
-
\`\`\`
|
|
500
|
-
`
|
|
501
|
-
},
|
|
502
|
-
{
|
|
503
|
-
title: "knowledges grep",
|
|
504
|
-
aliases: ["knowledges-grep", "grep"],
|
|
505
|
-
body: `# cngkit knowledges grep
|
|
506
|
-
|
|
507
|
-
Search inside hosted Harness catalog files with a JavaScript regular expression.
|
|
508
|
-
|
|
509
|
-
## Usage
|
|
510
|
-
|
|
511
|
-
\`\`\`bash
|
|
512
|
-
cngkit knowledges grep <pattern> [--path <path>] [--include <glob>] [--output-mode <mode>] [--context <n>] [--case-insensitive] [--json|--format json]
|
|
513
|
-
\`\`\`
|
|
514
|
-
|
|
515
|
-
## Inputs
|
|
516
|
-
|
|
517
|
-
- \`pattern\`: JavaScript regular expression source.
|
|
518
|
-
- \`--path\`: catalog path prefix. Default: \`skills\`.
|
|
519
|
-
- \`--include\`: filename include filter. Default: \`*\`.
|
|
520
|
-
- Modes: content, files_with_matches, or count.
|
|
521
|
-
- \`--output-mode\`: \`content\`, \`files_with_matches\`, or \`count\`. Default: \`content\`.
|
|
522
|
-
- \`--context\`: context lines around content matches. Default: \`0\`. Backend max: \`20\`.
|
|
523
|
-
- \`--case-insensitive\`: maps to backend \`case_insensitive=true\`.
|
|
524
|
-
|
|
525
|
-
## Output
|
|
526
|
-
|
|
527
|
-
- \`content\`: prints blocks as \`file_path:line_number\`, optional context lines, then \`> matching line\`.
|
|
528
|
-
- \`files_with_matches\`: prints one matching file path per line.
|
|
529
|
-
- \`count\`: prints \`file_path: match_count\` lines.
|
|
530
|
-
- \`--format json\` and \`--json\` print the typed backend response union.
|
|
531
|
-
|
|
532
|
-
## Examples
|
|
533
|
-
|
|
534
|
-
\`\`\`bash
|
|
535
|
-
npx --yes cngkit@latest knowledges grep Cloudflare --path /libraries/lib-cloudflare --output-mode files_with_matches
|
|
536
|
-
npx --yes cngkit@latest knowledges grep "Postgres|Hyperdrive" --path /libraries/lib-cloudflare --context 2
|
|
537
|
-
\`\`\`
|
|
538
|
-
`
|
|
539
|
-
},
|
|
540
|
-
{
|
|
541
|
-
title: "knowledges glob",
|
|
542
|
-
aliases: ["knowledges-glob", "glob"],
|
|
543
|
-
body: `# cngkit knowledges glob
|
|
544
|
-
|
|
545
|
-
Find hosted Harness catalog files by glob pattern.
|
|
546
|
-
|
|
547
|
-
## Usage
|
|
548
|
-
|
|
549
|
-
\`\`\`bash
|
|
550
|
-
cngkit knowledges glob [pattern] [--path <path>] [--json|--format json]
|
|
551
|
-
\`\`\`
|
|
552
|
-
|
|
553
|
-
## Inputs
|
|
554
|
-
|
|
555
|
-
- \`pattern\`: supported glob pattern. CLI default: \`**/*.md\`.
|
|
556
|
-
- \`--path\`: catalog path prefix. Default: \`skills\`.
|
|
557
|
-
|
|
558
|
-
## Supported Patterns
|
|
559
|
-
|
|
560
|
-
- \`**/*.md\`
|
|
561
|
-
- \`**/*.SUBSKILL.md\`
|
|
562
|
-
- \`**/SKILL.md\`
|
|
563
|
-
- \`*.md\`
|
|
564
|
-
- \`*.SUBSKILL.md\`
|
|
565
|
-
- \`SKILL.md\`
|
|
566
|
-
|
|
567
|
-
## Output
|
|
568
|
-
|
|
569
|
-
- Text mode prints one file path per line.
|
|
570
|
-
- If truncated, a final bracketed truncation note is printed.
|
|
571
|
-
- \`--format json\` and \`--json\` print \`{ files, total_files, truncated }\`.
|
|
572
|
-
|
|
573
|
-
## Example
|
|
574
|
-
|
|
575
|
-
\`\`\`bash
|
|
576
|
-
npx --yes cngkit@latest knowledges glob "**/*.md" --path /libraries/lib-cloudflare
|
|
577
|
-
\`\`\`
|
|
578
|
-
`
|
|
579
|
-
}
|
|
580
|
-
];
|
|
581
|
-
var helpTopicNames = helpTopics.filter((topic) => topic.title !== "cngkit").map((topic) => topic.title).sort();
|
|
582
|
-
var helpTopicByAlias = /* @__PURE__ */ new Map();
|
|
583
|
-
for (const topic of helpTopics) {
|
|
584
|
-
for (const alias of topic.aliases) {
|
|
585
|
-
helpTopicByAlias.set(alias, topic);
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
function formatCngkitHelp(topicName) {
|
|
589
|
-
const normalizedTopicName = normalizeHelpTopicName(topicName);
|
|
590
|
-
const topic = helpTopicByAlias.get(normalizedTopicName);
|
|
591
|
-
if (topic) {
|
|
592
|
-
return topic.body.trim();
|
|
593
|
-
}
|
|
594
|
-
if (normalizedTopicName === "") {
|
|
595
|
-
return helpTopicByAlias.get("")?.body.trim() ?? "";
|
|
596
|
-
}
|
|
597
|
-
return formatUnknownHelpTopic(normalizedTopicName);
|
|
598
|
-
}
|
|
599
|
-
function formatKnowledgesHelp(topicName) {
|
|
600
|
-
const normalizedTopicName = normalizeHelpTopicName(topicName);
|
|
601
|
-
const topicKey = normalizedTopicName ? `knowledges-${normalizedTopicName}` : "knowledges";
|
|
602
|
-
return formatCngkitHelp(topicKey);
|
|
603
|
-
}
|
|
604
|
-
function normalizeHelpTopicName(value) {
|
|
605
|
-
return value?.trim().toLowerCase().replace(/\s+/g, "-") ?? "";
|
|
606
|
-
}
|
|
607
|
-
function formatUnknownHelpTopic(topicName) {
|
|
608
|
-
return `# cngkit help
|
|
609
|
-
|
|
610
|
-
No help topic named \`${topicName}\`.
|
|
611
|
-
|
|
612
|
-
## Available Topics
|
|
613
|
-
|
|
614
|
-
${helpTopicNames.map((name) => `- \`${name}\``).join("\n")}
|
|
615
|
-
|
|
616
|
-
## Usage
|
|
617
|
-
|
|
618
|
-
\`\`\`bash
|
|
619
|
-
cngkit help <topic>
|
|
620
|
-
cngkit <command> --help
|
|
621
|
-
\`\`\``;
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
export {
|
|
625
|
-
formatCngkitHelp,
|
|
626
|
-
formatKnowledgesHelp
|
|
627
|
-
};
|
|
628
|
-
//# sourceMappingURL=chunk-KSW6QT5Q.js.map
|