@prom.codes/saver 0.1.2 → 0.1.4

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 +14 -17
  2. package/dist/bin.js +52 -9
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -9,21 +9,16 @@ caveats and destructive sequences **verbatim**.
9
9
  It is the third prom.codes tool, alongside **prom.codes Context** (code retrieval)
10
10
  and **prom.codes Memory** (agent memory).
11
11
 
12
- ## Quick start
13
-
14
- ```jsonc
15
- // Claude Desktop / Cursor MCP config
16
- {
17
- "mcpServers": {
18
- "saver": {
19
- "command": "npx",
20
- "args": ["-y", "@prom.codes/saver@latest"],
21
- "env": { "PROMETHEUS_WORKSPACE_ROOT": "/absolute/path/to/your/repo" }
22
- }
23
- }
24
- }
12
+ ## Quick start (Claude Code)
13
+
14
+ ```bash
15
+ claude mcp add saver -- npx -y @prom.codes/saver@latest
25
16
  ```
26
17
 
18
+ No key needed. `claude mcp add` defaults to local scope; add `--scope project`
19
+ for a committable `.mcp.json`. Other hosts (Cursor, VS Code) use the same
20
+ command/args in their own config.
21
+
27
22
  Then ask your agent to run `setup` once per workspace. Levels: `lite` (filler
28
23
  only), `balanced` (default — lean, not terse), `aggressive` (telegraphic, opt-in,
29
24
  never for code/destructive work). The rules keep code, caveats, destructive steps
@@ -31,8 +26,10 @@ and anything the agent needs later **verbatim** — it shapes phrasing, never wh
31
26
  agent does or remembers.
32
27
 
33
28
  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.
29
+ The workspace is auto-detected (Claude Code `CLAUDE_PROJECT_DIR`); set
30
+ `PROMETHEUS_WORKSPACE_ROOT` only to target a different folder. An API key is
31
+ **optional**: the Saver works fully without one, and accepts the same
32
+ `PROMETHEUS_API_KEY` (`prom_live_<tag>_<secret>`) as prom.codes Context and
33
+ Memory to tie the install to your account.
37
34
 
38
- Docs: https://prom.codes/docs
35
+ Docs: https://prom.codes/docs/mcp/saver
package/dist/bin.js CHANGED
@@ -1,11 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // dist/bin.js
4
- import { resolve } from "node:path";
5
4
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
5
 
7
6
  // dist/key.js
8
- var KEY_PATTERN = /^prom_(live|test)_[A-Za-z0-9]{10,}$/;
7
+ var KEY_PATTERN = /^prom_(live|test)_[A-Za-z0-9]{6,}(?:_[A-Za-z0-9]{6,})?$/;
9
8
  var API_KEY_ENV = "PROMETHEUS_API_KEY";
10
9
  function classifyKey(raw) {
11
10
  const key = raw?.trim();
@@ -14,8 +13,17 @@ function classifyKey(raw) {
14
13
  return KEY_PATTERN.test(key) ? "valid" : "malformed";
15
14
  }
16
15
 
17
- // dist/server.js
18
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
16
+ // dist/workspace.js
17
+ import { resolve } from "node:path";
18
+ function resolveWorkspaceRoot(env = process.env) {
19
+ const explicit = (env.PROMETHEUS_WORKSPACE_ROOT ?? "").trim();
20
+ if (explicit !== "")
21
+ return resolve(explicit);
22
+ const claude = (env.CLAUDE_PROJECT_DIR ?? "").trim();
23
+ if (claude !== "")
24
+ return resolve(claude);
25
+ return resolve(process.cwd());
26
+ }
19
27
 
20
28
  // dist/tools.js
21
29
  import { z } from "zod";
@@ -112,6 +120,7 @@ async function installRuntime(workspaceRoot, runtime, level) {
112
120
  }
113
121
 
114
122
  // dist/tools.js
123
+ var REQUIRE_KEY_ENV = "PROMETHEUS_SAVER_REQUIRE_KEY";
115
124
  function textResult(payload) {
116
125
  return { content: [{ type: "text", text: JSON.stringify(payload, null, 2) }] };
117
126
  }
@@ -122,23 +131,47 @@ var setupInput = {
122
131
  runtimes: z.array(runtimeEnum).min(1).optional()
123
132
  };
124
133
  function registerTools(server, deps) {
125
- const { workspaceRoot, apiKey } = deps;
134
+ const { workspaceRoot, apiKey, requireKey } = deps;
135
+ const keyState = deps.keyState ?? (apiKey !== void 0 ? "valid" : "absent");
126
136
  server.registerTool("setup", {
127
137
  title: "Install the prom.codes Saver efficient-output rules",
128
138
  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.",
129
139
  inputSchema: setupInput
130
140
  }, async (args) => {
141
+ if (requireKey === true && keyState !== "valid") {
142
+ return {
143
+ isError: true,
144
+ content: [
145
+ {
146
+ type: "text",
147
+ text: JSON.stringify({
148
+ ok: false,
149
+ installed: false,
150
+ keyState,
151
+ error: `prom.codes Saver: a valid ${API_KEY_ENV} (prom_live_\u2026 / prom_test_\u2026) is required to install because ${REQUIRE_KEY_ENV} is enabled (key is "${keyState}"). Set the key in this server's env block, or unset ${REQUIRE_KEY_ENV} to install keyless.`
152
+ }, null, 2)
153
+ }
154
+ ]
155
+ };
156
+ }
131
157
  const level = args.level ?? DEFAULT_LEVEL;
