@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.
- package/README.md +14 -17
- package/dist/bin.js +52 -9
- 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
|
-
```
|
|
15
|
-
|
|
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
|
-
|
|
35
|
-
`
|
|
36
|
-
|
|
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]{
|
|
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/
|
|
18
|
-
import {
|
|
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({
|
|
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 =
|
|
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({
|
|
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
|