mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-08 13:39:45 +08:00
fix: use correct gbrain put <slug> CLI verb in memory ingest
`put_page` is the MCP tool name, not a CLI subcommand. The actual gbrain verb is `put <slug>` with content via stdin and tags in YAML frontmatter. Every transcript / memory ingest fails today on clean installs. Switch to the right verb and inject title/type/tags into the frontmatter that buildTranscriptPage / buildArtifactPage already produce. Bundled in the same function: - timeout: 30s → 60s. Auto-link reconciliation hits 30s once the brain has a few hundred pages. - maxBuffer: 1MB → 16MB. Without it Node truncates gbrain's stderr and callers see only `Command failed:` with no detail. - Surface stderr/stdout in the returned error instead of the bare exception. Verified: bun test test/gstack-memory-ingest.test.ts -> 15/15 pass. bun test on the three test files touching this path -> 362/362.
This commit is contained in:
@@ -763,23 +763,41 @@ function gbrainPutPage(page: PageRecord): { ok: boolean; error?: string } {
|
||||
if (!gbrainAvailable()) {
|
||||
return { ok: false, error: "gbrain CLI not in PATH" };
|
||||
}
|
||||
// gbrain CLI verb is `put <slug>`; it does NOT accept --title / --type /
|
||||
// --tags flags. (`put_page` is the MCP tool name, not the CLI subcommand.)
|
||||
// Inject title/type/tags into the YAML frontmatter that page.body already
|
||||
// begins with so gbrain's frontmatter parser picks them up.
|
||||
let body = page.body;
|
||||
if (body.startsWith("---\n")) {
|
||||
const end = body.indexOf("\n---\n", 4);
|
||||
if (end > 0) {
|
||||
const inject = [
|
||||
`title: ${JSON.stringify(page.title)}`,
|
||||
`type: ${page.type}`,
|
||||
`tags:`,
|
||||
...page.tags.map((t) => ` - ${t}`),
|
||||
].join("\n");
|
||||
body = body.slice(0, end) + "\n" + inject + body.slice(end);
|
||||
}
|
||||
}
|
||||
try {
|
||||
const args = [
|
||||
"put_page",
|
||||
"--slug", page.slug,
|
||||
"--title", page.title,
|
||||
"--type", page.type,
|
||||
"--tags", page.tags.join(","),
|
||||
];
|
||||
execFileSync("gbrain", args, {
|
||||
input: page.body,
|
||||
execFileSync("gbrain", ["put", page.slug], {
|
||||
input: body,
|
||||
encoding: "utf-8",
|
||||
timeout: 30000,
|
||||
// Bumped from 30s: auto-link reconciliation on dense transcripts hits
|
||||
// 30s once the brain has a few hundred existing pages.
|
||||
timeout: 60000,
|
||||
// Bumped from default 1MB: without this, gbrain's actual stderr gets
|
||||
// truncated and callers see only "Command failed:" with no detail.
|
||||
maxBuffer: 16 * 1024 * 1024,
|
||||
stdio: ["pipe", "pipe", "pipe"],
|
||||
});
|
||||
return { ok: true };
|
||||
} catch (err) {
|
||||
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
||||
} catch (err: any) {
|
||||
const stderr = err?.stderr?.toString?.() ?? "";
|
||||
const stdout = err?.stdout?.toString?.() ?? "";
|
||||
const detail = stderr || stdout || (err instanceof Error ? err.message : String(err));
|
||||
return { ok: false, error: detail.split("\n")[0].slice(0, 300) };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user