@the-forge-flow/ultra-compress-pi 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +144 -0
  3. package/dist/commands/index.d.ts +6 -0
  4. package/dist/commands/index.d.ts.map +1 -0
  5. package/dist/commands/index.js +5 -0
  6. package/dist/commands/index.js.map +1 -0
  7. package/dist/commands/types.d.ts +18 -0
  8. package/dist/commands/types.d.ts.map +1 -0
  9. package/dist/commands/types.js +2 -0
  10. package/dist/commands/types.js.map +1 -0
  11. package/dist/commands/uc-file.d.ts +7 -0
  12. package/dist/commands/uc-file.d.ts.map +1 -0
  13. package/dist/commands/uc-file.js +105 -0
  14. package/dist/commands/uc-file.js.map +1 -0
  15. package/dist/commands/uc-revert.d.ts +3 -0
  16. package/dist/commands/uc-revert.d.ts.map +1 -0
  17. package/dist/commands/uc-revert.js +38 -0
  18. package/dist/commands/uc-revert.js.map +1 -0
  19. package/dist/commands/uc-status.d.ts +3 -0
  20. package/dist/commands/uc-status.d.ts.map +1 -0
  21. package/dist/commands/uc-status.js +27 -0
  22. package/dist/commands/uc-status.js.map +1 -0
  23. package/dist/commands/uc.d.ts +3 -0
  24. package/dist/commands/uc.d.ts.map +1 -0
  25. package/dist/commands/uc.js +28 -0
  26. package/dist/commands/uc.js.map +1 -0
  27. package/dist/hooks/agent-end.d.ts +10 -0
  28. package/dist/hooks/agent-end.d.ts.map +1 -0
  29. package/dist/hooks/agent-end.js +38 -0
  30. package/dist/hooks/agent-end.js.map +1 -0
  31. package/dist/hooks/before-agent-start.d.ts +13 -0
  32. package/dist/hooks/before-agent-start.d.ts.map +1 -0
  33. package/dist/hooks/before-agent-start.js +11 -0
  34. package/dist/hooks/before-agent-start.js.map +1 -0
  35. package/dist/hooks/index.d.ts +7 -0
  36. package/dist/hooks/index.d.ts.map +1 -0
  37. package/dist/hooks/index.js +4 -0
  38. package/dist/hooks/index.js.map +1 -0
  39. package/dist/hooks/session-start.d.ts +13 -0
  40. package/dist/hooks/session-start.d.ts.map +1 -0
  41. package/dist/hooks/session-start.js +11 -0
  42. package/dist/hooks/session-start.js.map +1 -0
  43. package/dist/index.d.ts +40 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +101 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/services/backup-path.d.ts +2 -0
  48. package/dist/services/backup-path.d.ts.map +1 -0
  49. package/dist/services/backup-path.js +7 -0
  50. package/dist/services/backup-path.js.map +1 -0
  51. package/dist/services/compress-pipeline.d.ts +12 -0
  52. package/dist/services/compress-pipeline.d.ts.map +1 -0
  53. package/dist/services/compress-pipeline.js +81 -0
  54. package/dist/services/compress-pipeline.js.map +1 -0
  55. package/dist/services/file-ops.d.ts +12 -0
  56. package/dist/services/file-ops.d.ts.map +1 -0
  57. package/dist/services/file-ops.js +58 -0
  58. package/dist/services/file-ops.js.map +1 -0
  59. package/dist/services/index.d.ts +8 -0
  60. package/dist/services/index.d.ts.map +1 -0
  61. package/dist/services/index.js +7 -0
  62. package/dist/services/index.js.map +1 -0
  63. package/dist/services/level-prompts.d.ts +3 -0
  64. package/dist/services/level-prompts.d.ts.map +1 -0
  65. package/dist/services/level-prompts.js +78 -0
  66. package/dist/services/level-prompts.js.map +1 -0
  67. package/dist/services/level-rules.d.ts +9 -0
  68. package/dist/services/level-rules.d.ts.map +1 -0
  69. package/dist/services/level-rules.js +110 -0
  70. package/dist/services/level-rules.js.map +1 -0
  71. package/dist/services/llm-factory.d.ts +15 -0
  72. package/dist/services/llm-factory.d.ts.map +1 -0
  73. package/dist/services/llm-factory.js +24 -0
  74. package/dist/services/llm-factory.js.map +1 -0
  75. package/dist/services/path-guard.d.ts +8 -0
  76. package/dist/services/path-guard.d.ts.map +1 -0
  77. package/dist/services/path-guard.js +42 -0
  78. package/dist/services/path-guard.js.map +1 -0
  79. package/dist/services/state-store.d.ts +10 -0
  80. package/dist/services/state-store.d.ts.map +1 -0
  81. package/dist/services/state-store.js +106 -0
  82. package/dist/services/state-store.js.map +1 -0
  83. package/dist/services/stats.d.ts +4 -0
  84. package/dist/services/stats.d.ts.map +1 -0
  85. package/dist/services/stats.js +18 -0
  86. package/dist/services/stats.js.map +1 -0
  87. package/dist/services/validator.d.ts +3 -0
  88. package/dist/services/validator.d.ts.map +1 -0
  89. package/dist/services/validator.js +87 -0
  90. package/dist/services/validator.js.map +1 -0
  91. package/dist/skills/ultra-compress/SKILL.md +94 -0
  92. package/dist/types.d.ts +62 -0
  93. package/dist/types.d.ts.map +1 -0
  94. package/dist/types.js +41 -0
  95. package/dist/types.js.map +1 -0
  96. package/package.json +90 -0
