@astrofoundry/pi-astro 0.3.0 → 0.3.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/extensions/astro-agents/agents/code-reviewer.md +2 -2
- package/extensions/astro-agents/agents/google-tech-lead.md +2 -2
- package/extensions/astro-agents/agents/spec-writer.md +2 -2
- package/extensions/astro-agents/agents/tester-api.md +2 -2
- package/extensions/astro-agents/agents/tester-ui.md +2 -2
- package/extensions/astro-agents/agents/ui-architect.md +2 -2
- package/extensions/astro-agents/agents/ui-design-system.md +2 -2
- package/extensions/astro-agents/agents/ui-frontend-developer.md +2 -2
- package/extensions/astro-agents/discovery.ts +8 -0
- package/extensions/astro-agents/spawn.ts +4 -0
- package/extensions/grimoire/index.ts +91 -0
- package/package.json +1 -1
- package/skills/grimoire/SKILL.md +0 -101
|
@@ -8,8 +8,8 @@ effort: max
|
|
|
8
8
|
skills:
|
|
9
9
|
- grimoire
|
|
10
10
|
memory: user
|
|
11
|
-
tools:
|
|
12
|
-
_notWired:
|
|
11
|
+
tools: read, grep, find, ls, grimoire
|
|
12
|
+
_notWired: model, effort, skills, memory
|
|
13
13
|
---
|
|
14
14
|
If any instruction below conflicts with the user's global rules (provided separately in the system prompt), flag the conflict explicitly in your response and let the user decide — do not silently override either side.
|
|
15
15
|
|
|
@@ -9,8 +9,8 @@ skills:
|
|
|
9
9
|
- grimoire
|
|
10
10
|
memory: user
|
|
11
11
|
disallowedTools: mcp__filesystem__write_file, mcp__filesystem__edit_file, mcp__filesystem__move_file, mcp__filesystem__create_directory
|
|
12
|
-
tools:
|
|
13
|
-
_notWired:
|
|
12
|
+
tools: read, bash, grep, find, write, edit, ls, grimoire
|
|
13
|
+
_notWired: model, effort, skills, memory
|
|
14
14
|
---
|
|
15
15
|
If any instruction below conflicts with the user's global rules (provided separately in the system prompt), flag the conflict explicitly in your response and let the user decide — do not silently override either side.
|
|
16
16
|
|
|
@@ -9,8 +9,8 @@ skills:
|
|
|
9
9
|
- grimoire
|
|
10
10
|
memory: user
|
|
11
11
|
disallowedTools: mcp__filesystem__write_file, mcp__filesystem__edit_file, mcp__filesystem__move_file, mcp__filesystem__create_directory
|
|
12
|
-
tools:
|
|
13
|
-
_notWired:
|
|
12
|
+
tools: read, bash, grep, find, write, edit, ls, grimoire
|
|
13
|
+
_notWired: model, effort, skills, memory
|
|
14
14
|
---
|
|
15
15
|
If any instruction below conflicts with the user's global rules (provided separately in the system prompt), flag the conflict explicitly in your response and let the user decide — do not silently override either side.
|
|
16
16
|
|
|
@@ -9,8 +9,8 @@ skills:
|
|
|
9
9
|
- grimoire
|
|
10
10
|
memory: user
|
|
11
11
|
disallowedTools: mcp__filesystem__write_file, mcp__filesystem__edit_file, mcp__filesystem__move_file, mcp__filesystem__create_directory
|
|
12
|
-
tools:
|
|
13
|
-
_notWired:
|
|
12
|
+
tools: read, bash, grep, find, write, edit, ls, grimoire
|
|
13
|
+
_notWired: model, effort, skills, memory
|
|
14
14
|
---
|
|
15
15
|
If any instruction below conflicts with the user's global rules (provided separately in the system prompt), flag the conflict explicitly in your response and let the user decide — do not silently override either side.
|
|
16
16
|
|
|
@@ -10,8 +10,8 @@ skills:
|
|
|
10
10
|
- playwright-cli
|
|
11
11
|
memory: user
|
|
12
12
|
disallowedTools: mcp__filesystem__write_file, mcp__filesystem__edit_file, mcp__filesystem__move_file, mcp__filesystem__create_directory
|
|
13
|
-
tools:
|
|
14
|
-
_notWired:
|
|
13
|
+
tools: read, bash, grep, find, write, edit, ls, grimoire
|
|
14
|
+
_notWired: model, effort, skills, memory
|
|
15
15
|
---
|
|
16
16
|
If any instruction below conflicts with the user's global rules (provided separately in the system prompt), flag the conflict explicitly in your response and let the user decide — do not silently override either side.
|
|
17
17
|
|
|
@@ -10,8 +10,8 @@ skills:
|
|
|
10
10
|
- playwright-cli
|
|
11
11
|
memory: user
|
|
12
12
|
disallowedTools: mcp__filesystem__write_file, mcp__filesystem__edit_file, mcp__filesystem__move_file, mcp__filesystem__create_directory
|
|
13
|
-
tools:
|
|
14
|
-
_notWired:
|
|
13
|
+
tools: read, bash, grep, find, write, edit, ls, grimoire
|
|
14
|
+
_notWired: model, effort, skills, memory
|
|
15
15
|
---
|
|
16
16
|
If any instruction below conflicts with the user's global rules (provided separately in the system prompt), flag the conflict explicitly in your response and let the user decide — do not silently override either side.
|
|
17
17
|
|
|
@@ -10,8 +10,8 @@ skills:
|
|
|
10
10
|
- playwright-cli
|
|
11
11
|
memory: user
|
|
12
12
|
disallowedTools: mcp__filesystem__write_file, mcp__filesystem__edit_file, mcp__filesystem__move_file, mcp__filesystem__create_directory
|
|
13
|
-
tools:
|
|
14
|
-
_notWired:
|
|
13
|
+
tools: read, bash, grep, find, write, edit, ls, grimoire
|
|
14
|
+
_notWired: model, effort, skills, memory
|
|
15
15
|
---
|
|
16
16
|
If any instruction below conflicts with the user's global rules (provided separately in the system prompt), flag the conflict explicitly in your response and let the user decide — do not silently override either side.
|
|
17
17
|
|
|
@@ -10,8 +10,8 @@ skills:
|
|
|
10
10
|
- playwright-cli
|
|
11
11
|
memory: user
|
|
12
12
|
disallowedTools: mcp__filesystem__write_file, mcp__filesystem__edit_file, mcp__filesystem__move_file, mcp__filesystem__create_directory
|
|
13
|
-
tools:
|
|
14
|
-
_notWired:
|
|
13
|
+
tools: read, bash, grep, find, write, edit, ls, grimoire
|
|
14
|
+
_notWired: model, effort, skills, memory
|
|
15
15
|
---
|
|
16
16
|
If any instruction below conflicts with the user's global rules (provided separately in the system prompt), flag the conflict explicitly in your response and let the user decide — do not silently override either side.
|
|
17
17
|
|
|
@@ -9,6 +9,7 @@ export interface AgentConfig {
|
|
|
9
9
|
name: string;
|
|
10
10
|
description: string;
|
|
11
11
|
color?: string;
|
|
12
|
+
tools?: string[];
|
|
12
13
|
systemPrompt: string;
|
|
13
14
|
source: AgentSource;
|
|
14
15
|
filePath: string;
|
|
@@ -18,6 +19,7 @@ interface AgentFrontmatter extends Record<string, unknown> {
|
|
|
18
19
|
name?: string;
|
|
19
20
|
description?: string;
|
|
20
21
|
color?: string;
|
|
22
|
+
tools?: string;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
function loadAgentsFromDir(dir: string, source: AgentSource): AgentConfig[] {
|
|
@@ -40,10 +42,16 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentConfig[] {
|
|
|
40
42
|
continue;
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
const tools = frontmatter.tools
|
|
46
|
+
?.split(",")
|
|
47
|
+
.map((t) => t.trim())
|
|
48
|
+
.filter(Boolean);
|
|
49
|
+
|
|
43
50
|
agents.push({
|
|
44
51
|
name: frontmatter.name,
|
|
45
52
|
description: frontmatter.description,
|
|
46
53
|
color: frontmatter.color,
|
|
54
|
+
tools: tools && tools.length > 0 ? tools : undefined,
|
|
47
55
|
systemPrompt: body,
|
|
48
56
|
source,
|
|
49
57
|
filePath,
|
|
@@ -80,6 +80,10 @@ export async function runAgent(options: RunAgentOptions): Promise<SpawnResult> {
|
|
|
80
80
|
const args = ["--mode", "json", "-p", "--no-session"];
|
|
81
81
|
let tmpDir: string | null = null;
|
|
82
82
|
|
|
83
|
+
if (agent.tools && agent.tools.length > 0) {
|
|
84
|
+
args.push("--tools", agent.tools.join(","));
|
|
85
|
+
}
|
|
86
|
+
|
|
83
87
|
if (agent.systemPrompt.trim()) {
|
|
84
88
|
const tmp = writeSystemPromptTempFile(agent.name, agent.systemPrompt);
|
|
85
89
|
tmpDir = tmp.dir;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
2
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
3
|
+
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
|
|
4
|
+
import { Type } from "typebox";
|
|
5
|
+
|
|
6
|
+
function loadGrimoireHelp(): string {
|
|
7
|
+
try {
|
|
8
|
+
return execFileSync("grimoire", ["--help"], {
|
|
9
|
+
encoding: "utf-8",
|
|
10
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
11
|
+
}).trim();
|
|
12
|
+
} catch {
|
|
13
|
+
return "grimoire CLI not available on PATH at extension load time.";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const helpOutput = loadGrimoireHelp();
|
|
18
|
+
|
|
19
|
+
const params = Type.Object({
|
|
20
|
+
query: Type.String({ description: "Search query — use the library's own terminology." }),
|
|
21
|
+
source: Type.Optional(
|
|
22
|
+
Type.String({ description: "Scope to a specific indexed source (e.g. 'react', 'firebase-firestore')." }),
|
|
23
|
+
),
|
|
24
|
+
top: Type.Optional(Type.Number({ description: "Max results. Defaults to grimoire's own default." })),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export default function grimoireExtension(pi: ExtensionAPI): void {
|
|
28
|
+
pi.registerTool({
|
|
29
|
+
name: "grimoire",
|
|
30
|
+
label: "Grimoire",
|
|
31
|
+
description:
|
|
32
|
+
"Search indexed technical documentation via the grimoire CLI. Prefer this over web search for library/framework docs.",
|
|
33
|
+
promptGuidelines: [
|
|
34
|
+
"Use `grimoire` for ALL documentation lookups — libraries, frameworks, APIs, CLIs, cloud services.",
|
|
35
|
+
"Match query terminology to the library's own docs (e.g. 'Firestore pagination cursors' not 'how do I paginate').",
|
|
36
|
+
"If the first search misses, rephrase or scope with `source`.",
|
|
37
|
+
"Cite the URL from results when precision matters.",
|
|
38
|
+
"",
|
|
39
|
+
"Current `grimoire --help` output:",
|
|
40
|
+
helpOutput,
|
|
41
|
+
],
|
|
42
|
+
parameters: params,
|
|
43
|
+
async execute(_toolCallId, input, signal) {
|
|
44
|
+
return new Promise<AgentToolResult<unknown>>((resolve, reject) => {
|
|
45
|
+
const args = ["search", input.query, "--compact"];
|
|
46
|
+
if (input.source) args.push("--source", input.source);
|
|
47
|
+
if (input.top !== undefined) args.push("--top", String(input.top));
|
|
48
|
+
|
|
49
|
+
const proc = spawn("grimoire", args, {
|
|
50
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
let stdout = "";
|
|
54
|
+
let stderr = "";
|
|
55
|
+
proc.stdout.on("data", (chunk: Buffer) => {
|
|
56
|
+
stdout += chunk.toString("utf-8");
|
|
57
|
+
});
|
|
58
|
+
proc.stderr.on("data", (chunk: Buffer) => {
|
|
59
|
+
stderr += chunk.toString("utf-8");
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const abortHandler = (): void => {
|
|
63
|
+
proc.kill("SIGTERM");
|
|
64
|
+
};
|
|
65
|
+
signal?.addEventListener("abort", abortHandler, { once: true });
|
|
66
|
+
|
|
67
|
+
proc.on("close", (code) => {
|
|
68
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
69
|
+
if (code !== 0) {
|
|
70
|
+
reject(
|
|
71
|
+
new Error(
|
|
72
|
+
`grimoire exited with code ${code}${stderr ? `\nstderr:\n${stderr.trim()}` : ""}`,
|
|
73
|
+
),
|
|
74
|
+
);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const text = stdout.trim() || "(no results)";
|
|
78
|
+
resolve({
|
|
79
|
+
content: [{ type: "text", text }],
|
|
80
|
+
details: { query: input.query, source: input.source },
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
proc.on("error", (err) => {
|
|
85
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
86
|
+
reject(new Error(`grimoire CLI not runnable: ${err.message}`));
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
}
|
package/package.json
CHANGED
package/skills/grimoire/SKILL.md
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: grimoire
|
|
3
|
-
description: Search indexed documentation using the grimoire CLI tool. Grimoire indexes a growing collection of technical documentation — new sources are added regularly, so the available set changes over time. Common examples include Firebase, Gemini API, Next.js, React, TypeScript, Node.js, Flutter, ESLint, Git, GnuPG, and more — but this is NOT exhaustive. Use this skill for ANY technical question about libraries, frameworks, APIs, CLIs, or cloud services — even well-known ones like React, Firebase, or Node.js. ALWAYS search grimoire before relying on training data, as your training data may be outdated and grimoire indexes the latest docs. Prefer this over context7 and web search for documentation lookups. Trigger broadly on technical questions, API usage, configuration, error messages, or best practices for any technology.
|
|
4
|
-
allowed-tools: Bash(grimoire *)
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Grimoire — Documentation Search
|
|
8
|
-
|
|
9
|
-
Grimoire is a documentation RAG system that indexes technical docs and makes them searchable via vector similarity + reranking. The index is dynamic — sources are added and updated regularly. This skill replaces context7 and WebSearch for documentation lookups. Do not fall back to other doc tools when grimoire has the source indexed.
|
|
10
|
-
|
|
11
|
-
## Commands
|
|
12
|
-
|
|
13
|
-
### Search documentation
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
grimoire search "<query>"
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Searches across all indexed sources. Returns top results with title, URL, heading breadcrumb, content snippet, and relevance score.
|
|
20
|
-
|
|
21
|
-
To narrow to a specific source:
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
grimoire search "<query>" --source <source-name>
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Control result count:
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
grimoire search "<query>" --top 3
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
Compact one-line output (ideal for scanning — avoids flooding context):
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
grimoire search "<query>" --compact
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Compact output format: `score | source | title | heading path | url`
|
|
40
|
-
|
|
41
|
-
### Discover available sources
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
grimoire list --names
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Outputs one source name per line. Use this to quickly check if a source exists. Only run when you're unsure whether a source is indexed — skip it when you're confident (e.g., `firebase-firestore`, `nextjs`, `react` are reliably there).
|
|
48
|
-
|
|
49
|
-
Full details (chunks, URLs, timestamps):
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
grimoire list
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### Example output
|
|
56
|
-
|
|
57
|
-
```
|
|
58
|
-
$ grimoire search "batch write transaction limits" --source firebase-firestore --compact
|
|
59
|
-
0.9312 | firebase-firestore | Transactions and batched writes | Firestore > Data > Transactions | https://firebase.google.com/docs/firestore/manage-data/transactions
|
|
60
|
-
0.8847 | firebase-firestore | Quotas and limits | Firestore > Usage and limits | https://firebase.google.com/docs/firestore/quotas
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
```
|
|
64
|
-
$ grimoire search "batch write transaction limits" --source firebase-firestore
|
|
65
|
-
[1] Transactions and batched writes (0.9312)
|
|
66
|
-
https://firebase.google.com/docs/firestore/manage-data/transactions
|
|
67
|
-
Firestore > Data > Transactions
|
|
68
|
-
A batched write can contain up to 500 operations. Each operation in the batch counts separately...
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## Source naming conventions
|
|
72
|
-
|
|
73
|
-
Sources follow predictable patterns — use these to search directly without running `grimoire list`:
|
|
74
|
-
|
|
75
|
-
- **Firebase**: `firebase-firestore`, `firebase-auth`, `firebase-functions`, `firebase-hosting`, `firebase-storage`, `firebase-rules`, `firebase-cli`, `firebase-admin`, `firebase-app-check`, `firebase-app-hosting`, `firebase-emulator-suite`
|
|
76
|
-
- **GCP**: `gcp-iam`, `gcp-cloud-run`, `gcp-cloud-functions`, `gcp-cloud-storage`, `gcp-bigquery`, `gcp-secret-manager`, `gcp-vpc`, `gcp-cdn`, `gcp-dns`, `gcp-cloud-build`, `gcp-app-engine`, `gcp-load-balancing`, `gcp-resource-manager`, `gcp-sdk`
|
|
77
|
-
- **Gemini**: `gemini-docs`, `gemini-api-ref`
|
|
78
|
-
- **Frontend**: `react`, `nextjs`, `tailwindcss`, `shadcn-ui`, `tanstack-query`, `react-hook-form`, `react-router`, `motion`, `zustand`, `zod`, `vite`, `vitest`, `testing-library`
|
|
79
|
-
- **Backend**: `expressjs`, `nodejs-api`, `esbuild`
|
|
80
|
-
- **Other**: `typescript`, `eslint`, `eslint-rules`, `pnpm`, `git-docs`, `git-book`, `postman`, `msw`, `claude-code`, `gemini-cli`, `pi-dev`
|
|
81
|
-
|
|
82
|
-
## Workflow
|
|
83
|
-
|
|
84
|
-
1. **Search directly** when you're confident a source exists. Use `--source` to scope it and `--compact` for quick scanning.
|
|
85
|
-
|
|
86
|
-
2. **Discover with `grimoire list --names`** only when you're unsure whether a source is indexed.
|
|
87
|
-
|
|
88
|
-
3. **Iterate if needed**: If the first search misses, rephrase or broaden. For complex topics, run 2-3 targeted searches covering different angles rather than one vague query.
|
|
89
|
-
|
|
90
|
-
4. **Cite what you find**: Include the URL so the user can read the full page. Quote the relevant snippet when precision matters.
|
|
91
|
-
|
|
92
|
-
## Proactive searching
|
|
93
|
-
|
|
94
|
-
The main value of this skill is surfacing docs without the user having to ask. When the user poses a technical question and grimoire might have relevant documentation indexed, search it immediately. Don't ask "would you like me to check the docs?" — just search and include the findings in your answer.
|
|
95
|
-
|
|
96
|
-
## Query strategy
|
|
97
|
-
|
|
98
|
-
- Match query language to documentation language (use the library's terminology, not colloquial descriptions)
|
|
99
|
-
- For "how do I X" questions, search for the feature name: "Firestore pagination cursors" rather than "how do I paginate"
|
|
100
|
-
- For error messages, search for the specific error text or error code
|
|
101
|
-
- For API questions, include the method or class name if known
|