@oh-my-pi/cli 0.3.0 → 0.4.0

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.
Files changed (48) hide show
  1. package/.editorconfig +14 -0
  2. package/.prettierrc +6 -0
  3. package/README.md +65 -71
  4. package/bun.lock +13 -10
  5. package/dist/cli.js +114 -34
  6. package/dist/commands/config.d.ts.map +1 -1
  7. package/dist/commands/features.d.ts.map +1 -1
  8. package/dist/commands/install.d.ts.map +1 -1
  9. package/dist/commands/list.d.ts.map +1 -1
  10. package/dist/commands/uninstall.d.ts.map +1 -1
  11. package/dist/commands/update.d.ts.map +1 -1
  12. package/dist/runtime.d.ts.map +1 -1
  13. package/dist/symlinks.d.ts +1 -0
  14. package/dist/symlinks.d.ts.map +1 -1
  15. package/package.json +11 -4
  16. package/plugins/exa/README.md +44 -38
  17. package/plugins/exa/package.json +44 -11
  18. package/plugins/exa/tools/exa/company.ts +24 -13
  19. package/plugins/exa/tools/exa/index.ts +43 -34
  20. package/plugins/exa/tools/exa/linkedin.ts +24 -13
  21. package/plugins/exa/tools/exa/researcher.ts +26 -18
  22. package/plugins/exa/tools/exa/search.ts +31 -20
  23. package/plugins/exa/tools/exa/shared.ts +182 -156
  24. package/plugins/exa/tools/exa/websets.ts +39 -28
  25. package/plugins/metal-theme/package.json +13 -4
  26. package/plugins/subagents/README.md +3 -0
  27. package/plugins/subagents/agents/explore.md +11 -0
  28. package/plugins/subagents/agents/planner.md +3 -0
  29. package/plugins/subagents/agents/reviewer.md +6 -0
  30. package/plugins/subagents/agents/task.md +8 -1
  31. package/plugins/subagents/commands/architect-plan.md +1 -0
  32. package/plugins/subagents/commands/implement-with-critic.md +1 -0
  33. package/plugins/subagents/commands/implement.md +1 -0
  34. package/plugins/subagents/package.json +43 -11
  35. package/plugins/subagents/tools/task/index.ts +1089 -861
  36. package/plugins/user-prompt/README.md +22 -66
  37. package/plugins/user-prompt/package.json +15 -4
  38. package/plugins/user-prompt/tools/user-prompt/index.ts +185 -157
  39. package/scripts/bump-version.sh +10 -13
  40. package/src/cli.ts +1 -1
  41. package/src/commands/config.ts +21 -6
  42. package/src/commands/features.ts +49 -12
  43. package/src/commands/install.ts +91 -24
  44. package/src/commands/list.ts +14 -3
  45. package/src/commands/uninstall.ts +4 -1
  46. package/src/commands/update.ts +6 -1
  47. package/src/runtime.ts +3 -10
  48. package/src/symlinks.ts +12 -7
