cngkit 1.1.17 → 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 +100 -7
- package/dist/chunk-3A6GRNEV.js +1590 -0
- package/dist/chunk-3A6GRNEV.js.map +1 -0
- package/dist/{chunk-HRFI2IEP.js → chunk-7SO75QXJ.js} +886 -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-5ZNV3FDG.js → chunk-GBONV6XP.js} +16 -4
- package/dist/chunk-GBONV6XP.js.map +1 -0
- package/dist/chunk-L6ZVQRSY.js +569 -0
- package/dist/chunk-L6ZVQRSY.js.map +1 -0
- package/dist/{chunk-VCWNKNUE.js → chunk-NGEWD4BW.js} +10 -1
- package/dist/chunk-NGEWD4BW.js.map +1 -0
- package/dist/chunk-TYDIBWZV.js +35 -0
- package/dist/chunk-TYDIBWZV.js.map +1 -0
- package/dist/{chunk-GT2MTS6E.js → chunk-X4E7NAN4.js} +2 -2
- package/dist/cli.js +82 -16
- 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 +25 -0
- package/dist/commands/hookify/index.js.map +1 -0
- package/dist/commands/hookify/ingest.js +127 -0
- package/dist/commands/hookify/ingest.js.map +1 -0
- 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 +40 -0
- package/dist/commands/knowledges/ls.js.map +1 -0
- 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-5ZNV3FDG.js.map +0 -1
- package/dist/chunk-BL3XMLIH.js +0 -573
- package/dist/chunk-BL3XMLIH.js.map +0 -1
- package/dist/chunk-HRFI2IEP.js.map +0 -1
- package/dist/chunk-K36DKQWH.js +0 -327
- package/dist/chunk-K36DKQWH.js.map +0 -1
- package/dist/chunk-VCWNKNUE.js.map +0 -1
- package/dist/chunk-WYJTGGMN.js +0 -222
- package/dist/chunk-WYJTGGMN.js.map +0 -1
- /package/dist/{chunk-GT2MTS6E.js.map → chunk-X4E7NAN4.js.map} +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runKnowTailCommand
|
|
3
|
+
} from "../../chunk-L6ZVQRSY.js";
|
|
4
|
+
import "../../chunk-XQGLUQFM.js";
|
|
5
|
+
import "../../chunk-3A6GRNEV.js";
|
|
6
|
+
import "../../chunk-TYDIBWZV.js";
|
|
7
|
+
import {
|
|
8
|
+
JsonOutputOptionsSchema,
|
|
9
|
+
RequiredFilePathArgsSchema
|
|
10
|
+
} from "../../chunk-NGEWD4BW.js";
|
|
11
|
+
import {
|
|
12
|
+
CommandRunner
|
|
13
|
+
} from "../../chunk-X4E7NAN4.js";
|
|
14
|
+
import "../../chunk-7SO75QXJ.js";
|
|
15
|
+
import "../../chunk-PZ5AY32C.js";
|
|
16
|
+
|
|
17
|
+
// src/commands/knowledges/tail.tsx
|
|
18
|
+
import { option } from "pastel";
|
|
19
|
+
import { z } from "zod";
|
|
20
|
+
import { jsx } from "react/jsx-runtime";
|
|
21
|
+
var description = "Print the last lines of a remote catalog file";
|
|
22
|
+
var args = RequiredFilePathArgsSchema;
|
|
23
|
+
var options = JsonOutputOptionsSchema.extend({
|
|
24
|
+
lines: z.number().optional().describe(
|
|
25
|
+
option({
|
|
26
|
+
alias: "n",
|
|
27
|
+
description: "Number of lines",
|
|
28
|
+
valueDescription: "n"
|
|
29
|
+
})
|
|
30
|
+
)
|
|
31
|
+
});
|
|
32
|
+
function TailCommand({ args: args2, options: options2 }) {
|
|
33
|
+
return /* @__PURE__ */ jsx(CommandRunner, { run: (output) => runKnowTailCommand(args2[0], options2, output) });
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
args,
|
|
37
|
+
TailCommand as default,
|
|
38
|
+
description,
|
|
39
|
+
options
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=tail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/knowledges/tail.tsx"],"sourcesContent":["import { option } from \"pastel\";\nimport { z } from \"zod\";\n\nimport { JsonOutputOptionsSchema, RequiredFilePathArgsSchema } from \"../../cli/options.js\";\nimport { runKnowTailCommand, type KnowTailCommandOptions } from \"../../features/knowledges/run-knowledges-command.js\";\nimport { CommandRunner } from \"../../cli/command-runner.js\";\n\nexport const description = \"Print the last lines of a remote catalog file\";\nexport const args = RequiredFilePathArgsSchema;\nexport const options = JsonOutputOptionsSchema.extend({\n lines: z\n .number()\n .optional()\n .describe(\n option({\n alias: \"n\",\n description: \"Number of lines\",\n valueDescription: \"n\",\n })\n ),\n});\n\ntype TailCommandProps = {\n readonly args: [string];\n readonly options: KnowTailCommandOptions;\n};\n\nexport default function TailCommand({ args, options }: TailCommandProps) {\n return <CommandRunner run={(output) => runKnowTailCommand(args[0], options, output)} />;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA,SAAS,cAAc;AACvB,SAAS,SAAS;AA2BT;AArBF,IAAM,cAAc;AACpB,IAAM,OAAO;AACb,IAAM,UAAU,wBAAwB,OAAO;AAAA,EACpD,OAAO,EACJ,OAAO,EACP,SAAS,EACT;AAAA,IACC,OAAO;AAAA,MACL,OAAO;AAAA,MACP,aAAa;AAAA,MACb,kBAAkB;AAAA,IACpB,CAAC;AAAA,EACH;AACJ,CAAC;AAOc,SAAR,YAA6B,EAAE,MAAAA,OAAM,SAAAC,SAAQ,GAAqB;AACvE,SAAO,oBAAC,iBAAc,KAAK,CAAC,WAAW,mBAAmBD,MAAK,CAAC,GAAGC,UAAS,MAAM,GAAG;AACvF;","names":["args","options"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runKnowTreeCommand
|
|
3
|
+
} from "../../chunk-L6ZVQRSY.js";
|
|
4
|
+
import "../../chunk-XQGLUQFM.js";
|
|
5
|
+
import "../../chunk-3A6GRNEV.js";
|
|
6
|
+
import "../../chunk-TYDIBWZV.js";
|
|
7
|
+
import {
|
|
8
|
+
JsonOutputOptionsSchema,
|
|
9
|
+
OptionalPathArgsSchema
|
|
10
|
+
} from "../../chunk-NGEWD4BW.js";
|
|
11
|
+
import {
|
|
12
|
+
CommandRunner
|
|
13
|
+
} from "../../chunk-X4E7NAN4.js";
|
|
14
|
+
import "../../chunk-7SO75QXJ.js";
|
|
15
|
+
import "../../chunk-PZ5AY32C.js";
|
|
16
|
+
|
|
17
|
+
// src/commands/knowledges/tree.tsx
|
|
18
|
+
import { option } from "pastel";
|
|
19
|
+
import { z } from "zod";
|
|
20
|
+
import { jsx } from "react/jsx-runtime";
|
|
21
|
+
var description = "Print a remote catalog directory tree";
|
|
22
|
+
var args = OptionalPathArgsSchema;
|
|
23
|
+
var options = JsonOutputOptionsSchema.extend({
|
|
24
|
+
depth: z.number().optional().describe(
|
|
25
|
+
option({
|
|
26
|
+
description: "Maximum tree depth",
|
|
27
|
+
valueDescription: "n"
|
|
28
|
+
})
|
|
29
|
+
),
|
|
30
|
+
limit: z.number().optional().describe(
|
|
31
|
+
option({
|
|
32
|
+
description: "Maximum entries",
|
|
33
|
+
valueDescription: "n"
|
|
34
|
+
})
|
|
35
|
+
)
|
|
36
|
+
});
|
|
37
|
+
function TreeCommand({ args: args2, options: options2 }) {
|
|
38
|
+
return /* @__PURE__ */ jsx(CommandRunner, { run: (output) => runKnowTreeCommand(args2[0], options2, output) });
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
args,
|
|
42
|
+
TreeCommand as default,
|
|
43
|
+
description,
|
|
44
|
+
options
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/knowledges/tree.tsx"],"sourcesContent":["import { option } from \"pastel\";\nimport { z } from \"zod\";\n\nimport { JsonOutputOptionsSchema, OptionalPathArgsSchema } from \"../../cli/options.js\";\nimport { runKnowTreeCommand, type KnowTreeCommandOptions } from \"../../features/knowledges/run-knowledges-command.js\";\nimport { CommandRunner } from \"../../cli/command-runner.js\";\n\nexport const description = \"Print a remote catalog directory tree\";\nexport const args = OptionalPathArgsSchema;\nexport const options = JsonOutputOptionsSchema.extend({\n depth: z\n .number()\n .optional()\n .describe(\n option({\n description: \"Maximum tree depth\",\n valueDescription: \"n\",\n })\n ),\n limit: z\n .number()\n .optional()\n .describe(\n option({\n description: \"Maximum entries\",\n valueDescription: \"n\",\n })\n ),\n});\n\ntype TreeCommandProps = {\n readonly args: [string?];\n readonly options: KnowTreeCommandOptions;\n};\n\nexport default function TreeCommand({ args, options }: TreeCommandProps) {\n return <CommandRunner run={(output) => runKnowTreeCommand(args[0], options, output)} />;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA,SAAS,cAAc;AACvB,SAAS,SAAS;AAmCT;AA7BF,IAAM,cAAc;AACpB,IAAM,OAAO;AACb,IAAM,UAAU,wBAAwB,OAAO;AAAA,EACpD,OAAO,EACJ,OAAO,EACP,SAAS,EACT;AAAA,IACC,OAAO;AAAA,MACL,aAAa;AAAA,MACb,kBAAkB;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EACF,OAAO,EACJ,OAAO,EACP,SAAS,EACT;AAAA,IACC,OAAO;AAAA,MACL,aAAa;AAAA,MACb,kBAAkB;AAAA,IACpB,CAAC;AAAA,EACH;AACJ,CAAC;AAOc,SAAR,YAA6B,EAAE,MAAAA,OAAM,SAAAC,SAAQ,GAAqB;AACvE,SAAO,oBAAC,iBAAc,KAAK,CAAC,WAAW,mBAAmBD,MAAK,CAAC,GAAGC,UAAS,MAAM,GAAG;AACvF;","names":["args","options"]}
|
package/dist/commands/login.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
GlobalOptionsSchema
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-NGEWD4BW.js";
|
|
4
4
|
import {
|
|
5
5
|
CommandRunner
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-X4E7NAN4.js";
|
|
7
7
|
import {
|
|
8
8
|
resolveApiBaseUrl
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-7SO75QXJ.js";
|
|
10
10
|
import "../chunk-PZ5AY32C.js";
|
|
11
11
|
|
|
12
12
|
// src/shared/browser.ts
|
package/dist/commands/scrub.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
GlobalOptionsSchema,
|
|
3
3
|
OptionalPathArgsSchema
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-NGEWD4BW.js";
|
|
5
5
|
import {
|
|
6
6
|
CommandRunner
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-X4E7NAN4.js";
|
|
8
|
+
import "../chunk-7SO75QXJ.js";
|
|
9
9
|
import "../chunk-PZ5AY32C.js";
|
|
10
10
|
|
|
11
11
|
// src/commands/scrub.tsx
|
|
@@ -6,16 +6,16 @@ import {
|
|
|
6
6
|
singleLine
|
|
7
7
|
} from "../chunk-XQGLUQFM.js";
|
|
8
8
|
import {
|
|
9
|
-
|
|
10
|
-
} from "../chunk-
|
|
9
|
+
renderCngkitHelp
|
|
10
|
+
} from "../chunk-3A6GRNEV.js";
|
|
11
11
|
import {
|
|
12
12
|
GlobalOptionsSchema,
|
|
13
13
|
TranscriptArgsSchema
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-NGEWD4BW.js";
|
|
15
15
|
import {
|
|
16
16
|
CommandRunner
|
|
17
|
-
} from "../chunk-
|
|
18
|
-
import "../chunk-
|
|
17
|
+
} from "../chunk-X4E7NAN4.js";
|
|
18
|
+
import "../chunk-7SO75QXJ.js";
|
|
19
19
|
import "../chunk-PZ5AY32C.js";
|
|
20
20
|
|
|
21
21
|
// src/commands/transcripts.tsx
|
|
@@ -295,7 +295,7 @@ async function runTranscriptCommand(args2, options2, output) {
|
|
|
295
295
|
const includeInternal = options2.includeInternal === true;
|
|
296
296
|
switch (action) {
|
|
297
297
|
case "help":
|
|
298
|
-
output.
|
|
298
|
+
output.component(renderCngkitHelp("transcripts"));
|
|
299
299
|
return;
|
|
300
300
|
case "list": {
|
|
301
301
|
const records = await listTranscriptRecords({ source, limit });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/transcripts.tsx","../../src/features/transcripts/reader.ts","../../src/features/transcripts/run-transcript-command.ts"],"sourcesContent":["import { option } from \"pastel\";\nimport { z } from \"zod\";\n\nimport { GlobalOptionsSchema, TranscriptArgsSchema } from \"../cli/options.js\";\nimport { runTranscriptCommand, type TranscriptCommandOptions } from \"../features/transcripts/run-transcript-command.js\";\nimport { CommandRunner } from \"../cli/command-runner.js\";\n\nexport const description = \"List, read, and grep local Claude/Codex transcript JSONL files\";\nexport const args = TranscriptArgsSchema;\nexport const options = GlobalOptionsSchema.extend({\n source: z\n .enum([\"all\", \"codex\", \"claude\"])\n .optional()\n .describe(\n option({\n description: \"Transcript source. Default: all\",\n valueDescription: \"all|codex|claude\",\n })\n ),\n limit: z\n .number()\n .optional()\n .describe(\n option({\n description: \"Maximum records or entries\",\n valueDescription: \"n\",\n })\n ),\n fileLimit: z\n .number()\n .optional()\n .describe(\n option({\n description: \"Maximum recent files to scan for grep\",\n valueDescription: \"n\",\n })\n ),\n includeInternal: z\n .boolean()\n .optional()\n .describe(\n option({\n description: \"Include developer/system/internal transcript entries\",\n })\n ),\n json: z\n .boolean()\n .optional()\n .describe(\n option({\n description: \"Print raw JSON\",\n })\n ),\n});\n\ntype TranscriptsCommandProps = {\n readonly args: string[];\n readonly options: TranscriptCommandOptions;\n};\n\nexport default function TranscriptsCommand({ args, options }: TranscriptsCommandProps) {\n return <CommandRunner run={(output) => runTranscriptCommand(args, options, output)} />;\n}\n","import { promises as fs } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nexport const TranscriptSourceNames = [\"codex\", \"claude\"] as const;\n\nexport type TranscriptSourceName = (typeof TranscriptSourceNames)[number];\nexport type TranscriptScopeName = TranscriptSourceName | \"all\";\n\nexport type TranscriptRecord = {\n readonly source: TranscriptSourceName;\n readonly filePath: string;\n readonly updatedAt: string;\n readonly sessionId?: string;\n readonly cwd?: string;\n readonly title?: string;\n};\n\nexport type TranscriptEntry = {\n readonly source: TranscriptSourceName;\n readonly filePath: string;\n readonly timestamp?: string;\n readonly role: string;\n readonly text: string;\n};\n\nexport type TranscriptListOptions = {\n readonly source: TranscriptScopeName;\n readonly limit: number;\n};\n\nexport type TranscriptReadOptions = {\n readonly source: TranscriptScopeName;\n readonly target: string;\n readonly limit: number;\n readonly includeInternal: boolean;\n};\n\nexport type TranscriptGrepOptions = {\n readonly source: TranscriptScopeName;\n readonly query: string;\n readonly limit: number;\n readonly fileLimit: number;\n readonly includeInternal: boolean;\n};\n\ntype JsonObject = Record<string, unknown>;\n\nexport async function listTranscriptRecords(\n options: TranscriptListOptions\n): Promise<TranscriptRecord[]> {\n const files = await discoverTranscriptFiles(options.source);\n const records = await Promise.all(files.slice(0, options.limit).map(readTranscriptRecord));\n return records;\n}\n\nexport async function readTranscriptEntries(\n options: TranscriptReadOptions\n): Promise<TranscriptEntry[]> {\n const file = await resolveTranscriptFile(options.source, options.target);\n const entries = await readEntriesFromFile(file, options.includeInternal);\n return entries.slice(Math.max(0, entries.length - options.limit));\n}\n\nexport async function grepTranscriptEntries(\n options: TranscriptGrepOptions\n): Promise<TranscriptEntry[]> {\n const files = await discoverTranscriptFiles(options.source);\n const normalizedQuery = options.query.toLowerCase();\n const matches: TranscriptEntry[] = [];\n\n for (const file of files.slice(0, options.fileLimit)) {\n const entries = await readEntriesFromFile(file, options.includeInternal);\n\n for (const entry of entries) {\n if (entry.text.toLowerCase().includes(normalizedQuery)) {\n matches.push(entry);\n }\n\n if (matches.length >= options.limit) {\n return matches;\n }\n }\n }\n\n return matches;\n}\n\nasync function discoverTranscriptFiles(source: TranscriptScopeName): Promise<TranscriptRecord[]> {\n const sources = source === \"all\" ? TranscriptSourceNames : [source];\n const records = await Promise.all(sources.flatMap((sourceName) => sourceRoots(sourceName)));\n return records\n .flat()\n .sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));\n}\n\nfunction sourceRoots(source: TranscriptSourceName): Promise<TranscriptRecord[]>[] {\n if (source === \"codex\") {\n return [\n discoverJsonlFiles(\"codex\", expandHome(\"~/.codex/sessions\")),\n discoverJsonlFiles(\"codex\", expandHome(\"~/.codex/archived_sessions\")),\n ];\n }\n\n return [\n discoverJsonlFiles(\"claude\", expandHome(\"~/.claude/projects\")),\n discoverJsonlFiles(\"claude\", expandHome(\"~/.claude/history.jsonl\")),\n ];\n}\n\nasync function discoverJsonlFiles(\n source: TranscriptSourceName,\n rootPath: string\n): Promise<TranscriptRecord[]> {\n const stat = await statIfExists(rootPath);\n if (!stat) {\n return [];\n }\n\n if (stat.isFile()) {\n return [await recordFromPath(source, rootPath, stat.mtime)];\n }\n\n const records: TranscriptRecord[] = [];\n const entries = await fs.readdir(rootPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const entryPath = path.join(rootPath, entry.name);\n if (entry.isDirectory()) {\n records.push(...(await discoverJsonlFiles(source, entryPath)));\n continue;\n }\n\n if (entry.isFile() && entry.name.endsWith(\".jsonl\")) {\n const entryStat = await fs.stat(entryPath);\n records.push(await recordFromPath(source, entryPath, entryStat.mtime));\n }\n }\n\n return records;\n}\n\nasync function recordFromPath(\n source: TranscriptSourceName,\n filePath: string,\n mtime: Date\n): Promise<TranscriptRecord> {\n return {\n source,\n filePath,\n updatedAt: mtime.toISOString(),\n };\n}\n\nasync function readTranscriptRecord(record: TranscriptRecord): Promise<TranscriptRecord> {\n const metadata = await readMetadataFromFile(record.source, record.filePath);\n return {\n ...record,\n ...metadata,\n };\n}\n\nasync function readMetadataFromFile(\n source: TranscriptSourceName,\n filePath: string\n): Promise<Pick<TranscriptRecord, \"cwd\" | \"sessionId\" | \"title\">> {\n const lines = await readJsonlLines(filePath, 80);\n\n for (const line of lines) {\n const parsed = parseJsonObject(line);\n if (!parsed) {\n continue;\n }\n\n if (source === \"codex\") {\n const payload = asObject(parsed.payload);\n if (parsed.type === \"session_meta\" && payload) {\n return {\n cwd: readString(payload.cwd),\n sessionId: readString(payload.session_id) ?? readString(payload.id),\n title: readString(payload.cwd),\n };\n }\n }\n\n if (source === \"claude\") {\n const message = asObject(parsed.message);\n const role = readString(message?.role) ?? readString(parsed.type);\n const content = message ? extractContentText(message.content) : readString(parsed.content);\n if (content && (role === \"user\" || role === \"assistant\")) {\n return {\n cwd: readString(parsed.cwd) ?? readString(parsed.project),\n sessionId: readString(parsed.sessionId),\n title: truncateSingleLine(content, 120),\n };\n }\n }\n }\n\n return {\n sessionId: path.basename(filePath, \".jsonl\"),\n };\n}\n\nasync function resolveTranscriptFile(\n source: TranscriptScopeName,\n target: string\n): Promise<TranscriptRecord> {\n const expandedTarget = expandHome(target);\n const directStat = await statIfExists(expandedTarget);\n if (directStat?.isFile()) {\n return recordFromPath(detectSourceFromPath(expandedTarget), expandedTarget, directStat.mtime);\n }\n\n const files = await discoverTranscriptFiles(source);\n const normalizedTarget = target.toLowerCase();\n const match = files.find((file) => {\n return (\n file.filePath.toLowerCase().includes(normalizedTarget) ||\n file.sessionId?.toLowerCase().includes(normalizedTarget)\n );\n });\n\n if (!match) {\n throw new Error(`No transcript matched \"${target}\". Run cngkit transcripts list first.`);\n }\n\n return match;\n}\n\nasync function readEntriesFromFile(\n record: TranscriptRecord,\n includeInternal: boolean\n): Promise<TranscriptEntry[]> {\n const content = await fs.readFile(record.filePath, \"utf8\");\n const entries: TranscriptEntry[] = [];\n\n for (const line of content.split(\"\\n\")) {\n if (!line.trim()) {\n continue;\n }\n\n const parsed = parseJsonObject(line);\n if (!parsed) {\n continue;\n }\n\n const entry =\n record.source === \"codex\"\n ? parseCodexEntry(record, parsed, includeInternal)\n : parseClaudeEntry(record, parsed, includeInternal);\n\n if (entry) {\n entries.push(entry);\n }\n }\n\n return entries;\n}\n\nfunction parseCodexEntry(\n record: TranscriptRecord,\n parsed: JsonObject,\n includeInternal: boolean\n): TranscriptEntry | undefined {\n const payload = asObject(parsed.payload);\n if (!payload || parsed.type !== \"response_item\") {\n return undefined;\n }\n\n const role = readString(payload.role);\n if (!role || (!includeInternal && role !== \"user\" && role !== \"assistant\")) {\n return undefined;\n }\n\n const text = extractContentText(payload.content);\n if (!text) {\n return undefined;\n }\n\n return {\n source: record.source,\n filePath: record.filePath,\n timestamp: readString(parsed.timestamp),\n role,\n text,\n };\n}\n\nfunction parseClaudeEntry(\n record: TranscriptRecord,\n parsed: JsonObject,\n includeInternal: boolean\n): TranscriptEntry | undefined {\n const message = asObject(parsed.message);\n const role = readString(message?.role) ?? readString(parsed.type);\n\n if (!role || (!includeInternal && role !== \"user\" && role !== \"assistant\")) {\n return undefined;\n }\n\n const text = message ? extractContentText(message.content) : readString(parsed.content);\n if (!text) {\n return undefined;\n }\n\n return {\n source: record.source,\n filePath: record.filePath,\n timestamp: readString(parsed.timestamp),\n role,\n text,\n };\n}\n\nfunction extractContentText(value: unknown): string | undefined {\n if (typeof value === \"string\") {\n return value;\n }\n\n if (!Array.isArray(value)) {\n return undefined;\n }\n\n const parts = value.flatMap((item) => {\n if (typeof item === \"string\") {\n return [item];\n }\n\n const objectItem = asObject(item);\n if (!objectItem) {\n return [];\n }\n\n return [readString(objectItem.text), readString(objectItem.content)].filter(\n (part): part is string => Boolean(part)\n );\n });\n\n return parts.length > 0 ? parts.join(\"\\n\") : undefined;\n}\n\nasync function readJsonlLines(filePath: string, limit: number): Promise<string[]> {\n const content = await fs.readFile(filePath, \"utf8\");\n return content.split(\"\\n\").filter(Boolean).slice(0, limit);\n}\n\nasync function statIfExists(filePath: string) {\n try {\n return await fs.stat(filePath);\n } catch (error) {\n if (isNodeError(error) && error.code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nfunction parseJsonObject(line: string): JsonObject | undefined {\n try {\n const parsed: unknown = JSON.parse(line);\n return asObject(parsed);\n } catch {\n return undefined;\n }\n}\n\nfunction asObject(value: unknown): JsonObject | undefined {\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n return value as JsonObject;\n }\n return undefined;\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value : undefined;\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && \"code\" in error;\n}\n\nfunction expandHome(value: string): string {\n if (value === \"~\") {\n return os.homedir();\n }\n if (value.startsWith(\"~/\")) {\n return path.join(os.homedir(), value.slice(2));\n }\n return value;\n}\n\nfunction detectSourceFromPath(filePath: string): TranscriptSourceName {\n return filePath.includes(`${path.sep}.claude${path.sep}`) ? \"claude\" : \"codex\";\n}\n\nfunction truncateSingleLine(value: string, maxLength: number): string {\n const line = value.replace(/\\s+/g, \" \").trim();\n return line.length > maxLength ? `${line.slice(0, maxLength - 1)}...` : line;\n}\n","import { formatCngkitHelp } from \"../../cli/help-specs.js\";\nimport {\n coerceLimit,\n formatJson,\n optionalJoinedArgument,\n shouldPrintJson,\n singleLine,\n type JsonOutputOptions,\n type NumberOption,\n} from \"../../shared/command-utils.js\";\nimport type { GlobalCommandOptions } from \"../../shared/config.js\";\nimport type { CommandOutput } from \"../../shared/output.js\";\nimport {\n grepTranscriptEntries,\n listTranscriptRecords,\n readTranscriptEntries,\n type TranscriptEntry,\n type TranscriptRecord,\n type TranscriptScopeName,\n} from \"./reader.js\";\n\nexport type TranscriptCommandOptions = GlobalCommandOptions &\n JsonOutputOptions & {\n source?: string;\n limit?: NumberOption;\n fileLimit?: NumberOption;\n includeInternal?: boolean;\n };\n\nexport async function runTranscriptCommand(\n args: string[] | undefined,\n options: TranscriptCommandOptions,\n output: CommandOutput\n): Promise<void> {\n const [action = \"list\", ...actionArgs] = args ?? [];\n const source = normalizeTranscriptSource(options.source);\n const limit = coerceLimit(options.limit, action === \"list\" ? 12 : 80, 500);\n const includeInternal = options.includeInternal === true;\n\n switch (action) {\n case \"help\":\n output.markdown(formatCngkitHelp(\"transcripts\"));\n return;\n case \"list\": {\n const records = await listTranscriptRecords({ source, limit });\n if (shouldPrintJson(options)) {\n output.raw(formatJson({ records }));\n return;\n }\n\n output.info(formatTranscriptRecords(records));\n return;\n }\n case \"read\": {\n const target = actionArgs[0];\n if (!target) {\n throw new Error(\"Missing transcript target. Usage: cngkit transcripts read <path-or-id>\");\n }\n\n const entries = await readTranscriptEntries({\n source,\n target,\n limit,\n includeInternal,\n });\n\n if (shouldPrintJson(options)) {\n output.raw(formatJson({ entries }));\n return;\n }\n\n output.raw(formatTranscriptEntries(entries));\n return;\n }\n case \"grep\": {\n const query = optionalJoinedArgument(actionArgs);\n if (!query) {\n throw new Error(\"Missing query. Usage: cngkit transcripts grep <query>\");\n }\n\n const entries = await grepTranscriptEntries({\n source,\n query,\n limit,\n fileLimit: coerceLimit(options.fileLimit, 60, 5000),\n includeInternal,\n });\n\n if (shouldPrintJson(options)) {\n output.raw(formatJson({ entries }));\n return;\n }\n\n output.raw(formatTranscriptEntries(entries));\n return;\n }\n default:\n throw new Error(\"Unknown transcripts command. Usage: cngkit transcripts <list|read|grep>\");\n }\n}\n\nfunction formatTranscriptRecords(records: TranscriptRecord[]): string {\n if (records.length === 0) {\n return \"No transcript files found.\";\n }\n\n return records\n .map((record, index) => {\n const title = record.title ? `\\n ${singleLine(record.title)}` : \"\";\n const cwd = record.cwd ? `\\n cwd ${record.cwd}` : \"\";\n const session = record.sessionId ? `\\n session ${record.sessionId}` : \"\";\n return `${index + 1}. ${record.source} ${record.updatedAt}\\n ${record.filePath}${session}${cwd}${title}`;\n })\n .join(\"\\n\");\n}\n\nfunction formatTranscriptEntries(entries: TranscriptEntry[]): string {\n if (entries.length === 0) {\n return \"No transcript entries found.\";\n }\n\n return entries\n .map((entry) => {\n const when = entry.timestamp ? ` ${entry.timestamp}` : \"\";\n return `[${entry.source}] ${entry.role}${when}\\n${entry.text.trim()}`;\n })\n .join(\"\\n\\n\");\n}\n\nfunction normalizeTranscriptSource(value: string | undefined): TranscriptScopeName {\n if (value === undefined) {\n return \"all\";\n }\n\n switch (value) {\n case \"all\":\n case \"codex\":\n case \"claude\":\n return value;\n default:\n throw new Error(\"Unknown transcript source. Use one of: all, codex, claude.\");\n }\n}\n"],"mappings":"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","names":["options","args","options","args","options"]}
|
|
1
|
+
{"version":3,"sources":["../../src/commands/transcripts.tsx","../../src/features/transcripts/reader.ts","../../src/features/transcripts/run-transcript-command.ts"],"sourcesContent":["import { option } from \"pastel\";\nimport { z } from \"zod\";\n\nimport { GlobalOptionsSchema, TranscriptArgsSchema } from \"../cli/options.js\";\nimport { runTranscriptCommand, type TranscriptCommandOptions } from \"../features/transcripts/run-transcript-command.js\";\nimport { CommandRunner } from \"../cli/command-runner.js\";\n\nexport const description = \"List, read, and grep local Claude/Codex transcript JSONL files\";\nexport const args = TranscriptArgsSchema;\nexport const options = GlobalOptionsSchema.extend({\n source: z\n .enum([\"all\", \"codex\", \"claude\"])\n .optional()\n .describe(\n option({\n description: \"Transcript source. Default: all\",\n valueDescription: \"all|codex|claude\",\n })\n ),\n limit: z\n .number()\n .optional()\n .describe(\n option({\n description: \"Maximum records or entries\",\n valueDescription: \"n\",\n })\n ),\n fileLimit: z\n .number()\n .optional()\n .describe(\n option({\n description: \"Maximum recent files to scan for grep\",\n valueDescription: \"n\",\n })\n ),\n includeInternal: z\n .boolean()\n .optional()\n .describe(\n option({\n description: \"Include developer/system/internal transcript entries\",\n })\n ),\n json: z\n .boolean()\n .optional()\n .describe(\n option({\n description: \"Print raw JSON\",\n })\n ),\n});\n\ntype TranscriptsCommandProps = {\n readonly args: string[];\n readonly options: TranscriptCommandOptions;\n};\n\nexport default function TranscriptsCommand({ args, options }: TranscriptsCommandProps) {\n return <CommandRunner run={(output) => runTranscriptCommand(args, options, output)} />;\n}\n","import { promises as fs } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nexport const TranscriptSourceNames = [\"codex\", \"claude\"] as const;\n\nexport type TranscriptSourceName = (typeof TranscriptSourceNames)[number];\nexport type TranscriptScopeName = TranscriptSourceName | \"all\";\n\nexport type TranscriptRecord = {\n readonly source: TranscriptSourceName;\n readonly filePath: string;\n readonly updatedAt: string;\n readonly sessionId?: string;\n readonly cwd?: string;\n readonly title?: string;\n};\n\nexport type TranscriptEntry = {\n readonly source: TranscriptSourceName;\n readonly filePath: string;\n readonly timestamp?: string;\n readonly role: string;\n readonly text: string;\n};\n\nexport type TranscriptListOptions = {\n readonly source: TranscriptScopeName;\n readonly limit: number;\n};\n\nexport type TranscriptReadOptions = {\n readonly source: TranscriptScopeName;\n readonly target: string;\n readonly limit: number;\n readonly includeInternal: boolean;\n};\n\nexport type TranscriptGrepOptions = {\n readonly source: TranscriptScopeName;\n readonly query: string;\n readonly limit: number;\n readonly fileLimit: number;\n readonly includeInternal: boolean;\n};\n\ntype JsonObject = Record<string, unknown>;\n\nexport async function listTranscriptRecords(\n options: TranscriptListOptions\n): Promise<TranscriptRecord[]> {\n const files = await discoverTranscriptFiles(options.source);\n const records = await Promise.all(files.slice(0, options.limit).map(readTranscriptRecord));\n return records;\n}\n\nexport async function readTranscriptEntries(\n options: TranscriptReadOptions\n): Promise<TranscriptEntry[]> {\n const file = await resolveTranscriptFile(options.source, options.target);\n const entries = await readEntriesFromFile(file, options.includeInternal);\n return entries.slice(Math.max(0, entries.length - options.limit));\n}\n\nexport async function grepTranscriptEntries(\n options: TranscriptGrepOptions\n): Promise<TranscriptEntry[]> {\n const files = await discoverTranscriptFiles(options.source);\n const normalizedQuery = options.query.toLowerCase();\n const matches: TranscriptEntry[] = [];\n\n for (const file of files.slice(0, options.fileLimit)) {\n const entries = await readEntriesFromFile(file, options.includeInternal);\n\n for (const entry of entries) {\n if (entry.text.toLowerCase().includes(normalizedQuery)) {\n matches.push(entry);\n }\n\n if (matches.length >= options.limit) {\n return matches;\n }\n }\n }\n\n return matches;\n}\n\nasync function discoverTranscriptFiles(source: TranscriptScopeName): Promise<TranscriptRecord[]> {\n const sources = source === \"all\" ? TranscriptSourceNames : [source];\n const records = await Promise.all(sources.flatMap((sourceName) => sourceRoots(sourceName)));\n return records\n .flat()\n .sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));\n}\n\nfunction sourceRoots(source: TranscriptSourceName): Promise<TranscriptRecord[]>[] {\n if (source === \"codex\") {\n return [\n discoverJsonlFiles(\"codex\", expandHome(\"~/.codex/sessions\")),\n discoverJsonlFiles(\"codex\", expandHome(\"~/.codex/archived_sessions\")),\n ];\n }\n\n return [\n discoverJsonlFiles(\"claude\", expandHome(\"~/.claude/projects\")),\n discoverJsonlFiles(\"claude\", expandHome(\"~/.claude/history.jsonl\")),\n ];\n}\n\nasync function discoverJsonlFiles(\n source: TranscriptSourceName,\n rootPath: string\n): Promise<TranscriptRecord[]> {\n const stat = await statIfExists(rootPath);\n if (!stat) {\n return [];\n }\n\n if (stat.isFile()) {\n return [await recordFromPath(source, rootPath, stat.mtime)];\n }\n\n const records: TranscriptRecord[] = [];\n const entries = await fs.readdir(rootPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const entryPath = path.join(rootPath, entry.name);\n if (entry.isDirectory()) {\n records.push(...(await discoverJsonlFiles(source, entryPath)));\n continue;\n }\n\n if (entry.isFile() && entry.name.endsWith(\".jsonl\")) {\n const entryStat = await fs.stat(entryPath);\n records.push(await recordFromPath(source, entryPath, entryStat.mtime));\n }\n }\n\n return records;\n}\n\nasync function recordFromPath(\n source: TranscriptSourceName,\n filePath: string,\n mtime: Date\n): Promise<TranscriptRecord> {\n return {\n source,\n filePath,\n updatedAt: mtime.toISOString(),\n };\n}\n\nasync function readTranscriptRecord(record: TranscriptRecord): Promise<TranscriptRecord> {\n const metadata = await readMetadataFromFile(record.source, record.filePath);\n return {\n ...record,\n ...metadata,\n };\n}\n\nasync function readMetadataFromFile(\n source: TranscriptSourceName,\n filePath: string\n): Promise<Pick<TranscriptRecord, \"cwd\" | \"sessionId\" | \"title\">> {\n const lines = await readJsonlLines(filePath, 80);\n\n for (const line of lines) {\n const parsed = parseJsonObject(line);\n if (!parsed) {\n continue;\n }\n\n if (source === \"codex\") {\n const payload = asObject(parsed.payload);\n if (parsed.type === \"session_meta\" && payload) {\n return {\n cwd: readString(payload.cwd),\n sessionId: readString(payload.session_id) ?? readString(payload.id),\n title: readString(payload.cwd),\n };\n }\n }\n\n if (source === \"claude\") {\n const message = asObject(parsed.message);\n const role = readString(message?.role) ?? readString(parsed.type);\n const content = message ? extractContentText(message.content) : readString(parsed.content);\n if (content && (role === \"user\" || role === \"assistant\")) {\n return {\n cwd: readString(parsed.cwd) ?? readString(parsed.project),\n sessionId: readString(parsed.sessionId),\n title: truncateSingleLine(content, 120),\n };\n }\n }\n }\n\n return {\n sessionId: path.basename(filePath, \".jsonl\"),\n };\n}\n\nasync function resolveTranscriptFile(\n source: TranscriptScopeName,\n target: string\n): Promise<TranscriptRecord> {\n const expandedTarget = expandHome(target);\n const directStat = await statIfExists(expandedTarget);\n if (directStat?.isFile()) {\n return recordFromPath(detectSourceFromPath(expandedTarget), expandedTarget, directStat.mtime);\n }\n\n const files = await discoverTranscriptFiles(source);\n const normalizedTarget = target.toLowerCase();\n const match = files.find((file) => {\n return (\n file.filePath.toLowerCase().includes(normalizedTarget) ||\n file.sessionId?.toLowerCase().includes(normalizedTarget)\n );\n });\n\n if (!match) {\n throw new Error(`No transcript matched \"${target}\". Run cngkit transcripts list first.`);\n }\n\n return match;\n}\n\nasync function readEntriesFromFile(\n record: TranscriptRecord,\n includeInternal: boolean\n): Promise<TranscriptEntry[]> {\n const content = await fs.readFile(record.filePath, \"utf8\");\n const entries: TranscriptEntry[] = [];\n\n for (const line of content.split(\"\\n\")) {\n if (!line.trim()) {\n continue;\n }\n\n const parsed = parseJsonObject(line);\n if (!parsed) {\n continue;\n }\n\n const entry =\n record.source === \"codex\"\n ? parseCodexEntry(record, parsed, includeInternal)\n : parseClaudeEntry(record, parsed, includeInternal);\n\n if (entry) {\n entries.push(entry);\n }\n }\n\n return entries;\n}\n\nfunction parseCodexEntry(\n record: TranscriptRecord,\n parsed: JsonObject,\n includeInternal: boolean\n): TranscriptEntry | undefined {\n const payload = asObject(parsed.payload);\n if (!payload || parsed.type !== \"response_item\") {\n return undefined;\n }\n\n const role = readString(payload.role);\n if (!role || (!includeInternal && role !== \"user\" && role !== \"assistant\")) {\n return undefined;\n }\n\n const text = extractContentText(payload.content);\n if (!text) {\n return undefined;\n }\n\n return {\n source: record.source,\n filePath: record.filePath,\n timestamp: readString(parsed.timestamp),\n role,\n text,\n };\n}\n\nfunction parseClaudeEntry(\n record: TranscriptRecord,\n parsed: JsonObject,\n includeInternal: boolean\n): TranscriptEntry | undefined {\n const message = asObject(parsed.message);\n const role = readString(message?.role) ?? readString(parsed.type);\n\n if (!role || (!includeInternal && role !== \"user\" && role !== \"assistant\")) {\n return undefined;\n }\n\n const text = message ? extractContentText(message.content) : readString(parsed.content);\n if (!text) {\n return undefined;\n }\n\n return {\n source: record.source,\n filePath: record.filePath,\n timestamp: readString(parsed.timestamp),\n role,\n text,\n };\n}\n\nfunction extractContentText(value: unknown): string | undefined {\n if (typeof value === \"string\") {\n return value;\n }\n\n if (!Array.isArray(value)) {\n return undefined;\n }\n\n const parts = value.flatMap((item) => {\n if (typeof item === \"string\") {\n return [item];\n }\n\n const objectItem = asObject(item);\n if (!objectItem) {\n return [];\n }\n\n return [readString(objectItem.text), readString(objectItem.content)].filter(\n (part): part is string => Boolean(part)\n );\n });\n\n return parts.length > 0 ? parts.join(\"\\n\") : undefined;\n}\n\nasync function readJsonlLines(filePath: string, limit: number): Promise<string[]> {\n const content = await fs.readFile(filePath, \"utf8\");\n return content.split(\"\\n\").filter(Boolean).slice(0, limit);\n}\n\nasync function statIfExists(filePath: string) {\n try {\n return await fs.stat(filePath);\n } catch (error) {\n if (isNodeError(error) && error.code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nfunction parseJsonObject(line: string): JsonObject | undefined {\n try {\n const parsed: unknown = JSON.parse(line);\n return asObject(parsed);\n } catch {\n return undefined;\n }\n}\n\nfunction asObject(value: unknown): JsonObject | undefined {\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n return value as JsonObject;\n }\n return undefined;\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value : undefined;\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && \"code\" in error;\n}\n\nfunction expandHome(value: string): string {\n if (value === \"~\") {\n return os.homedir();\n }\n if (value.startsWith(\"~/\")) {\n return path.join(os.homedir(), value.slice(2));\n }\n return value;\n}\n\nfunction detectSourceFromPath(filePath: string): TranscriptSourceName {\n return filePath.includes(`${path.sep}.claude${path.sep}`) ? \"claude\" : \"codex\";\n}\n\nfunction truncateSingleLine(value: string, maxLength: number): string {\n const line = value.replace(/\\s+/g, \" \").trim();\n return line.length > maxLength ? `${line.slice(0, maxLength - 1)}...` : line;\n}\n","import { renderCngkitHelp } from \"../../cli/help-specs.js\";\nimport {\n coerceLimit,\n formatJson,\n optionalJoinedArgument,\n shouldPrintJson,\n singleLine,\n type JsonOutputOptions,\n type NumberOption,\n} from \"../../shared/command-utils.js\";\nimport type { GlobalCommandOptions } from \"../../shared/config.js\";\nimport type { CommandOutput } from \"../../shared/output.js\";\nimport {\n grepTranscriptEntries,\n listTranscriptRecords,\n readTranscriptEntries,\n type TranscriptEntry,\n type TranscriptRecord,\n type TranscriptScopeName,\n} from \"./reader.js\";\n\nexport type TranscriptCommandOptions = GlobalCommandOptions &\n JsonOutputOptions & {\n source?: string;\n limit?: NumberOption;\n fileLimit?: NumberOption;\n includeInternal?: boolean;\n };\n\nexport async function runTranscriptCommand(\n args: string[] | undefined,\n options: TranscriptCommandOptions,\n output: CommandOutput\n): Promise<void> {\n const [action = \"list\", ...actionArgs] = args ?? [];\n const source = normalizeTranscriptSource(options.source);\n const limit = coerceLimit(options.limit, action === \"list\" ? 12 : 80, 500);\n const includeInternal = options.includeInternal === true;\n\n switch (action) {\n case \"help\":\n output.component(renderCngkitHelp(\"transcripts\"));\n return;\n case \"list\": {\n const records = await listTranscriptRecords({ source, limit });\n if (shouldPrintJson(options)) {\n output.raw(formatJson({ records }));\n return;\n }\n\n output.info(formatTranscriptRecords(records));\n return;\n }\n case \"read\": {\n const target = actionArgs[0];\n if (!target) {\n throw new Error(\"Missing transcript target. Usage: cngkit transcripts read <path-or-id>\");\n }\n\n const entries = await readTranscriptEntries({\n source,\n target,\n limit,\n includeInternal,\n });\n\n if (shouldPrintJson(options)) {\n output.raw(formatJson({ entries }));\n return;\n }\n\n output.raw(formatTranscriptEntries(entries));\n return;\n }\n case \"grep\": {\n const query = optionalJoinedArgument(actionArgs);\n if (!query) {\n throw new Error(\"Missing query. Usage: cngkit transcripts grep <query>\");\n }\n\n const entries = await grepTranscriptEntries({\n source,\n query,\n limit,\n fileLimit: coerceLimit(options.fileLimit, 60, 5000),\n includeInternal,\n });\n\n if (shouldPrintJson(options)) {\n output.raw(formatJson({ entries }));\n return;\n }\n\n output.raw(formatTranscriptEntries(entries));\n return;\n }\n default:\n throw new Error(\"Unknown transcripts command. Usage: cngkit transcripts <list|read|grep>\");\n }\n}\n\nfunction formatTranscriptRecords(records: TranscriptRecord[]): string {\n if (records.length === 0) {\n return \"No transcript files found.\";\n }\n\n return records\n .map((record, index) => {\n const title = record.title ? `\\n ${singleLine(record.title)}` : \"\";\n const cwd = record.cwd ? `\\n cwd ${record.cwd}` : \"\";\n const session = record.sessionId ? `\\n session ${record.sessionId}` : \"\";\n return `${index + 1}. ${record.source} ${record.updatedAt}\\n ${record.filePath}${session}${cwd}${title}`;\n })\n .join(\"\\n\");\n}\n\nfunction formatTranscriptEntries(entries: TranscriptEntry[]): string {\n if (entries.length === 0) {\n return \"No transcript entries found.\";\n }\n\n return entries\n .map((entry) => {\n const when = entry.timestamp ? ` ${entry.timestamp}` : \"\";\n return `[${entry.source}] ${entry.role}${when}\\n${entry.text.trim()}`;\n })\n .join(\"\\n\\n\");\n}\n\nfunction normalizeTranscriptSource(value: string | undefined): TranscriptScopeName {\n if (value === undefined) {\n return \"all\";\n }\n\n switch (value) {\n case \"all\":\n case \"codex\":\n case \"claude\":\n return value;\n default:\n throw new Error(\"Unknown transcript source. Use one of: all, codex, claude.\");\n }\n}\n"],"mappings":"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","names":["options","args","options","args","options"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cngkit",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.19",
|
|
4
4
|
"description": "Opinionated Curly.ng CLI kit for Coderoom collaboration and website tooling.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"format": "prettier --write README.md src tsconfig.json tsup.config.ts package.json",
|
|
26
26
|
"lint": "eslint src",
|
|
27
27
|
"prepublishOnly": "pnpm run build && pnpm run smoke",
|
|
28
|
-
"smoke": "node dist/cli.js --help && node dist/cli.js --version && node dist/cli.js help && node dist/cli.js help knowledges && node dist/cli.js help coderoom && node dist/cli.js help transcripts && node dist/cli.js login --help && node dist/cli.js coderoom --help && node dist/cli.js coderoom share --help && node dist/cli.js coderoom join --help && node dist/cli.js scrub --help && node dist/cli.js transcripts --help && node dist/cli.js knowledges --help && node dist/cli.js knowledges audiences --help && node dist/cli.js knowledges search --help && node dist/cli.js knowledges read --help && node dist/cli.js knowledges grep --help && node dist/cli.js knowledges glob --help && node dist/cli.js knowledges list --help && node dist/cli.js knowledges files --help && node dist/cli.js knowledges status --help",
|
|
28
|
+
"smoke": "node dist/cli.js --help && node dist/cli.js --version && node dist/cli.js help && node dist/cli.js help knowledges && node dist/cli.js help coderoom && node dist/cli.js help transcripts && node dist/cli.js help hooks && node dist/cli.js help hookify && node dist/cli.js login --help && node dist/cli.js coderoom --help && node dist/cli.js coderoom share --help && node dist/cli.js coderoom join --help && node dist/cli.js scrub --help && node dist/cli.js transcripts --help && node dist/cli.js hooks --help && node dist/cli.js hooks install --help && node dist/cli.js hooks uninstall --help && node dist/cli.js hookify --help && node dist/cli.js hookify ingest --help && node dist/cli.js knowledges --help && node dist/cli.js knowledges audiences --help && node dist/cli.js knowledges search --help && node dist/cli.js knowledges ls --help && node dist/cli.js knowledges tree --help && node dist/cli.js knowledges cat --help && node dist/cli.js knowledges head --help && node dist/cli.js knowledges tail --help && node dist/cli.js knowledges find --help && node dist/cli.js knowledges stat --help && node dist/cli.js knowledges realpath --help && node dist/cli.js knowledges read --help && node dist/cli.js knowledges grep --help && node dist/cli.js knowledges glob --help && node dist/cli.js knowledges list --help && node dist/cli.js knowledges files --help && node dist/cli.js knowledges status --help",
|
|
29
29
|
"smoke:docker": "bash scripts/smoke-docker.sh",
|
|
30
30
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
31
31
|
},
|
|
@@ -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"]}
|