@mnemom/mnemom 0.7.1 → 0.8.0
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 +35 -31
- package/dist/commands/agents.d.ts +0 -14
- package/dist/commands/agents.js +35 -295
- package/dist/commands/auth.js +2 -7
- package/dist/commands/card.d.ts +21 -8
- package/dist/commands/card.js +328 -275
- package/dist/commands/integrity.js +6 -6
- package/dist/commands/license.js +14 -29
- package/dist/commands/logs.js +8 -8
- package/dist/commands/policy.d.ts +10 -23
- package/dist/commands/policy.js +20 -533
- package/dist/commands/protection.d.ts +14 -0
- package/dist/commands/protection.js +308 -0
- package/dist/commands/status.js +42 -50
- package/dist/index.js +114 -160
- package/dist/lib/api.d.ts +41 -0
- package/dist/lib/api.js +131 -1
- package/dist/lib/auth.d.ts +30 -21
- package/dist/lib/auth.js +95 -49
- package/dist/lib/config.d.ts +11 -98
- package/dist/lib/config.js +12 -220
- package/dist/lib/model-cache.js +5 -6
- package/dist/smoltbot-shim.js +1 -1
- package/package.json +2 -2
- package/dist/commands/init.d.ts +0 -7
- package/dist/commands/init.js +0 -763
- package/dist/commands/migrate-config.d.ts +0 -2
- package/dist/commands/migrate-config.js +0 -72
- package/dist/commands/register.d.ts +0 -6
- package/dist/commands/register.js +0 -362
package/README.md
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Mnemom CLI
|
|
2
2
|
|
|
3
|
-
[](https://github.com/mnemom/mnemom-platform/actions/workflows/ci.yml)
|
|
4
|
+
[](https://github.com/mnemom/mnemom-platform/actions/workflows/codeql.yml)
|
|
5
|
+
[](https://www.npmjs.com/package/@mnemom/mnemom)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
[](https://github.com/mnemom/aap)
|
|
8
8
|
[](https://github.com/mnemom/aip)
|
|
9
9
|
|
|
10
10
|
Transparent AI agent tracing. [AAP](https://github.com/mnemom/aap)-compliant.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Mnemom observes your AI agent's API calls and builds verifiable alignment traces — what decisions were made, what alternatives were considered, and whether behavior matches declared values. Your prompts and responses are never stored.
|
|
13
13
|
|
|
14
14
|
## Documentation
|
|
15
15
|
|
|
16
|
-
Full documentation is at **[docs.mnemom.ai
|
|
16
|
+
Full documentation is at **[docs.mnemom.ai](https://docs.mnemom.ai)**.
|
|
17
17
|
|
|
18
18
|
## Quick Start
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
npm install -g
|
|
22
|
-
|
|
21
|
+
npm install -g @mnemom/mnemom
|
|
22
|
+
mnemom init
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
That's it. `
|
|
25
|
+
That's it. `mnemom init` detects your configured AI provider API keys (Anthropic, OpenAI, Gemini) and configures your local environment to route API calls through the Mnemom gateway, where they're traced and verified. Your API keys never leave your machine — only SHA-256 hashes are used for agent identification.
|
|
26
26
|
|
|
27
27
|
## Supported Providers
|
|
28
28
|
|
|
@@ -36,28 +36,28 @@ That's it. `smoltbot init` detects your configured AI provider API keys (Anthrop
|
|
|
36
36
|
|
|
37
37
|
| Command | Description |
|
|
38
38
|
|---------|-------------|
|
|
39
|
-
| `
|
|
40
|
-
| `
|
|
41
|
-
| `
|
|
42
|
-
| `
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
39
|
+
| `mnemom init` | Configure tracing for your AI agent (multi-provider) |
|
|
40
|
+
| `mnemom status` | Show agent status, providers, and connection info |
|
|
41
|
+
| `mnemom integrity` | Display integrity score and verification stats |
|
|
42
|
+
| `mnemom logs [-l N]` | Show recent traces and actions |
|
|
43
|
+
| `mnemom card show` | Display active alignment card |
|
|
44
|
+
| `mnemom card publish <file>` | Publish alignment card from JSON file |
|
|
45
|
+
| `mnemom card validate <file>` | Validate card JSON locally |
|
|
46
46
|
|
|
47
47
|
## How It Works
|
|
48
48
|
|
|
49
49
|
```
|
|
50
|
-
|
|
51
|
-
Your App →
|
|
52
|
-
gateway
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
50
|
+
┌─── /anthropic/* ──→ Anthropic (Claude)
|
|
51
|
+
Your App → mnemom ├─── /openai/* ──→ OpenAI (GPT-5)
|
|
52
|
+
gateway └─── /gemini/* ──→ Google (Gemini)
|
|
53
|
+
↓
|
|
54
|
+
CF AI Gateway
|
|
55
|
+
↓
|
|
56
|
+
Observer Worker
|
|
57
|
+
↓
|
|
58
|
+
AP-Trace + Verify → Supabase
|
|
59
|
+
↓
|
|
60
|
+
Dashboard (mnemom.ai)
|
|
61
61
|
```
|
|
62
62
|
|
|
63
63
|
1. **Gateway** — A Cloudflare Worker that intercepts API requests to Anthropic, OpenAI, and Gemini. It identifies your agent via API key hash (zero-config), attaches tracing metadata, injects thinking/reasoning per provider, performs real-time integrity checking, injects conscience nudges, and delivers webhooks. Your prompts and responses pass through unchanged.
|
|
@@ -66,13 +66,13 @@ Your App → smoltbot ├─── /openai/* ──→ OpenAI (GPT-5)
|
|
|
66
66
|
|
|
67
67
|
3. **API** — Serves agent data, traces, integrity scores, drift alerts, enforcement status, and a unified conscience timeline. Powers both the CLI and the web dashboard.
|
|
68
68
|
|
|
69
|
-
4. **CLI** — The `
|
|
69
|
+
4. **CLI** — The `mnemom` command. Configures your local environment and queries your agent's transparency data.
|
|
70
70
|
|
|
71
71
|
5. **Dashboard** — Web UI at [mnemom.ai](https://mnemom.ai) where you can view the conscience timeline, claim your agent, and monitor alignment.
|
|
72
72
|
|
|
73
73
|
## What Gets Traced
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
Mnemom builds [AP-Traces](https://github.com/mnemom/aap) that record:
|
|
76
76
|
|
|
77
77
|
- **Action** — What the agent did (type, name, category)
|
|
78
78
|
- **Decision** — What alternatives were considered and why one was selected
|
|
@@ -109,13 +109,17 @@ Enforcement works across all providers where AIP is supported.
|
|
|
109
109
|
|
|
110
110
|
## Dependencies
|
|
111
111
|
|
|
112
|
-
- [Agent Alignment Protocol (AAP)](https://github.com/mnemom/aap) — `@mnemom/agent-alignment-protocol@0.
|
|
113
|
-
- [Agent Integrity Protocol (AIP)](https://github.com/mnemom/aip) — `@mnemom/agent-integrity-protocol@0.
|
|
112
|
+
- [Agent Alignment Protocol (AAP)](https://github.com/mnemom/aap) — `@mnemom/agent-alignment-protocol@1.0.0` on npm
|
|
113
|
+
- [Agent Integrity Protocol (AIP)](https://github.com/mnemom/aip) — `@mnemom/agent-integrity-protocol@1.0.0` on npm
|
|
114
114
|
- [Cloudflare Workers](https://workers.cloudflare.com/) — Gateway, observer, and API hosting
|
|
115
115
|
- [Cloudflare AI Gateway](https://developers.cloudflare.com/ai-gateway/) — Request logging and analytics
|
|
116
116
|
- [Supabase](https://supabase.com/) — Postgres database with row-level security
|
|
117
117
|
- API keys: Anthropic (required for AIP analysis), OpenAI and Gemini (optional, for multi-provider tracing)
|
|
118
118
|
|
|
119
|
+
## Supply Chain
|
|
120
|
+
|
|
121
|
+
All `@mnemom/*` packages are published with [SLSA build provenance](https://docs.mnemom.ai/guides/supply-chain-trust). Verify with `npm audit signatures`.
|
|
122
|
+
|
|
119
123
|
## License
|
|
120
124
|
|
|
121
125
|
[Apache-2.0](LICENSE)
|
|
@@ -1,15 +1 @@
|
|
|
1
1
|
export declare function agentsListCommand(): Promise<void>;
|
|
2
|
-
export declare function agentsDefaultCommand(name: string): Promise<void>;
|
|
3
|
-
/**
|
|
4
|
-
* smoltbot agents add <name-or-id> [--alias <alias>]
|
|
5
|
-
* Register an existing API agent in the local config.
|
|
6
|
-
*/
|
|
7
|
-
export declare function agentsAddCommand(nameOrId: string, alias?: string): Promise<void>;
|
|
8
|
-
export declare function agentsRemoveCommand(name: string): Promise<void>;
|
|
9
|
-
/**
|
|
10
|
-
* smoltbot agents rekey [agent-name]
|
|
11
|
-
* Re-bind a claimed agent to a new provider API key.
|
|
12
|
-
* The raw key is hashed locally (SHA-256) and never transmitted.
|
|
13
|
-
*/
|
|
14
|
-
export declare function agentsRekeyCommand(name?: string): Promise<void>;
|
|
15
|
-
export declare function agentsCheckBindingCommand(name?: string): Promise<void>;
|
package/dist/commands/agents.js
CHANGED
|
@@ -1,303 +1,43 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { listAgents } from "../lib/api.js";
|
|
2
|
+
import { requireAuth } from "../lib/auth.js";
|
|
3
3
|
import { fmt } from "../lib/format.js";
|
|
4
|
-
import { askInput } from "../lib/prompt.js";
|
|
5
4
|
export async function agentsListCommand() {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
console.log("\n" + fmt.error("smoltbot is not initialized") + "\n");
|
|
9
|
-
console.log("Run `smoltbot init` to get started.\n");
|
|
10
|
-
process.exit(1);
|
|
11
|
-
}
|
|
12
|
-
console.log(fmt.header("Registered Agents"));
|
|
13
|
-
console.log();
|
|
14
|
-
// Build reverse map: agentId → local alias name
|
|
15
|
-
const localAliases = new Map();
|
|
16
|
-
for (const [name, agent] of Object.entries(config.agents)) {
|
|
17
|
-
localAliases.set(agent.agentId, name);
|
|
18
|
-
}
|
|
19
|
-
// Fetch ALL agents from API for the authenticated user
|
|
20
|
-
let apiAgents = [];
|
|
21
|
-
try {
|
|
22
|
-
apiAgents = await listAgents();
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
console.log(fmt.warn("Could not reach API — showing local agents only") + "\n");
|
|
26
|
-
}
|
|
27
|
-
const shown = new Set();
|
|
28
|
-
if (apiAgents.length > 0) {
|
|
29
|
-
for (const agent of apiAgents) {
|
|
30
|
-
shown.add(agent.id);
|
|
31
|
-
const localName = localAliases.get(agent.id);
|
|
32
|
-
const isDefault = localName === config.defaultAgent;
|
|
33
|
-
const displayName = localName ?? agent.name ?? agent.email ?? agent.id;
|
|
34
|
-
const defaultMarker = isDefault ? " (default)" : "";
|
|
35
|
-
console.log(` ${fmt.label(displayName + defaultMarker, "")}`);
|
|
36
|
-
console.log(` ${fmt.label("Agent ID: ", agent.id)}`);
|
|
37
|
-
if (agent.key_prefix) {
|
|
38
|
-
console.log(` ${fmt.label("Key: ", ` ${agent.key_prefix}…`)}`);
|
|
39
|
-
}
|
|
40
|
-
if (localName && localName !== displayName) {
|
|
41
|
-
console.log(` ${fmt.label("Local alias:", " " + localName)}`);
|
|
42
|
-
}
|
|
43
|
-
if (agent.last_seen) {
|
|
44
|
-
console.log(` ${fmt.label("Last seen:", " " + new Date(agent.last_seen).toLocaleDateString())}`);
|
|
45
|
-
}
|
|
46
|
-
if (agent.created_at) {
|
|
47
|
-
console.log(` ${fmt.label("Created: ", new Date(agent.created_at).toLocaleDateString())}`);
|
|
48
|
-
}
|
|
49
|
-
console.log();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
// Show locally-registered agents not in the API response
|
|
53
|
-
for (const [name, agent] of Object.entries(config.agents)) {
|
|
54
|
-
if (!shown.has(agent.agentId)) {
|
|
55
|
-
const isDefault = name === config.defaultAgent;
|
|
56
|
-
const defaultMarker = isDefault ? " (default)" : "";
|
|
57
|
-
const providerInfo = agent.providers?.join(", ") ?? (agent.openclawConfigured ? "openclaw" : "unknown");
|
|
58
|
-
console.log(` ${fmt.label(name + defaultMarker, "")} ${fmt.warn("(local only — not found in account)")}`);
|
|
59
|
-
console.log(` ${fmt.label("Agent ID: ", agent.agentId)}`);
|
|
60
|
-
console.log(` ${fmt.label("Provider: ", providerInfo)}`);
|
|
61
|
-
console.log();
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
const total = apiAgents.length > 0 ? apiAgents.length : Object.keys(config.agents).length;
|
|
65
|
-
console.log(` Total: ${total} agent(s)\n`);
|
|
66
|
-
}
|
|
67
|
-
export async function agentsDefaultCommand(name) {
|
|
68
|
-
const config = loadConfig();
|
|
69
|
-
if (!config) {
|
|
70
|
-
console.log("\n" + fmt.error("smoltbot is not initialized") + "\n");
|
|
71
|
-
process.exit(1);
|
|
72
|
-
}
|
|
73
|
-
if (!config.agents[name]) {
|
|
74
|
-
console.log(fmt.error(`Agent "${name}" is not registered locally.`) + "\n");
|
|
75
|
-
console.log(`Run \`smoltbot agents add ${name}\` to register it first.\n`);
|
|
76
|
-
process.exit(1);
|
|
77
|
-
}
|
|
78
|
-
config.defaultAgent = name;
|
|
79
|
-
saveConfig(config);
|
|
80
|
-
console.log(fmt.success(`Default agent set to "${name}"`) + "\n");
|
|
81
|
-
console.log(fmt.label("Agent ID:", ` ${config.agents[name].agentId}`) + "\n");
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* smoltbot agents add <name-or-id> [--alias <alias>]
|
|
85
|
-
* Register an existing API agent in the local config.
|
|
86
|
-
*/
|
|
87
|
-
export async function agentsAddCommand(nameOrId, alias) {
|
|
88
|
-
const config = loadConfig();
|
|
89
|
-
if (!config) {
|
|
90
|
-
console.log("\n" + fmt.error("smoltbot is not initialized") + "\n");
|
|
91
|
-
console.log("Run `smoltbot init` to get started.\n");
|
|
92
|
-
process.exit(1);
|
|
93
|
-
}
|
|
94
|
-
// Fetch the agent from the API
|
|
95
|
-
let agentId;
|
|
96
|
-
let apiName = null;
|
|
97
|
-
let createdAt;
|
|
98
|
-
try {
|
|
99
|
-
if (/^smolt-[0-9a-f]{8}$/.test(nameOrId)) {
|
|
100
|
-
const a = await getAgent(nameOrId);
|
|
101
|
-
agentId = a.id;
|
|
102
|
-
createdAt = a.created_at;
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
const a = await getAgentByName(nameOrId);
|
|
106
|
-
if (!a) {
|
|
107
|
-
console.log(fmt.error(`Agent not found: ${nameOrId}`) + "\n");
|
|
108
|
-
console.log("Run `smoltbot agents` to see agents in your account.\n");
|
|
109
|
-
process.exit(1);
|
|
110
|
-
}
|
|
111
|
-
agentId = a.id;
|
|
112
|
-
apiName = a.name;
|
|
113
|
-
createdAt = a.created_at;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
catch (err) {
|
|
117
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
118
|
-
console.log("\n" + fmt.error(msg) + "\n");
|
|
119
|
-
process.exit(1);
|
|
120
|
-
}
|
|
121
|
-
const localAlias = alias ?? apiName ?? nameOrId;
|
|
122
|
-
// Check for conflicts
|
|
123
|
-
const existing = config.agents[localAlias];
|
|
124
|
-
if (existing) {
|
|
125
|
-
if (existing.agentId === agentId) {
|
|
126
|
-
console.log(fmt.success(`Agent "${localAlias}" is already registered (${agentId})`) + "\n");
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
console.log(fmt.error(`Alias "${localAlias}" is already in use by agent ${existing.agentId}.`) + "\n");
|
|
130
|
-
console.log(`Use --alias <name> to choose a different local name.\n`);
|
|
131
|
-
process.exit(1);
|
|
132
|
-
}
|
|
133
|
-
config.agents[localAlias] = { agentId, configuredAt: createdAt };
|
|
134
|
-
saveConfig(config);
|
|
135
|
-
console.log(fmt.success(`Agent registered as "${localAlias}"`) + "\n");
|
|
136
|
-
console.log(fmt.label("Agent ID:", ` ${agentId}`) + "\n");
|
|
137
|
-
console.log(`Use --agent ${localAlias} to target this agent.\n`);
|
|
138
|
-
}
|
|
139
|
-
export async function agentsRemoveCommand(name) {
|
|
140
|
-
const config = loadConfig();
|
|
141
|
-
if (!config) {
|
|
142
|
-
console.log("\n" + fmt.error("smoltbot is not initialized") + "\n");
|
|
143
|
-
process.exit(1);
|
|
144
|
-
}
|
|
145
|
-
if (!config.agents[name]) {
|
|
146
|
-
console.log(fmt.error(`Agent "${name}" not found`) + "\n");
|
|
147
|
-
console.log("Available agents: " + Object.keys(config.agents).join(", ") + "\n");
|
|
148
|
-
process.exit(1);
|
|
149
|
-
}
|
|
150
|
-
if (name === "default" && Object.keys(config.agents).length === 1) {
|
|
151
|
-
console.log(fmt.error("Cannot remove the only agent") + "\n");
|
|
152
|
-
console.log("Register another agent first with `smoltbot register <name>`.\n");
|
|
153
|
-
process.exit(1);
|
|
154
|
-
}
|
|
155
|
-
const removedId = config.agents[name].agentId;
|
|
156
|
-
delete config.agents[name];
|
|
157
|
-
// If we removed the default, switch to first remaining agent
|
|
158
|
-
if (config.defaultAgent === name) {
|
|
159
|
-
const remaining = Object.keys(config.agents);
|
|
160
|
-
config.defaultAgent = remaining[0] || "default";
|
|
161
|
-
console.log(fmt.warn(`Default agent switched to "${config.defaultAgent}"`) + "\n");
|
|
162
|
-
}
|
|
163
|
-
saveConfig(config);
|
|
164
|
-
console.log(fmt.success(`Agent "${name}" removed (${removedId})`) + "\n");
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* smoltbot agents rekey [agent-name]
|
|
168
|
-
* Re-bind a claimed agent to a new provider API key.
|
|
169
|
-
* The raw key is hashed locally (SHA-256) and never transmitted.
|
|
170
|
-
*/
|
|
171
|
-
export async function agentsRekeyCommand(name) {
|
|
172
|
-
const config = loadConfig();
|
|
173
|
-
if (!config) {
|
|
174
|
-
console.log("\n" + fmt.error("smoltbot is not initialized") + "\n");
|
|
175
|
-
console.log("Run `smoltbot init` to get started.\n");
|
|
176
|
-
process.exit(1);
|
|
177
|
-
}
|
|
178
|
-
// Resolve which agent to rekey
|
|
179
|
-
const agentName = name ?? config.defaultAgent;
|
|
180
|
-
const agentEntry = config.agents[agentName];
|
|
181
|
-
if (!agentEntry) {
|
|
182
|
-
console.log(fmt.error(`Agent "${agentName}" not found`) + "\n");
|
|
183
|
-
console.log("Available agents: " + Object.keys(config.agents).join(", ") + "\n");
|
|
184
|
-
process.exit(1);
|
|
185
|
-
}
|
|
186
|
-
const { agentId } = agentEntry;
|
|
187
|
-
// Fetch canonical name from API — required for named-agent hash computation
|
|
188
|
-
// (named agents: hash = SHA256(key + '|' + name), unnamed: SHA256(key))
|
|
189
|
-
let agentApiName = null;
|
|
190
|
-
try {
|
|
191
|
-
const agent = await getAgent(agentId);
|
|
192
|
-
agentApiName = agent.name ?? null;
|
|
193
|
-
}
|
|
194
|
-
catch {
|
|
195
|
-
console.log(fmt.warn("Could not fetch agent details from API — proceeding without name confirmation"));
|
|
196
|
-
}
|
|
197
|
-
console.log("\n" + fmt.header("Rekey Agent"));
|
|
198
|
-
console.log();
|
|
199
|
-
console.log(` Agent: ${agentName} (${agentId})`);
|
|
200
|
-
if (agentApiName) {
|
|
201
|
-
console.log(` Name: ${agentApiName}`);
|
|
202
|
-
}
|
|
203
|
-
console.log();
|
|
204
|
-
console.log(fmt.warn("Your new provider key will be hashed locally. The raw key never leaves your machine."));
|
|
5
|
+
await requireAuth();
|
|
6
|
+
console.log(fmt.header("Agents"));
|
|
205
7
|
console.log();
|
|
206
|
-
|
|
207
|
-
let newKey = (process.env.SMOLTBOT_NEW_KEY ?? "").trim();
|
|
208
|
-
if (!newKey) {
|
|
209
|
-
newKey = (await askInput("Enter your new provider API key:", true)).trim();
|
|
210
|
-
}
|
|
211
|
-
if (!newKey) {
|
|
212
|
-
console.log(fmt.error("No key provided") + "\n");
|
|
213
|
-
process.exit(1);
|
|
214
|
-
}
|
|
215
|
-
// Compute hash client-side — raw key never sent to API
|
|
216
|
-
const newKeyHash = computeAgentHash(newKey, agentApiName);
|
|
217
|
-
console.log(" Computing hash and calling API...\n");
|
|
218
|
-
// Call API
|
|
219
|
-
let result;
|
|
8
|
+
let agents;
|
|
220
9
|
try {
|
|
221
|
-
|
|
10
|
+
agents = await listAgents();
|
|
222
11
|
}
|
|
223
12
|
catch (err) {
|
|
224
13
|
const msg = err instanceof Error ? err.message : String(err);
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
console.log(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
process.exit(1);
|
|
255
|
-
}
|
|
256
|
-
const agentName = name ?? config.defaultAgent;
|
|
257
|
-
const agentEntry = config.agents[agentName];
|
|
258
|
-
if (!agentEntry) {
|
|
259
|
-
console.log(fmt.error(`Agent "${agentName}" not found`) + '\n');
|
|
260
|
-
console.log('Available agents: ' + Object.keys(config.agents).join(', ') + '\n');
|
|
261
|
-
process.exit(1);
|
|
262
|
-
}
|
|
263
|
-
const { agentId } = agentEntry;
|
|
264
|
-
// Fetch canonical name from API (needed for named-agent hash)
|
|
265
|
-
let agentApiName = null;
|
|
266
|
-
try {
|
|
267
|
-
const agent = await getAgent(agentId);
|
|
268
|
-
agentApiName = agent.name ?? null;
|
|
269
|
-
}
|
|
270
|
-
catch {
|
|
271
|
-
console.log(fmt.warn('Could not fetch agent details — proceeding without name confirmation'));
|
|
272
|
-
}
|
|
273
|
-
console.log('\n' + fmt.header('Check Key Binding'));
|
|
274
|
-
console.log(` Agent: ${agentName} (${agentId})`);
|
|
275
|
-
console.log();
|
|
276
|
-
let key = (process.env.SMOLTBOT_CHECK_KEY ?? '').trim();
|
|
277
|
-
if (!key) {
|
|
278
|
-
key = (await askInput('Enter the API key to check:', true)).trim();
|
|
279
|
-
}
|
|
280
|
-
if (!key) {
|
|
281
|
-
console.log(fmt.error('No key provided') + '\n');
|
|
282
|
-
process.exit(1);
|
|
283
|
-
}
|
|
284
|
-
const keyHash = computeAgentHash(key, agentApiName);
|
|
285
|
-
let result;
|
|
286
|
-
try {
|
|
287
|
-
result = await verifyBinding(agentId, keyHash);
|
|
288
|
-
}
|
|
289
|
-
catch (err) {
|
|
290
|
-
console.log(fmt.error(err instanceof Error ? err.message : String(err)) + '\n');
|
|
291
|
-
process.exit(1);
|
|
292
|
-
}
|
|
293
|
-
if (result.bound) {
|
|
294
|
-
console.log(fmt.success('Key is bound to this agent') + '\n');
|
|
295
|
-
}
|
|
296
|
-
else {
|
|
297
|
-
console.log(fmt.error('Key is NOT bound to this agent') + '\n');
|
|
298
|
-
}
|
|
299
|
-
if (result.key_prefix) {
|
|
300
|
-
const label = result.bound ? 'Key prefix: ' : 'Current prefix:';
|
|
301
|
-
console.log(fmt.label(label, ` ${result.key_prefix}…`) + '\n');
|
|
302
|
-
}
|
|
14
|
+
console.log(fmt.error(`Failed to list agents: ${msg}`) + "\n");
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
if (agents.length === 0) {
|
|
18
|
+
console.log(" No agents found.\n");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
// Table header
|
|
22
|
+
const nameW = 24;
|
|
23
|
+
const idW = 40;
|
|
24
|
+
const seenW = 14;
|
|
25
|
+
const statusW = 14;
|
|
26
|
+
const header = "Name".padEnd(nameW) +
|
|
27
|
+
"ID".padEnd(idW) +
|
|
28
|
+
"Last Seen".padEnd(seenW) +
|
|
29
|
+
"Containment";
|
|
30
|
+
console.log(` ${header}`);
|
|
31
|
+
console.log(` ${"─".repeat(nameW + idW + seenW + statusW)}`);
|
|
32
|
+
for (const agent of agents) {
|
|
33
|
+
const name = (agent.name ?? "-").slice(0, nameW - 2).padEnd(nameW);
|
|
34
|
+
const id = agent.id.padEnd(idW);
|
|
35
|
+
const lastSeen = agent.last_seen
|
|
36
|
+
? new Date(agent.last_seen).toLocaleDateString()
|
|
37
|
+
: "-";
|
|
38
|
+
const seen = lastSeen.padEnd(seenW);
|
|
39
|
+
const containment = agent.containment_status ?? "-";
|
|
40
|
+
console.log(` ${name}${id}${seen}${containment}`);
|
|
41
|
+
}
|
|
42
|
+
console.log(`\n Total: ${agents.length} agent(s)\n`);
|
|
303
43
|
}
|
package/dist/commands/auth.js
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getAuthInfo, clearAuthTokens } from "../lib/auth.js";
|
|
2
2
|
import { loginWithBrowser, loginWithPassword } from "../lib/auth.js";
|
|
3
3
|
import { fmt } from "../lib/format.js";
|
|
4
4
|
import { askInput } from "../lib/prompt.js";
|
|
5
5
|
export async function loginCommand(options = {}) {
|
|
6
|
-
if (!configExists()) {
|
|
7
|
-
console.log("\n" + fmt.error("smoltbot is not initialized") + "\n");
|
|
8
|
-
console.log("Run `smoltbot init` to get started.\n");
|
|
9
|
-
process.exit(1);
|
|
10
|
-
}
|
|
11
6
|
try {
|
|
12
7
|
let tokens;
|
|
13
8
|
if (options.noBrowser) {
|
|
@@ -45,7 +40,7 @@ export async function logoutCommand() {
|
|
|
45
40
|
export async function whoamiCommand() {
|
|
46
41
|
const auth = getAuthInfo();
|
|
47
42
|
if (!auth) {
|
|
48
|
-
console.log("\nNot logged in. Run `
|
|
43
|
+
console.log("\nNot logged in. Run `mnemom login` to authenticate.\n");
|
|
49
44
|
return;
|
|
50
45
|
}
|
|
51
46
|
const now = Math.floor(Date.now() / 1000);
|
package/dist/commands/card.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { type AlignmentCard } from "../lib/api.js";
|
|
2
1
|
export type CardFormat = "json" | "yaml";
|
|
3
2
|
export interface ParsedCard {
|
|
4
3
|
format: CardFormat;
|
|
5
|
-
parsed:
|
|
4
|
+
parsed: Record<string, unknown>;
|
|
5
|
+
raw: string;
|
|
6
6
|
}
|
|
7
7
|
export declare function parseCardFile(filePath: string): ParsedCard;
|
|
8
8
|
export interface ValidationCheck {
|
|
@@ -10,14 +10,27 @@ export interface ValidationCheck {
|
|
|
10
10
|
passed: boolean;
|
|
11
11
|
message: string;
|
|
12
12
|
}
|
|
13
|
-
/** @deprecated Use validateCard instead */
|
|
14
|
-
export declare const validateCardJson: typeof validateCard;
|
|
15
|
-
export declare function validateCard(raw: string): ValidationCheck[];
|
|
16
13
|
/**
|
|
17
|
-
* Validate a
|
|
18
|
-
*
|
|
14
|
+
* Validate a unified alignment card object against ADR-008 schema.
|
|
15
|
+
* Sections: principal, values, conscience, integrity, autonomy,
|
|
16
|
+
* capabilities, enforcement, audit, extensions
|
|
19
17
|
*/
|
|
20
|
-
export declare function
|
|
18
|
+
export declare function validateUnifiedCard(card: Record<string, unknown>): ValidationCheck[];
|
|
19
|
+
/** @deprecated Use validateUnifiedCard instead */
|
|
20
|
+
export declare const validateCardJson: (raw: string) => ValidationCheck[];
|
|
21
21
|
export declare function cardShowCommand(agentName?: string): Promise<void>;
|
|
22
22
|
export declare function cardPublishCommand(file: string, agentName?: string): Promise<void>;
|
|
23
23
|
export declare function cardValidateCommand(file: string): Promise<void>;
|
|
24
|
+
export declare function cardEditCommand(agentName?: string): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* mnemom card evaluate <card-file> --tools <tools> -- local CI/CD evaluation
|
|
27
|
+
*
|
|
28
|
+
* Runs entirely locally using the embedded policy engine. No API key needed.
|
|
29
|
+
* The card IS the policy source -- capabilities and enforcement sections
|
|
30
|
+
* are extracted by @mnemom/policy-engine 0.3.0's evaluatePolicy().
|
|
31
|
+
*/
|
|
32
|
+
export declare function cardEvaluateCommand(file: string, options: {
|
|
33
|
+
tools?: string;
|
|
34
|
+
toolManifest?: string;
|
|
35
|
+
strict?: boolean;
|
|
36
|
+
}): Promise<void>;
|