@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.
- package/LICENSE +21 -0
- package/README.md +144 -0
- package/dist/commands/index.d.ts +6 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +5 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/types.d.ts +18 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +2 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/commands/uc-file.d.ts +7 -0
- package/dist/commands/uc-file.d.ts.map +1 -0
- package/dist/commands/uc-file.js +105 -0
- package/dist/commands/uc-file.js.map +1 -0
- package/dist/commands/uc-revert.d.ts +3 -0
- package/dist/commands/uc-revert.d.ts.map +1 -0
- package/dist/commands/uc-revert.js +38 -0
- package/dist/commands/uc-revert.js.map +1 -0
- package/dist/commands/uc-status.d.ts +3 -0
- package/dist/commands/uc-status.d.ts.map +1 -0
- package/dist/commands/uc-status.js +27 -0
- package/dist/commands/uc-status.js.map +1 -0
- package/dist/commands/uc.d.ts +3 -0
- package/dist/commands/uc.d.ts.map +1 -0
- package/dist/commands/uc.js +28 -0
- package/dist/commands/uc.js.map +1 -0
- package/dist/hooks/agent-end.d.ts +10 -0
- package/dist/hooks/agent-end.d.ts.map +1 -0
- package/dist/hooks/agent-end.js +38 -0
- package/dist/hooks/agent-end.js.map +1 -0
- package/dist/hooks/before-agent-start.d.ts +13 -0
- package/dist/hooks/before-agent-start.d.ts.map +1 -0
- package/dist/hooks/before-agent-start.js +11 -0
- package/dist/hooks/before-agent-start.js.map +1 -0
- package/dist/hooks/index.d.ts +7 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +4 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/session-start.d.ts +13 -0
- package/dist/hooks/session-start.d.ts.map +1 -0
- package/dist/hooks/session-start.js +11 -0
- package/dist/hooks/session-start.js.map +1 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +101 -0
- package/dist/index.js.map +1 -0
- package/dist/services/backup-path.d.ts +2 -0
- package/dist/services/backup-path.d.ts.map +1 -0
- package/dist/services/backup-path.js +7 -0
- package/dist/services/backup-path.js.map +1 -0
- package/dist/services/compress-pipeline.d.ts +12 -0
- package/dist/services/compress-pipeline.d.ts.map +1 -0
- package/dist/services/compress-pipeline.js +81 -0
- package/dist/services/compress-pipeline.js.map +1 -0
- package/dist/services/file-ops.d.ts +12 -0
- package/dist/services/file-ops.d.ts.map +1 -0
- package/dist/services/file-ops.js +58 -0
- package/dist/services/file-ops.js.map +1 -0
- package/dist/services/index.d.ts +8 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +7 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/level-prompts.d.ts +3 -0
- package/dist/services/level-prompts.d.ts.map +1 -0
- package/dist/services/level-prompts.js +78 -0
- package/dist/services/level-prompts.js.map +1 -0
- package/dist/services/level-rules.d.ts +9 -0
- package/dist/services/level-rules.d.ts.map +1 -0
- package/dist/services/level-rules.js +110 -0
- package/dist/services/level-rules.js.map +1 -0
- package/dist/services/llm-factory.d.ts +15 -0
- package/dist/services/llm-factory.d.ts.map +1 -0
- package/dist/services/llm-factory.js +24 -0
- package/dist/services/llm-factory.js.map +1 -0
- package/dist/services/path-guard.d.ts +8 -0
- package/dist/services/path-guard.d.ts.map +1 -0
- package/dist/services/path-guard.js +42 -0
- package/dist/services/path-guard.js.map +1 -0
- package/dist/services/state-store.d.ts +10 -0
- package/dist/services/state-store.d.ts.map +1 -0
- package/dist/services/state-store.js +106 -0
- package/dist/services/state-store.js.map +1 -0
- package/dist/services/stats.d.ts +4 -0
- package/dist/services/stats.d.ts.map +1 -0
- package/dist/services/stats.js +18 -0
- package/dist/services/stats.js.map +1 -0
- package/dist/services/validator.d.ts +3 -0
- package/dist/services/validator.d.ts.map +1 -0
- package/dist/services/validator.js +87 -0
- package/dist/services/validator.js.map +1 -0
- package/dist/skills/ultra-compress/SKILL.md +94 -0
- package/dist/types.d.ts +62 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +41 -0
- package/dist/types.js.map +1 -0
- package/package.json +90 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 The Forge Flow
|
|
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
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/MonsieurBarti/The-Forge-Flow-CC/refs/heads/main/assets/forge-banner.png" alt="The Forge Flow" width="100%">
|
|
3
|
+
|
|
4
|
+
<h1>🗜️ Ultra-Compress PI Extension</h1>
|
|
5
|
+
|
|
6
|
+
<p>
|
|
7
|
+
<strong>Token-efficient prose for PI coding agents — level-based runtime compression and markdown file compression</strong>
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
<p>
|
|
11
|
+
<a href="https://github.com/MonsieurBarti/ultra-compress-pi/actions/workflows/ci.yml">
|
|
12
|
+
<img src="https://img.shields.io/github/actions/workflow/status/MonsieurBarti/ultra-compress-pi/ci.yml?label=CI&style=flat-square" alt="CI Status">
|
|
13
|
+
</a>
|
|
14
|
+
<a href="https://www.npmjs.com/package/@the-forge-flow/ultra-compress-pi">
|
|
15
|
+
<img src="https://img.shields.io/npm/v/@the-forge-flow/ultra-compress-pi?style=flat-square" alt="npm version">
|
|
16
|
+
</a>
|
|
17
|
+
<a href="LICENSE">
|
|
18
|
+
<img src="https://img.shields.io/github/license/MonsieurBarti/ultra-compress-pi?style=flat-square" alt="License">
|
|
19
|
+
</a>
|
|
20
|
+
</p>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
> "why use many token when few do trick"
|
|
26
|
+
|
|
27
|
+
## ✨ Features
|
|
28
|
+
|
|
29
|
+
- **🎚️ Runtime mode**: Reshape assistant output via a persistent compression level (`/uc <level>`). Auto-Clarity override falls back to prose for destructive/security/ordered turns.
|
|
30
|
+
- **📝 File mode**: Compress markdown files (skills, agents, memory docs) via `/uc-file <path> <level>`. Deterministic pre-pass → LLM rewrite → structural validator → targeted repair loop.
|
|
31
|
+
- **🪜 Five levels**: `off`, `lite`, `standard`, `ultra`, `symbolic` — from no change to Greek/math notation.
|
|
32
|
+
- **💾 Safe by default**: File mode backs up originals to `<path>.original.md`; `/uc-revert` restores them.
|
|
33
|
+
- **📚 Library API**: Importable helpers for other PI extensions to apply the same compression rules.
|
|
34
|
+
|
|
35
|
+
## 🪜 Levels
|
|
36
|
+
|
|
37
|
+
| Level | Effect |
|
|
38
|
+
|---|---|
|
|
39
|
+
| `off` | No modification. |
|
|
40
|
+
| `lite` | Drop filler, hedging, pleasantries. Keep articles. |
|
|
41
|
+
| `standard` | Drop articles + connectives. Fragments OK. Substitutions. |
|
|
42
|
+
| `ultra` | Abbreviations (DB, auth, req, res, fn, impl). Arrow causality. |
|
|
43
|
+
| `symbolic` | Math/logic notation (∀ ∃ ∧ → ⟺). Greek vars for repeated concepts. |
|
|
44
|
+
|
|
45
|
+
## 📦 Installation
|
|
46
|
+
|
|
47
|
+
PI discovers the extension automatically once installed as a pi package.
|
|
48
|
+
|
|
49
|
+
**From npm:**
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pi install npm:@the-forge-flow/ultra-compress-pi
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**From GitHub:**
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pi install git:github.com/MonsieurBarti/ultra-compress-pi
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Then reload PI with `/reload`.
|
|
62
|
+
|
|
63
|
+
## 🚀 Usage
|
|
64
|
+
|
|
65
|
+
### Commands
|
|
66
|
+
|
|
67
|
+
| Command | Description |
|
|
68
|
+
|---|---|
|
|
69
|
+
| `/uc <level>` | Set the active level for this project. Autocomplete over the 5 levels. Persists in `.pi/ultra-compress.json`. |
|
|
70
|
+
| `/uc-file <path> <level> [--yes]` | Compress a markdown file. Without `--yes`, prints a preview. With `--yes`, writes and backs up to `<path>.original.md`. |
|
|
71
|
+
| `/uc-status` | Show active level, session stats, and recently compressed files. |
|
|
72
|
+
| `/uc-revert <path>` | Restore a file from its `.original.md` backup. |
|
|
73
|
+
|
|
74
|
+
### Library API (for other PI extensions)
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import {
|
|
78
|
+
compressText,
|
|
79
|
+
compressTextLexical,
|
|
80
|
+
buildLevelPromptFragment,
|
|
81
|
+
validateCompression,
|
|
82
|
+
getActiveLevel,
|
|
83
|
+
} from "@the-forge-flow/ultra-compress-pi";
|
|
84
|
+
|
|
85
|
+
// In your extension's command/hook handler:
|
|
86
|
+
const result = await compressText(markdownBody, "ultra", ctx);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
All LLM-backed methods require an active PI `ExtensionContext` (for model registry access).
|
|
90
|
+
|
|
91
|
+
## 🧪 Development
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Install dependencies
|
|
95
|
+
bun install
|
|
96
|
+
|
|
97
|
+
# Run tests
|
|
98
|
+
bun test
|
|
99
|
+
|
|
100
|
+
# Lint & format
|
|
101
|
+
bun run lint
|
|
102
|
+
|
|
103
|
+
# Type check
|
|
104
|
+
bun run typecheck
|
|
105
|
+
|
|
106
|
+
# Build for publish
|
|
107
|
+
bun run build
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## 📁 Project Structure
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
src/
|
|
114
|
+
├── index.ts # Extension entry point + library exports
|
|
115
|
+
├── commands/ # /uc, /uc-file, /uc-status, /uc-revert
|
|
116
|
+
├── hooks/ # session_start, before_agent_start
|
|
117
|
+
├── services/ # state-store, level-rules, compress-pipeline, validator, stats
|
|
118
|
+
└── skills/
|
|
119
|
+
└── ultra-compress/
|
|
120
|
+
└── SKILL.md # dogfooded symbolic notation
|
|
121
|
+
tests/
|
|
122
|
+
└── unit/ # Unit tests
|
|
123
|
+
.github/workflows/
|
|
124
|
+
├── ci.yml # CI pipeline
|
|
125
|
+
└── release.yml # Release automation
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 🤝 Contributing
|
|
129
|
+
|
|
130
|
+
1. Fork the repository
|
|
131
|
+
2. Create your feature branch (`git checkout -b feature/amazing`)
|
|
132
|
+
3. Commit with conventional commits (`git commit -m "feat: add something"`)
|
|
133
|
+
4. Push to the branch (`git push origin feature/amazing`)
|
|
134
|
+
5. Open a Pull Request
|
|
135
|
+
|
|
136
|
+
## 📜 License
|
|
137
|
+
|
|
138
|
+
MIT © [MonsieurBarti](https://github.com/MonsieurBarti)
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
<div align="center">
|
|
143
|
+
<sub>Built with ⚡ by <a href="https://github.com/MonsieurBarti">MonsieurBarti</a></sub>
|
|
144
|
+
</div>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { createUcCommand } from "./uc";
|
|
2
|
+
export { createUcFileCommand } from "./uc-file";
|
|
3
|
+
export { createUcStatusCommand } from "./uc-status";
|
|
4
|
+
export { createUcRevertCommand } from "./uc-revert";
|
|
5
|
+
export type { AutocompleteItem, CommandContext, CommandDefinition, CommandUI } from "./types";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface AutocompleteItem {
|
|
2
|
+
value: string;
|
|
3
|
+
label: string;
|
|
4
|
+
}
|
|
5
|
+
export interface CommandUI {
|
|
6
|
+
notify(message: string, level?: "info" | "warning" | "error"): void;
|
|
7
|
+
}
|
|
8
|
+
export interface CommandContext {
|
|
9
|
+
cwd: string;
|
|
10
|
+
ui: CommandUI;
|
|
11
|
+
}
|
|
12
|
+
export interface CommandDefinition {
|
|
13
|
+
name: string;
|
|
14
|
+
description: string;
|
|
15
|
+
handler(args: string, ctx: CommandContext): Promise<void>;
|
|
16
|
+
getArgumentCompletions?(prefix: string): AutocompleteItem[] | null;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/commands/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,SAAS;IACzB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,IAAI,CAAC;CACpE;AAED,MAAM,WAAW,cAAc;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,SAAS,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,sBAAsB,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,EAAE,GAAG,IAAI,CAAC;CACnE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/commands/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CommandContext, CommandDefinition } from "./types";
|
|
2
|
+
export interface UcFileDeps {
|
|
3
|
+
llm: (ctx: CommandContext) => import("../services/compress-pipeline").LLMCall;
|
|
4
|
+
cwd?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function createUcFileCommand(deps: UcFileDeps): CommandDefinition;
|
|
7
|
+
//# sourceMappingURL=uc-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uc-file.d.ts","sourceRoot":"","sources":["../../src/commands/uc-file.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAoB,cAAc,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEnF,MAAM,WAAW,UAAU;IAC1B,GAAG,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,+BAA+B,EAAE,OAAO,CAAC;IAC9E,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAiBD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,iBAAiB,CA8FvE"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { readdirSync } from "node:fs";
|
|
2
|
+
import { basename, join } from "node:path";
|
|
3
|
+
import { compressTextPipeline } from "../services/compress-pipeline";
|
|
4
|
+
import { extOf, isSupportedExtension, resolveForCompression, writeWithBackup, } from "../services/file-ops";
|
|
5
|
+
import { PathEscapeError, SymlinkRejectedError } from "../services/path-guard";
|
|
6
|
+
import { appendCompressedFile } from "../services/state-store";
|
|
7
|
+
import { ACTIVE_LEVELS, BackupExistsError, FileTooLargeError, InvalidLevelError, UnsupportedFileTypeError, } from "../types";
|
|
8
|
+
function isActiveLevel(s) {
|
|
9
|
+
return ACTIVE_LEVELS.includes(s);
|
|
10
|
+
}
|
|
11
|
+
function parseArgs(args) {
|
|
12
|
+
const parts = args.trim().split(/\s+/);
|
|
13
|
+
const yes = parts.includes("--yes");
|
|
14
|
+
const filtered = parts.filter((p) => p !== "--yes");
|
|
15
|
+
return {
|
|
16
|
+
path: filtered[0] ?? "",
|
|
17
|
+
level: filtered[1] ?? "",
|
|
18
|
+
yes,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function createUcFileCommand(deps) {
|
|
22
|
+
return {
|
|
23
|
+
name: "uc-file",
|
|
24
|
+
description: "Compress a markdown file to a given level (preview → write with backup).",
|
|
25
|
+
getArgumentCompletions(prefix) {
|
|
26
|
+
const parts = prefix.split(/\s+/);
|
|
27
|
+
if (parts.length >= 2) {
|
|
28
|
+
const levelPrefix = parts[parts.length - 1] ?? "";
|
|
29
|
+
const items = ACTIVE_LEVELS.filter((l) => l.startsWith(levelPrefix)).map((l) => ({
|
|
30
|
+
value: l,
|
|
31
|
+
label: l,
|
|
32
|
+
}));
|
|
33
|
+
return items.length > 0 ? items : null;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const cwd = deps.cwd ?? process.cwd();
|
|
37
|
+
const entries = readdirSync(cwd, { withFileTypes: true });
|
|
38
|
+
const files = entries
|
|
39
|
+
.filter((e) => e.isFile() && isSupportedExtension(extOf(e.name)))
|
|
40
|
+
.map((e) => join(cwd, e.name))
|
|
41
|
+
.filter((p) => p.startsWith(join(cwd, parts[0] ?? "")));
|
|
42
|
+
return files.length > 0 ? files.map((f) => ({ value: f, label: basename(f) })) : null;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
async handler(args, ctx) {
|
|
49
|
+
const { path, level, yes } = parseArgs(args);
|
|
50
|
+
if (!isActiveLevel(level)) {
|
|
51
|
+
ctx.ui.notify(new InvalidLevelError(level).message, "error");
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
let abs;
|
|
55
|
+
let backupPath;
|
|
56
|
+
let input;
|
|
57
|
+
try {
|
|
58
|
+
({ abs, backupPath, content: input } = resolveForCompression(path, ctx.cwd));
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
if (e instanceof PathEscapeError ||
|
|
62
|
+
e instanceof SymlinkRejectedError ||
|
|
63
|
+
e instanceof UnsupportedFileTypeError ||
|
|
64
|
+
e instanceof BackupExistsError ||
|
|
65
|
+
e instanceof FileTooLargeError) {
|
|
66
|
+
ctx.ui.notify(e.message, "error");
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
throw e;
|
|
70
|
+
}
|
|
71
|
+
const llm = deps.llm(ctx);
|
|
72
|
+
let result;
|
|
73
|
+
try {
|
|
74
|
+
result = await compressTextPipeline({
|
|
75
|
+
input,
|
|
76
|
+
level,
|
|
77
|
+
mode: "file",
|
|
78
|
+
llm,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
ctx.ui.notify(`ultra-compress: ${e.message}`, "error");
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (!yes) {
|
|
86
|
+
const pct = Math.round(result.ratio * 100);
|
|
87
|
+
ctx.ui.notify(`ultra-compress preview: ${input.length} → ${result.compressed.length} (${pct}% saved). Re-run with --yes to write.`, "info");
|
|
88
|
+
if (result.warnings.length > 0) {
|
|
89
|
+
ctx.ui.notify(`warnings: ${result.warnings.join(" | ")}`, "warning");
|
|
90
|
+
}
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
writeWithBackup(abs, backupPath, result.compressed);
|
|
94
|
+
await appendCompressedFile({
|
|
95
|
+
path: abs,
|
|
96
|
+
level,
|
|
97
|
+
before: input.length,
|
|
98
|
+
after: result.compressed.length,
|
|
99
|
+
at: new Date().toISOString(),
|
|
100
|
+
}, ctx.cwd);
|
|
101
|
+
ctx.ui.notify(`ultra-compress: compressed and written. Backup at ${backupPath}.`, "info");
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=uc-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uc-file.js","sourceRoot":"","sources":["../../src/commands/uc-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uc-revert.d.ts","sourceRoot":"","sources":["../../src/commands/uc-revert.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,wBAAgB,qBAAqB,IAAI,iBAAiB,CAgCzD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { restoreFromBackup } from "../services/file-ops";
|
|
2
|
+
import { PathEscapeError, SymlinkRejectedError, safeResolveInCwd } from "../services/path-guard";
|
|
3
|
+
export function createUcRevertCommand() {
|
|
4
|
+
return {
|
|
5
|
+
name: "uc-revert",
|
|
6
|
+
description: "Restore a file from its ultra-compress .original.md backup.",
|
|
7
|
+
async handler(args, ctx) {
|
|
8
|
+
const path = args.trim();
|
|
9
|
+
if (!path) {
|
|
10
|
+
ctx.ui.notify("ultra-compress: usage: /uc-revert <path>", "error");
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
let abs;
|
|
14
|
+
try {
|
|
15
|
+
abs = safeResolveInCwd(path, ctx.cwd);
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
if (e instanceof PathEscapeError || e instanceof SymlinkRejectedError) {
|
|
19
|
+
ctx.ui.notify(e.message, "error");
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
throw e;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
restoreFromBackup(abs);
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
if (e.name === "NoBackupError") {
|
|
29
|
+
ctx.ui.notify(e.message, "error");
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
throw e;
|
|
33
|
+
}
|
|
34
|
+
ctx.ui.notify(`ultra-compress: restored ${abs} from backup.`, "info");
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=uc-revert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uc-revert.js","sourceRoot":"","sources":["../../src/commands/uc-revert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAGjG,MAAM,UAAU,qBAAqB;IACpC,OAAO;QACN,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,6DAA6D;QAC1E,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG;YACtB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,EAAE,CAAC;gBACX,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,0CAA0C,EAAE,OAAO,CAAC,CAAC;gBACnE,OAAO;YACR,CAAC;YACD,IAAI,GAAW,CAAC;YAChB,IAAI,CAAC;gBACJ,GAAG,GAAG,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;YACvC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,IAAI,CAAC,YAAY,eAAe,IAAI,CAAC,YAAY,oBAAoB,EAAE,CAAC;oBACvE,GAAG,CAAC,EAAE,CAAC,MAAM,CAAE,CAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;oBAC7C,OAAO;gBACR,CAAC;gBACD,MAAM,CAAC,CAAC;YACT,CAAC;YACD,IAAI,CAAC;gBACJ,iBAAiB,CAAC,GAAG,CAAC,CAAC;YACxB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,IAAK,CAAW,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;oBAC3C,GAAG,CAAC,EAAE,CAAC,MAAM,CAAE,CAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;oBAC7C,OAAO;gBACR,CAAC;gBACD,MAAM,CAAC,CAAC;YACT,CAAC;YACD,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,4BAA4B,GAAG,eAAe,EAAE,MAAM,CAAC,CAAC;QACvE,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uc-status.d.ts","sourceRoot":"","sources":["../../src/commands/uc-status.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,wBAAgB,qBAAqB,IAAI,iBAAiB,CAyBzD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { basename } from "node:path";
|
|
2
|
+
import { loadState } from "../services/state-store";
|
|
3
|
+
export function createUcStatusCommand() {
|
|
4
|
+
return {
|
|
5
|
+
name: "uc-status",
|
|
6
|
+
description: "Show ultra-compress active level and session stats.",
|
|
7
|
+
async handler(_args, ctx) {
|
|
8
|
+
const state = await loadState(ctx.cwd);
|
|
9
|
+
const last = state.session.filesCompressed.slice(-5);
|
|
10
|
+
const lastStr = last.length === 0
|
|
11
|
+
? "none"
|
|
12
|
+
: last
|
|
13
|
+
.map((f) => {
|
|
14
|
+
const pct = Math.round(((f.before - f.after) / f.before) * 100);
|
|
15
|
+
return `${basename(f.path)} (${f.level} ${pct}%)`;
|
|
16
|
+
})
|
|
17
|
+
.join(", ");
|
|
18
|
+
const msg = `ultra-compress: ${state.level} · ` +
|
|
19
|
+
`session started ${state.session.startedAt} · ` +
|
|
20
|
+
`~${state.session.estimatedOutputCharsSaved} chars saved · ` +
|
|
21
|
+
`auto-clarity ${state.session.autoClarityCount}× · ` +
|
|
22
|
+
`recent files: ${lastStr}`;
|
|
23
|
+
ctx.ui.notify(msg, "info");
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=uc-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uc-status.js","sourceRoot":"","sources":["../../src/commands/uc-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGpD,MAAM,UAAU,qBAAqB;IACpC,OAAO;QACN,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,qDAAqD;QAClE,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG;YACvB,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACvC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM,OAAO,GACZ,IAAI,CAAC,MAAM,KAAK,CAAC;gBAChB,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,IAAI;qBACH,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;oBACV,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;oBAChE,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;gBACnD,CAAC,CAAC;qBACD,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,MAAM,GAAG,GACR,mBAAmB,KAAK,CAAC,KAAK,KAAK;gBACnC,mBAAmB,KAAK,CAAC,OAAO,CAAC,SAAS,KAAK;gBAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,yBAAyB,iBAAiB;gBAC5D,gBAAgB,KAAK,CAAC,OAAO,CAAC,gBAAgB,MAAM;gBACpD,iBAAiB,OAAO,EAAE,CAAC;YAC5B,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC5B,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uc.d.ts","sourceRoot":"","sources":["../../src/commands/uc.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAoB,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAMnE,wBAAgB,eAAe,IAAI,iBAAiB,CAsBnD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { saveLevel } from "../services/state-store";
|
|
2
|
+
import { ALL_LEVELS, InvalidLevelError } from "../types";
|
|
3
|
+
function isLevel(s) {
|
|
4
|
+
return ALL_LEVELS.includes(s);
|
|
5
|
+
}
|
|
6
|
+
export function createUcCommand() {
|
|
7
|
+
return {
|
|
8
|
+
name: "uc",
|
|
9
|
+
description: "Set the ultra-compress level for this project (off|lite|standard|ultra|symbolic).",
|
|
10
|
+
getArgumentCompletions(prefix) {
|
|
11
|
+
const items = ALL_LEVELS.filter((l) => l.startsWith(prefix)).map((l) => ({
|
|
12
|
+
value: l,
|
|
13
|
+
label: l,
|
|
14
|
+
}));
|
|
15
|
+
return items.length > 0 ? items : null;
|
|
16
|
+
},
|
|
17
|
+
async handler(args, ctx) {
|
|
18
|
+
const level = args.trim();
|
|
19
|
+
if (!isLevel(level)) {
|
|
20
|
+
ctx.ui.notify(new InvalidLevelError(level).message, "error");
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
await saveLevel(level, ctx.cwd);
|
|
24
|
+
ctx.ui.notify(`ultra-compress → ${level}`, "info");
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=uc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uc.js","sourceRoot":"","sources":["../../src/commands/uc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAc,MAAM,UAAU,CAAC;AAGrE,SAAS,OAAO,CAAC,CAAS;IACzB,OAAQ,UAAgC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,eAAe;IAC9B,OAAO;QACN,IAAI,EAAE,IAAI;QACV,WAAW,EACV,mFAAmF;QACpF,sBAAsB,CAAC,MAAc;YACpC,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACxE,KAAK,EAAE,CAAC;gBACR,KAAK,EAAE,CAAC;aACR,CAAC,CAAC,CAAC;YACJ,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QACxC,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG;YACtB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrB,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,iBAAiB,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC7D,OAAO;YACR,CAAC;YACD,MAAM,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;YAChC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;QACpD,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface AgentEndEvent {
|
|
2
|
+
content?: unknown;
|
|
3
|
+
stopReason?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface AgentEndContext {
|
|
6
|
+
cwd: string;
|
|
7
|
+
}
|
|
8
|
+
export type AgentEndHook = (event: AgentEndEvent, ctx: AgentEndContext) => Promise<void>;
|
|
9
|
+
export declare function createAgentEndHook(): AgentEndHook;
|
|
10
|
+
//# sourceMappingURL=agent-end.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-end.d.ts","sourceRoot":"","sources":["../../src/hooks/agent-end.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC/B,GAAG,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAyBzF,wBAAgB,kBAAkB,IAAI,YAAY,CAWjD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { addCharsSaved, loadState } from "../services/state-store";
|
|
2
|
+
import { estimateCharsSaved } from "../services/stats";
|
|
3
|
+
// Best-effort extraction of a text length from a PI agent_end event. PI's
|
|
4
|
+
// actual event shape is runtime-dependent; we accept either a string `content`
|
|
5
|
+
// or an array of `{ type: "text", text: string }` parts (the pi-ai shape).
|
|
6
|
+
// Returns 0 when nothing extractable is present — never throws.
|
|
7
|
+
function extractContentLength(content) {
|
|
8
|
+
if (typeof content === "string")
|
|
9
|
+
return content.length;
|
|
10
|
+
if (Array.isArray(content)) {
|
|
11
|
+
let total = 0;
|
|
12
|
+
for (const part of content) {
|
|
13
|
+
if (part &&
|
|
14
|
+
typeof part === "object" &&
|
|
15
|
+
part.type === "text" &&
|
|
16
|
+
typeof part.text === "string") {
|
|
17
|
+
total += part.text.length;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return total;
|
|
21
|
+
}
|
|
22
|
+
return 0;
|
|
23
|
+
}
|
|
24
|
+
export function createAgentEndHook() {
|
|
25
|
+
return async function onAgentEnd(event, ctx) {
|
|
26
|
+
const state = await loadState(ctx.cwd);
|
|
27
|
+
if (state.level === "off")
|
|
28
|
+
return;
|
|
29
|
+
const chars = extractContentLength(event.content);
|
|
30
|
+
if (chars === 0)
|
|
31
|
+
return;
|
|
32
|
+
const saved = estimateCharsSaved(chars, state.level);
|
|
33
|
+
if (saved > 0) {
|
|
34
|
+
await addCharsSaved(saved, ctx.cwd);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=agent-end.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-end.js","sourceRoot":"","sources":["../../src/hooks/agent-end.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAavD,0EAA0E;AAC1E,+EAA+E;AAC/E,2EAA2E;AAC3E,gEAAgE;AAChE,SAAS,oBAAoB,CAAC,OAAgB;IAC7C,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,MAAM,CAAC;IACvD,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC5B,IACC,IAAI;gBACJ,OAAO,IAAI,KAAK,QAAQ;gBACvB,IAA2B,CAAC,IAAI,KAAK,MAAM;gBAC5C,OAAQ,IAA2B,CAAC,IAAI,KAAK,QAAQ,EACpD,CAAC;gBACF,KAAK,IAAK,IAAyB,CAAC,IAAI,CAAC,MAAM,CAAC;YACjD,CAAC;QACF,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,CAAC,CAAC;AACV,CAAC;AAED,MAAM,UAAU,kBAAkB;IACjC,OAAO,KAAK,UAAU,UAAU,CAAC,KAAK,EAAE,GAAG;QAC1C,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK;YAAE,OAAO;QAClC,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO;QACxB,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACf,MAAM,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,CAAC;IACF,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface BeforeAgentStartEvent {
|
|
2
|
+
prompt: string;
|
|
3
|
+
systemPrompt: string;
|
|
4
|
+
}
|
|
5
|
+
export interface BeforeAgentStartContext {
|
|
6
|
+
cwd: string;
|
|
7
|
+
}
|
|
8
|
+
export interface BeforeAgentStartResult {
|
|
9
|
+
systemPrompt: string;
|
|
10
|
+
}
|
|
11
|
+
export type BeforeAgentStartHook = (event: BeforeAgentStartEvent, ctx: BeforeAgentStartContext) => Promise<BeforeAgentStartResult | undefined>;
|
|
12
|
+
export declare function createBeforeAgentStartHook(): BeforeAgentStartHook;
|
|
13
|
+
//# sourceMappingURL=before-agent-start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"before-agent-start.d.ts","sourceRoot":"","sources":["../../src/hooks/before-agent-start.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACvC,GAAG,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,sBAAsB;IACtC,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,oBAAoB,GAAG,CAClC,KAAK,EAAE,qBAAqB,EAC5B,GAAG,EAAE,uBAAuB,KACxB,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC,CAAC;AAEjD,wBAAgB,0BAA0B,IAAI,oBAAoB,CAOjE"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { loadState } from "../services/state-store";
|
|
2
|
+
export function createBeforeAgentStartHook() {
|
|
3
|
+
return async function onBeforeAgentStart(event, ctx) {
|
|
4
|
+
const state = await loadState(ctx.cwd);
|
|
5
|
+
if (state.level === "off")
|
|
6
|
+
return undefined;
|
|
7
|
+
const marker = `\n\n[ultra-compress: LEVEL=${state.level}. Apply §${state.level} rules from ultra-compress skill. Auto-Clarity: fall back to prose for destructive/security/ordered turns.]`;
|
|
8
|
+
return { systemPrompt: event.systemPrompt + marker };
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=before-agent-start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"before-agent-start.js","sourceRoot":"","sources":["../../src/hooks/before-agent-start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAoBpD,MAAM,UAAU,0BAA0B;IACzC,OAAO,KAAK,UAAU,kBAAkB,CAAC,KAAK,EAAE,GAAG;QAClD,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK;YAAE,OAAO,SAAS,CAAC;QAC5C,MAAM,MAAM,GAAG,8BAA8B,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,KAAK,6GAA6G,CAAC;QAC7L,OAAO,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,GAAG,MAAM,EAAE,CAAC;IACtD,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { createSessionStartHook } from "./session-start";
|
|
2
|
+
export type { SessionStartEvent, SessionStartContext, NotifyFn, SessionStartHook, } from "./session-start";
|
|
3
|
+
export { createBeforeAgentStartHook } from "./before-agent-start";
|
|
4
|
+
export type { BeforeAgentStartEvent, BeforeAgentStartContext, BeforeAgentStartResult, BeforeAgentStartHook, } from "./before-agent-start";
|
|
5
|
+
export { createAgentEndHook } from "./agent-end";
|
|
6
|
+
export type { AgentEndEvent, AgentEndContext, AgentEndHook } from "./agent-end";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,YAAY,EACX,iBAAiB,EACjB,mBAAmB,EACnB,QAAQ,EACR,gBAAgB,GAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,YAAY,EACX,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,oBAAoB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAOzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAOlE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface SessionStartEvent {
|
|
2
|
+
reason: "startup" | "reload" | "new" | "resume" | "fork";
|
|
3
|
+
}
|
|
4
|
+
export interface SessionStartContext {
|
|
5
|
+
cwd: string;
|
|
6
|
+
}
|
|
7
|
+
export type NotifyFn = (message: string, level?: "info" | "warning" | "error") => void;
|
|
8
|
+
export interface SessionStartDeps {
|
|
9
|
+
notify: NotifyFn;
|
|
10
|
+
}
|
|
11
|
+
export type SessionStartHook = (event: SessionStartEvent, ctx: SessionStartContext) => Promise<void>;
|
|
12
|
+
export declare function createSessionStartHook(deps: SessionStartDeps): SessionStartHook;
|
|
13
|
+
//# sourceMappingURL=session-start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-start.d.ts","sourceRoot":"","sources":["../../src/hooks/session-start.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CACzD;AAED,MAAM,WAAW,mBAAmB;IACnC,GAAG,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,KAAK,IAAI,CAAC;AAEvF,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,QAAQ,CAAC;CACjB;AAED,MAAM,MAAM,gBAAgB,GAAG,CAC9B,KAAK,EAAE,iBAAiB,EACxB,GAAG,EAAE,mBAAmB,KACpB,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB,GAAG,gBAAgB,CAQ/E"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { loadState, resetSessionStats } from "../services/state-store";
|
|
2
|
+
export function createSessionStartHook(deps) {
|
|
3
|
+
return async function onSessionStart(_event, ctx) {
|
|
4
|
+
const before = await loadState(ctx.cwd);
|
|
5
|
+
await resetSessionStats(ctx.cwd);
|
|
6
|
+
if (before.level !== "off") {
|
|
7
|
+
deps.notify(`ultra-compress: ${before.level} (per-project)`, "info");
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=session-start.js.map
|