@noesis-brain/mcp-server 2.1.0 → 2.1.1
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/dist/agent/runner.d.ts +4 -0
- package/dist/agent/runner.d.ts.map +1 -1
- package/dist/agent/runner.js +99 -11
- package/dist/agent/runner.js.map +1 -1
- package/dist/tools/backlog.d.ts.map +1 -1
- package/dist/tools/backlog.js +11 -7
- package/dist/tools/backlog.js.map +1 -1
- package/dist/tools/index.d.ts +40 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +96 -70
- package/dist/tools/index.js.map +1 -1
- package/package.json +1 -1
- package/scripts/noesis-capture-watcher.mjs +51 -5
package/dist/agent/runner.d.ts
CHANGED
|
@@ -20,6 +20,10 @@ export interface AgentConfig {
|
|
|
20
20
|
fake: boolean;
|
|
21
21
|
}
|
|
22
22
|
export declare function resolveAgentConfig(): AgentConfig;
|
|
23
|
+
/** Drop anything the server asked for that is not on the read-only allowlist. */
|
|
24
|
+
export declare function clampAllowedTools(raw: unknown): string[];
|
|
25
|
+
/** Clamp the server-requested turn budget into a sane range. */
|
|
26
|
+
export declare function clampMaxTurns(raw: unknown): number;
|
|
23
27
|
/** Run the daemon loop until aborted. */
|
|
24
28
|
export declare function runAgentDaemon(cfg: AgentConfig, signal?: AbortSignal): Promise<void>;
|
|
25
29
|
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/agent/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/agent/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AASH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,wBAAgB,kBAAkB,IAAI,WAAW,CAUhD;AAoCD,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAMxD;AAED,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAIlD;AA2MD,yCAAyC;AACzC,wBAAsB,cAAc,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAU1F"}
|
package/dist/agent/runner.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* FOOTGUN GUARD: if ANTHROPIC_API_KEY is set, the Agent SDK bills the metered API
|
|
14
14
|
* instead of the subscription — so we delete it (and warn) before any query().
|
|
15
15
|
*/
|
|
16
|
+
import { fileURLToPath } from 'node:url';
|
|
16
17
|
const POLL_INTERVAL_MS = 2000; // idle poll cadence
|
|
17
18
|
const CHUNK_FLUSH_MS = 500; // batch streamed deltas before POST /events
|
|
18
19
|
const KEEPALIVE_MS = 30_000; // hold the lease during quiet stretches (< server's 120s stale)
|
|
@@ -30,6 +31,55 @@ export function resolveAgentConfig() {
|
|
|
30
31
|
concurrency = MAX_CONCURRENCY;
|
|
31
32
|
return { apiBaseUrl, apiToken, concurrency, fake: process.env.NOESIS_AGENT_FAKE === '1' };
|
|
32
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* The ONLY tools the server may pre-approve — a literal allowlist, not a namespace
|
|
36
|
+
* prefix. Everything named here runs under this machine's ambient Claude Code login
|
|
37
|
+
* with no further prompt, so the boundary must be the exact set, not `mcp__noesis__*`:
|
|
38
|
+
* that namespace also contains mutating tools (`pull_notes` writes to an arbitrary
|
|
39
|
+
* local path with an overwrite flag, `add_root` + `sync_notes` ingest local files),
|
|
40
|
+
* which would hand a compromised server a filesystem primitive it otherwise lacks.
|
|
41
|
+
* Read-only Noesis lookups only.
|
|
42
|
+
*/
|
|
43
|
+
const ALLOWED_TOOLS = new Set([
|
|
44
|
+
'mcp__noesis__search_notes',
|
|
45
|
+
'mcp__noesis__search_semantic',
|
|
46
|
+
'mcp__noesis__get_note',
|
|
47
|
+
'mcp__noesis__list_notes',
|
|
48
|
+
]);
|
|
49
|
+
/** Highest turn budget a server may request; a tool loop otherwise burns the subscription. */
|
|
50
|
+
const MAX_TURNS_CEILING = 12;
|
|
51
|
+
/** Drop anything the server asked for that is not on the read-only allowlist. */
|
|
52
|
+
export function clampAllowedTools(raw) {
|
|
53
|
+
if (!Array.isArray(raw))
|
|
54
|
+
return [];
|
|
55
|
+
const kept = raw.filter((t) => typeof t === 'string' && ALLOWED_TOOLS.has(t));
|
|
56
|
+
const dropped = raw.length - kept.length;
|
|
57
|
+
if (dropped > 0)
|
|
58
|
+
console.error(`[noesis-agent] dropped ${dropped} tool name(s) not on the read-only allowlist`);
|
|
59
|
+
return kept;
|
|
60
|
+
}
|
|
61
|
+
/** Clamp the server-requested turn budget into a sane range. */
|
|
62
|
+
export function clampMaxTurns(raw) {
|
|
63
|
+
const n = typeof raw === 'number' && Number.isFinite(raw) ? Math.floor(raw) : 1;
|
|
64
|
+
if (n < 1)
|
|
65
|
+
return 1;
|
|
66
|
+
return Math.min(n, MAX_TURNS_CEILING);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* MCP server config for the tools above, built from the daemon's OWN config —
|
|
70
|
+
* deliberately never from the job payload, so the server cannot point the model
|
|
71
|
+
* at a different endpoint or hand it a different token.
|
|
72
|
+
*/
|
|
73
|
+
function noesisMcpServers(cfg) {
|
|
74
|
+
const entry = fileURLToPath(new URL('../index.js', import.meta.url));
|
|
75
|
+
return {
|
|
76
|
+
noesis: {
|
|
77
|
+
command: process.execPath,
|
|
78
|
+
args: [entry],
|
|
79
|
+
env: { ...process.env, NOESIS_API_TOKEN: cfg.apiToken, NOESIS_API_URL: cfg.apiBaseUrl },
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
33
83
|
async function api(cfg, path, body) {
|
|
34
84
|
return fetch(`${cfg.apiBaseUrl}${path}`, {
|
|
35
85
|
method: 'POST',
|
|
@@ -130,36 +180,74 @@ async function executeJob(cfg, job, sink) {
|
|
|
130
180
|
throw new Error('Install @anthropic-ai/claude-agent-sdk to run the Noesis local agent (real mode).');
|
|
131
181
|
});
|
|
132
182
|
let finalText = '';
|
|
183
|
+
let sawDelta = false;
|
|
184
|
+
let terminalText = '';
|
|
185
|
+
const allowedTools = clampAllowedTools(job.payload.allowedTools);
|
|
133
186
|
const stream = sdk.query({
|
|
134
187
|
prompt,
|
|
135
188
|
options: {
|
|
136
189
|
...(job.payload.system ? { systemPrompt: job.payload.system } : {}),
|
|
137
|
-
allowedTools
|
|
138
|
-
|
|
190
|
+
allowedTools,
|
|
191
|
+
// Only spawn the Noesis MCP server when a tool actually survived clamping.
|
|
192
|
+
...(allowedTools.length > 0 ? { mcpServers: noesisMcpServers(cfg) } : {}),
|
|
193
|
+
maxTurns: clampMaxTurns(job.payload.maxTurns),
|
|
139
194
|
includePartialMessages: true,
|
|
140
195
|
},
|
|
141
196
|
});
|
|
197
|
+
// With includePartialMessages the stream carries BOTH incremental `stream_event`
|
|
198
|
+
// deltas AND a terminal `assistant` message holding the whole reply. Taking both
|
|
199
|
+
// would emit the answer twice, so deltas win and the terminal message is only a
|
|
200
|
+
// fallback for a stream that produced none (older SDK, or partials unsupported).
|
|
142
201
|
for await (const message of stream) {
|
|
143
202
|
if (sink.isClosed())
|
|
144
203
|
break;
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
204
|
+
const delta = extractStreamDelta(message);
|
|
205
|
+
if (delta) {
|
|
206
|
+
sawDelta = true;
|
|
207
|
+
sink.push(delta);
|
|
208
|
+
finalText += delta;
|
|
209
|
+
continue;
|
|
151
210
|
}
|
|
211
|
+
// Concatenate, don't overwrite: with tools the run is multi-turn, and a
|
|
212
|
+
// stream that produced no deltas would otherwise keep only the LAST turn.
|
|
213
|
+
const whole = extractTerminalText(message);
|
|
214
|
+
if (whole)
|
|
215
|
+
terminalText += whole;
|
|
216
|
+
}
|
|
217
|
+
if (!sawDelta && terminalText) {
|
|
218
|
+
sink.push(terminalText);
|
|
219
|
+
finalText = terminalText;
|
|
152
220
|
}
|
|
153
221
|
return finalText;
|
|
154
222
|
}
|
|
155
|
-
|
|
223
|
+
/**
|
|
224
|
+
* Text carried by one streamed partial. Verified against the SDK (0.1.x): partials
|
|
225
|
+
* arrive as `{type:'stream_event', event:{type:'content_block_delta',
|
|
226
|
+
* delta:{type:'text_delta', text}}}`. The un-enveloped shape is accepted too, since
|
|
227
|
+
* this is the field older versions used.
|
|
228
|
+
*/
|
|
229
|
+
function extractStreamDelta(message) {
|
|
230
|
+
if (!message || typeof message !== 'object')
|
|
231
|
+
return '';
|
|
232
|
+
const m = message;
|
|
233
|
+
if (m.type !== 'stream_event')
|
|
234
|
+
return '';
|
|
235
|
+
const ev = m.event;
|
|
236
|
+
if (ev?.type === 'content_block_delta' && typeof ev?.delta?.text === 'string')
|
|
237
|
+
return ev.delta.text;
|
|
238
|
+
if (typeof m.delta?.text === 'string')
|
|
239
|
+
return m.delta.text;
|
|
240
|
+
return '';
|
|
241
|
+
}
|
|
242
|
+
/** Whole-reply text from the terminal assistant message. Never combined with deltas. */
|
|
243
|
+
function extractTerminalText(message) {
|
|
156
244
|
if (!message || typeof message !== 'object')
|
|
157
245
|
return '';
|
|
158
246
|
const m = message;
|
|
247
|
+
if (m.type === 'stream_event' || m.type === 'system' || m.type === 'result')
|
|
248
|
+
return '';
|
|
159
249
|
if (typeof m.text === 'string')
|
|
160
250
|
return m.text;
|
|
161
|
-
if (m.delta && typeof m.delta.text === 'string')
|
|
162
|
-
return m.delta.text;
|
|
163
251
|
const content = m.message?.content ?? m.content;
|
|
164
252
|
if (Array.isArray(content)) {
|
|
165
253
|
return content.map((b) => (typeof b?.text === 'string' ? b.text : '')).join('');
|
package/dist/agent/runner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/agent/runner.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/agent/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backlog.d.ts","sourceRoot":"","sources":["../../src/tools/backlog.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"backlog.d.ts","sourceRoot":"","sources":["../../src/tools/backlog.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAiB3D,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAiLlF"}
|
package/dist/tools/backlog.js
CHANGED
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
* Backlog v2 MCP tools — the loop's view of /api/mcp/backlog. Thin wrappers:
|
|
3
3
|
* every rule (stage legality, OWNER_GATE, freeze, park guards) is enforced
|
|
4
4
|
* server-side; these tools shape requests and return compact JSON text that a
|
|
5
|
-
* driving loop can parse. The owner-only acts (approve /
|
|
6
|
-
* NO tool here by design — they exist only on the
|
|
5
|
+
* driving loop can parse. The owner-only acts (approve / cancel, and reject of
|
|
6
|
+
* anything UN-parked) have NO tool here by design — they exist only on the
|
|
7
|
+
* owner's page. The one disposal this surface carries is the owner-instructed
|
|
8
|
+
* reject of a PARKED item: ambiguous|superseded -> rejected, reason required.
|
|
7
9
|
*/
|
|
8
10
|
import { z } from 'zod';
|
|
9
|
-
|
|
11
|
+
// 'rejected' rides along for set_stage's parked disposal and as a backlog_get
|
|
12
|
+
// list filter; it is NOT a stage the loop may reach from un-parked items.
|
|
13
|
+
const STAGE_ENUM = z.enum(['jot', 'ambiguous', 'superseded', 'refined', 'materialized', 'approved', 'running', 'implemented', 'shipped', 'rejected']);
|
|
10
14
|
const KIND_ENUM = z.enum(['feature', 'bug', 'design', 'process', 'research']);
|
|
11
15
|
const SIZE_ENUM = z.enum(['S', 'M', 'L']);
|
|
12
16
|
function jsonText(data) {
|
|
@@ -17,7 +21,7 @@ function errText(e) {
|
|
|
17
21
|
return { content: [{ type: 'text', text: `Backlog tool failed: ${msg}` }], isError: true };
|
|
18
22
|
}
|
|
19
23
|
export function registerBacklogTools(server, client) {
|
|
20
|
-
server.tool('backlog_get', 'Read the Backlog: without a key, list issues (+ per-stage counts, optionally filtered by stage or a text query); with a key (TCK-<n>), the full issue including increments
|
|
24
|
+
server.tool('backlog_get', 'Read the Backlog: without a key, list issues (+ per-stage counts and open_question_count, optionally filtered by stage or a text query); with a key (TCK-<n>), the full issue including increments, open owner questions, and the bounded message thread (questions + answers linked via answered_by_message_id — what RESOLVE reads).', {
|
|
21
25
|
key: z.string().optional().describe('Issue key like TCK-7 (omit to list)'),
|
|
22
26
|
stage: STAGE_ENUM.optional().describe('List filter: only this stage'),
|
|
23
27
|
query: z.string().optional().describe('List filter: title/body text search'),
|
|
@@ -59,10 +63,10 @@ export function registerBacklogTools(server, client) {
|
|
|
59
63
|
return errText(e);
|
|
60
64
|
}
|
|
61
65
|
});
|
|
62
|
-
server.tool('backlog_set_stage', "Move an issue through its lifecycle on the loop surface: jot->refined, refined->materialized (send-back too), approved->running, running->approved (STOP-acknowledge), running->implemented, implemented->shipped. Cannot approve/
|
|
66
|
+
server.tool('backlog_set_stage', "Move an issue through its lifecycle on the loop surface: jot->refined, refined->materialized (send-back too), approved->running, running->approved (STOP-acknowledge), running->implemented, implemented->shipped; plus the groom detours: jot->ambiguous (reading forks; post the question FIRST), ambiguous->refined/jot (resolve/retract), and jot|refined|ambiguous|materialized->superseded (grooming believes it ALREADY SHIPPED — post the evidence question first), superseded->jot/refined (retract/keep). Parked disposal: ambiguous|superseded->rejected, ONLY on the owner's explicit instruction (in chat, or their answer to the park question) — reason REQUIRED and must record that instruction. Cannot approve/cancel, nor reject un-parked items — those are the owner's page buttons (OWNER_GATE).", {
|
|
63
67
|
key: z.string().describe('Issue key like TCK-7'),
|
|
64
68
|
to: STAGE_ENUM.describe('Target stage (approve only as the running->approved stop-ack)'),
|
|
65
|
-
reason: z.string().optional().describe(
|
|
69
|
+
reason: z.string().optional().describe("Reason for send-backs; REQUIRED for rejected (record the owner's instruction)"),
|
|
66
70
|
}, async (args) => {
|
|
67
71
|
try {
|
|
68
72
|
return jsonText(await client.backlogSetStage(args.key, args.to, args.reason));
|
|
@@ -121,7 +125,7 @@ export function registerBacklogTools(server, client) {
|
|
|
121
125
|
return errText(e);
|
|
122
126
|
}
|
|
123
127
|
});
|
|
124
|
-
server.tool('backlog_post_message', "The loop's voice on an issue: kind 'answer' + answer_to replies to an owner question WITHOUT stopping work; kind 'question'
|
|
128
|
+
server.tool('backlog_post_message', "The loop's voice on an issue: kind 'answer' + answer_to replies to an owner question WITHOUT stopping work; kind 'question' + parks_sequence asks the owner and parks that increment ([Q] park); kind 'question' WITHOUT parks_sequence is the issue-level groom question (pair it with set_stage to 'ambiguous' for reading forks, or 'superseded' for already-shipped evidence); kind 'comment' leaves a note.", {
|
|
125
129
|
key: z.string(),
|
|
126
130
|
body_md: z.string(),
|
|
127
131
|
kind: z.enum(['answer', 'question', 'comment']),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backlog.js","sourceRoot":"","sources":["../../src/tools/backlog.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"backlog.js","sourceRoot":"","sources":["../../src/tools/backlog.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -61,5 +61,45 @@ export declare function syncSpecificFiles(filePaths: string[], dryRun: boolean,
|
|
|
61
61
|
}>;
|
|
62
62
|
isError?: boolean;
|
|
63
63
|
}>;
|
|
64
|
+
/**
|
|
65
|
+
* Split leading YAML frontmatter from a markdown document.
|
|
66
|
+
*
|
|
67
|
+
* The opening `---` must be the very first line and the closing `---` must be on its
|
|
68
|
+
* own line (line-anchored). This deliberately does NOT use `indexOf('---', 3)`: a bare
|
|
69
|
+
* substring search matches a `---` inside a frontmatter value, a `---`/`----` thematic
|
|
70
|
+
* break in the body, or a `---` inside a code fence — which previously caused notes to
|
|
71
|
+
* be truncated / their frontmatter duplicated on sync.
|
|
72
|
+
*
|
|
73
|
+
* @returns raw = whole matched block incl. fences + trailing newline; inner = the YAML
|
|
74
|
+
* between the fences; body = everything after the block. If there is no valid
|
|
75
|
+
* leading frontmatter, raw/inner are '' and body is the full content.
|
|
76
|
+
*/
|
|
77
|
+
export declare function splitFrontmatter(content: string): {
|
|
78
|
+
raw: string;
|
|
79
|
+
inner: string;
|
|
80
|
+
body: string;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Update frontmatter in file content with new metadata values
|
|
84
|
+
* Preserves existing frontmatter structure and only updates specified fields
|
|
85
|
+
*/
|
|
86
|
+
export declare function updateFrontmatter(content: string, updates: {
|
|
87
|
+
title?: string;
|
|
88
|
+
description?: string;
|
|
89
|
+
keywords?: string[];
|
|
90
|
+
}): string;
|
|
91
|
+
/**
|
|
92
|
+
* Parse markdown content into structure: frontmatter, H1 heading, and body
|
|
93
|
+
*/
|
|
94
|
+
export declare function parseMarkdownStructure(content: string): {
|
|
95
|
+
frontmatter: string;
|
|
96
|
+
h1: string | null;
|
|
97
|
+
body: string;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Merge local content with cloud content
|
|
101
|
+
* Strategy: Cloud's H1 wins (Noesis edits), Local's body wins (local edits)
|
|
102
|
+
*/
|
|
103
|
+
export declare function mergeContent(localContent: string, cloudContent: string): string;
|
|
64
104
|
export {};
|
|
65
105
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,YAAY,EAAyC,KAAK,IAAI,EAA2D,MAAM,wBAAwB,CAAC;AAqIjK;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAC1C;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAejD;AAqBD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,YAAY,EAAyC,KAAK,IAAI,EAA2D,MAAM,wBAAwB,CAAC;AAqIjK;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAC1C;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAejD;AAqBD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CA44F7E;AA0DD;;;;GAIG;AACH,KAAK,YAAY,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IACnC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CAYxF;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EAAE,EACnB,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,YAAY,EACpB,KAAK,GAAE,OAAe,EACtB,kBAAkB,GAAE,OAAe,GAClC,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAigBhF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAI9F;AA+DD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GACrE,MAAM,CA2FR;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd,CAqBA;AA4SD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAY/E"}
|
package/dist/tools/index.js
CHANGED
|
@@ -1390,20 +1390,27 @@ export function registerTools(server, services) {
|
|
|
1390
1390
|
keywords: cloudKw.length > 0 ? cloudKw : undefined
|
|
1391
1391
|
})
|
|
1392
1392
|
: mergedContent;
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1393
|
+
// Safety net: never silently destroy content on merge (see per-file branch).
|
|
1394
|
+
if (enrichedContent.length < localFile.content.length * 0.5 && localFile.content.length > 2048) {
|
|
1395
|
+
const lost = Math.round(100 * (1 - enrichedContent.length / localFile.content.length));
|
|
1396
|
+
result.errors.push(`Skipped push for ${relativePath}: merge would drop ${lost}% of content (${localFile.content.length}->${enrichedContent.length} bytes). Left unchanged to avoid data loss.`);
|
|
1397
|
+
}
|
|
1398
|
+
else {
|
|
1399
|
+
const enrichedHash = NoesisClient.computeHash(enrichedContent);
|
|
1400
|
+
const mergedFile = {
|
|
1401
|
+
...localFile,
|
|
1402
|
+
content: enrichedContent,
|
|
1403
|
+
hash: enrichedHash
|
|
1404
|
+
};
|
|
1405
|
+
// preserveMetadata=true: keep cloud's AI-generated title/description/keywords
|
|
1406
|
+
await client.upsertNote(mergedFile, metadata, { force: true, regenerateMetadata, preserveMetadata: true });
|
|
1407
|
+
// Write enriched content back to local file
|
|
1408
|
+
const localPath = path.join(syncRoot.path, relativePath);
|
|
1409
|
+
fs.writeFileSync(localPath, enrichedContent, 'utf-8');
|
|
1410
|
+
stateMgr.setBaseline(relativePath, { hash: enrichedHash, lastSyncedAt: new Date().toISOString() }, enrichedContent);
|
|
1411
|
+
result.details.push({ file: relativePath, action: 'pushed_update', reason: 'merged' });
|
|
1412
|
+
result.pushed.updated++;
|
|
1413
|
+
}
|
|
1407
1414
|
}
|
|
1408
1415
|
}
|
|
1409
1416
|
else if (direction === 'pull') {
|
|
@@ -3051,26 +3058,35 @@ export async function syncSpecificFiles(filePaths, dryRun, client, force = false
|
|
|
3051
3058
|
keywords: cloudKw.length > 0 ? cloudKw : undefined
|
|
3052
3059
|
})
|
|
3053
3060
|
: mergedContent;
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3061
|
+
// Safety net: a merge must never silently destroy content. If the merged
|
|
3062
|
+
// result lost most of the local body, abort this file's push instead of
|
|
3063
|
+
// overwriting local + cloud with a truncated note.
|
|
3064
|
+
if (enrichedContent.length < localContent.length * 0.5 && localContent.length > 2048) {
|
|
3065
|
+
const lost = Math.round(100 * (1 - enrichedContent.length / localContent.length));
|
|
3066
|
+
result.errors.push(`Skipped push for ${relativePath}: merge would drop ${lost}% of content (${localContent.length}->${enrichedContent.length} bytes). Left unchanged to avoid data loss.`);
|
|
3067
|
+
}
|
|
3068
|
+
else {
|
|
3069
|
+
const enrichedHash = NoesisClient.computeHash(enrichedContent);
|
|
3070
|
+
const localFile = {
|
|
3071
|
+
path: normalizedPath,
|
|
3072
|
+
relativePath,
|
|
3073
|
+
content: enrichedContent,
|
|
3074
|
+
hash: enrichedHash,
|
|
3075
|
+
mtime: stats.mtime,
|
|
3076
|
+
size: stats.size,
|
|
3077
|
+
rootId: matchingRoot.id,
|
|
3078
|
+
rootName: matchingRoot.name,
|
|
3079
|
+
project
|
|
3080
|
+
};
|
|
3081
|
+
// preserveMetadata=true: keep cloud's AI-generated title/description/keywords
|
|
3082
|
+
await client.upsertNote(localFile, localMetadata, { force: true, regenerateMetadata, preserveMetadata: true });
|
|
3083
|
+
// Write enriched content back to local file
|
|
3084
|
+
fs.writeFileSync(normalizedPath, enrichedContent, 'utf-8');
|
|
3085
|
+
stateMgr.setBaseline(relativePath, { hash: enrichedHash, lastSyncedAt: new Date().toISOString() }, enrichedContent);
|
|
3086
|
+
result.details.push({ file: relativePath, action: 'pushed_update', reason: 'merged' });
|
|
3087
|
+
result.pushed.updated++;
|
|
3088
|
+
affectedRoots.add(matchingRoot.id);
|
|
3089
|
+
}
|
|
3074
3090
|
}
|
|
3075
3091
|
}
|
|
3076
3092
|
else if (direction === 'pull') {
|
|
@@ -3185,22 +3201,36 @@ export async function syncSpecificFiles(filePaths, dryRun, client, force = false
|
|
|
3185
3201
|
}]
|
|
3186
3202
|
};
|
|
3187
3203
|
}
|
|
3204
|
+
/**
|
|
3205
|
+
* Split leading YAML frontmatter from a markdown document.
|
|
3206
|
+
*
|
|
3207
|
+
* The opening `---` must be the very first line and the closing `---` must be on its
|
|
3208
|
+
* own line (line-anchored). This deliberately does NOT use `indexOf('---', 3)`: a bare
|
|
3209
|
+
* substring search matches a `---` inside a frontmatter value, a `---`/`----` thematic
|
|
3210
|
+
* break in the body, or a `---` inside a code fence — which previously caused notes to
|
|
3211
|
+
* be truncated / their frontmatter duplicated on sync.
|
|
3212
|
+
*
|
|
3213
|
+
* @returns raw = whole matched block incl. fences + trailing newline; inner = the YAML
|
|
3214
|
+
* between the fences; body = everything after the block. If there is no valid
|
|
3215
|
+
* leading frontmatter, raw/inner are '' and body is the full content.
|
|
3216
|
+
*/
|
|
3217
|
+
export function splitFrontmatter(content) {
|
|
3218
|
+
const m = content.match(/^---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*(?:\r?\n|$)/);
|
|
3219
|
+
if (!m)
|
|
3220
|
+
return { raw: '', inner: '', body: content };
|
|
3221
|
+
return { raw: m[0], inner: m[1], body: content.slice(m[0].length) };
|
|
3222
|
+
}
|
|
3188
3223
|
/**
|
|
3189
3224
|
* Parse YAML frontmatter from markdown content using js-yaml
|
|
3190
3225
|
*/
|
|
3191
3226
|
function parseYamlFrontmatter(content) {
|
|
3192
3227
|
const result = {};
|
|
3193
|
-
|
|
3194
|
-
if (!
|
|
3195
|
-
return result;
|
|
3196
|
-
}
|
|
3197
|
-
const endIndex = content.indexOf('---', 3);
|
|
3198
|
-
if (endIndex === -1) {
|
|
3228
|
+
const { inner } = splitFrontmatter(content);
|
|
3229
|
+
if (!inner) {
|
|
3199
3230
|
return result;
|
|
3200
3231
|
}
|
|
3201
|
-
const frontmatterStr = content.substring(3, endIndex).trim();
|
|
3202
3232
|
try {
|
|
3203
|
-
const parsed = yaml.load(
|
|
3233
|
+
const parsed = yaml.load(inner);
|
|
3204
3234
|
if (!parsed || typeof parsed !== 'object') {
|
|
3205
3235
|
return result;
|
|
3206
3236
|
}
|
|
@@ -3248,9 +3278,14 @@ function parseCloudKeywords(keywords) {
|
|
|
3248
3278
|
* Update frontmatter in file content with new metadata values
|
|
3249
3279
|
* Preserves existing frontmatter structure and only updates specified fields
|
|
3250
3280
|
*/
|
|
3251
|
-
function updateFrontmatter(content, updates) {
|
|
3252
|
-
|
|
3253
|
-
|
|
3281
|
+
export function updateFrontmatter(content, updates) {
|
|
3282
|
+
const { inner, body } = splitFrontmatter(content);
|
|
3283
|
+
// If no (valid) frontmatter exists, create one
|
|
3284
|
+
if (!inner) {
|
|
3285
|
+
if (content.startsWith('---')) {
|
|
3286
|
+
// Opens with a fence but has no valid closing fence: don't risk mangling it.
|
|
3287
|
+
return content;
|
|
3288
|
+
}
|
|
3254
3289
|
const frontmatterLines = ['---'];
|
|
3255
3290
|
if (updates.title)
|
|
3256
3291
|
frontmatterLines.push(`title: ${updates.title}`);
|
|
@@ -3265,13 +3300,8 @@ function updateFrontmatter(content, updates) {
|
|
|
3265
3300
|
frontmatterLines.push('---');
|
|
3266
3301
|
return frontmatterLines.join('\n') + '\n' + content;
|
|
3267
3302
|
}
|
|
3268
|
-
|
|
3269
|
-
const
|
|
3270
|
-
if (endIndex === -1) {
|
|
3271
|
-
return content; // Invalid frontmatter, return unchanged
|
|
3272
|
-
}
|
|
3273
|
-
const frontmatter = content.substring(3, endIndex);
|
|
3274
|
-
const bodyContent = content.substring(endIndex + 3);
|
|
3303
|
+
const frontmatter = inner;
|
|
3304
|
+
const bodyContent = body;
|
|
3275
3305
|
const lines = frontmatter.split(/\r?\n/);
|
|
3276
3306
|
const newLines = [];
|
|
3277
3307
|
const updatedKeys = new Set();
|
|
@@ -3334,31 +3364,27 @@ function updateFrontmatter(content, updates) {
|
|
|
3334
3364
|
newLines.push(` - ${kw}`);
|
|
3335
3365
|
}
|
|
3336
3366
|
}
|
|
3337
|
-
return '---\n' + newLines.filter(l => l.trim() !== '').join('\n') + '\n
|
|
3367
|
+
return '---\n' + newLines.filter(l => l.trim() !== '').join('\n') + '\n---\n' + bodyContent;
|
|
3338
3368
|
}
|
|
3339
3369
|
/**
|
|
3340
3370
|
* Parse markdown content into structure: frontmatter, H1 heading, and body
|
|
3341
3371
|
*/
|
|
3342
|
-
function parseMarkdownStructure(content) {
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
}
|
|
3353
|
-
// Extract first H1 heading (# ...)
|
|
3354
|
-
const h1Match = remaining.match(/^(#\s+.+?)(\r?\n|$)/m);
|
|
3372
|
+
export function parseMarkdownStructure(content) {
|
|
3373
|
+
// Extract YAML frontmatter (line-anchored; see splitFrontmatter).
|
|
3374
|
+
const { raw, body: afterFrontmatter } = splitFrontmatter(content);
|
|
3375
|
+
const frontmatter = raw ? raw.replace(/\r?\n$/, '') : ''; // keep fences; reconstruct re-adds the trailing newline
|
|
3376
|
+
const remaining = afterFrontmatter;
|
|
3377
|
+
// Extract the note's H1 heading — ONLY when it is the first non-blank line of the
|
|
3378
|
+
// body. A non-anchored /m search would match a `# ...` line inside a fenced code
|
|
3379
|
+
// block (e.g. a shell comment) and set body to everything after it, silently
|
|
3380
|
+
// dropping the whole note above it. Anchoring to the start keeps all content.
|
|
3381
|
+
const h1Match = remaining.match(/^\s*(#[ \t]+.+?)(\r?\n|$)/);
|
|
3355
3382
|
let h1 = null;
|
|
3356
3383
|
let body = remaining;
|
|
3357
3384
|
if (h1Match) {
|
|
3358
3385
|
h1 = h1Match[1];
|
|
3359
|
-
//
|
|
3360
|
-
|
|
3361
|
-
body = remaining.substring(h1EndIndex);
|
|
3386
|
+
// Everything after the matched leading H1 line becomes the body.
|
|
3387
|
+
body = remaining.substring(h1Match[0].length);
|
|
3362
3388
|
}
|
|
3363
3389
|
return { frontmatter, h1, body };
|
|
3364
3390
|
}
|
|
@@ -3628,7 +3654,7 @@ async function runConflictCascade(opts) {
|
|
|
3628
3654
|
* Merge local content with cloud content
|
|
3629
3655
|
* Strategy: Cloud's H1 wins (Noesis edits), Local's body wins (local edits)
|
|
3630
3656
|
*/
|
|
3631
|
-
function mergeContent(localContent, cloudContent) {
|
|
3657
|
+
export function mergeContent(localContent, cloudContent) {
|
|
3632
3658
|
const localParsed = parseMarkdownStructure(localContent);
|
|
3633
3659
|
const cloudParsed = parseMarkdownStructure(cloudContent);
|
|
3634
3660
|
// Use cloud's H1 if it exists and differs from local, otherwise use local's H1
|