@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.
@@ -8,8 +8,8 @@ effort: max
8
8
  skills:
9
9
  - grimoire
10
10
  memory: user
11
- tools: Read, Bash, Grep, Glob, Skill, mcp__filesystem__read_file, mcp__filesystem__directory_tree, mcp__filesystem__list_directory, mcp__filesystem__search_files, mcp__filesystem__get_file_info
12
- _notWired: tools, model, effort, skills, memory
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: Write, Read, MultiEdit, Bash, Grep, Glob, Skill, mcp__filesystem__read_file, mcp__filesystem__directory_tree, mcp__filesystem__list_directory, mcp__filesystem__search_files, mcp__filesystem__get_file_info
13
- _notWired: tools, model, effort, skills, memory
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: Write, Read, MultiEdit, Bash, Grep, Glob, Skill, mcp__filesystem__read_file, mcp__filesystem__directory_tree, mcp__filesystem__list_directory, mcp__filesystem__search_files, mcp__filesystem__get_file_info
13
- _notWired: tools, model, effort, skills, memory
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: Write, Read, MultiEdit, Bash, Grep, Glob, Skill, mcp__filesystem__read_file, mcp__filesystem__directory_tree, mcp__filesystem__list_directory, mcp__filesystem__search_files, mcp__filesystem__get_file_info
13
- _notWired: tools, model, effort, skills, memory
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: Write, Read, MultiEdit, Bash, Grep, Glob, Skill, mcp__filesystem__read_file, mcp__filesystem__directory_tree, mcp__filesystem__list_directory, mcp__filesystem__search_files, mcp__filesystem__get_file_info
14
- _notWired: tools, model, effort, skills, memory
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: Write, Read, MultiEdit, Bash, Grep, Glob, Skill, mcp__filesystem__read_file, mcp__filesystem__directory_tree, mcp__filesystem__list_directory, mcp__filesystem__search_files, mcp__filesystem__get_file_info
14
- _notWired: tools, model, effort, skills, memory
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: Write, Read, MultiEdit, Bash, Grep, Glob, Skill, mcp__filesystem__read_file, mcp__filesystem__directory_tree, mcp__filesystem__list_directory, mcp__filesystem__search_files, mcp__filesystem__get_file_info
14
- _notWired: tools, model, effort, skills, memory
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: Write, Read, MultiEdit, Bash, Grep, Glob, Skill, mcp__filesystem__read_file, mcp__filesystem__directory_tree, mcp__filesystem__list_directory, mcp__filesystem__search_files, mcp__filesystem__get_file_info
14
- _notWired: tools, model, effort, skills, memory
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrofoundry/pi-astro",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Personal pi customizations (extensions, skills, prompts, themes) for the pi coding agent.",
5
5
  "keywords": [
6
6
  "pi-package"
@@ -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