@webywz/context-diet 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +170 -2
  3. package/dist/blocks.d.ts +8 -0
  4. package/dist/blocks.d.ts.map +1 -0
  5. package/dist/blocks.js +129 -0
  6. package/dist/blocks.js.map +1 -0
  7. package/dist/cli.d.ts +12 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +149 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/diet.d.ts +12 -0
  12. package/dist/diet.d.ts.map +1 -0
  13. package/dist/diet.js +66 -0
  14. package/dist/diet.js.map +1 -0
  15. package/dist/heuristics.d.ts +13 -0
  16. package/dist/heuristics.d.ts.map +1 -0
  17. package/dist/heuristics.js +238 -0
  18. package/dist/heuristics.js.map +1 -0
  19. package/dist/index.d.ts +7 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +7 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/llm.d.ts +12 -0
  24. package/dist/llm.d.ts.map +1 -0
  25. package/dist/llm.js +107 -0
  26. package/dist/llm.js.map +1 -0
  27. package/dist/package-info.d.ts +5 -0
  28. package/dist/package-info.d.ts.map +1 -0
  29. package/dist/package-info.js +13 -0
  30. package/dist/package-info.js.map +1 -0
  31. package/dist/parse-args.d.ts +19 -0
  32. package/dist/parse-args.d.ts.map +1 -0
  33. package/dist/parse-args.js +172 -0
  34. package/dist/parse-args.js.map +1 -0
  35. package/dist/report.d.ts +24 -0
  36. package/dist/report.d.ts.map +1 -0
  37. package/dist/report.js +56 -0
  38. package/dist/report.js.map +1 -0
  39. package/dist/tokens.d.ts +6 -0
  40. package/dist/tokens.d.ts.map +1 -0
  41. package/dist/tokens.js +73 -0
  42. package/dist/tokens.js.map +1 -0
  43. package/dist/truncate.d.ts +4 -0
  44. package/dist/truncate.d.ts.map +1 -0
  45. package/dist/truncate.js +136 -0
  46. package/dist/truncate.js.map +1 -0
  47. package/dist/types.d.ts +48 -0
  48. package/dist/types.d.ts.map +1 -0
  49. package/dist/types.js +18 -0
  50. package/dist/types.js.map +1 -0
  51. package/package.json +58 -4
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 webywz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,171 @@
1
- # Temporary Holding Version
1
+ # context-diet
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **Slim LLM context before you send it.** Drop the noise, keep the signal, estimate tokens — locally, offline, in milliseconds.
4
+
5
+ Engineers paste logs, docs, and chat history into models. Most of it is filler: repeated `DEBUG` lines, email signatures, duplicated paragraphs, 4KB of base64. `context-diet` is a small CLI that strips that chrome, optionally fits a token budget, and tells you what it cut.
6
+
7
+ ```bash
8
+ npm i -g @webywz/context-diet
9
+ ```
10
+
11
+ ```bash
12
+ context-diet logs.txt --max-tokens 2000 --keep headings|code
13
+ ```
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ npm i -g @webywz/context-diet
19
+ ```
20
+
21
+ Node 18+ is required. No tokenizer files, no GPU, no account.
22
+
23
+ ```bash
24
+ # one-off
25
+ npx @webywz/context-diet --help
26
+ ```
27
+
28
+ ## Quick start
29
+
30
+ ```bash
31
+ # file → slimmed text on stdout, report on stderr
32
+ context-diet input.txt
33
+
34
+ # stdin
35
+ cat noisy.log | context-diet --max-tokens 1500 > slim.txt
36
+
37
+ # write the body to a file
38
+ context-diet notes.md -o slim.md --keep headings,code,lists
39
+
40
+ # machine-readable
41
+ context-diet input.txt --json | jq '{tokens: .output.tokens, cuts}'
42
+ ```
43
+
44
+ ### Before / after
45
+
46
+ Input (`examples/noisy.txt`) — repeated logs, a duplicated runbook, a signature, a fat blob:
47
+
48
+ ```
49
+ [2026-03-14 09:01:02] INFO Starting request handler
50
+ [2026-03-14 09:01:02] DEBUG loading config from /etc/app/config.yaml
51
+ [2026-03-14 09:01:03] DEBUG loading config from /etc/app/config.yaml
52
+ [2026-03-14 09:01:03] DEBUG loading config from /etc/app/config.yaml
53
+ …
54
+ CONFIDENTIALITY NOTICE
55
+ This email is confidential and intended only for the recipient.
56
+ …
57
+
58
+ The deploy runbook covers staging and production.
59
+ The deploy runbook covers staging and production rollouts.
60
+ …
61
+
62
+ Sent from my iPhone
63
+ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAY… (huge)
64
+ ```
65
+
66
+ ```bash
67
+ context-diet examples/noisy.txt --keep headings|code|lists
68
+ ```
69
+
70
+ Stderr:
71
+
72
+ ```
73
+ context-diet 0.1.0
74
+ source: examples/noisy.txt
75
+ chars: 1,666 → 834 (−49.9%)
76
+ tokens: ~667 → ~312 (−53.2%)
77
+ cut:
78
+ ansi sequences 0
79
+ boilerplate lines 9
80
+ duplicate paragraphs 2
81
+ whitespace runs 5
82
+ omitted heavy blobs 1
83
+ truncated blocks 0
84
+ truncated tokens ~0
85
+ llm deepen no
86
+ ```
87
+
88
+ Stdout keeps the redis error, the unique runbook facts, the rollback list, and the `healthz` fence — not the fourth identical `DEBUG` line, not the iPhone signature, not the blob.
89
+
90
+ ## What it does
91
+
92
+ All of this is **offline heuristics**. No network unless you pass `--deepen`.
93
+
94
+ | Step | Behavior |
95
+ | --- | --- |
96
+ | Strip ANSI | Terminal color / OSC sequences |
97
+ | Omit heavy blobs | Long base64 / data-URIs → `[omitted blob: N chars]` |
98
+ | Collapse whitespace | Trailing space, squeezed blanks — **never inside code fences** |
99
+ | Drop boilerplate | Repeated log lines (timestamps/UUIDs normalized), signatures, `DEBUG` chrome, horizontal rules |
100
+ | Dedupe paragraphs | Exact and near-identical (Jaccard ≥ 0.87) prose/list blocks |
101
+ | Truncate | `--max-tokens N` drops low-value blocks first; `--keep headings\|code\|lists` pins those types |
102
+
103
+ Token estimates are **cl100k-ish** (GPT-4 family grain: ~4 chars/word, 1 CJK char ≈ 1 token, punctuation is dense). Good enough to budget a prompt. Not a billed tokenizer — do not invoice with it.
104
+
105
+ ## Usage
106
+
107
+ ```
108
+ context-diet [file] [options]
109
+ ```
110
+
111
+ | Flag | Meaning |
112
+ | --- | --- |
113
+ | `[file]` | Path to read. Omit or pass `-` to read stdin |
114
+ | `-o, --output <file>` | Write slimmed text here instead of stdout |
115
+ | `--max-tokens <n>` | Cap estimated output tokens |
116
+ | `--keep <cats>` | Prefer `headings`, `code`, `lists` when truncating (comma or `\|`) |
117
+ | `--json` | JSON report on stdout (includes `text`, unless `-o` was set) |
118
+ | `--deepen` | Optional LLM rewrite (see below) |
119
+ | `--provider openai\|anthropic` | Force a provider for `--deepen` |
120
+ | `-q, --quiet` | No human report on stderr |
121
+ | `-h, --help` | Help |
122
+ | `-V, --version` | Version |
123
+
124
+ Default I/O: **slimmed body on stdout**, **human report on stderr**, so this stays pipe-friendly:
125
+
126
+ ```bash
127
+ pbpaste | context-diet --max-tokens 800 --keep code | pbcopy
128
+ ```
129
+
130
+ ## Optional LLM pass
131
+
132
+ `--deepen` is **never required**. If you already have a key and want a second squeeze after the local diet:
133
+
134
+ ```bash
135
+ export OPENAI_API_KEY=sk-... # or ANTHROPIC_API_KEY
136
+ context-diet chapter.md --deepen --max-tokens 1200
137
+ ```
138
+
139
+ Defaults: `gpt-4o-mini` / `claude-3-5-haiku-20241022` (override with `OPENAI_MODEL` or `ANTHROPIC_MODEL`). The local result wins if the model comes back *longer*. Without a key, `--deepen` exits `2` with a clear message and does not phone home.
140
+
141
+ ## Library
142
+
143
+ ```ts
144
+ import { diet, dietAsync, estimateTokens } from "@webywz/context-diet";
145
+
146
+ const { text, input, output, cuts } = diet(raw, {
147
+ maxTokens: 2000,
148
+ keep: ["headings", "code"],
149
+ });
150
+
151
+ await dietAsync(raw, { deepen: true }); // keys from process.env
152
+ estimateTokens(text); // cl100k-ish heuristic
153
+ ```
154
+
155
+ ## Exit codes
156
+
157
+ | Code | Meaning |
158
+ | --- | --- |
159
+ | 0 | Success |
160
+ | 1 | Usage / missing input / unreadable file |
161
+ | 2 | `--deepen` failed (no key, HTTP error) |
162
+
163
+ ## Development
164
+
165
+ ```bash
166
+ npm test
167
+ npm run build
168
+ node dist/cli.js --help
169
+ ```
170
+
171
+ MIT © webywz
@@ -0,0 +1,8 @@
1
+ export type BlockType = "code" | "heading" | "list" | "paragraph" | "blank" | "rule";
2
+ export interface Block {
3
+ type: BlockType;
4
+ raw: string;
5
+ }
6
+ export declare function parseBlocks(text: string): Block[];
7
+ export declare function joinBlocks(blocks: Block[]): string;
8
+ //# sourceMappingURL=blocks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../src/blocks.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,SAAS,GACT,MAAM,GACN,WAAW,GACX,OAAO,GACP,MAAM,CAAC;AAEX,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAuBD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,EAAE,CA4GjD;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAOlD"}
package/dist/blocks.js ADDED
@@ -0,0 +1,129 @@
1
+ const FENCE_RE = /^ {0,3}(`{3,}|~{3,})(.*)$/;
2
+ const ATX_RE = /^ {0,3}#{1,6}(?:\s+\S|\s*$)/;
3
+ const RULE_RE = /^ {0,3}(?:(?:-[\t ]*){3,}|(?:_[\t ]*){3,}|(?:\*[\t ]*){3,})\s*$/;
4
+ const LIST_RE = /^ {0,3}(?:[-+*]|\d{1,9}[.)])\s+\S/;
5
+ const SETEXT_RE = /^ {0,3}(=+|-+)\s*$/;
6
+ function isSetextUnderline(line, heading) {
7
+ if (!SETEXT_RE.test(line))
8
+ return false;
9
+ const mark = line.trim();
10
+ // Long runs of =/- are banners, not Setext underlines.
11
+ if (mark.length > 40)
12
+ return false;
13
+ if (heading.trim().length > 80)
14
+ return false;
15
+ return true;
16
+ }
17
+ function fenceCloser(opener) {
18
+ const ch = opener[0] === "~" ? "~" : "`";
19
+ const n = opener.length;
20
+ return new RegExp(`^ {0,3}${ch}{${n},}\\s*$`);
21
+ }
22
+ export function parseBlocks(text) {
23
+ const lines = text.split("\n");
24
+ const blocks = [];
25
+ let i = 0;
26
+ const push = (type, chunk) => {
27
+ if (chunk.length === 0)
28
+ return;
29
+ blocks.push({ type, raw: chunk.join("\n") });
30
+ };
31
+ while (i < lines.length) {
32
+ const line = lines[i];
33
+ const fence = FENCE_RE.exec(line);
34
+ if (fence) {
35
+ const marker = fence[1];
36
+ const chunk = [line];
37
+ i++;
38
+ const closer = fenceCloser(marker);
39
+ while (i < lines.length) {
40
+ chunk.push(lines[i]);
41
+ const isClose = closer.test(lines[i]);
42
+ i++;
43
+ if (isClose)
44
+ break;
45
+ }
46
+ push("code", chunk);
47
+ continue;
48
+ }
49
+ if (line.trim() === "") {
50
+ const chunk = [line];
51
+ i++;
52
+ while (i < lines.length && lines[i].trim() === "") {
53
+ chunk.push(lines[i]);
54
+ i++;
55
+ }
56
+ push("blank", chunk);
57
+ continue;
58
+ }
59
+ if (RULE_RE.test(line)) {
60
+ blocks.push({ type: "rule", raw: line });
61
+ i++;
62
+ continue;
63
+ }
64
+ if (ATX_RE.test(line)) {
65
+ blocks.push({ type: "heading", raw: line });
66
+ i++;
67
+ continue;
68
+ }
69
+ if (i + 1 < lines.length &&
70
+ line.trim() !== "" &&
71
+ !LIST_RE.test(line) &&
72
+ isSetextUnderline(lines[i + 1], line)) {
73
+ blocks.push({ type: "heading", raw: `${line}\n${lines[i + 1]}` });
74
+ i += 2;
75
+ continue;
76
+ }
77
+ if (LIST_RE.test(line)) {
78
+ const chunk = [line];
79
+ i++;
80
+ while (i < lines.length) {
81
+ const next = lines[i];
82
+ if (next.trim() === "")
83
+ break;
84
+ if (FENCE_RE.test(next) || ATX_RE.test(next) || RULE_RE.test(next))
85
+ break;
86
+ if (LIST_RE.test(next) || /^\s+\S/.test(next)) {
87
+ chunk.push(next);
88
+ i++;
89
+ continue;
90
+ }
91
+ break;
92
+ }
93
+ push("list", chunk);
94
+ continue;
95
+ }
96
+ const chunk = [line];
97
+ i++;
98
+ while (i < lines.length) {
99
+ const next = lines[i];
100
+ if (next.trim() === "")
101
+ break;
102
+ if (FENCE_RE.test(next) ||
103
+ ATX_RE.test(next) ||
104
+ RULE_RE.test(next) ||
105
+ LIST_RE.test(next)) {
106
+ break;
107
+ }
108
+ if (i + 1 < lines.length &&
109
+ next.trim() !== "" &&
110
+ isSetextUnderline(lines[i + 1], next)) {
111
+ break;
112
+ }
113
+ chunk.push(next);
114
+ i++;
115
+ }
116
+ push("paragraph", chunk);
117
+ }
118
+ return blocks;
119
+ }
120
+ export function joinBlocks(blocks) {
121
+ const chunks = blocks
122
+ .filter((b) => b.type !== "blank")
123
+ .map((b) => b.raw.replace(/[ \t]+$/gm, "").trimEnd())
124
+ .filter((s) => s.length > 0);
125
+ if (chunks.length === 0)
126
+ return "";
127
+ return `${chunks.join("\n\n")}\n`;
128
+ }
129
+ //# sourceMappingURL=blocks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blocks.js","sourceRoot":"","sources":["../src/blocks.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ export interface Io {
3
+ stdin: NodeJS.ReadableStream;
4
+ stdout: NodeJS.WritableStream;
5
+ stderr: NodeJS.WritableStream;
6
+ stdinIsTTY: boolean | undefined;
7
+ env: NodeJS.ProcessEnv;
8
+ readFile: (path: string) => Promise<string>;
9
+ writeFile: (path: string, contents: string) => Promise<void>;
10
+ }
11
+ export declare function run(argv: string[], io?: Io): Promise<number>;
12
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAWA,MAAM,WAAW,EAAE;IACjB,KAAK,EAAE,MAAM,CAAC,cAAc,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AAqDD,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,EAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0E/E"}
package/dist/cli.js ADDED
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env node
2
+ import { readFile, writeFile } from "node:fs/promises";
3
+ import { isAbsolute, resolve } from "node:path";
4
+ import process from "node:process";
5
+ import { fileURLToPath } from "node:url";
6
+ import { dietAsync } from "./diet.js";
7
+ import { DeepenError } from "./llm.js";
8
+ import { packageInfo } from "./package-info.js";
9
+ import { HELP_TEXT, parseArgs, UsageError } from "./parse-args.js";
10
+ import { formatHumanReport, toJsonReport } from "./report.js";
11
+ const defaultIo = () => ({
12
+ stdin: process.stdin,
13
+ stdout: process.stdout,
14
+ stderr: process.stderr,
15
+ stdinIsTTY: process.stdin.isTTY,
16
+ env: process.env,
17
+ readFile: (path) => readFile(path, "utf8"),
18
+ writeFile: (path, contents) => writeFile(path, contents, "utf8"),
19
+ });
20
+ function readStream(stream) {
21
+ return new Promise((resolve, reject) => {
22
+ const chunks = [];
23
+ stream.on("data", (c) => {
24
+ chunks.push(typeof c === "string" ? Buffer.from(c) : c);
25
+ });
26
+ stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
27
+ stream.on("error", reject);
28
+ });
29
+ }
30
+ async function readInput(args, io) {
31
+ if (args.file && args.file !== "-") {
32
+ try {
33
+ const text = await io.readFile(args.file);
34
+ return { text, source: args.file };
35
+ }
36
+ catch (err) {
37
+ const msg = err instanceof Error ? err.message : String(err);
38
+ throw new UsageError(`Cannot read ${args.file}: ${msg}`);
39
+ }
40
+ }
41
+ const useStdin = !args.file || args.file === "-";
42
+ if (useStdin && io.stdinIsTTY) {
43
+ throw new UsageError("No input. Pass a file path, pipe stdin, or use `-` with redirected input.");
44
+ }
45
+ const text = await readStream(io.stdin);
46
+ return { text, source: "stdin" };
47
+ }
48
+ function writeOut(stream, chunk) {
49
+ return new Promise((resolveWrite, reject) => {
50
+ stream.write(chunk, "utf8", (err) => {
51
+ if (err)
52
+ reject(err);
53
+ else
54
+ resolveWrite();
55
+ });
56
+ });
57
+ }
58
+ export async function run(argv, io = defaultIo()) {
59
+ let args;
60
+ try {
61
+ args = parseArgs(argv);
62
+ }
63
+ catch (err) {
64
+ if (err instanceof UsageError) {
65
+ await writeOut(io.stderr, `${err.message}\n\n${HELP_TEXT}`);
66
+ return 1;
67
+ }
68
+ throw err;
69
+ }
70
+ const { version } = packageInfo();
71
+ if (args.help) {
72
+ await writeOut(io.stdout, HELP_TEXT);
73
+ return 0;
74
+ }
75
+ if (args.version) {
76
+ await writeOut(io.stdout, `${version}\n`);
77
+ return 0;
78
+ }
79
+ let source;
80
+ let text;
81
+ try {
82
+ const input = await readInput(args, io);
83
+ source = input.source;
84
+ text = input.text;
85
+ }
86
+ catch (err) {
87
+ if (err instanceof UsageError) {
88
+ await writeOut(io.stderr, `${err.message}\n`);
89
+ return 1;
90
+ }
91
+ throw err;
92
+ }
93
+ let result;
94
+ try {
95
+ result = await dietAsync(text, {
96
+ maxTokens: args.maxTokens,
97
+ keep: args.keep,
98
+ deepen: args.deepen,
99
+ provider: args.provider,
100
+ env: io.env,
101
+ });
102
+ }
103
+ catch (err) {
104
+ if (err instanceof DeepenError) {
105
+ await writeOut(io.stderr, `${err.message}\n`);
106
+ return 2;
107
+ }
108
+ throw err;
109
+ }
110
+ const json = toJsonReport(result, source);
111
+ if (args.output) {
112
+ await io.writeFile(args.output, result.text);
113
+ }
114
+ if (args.json) {
115
+ const payload = args.output ? { ...json, text: undefined, outputPath: args.output } : json;
116
+ await writeOut(io.stdout, `${JSON.stringify(payload, null, 2)}\n`);
117
+ return 0;
118
+ }
119
+ if (!args.output) {
120
+ await writeOut(io.stdout, result.text);
121
+ }
122
+ if (!args.quiet) {
123
+ await writeOut(io.stderr, formatHumanReport(result, source, version));
124
+ }
125
+ return 0;
126
+ }
127
+ function isMainModule() {
128
+ const entry = process.argv[1];
129
+ if (!entry)
130
+ return false;
131
+ try {
132
+ const self = fileURLToPath(import.meta.url);
133
+ const resolved = isAbsolute(entry) ? entry : resolve(entry);
134
+ return self === resolved;
135
+ }
136
+ catch {
137
+ return false;
138
+ }
139
+ }
140
+ if (isMainModule()) {
141
+ run(process.argv.slice(2)).then((code) => {
142
+ process.exitCode = code;
143
+ }, (err) => {
144
+ const msg = err instanceof Error ? err.stack ?? err.message : String(err);
145
+ process.stderr.write(`${msg}\n`);
146
+ process.exitCode = 1;
147
+ });
148
+ }
149
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/diet.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { type DietOptions, type DietResult } from "./types.js";
2
+ /**
3
+ * Offline diet: strip chrome, collapse whitespace, dedupe near-identical
4
+ * paragraphs, and optionally truncate to a token budget.
5
+ */
6
+ export declare function diet(text: string, options?: DietOptions): DietResult;
7
+ /**
8
+ * Same as {@link diet}, then optionally asks OpenAI/Anthropic to compress
9
+ * further. Keys are never required; pass `deepen: true` to opt in.
10
+ */
11
+ export declare function dietAsync(text: string, options?: DietOptions): Promise<DietResult>;
12
+ //# sourceMappingURL=diet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diet.d.ts","sourceRoot":"","sources":["../src/diet.ts"],"names":[],"mappings":"AASA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAiCpB;;;GAGG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,UAAU,CAKxE;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC,CAsBrB"}
package/dist/diet.js ADDED
@@ -0,0 +1,66 @@
1
+ import { joinBlocks, parseBlocks } from "./blocks.js";
2
+ import { omitHeavyBlobs, stripAnsi, tidy, } from "./heuristics.js";
3
+ import { deepenText } from "./llm.js";
4
+ import { snapshot } from "./tokens.js";
5
+ import { truncateToBudget } from "./truncate.js";
6
+ import { emptyCuts, } from "./types.js";
7
+ function localDiet(text, options) {
8
+ const cuts = emptyCuts();
9
+ const input = snapshot(text);
10
+ let next = stripAnsi(text, cuts);
11
+ next = omitHeavyBlobs(next, cuts);
12
+ next = tidy(next, cuts);
13
+ if (options.maxTokens && options.maxTokens > 0) {
14
+ const blocks = parseBlocks(next);
15
+ const trimmed = truncateToBudget(blocks, options.maxTokens, options.keep ?? [], cuts);
16
+ next = joinBlocks(trimmed);
17
+ }
18
+ // Final trailing-newline hygiene.
19
+ next = next.replace(/[ \t]+\n/g, "\n").replace(/\n{3,}/g, "\n\n");
20
+ if (next.length > 0 && !next.endsWith("\n"))
21
+ next += "\n";
22
+ return {
23
+ text: next,
24
+ input,
25
+ output: snapshot(next),
26
+ cuts,
27
+ };
28
+ }
29
+ /**
30
+ * Offline diet: strip chrome, collapse whitespace, dedupe near-identical
31
+ * paragraphs, and optionally truncate to a token budget.
32
+ */
33
+ export function diet(text, options = {}) {
34
+ return localDiet(text, {
35
+ maxTokens: options.maxTokens,
36
+ keep: options.keep,
37
+ });
38
+ }
39
+ /**
40
+ * Same as {@link diet}, then optionally asks OpenAI/Anthropic to compress
41
+ * further. Keys are never required; pass `deepen: true` to opt in.
42
+ */
43
+ export async function dietAsync(text, options = {}) {
44
+ const local = localDiet(text, options);
45
+ if (!options.deepen)
46
+ return local;
47
+ const deepened = await deepenText(local.text, {
48
+ provider: options.provider,
49
+ env: options.env,
50
+ fetch: options.fetch,
51
+ });
52
+ // Keep whichever version is actually smaller; models sometimes ramble.
53
+ const localTokens = local.output.tokens;
54
+ const deepTokens = snapshot(deepened).tokens;
55
+ if (deepTokens >= localTokens) {
56
+ return { ...local, cuts: { ...local.cuts, deepened: true } };
57
+ }
58
+ const textOut = deepened.endsWith("\n") ? deepened : `${deepened}\n`;
59
+ return {
60
+ text: textOut,
61
+ input: local.input,
62
+ output: snapshot(textOut),
63
+ cuts: { ...local.cuts, deepened: true },
64
+ };
65
+ }
66
+ //# sourceMappingURL=diet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diet.js","sourceRoot":"","sources":["../src/diet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACL,cAAc,EACd,SAAS,EACT,IAAI,GACL,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EACL,SAAS,GAGV,MAAM,YAAY,CAAC;AAEpB,SAAS,SAAS,CAAC,IAAY,EAAE,OAAoB;IACnD,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC;IACzB,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAE7B,IAAI,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjC,IAAI,GAAG,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClC,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAExB,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,gBAAgB,CAC9B,MAAM,EACN,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,IAAI,IAAI,EAAE,EAClB,IAAI,CACL,CAAC;QACF,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,kCAAkC;IAClC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAClE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,IAAI,IAAI,IAAI,CAAC;IAE1D,OAAO;QACL,IAAI,EAAE,IAAI;QACV,KAAK;QACL,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC;QACtB,IAAI;KACL,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,UAAuB,EAAE;IAC1D,OAAO,SAAS,CAAC,IAAI,EAAE;QACrB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,IAAY,EACZ,UAAuB,EAAE;IAEzB,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACvC,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAElC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE;QAC5C,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC,CAAC;IACH,uEAAuE;IACvE,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;IACxC,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;IAC7C,IAAI,UAAU,IAAI,WAAW,EAAE,CAAC;QAC9B,OAAO,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC;IAC/D,CAAC;IACD,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,CAAC;IACrE,OAAO;QACL,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC;QACzB,IAAI,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;KACxC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { type Block } from "./blocks.js";
2
+ import type { CutCounts } from "./types.js";
3
+ export declare function stripAnsi(text: string, cuts: CutCounts): string;
4
+ export declare function omitHeavyBlobs(text: string, cuts: CutCounts): string;
5
+ export declare function collapseBlankBlocks(blocks: Block[], cuts: CutCounts): Block[];
6
+ /**
7
+ * Drop repeated log/chrome lines and known signatures, keeping the first few
8
+ * occurrences so the pattern is still visible.
9
+ */
10
+ export declare function stripBoilerplate(blocks: Block[], cuts: CutCounts): Block[];
11
+ export declare function dedupeParagraphs(blocks: Block[], cuts: CutCounts): Block[];
12
+ export declare function tidy(text: string, cuts: CutCounts): string;
13
+ //# sourceMappingURL=heuristics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heuristics.d.ts","sourceRoot":"","sources":["../src/heuristics.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA0B5C,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CAQ/D;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CAepE;AAeD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,KAAK,EAAE,CAsB7E;AAgCD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,KAAK,EAAE,CAiD1E;AAyBD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,KAAK,EAAE,CAyC1E;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CAQ1D"}