@monoes/monomindcli 2.10.9 → 2.10.13
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/.claude/commands/mastermind/brain.md +14 -14
- package/.claude/commands/mastermind/help.md +2 -2
- package/.claude/commands/mastermind/master.md +24 -19
- package/.claude/commands/mastermind/memory.md +8 -8
- package/.claude/commands/mastermind/monoswarm.md +4 -4
- package/.claude/commands/mastermind.md +7 -7
- package/.claude/commands/truth/start.md +3 -3
- package/.claude/settings.json +0 -4
- package/.claude/skills/mastermind/SKILL.md +7 -16
- package/.claude/skills/mastermind/references/antigravity-tools.md +0 -62
- package/.claude/skills/mastermind/references/claude-code-tools.md +0 -52
- package/.claude/skills/mastermind/references/codex-tools.md +0 -66
- package/.claude/skills/mastermind/references/copilot-tools.md +0 -51
- package/.claude/skills/mastermind/references/gemini-tools.md +0 -65
- package/.claude/skills/mastermind/references/pi-tools.md +0 -30
- package/.claude/skills/mastermind-createorg/SKILL.md +3 -1
- package/.claude/skills/mastermind-debug/SKILL.md +3 -277
- package/.claude/skills/mastermind-design/SKILL.md +2 -0
- package/.claude/skills/mastermind-execute/SKILL.md +59 -103
- package/.claude/skills/mastermind-idea/SKILL.md +9 -2
- package/.claude/skills/mastermind-intake/SKILL.md +31 -7
- package/.claude/skills/mastermind-issue-detail/SKILL.md +70 -16
- package/.claude/skills/mastermind-issues/SKILL.md +111 -16
- package/.claude/skills/mastermind-liveness/SKILL.md +96 -26
- package/.claude/skills/mastermind-memory/SKILL.md +0 -316
- package/.claude/skills/mastermind-my-issues/SKILL.md +40 -8
- package/.claude/skills/mastermind-org/SKILL.md +1 -12
- package/.claude/skills/mastermind-plan/SKILL.md +7 -228
- package/.claude/skills/mastermind-plan-to-tasks/SKILL.md +132 -24
- package/.claude/skills/mastermind-protocol/SKILL.md +33 -22
- package/.claude/skills/mastermind-research/SKILL.md +0 -163
- package/.claude/skills/mastermind-review/SKILL.md +0 -228
- package/.claude/skills/mastermind-runorg/SKILL.md +22 -3
- package/.claude/skills/mastermind-skill-builder/SKILL.md +1 -1
- package/.claude/skills/mastermind-tasks/SKILL.md +5 -0
- package/.claude/skills/mastermind-techport/SKILL.md +1 -1
- package/.claude/skills/performance-analysis/SKILL.md +1 -1
- package/.claude/skills/verification-quality/SKILL.md +2 -3
- package/README.md +2 -2
- package/dist/src/commands/agent-exec.d.ts +2 -0
- package/dist/src/commands/agent-exec.d.ts.map +1 -1
- package/dist/src/commands/agent-exec.js +16 -0
- package/dist/src/commands/agent-exec.js.map +1 -1
- package/dist/src/commands/doc.js +2 -2
- package/dist/src/commands/doc.js.map +1 -1
- package/dist/src/commands/doctor-project-checks.d.ts.map +1 -1
- package/dist/src/commands/doctor-project-checks.js +20 -1
- package/dist/src/commands/doctor-project-checks.js.map +1 -1
- package/dist/src/commands/init-wizard.d.ts.map +1 -1
- package/dist/src/commands/init-wizard.js +6 -0
- package/dist/src/commands/init-wizard.js.map +1 -1
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/init.js +12 -2
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/monograph.d.ts.map +1 -1
- package/dist/src/commands/monograph.js +11 -4
- package/dist/src/commands/monograph.js.map +1 -1
- package/dist/src/commands/org-observe.d.ts +2 -0
- package/dist/src/commands/org-observe.d.ts.map +1 -1
- package/dist/src/commands/org-observe.js +115 -6
- package/dist/src/commands/org-observe.js.map +1 -1
- package/dist/src/commands/org.d.ts +26 -0
- package/dist/src/commands/org.d.ts.map +1 -1
- package/dist/src/commands/org.js +186 -28
- package/dist/src/commands/org.js.map +1 -1
- package/dist/src/init/codex-generator.d.ts +5 -0
- package/dist/src/init/codex-generator.d.ts.map +1 -1
- package/dist/src/init/codex-generator.js +12 -3
- package/dist/src/init/codex-generator.js.map +1 -1
- package/dist/src/init/executor.d.ts.map +1 -1
- package/dist/src/init/executor.js +10 -9
- package/dist/src/init/executor.js.map +1 -1
- package/dist/src/init/settings-generator.d.ts.map +1 -1
- package/dist/src/init/settings-generator.js +0 -5
- package/dist/src/init/settings-generator.js.map +1 -1
- package/dist/src/init/write-codex.d.ts.map +1 -1
- package/dist/src/init/write-codex.js +6 -5
- package/dist/src/init/write-codex.js.map +1 -1
- package/dist/src/knowledge/document-pipeline.d.ts +5 -0
- package/dist/src/knowledge/document-pipeline.d.ts.map +1 -1
- package/dist/src/knowledge/document-pipeline.js +32 -16
- package/dist/src/knowledge/document-pipeline.js.map +1 -1
- package/dist/src/mcp-tools/hooks-routing.d.ts +9 -0
- package/dist/src/mcp-tools/hooks-routing.d.ts.map +1 -1
- package/dist/src/mcp-tools/hooks-routing.js +12 -1
- package/dist/src/mcp-tools/hooks-routing.js.map +1 -1
- package/dist/src/mcp-tools/knowledge-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/knowledge-tools.js +105 -13
- package/dist/src/mcp-tools/knowledge-tools.js.map +1 -1
- package/dist/src/mcp-tools/memory-tools.d.ts +13 -0
- package/dist/src/mcp-tools/memory-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/memory-tools.js +257 -31
- package/dist/src/mcp-tools/memory-tools.js.map +1 -1
- package/dist/src/mcp-tools/monograph/health-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/monograph/health-tools.js +99 -42
- package/dist/src/mcp-tools/monograph/health-tools.js.map +1 -1
- package/dist/src/mcp-tools/monograph/impact-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/monograph/impact-tools.js +123 -51
- package/dist/src/mcp-tools/monograph/impact-tools.js.map +1 -1
- package/dist/src/mcp-tools/monograph/query-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/monograph/query-tools.js +113 -96
- package/dist/src/mcp-tools/monograph/query-tools.js.map +1 -1
- package/dist/src/mcp-tools/monograph/shared.d.ts +37 -4
- package/dist/src/mcp-tools/monograph/shared.d.ts.map +1 -1
- package/dist/src/mcp-tools/monograph/shared.js +75 -56
- package/dist/src/mcp-tools/monograph/shared.js.map +1 -1
- package/dist/src/memory/embedding-operations.d.ts.map +1 -1
- package/dist/src/memory/embedding-operations.js +9 -4
- package/dist/src/memory/embedding-operations.js.map +1 -1
- package/dist/src/memory/memory-bridge.d.ts +60 -1
- package/dist/src/memory/memory-bridge.d.ts.map +1 -1
- package/dist/src/memory/memory-bridge.js +185 -42
- package/dist/src/memory/memory-bridge.js.map +1 -1
- package/dist/src/memory/memory-kg.d.ts +495 -28
- package/dist/src/memory/memory-kg.d.ts.map +1 -1
- package/dist/src/memory/memory-kg.js +2186 -251
- package/dist/src/memory/memory-kg.js.map +1 -1
- package/dist/src/memory/query-router.d.ts +51 -0
- package/dist/src/memory/query-router.d.ts.map +1 -1
- package/dist/src/memory/query-router.js +38 -2
- package/dist/src/memory/query-router.js.map +1 -1
- package/dist/src/orgrt/agent-exec.d.ts +14 -0
- package/dist/src/orgrt/agent-exec.d.ts.map +1 -1
- package/dist/src/orgrt/agent-exec.js +88 -4
- package/dist/src/orgrt/agent-exec.js.map +1 -1
- package/dist/src/orgrt/agent-runner.d.ts +26 -1
- package/dist/src/orgrt/agent-runner.d.ts.map +1 -1
- package/dist/src/orgrt/agent-runner.js +73 -22
- package/dist/src/orgrt/agent-runner.js.map +1 -1
- package/dist/src/orgrt/antigravity-runner.d.ts +1 -1
- package/dist/src/orgrt/antigravity-runner.d.ts.map +1 -1
- package/dist/src/orgrt/antigravity-runner.js +36 -19
- package/dist/src/orgrt/antigravity-runner.js.map +1 -1
- package/dist/src/orgrt/approvals.d.ts +26 -2
- package/dist/src/orgrt/approvals.d.ts.map +1 -1
- package/dist/src/orgrt/approvals.js +67 -7
- package/dist/src/orgrt/approvals.js.map +1 -1
- package/dist/src/orgrt/broker.d.ts +21 -2
- package/dist/src/orgrt/broker.d.ts.map +1 -1
- package/dist/src/orgrt/broker.js +56 -8
- package/dist/src/orgrt/broker.js.map +1 -1
- package/dist/src/orgrt/bus.d.ts +8 -0
- package/dist/src/orgrt/bus.d.ts.map +1 -1
- package/dist/src/orgrt/bus.js +27 -0
- package/dist/src/orgrt/bus.js.map +1 -1
- package/dist/src/orgrt/checkpoint-ops.d.ts.map +1 -1
- package/dist/src/orgrt/checkpoint-ops.js +15 -5
- package/dist/src/orgrt/checkpoint-ops.js.map +1 -1
- package/dist/src/orgrt/checkpoint.d.ts +42 -4
- package/dist/src/orgrt/checkpoint.d.ts.map +1 -1
- package/dist/src/orgrt/checkpoint.js +75 -4
- package/dist/src/orgrt/checkpoint.js.map +1 -1
- package/dist/src/orgrt/codex-runner.d.ts +1 -1
- package/dist/src/orgrt/codex-runner.d.ts.map +1 -1
- package/dist/src/orgrt/codex-runner.js +50 -23
- package/dist/src/orgrt/codex-runner.js.map +1 -1
- package/dist/src/orgrt/copilot-runner.d.ts +24 -2
- package/dist/src/orgrt/copilot-runner.d.ts.map +1 -1
- package/dist/src/orgrt/copilot-runner.js +257 -157
- package/dist/src/orgrt/copilot-runner.js.map +1 -1
- package/dist/src/orgrt/cross-org.d.ts +10 -3
- package/dist/src/orgrt/cross-org.d.ts.map +1 -1
- package/dist/src/orgrt/cross-org.js +225 -10
- package/dist/src/orgrt/cross-org.js.map +1 -1
- package/dist/src/orgrt/crush-runner.d.ts +22 -2
- package/dist/src/orgrt/crush-runner.d.ts.map +1 -1
- package/dist/src/orgrt/crush-runner.js +227 -120
- package/dist/src/orgrt/crush-runner.js.map +1 -1
- package/dist/src/orgrt/daemon.d.ts +77 -7
- package/dist/src/orgrt/daemon.d.ts.map +1 -1
- package/dist/src/orgrt/daemon.js +989 -385
- package/dist/src/orgrt/daemon.js.map +1 -1
- package/dist/src/orgrt/decisions.d.ts +2 -2
- package/dist/src/orgrt/decisions.d.ts.map +1 -1
- package/dist/src/orgrt/decisions.js +90 -18
- package/dist/src/orgrt/decisions.js.map +1 -1
- package/dist/src/orgrt/grok-runner.d.ts +29 -3
- package/dist/src/orgrt/grok-runner.d.ts.map +1 -1
- package/dist/src/orgrt/grok-runner.js +286 -150
- package/dist/src/orgrt/grok-runner.js.map +1 -1
- package/dist/src/orgrt/kimicode-runner.d.ts +5 -5
- package/dist/src/orgrt/kimicode-runner.d.ts.map +1 -1
- package/dist/src/orgrt/kimicode-runner.js +53 -32
- package/dist/src/orgrt/kimicode-runner.js.map +1 -1
- package/dist/src/orgrt/mailbox.d.ts +15 -0
- package/dist/src/orgrt/mailbox.d.ts.map +1 -1
- package/dist/src/orgrt/mailbox.js +29 -1
- package/dist/src/orgrt/mailbox.js.map +1 -1
- package/dist/src/orgrt/migrate.d.ts.map +1 -1
- package/dist/src/orgrt/migrate.js +8 -5
- package/dist/src/orgrt/migrate.js.map +1 -1
- package/dist/src/orgrt/opencode-runner.d.ts +1 -1
- package/dist/src/orgrt/opencode-runner.d.ts.map +1 -1
- package/dist/src/orgrt/opencode-runner.js +29 -3
- package/dist/src/orgrt/opencode-runner.js.map +1 -1
- package/dist/src/orgrt/org-memory.d.ts +19 -3
- package/dist/src/orgrt/org-memory.d.ts.map +1 -1
- package/dist/src/orgrt/org-memory.js +110 -38
- package/dist/src/orgrt/org-memory.js.map +1 -1
- package/dist/src/orgrt/pi-rpc-runner.d.ts +3 -1
- package/dist/src/orgrt/pi-rpc-runner.d.ts.map +1 -1
- package/dist/src/orgrt/pi-rpc-runner.js +35 -3
- package/dist/src/orgrt/pi-rpc-runner.js.map +1 -1
- package/dist/src/orgrt/pi-runner.d.ts +25 -2
- package/dist/src/orgrt/pi-runner.d.ts.map +1 -1
- package/dist/src/orgrt/pi-runner.js +271 -152
- package/dist/src/orgrt/pi-runner.js.map +1 -1
- package/dist/src/orgrt/policy.d.ts +1 -0
- package/dist/src/orgrt/policy.d.ts.map +1 -1
- package/dist/src/orgrt/policy.js +199 -39
- package/dist/src/orgrt/policy.js.map +1 -1
- package/dist/src/orgrt/provider.d.ts +4 -0
- package/dist/src/orgrt/provider.d.ts.map +1 -1
- package/dist/src/orgrt/provider.js +16 -0
- package/dist/src/orgrt/provider.js.map +1 -1
- package/dist/src/orgrt/qwen-rpc-runner.d.ts +3 -1
- package/dist/src/orgrt/qwen-rpc-runner.d.ts.map +1 -1
- package/dist/src/orgrt/qwen-rpc-runner.js +35 -3
- package/dist/src/orgrt/qwen-rpc-runner.js.map +1 -1
- package/dist/src/orgrt/qwen-runner.d.ts +30 -3
- package/dist/src/orgrt/qwen-runner.d.ts.map +1 -1
- package/dist/src/orgrt/qwen-runner.js +282 -142
- package/dist/src/orgrt/qwen-runner.js.map +1 -1
- package/dist/src/orgrt/role-slot.d.ts +88 -0
- package/dist/src/orgrt/role-slot.d.ts.map +1 -0
- package/dist/src/orgrt/role-slot.js +133 -0
- package/dist/src/orgrt/role-slot.js.map +1 -0
- package/dist/src/orgrt/runtime-options.d.ts +17 -0
- package/dist/src/orgrt/runtime-options.d.ts.map +1 -0
- package/dist/src/orgrt/runtime-options.js +32 -0
- package/dist/src/orgrt/runtime-options.js.map +1 -0
- package/dist/src/orgrt/scheduler-integration.d.ts +11 -0
- package/dist/src/orgrt/scheduler-integration.d.ts.map +1 -1
- package/dist/src/orgrt/scheduler-integration.js +75 -17
- package/dist/src/orgrt/scheduler-integration.js.map +1 -1
- package/dist/src/orgrt/scheduler.d.ts +4 -0
- package/dist/src/orgrt/scheduler.d.ts.map +1 -1
- package/dist/src/orgrt/scheduler.js +7 -1
- package/dist/src/orgrt/scheduler.js.map +1 -1
- package/dist/src/orgrt/server.d.ts +8 -3
- package/dist/src/orgrt/server.d.ts.map +1 -1
- package/dist/src/orgrt/server.js +48 -13
- package/dist/src/orgrt/server.js.map +1 -1
- package/dist/src/orgrt/session.d.ts +26 -2
- package/dist/src/orgrt/session.d.ts.map +1 -1
- package/dist/src/orgrt/session.js +99 -5
- package/dist/src/orgrt/session.js.map +1 -1
- package/dist/src/orgrt/task-dag.d.ts +5 -0
- package/dist/src/orgrt/task-dag.d.ts.map +1 -1
- package/dist/src/orgrt/task-dag.js +41 -0
- package/dist/src/orgrt/task-dag.js.map +1 -1
- package/dist/src/orgrt/test-loop.js +2 -2
- package/dist/src/orgrt/test-loop.js.map +1 -1
- package/dist/src/orgrt/types.d.ts +14 -2
- package/dist/src/orgrt/types.d.ts.map +1 -1
- package/dist/src/orgrt/types.js +15 -1
- package/dist/src/orgrt/types.js.map +1 -1
- package/dist/src/orgrt/vercel-runner.d.ts.map +1 -1
- package/dist/src/orgrt/vercel-runner.js +4 -0
- package/dist/src/orgrt/vercel-runner.js.map +1 -1
- package/dist/src/ui/routes-org.mjs +27 -7
- package/dist/src/ui/server.mjs +82 -48
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/dist/src/ui/data/mastermind-sessions.json +0 -1
package/dist/src/commands/org.js
CHANGED
|
@@ -100,7 +100,54 @@ function liveServeDaemonPid(cwd) {
|
|
|
100
100
|
return null;
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
+
/** Mutual-exclusion check for `org serve` startup.
|
|
104
|
+
*
|
|
105
|
+
* Two `org serve` processes started against the same project root have zero
|
|
106
|
+
* visibility into each other — each builds its own in-memory `OrgDaemon` and
|
|
107
|
+
* independently decides which orgs are "due now", so both can call
|
|
108
|
+
* `daemon.startOrg(name)` for the same org and have both processes write to
|
|
109
|
+
* the same on-disk state (runtime.json, decisions.jsonl, history.jsonl,
|
|
110
|
+
* .mail/) at once. `liveServeDaemonPid` already knows how to read this
|
|
111
|
+
* project's serve-heartbeat.json and tell a live daemon's heartbeat from a
|
|
112
|
+
* stale one (dead pid, or aged past a few missed 30s beats) — reused here
|
|
113
|
+
* as the actual pidfile lock, rather than inventing a second file, since it
|
|
114
|
+
* already IS a pidfile (pid + timestamp, written at startup and every
|
|
115
|
+
* heartbeat, removed on clean shutdown by `daemon.clearHeartbeat()`).
|
|
116
|
+
*
|
|
117
|
+
* Call this before the daemon/server/scheduler are constructed, so a
|
|
118
|
+
* refusal never opens a port, binds a broker lease, or touches any org's
|
|
119
|
+
* state. */
|
|
120
|
+
export function checkServeLock(cwd) {
|
|
121
|
+
const owner = liveServeDaemonPid(cwd);
|
|
122
|
+
if (owner != null)
|
|
123
|
+
return { ok: false, pid: owner };
|
|
124
|
+
// liveServeDaemonPid() has already ruled out a live owner — any heartbeat
|
|
125
|
+
// file still on disk here is stale (dead pid, or a SIGKILLed daemon that
|
|
126
|
+
// never reached clearHeartbeat()). Remove it so it can't be misread by
|
|
127
|
+
// `org run`/`org status` before this daemon's own writeHeartbeat() lands.
|
|
128
|
+
const heartbeatPath = join(cwd, '.monomind', 'serve-heartbeat.json');
|
|
129
|
+
const staleHeartbeatRemoved = existsSync(heartbeatPath);
|
|
130
|
+
if (staleHeartbeatRemoved)
|
|
131
|
+
rmSync(heartbeatPath, { force: true });
|
|
132
|
+
return { ok: true, staleHeartbeatRemoved };
|
|
133
|
+
}
|
|
103
134
|
const runAction = async (ctx) => {
|
|
135
|
+
// Org runs skip local embeddings entirely — on some machines
|
|
136
|
+
// @huggingface/transformers' native ONNX runtime crashes the whole
|
|
137
|
+
// process (a libc++abi terminate, not a catchable JS error) the moment
|
|
138
|
+
// any memory/KG lookup tries to load its model. A crashed unattended org
|
|
139
|
+
// run is much worse than one that falls back to keyword-only memory
|
|
140
|
+
// search — see the matching guards in memory-bridge.ts/embedding-operations.ts.
|
|
141
|
+
process.env.MONOMIND_NO_LOCAL_EMBEDDINGS = '1';
|
|
142
|
+
// The embedding-model crash above has a sibling: loadReranker() in
|
|
143
|
+
// memory-bridge.ts loads a SEPARATE cross-encoder model
|
|
144
|
+
// (cross-encoder/ettin-reranker-32m-v1, its own tokenizer architecture)
|
|
145
|
+
// for search-result reranking, independent of the embedder guard above —
|
|
146
|
+
// reranking runs on (query, passage) text pairs directly, so it can
|
|
147
|
+
// still fire and hit the same native crash even with embeddings off.
|
|
148
|
+
// MONOMIND_RERANKER=0 is an existing, already-wired guard (see
|
|
149
|
+
// loadReranker's own early-return) — just never set for org runs before.
|
|
150
|
+
process.env.MONOMIND_RERANKER = '0';
|
|
104
151
|
if (!ctx.args[0])
|
|
105
152
|
return { success: false, message: 'org name required: monomind org run <name> [--task "..."]' };
|
|
106
153
|
const validated = validateOrgName(ctx.args[0]);
|
|
@@ -136,7 +183,11 @@ const runAction = async (ctx) => {
|
|
|
136
183
|
const glossary = await (async () => {
|
|
137
184
|
try {
|
|
138
185
|
const kg = await import('../memory/memory-kg.js');
|
|
139
|
-
|
|
186
|
+
const { orgKgScope } = await import('../orgrt/org-memory.js');
|
|
187
|
+
return await kg.kgGlossary({
|
|
188
|
+
dbPath: join(process.cwd(), '.monomind', 'org-memory'),
|
|
189
|
+
scope: orgKgScope(name),
|
|
190
|
+
});
|
|
140
191
|
}
|
|
141
192
|
catch {
|
|
142
193
|
return [];
|
|
@@ -327,7 +378,7 @@ const runAction = async (ctx) => {
|
|
|
327
378
|
let srv;
|
|
328
379
|
if (crossProcess) {
|
|
329
380
|
srv = await startOrgServer(daemon, 0);
|
|
330
|
-
daemon.setInboxUrl(`http://127.0.0.1:${srv.port}`, srv.
|
|
381
|
+
daemon.setInboxUrl(`http://127.0.0.1:${srv.port}`, srv.operatorCredential);
|
|
331
382
|
}
|
|
332
383
|
let running;
|
|
333
384
|
try {
|
|
@@ -988,21 +1039,58 @@ WantedBy=default.target
|
|
|
988
1039
|
return { success: true, message: `${format} unit emitted` };
|
|
989
1040
|
};
|
|
990
1041
|
const serveAction = async (ctx) => {
|
|
1042
|
+
// Mutual exclusion: refuse to start a second `org serve` for this project
|
|
1043
|
+
// root. Checked before anything else so a refusal never opens a port,
|
|
1044
|
+
// registers a broker lease, or starts a scheduled org that a live daemon
|
|
1045
|
+
// is already running — see checkServeLock's header for the failure mode
|
|
1046
|
+
// this prevents.
|
|
1047
|
+
const lock = checkServeLock(ctx.cwd);
|
|
1048
|
+
if (!lock.ok) {
|
|
1049
|
+
log(output.error(`org serve: another daemon (pid ${lock.pid}) is already running for this project root.`));
|
|
1050
|
+
log(output.info(` Check what it's doing with: monomind org status`));
|
|
1051
|
+
log(output.info(` Stop it first (Ctrl-C in its terminal, or "kill ${lock.pid}"), then retry.`));
|
|
1052
|
+
return { success: false, message: `org serve already running (pid ${lock.pid})` };
|
|
1053
|
+
}
|
|
1054
|
+
if (lock.staleHeartbeatRemoved) {
|
|
1055
|
+
log(output.warning('org serve: cleaned up a stale heartbeat left by a previous daemon that did not shut down cleanly.'));
|
|
1056
|
+
}
|
|
1057
|
+
// See the matching comment in runAction — same rationale, same guard.
|
|
1058
|
+
process.env.MONOMIND_NO_LOCAL_EMBEDDINGS = '1';
|
|
1059
|
+
// The embedding-model crash above has a sibling: loadReranker() in
|
|
1060
|
+
// memory-bridge.ts loads a SEPARATE cross-encoder model
|
|
1061
|
+
// (cross-encoder/ettin-reranker-32m-v1, its own tokenizer architecture)
|
|
1062
|
+
// for search-result reranking, independent of the embedder guard above —
|
|
1063
|
+
// reranking runs on (query, passage) text pairs directly, so it can
|
|
1064
|
+
// still fire and hit the same native crash even with embeddings off.
|
|
1065
|
+
// MONOMIND_RERANKER=0 is an existing, already-wired guard (see
|
|
1066
|
+
// loadReranker's own early-return) — just never set for org runs before.
|
|
1067
|
+
process.env.MONOMIND_RERANKER = '0';
|
|
991
1068
|
const crossProcess = ctx.flags.crossProcess !== false;
|
|
992
1069
|
const daemon = new OrgDaemon(ctx.cwd, { crossProcess });
|
|
993
1070
|
let srv;
|
|
994
1071
|
if (crossProcess) {
|
|
995
1072
|
srv = await startOrgServer(daemon, 0);
|
|
996
|
-
daemon.setInboxUrl(`http://127.0.0.1:${srv.port}`, srv.
|
|
1073
|
+
daemon.setInboxUrl(`http://127.0.0.1:${srv.port}`, srv.operatorCredential);
|
|
997
1074
|
}
|
|
998
1075
|
// Crash handlers: log the reason and persist crashed state so `org status`
|
|
999
|
-
// shows what happened instead of a silent "pid is gone".
|
|
1076
|
+
// shows what happened instead of a silent "pid is gone". A truly unknown
|
|
1077
|
+
// uncaught exception's blast radius can't always be attributed to one org,
|
|
1078
|
+
// so the whole process still exits (the safety-first default) — but naming
|
|
1079
|
+
// which orgs were in flight at the moment it fired at least tells the
|
|
1080
|
+
// operator the blast radius they actually hit, instead of leaving them to
|
|
1081
|
+
// guess from an error with no org context.
|
|
1000
1082
|
const crashExit = (label, err) => {
|
|
1001
1083
|
try {
|
|
1002
|
-
|
|
1084
|
+
const running = daemon.listRunning();
|
|
1085
|
+
console.error(`[org serve] ${label}:`, err, running.length ? `— orgs in flight: ${running.join(', ')}` : '— no orgs were running');
|
|
1003
1086
|
}
|
|
1004
1087
|
catch {
|
|
1005
|
-
|
|
1088
|
+
try {
|
|
1089
|
+
console.error(`[org serve] ${label}:`, err);
|
|
1090
|
+
}
|
|
1091
|
+
catch {
|
|
1092
|
+
/* stderr gone */
|
|
1093
|
+
}
|
|
1006
1094
|
}
|
|
1007
1095
|
daemon.persistCrashStateAll(`${label}: ${err instanceof Error ? err.message : String(err)}`);
|
|
1008
1096
|
daemon.clearHeartbeat();
|
|
@@ -1180,16 +1268,30 @@ const serveAction = async (ctx) => {
|
|
|
1180
1268
|
}
|
|
1181
1269
|
}
|
|
1182
1270
|
}
|
|
1271
|
+
// Each poll pass already wraps its own per-org daemon calls in try/catch,
|
|
1272
|
+
// but a synchronous throw from something ahead of those (e.g.
|
|
1273
|
+
// daemon.listRunning(), listOrgConfigFiles()) still rejects the async
|
|
1274
|
+
// function itself. `void`-ing that call, as before, discards the promise
|
|
1275
|
+
// without observing a rejection — which becomes an unhandled rejection at
|
|
1276
|
+
// the process level and takes down every other org's in-flight run via
|
|
1277
|
+
// crashExit, even though the failure was local to one poll pass. .catch()
|
|
1278
|
+
// keeps it a per-pass, logged failure instead.
|
|
1183
1279
|
const stopPoll = setInterval(() => {
|
|
1184
|
-
|
|
1280
|
+
pollStopfiles(ctx.cwd, daemon).catch((err) => {
|
|
1281
|
+
console.error('[org serve] stopfile poll failed:', err);
|
|
1282
|
+
});
|
|
1185
1283
|
}, 2000);
|
|
1186
1284
|
stopPoll.unref?.();
|
|
1187
1285
|
const runPoll = setInterval(() => {
|
|
1188
|
-
|
|
1286
|
+
pollRunfiles(ctx.cwd, daemon).catch((err) => {
|
|
1287
|
+
console.error('[org serve] runfile poll failed:', err);
|
|
1288
|
+
});
|
|
1189
1289
|
}, 2000);
|
|
1190
1290
|
runPoll.unref?.();
|
|
1191
1291
|
const reloadPoll = setInterval(() => {
|
|
1192
|
-
|
|
1292
|
+
pollReloadfiles(ctx.cwd, daemon).catch((err) => {
|
|
1293
|
+
console.error('[org serve] reloadfile poll failed:', err);
|
|
1294
|
+
});
|
|
1193
1295
|
}, 2000);
|
|
1194
1296
|
reloadPoll.unref?.();
|
|
1195
1297
|
await new Promise((r) => {
|
|
@@ -1771,7 +1873,7 @@ export const orgCommand = {
|
|
|
1771
1873
|
},
|
|
1772
1874
|
{
|
|
1773
1875
|
name: 'memory',
|
|
1774
|
-
description: "Inspect an org's cross-run memory and knowledge graph (stats | search <query> | rules | rollback <run-ref>)",
|
|
1876
|
+
description: "Inspect an org's cross-run memory and knowledge graph (stats | search <query> | rules | rollback <run-ref> | promote <run-ref>)",
|
|
1775
1877
|
examples: [
|
|
1776
1878
|
{ command: 'monomind org memory growth stats', description: 'KG size and namespaces' },
|
|
1777
1879
|
{
|
|
@@ -1780,7 +1882,11 @@ export const orgCommand = {
|
|
|
1780
1882
|
},
|
|
1781
1883
|
{
|
|
1782
1884
|
command: 'monomind org memory growth rollback run:m4x2',
|
|
1783
|
-
description:
|
|
1885
|
+
description: "Withdraw one run's support from this org's KG",
|
|
1886
|
+
},
|
|
1887
|
+
{
|
|
1888
|
+
command: 'monomind org memory growth promote run:m4x2',
|
|
1889
|
+
description: "Share one run's claims with project-wide knowledge",
|
|
1784
1890
|
},
|
|
1785
1891
|
],
|
|
1786
1892
|
action: async (ctx) => {
|
|
@@ -1789,31 +1895,47 @@ export const orgCommand = {
|
|
|
1789
1895
|
return v.result;
|
|
1790
1896
|
const sub = String(ctx.args[1] ?? 'stats');
|
|
1791
1897
|
const { join } = await import('node:path');
|
|
1792
|
-
const
|
|
1898
|
+
const cwd = ctx.cwd || process.cwd();
|
|
1899
|
+
const dbPath = join(cwd, '.monomind', 'org-memory');
|
|
1793
1900
|
const kg = await import('../memory/memory-kg.js');
|
|
1794
1901
|
const bridge = await import('../memory/memory-bridge.js');
|
|
1902
|
+
const { orgKgScope, orgMemoryNamespace } = await import('../orgrt/org-memory.js');
|
|
1903
|
+
// Every KG operation below is scoped to the requested org, so the org
|
|
1904
|
+
// name in the output describes what was actually read, not just what
|
|
1905
|
+
// was asked for. Reads of the shared store are unchanged.
|
|
1906
|
+
const scope = orgKgScope(v.name);
|
|
1907
|
+
const kgNs = kg.kgNamespaces(scope);
|
|
1908
|
+
// Flat org memory is namespaced by the org DEFINITION, not by name —
|
|
1909
|
+
// resolve it the way the runtime writes it (B4), so a configured
|
|
1910
|
+
// `memory_namespace` is searched instead of a guessed `org:<name>`.
|
|
1911
|
+
const defPath = join(cwd, ORG_DIR, `${v.name}.json`);
|
|
1912
|
+
const flatNs = existsSync(defPath)
|
|
1913
|
+
? orgMemoryNamespace(v.name, OrgDefSchema.parse(JSON.parse(readFileSync(defPath, 'utf8'))))
|
|
1914
|
+
: `org:${v.name}`;
|
|
1795
1915
|
try {
|
|
1796
1916
|
if (sub === 'stats') {
|
|
1797
1917
|
const [stats, glossary, backend] = await Promise.all([
|
|
1798
|
-
kg.kgStats({ dbPath }),
|
|
1799
|
-
kg.kgGlossary({ dbPath, limit: 15 }),
|
|
1918
|
+
kg.kgStats({ dbPath, scope }),
|
|
1919
|
+
kg.kgGlossary({ dbPath, limit: 15, scope }),
|
|
1800
1920
|
bridge.bridgeGetBackendStats(dbPath),
|
|
1801
1921
|
]);
|
|
1922
|
+
// The backend reports every namespace in the SHARED store, so
|
|
1923
|
+
// listing it raw put other orgs' namespaces (and their counts)
|
|
1924
|
+
// under this org's name. Keep only what this org owns.
|
|
1925
|
+
// Spread kgNs rather than listing namespaces: the identity work
|
|
1926
|
+
// added `names` (the entity name index), and a hand-written list
|
|
1927
|
+
// silently omits any namespace added later, hiding rows this org
|
|
1928
|
+
// does own.
|
|
1929
|
+
const owned = new Set([...Object.values(kgNs), flatNs]);
|
|
1930
|
+
const byNs = Object.fromEntries(Object.entries(backend?.entriesByNamespace ?? {}).filter(([ns]) => owned.has(ns) || ns.startsWith(`agent:${flatNs}:`)));
|
|
1802
1931
|
if (ctx.flags.format === 'json') {
|
|
1803
|
-
const payload = {
|
|
1804
|
-
v: 1,
|
|
1805
|
-
org: v.name,
|
|
1806
|
-
...stats,
|
|
1807
|
-
glossary,
|
|
1808
|
-
namespaces: backend?.entriesByNamespace ?? {},
|
|
1809
|
-
};
|
|
1932
|
+
const payload = { v: 1, org: v.name, ...stats, glossary, namespaces: byNs };
|
|
1810
1933
|
process.stdout.write(`${JSON.stringify(payload)}\n`);
|
|
1811
1934
|
return { success: true, data: payload };
|
|
1812
1935
|
}
|
|
1813
1936
|
log(output.info(`Knowledge graph: ${stats.nodes} entities, ${stats.edges} relations, ${stats.rules} rules`));
|
|
1814
1937
|
if (glossary.length)
|
|
1815
1938
|
log(output.info(`Top entities: ${glossary.join(', ')}`));
|
|
1816
|
-
const byNs = backend?.entriesByNamespace ?? {};
|
|
1817
1939
|
for (const [ns, count] of Object.entries(byNs))
|
|
1818
1940
|
log(output.info(` ${ns}: ${count} entries`));
|
|
1819
1941
|
return {
|
|
@@ -1829,11 +1951,11 @@ export const orgCommand = {
|
|
|
1829
1951
|
const [mem, graph] = await Promise.all([
|
|
1830
1952
|
bridge.bridgeSearchEntries({
|
|
1831
1953
|
query: q,
|
|
1832
|
-
namespace:
|
|
1954
|
+
namespace: flatNs,
|
|
1833
1955
|
limit: 5,
|
|
1834
1956
|
dbPath,
|
|
1835
1957
|
}),
|
|
1836
|
-
kg.kgSearch({ query: q, dbPath, limit: 8 }),
|
|
1958
|
+
kg.kgSearch({ query: q, dbPath, limit: 8, scope }),
|
|
1837
1959
|
]);
|
|
1838
1960
|
if (ctx.flags.format === 'json') {
|
|
1839
1961
|
const payload = {
|
|
@@ -1857,7 +1979,7 @@ export const orgCommand = {
|
|
|
1857
1979
|
};
|
|
1858
1980
|
}
|
|
1859
1981
|
if (sub === 'rules') {
|
|
1860
|
-
const rules = await kg.kgListRules({ dbPath, limit: 50 });
|
|
1982
|
+
const rules = await kg.kgListRules({ dbPath, limit: 50, scope });
|
|
1861
1983
|
if (ctx.flags.format === 'json') {
|
|
1862
1984
|
const payload = { v: 1, org: v.name, items: rules };
|
|
1863
1985
|
process.stdout.write(`${JSON.stringify(payload)}\n`);
|
|
@@ -1874,18 +1996,39 @@ export const orgCommand = {
|
|
|
1874
1996
|
success: false,
|
|
1875
1997
|
message: 'usage: org memory <org> rollback <origin-ref> (e.g. run:m4x2)',
|
|
1876
1998
|
};
|
|
1877
|
-
|
|
1999
|
+
// Scoped: the ref is resolved inside this org's namespaces and
|
|
2000
|
+
// origin space, so the org name in the command is an ownership
|
|
2001
|
+
// restriction rather than a label on an unfiltered rollback.
|
|
2002
|
+
const res = await kg.kgRollback({ originRef: ref, scope, dbPath });
|
|
1878
2003
|
if (ctx.flags.format === 'json') {
|
|
1879
2004
|
const payload = { v: 1, org: v.name, ref, ...res };
|
|
1880
2005
|
process.stdout.write(`${JSON.stringify(payload)}\n`);
|
|
1881
2006
|
return { success: res.success, data: payload };
|
|
1882
2007
|
}
|
|
1883
|
-
log(output.info(`Rolled back ${ref}: ${res.deleted} deleted, ${res.retained} retained (shared with other origins)`));
|
|
2008
|
+
log(output.info(`Rolled back ${ref} for org ${v.name}: ${res.deleted} deleted, ${res.retained} retained (shared with other origins)`));
|
|
1884
2009
|
return { success: res.success, message: `rollback ${ref}`, data: res };
|
|
1885
2010
|
}
|
|
2011
|
+
if (sub === 'promote') {
|
|
2012
|
+
const ref = ctx.args[2];
|
|
2013
|
+
if (!ref)
|
|
2014
|
+
return {
|
|
2015
|
+
success: false,
|
|
2016
|
+
message: 'usage: org memory <org> promote <origin-ref> (e.g. run:m4x2)',
|
|
2017
|
+
};
|
|
2018
|
+
const res = await kg.kgPromote({ originRef: ref, from: scope, dbPath });
|
|
2019
|
+
if (ctx.flags.format === 'json') {
|
|
2020
|
+
const payload = { v: 1, org: v.name, ref, ...res };
|
|
2021
|
+
process.stdout.write(`${JSON.stringify(payload)}\n`);
|
|
2022
|
+
return { success: res.success, data: payload };
|
|
2023
|
+
}
|
|
2024
|
+
log(output.info(res.success
|
|
2025
|
+
? `Promoted ${ref} from org ${v.name} to project-shared knowledge: ${res.nodes} entities, ${res.edges} relations, ${res.rules} rules. Withdraw with origin ref ${res.promotedAs}.`
|
|
2026
|
+
: `Promotion of ${ref} failed: ${res.error ?? 'unknown error'}`));
|
|
2027
|
+
return { success: res.success, message: `promote ${ref}`, data: res };
|
|
2028
|
+
}
|
|
1886
2029
|
return {
|
|
1887
2030
|
success: false,
|
|
1888
|
-
message: `unknown subcommand "${sub}" — use stats | search | rules | rollback`,
|
|
2031
|
+
message: `unknown subcommand "${sub}" — use stats | search | rules | rollback | promote`,
|
|
1889
2032
|
};
|
|
1890
2033
|
}
|
|
1891
2034
|
finally {
|
|
@@ -1979,6 +2122,21 @@ export const orgCommand = {
|
|
|
1979
2122
|
return questionsAction(ctx, v.name);
|
|
1980
2123
|
},
|
|
1981
2124
|
},
|
|
2125
|
+
{
|
|
2126
|
+
name: 'approvals',
|
|
2127
|
+
description: "List pending tool/action approval requests from an org's agents",
|
|
2128
|
+
options: [{ name: 'all', description: 'Include resolved approvals', type: 'boolean' }],
|
|
2129
|
+
examples: [
|
|
2130
|
+
{ command: 'monomind org approvals growth', description: 'Show pending approvals' },
|
|
2131
|
+
],
|
|
2132
|
+
action: async (ctx) => {
|
|
2133
|
+
const v = validateOrgName(ctx.args[0]);
|
|
2134
|
+
if (!v.ok)
|
|
2135
|
+
return v.result;
|
|
2136
|
+
const { approvalsAction } = await import('./org-observe.js');
|
|
2137
|
+
return approvalsAction(ctx, v.name);
|
|
2138
|
+
},
|
|
2139
|
+
},
|
|
1982
2140
|
{
|
|
1983
2141
|
name: 'answer',
|
|
1984
2142
|
description: 'Answer a pending ask_human question (live if the org is running, queued otherwise)',
|