@prom.codes/saver 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -2
- package/dist/bin.js +30 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,7 +26,13 @@ and **prom.codes Memory** (agent memory).
|
|
|
26
26
|
|
|
27
27
|
Then ask your agent to run `setup` once per workspace. Levels: `lite` (filler
|
|
28
28
|
only), `balanced` (default — lean, not terse), `aggressive` (telegraphic, opt-in,
|
|
29
|
-
never for code/destructive work).
|
|
30
|
-
|
|
29
|
+
never for code/destructive work). The rules keep code, caveats, destructive steps
|
|
30
|
+
and anything the agent needs later **verbatim** — it shapes phrasing, never what the
|
|
31
|
+
agent does or remembers.
|
|
32
|
+
|
|
33
|
+
No database and no native modules — `npx` works turnkey everywhere (Node ≥ 20.10).
|
|
34
|
+
An API key is **optional**: Saver works fully without one, and accepts the same
|
|
35
|
+
`PROMETHEUS_API_KEY` (`prom_live_…`) as prom.codes Context and Memory to tie the
|
|
36
|
+
install to your account.
|
|
31
37
|
|
|
32
38
|
Docs: https://prom.codes/docs
|
package/dist/bin.js
CHANGED
|
@@ -4,6 +4,16 @@
|
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
5
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
6
|
|
|
7
|
+
// dist/key.js
|
|
8
|
+
var KEY_PATTERN = /^prom_(live|test)_[A-Za-z0-9]{10,}$/;
|
|
9
|
+
var API_KEY_ENV = "PROMETHEUS_API_KEY";
|
|
10
|
+
function classifyKey(raw) {
|
|
11
|
+
const key = raw?.trim();
|
|
12
|
+
if (!key)
|
|
13
|
+
return "absent";
|
|
14
|
+
return KEY_PATTERN.test(key) ? "valid" : "malformed";
|
|
15
|
+
}
|
|
16
|
+
|
|
7
17
|
// dist/server.js
|
|
8
18
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
9
19
|
|
|
@@ -24,25 +34,26 @@ var SAVER_RUNTIMES = [
|
|
|
24
34
|
];
|
|
25
35
|
var BLOCK_START = "<!-- prom-saver:start -->";
|
|
26
36
|
var BLOCK_END = "<!-- prom-saver:end -->";
|
|
27
|
-
var NEVER_COMPRESS = `**Never
|
|
37
|
+
var NEVER_COMPRESS = `**Never cut substance (all levels) \u2014 these are never "filler":**
|
|
28
38
|
- Code, diffs, commit messages, CLI commands, API names, file paths and exact error strings \u2014 verbatim.
|
|
29
|
-
- Load-bearing caveats, trade-offs, warnings
|
|
30
|
-
- Destructive, irreversible or multi-step sequences \u2014 spell those out in full
|
|
39
|
+
- Load-bearing caveats, trade-offs, warnings, negations ("not"/"only"/"unless"/"before"), and \u2014 for risky or destructive work \u2014 safer alternatives, precautions, dependency/foreign-key checks and backup/rollback advice. If it changes correctness or safety, keep it.
|
|
40
|
+
- Destructive, irreversible or multi-step sequences \u2014 spell those out in full, including every step the task needs to actually work (e.g. a "without downtime" procedure keeps the dual-running / grace-period steps).
|
|
41
|
+
- **Anything you will need on a later turn \u2014 your own working context.** What you write IS your memory of this turn; condensing a recap is never a reason to drop a file path, value, decision, finding or error you may act on again. When unsure whether a detail matters later, keep it.`;
|
|
31
42
|
var LEVEL_BODY = {
|
|
32
|
-
lite: `
|
|
33
|
-
balanced: `Lead with the answer or the action
|
|
34
|
-
aggressive: `Telegraphic prose: drop articles and filler, minimal hedging, the shortest wording
|
|
43
|
+
lite: `Drop ceremony and filler from your prose: no greetings, apologies, sign-offs, restating the question, or "I will now\u2026" preamble. Otherwise write normally.`,
|
|
44
|
+
balanced: `Lead with the answer or the action; cut preamble, sign-offs and play-by-play self-narration. Don't restate the question or pad. When several examples would be near-duplicates, give one. When recapping long tool or command output, keep the lines that carry meaning (failures, errors, the decision) and drop the noise. But include every step, caveat and precaution the answer needs to be correct and safe \u2014 if removing something would let a competent reviewer call the answer wrong, incomplete or unsafe, it stays. Lean, not terse: shorter because there is less filler, never because there is less help.`,
|
|
45
|
+
aggressive: `Telegraphic prose: drop articles and filler, minimal hedging, the shortest unambiguous wording; recap tool output as the load-bearing lines only. Opt-in \u2014 more savings, more risk: the carve-outs below are hard limits, and you MUST fall back to "balanced" for any code-generation, debugging or destructive/irreversible work, where losing a single detail is costly.`
|
|
35
46
|
};
|
|
36
47
|
function ruleBlockFor(level) {
|
|
37
48
|
return `## prom.codes Saver \u2014 efficient output (level: ${level})
|
|
38
49
|
|
|
39
|
-
Cut token cost
|
|
50
|
+
Cut token cost by writing less FILLER \u2014 without cutting quality or losing context. This shapes ONLY how you PHRASE your own messages: never code, commands, tool inputs, what you do, or what you need to remember. Trim ceremony, restating, padding and redundant examples; keep all substance.
|
|
40
51
|
|
|
41
52
|
${LEVEL_BODY[level]}
|
|
42
53
|
|
|
43
54
|
${NEVER_COMPRESS}
|
|
44
55
|
|
|
45
|
-
|
|
56
|
+
Correctness, safety, completeness and your own working context come FIRST; saving tokens comes second. If the two ever conflict, do not compress \u2014 cut filler, never substance.`;
|
|
46
57
|
}
|
|
47
58
|
function withMarkers(block) {
|
|
48
59
|
return `${BLOCK_START}
|
|
@@ -111,7 +122,7 @@ var setupInput = {
|
|
|
111
122
|
runtimes: z.array(runtimeEnum).min(1).optional()
|
|
112
123
|
};
|
|
113
124
|
function registerTools(server, deps) {
|
|
114
|
-
const { workspaceRoot } = deps;
|
|
125
|
+
const { workspaceRoot, apiKey } = deps;
|
|
115
126
|
server.registerTool("setup", {
|
|
116
127
|
title: "Install the prom.codes Saver efficient-output rules",
|
|
117
128
|
description: "Idempotently install the prom.codes Saver efficient-output rule block into this workspace's agent runtime configs (CLAUDE.md / .cursor/rules / .augment/rules / AGENTS.md). The rules cut token cost by trimming the agent's own prose (preamble, narration, pasted tool output) while keeping code, caveats and destructive sequences verbatim. `level`: `lite` (filler only) | `balanced` (default \u2014 lean, not terse) | `aggressive` (telegraphic, opt-in, never for code/destructive). Without `runtimes` it auto-detects which are present (fallback: agents). Re-running updates the block in place. Run this once per workspace.",
|
|
@@ -123,7 +134,7 @@ function registerTools(server, deps) {
|
|
|
123
134
|
for (const runtime of runtimes) {
|
|
124
135
|
results.push(await installRuntime(workspaceRoot, runtime, level));
|
|
125
136
|
}
|
|
126
|
-
return textResult({ workspaceRoot, level, results });
|
|
137
|
+
return textResult({ workspaceRoot, level, keyed: apiKey !== void 0, results });
|
|
127
138
|
});
|
|
128
139
|
}
|
|
129
140
|
|
|
@@ -148,9 +159,16 @@ function createServer(deps, options = {}) {
|
|
|
148
159
|
// dist/bin.js
|
|
149
160
|
async function main() {
|
|
150
161
|
const workspaceRoot = resolve(process.env.PROMETHEUS_WORKSPACE_ROOT ?? process.cwd());
|
|
151
|
-
process.
|
|
162
|
+
const rawKey = process.env[API_KEY_ENV];
|
|
163
|
+
const keyState = classifyKey(rawKey);
|
|
164
|
+
if (keyState === "malformed") {
|
|
165
|
+
process.stderr.write(`prom-codes-saver: ${API_KEY_ENV} is malformed (expected prom_live_\u2026 / prom_test_\u2026); continuing keyless.
|
|
166
|
+
`);
|
|
167
|
+
}
|
|
168
|
+
const apiKey = keyState === "valid" ? rawKey.trim() : void 0;
|
|
169
|
+
process.stderr.write(`prom-codes-saver: workspace=${workspaceRoot} key=${keyState}
|
|
152
170
|
`);
|
|
153
|
-
const server = createServer({ workspaceRoot });
|
|
171
|
+
const server = createServer({ workspaceRoot, ...apiKey !== void 0 ? { apiKey } : {} });
|
|
154
172
|
const transport = new StdioServerTransport();
|
|
155
173
|
const shutdown = async (signal) => {
|
|
156
174
|
process.stderr.write(`prom-codes-saver: received ${signal}, shutting down
|