@prom.codes/saver 0.1.0 → 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 (3) hide show
  1. package/README.md +8 -2
  2. package/dist/bin.js +27 -9
  3. 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). No API key, no database, no native modules —
30
- `npx` works turnkey everywhere. Requires Node 20.10.
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
 
@@ -27,22 +37,23 @@ var BLOCK_END = "<!-- prom-saver:end -->";
27
37
  var NEVER_COMPRESS = `**Never compress (all levels):**
28
38
  - Code, diffs, commit messages, CLI commands, API names, file paths and exact error strings \u2014 verbatim.
29
39
  - Load-bearing caveats, trade-offs, warnings and negations ("not", "only", "unless", "before"). If it changes correctness or safety, keep it.
30
- - Destructive, irreversible or multi-step sequences \u2014 spell those out in full.`;
40
+ - Destructive, irreversible or multi-step sequences \u2014 spell those out in full.
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 for the reader 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. This is the rule that prevents context loss \u2014 it overrides any urge to be brief.`;
31
42
  var LEVEL_BODY = {
32
43
  lite: `Trim only ceremony and filler from your own prose: skip greetings, apologies, restating the question, and "I will now\u2026" preamble. Otherwise write normally.`,
33
- balanced: `Lead with the answer or the action. Skip preamble and the play-by-play narration of routine tool calls \u2014 act, then give a short result. Summarize long tool/command output instead of pasting it verbatim; quote only the lines that matter. Close a task with one concise summary, not running commentary. Keep substance over brevity \u2014 when in doubt, say the necessary thing. This is "lean", not "terse".`,
34
- aggressive: `Telegraphic prose: drop articles and filler, minimal hedging, the shortest wording that stays unambiguous; summarize all tool output to the essential lines. 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 or destructive/irreversible work.`
44
+ balanced: `Lead with the answer or the action. Skip preamble and the play-by-play narration of routine tool calls \u2014 act, then give a short result. When you recap a long tool or command output for the reader, quote the lines that matter rather than pasting all of it \u2014 but keep every detail you might act on later. Close a task with one concise summary, not running commentary. Substance over brevity \u2014 when in doubt, say the necessary thing. This is "lean", not "terse".`,
45
+ aggressive: `Telegraphic prose: drop articles and filler, minimal hedging, the shortest wording that stays unambiguous; recap tool output as the essential 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 WITHOUT cutting quality. This shapes ONLY your own assistant prose \u2014 it never changes code, commands, tool inputs, or what you actually do.
50
+ Cut token cost WITHOUT cutting quality or losing context. This shapes ONLY how you PHRASE your own assistant messages \u2014 it never changes code, commands, tool inputs, what you do, or what you need to remember.
40
51
 
41
52
  ${LEVEL_BODY[level]}
42
53
 
43
54
  ${NEVER_COMPRESS}
44
55
 
45
- The user asked for fewer wasted tokens, not a worse answer: preserve correctness, safety and completeness first, save tokens second.`;
56
+ Correctness, safety, completeness and your own working context come FIRST; saving tokens comes second. If the two ever conflict, do not compress.`;
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.stderr.write(`prom-codes-saver: workspace=${workspaceRoot}
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prom.codes/saver",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "prom.codes Saver — cut token cost without cutting quality, as an MCP installer.",
5
5
  "type": "module",
6
6
  "bin": {