Implement layered maps and context retrieval
This commit is contained in:
@@ -81,12 +81,13 @@ describe("pi-extension", () => {
|
||||
});
|
||||
|
||||
describe("tool registration", () => {
|
||||
it("registers 4 tools", () => {
|
||||
expect(Object.keys(registeredTools)).toHaveLength(4);
|
||||
it("registers 5 tools", () => {
|
||||
expect(Object.keys(registeredTools)).toHaveLength(5);
|
||||
expect(registeredTools).toHaveProperty("project_map_init");
|
||||
expect(registeredTools).toHaveProperty("project_map_patch");
|
||||
expect(registeredTools).toHaveProperty("project_map_validate");
|
||||
expect(registeredTools).toHaveProperty("project_map_reinit");
|
||||
expect(registeredTools).toHaveProperty("project_map_context");
|
||||
});
|
||||
|
||||
it("registers session_start and before_agent_start events", () => {
|
||||
@@ -141,11 +142,15 @@ describe("pi-extension", () => {
|
||||
});
|
||||
|
||||
describe("project_map_validate tool", () => {
|
||||
it("reports clean when map exists and is up to date", async () => {
|
||||
it("reports clean when map and index exist and are up to date", async () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "pi-ext-test-"));
|
||||
writeFileSync(
|
||||
join(dir, ".pi-map.md"),
|
||||
"# .\n## role\nTest\n## files\n## arch\n## dirty\n-\n",
|
||||
"# .\ndir: .\n\nindex: ./.pi-map.index.md\n\n## Project Map Protocol\n\n1. Read this protocol and the root `.pi-map.index.md` first.\n\nTrust boundary: index routes, map orients, source decides.\n\n## role\nTest\n## files\n-\n## arch\nTest arch\n## tags\n-\n## symbols\n-\n## workflows\n-\n## dirty\n-\n",
|
||||
);
|
||||
writeFileSync(
|
||||
join(dir, ".pi-map.index.md"),
|
||||
"# . (index)\ndir: .\n\n## Project Map Protocol\n\n1. Read this protocol and the root `.pi-map.index.md` first.\n\nTrust boundary: index routes, map orients, source decides.\n\n## role\nTest\n## parent\n-\n## children\n-\n## files\n-\n## links\nindex: ./.pi-map.index.md\nmap: ./.pi-map.md\n## workflows\n-\n## dirty\n-\n",
|
||||
);
|
||||
mockCtx.cwd = dir;
|
||||
|
||||
@@ -180,6 +185,51 @@ describe("pi-extension", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("project_map_context tool", () => {
|
||||
it("returns a context bundle for a query", async () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "pi-ext-test-"));
|
||||
// Create a minimal map + index
|
||||
writeFileSync(
|
||||
join(dir, ".pi-map.md"),
|
||||
"# .\ndir: .\n\nindex: ./.pi-map.index.md\n\n## Project Map Protocol\n\nTrust boundary: index routes, map orients, source decides.\n\n## role\nTest project\n## files\n- test.ts | Test file\n## arch\nTest\n## tags\ntest\n## symbols\n- main\n## workflows\n-\n## dirty\n-\n",
|
||||
);
|
||||
writeFileSync(
|
||||
join(dir, ".pi-map.index.md"),
|
||||
"# . (index)\ndir: .\n\n## role\nTest project\n## parent\n-\n## children\n-\n## files\n- test.ts\n## links\nindex: ./.pi-map.index.md\nmap: ./.pi-map.md\n## workflows\n-\n## dirty\n-\n",
|
||||
);
|
||||
mockCtx.cwd = dir;
|
||||
|
||||
const tool = registeredTools.project_map_context;
|
||||
const result = await tool.execute(
|
||||
"tool-1",
|
||||
{ query: "test" },
|
||||
null,
|
||||
null,
|
||||
mockCtx,
|
||||
);
|
||||
expect(result.details.success).toBe(true);
|
||||
expect(result.content[0].text).toContain("# Context bundle: test");
|
||||
expect(result.content[0].text).toContain("## relevant indexes");
|
||||
expect(result.content[0].text).toContain("## instructions");
|
||||
});
|
||||
|
||||
it("returns no-results bundle when no maps match", async () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "pi-ext-test-"));
|
||||
mockCtx.cwd = dir;
|
||||
|
||||
const tool = registeredTools.project_map_context;
|
||||
const result = await tool.execute(
|
||||
"tool-1",
|
||||
{ query: "nonexistent" },
|
||||
null,
|
||||
null,
|
||||
mockCtx,
|
||||
);
|
||||
expect(result.details.success).toBe(true);
|
||||
expect(result.content[0].text).toContain("No relevant directories found");
|
||||
});
|
||||
});
|
||||
|
||||
describe("session_start event", () => {
|
||||
it("notifies when dirty .pi-map.md files exist", async () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "pi-ext-test-"));
|
||||
@@ -221,7 +271,7 @@ describe("pi-extension", () => {
|
||||
});
|
||||
|
||||
describe("before_agent_start event", () => {
|
||||
it("injects hint when .pi-map.md files exist", async () => {
|
||||
it("injects layered protocol hint when project map files exist", async () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "pi-ext-test-"));
|
||||
writeFileSync(join(dir, ".pi-map.md"), "# .\n## role\nTest\n");
|
||||
mockCtx.cwd = dir;
|
||||
@@ -230,7 +280,9 @@ describe("pi-extension", () => {
|
||||
const result = await handler(null, mockCtx);
|
||||
|
||||
expect(result).toHaveProperty("message");
|
||||
expect(result.message.content).toContain("root `.pi-map.index.md`");
|
||||
expect(result.message.content).toContain("project_map_patch");
|
||||
expect(result.message.content).toContain("project_map_validate");
|
||||
expect(result.message.display).toBe(false);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user