@@ -0,0 +1,15 @@
1
+ import type { LLMCall } from "./compress-pipeline";
2
+ interface PiModelRegistry {
3
+ find(provider: string, model: string): unknown;
4
+ getApiKeyAndHeaders(model: unknown): Promise<{
5
+ apiKey: string;
6
+ headers: Record<string, string>;
7
+ }>;
8
+ }
9
+ export interface LLMFactoryContext {
10
+ modelRegistry?: PiModelRegistry;
11
+ signal?: AbortSignal;
12
+ }
13
+ export declare function makeLLM(piCtx: LLMFactoryContext): LLMCall;
14
+ export {};
15
+ //# sourceMappingURL=llm-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-factory.d.ts","sourceRoot":"","sources":["../../src/services/llm-factory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,UAAU,eAAe;IACxB,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/C,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC,CAAC;CAClG;AAED,MAAM,WAAW,iBAAiB;IACjC,aAAa,CAAC,EAAE,eAAe,CAAC;IAChC,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAID,wBAAgB,OAAO,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CA0BzD"}
@@ -0,0 +1,24 @@
1
+ import { PIContextRequiredError } from "../types";
2
+ // Build a live LLMCall bound to the PI session's default model. Throws
3
+ // PIContextRequiredError when invoked outside a live PI runtime (no registry).
4
+ export function makeLLM(piCtx) {
5
+ return async (prompt, signal) => {
6
+ if (!piCtx.modelRegistry)
7
+ throw new PIContextRequiredError();
8
+ const mod = await import("@mariozechner/pi-ai");
9
+ const complete = mod.complete;
10
+ const model = piCtx.modelRegistry.find("", "");
11
+ const auth = await piCtx.modelRegistry.getApiKeyAndHeaders(model);
12
+ const resp = await complete(model, { messages: [{ role: "user", content: prompt }] }, {
13
+ apiKey: auth.apiKey,
14
+ headers: auth.headers,
15
+ maxTokens: 8192,
16
+ signal: signal ?? piCtx.signal,
17
+ });
18
+ return resp.content
19
+ .filter((c) => c.type === "text")
20
+ .map((c) => c.text ?? "")
21
+ .join("");
22
+ };
23
+ }
24
+ //# sourceMappingURL=llm-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-factory.js","sourceRoot":"","sources":["../../src/services/llm-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAalD,uEAAuE;AACvE,+EAA+E;AAC/E,MAAM,UAAU,OAAO,CAAC,KAAwB;IAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;QAC/B,IAAI,CAAC,KAAK,CAAC,aAAa;YAAE,MAAM,IAAI,sBAAsB,EAAE,CAAC;QAC7D,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;QAChD,MAAM,QAAQ,GACb,GAGA,CAAC,QAAQ,CAAC;QACX,MAAM,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAClE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAC1B,KAAK,EACL,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,EACjD;YACC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,MAAM,IAAI,KAAK,CAAC,MAAM;SAC9B,CACD,CAAC;QACF,OAAO,IAAI,CAAC,OAAO;aACjB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;aAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;aACxB,IAAI,CAAC,EAAE,CAAC,CAAC;IACZ,CAAC,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare class PathEscapeError extends Error {
2
+ constructor(given: string, root: string);
3
+ }
4
+ export declare class SymlinkRejectedError extends Error {
5
+ constructor(path: string);
6
+ }
7
+ export declare function safeResolveInCwd(input: string, cwd: string): string;
8
+ //# sourceMappingURL=path-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-guard.d.ts","sourceRoot":"","sources":["../../src/services/path-guard.ts"],"names":[],"mappings":"AAGA,qBAAa,eAAgB,SAAQ,KAAK;gBAC7B,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAIvC;AAED,qBAAa,oBAAqB,SAAQ,KAAK;gBAClC,IAAI,EAAE,MAAM;CAIxB;AAID,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAqBnE"}
@@ -0,0 +1,42 @@
1
+ import { lstatSync } from "node:fs";
2
+ import { resolve, sep } from "node:path";
3
+ export class PathEscapeError extends Error {
4
+ constructor(given, root) {
5
+ super(`ultra-compress: refusing to access "${given}" — escapes project root "${root}"`);
6
+ this.name = "PathEscapeError";
7
+ }
8
+ }
9
+ export class SymlinkRejectedError extends Error {
10
+ constructor(path) {
11
+ super(`ultra-compress: refusing to follow symlink at "${path}"`);
12
+ this.name = "SymlinkRejectedError";
13
+ }
14
+ }
15
+ // Resolve `input` against `cwd`, reject if the resolved path escapes cwd,
16
+ // and reject if any path component (the file itself) is a symlink.
17
+ export function safeResolveInCwd(input, cwd) {
18
+ const cwdAbs = resolve(cwd);
19
+ const abs = resolve(cwdAbs, input);
20
+ const prefix = cwdAbs.endsWith(sep) ? cwdAbs : cwdAbs + sep;
21
+ if (abs !== cwdAbs && !abs.startsWith(prefix)) {
22
+ throw new PathEscapeError(input, cwdAbs);
23
+ }
24
+ // lstat to detect symlinks without following them. Only checks the final
25
+ // path; acceptable for v1 (callers can't plant a symlink they couldn't
26
+ // already read/write via the OS). Skip if path doesn't exist (creation OK).
27
+ try {
28
+ const st = lstatSync(abs);
29
+ if (st.isSymbolicLink())
30
+ throw new SymlinkRejectedError(abs);
31
+ }
32
+ catch (e) {
33
+ if (e.code !== "ENOENT") {
34
+ if (e instanceof SymlinkRejectedError)
35
+ throw e;
36
+ // other stat errors (EACCES etc.) are passed through
37
+ throw e;
38
+ }
39
+ }
40
+ return abs;
41
+ }
42
+ //# sourceMappingURL=path-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-guard.js","sourceRoot":"","sources":["../../src/services/path-guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACzC,YAAY,KAAa,EAAE,IAAY;QACtC,KAAK,CAAC,uCAAuC,KAAK,6BAA6B,IAAI,GAAG,CAAC,CAAC;QACxF,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAC/B,CAAC;CACD;AAED,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC9C,YAAY,IAAY;QACvB,KAAK,CAAC,kDAAkD,IAAI,GAAG,CAAC,CAAC;QACjE,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACpC,CAAC;CACD;AAED,0EAA0E;AAC1E,mEAAmE;AACnE,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,GAAW;IAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;IAC5D,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IACD,yEAAyE;IACzE,uEAAuE;IACvE,4EAA4E;IAC5E,IAAI,CAAC;QACJ,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,EAAE,CAAC,cAAc,EAAE;YAAE,MAAM,IAAI,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC9D,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACZ,IAAK,CAA2B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACpD,IAAI,CAAC,YAAY,oBAAoB;gBAAE,MAAM,CAAC,CAAC;YAC/C,qDAAqD;YACrD,MAAM,CAAC,CAAC;QACT,CAAC;IACF,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Level, ProjectState } from "../types";
2
+ export declare function setProjectRootForTest(root: string): void;
3
+ export declare function loadState(projectRoot?: string): Promise<ProjectState>;
4
+ export declare function saveState(state: ProjectState, projectRoot?: string): Promise<void>;
5
+ export declare function saveLevel(level: Level, projectRoot?: string): Promise<ProjectState>;
6
+ export declare function resetSessionStats(projectRoot?: string): Promise<ProjectState>;
7
+ export declare function appendCompressedFile(entry: ProjectState["session"]["filesCompressed"][number], projectRoot?: string): Promise<void>;
8
+ export declare function incrementAutoClarity(projectRoot?: string): Promise<void>;
9
+ export declare function addCharsSaved(chars: number, projectRoot?: string): Promise<void>;
10
+ //# sourceMappingURL=state-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-store.d.ts","sourceRoot":"","sources":["../../src/services/state-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAgB,MAAM,UAAU,CAAC;AAOlE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAExD;AAwBD,wBAAsB,SAAS,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAmB3E;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBxF;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CASzF;AAED,wBAAsB,iBAAiB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CASnF;AAED,wBAAsB,oBAAoB,CACzC,KAAK,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC,EACzD,WAAW,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,wBAAsB,oBAAoB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9E;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAItF"}
@@ -0,0 +1,106 @@
1
+ import { existsSync, lstatSync } from "node:fs";
2
+ import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ const STATE_FILENAME = "ultra-compress.json";
5
+ const STATE_SUBDIR = ".pi";
6
+ let projectRootOverride;
7
+ export function setProjectRootForTest(root) {
8
+ projectRootOverride = root;
9
+ }
10
+ function resolveStatePath(projectRoot) {
11
+ const root = projectRootOverride ?? projectRoot ?? process.cwd();
12
+ return join(root, STATE_SUBDIR, STATE_FILENAME);
13
+ }
14
+ function freshSession() {
15
+ return {
16
+ startedAt: new Date().toISOString(),
17
+ autoClarityCount: 0,
18
+ estimatedOutputCharsSaved: 0,
19
+ filesCompressed: [],
20
+ };
21
+ }
22
+ function defaultState() {
23
+ return {
24
+ level: "off",
25
+ updatedAt: new Date().toISOString(),
26
+ session: freshSession(),
27
+ };
28
+ }
29
+ export async function loadState(projectRoot) {
30
+ const path = resolveStatePath(projectRoot);
31
+ if (!existsSync(path))
32
+ return defaultState();
33
+ try {
34
+ const raw = await readFile(path, "utf8");
35
+ const parsed = JSON.parse(raw);
36
+ if (!parsed || typeof parsed !== "object")
37
+ throw new Error("not an object");
38
+ const level = (parsed.level ?? "off");
39
+ return {
40
+ level,
41
+ updatedAt: parsed.updatedAt ?? new Date().toISOString(),
42
+ session: parsed.session ?? freshSession(),
43
+ };
44
+ }
45
+ catch {
46
+ const corruptPath = `${path}.corrupt-${Date.now()}`;
47
+ await rename(path, corruptPath).catch(() => { });
48
+ return defaultState();
49
+ }
50
+ }
51
+ export async function saveState(state, projectRoot) {
52
+ const path = resolveStatePath(projectRoot);
53
+ await mkdir(dirname(path), { recursive: true });
54
+ // Refuse to write if the existing path is a symlink (avoid writing through
55
+ // a symlink the user didn't intend).
56
+ try {
57
+ const st = lstatSync(path);
58
+ if (st.isSymbolicLink()) {
59
+ throw new Error(`ultra-compress: refusing to overwrite symlink state file at ${path}`);
60
+ }
61
+ }
62
+ catch (e) {
63
+ if (e.code !== "ENOENT")
64
+ throw e;
65
+ }
66
+ const tmp = `${path}.tmp-${process.pid}-${Math.random().toString(36).slice(2, 10)}`;
67
+ await writeFile(tmp, JSON.stringify(state, null, 2), "utf8");
68
+ await rename(tmp, path);
69
+ }
70
+ export async function saveLevel(level, projectRoot) {
71
+ const current = await loadState(projectRoot);
72
+ const next = {
73
+ ...current,
74
+ level,
75
+ updatedAt: new Date().toISOString(),
76
+ };
77
+ await saveState(next, projectRoot);
78
+ return next;
79
+ }
80
+ export async function resetSessionStats(projectRoot) {
81
+ const current = await loadState(projectRoot);
82
+ const next = {
83
+ ...current,
84
+ session: freshSession(),
85
+ updatedAt: new Date().toISOString(),
86
+ };
87
+ await saveState(next, projectRoot);
88
+ return next;
89
+ }
90
+ export async function appendCompressedFile(entry, projectRoot) {
91
+ const current = await loadState(projectRoot);
92
+ current.session.filesCompressed.push(entry);
93
+ current.updatedAt = new Date().toISOString();
94
+ await saveState(current, projectRoot);
95
+ }
96
+ export async function incrementAutoClarity(projectRoot) {
97
+ const current = await loadState(projectRoot);
98
+ current.session.autoClarityCount += 1;
99
+ await saveState(current, projectRoot);
100
+ }
101
+ export async function addCharsSaved(chars, projectRoot) {
102
+ const current = await loadState(projectRoot);
103
+ current.session.estimatedOutputCharsSaved += chars;
104
+ await saveState(current, projectRoot);
105
+ }
106
+ //# sourceMappingURL=state-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-store.js","sourceRoot":"","sources":["../../src/services/state-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Level } from "../types";
2
+ export declare function levelFactor(level: Level): number;
3
+ export declare function estimateCharsSaved(actualChars: number, level: Level): number;
4
+ //# sourceMappingURL=stats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/services/stats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAUtC,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAEhD;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAK5E"}
@@ -0,0 +1,18 @@
1
+ const FACTORS = {
2
+ off: 1,
3
+ lite: 0.85,
4
+ standard: 0.65,
5
+ ultra: 0.5,
6
+ symbolic: 0.4,
7
+ };
8
+ export function levelFactor(level) {
9
+ return FACTORS[level];
10
+ }
11
+ export function estimateCharsSaved(actualChars, level) {
12
+ if (level === "off")
13
+ return 0;
14
+ const factor = FACTORS[level];
15
+ const baseline = actualChars / factor;
16
+ return Math.max(0, Math.round(baseline - actualChars));
17
+ }
18
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/services/stats.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,GAA0B;IACtC,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,IAAI;IACV,QAAQ,EAAE,IAAI;IACd,KAAK,EAAE,GAAG;IACV,QAAQ,EAAE,GAAG;CACb,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,KAAY;IACvC,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,WAAmB,EAAE,KAAY;IACnE,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9B,MAAM,QAAQ,GAAG,WAAW,GAAG,MAAM,CAAC;IACtC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ValidatorReport } from "../types";
2
+ export declare function validateCompression(original: string, compressed: string): ValidatorReport;
3
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/services/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AA6BhD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,eAAe,CAkEzF"}
@@ -0,0 +1,87 @@
1
+ const FENCED_RE = /```[\s\S]*?```/g;
2
+ const URL_RE = /\bhttps?:\/\/\S+/g;
3
+ const PATH_RE = /(?:^|\s)(\.?[\w.\-/]+\/[\w.\-/]+)(?=\s|$)/g;
4
+ const HEADING_RE = /^(#{1,6})\s+(.+?)\s*$/gm;
5
+ const FRONTMATTER_RE = /^---\n([\s\S]*?)\n---\n/;
6
+ const BULLET_RE = /^\s*[-*+]\s+/gm;
7
+ const ARG_RE = /\$ARGUMENTS\b/g;
8
+ function extractAll(re, src, group = 0) {
9
+ const out = [];
10
+ const r = new RegExp(re.source, re.flags);
11
+ let m = r.exec(src);
12
+ while (m !== null) {
13
+ out.push(m[group] ?? m[0]);
14
+ m = r.exec(src);
15
+ }
16
+ return out;
17
+ }
18
+ function setEqual(a, b) {
19
+ const as = new Set(a);
20
+ const bs = new Set(b);
21
+ if (as.size !== bs.size)
22
+ return false;
23
+ for (const v of as)
24
+ if (!bs.has(v))
25
+ return false;
26
+ return true;
27
+ }
28
+ export function validateCompression(original, compressed) {
29
+ const errors = [];
30
+ const warnings = [];
31
+ const fencedBefore = extractAll(FENCED_RE, original);
32
+ const fencedAfter = extractAll(FENCED_RE, compressed);
33
+ if (fencedBefore.length !== fencedAfter.length) {
34
+ errors.push(`fenced code block count changed: ${fencedBefore.length} → ${fencedAfter.length}`);
35
+ }
36
+ else {
37
+ for (let i = 0; i < fencedBefore.length; i++) {
38
+ if (fencedBefore[i] !== fencedAfter[i]) {
39
+ errors.push(`fenced code block #${i} content changed`);
40
+ break;
41
+ }
42
+ }
43
+ }
44
+ const urlsBefore = extractAll(URL_RE, original);
45
+ const urlsAfter = extractAll(URL_RE, compressed);
46
+ if (!setEqual(urlsBefore, urlsAfter)) {
47
+ errors.push(`URL set changed (before=${urlsBefore.length}, after=${urlsAfter.length})`);
48
+ }
49
+ const pathsBefore = extractAll(PATH_RE, original, 1);
50
+ const pathsAfter = extractAll(PATH_RE, compressed, 1);
51
+ if (!setEqual(pathsBefore, pathsAfter)) {
52
+ errors.push(`path set changed (before=${pathsBefore.length}, after=${pathsAfter.length})`);
53
+ }
54
+ const headingsBefore = extractAll(HEADING_RE, original).map((h) => h.trim());
55
+ const headingsAfter = extractAll(HEADING_RE, compressed).map((h) => h.trim());
56
+ if (headingsBefore.length !== headingsAfter.length) {
57
+ errors.push(`heading count changed: ${headingsBefore.length} → ${headingsAfter.length}`);
58
+ }
59
+ else {
60
+ for (let i = 0; i < headingsBefore.length; i++) {
61
+ if (headingsBefore[i] !== headingsAfter[i]) {
62
+ errors.push(`heading order or text changed at position ${i}`);
63
+ break;
64
+ }
65
+ }
66
+ }
67
+ const fmBefore = original.match(FRONTMATTER_RE)?.[0];
68
+ const fmAfter = compressed.match(FRONTMATTER_RE)?.[0];
69
+ if (fmBefore && fmBefore !== fmAfter) {
70
+ errors.push("frontmatter drifted");
71
+ }
72
+ const argsBefore = (original.match(ARG_RE) ?? []).length;
73
+ const argsAfter = (compressed.match(ARG_RE) ?? []).length;
74
+ if (argsBefore !== argsAfter) {
75
+ errors.push(`$ARGUMENTS count changed: ${argsBefore} → ${argsAfter}`);
76
+ }
77
+ const bulletsBefore = (original.match(BULLET_RE) ?? []).length;
78
+ const bulletsAfter = (compressed.match(BULLET_RE) ?? []).length;
79
+ if (bulletsBefore > 0) {
80
+ const drift = Math.abs(bulletsBefore - bulletsAfter) / bulletsBefore;
81
+ if (drift > 0.15) {
82
+ warnings.push(`bullet count drift ${(drift * 100).toFixed(0)}% (${bulletsBefore} → ${bulletsAfter})`);
83
+ }
84
+ }
85
+ return { ok: errors.length === 0, warnings, errors };
86
+ }
87
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/services/validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: ultra-compress
3
+ description: "Compress runtime output or markdown files. Levels: off|lite|standard|ultra|symbolic. Triggers: \"caveman mode\" | \"ultra compress\" | \"shorten output\" | \"compress skill\" | \"compress this file\" | \"make it formal\" | \"use formal notation\" | \"talk like caveman\"."
4
+ license: MIT
5
+ allowed-tools: read, write, edit, glob, grep
6
+ disable-model-invocation: false
7
+ ---
8
+
9
+ # ultra-compress — κ
10
+
11
+ Let:
12
+ L ∈ {off, lite, standard, ultra, symbolic} — level
13
+ M ∈ {runtime, file} — mode
14
+ Π := protected zones (¬compress)
15
+ Ω := Auto-Clarity override
16
+
17
+ ## κ(L, M) — compress
18
+
19
+ M = runtime → reshape current assistant msg per L rules.
20
+ M = file → rewrite .md file per L rules, preserve Π byte-identical.
21
+
22
+ Each L ⊃ all prior L's rules (inheritance).
23
+
24
+ ## L = lite
25
+
26
+ ¬{filler: just, really, basically, actually, simply, essentially, generally};
27
+ ¬{hedging: "might be worth", "could consider", "you might want to"};
28
+ ¬{pleasantries: sure, certainly, "of course", "happy to", "I'd recommend"};
29
+ keep articles ∧ full sentences.
30
+
31
+ ## L = standard
32
+
33
+ lite ∧:
34
+ ¬articles(a, an, the);
35
+ ¬connectives(however, furthermore, additionally, moreover);
36
+ fragments OK: [thing] [action] [reason]. [next].
37
+ subst: {utilize → use, "in order to" → to, "make sure to" → ensure,
38
+ "the reason is because" → because, "prior to" → before}.
39
+
40
+ ## L = ultra
41
+
42
+ standard ∧:
43
+ abbrev: {database → DB, authentication → auth, configuration → config,
44
+ request → req, response → res, function → fn, implementation → impl,
45
+ environment → env, error → err};
46
+ causality: "X causes Y" → "X → Y";
47
+ ¬conjunctions(where meaning survives).
48
+
49
+ ## L = symbolic
50
+
51
+ ultra ∧:
52
+ math/logic ops: {∀, ∃, ∧, ∨, ¬, →, ⟺, ∈, ∉, ⊂, ∪, ∩, ∅, { }, ; };
53
+ predicate folding: "pred(x) ⟺ A ∧ B";
54
+ Greek vars (φ, γ, τ, π, σ) ← concepts ≥3×;
55
+ IMPORTANT: ∃ context ⟹ reader ¬fluent(notation) → fallback L = ultra.
56
+
57
+ ## Π — protected zones (¬compress, ∀ L, ∀ M)
58
+
59
+ frontmatter · fenced + inline code · URLs · file paths · CLI commands ·
60
+ headings(count + order) · $ARGUMENTS · tool names · numeric versions/dates ·
61
+ quoted error strings · table structure · bullet nesting depth.
62
+
63
+ ## Ω — Auto-Clarity (M = runtime ∧ L ≠ off)
64
+
65
+ turn ∈ { security-warning, destructive-confirm, ordered-multi-step, verbatim-error-quote }
66
+ → fallback prose(current msg) ∧ resume(L, next turn) ∧ autoClarityCount += 1.
67
+
68
+ destructive := { rm -rf, "git reset --hard", force-push, DROP, TRUNCATE }.
69
+
70
+ ## file-mode pipeline (M = file)
71
+
72
+ O_file {
73
+ resolve(path);
74
+ guard(size ≤ 500KB ∧ ext ∈ {md, txt, rst} ∧ ¬backup-exists);
75
+ mask(input, Π) → (masked, tokens);
76
+ lexical-pre-pass(masked, L) → L-masked;
77
+ LLM(L-masked, level-prompt(L, file)) → raw;
78
+ strip-outer-fence(raw) → stripped;
79
+ unmask(stripped, tokens) → candidate;
80
+ validate(input, candidate) → report;
81
+ report.ok ? write(candidate, backup=.original.md) : repair-loop(≤ 2);
82
+ } → { compressed, ratio, warnings }.
83
+
84
+ repair-loop: LLM(¬recompress ∧ patch-only(report.errors)) → retry.
85
+ final-fail → restore(original) ∧ throw ValidatorFailedError.
86
+
87
+ ## commands (PI)
88
+
89
+ /uc L → κ-runtime set L, persist .pi/ultra-compress.json
90
+ /uc-file path L [--yes] → κ-file path L, preview unless --yes
91
+ /uc-status → L ∧ session stats
92
+ /uc-revert path → restore path from .original.md
93
+
94
+ completers: autocomplete(L) ∀ /uc, /uc-file; glob(*.md) ∀ /uc-file position 1.
@@ -0,0 +1,62 @@
1
+ export type Level = "off" | "lite" | "standard" | "ultra" | "symbolic";
2
+ export type ActiveLevel = Exclude<Level, "off">;
3
+ export type Mode = "runtime" | "file";
4
+ export declare const ALL_LEVELS: readonly ["off", "lite", "standard", "ultra", "symbolic"];
5
+ export declare const ACTIVE_LEVELS: readonly ["lite", "standard", "ultra", "symbolic"];
6
+ export interface SessionStats {
7
+ startedAt: string;
8
+ autoClarityCount: number;
9
+ estimatedOutputCharsSaved: number;
10
+ filesCompressed: CompressedFileEntry[];
11
+ }
12
+ export interface CompressedFileEntry {
13
+ path: string;
14
+ level: ActiveLevel;
15
+ before: number;
16
+ after: number;
17
+ at: string;
18
+ }
19
+ export interface ProjectState {
20
+ level: Level;
21
+ updatedAt: string;
22
+ session: SessionStats;
23
+ }
24
+ export interface CompressResult {
25
+ compressed: string;
26
+ before: number;
27
+ after: number;
28
+ ratio: number;
29
+ warnings: string[];
30
+ substitutions?: Array<{
31
+ symbol: string;
32
+ concept: string;
33
+ }>;
34
+ }
35
+ export interface CompressOptions {
36
+ maxRepairRetries?: number;
37
+ }
38
+ export interface ValidatorReport {
39
+ ok: boolean;
40
+ warnings: string[];
41
+ errors: string[];
42
+ }
43
+ export declare class PIContextRequiredError extends Error {
44
+ constructor();
45
+ }
46
+ export declare class InvalidLevelError extends Error {
47
+ constructor(given: string);
48
+ }
49
+ export declare class FileTooLargeError extends Error {
50
+ constructor(path: string, bytes: number);
51
+ }
52
+ export declare class BackupExistsError extends Error {
53
+ constructor(backupPath: string);
54
+ }
55
+ export declare class UnsupportedFileTypeError extends Error {
56
+ constructor(path: string, reason: string);
57
+ }
58
+ export declare class ValidatorFailedError extends Error {
59
+ readonly errors: string[];
60
+ constructor(errors: string[]);
61
+ }
62
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;AAEvE,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAEhD,MAAM,MAAM,IAAI,GAAG,SAAS,GAAG,MAAM,CAAC;AAEtC,eAAO,MAAM,UAAU,2DAA4D,CAAC;AACpF,eAAO,MAAM,aAAa,oDAAqD,CAAC;AAEhF,MAAM,WAAW,YAAY;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,yBAAyB,EAAE,MAAM,CAAC;IAClC,eAAe,EAAE,mBAAmB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,eAAe;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,qBAAa,sBAAuB,SAAQ,KAAK;;CAKhD;AAED,qBAAa,iBAAkB,SAAQ,KAAK;gBAC/B,KAAK,EAAE,MAAM;CAMzB;AAED,qBAAa,iBAAkB,SAAQ,KAAK;gBAC/B,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;CAIvC;AAED,qBAAa,iBAAkB,SAAQ,KAAK;gBAC/B,UAAU,EAAE,MAAM;CAI9B;AAED,qBAAa,wBAAyB,SAAQ,KAAK;gBACtC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAIxC;AAED,qBAAa,oBAAqB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;gBACd,MAAM,EAAE,MAAM,EAAE;CAK5B"}
package/dist/types.js ADDED
@@ -0,0 +1,41 @@
1
+ export const ALL_LEVELS = ["off", "lite", "standard", "ultra", "symbolic"];
2
+ export const ACTIVE_LEVELS = ["lite", "standard", "ultra", "symbolic"];
3
+ export class PIContextRequiredError extends Error {
4
+ constructor() {
5
+ super("ultra-compress: PI ExtensionContext is required for LLM-backed operations");
6
+ this.name = "PIContextRequiredError";
7
+ }
8
+ }
9
+ export class InvalidLevelError extends Error {
10
+ constructor(given) {
11
+ super(`ultra-compress: invalid level "${given}" (expected one of: off|lite|standard|ultra|symbolic)`);
12
+ this.name = "InvalidLevelError";
13
+ }
14
+ }
15
+ export class FileTooLargeError extends Error {
16
+ constructor(path, bytes) {
17
+ super(`ultra-compress: file "${path}" is ${bytes} bytes (max 512000)`);
18
+ this.name = "FileTooLargeError";
19
+ }
20
+ }
21
+ export class BackupExistsError extends Error {
22
+ constructor(backupPath) {
23
+ super(`ultra-compress: backup "${backupPath}" already exists — run /uc-revert first`);
24
+ this.name = "BackupExistsError";
25
+ }
26
+ }
27
+ export class UnsupportedFileTypeError extends Error {
28
+ constructor(path, reason) {
29
+ super(`ultra-compress: refusing to compress "${path}": ${reason}`);
30
+ this.name = "UnsupportedFileTypeError";
31
+ }
32
+ }
33
+ export class ValidatorFailedError extends Error {
34
+ errors;
35
+ constructor(errors) {
36
+ super(`ultra-compress: validator failed after repair retries — ${errors.join("; ")}`);
37
+ this.name = "ValidatorFailedError";
38
+ this.errors = errors;
39
+ }
40
+ }
41
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,CAAU,CAAC;AACpF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,CAAU,CAAC;AA0ChF,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAChD;QACC,KAAK,CAAC,2EAA2E,CAAC,CAAC;QACnF,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACtC,CAAC;CACD;AAED,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC3C,YAAY,KAAa;QACxB,KAAK,CACJ,kCAAkC,KAAK,uDAAuD,CAC9F,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IACjC,CAAC;CACD;AAED,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC3C,YAAY,IAAY,EAAE,KAAa;QACtC,KAAK,CAAC,yBAAyB,IAAI,QAAQ,KAAK,qBAAqB,CAAC,CAAC;QACvE,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IACjC,CAAC;CACD;AAED,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC3C,YAAY,UAAkB;QAC7B,KAAK,CAAC,2BAA2B,UAAU,yCAAyC,CAAC,CAAC;QACtF,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IACjC,CAAC;CACD;AAED,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IAClD,YAAY,IAAY,EAAE,MAAc;QACvC,KAAK,CAAC,yCAAyC,IAAI,MAAM,MAAM,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACxC,CAAC;CACD;AAED,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACrC,MAAM,CAAW;IAC1B,YAAY,MAAgB;QAC3B,KAAK,CAAC,2DAA2D,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtF,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;CACD"}