@miriad-systems/nuum 0.1.10 → 0.1.12
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 +208 -55
- package/dist/index.js +66 -325
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,82 +1,234 @@
|
|
|
1
1
|
# Nuum
|
|
2
2
|
|
|
3
|
-
An AI coding agent with
|
|
3
|
+
An AI coding agent with **"infinite memory"** — continuous context across sessions.
|
|
4
4
|
|
|
5
5
|
*Nuum* — from "continuum" — maintains persistent memory across conversations, learning your codebase, preferences, and decisions over time.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Quick Start
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
```bash
|
|
10
|
+
export ANTHROPIC_API_KEY=your-key-here
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
- **Mid-turn injection** — Send corrections while the agent is working; they're injected into the conversation
|
|
14
|
-
- **Persistent identity** — One database = one agent with continuous memory forever
|
|
12
|
+
# Install and run interactively
|
|
13
|
+
bunx @miriad-systems/nuum --repl
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
# Or with npx
|
|
16
|
+
npx @miriad-systems/nuum --repl
|
|
17
|
+
```
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
That's it. Start chatting. Your agent remembers everything.
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
# Using bunx (recommended - runs in Bun, fast)
|
|
22
|
-
bunx @miriad-systems/nuum
|
|
21
|
+
### REPL Commands
|
|
23
22
|
|
|
24
|
-
# Using npx (runs in Node.js)
|
|
25
|
-
npx @miriad-systems/nuum
|
|
26
23
|
```
|
|
24
|
+
/help Show available commands
|
|
25
|
+
/inspect Show memory statistics
|
|
26
|
+
/dump Show full system prompt
|
|
27
|
+
/quit Exit
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Other Modes
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
nuum -p "What files are in src/" # Single prompt
|
|
34
|
+
nuum --inspect # View memory stats
|
|
35
|
+
nuum --db ./project.db --repl # Custom database
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## ⚠️ Experimental Software
|
|
41
|
+
|
|
42
|
+
Nuum currently runs in **full autonomy mode** — no permission prompts, no confirmations. It was created for [Miriad](https://miriad.systems) as an embedded agent engine, typically running in containerized environments where the host platform manages security.
|
|
43
|
+
|
|
44
|
+
**Why we built this:** We were frustrated with how traditional coding agents seem to suffer some kind of contextual collapse after prolonged use — getting mixed up, repeating mistakes, losing track of decisions. Nuum explores how to keep agents effective indefinitely through recursive memory compression and persistent knowledge.
|
|
27
45
|
|
|
28
|
-
|
|
46
|
+
---
|
|
29
47
|
|
|
30
|
-
|
|
48
|
+
## MCP Servers
|
|
49
|
+
|
|
50
|
+
Nuum supports [Model Context Protocol](https://modelcontextprotocol.io/) servers for extended capabilities. Configure via environment variable:
|
|
31
51
|
|
|
32
52
|
```bash
|
|
33
|
-
|
|
34
|
-
|
|
53
|
+
export NUUM_MCP_SERVERS='{
|
|
54
|
+
"filesystem": {
|
|
55
|
+
"command": "npx",
|
|
56
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"]
|
|
57
|
+
},
|
|
58
|
+
"github": {
|
|
59
|
+
"command": "npx",
|
|
60
|
+
"args": ["-y", "@modelcontextprotocol/server-github"],
|
|
61
|
+
"env": { "GITHUB_TOKEN": "your-token" }
|
|
62
|
+
}
|
|
63
|
+
}'
|
|
35
64
|
```
|
|
36
65
|
|
|
37
|
-
|
|
66
|
+
Or pass via protocol when embedding:
|
|
38
67
|
|
|
39
68
|
```json
|
|
40
|
-
|
|
41
|
-
← {"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"Hello! How can I help?"}]},"session_id":"nuum_01JD..."}
|
|
42
|
-
← {"type":"result","subtype":"success","duration_ms":800,"session_id":"nuum_01JD..."}
|
|
69
|
+
{"type":"user","message":{...},"mcp_servers":{"name":{"command":"...","args":[...]}}}
|
|
43
70
|
```
|
|
44
71
|
|
|
45
|
-
|
|
72
|
+
MCP tools appear alongside built-in tools. The agent discovers and uses them automatically.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Embedding in Applications
|
|
77
|
+
|
|
78
|
+
Nuum is designed to be **embedded**. While it runs standalone, its primary use case is integration into host applications, IDEs, and orchestration platforms.
|
|
46
79
|
|
|
47
80
|
```bash
|
|
48
|
-
nuum
|
|
49
|
-
nuum --db ./my
|
|
81
|
+
nuum --stdio # NDJSON protocol over stdin/stdout
|
|
82
|
+
nuum --stdio --db ./my.db # With custom database
|
|
50
83
|
```
|
|
51
84
|
|
|
52
|
-
|
|
85
|
+
**Key properties:**
|
|
86
|
+
- **Stateless process, stateful memory** — Process can restart anytime; all state lives in SQLite
|
|
87
|
+
- **Simple wire protocol** — JSON messages over stdin/stdout, easy to integrate from any language
|
|
88
|
+
- **Mid-turn injection** — Send corrections while the agent is working
|
|
89
|
+
- **Persistent identity** — One database = one agent with continuous memory
|
|
90
|
+
|
|
91
|
+
See **[docs/protocol.md](docs/protocol.md)** for the full wire protocol specification.
|
|
53
92
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Memory Architecture
|
|
96
|
+
|
|
97
|
+
Nuum has a three-tier memory system that mirrors human cognition.
|
|
98
|
+
|
|
99
|
+
**Key insight:** Agents perform best when context is **30-50% full** — informed but not overwhelmed. Nuum's memory system maintains this sweet spot automatically.
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
103
|
+
│ WORKING MEMORY │
|
|
104
|
+
│ (Temporal Message Store) │
|
|
105
|
+
│ │
|
|
106
|
+
│ Recent messages live here in full detail. As context grows, older │
|
|
107
|
+
│ content is recursively distilled — compressed while retaining what │
|
|
108
|
+
│ matters for effective action. │
|
|
109
|
+
│ │
|
|
110
|
+
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
|
111
|
+
│ │ msg msg msg msg msg msg msg msg msg msg msg msg msg msg msg msg ... │ │
|
|
112
|
+
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
|
|
113
|
+
│ │ └───┴───┴───┴───┘ └───┴───┴───┘ └───┴───┴───┘ │ │ │ │ │
|
|
114
|
+
│ │ │ │ │ │ │ │ │ │
|
|
115
|
+
│ │ [distill-1] [distill-2] [distill-3] │ │ │ │ │
|
|
116
|
+
│ │ │ │ │ │ │ │ │ │
|
|
117
|
+
│ │ └───────────────────┴───────────────┘ │ │ │ │ │
|
|
118
|
+
│ │ │ │ │ │ │ │
|
|
119
|
+
│ │ [distill-4] │ │ │ │ │
|
|
120
|
+
│ │ │ │ │ │ │ │
|
|
121
|
+
│ │ └─────────────────────────┘ │ │ │ │
|
|
122
|
+
│ │ │ │ │ │ │
|
|
123
|
+
│ │ [distill-5] [recent msgs] │ │
|
|
124
|
+
│ │ │ │
|
|
125
|
+
│ │ Older ◄──────────────────────────────────────────────────► Newer │ │
|
|
126
|
+
│ └─────────────────────────────────────────────────────────────────────┘ │
|
|
127
|
+
│ │
|
|
128
|
+
│ The agent sees: [distill-5] + [recent messages] │
|
|
129
|
+
│ 55x compression ratio achieved (1.3M tokens → 25k effective) │
|
|
130
|
+
└─────────────────────────────────────────────────────────────────────────────┘
|
|
131
|
+
|
|
132
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
133
|
+
│ PRESENT STATE │
|
|
134
|
+
│ │
|
|
135
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────────────┐ │
|
|
136
|
+
│ │ Mission │ │ Status │ │ Tasks │ │
|
|
137
|
+
│ │ │ │ │ │ ☑ Setup repository │ │
|
|
138
|
+
│ │ "Build │ │ "reviewing │ │ ☑ Implement auth │ │
|
|
139
|
+
│ │ auth │ │ PR #42" │ │ ☐ Write tests │ │
|
|
140
|
+
│ │ system" │ │ │ │ ☐ Deploy to staging │ │
|
|
141
|
+
│ └─────────────┘ └─────────────┘ └─────────────────────────────────┘ │
|
|
142
|
+
│ │
|
|
143
|
+
│ Agent-managed working state. Updated as work progresses. │
|
|
144
|
+
└─────────────────────────────────────────────────────────────────────────────┘
|
|
145
|
+
|
|
146
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
147
|
+
│ LONG-TERM MEMORY │
|
|
148
|
+
│ (Knowledge Base Tree) │
|
|
149
|
+
│ │
|
|
150
|
+
│ /identity ─────────────── "Who I am, my nature and relationships" │
|
|
151
|
+
│ /behavior ─────────────── "How I should operate, user preferences" │
|
|
152
|
+
│ /miriad-code │
|
|
153
|
+
│ ├── /cast-integration ─ "CAST/Miriad integration notes" │
|
|
154
|
+
│ ├── /memory │
|
|
155
|
+
│ │ └── /background-reports-system │
|
|
156
|
+
│ ├── /anthropic-prompt-caching │
|
|
157
|
+
│ └── /distillation-improvements-jan2026 │
|
|
158
|
+
│ /mcp │
|
|
159
|
+
│ ├── /mcp-implementation │
|
|
160
|
+
│ └── /mcp-config-resolution │
|
|
161
|
+
│ │
|
|
162
|
+
│ Hierarchical knowledge that persists forever. Background workers │
|
|
163
|
+
│ extract important information from conversations and organize it here. │
|
|
164
|
+
└─────────────────────────────────────────────────────────────────────────────┘
|
|
58
165
|
```
|
|
59
166
|
|
|
60
|
-
###
|
|
167
|
+
### Recursive Distillation
|
|
168
|
+
|
|
169
|
+
**No pause for compaction.** Unlike most coding agents that stop mid-conversation to "compact memory," Nuum's distillation runs concurrently while you work. You never wait for memory management — it happens invisibly in the background.
|
|
170
|
+
|
|
171
|
+
The distillation system is **not summarization** — it's operational intelligence extraction:
|
|
172
|
+
|
|
173
|
+
**RETAIN** (actionable intelligence):
|
|
174
|
+
- File paths and what they contain
|
|
175
|
+
- Decisions made and WHY (rationale matters)
|
|
176
|
+
- User preferences and corrections
|
|
177
|
+
- Specific values: URLs, configs, commands
|
|
178
|
+
- Errors and how they were resolved
|
|
179
|
+
|
|
180
|
+
**EXCISE** (noise):
|
|
181
|
+
- Back-and-forth debugging that led nowhere
|
|
182
|
+
- Missteps and corrections (keep only final approach)
|
|
183
|
+
- Verbose tool outputs
|
|
184
|
+
- Narrative filler ("Let me check...")
|
|
185
|
+
- Casual chatter and acknowledgments
|
|
186
|
+
|
|
187
|
+
Distillations are recursive — older distillations get distilled again, creating a fractal compression where ancient history becomes highly compressed while recent work stays detailed.
|
|
188
|
+
|
|
189
|
+
### Long-Term Memory Curation
|
|
190
|
+
|
|
191
|
+
A background worker (the **LTM Curator**) runs continuously in the background:
|
|
192
|
+
|
|
193
|
+
1. **CAPTURES** important information into knowledge entries
|
|
194
|
+
2. **STRENGTHENS** entries by researching and adding context
|
|
195
|
+
3. **CURATES** the knowledge tree structure
|
|
196
|
+
|
|
197
|
+
The curator has access to web search, file reading, and the full knowledge base. It works autonomously — you never see it running, but the agent's knowledge grows over time. Reports are filed silently and surfaced to the main agent on the next interaction.
|
|
198
|
+
|
|
199
|
+
### Reflection
|
|
200
|
+
|
|
201
|
+
When the agent needs to recall something specific — a file path, a decision, a value from weeks ago — it uses the **reflect** tool:
|
|
61
202
|
|
|
62
203
|
```
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
204
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
205
|
+
│ REFLECTION │
|
|
206
|
+
│ │
|
|
207
|
+
│ Main Agent Reflection Sub-Agent │
|
|
208
|
+
│ │ │ │
|
|
209
|
+
│ │ "What was the auth bug fix?" │ │
|
|
210
|
+
│ │ ────────────────────────────────────►│ │
|
|
211
|
+
│ │ │ │
|
|
212
|
+
│ │ ┌───────────┴───────────┐ │
|
|
213
|
+
│ │ │ Search FTS index │ │
|
|
214
|
+
│ │ │ Search LTM entries │ │
|
|
215
|
+
│ │ │ Read relevant docs │ │
|
|
216
|
+
│ │ │ Synthesize answer │ │
|
|
217
|
+
│ │ └───────────┬───────────┘ │
|
|
218
|
+
│ │ │ │
|
|
219
|
+
│ │ "The auth bug was in session.ts, │ │
|
|
220
|
+
│ │ line 42. Fixed by adding null │ │
|
|
221
|
+
│ │ check. Committed in abc123." │ │
|
|
222
|
+
│ │ ◄────────────────────────────────────│ │
|
|
223
|
+
│ │ │ │
|
|
224
|
+
└─────────────────────────────────────────────────────────────────────────────┘
|
|
75
225
|
```
|
|
76
226
|
|
|
77
|
-
|
|
227
|
+
Reflection searches the full conversation history (via FTS5 full-text search) and the knowledge base, then synthesizes an answer. It's like the agent asking its own memory system a question.
|
|
78
228
|
|
|
79
|
-
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Configuration
|
|
80
232
|
|
|
81
233
|
```bash
|
|
82
234
|
# Required
|
|
@@ -89,16 +241,7 @@ AGENT_MODEL_FAST=claude-haiku-4-5-20251001
|
|
|
89
241
|
AGENT_DB=./agent.db
|
|
90
242
|
```
|
|
91
243
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
### Temporal Memory (Working Memory)
|
|
95
|
-
Every message is logged chronologically. As the conversation grows, older content is **distilled** — compressed to retain actionable intelligence: file paths, decisions and rationale, user preferences, specific values.
|
|
96
|
-
|
|
97
|
-
### Present State
|
|
98
|
-
Tracks the current mission, status, and task list. Updated by the agent as work progresses. Always visible in context.
|
|
99
|
-
|
|
100
|
-
### Long-Term Memory (LTM)
|
|
101
|
-
A hierarchical knowledge base that persists across sessions. Contains identity, behavioral guidelines, and accumulated knowledge. Background workers consolidate important information from conversations into LTM.
|
|
244
|
+
---
|
|
102
245
|
|
|
103
246
|
## Development
|
|
104
247
|
|
|
@@ -110,6 +253,8 @@ bun test # Run tests
|
|
|
110
253
|
bun run build # Build for distribution
|
|
111
254
|
```
|
|
112
255
|
|
|
256
|
+
---
|
|
257
|
+
|
|
113
258
|
## Acknowledgments
|
|
114
259
|
|
|
115
260
|
### Letta (formerly MemGPT)
|
|
@@ -126,6 +271,14 @@ Infrastructure adapted from [OpenCode](https://github.com/anthropics/opencode):
|
|
|
126
271
|
- Permission system
|
|
127
272
|
- Process management
|
|
128
273
|
|
|
274
|
+
---
|
|
275
|
+
|
|
129
276
|
## License
|
|
130
277
|
|
|
131
278
|
MIT
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
<p align="center">
|
|
283
|
+
Nuum is part of <a href="https://miriad.systems">Miriad</a>, experimental software from <a href="https://sanity.io">Sanity.io</a>
|
|
284
|
+
</p>
|
package/dist/index.js
CHANGED
|
@@ -16933,7 +16933,7 @@ var require_dist = __commonJS((exports, module) => {
|
|
|
16933
16933
|
exports.default = formatsPlugin;
|
|
16934
16934
|
});
|
|
16935
16935
|
|
|
16936
|
-
// node_modules/cross-spawn/node_modules/
|
|
16936
|
+
// node_modules/cross-spawn/node_modules/isexe/windows.js
|
|
16937
16937
|
var require_windows = __commonJS((exports, module) => {
|
|
16938
16938
|
module.exports = isexe;
|
|
16939
16939
|
isexe.sync = sync;
|
|
@@ -16971,7 +16971,7 @@ var require_windows = __commonJS((exports, module) => {
|
|
|
16971
16971
|
}
|
|
16972
16972
|
});
|
|
16973
16973
|
|
|
16974
|
-
// node_modules/cross-spawn/node_modules/
|
|
16974
|
+
// node_modules/cross-spawn/node_modules/isexe/mode.js
|
|
16975
16975
|
var require_mode = __commonJS((exports, module) => {
|
|
16976
16976
|
module.exports = isexe;
|
|
16977
16977
|
isexe.sync = sync;
|
|
@@ -17002,7 +17002,7 @@ var require_mode = __commonJS((exports, module) => {
|
|
|
17002
17002
|
}
|
|
17003
17003
|
});
|
|
17004
17004
|
|
|
17005
|
-
// node_modules/cross-spawn/node_modules/
|
|
17005
|
+
// node_modules/cross-spawn/node_modules/isexe/index.js
|
|
17006
17006
|
var require_isexe = __commonJS((exports, module) => {
|
|
17007
17007
|
var fs7 = __require("fs");
|
|
17008
17008
|
var core2;
|
|
@@ -32053,6 +32053,18 @@ function sleep(ms) {
|
|
|
32053
32053
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
32054
32054
|
}
|
|
32055
32055
|
|
|
32056
|
+
// src/context/environment.ts
|
|
32057
|
+
var currentEnvironment = {};
|
|
32058
|
+
function setEnvironment(env) {
|
|
32059
|
+
currentEnvironment = env;
|
|
32060
|
+
}
|
|
32061
|
+
function getSpawnEnvironment() {
|
|
32062
|
+
return {
|
|
32063
|
+
...process.env,
|
|
32064
|
+
...currentEnvironment
|
|
32065
|
+
};
|
|
32066
|
+
}
|
|
32067
|
+
|
|
32056
32068
|
// src/tool/bash.ts
|
|
32057
32069
|
var MAX_OUTPUT_LENGTH = 50000;
|
|
32058
32070
|
var DEFAULT_TIMEOUT_MS = 2 * 60 * 1000;
|
|
@@ -32094,7 +32106,7 @@ Use this tool for:
|
|
|
32094
32106
|
const proc = spawn2(params.command, {
|
|
32095
32107
|
shell,
|
|
32096
32108
|
cwd,
|
|
32097
|
-
env:
|
|
32109
|
+
env: getSpawnEnvironment(),
|
|
32098
32110
|
stdio: ["ignore", "pipe", "pipe"],
|
|
32099
32111
|
detached: process.platform !== "win32"
|
|
32100
32112
|
});
|
|
@@ -33791,7 +33803,8 @@ var Ripgrep;
|
|
|
33791
33803
|
}
|
|
33792
33804
|
const proc = spawn3(rgPath, args, {
|
|
33793
33805
|
cwd: input.cwd,
|
|
33794
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
33806
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
33807
|
+
env: getSpawnEnvironment()
|
|
33795
33808
|
});
|
|
33796
33809
|
let buffer = "";
|
|
33797
33810
|
for await (const chunk of proc.stdout) {
|
|
@@ -33941,7 +33954,8 @@ Respects .gitignore patterns.`,
|
|
|
33941
33954
|
}
|
|
33942
33955
|
args.push(searchPath);
|
|
33943
33956
|
const proc = spawn4(rgPath, args, {
|
|
33944
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
33957
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
33958
|
+
env: getSpawnEnvironment()
|
|
33945
33959
|
});
|
|
33946
33960
|
let output = "";
|
|
33947
33961
|
let errorOutput = "";
|
|
@@ -34455,6 +34469,10 @@ Use reflect when:
|
|
|
34455
34469
|
- You need a specific value or path from earlier work
|
|
34456
34470
|
- The user asks "remember when..." or "what did we decide about..."
|
|
34457
34471
|
- You want to verify your memory before acting
|
|
34472
|
+
|
|
34473
|
+
## Message Prefixes
|
|
34474
|
+
|
|
34475
|
+
Messages in your history have automatic prefixes like \`[2026-01-26 15:30 id:msg_xxx]\` showing timestamp and ID. These are added by the system for internal tracking - you don't need to reference or echo them. Just read the message content normally.
|
|
34458
34476
|
`;
|
|
34459
34477
|
const systemPromptOverlay = await storage.session.getSystemPromptOverlay();
|
|
34460
34478
|
if (systemPromptOverlay) {
|
|
@@ -34545,14 +34563,29 @@ Retained facts:
|
|
|
34545
34563
|
}
|
|
34546
34564
|
return turns;
|
|
34547
34565
|
}
|
|
34548
|
-
function
|
|
34549
|
-
|
|
34566
|
+
function formatTimestamp(isoTimestamp) {
|
|
34567
|
+
const date2 = new Date(isoTimestamp);
|
|
34568
|
+
const year = date2.getFullYear();
|
|
34569
|
+
const month = String(date2.getMonth() + 1).padStart(2, "0");
|
|
34570
|
+
const day = String(date2.getDate()).padStart(2, "0");
|
|
34571
|
+
const hours = String(date2.getHours()).padStart(2, "0");
|
|
34572
|
+
const minutes = String(date2.getMinutes()).padStart(2, "0");
|
|
34573
|
+
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
|
34574
|
+
}
|
|
34575
|
+
function formatWithId(id, timestamp, content) {
|
|
34576
|
+
return `[${formatTimestamp(timestamp)} id:${id}] ${content}`;
|
|
34577
|
+
}
|
|
34578
|
+
function formatIdRange(firstId, lastId, timestamp) {
|
|
34579
|
+
if (firstId === lastId) {
|
|
34580
|
+
return `[${formatTimestamp(timestamp)} id:${firstId}]`;
|
|
34581
|
+
}
|
|
34582
|
+
return `[${formatTimestamp(timestamp)} id:${firstId}...${lastId}]`;
|
|
34550
34583
|
}
|
|
34551
34584
|
function processMessageForTurn(message, allMessages, currentIdx) {
|
|
34552
34585
|
const turns = [];
|
|
34553
34586
|
switch (message.type) {
|
|
34554
34587
|
case "user":
|
|
34555
|
-
turns.push({ role: "user", content: formatWithId(message.id, message.content) });
|
|
34588
|
+
turns.push({ role: "user", content: formatWithId(message.id, message.createdAt, message.content) });
|
|
34556
34589
|
return { turns, nextIdx: currentIdx + 1 };
|
|
34557
34590
|
case "assistant": {
|
|
34558
34591
|
const toolCalls = [];
|
|
@@ -34594,7 +34627,7 @@ function processMessageForTurn(message, allMessages, currentIdx) {
|
|
|
34594
34627
|
}
|
|
34595
34628
|
if (toolCalls.length > 0) {
|
|
34596
34629
|
const assistantContent = [];
|
|
34597
|
-
const idPrefix = message.id
|
|
34630
|
+
const idPrefix = formatIdRange(message.id, lastMessageId, message.createdAt);
|
|
34598
34631
|
if (message.content) {
|
|
34599
34632
|
assistantContent.push({ type: "text", text: `${idPrefix} ${message.content}` });
|
|
34600
34633
|
} else {
|
|
@@ -34614,7 +34647,7 @@ function processMessageForTurn(message, allMessages, currentIdx) {
|
|
|
34614
34647
|
turns.push(toolMsg);
|
|
34615
34648
|
}
|
|
34616
34649
|
} else {
|
|
34617
|
-
turns.push({ role: "assistant", content: formatWithId(message.id, message.content) });
|
|
34650
|
+
turns.push({ role: "assistant", content: formatWithId(message.id, message.createdAt, message.content) });
|
|
34618
34651
|
}
|
|
34619
34652
|
return { turns, nextIdx };
|
|
34620
34653
|
}
|
|
@@ -34658,7 +34691,7 @@ function processMessageForTurn(message, allMessages, currentIdx) {
|
|
|
34658
34691
|
nextIdx++;
|
|
34659
34692
|
}
|
|
34660
34693
|
if (toolCalls.length > 0) {
|
|
34661
|
-
const idPrefix = firstMessageId
|
|
34694
|
+
const idPrefix = formatIdRange(firstMessageId, lastMessageId, message.createdAt);
|
|
34662
34695
|
const assistantContent = [
|
|
34663
34696
|
{ type: "text", text: idPrefix },
|
|
34664
34697
|
...toolCalls
|
|
@@ -34686,7 +34719,7 @@ function processMessageForTurn(message, allMessages, currentIdx) {
|
|
|
34686
34719
|
case "system":
|
|
34687
34720
|
turns.push({
|
|
34688
34721
|
role: "assistant",
|
|
34689
|
-
content: `[system ${formatWithId(message.id, message.content)}]`
|
|
34722
|
+
content: `[system ${formatWithId(message.id, message.createdAt, message.content)}]`
|
|
34690
34723
|
});
|
|
34691
34724
|
return { turns, nextIdx: currentIdx + 1 };
|
|
34692
34725
|
default:
|
|
@@ -35039,11 +35072,13 @@ Your working memory (conversation history) needs to be optimized for effective a
|
|
|
35039
35072
|
${underTarget ? "**Status:** Already at/under target. You may clean up noise if you see any, or call finish_distillation." : `**To distill:** ~${(currentTokens - targetTokens).toLocaleString()} tokens`}
|
|
35040
35073
|
**Recency buffer:** ${recencyBuffer} most recent messages are protected
|
|
35041
35074
|
|
|
35042
|
-
The conversation above contains IDs you can reference:
|
|
35043
|
-
- Messages have \`[id:xxx]\` prefixes
|
|
35075
|
+
The conversation above contains timestamps and IDs you can reference:
|
|
35076
|
+
- Messages have \`[YYYY-MM-DD HH:MM id:xxx]\` prefixes (timestamp + ID)
|
|
35044
35077
|
- Distillations show \`[distilled from:xxx to:yyy]\` ranges
|
|
35045
35078
|
- The most recent ${recencyBuffer} messages cannot be distilled (preserve immediate context)
|
|
35046
35079
|
|
|
35080
|
+
Note: These prefixes are for YOUR reference when creating distillations. Do not echo them in responses.
|
|
35081
|
+
|
|
35047
35082
|
## Your Task: Distill, Don't Summarize
|
|
35048
35083
|
|
|
35049
35084
|
The goal is NOT narrative summarization ("we discussed X and decided Y").
|
|
@@ -45552,7 +45587,7 @@ async function runAgent(prompt, options) {
|
|
|
45552
45587
|
|
|
45553
45588
|
// src/cli/verbose.ts
|
|
45554
45589
|
var SEPARATOR = "\u2500".repeat(70);
|
|
45555
|
-
function
|
|
45590
|
+
function formatTimestamp2() {
|
|
45556
45591
|
return new Date().toISOString().slice(11, 23);
|
|
45557
45592
|
}
|
|
45558
45593
|
|
|
@@ -45632,7 +45667,7 @@ LTM:`);
|
|
|
45632
45667
|
this.events = [];
|
|
45633
45668
|
}
|
|
45634
45669
|
event(event) {
|
|
45635
|
-
const ts = event.timestamp ??
|
|
45670
|
+
const ts = event.timestamp ?? formatTimestamp2();
|
|
45636
45671
|
const arrow = event.type === "user" || event.type === "tool_result" ? "\u2192" : "\u2190";
|
|
45637
45672
|
const typeLabel = event.type.replace("_", " ");
|
|
45638
45673
|
const content = event.content.length > 100 ? event.content.slice(0, 100) + "..." : event.content;
|
|
@@ -46155,7 +46190,8 @@ var UserMessageSchema = exports_external.object({
|
|
|
46155
46190
|
}),
|
|
46156
46191
|
session_id: exports_external.string().optional(),
|
|
46157
46192
|
system_prompt: exports_external.string().optional(),
|
|
46158
|
-
mcp_servers: exports_external.record(exports_external.unknown()).optional()
|
|
46193
|
+
mcp_servers: exports_external.record(exports_external.unknown()).optional(),
|
|
46194
|
+
environment: exports_external.record(exports_external.string()).optional()
|
|
46159
46195
|
});
|
|
46160
46196
|
var ControlRequestSchema = exports_external.object({
|
|
46161
46197
|
type: exports_external.literal("control"),
|
|
@@ -46351,6 +46387,14 @@ class Server {
|
|
|
46351
46387
|
if (userMessage.mcp_servers !== undefined) {
|
|
46352
46388
|
await this.reinitializeMcpWithOverride(userMessage.mcp_servers);
|
|
46353
46389
|
}
|
|
46390
|
+
if (userMessage.environment !== undefined) {
|
|
46391
|
+
setEnvironment(userMessage.environment);
|
|
46392
|
+
log11.info("applied environment from message", {
|
|
46393
|
+
count: Object.keys(userMessage.environment).length
|
|
46394
|
+
});
|
|
46395
|
+
} else {
|
|
46396
|
+
setEnvironment({});
|
|
46397
|
+
}
|
|
46354
46398
|
this.currentTurn = {
|
|
46355
46399
|
sessionId,
|
|
46356
46400
|
abortController,
|
|
@@ -46582,12 +46626,6 @@ Goodbye!`);
|
|
|
46582
46626
|
console.log("Goodbye!");
|
|
46583
46627
|
process.exit(0);
|
|
46584
46628
|
break;
|
|
46585
|
-
case "clear":
|
|
46586
|
-
this.storage = createStorage(this.options.dbPath);
|
|
46587
|
-
await initializeDefaultEntries(this.storage);
|
|
46588
|
-
console.log("Conversation cleared. Starting fresh session.");
|
|
46589
|
-
this.rl?.prompt();
|
|
46590
|
-
break;
|
|
46591
46629
|
case "inspect":
|
|
46592
46630
|
try {
|
|
46593
46631
|
await runInspect(this.options.dbPath);
|
|
@@ -46621,7 +46659,6 @@ Goodbye!`);
|
|
|
46621
46659
|
console.log("Commands:");
|
|
46622
46660
|
console.log(" /help, /h, /? Show this help");
|
|
46623
46661
|
console.log(" /quit, /exit, /q Exit the REPL");
|
|
46624
|
-
console.log(" /clear Clear conversation history (fresh session)");
|
|
46625
46662
|
console.log(" /inspect Show memory statistics");
|
|
46626
46663
|
console.log(" /dump Show full system prompt");
|
|
46627
46664
|
console.log();
|
|
@@ -46767,288 +46804,9 @@ async function runRepl(options) {
|
|
|
46767
46804
|
await session.start();
|
|
46768
46805
|
}
|
|
46769
46806
|
|
|
46770
|
-
// src/cli/repl-protocol.ts
|
|
46771
|
-
import * as readline3 from "readline";
|
|
46772
|
-
import * as fs9 from "fs";
|
|
46773
|
-
import * as path10 from "path";
|
|
46774
|
-
import * as os4 from "os";
|
|
46775
|
-
import { spawn as spawn6 } from "child_process";
|
|
46776
|
-
var PROMPT2 = "protocol> ";
|
|
46777
|
-
var HISTORY_FILE2 = path10.join(os4.homedir(), ".miriad-code-protocol-history");
|
|
46778
|
-
var MAX_HISTORY2 = 1000;
|
|
46779
|
-
|
|
46780
|
-
class ProtocolReplSession {
|
|
46781
|
-
options;
|
|
46782
|
-
rl = null;
|
|
46783
|
-
serverProcess = null;
|
|
46784
|
-
history = [];
|
|
46785
|
-
isRunning = false;
|
|
46786
|
-
sessionId = `session_${Date.now()}`;
|
|
46787
|
-
lineBuffer = "";
|
|
46788
|
-
constructor(options) {
|
|
46789
|
-
this.options = options;
|
|
46790
|
-
}
|
|
46791
|
-
async start() {
|
|
46792
|
-
this.loadHistory();
|
|
46793
|
-
this.startServer();
|
|
46794
|
-
this.rl = readline3.createInterface({
|
|
46795
|
-
input: process.stdin,
|
|
46796
|
-
output: process.stdout,
|
|
46797
|
-
prompt: PROMPT2,
|
|
46798
|
-
historySize: MAX_HISTORY2,
|
|
46799
|
-
terminal: true
|
|
46800
|
-
});
|
|
46801
|
-
for (const line of this.history) {
|
|
46802
|
-
this.rl.history?.unshift(line);
|
|
46803
|
-
}
|
|
46804
|
-
this.rl.on("SIGINT", () => {
|
|
46805
|
-
if (this.isRunning) {
|
|
46806
|
-
this.sendControl("interrupt");
|
|
46807
|
-
process.stdout.write(`
|
|
46808
|
-
^C - Interrupt sent
|
|
46809
|
-
`);
|
|
46810
|
-
} else {
|
|
46811
|
-
process.stdout.write(`
|
|
46812
|
-
(Use /quit or Ctrl+D to exit)
|
|
46813
|
-
`);
|
|
46814
|
-
this.rl?.prompt();
|
|
46815
|
-
}
|
|
46816
|
-
});
|
|
46817
|
-
this.rl.on("close", () => {
|
|
46818
|
-
this.shutdown();
|
|
46819
|
-
});
|
|
46820
|
-
this.rl.on("line", (line) => {
|
|
46821
|
-
this.handleLine(line).catch((error2) => {
|
|
46822
|
-
console.error(`Error: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
46823
|
-
this.rl?.prompt();
|
|
46824
|
-
});
|
|
46825
|
-
});
|
|
46826
|
-
this.printWelcome();
|
|
46827
|
-
this.rl.prompt();
|
|
46828
|
-
}
|
|
46829
|
-
startServer() {
|
|
46830
|
-
const args = ["run", "src/cli/index.ts", "--stdio", "--db", this.options.dbPath];
|
|
46831
|
-
this.serverProcess = spawn6("bun", args, {
|
|
46832
|
-
stdio: ["pipe", "pipe", "inherit"],
|
|
46833
|
-
cwd: process.cwd()
|
|
46834
|
-
});
|
|
46835
|
-
this.serverProcess.stdout?.on("data", (data) => {
|
|
46836
|
-
this.lineBuffer += data.toString();
|
|
46837
|
-
const lines = this.lineBuffer.split(`
|
|
46838
|
-
`);
|
|
46839
|
-
this.lineBuffer = lines.pop() || "";
|
|
46840
|
-
for (const line of lines) {
|
|
46841
|
-
if (line.trim()) {
|
|
46842
|
-
this.handleServerMessage(line.trim());
|
|
46843
|
-
}
|
|
46844
|
-
}
|
|
46845
|
-
});
|
|
46846
|
-
this.serverProcess.on("exit", (code) => {
|
|
46847
|
-
console.log(`
|
|
46848
|
-
Server exited with code ${code}`);
|
|
46849
|
-
process.exit(code ?? 0);
|
|
46850
|
-
});
|
|
46851
|
-
this.serverProcess.on("error", (error2) => {
|
|
46852
|
-
console.error(`Server error: ${error2.message}`);
|
|
46853
|
-
process.exit(1);
|
|
46854
|
-
});
|
|
46855
|
-
}
|
|
46856
|
-
handleServerMessage(line) {
|
|
46857
|
-
try {
|
|
46858
|
-
const msg = JSON.parse(line);
|
|
46859
|
-
this.displayMessage(msg);
|
|
46860
|
-
} catch (error2) {}
|
|
46861
|
-
}
|
|
46862
|
-
displayMessage(msg) {
|
|
46863
|
-
process.stdout.write("\r\x1B[K");
|
|
46864
|
-
switch (msg.type) {
|
|
46865
|
-
case "assistant":
|
|
46866
|
-
const text3 = msg.message.content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
46867
|
-
if (text3) {
|
|
46868
|
-
console.log(`\x1B[36m${text3}\x1B[0m`);
|
|
46869
|
-
}
|
|
46870
|
-
break;
|
|
46871
|
-
case "result":
|
|
46872
|
-
this.isRunning = false;
|
|
46873
|
-
const status = msg.subtype === "success" ? "\x1B[32m\u2713\x1B[0m" : msg.subtype === "cancelled" ? "\x1B[33m\u2298\x1B[0m" : "\x1B[31m\u2717\x1B[0m";
|
|
46874
|
-
console.log(`
|
|
46875
|
-
${status} ${msg.subtype} (${msg.duration_ms}ms, ${msg.num_turns} turns)`);
|
|
46876
|
-
if (msg.usage) {
|
|
46877
|
-
console.log(` tokens: ${msg.usage.input_tokens} in / ${msg.usage.output_tokens} out`);
|
|
46878
|
-
}
|
|
46879
|
-
this.rl?.prompt();
|
|
46880
|
-
break;
|
|
46881
|
-
case "system":
|
|
46882
|
-
switch (msg.subtype) {
|
|
46883
|
-
case "queued":
|
|
46884
|
-
console.log(`\x1B[90m[Queued: position ${msg.position}]\x1B[0m`);
|
|
46885
|
-
break;
|
|
46886
|
-
case "injected":
|
|
46887
|
-
console.log(`\x1B[90m[Injected: ${msg.message_count} message(s)]\x1B[0m`);
|
|
46888
|
-
break;
|
|
46889
|
-
case "interrupted":
|
|
46890
|
-
console.log(`\x1B[33m[Interrupted]\x1B[0m`);
|
|
46891
|
-
break;
|
|
46892
|
-
case "status":
|
|
46893
|
-
console.log(`\x1B[90m[Status: running=${msg.running}, queued=${msg.queued_messages}]\x1B[0m`);
|
|
46894
|
-
this.rl?.prompt();
|
|
46895
|
-
break;
|
|
46896
|
-
case "tool_result":
|
|
46897
|
-
break;
|
|
46898
|
-
case "error":
|
|
46899
|
-
console.log(`\x1B[31m[Error: ${msg.message}]\x1B[0m`);
|
|
46900
|
-
break;
|
|
46901
|
-
default:
|
|
46902
|
-
console.log(`\x1B[90m[${msg.subtype}]\x1B[0m`);
|
|
46903
|
-
}
|
|
46904
|
-
break;
|
|
46905
|
-
}
|
|
46906
|
-
}
|
|
46907
|
-
printWelcome() {
|
|
46908
|
-
console.log();
|
|
46909
|
-
console.log("miriad-code protocol REPL");
|
|
46910
|
-
console.log("Type messages to send to the agent via protocol");
|
|
46911
|
-
console.log("Messages sent while agent is working will be injected mid-turn");
|
|
46912
|
-
console.log("Type /help for commands");
|
|
46913
|
-
console.log();
|
|
46914
|
-
}
|
|
46915
|
-
async handleLine(line) {
|
|
46916
|
-
const trimmed = line.trim();
|
|
46917
|
-
if (!trimmed) {
|
|
46918
|
-
this.rl?.prompt();
|
|
46919
|
-
return;
|
|
46920
|
-
}
|
|
46921
|
-
this.addToHistory(trimmed);
|
|
46922
|
-
if (trimmed.startsWith("/")) {
|
|
46923
|
-
await this.handleCommand(trimmed);
|
|
46924
|
-
return;
|
|
46925
|
-
}
|
|
46926
|
-
this.sendUserMessage(trimmed);
|
|
46927
|
-
}
|
|
46928
|
-
async handleCommand(input) {
|
|
46929
|
-
const parts = input.slice(1).split(/\s+/);
|
|
46930
|
-
const command = parts[0].toLowerCase();
|
|
46931
|
-
switch (command) {
|
|
46932
|
-
case "quit":
|
|
46933
|
-
case "exit":
|
|
46934
|
-
case "q":
|
|
46935
|
-
this.shutdown();
|
|
46936
|
-
break;
|
|
46937
|
-
case "status":
|
|
46938
|
-
this.sendControl("status");
|
|
46939
|
-
break;
|
|
46940
|
-
case "interrupt":
|
|
46941
|
-
case "cancel":
|
|
46942
|
-
this.sendControl("interrupt");
|
|
46943
|
-
break;
|
|
46944
|
-
case "help":
|
|
46945
|
-
case "h":
|
|
46946
|
-
case "?":
|
|
46947
|
-
this.printHelp();
|
|
46948
|
-
this.rl?.prompt();
|
|
46949
|
-
break;
|
|
46950
|
-
default:
|
|
46951
|
-
console.log(`Unknown command: /${command}`);
|
|
46952
|
-
console.log("Type /help for available commands.");
|
|
46953
|
-
this.rl?.prompt();
|
|
46954
|
-
}
|
|
46955
|
-
}
|
|
46956
|
-
printHelp() {
|
|
46957
|
-
console.log();
|
|
46958
|
-
console.log("Commands:");
|
|
46959
|
-
console.log(" /help, /h, /? Show this help");
|
|
46960
|
-
console.log(" /quit, /exit, /q Exit the REPL");
|
|
46961
|
-
console.log(" /status Get server status");
|
|
46962
|
-
console.log(" /interrupt Cancel current turn");
|
|
46963
|
-
console.log();
|
|
46964
|
-
console.log("Shortcuts:");
|
|
46965
|
-
console.log(" Ctrl+C Send interrupt");
|
|
46966
|
-
console.log(" Ctrl+D Exit");
|
|
46967
|
-
console.log();
|
|
46968
|
-
console.log("Mid-turn messaging:");
|
|
46969
|
-
console.log(" Type while the agent is working to inject messages");
|
|
46970
|
-
console.log(" Messages are queued and injected before the next model call");
|
|
46971
|
-
console.log();
|
|
46972
|
-
}
|
|
46973
|
-
sendUserMessage(content) {
|
|
46974
|
-
const msg = {
|
|
46975
|
-
type: "user",
|
|
46976
|
-
message: { role: "user", content },
|
|
46977
|
-
session_id: this.sessionId
|
|
46978
|
-
};
|
|
46979
|
-
this.serverProcess?.stdin?.write(JSON.stringify(msg) + `
|
|
46980
|
-
`);
|
|
46981
|
-
this.isRunning = true;
|
|
46982
|
-
}
|
|
46983
|
-
sendControl(action) {
|
|
46984
|
-
const msg = { type: "control", action };
|
|
46985
|
-
this.serverProcess?.stdin?.write(JSON.stringify(msg) + `
|
|
46986
|
-
`);
|
|
46987
|
-
}
|
|
46988
|
-
shutdown() {
|
|
46989
|
-
this.saveHistory();
|
|
46990
|
-
console.log(`
|
|
46991
|
-
Goodbye!`);
|
|
46992
|
-
this.serverProcess?.kill();
|
|
46993
|
-
process.exit(0);
|
|
46994
|
-
}
|
|
46995
|
-
loadHistory() {
|
|
46996
|
-
try {
|
|
46997
|
-
if (fs9.existsSync(HISTORY_FILE2)) {
|
|
46998
|
-
const content = fs9.readFileSync(HISTORY_FILE2, "utf-8");
|
|
46999
|
-
this.history = content.split(`
|
|
47000
|
-
`).filter((line) => line.trim()).slice(-MAX_HISTORY2);
|
|
47001
|
-
}
|
|
47002
|
-
} catch {}
|
|
47003
|
-
}
|
|
47004
|
-
saveHistory() {
|
|
47005
|
-
try {
|
|
47006
|
-
const rlHistory = this.rl?.history || [];
|
|
47007
|
-
const allHistory = [...new Set([...rlHistory.reverse(), ...this.history])];
|
|
47008
|
-
const trimmed = allHistory.slice(-MAX_HISTORY2);
|
|
47009
|
-
fs9.writeFileSync(HISTORY_FILE2, trimmed.join(`
|
|
47010
|
-
`) + `
|
|
47011
|
-
`);
|
|
47012
|
-
} catch {}
|
|
47013
|
-
}
|
|
47014
|
-
addToHistory(line) {
|
|
47015
|
-
if (line.startsWith("/"))
|
|
47016
|
-
return;
|
|
47017
|
-
this.history.push(line);
|
|
47018
|
-
}
|
|
47019
|
-
}
|
|
47020
|
-
async function runProtocolRepl(options) {
|
|
47021
|
-
const session = new ProtocolReplSession(options);
|
|
47022
|
-
await session.start();
|
|
47023
|
-
}
|
|
47024
|
-
|
|
47025
46807
|
// src/version.ts
|
|
47026
|
-
|
|
47027
|
-
|
|
47028
|
-
import { join as join9, dirname as dirname5 } from "path";
|
|
47029
|
-
import { fileURLToPath } from "url";
|
|
47030
|
-
function getPackageVersion() {
|
|
47031
|
-
try {
|
|
47032
|
-
const __dirname2 = dirname5(fileURLToPath(import.meta.url));
|
|
47033
|
-
const pkgPath = join9(__dirname2, "..", "package.json");
|
|
47034
|
-
const pkg = JSON.parse(readFileSync7(pkgPath, "utf-8"));
|
|
47035
|
-
return pkg.version || "0.0.0";
|
|
47036
|
-
} catch {
|
|
47037
|
-
return "0.0.0";
|
|
47038
|
-
}
|
|
47039
|
-
}
|
|
47040
|
-
function getGitHash() {
|
|
47041
|
-
try {
|
|
47042
|
-
return execSync("git rev-parse --short HEAD", {
|
|
47043
|
-
encoding: "utf-8",
|
|
47044
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
47045
|
-
}).trim();
|
|
47046
|
-
} catch {
|
|
47047
|
-
return "unknown";
|
|
47048
|
-
}
|
|
47049
|
-
}
|
|
47050
|
-
var VERSION = getPackageVersion();
|
|
47051
|
-
var GIT_HASH = getGitHash();
|
|
46808
|
+
var VERSION = "0.1.12";
|
|
46809
|
+
var GIT_HASH = "712107d";
|
|
47052
46810
|
var VERSION_STRING = `miriad-code v${VERSION} (${GIT_HASH})`;
|
|
47053
46811
|
|
|
47054
46812
|
// src/cli/index.ts
|
|
@@ -47065,8 +46823,7 @@ function parseCliArgs() {
|
|
|
47065
46823
|
dump: { type: "boolean", default: false },
|
|
47066
46824
|
compact: { type: "boolean", default: false },
|
|
47067
46825
|
stdio: { type: "boolean", default: false },
|
|
47068
|
-
repl: { type: "boolean", default: false }
|
|
47069
|
-
"repl-protocol": { type: "boolean", default: false }
|
|
46826
|
+
repl: { type: "boolean", default: false }
|
|
47070
46827
|
},
|
|
47071
46828
|
allowPositionals: false
|
|
47072
46829
|
});
|
|
@@ -47081,8 +46838,7 @@ function parseCliArgs() {
|
|
|
47081
46838
|
dump: values.dump ?? false,
|
|
47082
46839
|
compact: values.compact ?? false,
|
|
47083
46840
|
stdio: values.stdio ?? false,
|
|
47084
|
-
repl: values.repl ?? false
|
|
47085
|
-
replProtocol: values["repl-protocol"] ?? false
|
|
46841
|
+
repl: values.repl ?? false
|
|
47086
46842
|
};
|
|
47087
46843
|
}
|
|
47088
46844
|
function printHelp() {
|
|
@@ -47095,7 +46851,6 @@ Usage:
|
|
|
47095
46851
|
miriad-code -p "prompt" Run agent with a prompt
|
|
47096
46852
|
miriad-code -p "prompt" --verbose Show debug output
|
|
47097
46853
|
miriad-code --repl Start interactive REPL mode
|
|
47098
|
-
miriad-code --repl-protocol Start REPL using protocol server (for testing)
|
|
47099
46854
|
miriad-code --stdio Start protocol server over stdin/stdout
|
|
47100
46855
|
miriad-code --inspect Show memory stats (no LLM call)
|
|
47101
46856
|
miriad-code --dump Show raw system prompt (no LLM call)
|
|
@@ -47106,7 +46861,6 @@ Options:
|
|
|
47106
46861
|
-p, --prompt <text> The prompt to send to the agent
|
|
47107
46862
|
-v, --verbose Show memory state, token usage, and execution trace
|
|
47108
46863
|
--repl Start interactive REPL with readline support
|
|
47109
|
-
--repl-protocol Start REPL that uses protocol server (test mid-turn messages)
|
|
47110
46864
|
--stdio Start Claude Code SDK protocol server on stdin/stdout
|
|
47111
46865
|
--inspect Show memory statistics: temporal, present, LTM
|
|
47112
46866
|
--dump Dump the full system prompt that would be sent to LLM
|
|
@@ -47171,19 +46925,6 @@ async function main() {
|
|
|
47171
46925
|
}
|
|
47172
46926
|
return;
|
|
47173
46927
|
}
|
|
47174
|
-
if (options.replProtocol) {
|
|
47175
|
-
try {
|
|
47176
|
-
await runProtocolRepl({ dbPath: options.db });
|
|
47177
|
-
} catch (error2) {
|
|
47178
|
-
if (error2 instanceof Error) {
|
|
47179
|
-
console.error(`Error: ${error2.message}`);
|
|
47180
|
-
} else {
|
|
47181
|
-
console.error("Unknown error:", error2);
|
|
47182
|
-
}
|
|
47183
|
-
process.exit(1);
|
|
47184
|
-
}
|
|
47185
|
-
return;
|
|
47186
|
-
}
|
|
47187
46928
|
if (options.stdio) {
|
|
47188
46929
|
try {
|
|
47189
46930
|
await runServer({ dbPath: options.db });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@miriad-systems/nuum",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "AI coding agent with continuous memory - infinite context across sessions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"src/storage/migrations"
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
|
-
"build": "bun build ./src/cli/index.ts --outdir ./dist --target bun && node -e \"const fs=require('fs');const f='./dist/index.js';fs.writeFileSync(f,fs.readFileSync(f,'utf8').replace('#!/usr/bin/env node','#!/usr/bin/env bun'))\"",
|
|
14
|
+
"build": "bun build ./src/cli/index.ts --outdir ./dist --target bun --define \"BUILD_VERSION='$(node -p \"require('./package.json').version\")'\" --define \"BUILD_GIT_HASH='$(git rev-parse --short HEAD 2>/dev/null || echo unknown)'\" && node -e \"const fs=require('fs');const f='./dist/index.js';fs.writeFileSync(f,fs.readFileSync(f,'utf8').replace('#!/usr/bin/env node','#!/usr/bin/env bun'))\"",
|
|
15
15
|
"dev": "bun run ./src/cli/index.ts",
|
|
16
16
|
"typecheck": "tsc --noEmit",
|
|
17
17
|
"test": "bun test",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"repository": {
|
|
33
33
|
"type": "git",
|
|
34
|
-
"url": "https://github.com/
|
|
34
|
+
"url": "https://github.com/sanity-labs/nuum.git"
|
|
35
35
|
},
|
|
36
36
|
"engines": {
|
|
37
37
|
"node": ">=18.0.0"
|