@@ -1 +1 @@
1
- {"version":3,"file":"symlinks.d.ts","sourceRoot":"","sources":["../src/symlinks.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAKzG;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,GAAG,eAAe,EAAE,CAE/E;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACvC,OAAO,EAAE,iBAAiB,EAC1B,gBAAgB,CAAC,EAAE,MAAM,EAAE,GACzB,eAAe,EAAE,CAEnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAEvE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAIjF;AAgCD,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACzC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,iBAAiB,EAC1B,MAAM,UAAO,EACb,OAAO,UAAO,EACd,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAC9B,eAAe,CAAC,EAAE,MAAM,EAAE,GACxB,OAAO,CAAC,aAAa,CAAC,CAwHxB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,mBAAmB,CAO1E;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACvC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,mBAAmB,EAC3B,OAAO,UAAQ,GACb,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAO,GAAG,MAAM,GAAG,IAAI,CAK7F;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACzC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,iBAAiB,EAC1B,MAAM,UAAO,EACb,OAAO,UAAO,GACZ,OAAO,CAAC,oBAAoB,CAAC,CAkE/B;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACxC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,iBAAiB,EAC1B,MAAM,UAAO,GACX,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAwDnE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACxC,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAC9C,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWxB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACvC,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAChD,MAAM,UAAO,GACX,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,eAAe,CAAA;CAAE,GAAG,IAAI,CAAC,CAmB5D"}
1
+ {"version":3,"file":"symlinks.d.ts","sourceRoot":"","sources":["../src/symlinks.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAKzG;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,GAAG,eAAe,EAAE,CAE/E;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE,CAEnH;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAEvE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAIjF;AAgCD,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACzC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,iBAAiB,EAC1B,MAAM,UAAO,EACb,OAAO,UAAO,EACd,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAC9B,eAAe,CAAC,EAAE,MAAM,EAAE,GACxB,OAAO,CAAC,aAAa,CAAC,CAwHxB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,mBAAmB,CAS1E;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACvC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,mBAAmB,EAC3B,OAAO,UAAQ,GACb,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAO,GAAG,MAAM,GAAG,IAAI,CAK7F;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACzC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,iBAAiB,EAC1B,MAAM,UAAO,EACb,OAAO,UAAO,GACZ,OAAO,CAAC,oBAAoB,CAAC,CAsE/B;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACxC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,iBAAiB,EAC1B,MAAM,UAAO,GACX,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA4DnE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACxC,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAC9C,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWxB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACvC,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAChD,MAAM,UAAO,GACX,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,eAAe,CAAA;CAAE,GAAG,IAAI,CAAC,CAmB5D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oh-my-pi/cli",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Plugin manager for pi - install and manage pi config plugins from git repos",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -12,13 +12,19 @@
12
12
  "build": "bun build src/cli.ts --outdir dist --target bun && tsc --emitDeclarationOnly",
13
13
  "dev": "bun --watch src/cli.ts",
14
14
  "lint": "biome check --write .",
15
- "check": "bun run lint && tsc --noEmit",
15
+ "format": "prettier --write \"**/*.md\" && biome check --write .",
16
+ "check": "bun run format && tsc --noEmit",
16
17
  "clean": "rm -rf dist",
17
18
  "publish:all": "./scripts/publish.sh",
18
19
  "publish:dry": "./scripts/publish.sh --dry-run",
19
20
  "version:bump": "./scripts/bump-version.sh"
20
21
  },
21
- "keywords": ["pi", "plugin", "manager", "cli"],
22
+ "keywords": [
23
+ "pi",
24
+ "plugin",
25
+ "manager",
26
+ "cli"
27
+ ],
22
28
  "author": "Can Bölük <me@can.ac>",
23
29
  "license": "MIT",
24
30
  "repository": {
@@ -26,9 +32,10 @@
26
32
  "url": "https://github.com/can1357/oh-my-pi.git"
27
33
  },
28
34
  "devDependencies": {
29
- "@biomejs/biome": "2.3.5",
35
+ "@biomejs/biome": "2.3.10",
30
36
  "@types/node": "^22.10.5",
31
37
  "bun-types": "^1.2.17",
38
+ "prettier": "^3.7.4",
32
39
  "typescript": "^5.9.2"
33
40
  },
34
41
  "dependencies": {
@@ -17,13 +17,13 @@ omp install @oh-my-pi/exa[search,linkedin,websets]
17
17
 
18
18
  ## Features
19
19
 
20
- | Feature | Default | Description | Tools |
21
- |---------|---------|-------------|-------|
22
- | `search` | ✓ | Core web search capabilities | 4 tools |
23
- | `linkedin` | | LinkedIn profile and company search | 1 tool |
24
- | `company` | | Comprehensive company research | 1 tool |
25
- | `researcher` | | Long-running AI research tasks | 2 tools |
26
- | `websets` | | Entity collection management | 14 tools |
20
+ | Feature | Default | Description | Tools |
21
+ | ------------ | ------- | ----------------------------------- | -------- |
22
+ | `search` | ✓ | Core web search capabilities | 4 tools |
23
+ | `linkedin` | | LinkedIn profile and company search | 1 tool |
24
+ | `company` | | Comprehensive company research | 1 tool |
25
+ | `researcher` | | Long-running AI research tasks | 2 tools |
26
+ | `websets` | | Entity collection management | 14 tools |
27
27
 
28
28
  Manage features after install:
29
29
 
@@ -62,76 +62,81 @@ Get your API key from: https://dashboard.exa.ai/api-keys
62
62
 
63
63
  ### search (default)
64
64
 
65
- | Tool | Description |
66
- |------|-------------|
67
- | `web_search_general` | Real-time web searches with content extraction |
68
- | `web_search_deep` | Natural language web search with synthesized results |
69
- | `web_search_code_context` | Search code snippets, docs, and examples |
70
- | `web_search_crawl_url` | Extract content from specific URLs |
65
+ | Tool | Description |
66
+ | ------------------------- | ---------------------------------------------------- |
67
+ | `web_search_general` | Real-time web searches with content extraction |
68
+ | `web_search_deep` | Natural language web search with synthesized results |
69
+ | `web_search_code_context` | Search code snippets, docs, and examples |
70
+ | `web_search_crawl_url` | Extract content from specific URLs |
71
71
 
72
72
  ### linkedin
73
73
 
74
- | Tool | Description |
75
- |------|-------------|
74
+ | Tool | Description |
75
+ | --------------------- | -------------------------------------- |
76
76
  | `web_search_linkedin` | Search LinkedIn profiles and companies |
77
77
 
78
78
  ### company
79
79
 
80
- | Tool | Description |
81
- |------|-------------|
80
+ | Tool | Description |
81
+ | ----------------------------- | ------------------------------ |
82
82
  | `web_search_company_research` | Comprehensive company research |
83
83
 
84
84
  ### researcher
85
85
 
86
- | Tool | Description |
87
- |------|-------------|
86
+ | Tool | Description |
87
+ | ----------------------------- | -------------------------------------------- |
88
88
  | `web_search_researcher_start` | Start comprehensive AI-powered research task |
89
- | `web_search_researcher_check` | Check research task status and get results |
89
+ | `web_search_researcher_check` | Check research task status and get results |
90
90
 
91
91
  ### websets
92
92
 
93
- | Tool | Description |
94
- |------|-------------|
95
- | `webset_create` | Create entity collections with search and enrichments |
96
- | `webset_list` | List all websets in your account |
97
- | `webset_get` | Get detailed webset information |
98
- | `webset_update` | Update webset metadata |
99
- | `webset_delete` | Delete a webset |
100
- | `webset_items_list` | List items in a webset |
101
- | `webset_item_get` | Get item details |
102
- | `webset_search_create` | Add search to find entities for a webset |
103
- | `webset_search_get` | Check search status |
104
- | `webset_search_cancel` | Cancel running search |
105
- | `webset_enrichment_create` | Extract custom data from webset items |
106
- | `webset_enrichment_get` | Get enrichment details |
107
- | `webset_enrichment_update` | Update enrichment metadata |
108
- | `webset_enrichment_delete` | Delete enrichment |
109
- | `webset_enrichment_cancel` | Cancel running enrichment |
110
- | `webset_monitor_create` | Auto-update webset on schedule |
93
+ | Tool | Description |
94
+ | -------------------------- | ----------------------------------------------------- |
95
+ | `webset_create` | Create entity collections with search and enrichments |
96
+ | `webset_list` | List all websets in your account |
97
+ | `webset_get` | Get detailed webset information |
98
+ | `webset_update` | Update webset metadata |
99
+ | `webset_delete` | Delete a webset |
100
+ | `webset_items_list` | List items in a webset |
101
+ | `webset_item_get` | Get item details |
102
+ | `webset_search_create` | Add search to find entities for a webset |
103
+ | `webset_search_get` | Check search status |
104
+ | `webset_search_cancel` | Cancel running search |
105
+ | `webset_enrichment_create` | Extract custom data from webset items |
106
+ | `webset_enrichment_get` | Get enrichment details |
107
+ | `webset_enrichment_update` | Update enrichment metadata |
108
+ | `webset_enrichment_delete` | Delete enrichment |
109
+ | `webset_enrichment_cancel` | Cancel running enrichment |
110
+ | `webset_monitor_create` | Auto-update webset on schedule |
111
111
 
112
112
  ## Usage Examples
113
113
 
114
114
  ### Code Search
115
+
115
116
  ```
116
117
  Find examples of how to use React hooks with TypeScript
117
118
  ```
118
119
 
119
120
  ### Web Search
121
+
120
122
  ```
121
123
  Search for the latest news about AI regulation in the EU
122
124
  ```
123
125
 
124
126
  ### Company Research (requires company feature)
127
+
125
128
  ```
126
129
  Research the company OpenAI and find information about their products
127
130
  ```
128
131
 
129
132
  ### Deep Research (requires researcher feature)
133
+
130
134
  ```
131
135
  Start a deep research project on the impact of large language models on software development
132
136
  ```
133
137
 
134
138
  ### Websets (requires websets feature)
139
+
135
140
  ```
136
141
  Create a webset of AI startups in San Francisco founded after 2020,
137
142
  find 10 companies and enrich with CEO name and funding amount
@@ -140,6 +145,7 @@ find 10 companies and enrich with CEO name and funding amount
140
145
  ## How It Works
141
146
 
142
147
  The plugin connects to Exa's hosted MCP (Model Context Protocol) servers:
148
+
143
149
  - `https://mcp.exa.ai/mcp` - Search tools
144
150
  - `https://websetsmcp.exa.ai/mcp` - Websets tools
145
151
 
@@ -1,8 +1,14 @@
1
1
  {
2
2
  "name": "@oh-my-pi/exa",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Exa AI web search and websets tools for pi",
5
- "keywords": ["omp-plugin", "exa", "web-search", "websets", "ai-search"],
5
+ "keywords": [
6
+ "omp-plugin",
7
+ "exa",
8
+ "web-search",
9
+ "websets",
10
+ "ai-search"
11
+ ],
6
12
  "author": "Can Bölük <me@can.ac>",
7
13
  "license": "MIT",
8
14
  "repository": {
@@ -12,14 +18,39 @@
12
18
  },
13
19
  "omp": {
14
20
  "install": [
15
- { "src": "tools/exa/runtime.json", "dest": "agent/tools/exa/runtime.json", "copy": true },
16
- { "src": "tools/exa/index.ts", "dest": "agent/tools/exa/index.ts" },
17
- { "src": "tools/exa/shared.ts", "dest": "agent/tools/exa/shared.ts" },
18
- { "src": "tools/exa/search.ts", "dest": "agent/tools/exa/search.ts" },
19
- { "src": "tools/exa/linkedin.ts", "dest": "agent/tools/exa/linkedin.ts" },
20
- { "src": "tools/exa/company.ts", "dest": "agent/tools/exa/company.ts" },
21
- { "src": "tools/exa/researcher.ts", "dest": "agent/tools/exa/researcher.ts" },
22
- { "src": "tools/exa/websets.ts", "dest": "agent/tools/exa/websets.ts" }
21
+ {
22
+ "src": "tools/exa/runtime.json",
23
+ "dest": "agent/tools/exa/runtime.json",
24
+ "copy": true
25
+ },
26
+ {
27
+ "src": "tools/exa/index.ts",
28
+ "dest": "agent/tools/exa/index.ts"
29
+ },
30
+ {
31
+ "src": "tools/exa/shared.ts",
32
+ "dest": "agent/tools/exa/shared.ts"
33
+ },
34
+ {
35
+ "src": "tools/exa/search.ts",
36
+ "dest": "agent/tools/exa/search.ts"
37
+ },
38
+ {
39
+ "src": "tools/exa/linkedin.ts",
40
+ "dest": "agent/tools/exa/linkedin.ts"
41
+ },
42
+ {
43
+ "src": "tools/exa/company.ts",
44
+ "dest": "agent/tools/exa/company.ts"
45
+ },
46
+ {
47
+ "src": "tools/exa/researcher.ts",
48
+ "dest": "agent/tools/exa/researcher.ts"
49
+ },
50
+ {
51
+ "src": "tools/exa/websets.ts",
52
+ "dest": "agent/tools/exa/websets.ts"
53
+ }
23
54
  ],
24
55
  "variables": {
25
56
  "apiKey": {
@@ -52,5 +83,7 @@
52
83
  }
53
84
  }
54
85
  },
55
- "files": ["tools"]
86
+ "files": [
87
+ "tools"
88
+ ]
56
89
  }
@@ -6,30 +6,41 @@
6
6
  */
7
7
 
8
8
  import type { TSchema } from "@sinclair/typebox";
9
- import type { CustomAgentTool, CustomToolFactory, ToolAPI } from "@mariozechner/pi-coding-agent";
10
- import { callExaTool, createToolWrapper, fetchExaTools, findApiKey } from "./shared";
9
+ import type {
10
+ CustomAgentTool,
11
+ CustomToolFactory,
12
+ ToolAPI,
13
+ } from "@mariozechner/pi-coding-agent";
14
+ import {
15
+ callExaTool,
16
+ createToolWrapper,
17
+ fetchExaTools,
18
+ findApiKey,
19
+ } from "./shared";
11
20
 
12
21
  // MCP tool names for this feature
13
22
  const TOOL_NAMES = ["company_research_exa"];
14
23
 
15
24
  // Tool name mapping: MCP name -> exposed name
16
25
  const NAME_MAP: Record<string, string> = {
17
- "company_research_exa": "web_search_company_research",
26
+ company_research_exa: "web_search_company_research",
18
27
  };
19
28
 
20
- const factory: CustomToolFactory = async (_toolApi: ToolAPI): Promise<CustomAgentTool<TSchema, unknown>[] | null> => {
21
- const apiKey = findApiKey();
22
- if (!apiKey) return null;
29
+ const factory: CustomToolFactory = async (
30
+ _toolApi: ToolAPI,
31
+ ): Promise<CustomAgentTool<TSchema, unknown>[] | null> => {
32
+ const apiKey = findApiKey();
33
+ if (!apiKey) return null;
23
34
 
24
- const mcpTools = await fetchExaTools(apiKey, TOOL_NAMES);
25
- if (mcpTools.length === 0) return null;
35
+ const mcpTools = await fetchExaTools(apiKey, TOOL_NAMES);
36
+ if (mcpTools.length === 0) return null;
26
37
 
27
- const callFn = (toolName: string, args: Record<string, unknown>) =>
28
- callExaTool(apiKey, TOOL_NAMES, toolName, args);
38
+ const callFn = (toolName: string, args: Record<string, unknown>) =>
39
+ callExaTool(apiKey, TOOL_NAMES, toolName, args);
29
40
 
30
- return mcpTools.map((tool) =>
31
- createToolWrapper(tool, NAME_MAP[tool.name] ?? tool.name, callFn)
32
- );
41
+ return mcpTools.map((tool) =>
42
+ createToolWrapper(tool, NAME_MAP[tool.name] ?? tool.name, callFn),
43
+ );
33
44
  };
34
45
 
35
46
  export default factory;
@@ -13,54 +13,63 @@
13
13
  */
14
14
 
15
15
  import type { TSchema } from "@sinclair/typebox";
16
- import type { CustomAgentTool, CustomToolFactory, ToolAPI } from "@mariozechner/pi-coding-agent";
16
+ import type {
17
+ CustomAgentTool,
18
+ CustomToolFactory,
19
+ ToolAPI,
20
+ } from "@mariozechner/pi-coding-agent";
17
21
  import runtime from "./runtime.json";
18
22
 
19
23
  // Map feature names to their module imports
20
- const FEATURE_LOADERS: Record<string, () => Promise<{ default: CustomToolFactory }>> = {
21
- search: () => import("./search"),
22
- linkedin: () => import("./linkedin"),
23
- company: () => import("./company"),
24
- researcher: () => import("./researcher"),
25
- websets: () => import("./websets"),
24
+ const FEATURE_LOADERS: Record<
25
+ string,
26
+ () => Promise<{ default: CustomToolFactory }>
27
+ > = {
28
+ search: () => import("./search"),
29
+ linkedin: () => import("./linkedin"),
30
+ company: () => import("./company"),
31
+ researcher: () => import("./researcher"),
32
+ websets: () => import("./websets"),
26
33
  };
27
34
 
28
35
  /**
29
36
  * Factory function that loads enabled features from runtime.json
30
37
  */
31
- const factory: CustomToolFactory = async (toolApi: ToolAPI): Promise<CustomAgentTool<TSchema, unknown>[] | null> => {
32
- const allTools: CustomAgentTool<TSchema, unknown>[] = [];
33
- const enabledFeatures = runtime.features ?? [];
38
+ const factory: CustomToolFactory = async (
39
+ toolApi: ToolAPI,
40
+ ): Promise<CustomAgentTool<TSchema, unknown>[] | null> => {
41
+ const allTools: CustomAgentTool<TSchema, unknown>[] = [];
42
+ const enabledFeatures = runtime.features ?? [];
34
43
 
35
- for (const feature of enabledFeatures) {
36
- const loader = FEATURE_LOADERS[feature];
37
- if (!loader) {
38
- console.error(`Unknown exa feature: "${feature}"`);
39
- continue;
40
- }
44
+ for (const feature of enabledFeatures) {
45
+ const loader = FEATURE_LOADERS[feature];
46
+ if (!loader) {
47
+ console.error(`Unknown exa feature: "${feature}"`);
48
+ continue;
49
+ }
41
50
 
42
- try {
43
- const module = await loader();
44
- const featureFactory = module.default;
51
+ try {
52
+ const module = await loader();
53
+ const featureFactory = module.default;
45
54
 
46
- if (typeof featureFactory === "function") {
47
- const result = await featureFactory(toolApi);
48
- // Handle both single tool and array of tools
49
- if (result) {
50
- const tools = Array.isArray(result) ? result : [result];
51
- for (const tool of tools) {
52
- if (tool && typeof tool === "object" && "name" in tool) {
53
- allTools.push(tool);
54
- }
55
- }
55
+ if (typeof featureFactory === "function") {
56
+ const result = await featureFactory(toolApi);
57
+ // Handle both single tool and array of tools
58
+ if (result) {
59
+ const tools = Array.isArray(result) ? result : [result];
60
+ for (const tool of tools) {
61
+ if (tool && typeof tool === "object" && "name" in tool) {
62
+ allTools.push(tool);
56
63
  }
57
- }
58
- } catch (error) {
59
- console.error(`Failed to load exa feature "${feature}":`, error);
64
+ }
65
+ }
60
66
  }
61
- }
67
+ } catch (error) {
68
+ console.error(`Failed to load exa feature "${feature}":`, error);
69
+ }
70
+ }
62
71
 
63
- return allTools.length > 0 ? allTools : null;
72
+ return allTools.length > 0 ? allTools : null;
64
73
  };
65
74
 
66
75
  export default factory;
@@ -6,30 +6,41 @@
6
6
  */
7
7
 
8
8
  import type { TSchema } from "@sinclair/typebox";
9
- import type { CustomAgentTool, CustomToolFactory, ToolAPI } from "@mariozechner/pi-coding-agent";
10
- import { callExaTool, createToolWrapper, fetchExaTools, findApiKey } from "./shared";
9
+ import type {
10
+ CustomAgentTool,
11
+ CustomToolFactory,
12
+ ToolAPI,
13
+ } from "@mariozechner/pi-coding-agent";
14
+ import {
15
+ callExaTool,
16
+ createToolWrapper,
17
+ fetchExaTools,
18
+ findApiKey,
19
+ } from "./shared";
11
20
 
12
21
  // MCP tool names for this feature
13
22
  const TOOL_NAMES = ["linkedin_search_exa"];
14
23
 
15
24
  // Tool name mapping: MCP name -> exposed name
16
25
  const NAME_MAP: Record<string, string> = {
17
- "linkedin_search_exa": "web_search_linkedin",
26
+ linkedin_search_exa: "web_search_linkedin",
18
27
  };
19
28
 
20
- const factory: CustomToolFactory = async (_toolApi: ToolAPI): Promise<CustomAgentTool<TSchema, unknown>[] | null> => {
21
- const apiKey = findApiKey();
22
- if (!apiKey) return null;
29
+ const factory: CustomToolFactory = async (
30
+ _toolApi: ToolAPI,
31
+ ): Promise<CustomAgentTool<TSchema, unknown>[] | null> => {
32
+ const apiKey = findApiKey();
33
+ if (!apiKey) return null;
23
34
 
24
- const mcpTools = await fetchExaTools(apiKey, TOOL_NAMES);
25
- if (mcpTools.length === 0) return null;
35
+ const mcpTools = await fetchExaTools(apiKey, TOOL_NAMES);
36
+ if (mcpTools.length === 0) return null;
26
37
 
27
- const callFn = (toolName: string, args: Record<string, unknown>) =>
28
- callExaTool(apiKey, TOOL_NAMES, toolName, args);
38
+ const callFn = (toolName: string, args: Record<string, unknown>) =>
39
+ callExaTool(apiKey, TOOL_NAMES, toolName, args);
29
40
 
30
- return mcpTools.map((tool) =>
31
- createToolWrapper(tool, NAME_MAP[tool.name] ?? tool.name, callFn)
32
- );
41
+ return mcpTools.map((tool) =>
42
+ createToolWrapper(tool, NAME_MAP[tool.name] ?? tool.name, callFn),
43
+ );
33
44
  };
34
45
 
35
46
  export default factory;
@@ -7,34 +7,42 @@
7
7
  */
8
8
 
9
9
  import type { TSchema } from "@sinclair/typebox";
10
- import type { CustomAgentTool, CustomToolFactory, ToolAPI } from "@mariozechner/pi-coding-agent";
11
- import { callExaTool, createToolWrapper, fetchExaTools, findApiKey } from "./shared";
10
+ import type {
11
+ CustomAgentTool,
12
+ CustomToolFactory,
13
+ ToolAPI,
14
+ } from "@mariozechner/pi-coding-agent";
15
+ import {
16
+ callExaTool,
17
+ createToolWrapper,
18
+ fetchExaTools,
19
+ findApiKey,
20
+ } from "./shared";
12
21
 
13
22
  // MCP tool names for this feature
14
- const TOOL_NAMES = [
15
- "deep_researcher_start",
16
- "deep_researcher_check",
17
- ];
23
+ const TOOL_NAMES = ["deep_researcher_start", "deep_researcher_check"];
18
24
 
19
25
  // Tool name mapping: MCP name -> exposed name
20
26
  const NAME_MAP: Record<string, string> = {
21
- "deep_researcher_start": "web_search_researcher_start",
22
- "deep_researcher_check": "web_search_researcher_check",
27
+ deep_researcher_start: "web_search_researcher_start",
28
+ deep_researcher_check: "web_search_researcher_check",
23
29
  };
24
30
 
25
- const factory: CustomToolFactory = async (_toolApi: ToolAPI): Promise<CustomAgentTool<TSchema, unknown>[] | null> => {
26
- const apiKey = findApiKey();
27
- if (!apiKey) return null;
31
+ const factory: CustomToolFactory = async (
32
+ _toolApi: ToolAPI,
33
+ ): Promise<CustomAgentTool<TSchema, unknown>[] | null> => {
34
+ const apiKey = findApiKey();
35
+ if (!apiKey) return null;
28
36
 
29
- const mcpTools = await fetchExaTools(apiKey, TOOL_NAMES);
30
- if (mcpTools.length === 0) return null;
37
+ const mcpTools = await fetchExaTools(apiKey, TOOL_NAMES);
38
+ if (mcpTools.length === 0) return null;
31
39
 
32
- const callFn = (toolName: string, args: Record<string, unknown>) =>
33
- callExaTool(apiKey, TOOL_NAMES, toolName, args);
40
+ const callFn = (toolName: string, args: Record<string, unknown>) =>
41
+ callExaTool(apiKey, TOOL_NAMES, toolName, args);
34
42
 
35
- return mcpTools.map((tool) =>
36
- createToolWrapper(tool, NAME_MAP[tool.name] ?? tool.name, callFn)
37
- );
43
+ return mcpTools.map((tool) =>
44
+ createToolWrapper(tool, NAME_MAP[tool.name] ?? tool.name, callFn),
45
+ );
38
46
  };
39
47
 
40
48
  export default factory;
@@ -9,38 +9,49 @@
9
9
  */
10
10
 
11
11
  import type { TSchema } from "@sinclair/typebox";
12
- import type { CustomAgentTool, CustomToolFactory, ToolAPI } from "@mariozechner/pi-coding-agent";
13
- import { callExaTool, createToolWrapper, fetchExaTools, findApiKey } from "./shared";
12
+ import type {
13
+ CustomAgentTool,
14
+ CustomToolFactory,
15
+ ToolAPI,
16
+ } from "@mariozechner/pi-coding-agent";
17
+ import {
18
+ callExaTool,
19
+ createToolWrapper,
20
+ fetchExaTools,
21
+ findApiKey,
22
+ } from "./shared";
14
23
 
15
24
  // MCP tool names for this feature
16
25
  const TOOL_NAMES = [
17
- "web_search_exa",
18
- "deep_search_exa",
19
- "get_code_context_exa",
20
- "crawling_exa",
26
+ "web_search_exa",
27
+ "deep_search_exa",
28
+ "get_code_context_exa",
29
+ "crawling_exa",
21
30
  ];
22
31
 
23
32
  // Tool name mapping: MCP name -> exposed name
24
33
  const NAME_MAP: Record<string, string> = {
25
- "web_search_exa": "web_search_general",
26
- "deep_search_exa": "web_search_deep",
27
- "get_code_context_exa": "web_search_code_context",
28
- "crawling_exa": "web_search_crawl_url",
34
+ web_search_exa: "web_search_general",
35
+ deep_search_exa: "web_search_deep",
36
+ get_code_context_exa: "web_search_code_context",
37
+ crawling_exa: "web_search_crawl_url",
29
38
  };
30
39
 
31
- const factory: CustomToolFactory = async (_toolApi: ToolAPI): Promise<CustomAgentTool<TSchema, unknown>[] | null> => {
32
- const apiKey = findApiKey();
33
- if (!apiKey) return null;
40
+ const factory: CustomToolFactory = async (
41
+ _toolApi: ToolAPI,
42
+ ): Promise<CustomAgentTool<TSchema, unknown>[] | null> => {
43
+ const apiKey = findApiKey();
44
+ if (!apiKey) return null;
34
45
 
35
- const mcpTools = await fetchExaTools(apiKey, TOOL_NAMES);
36
- if (mcpTools.length === 0) return null;
46
+ const mcpTools = await fetchExaTools(apiKey, TOOL_NAMES);
47
+ if (mcpTools.length === 0) return null;
37
48
 
38
- const callFn = (toolName: string, args: Record<string, unknown>) =>
39
- callExaTool(apiKey, TOOL_NAMES, toolName, args);
49
+ const callFn = (toolName: string, args: Record<string, unknown>) =>
50
+ callExaTool(apiKey, TOOL_NAMES, toolName, args);
40
51
 
41
- return mcpTools.map((tool) =>
42
- createToolWrapper(tool, NAME_MAP[tool.name] ?? tool.name, callFn)
43
- );
52
+ return mcpTools.map((tool) =>
53
+ createToolWrapper(tool, NAME_MAP[tool.name] ?? tool.name, callFn),
54
+ );
44
55
  };
45
56
 
46
57
  export default factory;