132
158
  const runtimes = args.runtimes ?? detectRuntimes(workspaceRoot);
133
159
  const results = [];
134
160
  for (const runtime of runtimes) {
135
161
  results.push(await installRuntime(workspaceRoot, runtime, level));
136
162
  }
137
- return textResult({ workspaceRoot, level, keyed: apiKey !== void 0, results });
163
+ return textResult({
164
+ workspaceRoot,
165
+ level,
166
+ keyed: apiKey !== void 0,
167
+ keyState,
168
+ results
169
+ });
138
170
  });
139
171
  }
140
172
 
141
173
  // dist/server.js
174
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
142
175
  var SERVER_IDENTITY = {
143
176
  name: "prom-codes-saver",
144
177
  version: "0.1.0",
@@ -158,17 +191,27 @@ function createServer(deps, options = {}) {
158
191
 
159
192
  // dist/bin.js
160
193
  async function main() {
161
- const workspaceRoot = resolve(process.env.PROMETHEUS_WORKSPACE_ROOT ?? process.cwd());
194
+ const workspaceRoot = resolveWorkspaceRoot(process.env);
162
195
  const rawKey = process.env[API_KEY_ENV];
163
196
  const keyState = classifyKey(rawKey);
197
+ const requireKey = /^(1|true|yes|on)$/i.test(process.env[REQUIRE_KEY_ENV] ?? "");
164
198
  if (keyState === "malformed") {
165
199
  process.stderr.write(`prom-codes-saver: ${API_KEY_ENV} is malformed (expected prom_live_\u2026 / prom_test_\u2026); continuing keyless.
200
+ `);
201
+ }
202
+ if (requireKey && keyState !== "valid") {
203
+ process.stderr.write(`prom-codes-saver: ${REQUIRE_KEY_ENV} is on but ${API_KEY_ENV} is ${keyState}; setup will refuse to install until a valid prom_ key is provided.
166
204
  `);
167
205
  }
168
206
  const apiKey = keyState === "valid" ? rawKey.trim() : void 0;
169
- process.stderr.write(`prom-codes-saver: workspace=${workspaceRoot} key=${keyState}
207
+ process.stderr.write(`prom-codes-saver: workspace=${workspaceRoot} key=${keyState} requireKey=${requireKey}
170
208
  `);
171
- const server = createServer({ workspaceRoot, ...apiKey !== void 0 ? { apiKey } : {} });
209
+ const server = createServer({
210
+ workspaceRoot,
211
+ keyState,
212
+ requireKey,
213
+ ...apiKey !== void 0 ? { apiKey } : {}
214
+ });
172
215
  const transport = new StdioServerTransport();
173
216
  const shutdown = async (signal) => {
174
217
  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.2",
3
+ "version": "0.1.4",
4
4
  "description": "prom.codes Saver — cut token cost without cutting quality, as an MCP installer.",
5
5
  "type": "module",
6
6
  "bin": {