@mercury-fw/core 0.31.0 → 0.31.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/CHANGELOG.md +11 -0
- package/dist/src/wiki/wiki-note.d.ts +3 -0
- package/dist/src/wiki/wiki-read.d.ts +2 -1
- package/package.json +5 -5
- package/src/admin/wiki-routes.ts +2 -1
- package/src/wiki/self-review-tools.ts +4 -3
- package/src/wiki/vault-cli.ts +1 -1
- package/src/wiki/wiki-note.ts +6 -0
- package/src/wiki/wiki-read.ts +3 -2
- package/src/wiki/wiki-tools.ts +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @mercury-fw/core
|
|
2
2
|
|
|
3
|
+
## 0.31.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 7926aa2: - Wiki grep ignores case, for the agent, the nightly review, `mfw vault grep` and the HTTP `/wiki/grep` route.
|
|
8
|
+
- The agent's `write_file` and the nightly review's `write_curated` take a path starting with `curated/`, as listing, reading and grepping give it, instead of writing under `curated/curated/`.
|
|
9
|
+
- @mercury-fw/plugin-types@0.31.1
|
|
10
|
+
- @mercury-fw/channel-types@0.31.1
|
|
11
|
+
- @mercury-fw/cli-engine@0.31.1
|
|
12
|
+
- @mercury-fw/confirm-engine@0.31.1
|
|
13
|
+
|
|
3
14
|
## 0.31.0
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/** `path` relative to curated/: a vault-relative one (`curated/x.md`, as
|
|
2
|
+
* listing, reading and grepping give it) loses its leading `curated/`. */
|
|
3
|
+
export declare function relativeToCurated(path: string): string;
|
|
1
4
|
/** Writes a curated doc at `curated/<relativePath>` (e.g. "standards/jira-fields.md"). */
|
|
2
5
|
export declare function writeCuratedNote(vaultPath: string, relativePath: string, fields: {
|
|
3
6
|
author?: string;
|
|
@@ -19,7 +19,8 @@ export type WikiGrepMatch = {
|
|
|
19
19
|
line: number;
|
|
20
20
|
text: string;
|
|
21
21
|
};
|
|
22
|
-
/** Searches every file under `roots` for `pattern` (a regular expression
|
|
22
|
+
/** Searches every file under `roots` for `pattern` (a regular expression,
|
|
23
|
+
* case-insensitive: a note's wording isn't the question's), line by line. */
|
|
23
24
|
export declare function grepWikiInRoots(vaultPath: string, roots: string[], pattern: string): Promise<WikiGrepMatch[]>;
|
|
24
25
|
/** Searches every file visible to `userId` for `pattern` (a regular expression), line by line. */
|
|
25
26
|
export declare function grepWiki(vaultPath: string, userId: string, pattern: string): Promise<WikiGrepMatch[]>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mercury-fw/core",
|
|
3
|
-
"version": "0.31.
|
|
3
|
+
"version": "0.31.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"test": "bun test"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@mercury-fw/channel-types": "0.31.
|
|
35
|
-
"@mercury-fw/cli-engine": "0.31.
|
|
36
|
-
"@mercury-fw/confirm-engine": "0.31.
|
|
37
|
-
"@mercury-fw/plugin-types": "0.31.
|
|
34
|
+
"@mercury-fw/channel-types": "0.31.1",
|
|
35
|
+
"@mercury-fw/cli-engine": "0.31.1",
|
|
36
|
+
"@mercury-fw/confirm-engine": "0.31.1",
|
|
37
|
+
"@mercury-fw/plugin-types": "0.31.1",
|
|
38
38
|
"@qdrant/js-client-rest": "^1.19.0",
|
|
39
39
|
"ai": "^7.0.126",
|
|
40
40
|
"ai-sdk-ollama": "^4.4.0",
|
package/src/admin/wiki-routes.ts
CHANGED
|
@@ -31,7 +31,8 @@ export async function readWikiVaultFile(vaultPath: string, relativePath: string)
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export async function grepWikiVault(vaultPath: string, pattern: string): Promise<WikiGrepMatch[]> {
|
|
34
|
-
|
|
34
|
+
// Case-insensitive, like every other wiki grep.
|
|
35
|
+
const regex = new RegExp(pattern, "i");
|
|
35
36
|
const files = await listWikiVault(vaultPath);
|
|
36
37
|
const matches: WikiGrepMatch[] = [];
|
|
37
38
|
for (const file of files) {
|
|
@@ -19,7 +19,7 @@ import type { ExecutableTool } from "@mercury-fw/plugin-types";
|
|
|
19
19
|
import { tool } from "ai";
|
|
20
20
|
import { z } from "zod";
|
|
21
21
|
import { listWikiFilesInRoots, readWikiFileInRoots, grepWikiInRoots, selfReviewRoots, readIndexFile } from "./wiki-read.ts";
|
|
22
|
-
import { writeCuratedNote, writeIndexFile, deleteRawEntry, deleteCuratedEntry } from "./wiki-note.ts";
|
|
22
|
+
import { writeCuratedNote, writeIndexFile, deleteRawEntry, deleteCuratedEntry, relativeToCurated } from "./wiki-note.ts";
|
|
23
23
|
import { normalizeIndexKey, upsertIndexEntry, removeIndexEntry } from "./index-entry.ts";
|
|
24
24
|
|
|
25
25
|
export type SelfReviewToolsDeps = { vaultPath: string };
|
|
@@ -76,11 +76,12 @@ export function createSelfReviewTools(
|
|
|
76
76
|
});
|
|
77
77
|
|
|
78
78
|
const write_curated = tool({
|
|
79
|
-
description:
|
|
79
|
+
description:
|
|
80
|
+
'Create or overwrite a curated doc. "path" is relative to curated/, e.g. "standards/jira-fields.md"; the path list_files and grep give ("curated/standards/jira-fields.md") works too.',
|
|
80
81
|
inputSchema: z.object({ path: z.string().min(1), content: z.string() }),
|
|
81
82
|
execute: async ({ path, content }) => {
|
|
82
83
|
try {
|
|
83
|
-
await writeCuratedNote(vaultPath, path, {}, content);
|
|
84
|
+
await writeCuratedNote(vaultPath, relativeToCurated(path), {}, content);
|
|
84
85
|
return { ok: true as const };
|
|
85
86
|
} catch (err) {
|
|
86
87
|
return { ok: false as const, error: String(err) };
|
package/src/wiki/vault-cli.ts
CHANGED
|
@@ -127,7 +127,7 @@ async function main(): Promise<void> {
|
|
|
127
127
|
case "grep": {
|
|
128
128
|
const pattern = args[0];
|
|
129
129
|
if (!pattern) usage();
|
|
130
|
-
const regex = new RegExp(pattern);
|
|
130
|
+
const regex = new RegExp(pattern, "i");
|
|
131
131
|
const glob = new Bun.Glob("**/*.md");
|
|
132
132
|
for await (const file of glob.scan({ cwd: vaultPath })) {
|
|
133
133
|
const content = await Bun.file(`${vaultPath}/${file}`).text();
|
package/src/wiki/wiki-note.ts
CHANGED
|
@@ -201,6 +201,12 @@ async function deleteVaultFile(vaultPath: string, fullPath: string, commitMessag
|
|
|
201
201
|
});
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
+
/** `path` relative to curated/: a vault-relative one (`curated/x.md`, as
|
|
205
|
+
* listing, reading and grepping give it) loses its leading `curated/`. */
|
|
206
|
+
export function relativeToCurated(path: string): string {
|
|
207
|
+
return path.replace(/^curated\//, "");
|
|
208
|
+
}
|
|
209
|
+
|
|
204
210
|
/** Writes a curated doc at `curated/<relativePath>` (e.g. "standards/jira-fields.md"). */
|
|
205
211
|
export async function writeCuratedNote(
|
|
206
212
|
vaultPath: string,
|
package/src/wiki/wiki-read.ts
CHANGED
|
@@ -88,9 +88,10 @@ export async function readWikiFile(vaultPath: string, userId: string, relativePa
|
|
|
88
88
|
|
|
89
89
|
export type WikiGrepMatch = { path: string; line: number; text: string };
|
|
90
90
|
|
|
91
|
-
/** Searches every file under `roots` for `pattern` (a regular expression
|
|
91
|
+
/** Searches every file under `roots` for `pattern` (a regular expression,
|
|
92
|
+
* case-insensitive: a note's wording isn't the question's), line by line. */
|
|
92
93
|
export async function grepWikiInRoots(vaultPath: string, roots: string[], pattern: string): Promise<WikiGrepMatch[]> {
|
|
93
|
-
const regex = new RegExp(pattern);
|
|
94
|
+
const regex = new RegExp(pattern, "i");
|
|
94
95
|
const files = await listWikiFilesInRoots(vaultPath, roots);
|
|
95
96
|
const matches: WikiGrepMatch[] = [];
|
|
96
97
|
|
package/src/wiki/wiki-tools.ts
CHANGED
|
@@ -15,7 +15,7 @@ import type { ExecutableTool } from "@mercury-fw/plugin-types";
|
|
|
15
15
|
import { tool } from "ai";
|
|
16
16
|
import { z } from "zod";
|
|
17
17
|
import { listWikiFiles, readWikiFile, grepWiki, readWikiFileInRoots } from "./wiki-read.ts";
|
|
18
|
-
import { writeCuratedNote } from "./wiki-note.ts";
|
|
18
|
+
import { writeCuratedNote, relativeToCurated } from "./wiki-note.ts";
|
|
19
19
|
|
|
20
20
|
export type WikiToolsDeps = { vaultPath: string; userId: string };
|
|
21
21
|
|
|
@@ -55,12 +55,13 @@ export function createWikiTools(
|
|
|
55
55
|
const write_file = tool({
|
|
56
56
|
description:
|
|
57
57
|
'Write or update a curated wiki document (team knowledge — conventions, standards, decisions). "path" ' +
|
|
58
|
-
'is relative to curated/, e.g. "standards/jira-fields.md"
|
|
58
|
+
'is relative to curated/, e.g. "standards/jira-fields.md"; the path grep and read_file give ' +
|
|
59
|
+
'("curated/standards/jira-fields.md") works too. This can only write under curated/ — your ' +
|
|
59
60
|
"own semantic notes are managed automatically by the memory consolidation process, not through this tool.",
|
|
60
61
|
inputSchema: z.object({ path: z.string().min(1), content: z.string() }),
|
|
61
62
|
execute: async ({ path, content }) => {
|
|
62
63
|
try {
|
|
63
|
-
await writeCuratedNote(vaultPath, path, { last_updated: new Date().toISOString().slice(0, 10) }, content);
|
|
64
|
+
await writeCuratedNote(vaultPath, relativeToCurated(path), { last_updated: new Date().toISOString().slice(0, 10) }, content);
|
|
64
65
|
return { ok: true as const };
|
|
65
66
|
} catch (err) {
|
|
66
67
|
return { ok: false as const, error: String(err) };
|
|
@@ -70,7 +71,7 @@ export function createWikiTools(
|
|
|
70
71
|
|
|
71
72
|
const grep = tool({
|
|
72
73
|
description:
|
|
73
|
-
"Search wiki documents (curated/ plus your own inferred/ notes) for a regular expression pattern. " +
|
|
74
|
+
"Search wiki documents (curated/ plus your own inferred/ notes) for a regular expression pattern, ignoring case. " +
|
|
74
75
|
"Returns matching lines with their file path and line number.",
|
|
75
76
|
inputSchema: z.object({ pattern: z.string().min(1) }),
|
|
76
77
|
execute: async ({ pattern }) => {
|