@apmantza/greedysearch-pi 1.0.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.
- package/.claude/settings.local.json +12 -0
- package/README.md +59 -0
- package/cdp.mjs +788 -0
- package/extractors/bing-copilot.mjs +169 -0
- package/extractors/consent.mjs +29 -0
- package/extractors/google-ai.mjs +152 -0
- package/extractors/perplexity.mjs +170 -0
- package/extractors/stackoverflow-ai.mjs +169 -0
- package/index.ts +145 -0
- package/launch.mjs +194 -0
- package/package.json +26 -0
- package/search.mjs +297 -0
- package/setup.mjs +138 -0
- package/skills/greedy-search/SKILL.md +38 -0
package/setup.mjs
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// setup.mjs — install GreedySearch as a Claude Code skill
|
|
3
|
+
//
|
|
4
|
+
// Usage:
|
|
5
|
+
// node setup.mjs — install / update
|
|
6
|
+
// node setup.mjs --check — verify installation without changing anything
|
|
7
|
+
|
|
8
|
+
import { existsSync, mkdirSync, cpSync, readFileSync, appendFileSync } from 'fs';
|
|
9
|
+
import { join, dirname } from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
import { homedir } from 'os';
|
|
12
|
+
import { execSync } from 'child_process';
|
|
13
|
+
|
|
14
|
+
const __dir = dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
const SKILLS = join(homedir(), '.claude', 'skills');
|
|
16
|
+
const SKILL_DIR = join(SKILLS, 'greedysearch');
|
|
17
|
+
const CDP_DIR = join(SKILLS, 'chrome-cdp');
|
|
18
|
+
const CLAUDE_MD = join(homedir(), '.claude', 'CLAUDE.md');
|
|
19
|
+
const CDP_REPO = 'https://github.com/pasky/chrome-cdp-skill';
|
|
20
|
+
|
|
21
|
+
const CHECK_ONLY = process.argv.includes('--check');
|
|
22
|
+
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
function log(msg) { console.log(` ✓ ${msg}`); }
|
|
26
|
+
function warn(msg) { console.log(` ! ${msg}`); }
|
|
27
|
+
function fail(msg) { console.error(` ✗ ${msg}`); process.exit(1); }
|
|
28
|
+
function section(msg) { console.log(`\n${msg}`); }
|
|
29
|
+
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
section('Checking dependencies...');
|
|
33
|
+
|
|
34
|
+
// 1. Node.js version
|
|
35
|
+
const [major] = process.versions.node.split('.').map(Number);
|
|
36
|
+
if (major < 18) fail(`Node.js 18+ required (found ${process.versions.node})`);
|
|
37
|
+
log(`Node.js ${process.versions.node}`);
|
|
38
|
+
|
|
39
|
+
// 2. git (needed to clone chrome-cdp if missing)
|
|
40
|
+
try { execSync('git --version', { stdio: 'ignore' }); log('git available'); }
|
|
41
|
+
catch { fail('git not found — required to install chrome-cdp dependency'); }
|
|
42
|
+
|
|
43
|
+
// 3. chrome-cdp skill
|
|
44
|
+
if (existsSync(join(CDP_DIR, 'scripts', 'cdp.mjs'))) {
|
|
45
|
+
log('chrome-cdp skill already installed');
|
|
46
|
+
} else if (CHECK_ONLY) {
|
|
47
|
+
warn(`chrome-cdp skill missing at ${CDP_DIR}`);
|
|
48
|
+
} else {
|
|
49
|
+
section('Installing chrome-cdp dependency...');
|
|
50
|
+
mkdirSync(SKILLS, { recursive: true });
|
|
51
|
+
try {
|
|
52
|
+
execSync(`git clone ${CDP_REPO} "${CDP_DIR}"`, { stdio: 'inherit' });
|
|
53
|
+
log('chrome-cdp cloned');
|
|
54
|
+
} catch {
|
|
55
|
+
fail(`Failed to clone ${CDP_REPO} — check your internet connection`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
|
|
61
|
+
section('Installing GreedySearch skill...');
|
|
62
|
+
|
|
63
|
+
if (CHECK_ONLY) {
|
|
64
|
+
const installed = existsSync(join(SKILL_DIR, 'search.mjs'));
|
|
65
|
+
installed ? log(`skill installed at ${SKILL_DIR}`) : warn(`skill not installed at ${SKILL_DIR}`);
|
|
66
|
+
} else {
|
|
67
|
+
mkdirSync(SKILL_DIR, { recursive: true });
|
|
68
|
+
|
|
69
|
+
// Copy scripts
|
|
70
|
+
const filesToCopy = ['search.mjs', 'launch.mjs', 'SKILL.md'];
|
|
71
|
+
for (const f of filesToCopy) {
|
|
72
|
+
const src = join(__dir, f);
|
|
73
|
+
if (!existsSync(src)) fail(`Missing source file: ${f}`);
|
|
74
|
+
cpSync(src, join(SKILL_DIR, f));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Copy extractors directory
|
|
78
|
+
cpSync(join(__dir, 'extractors'), join(SKILL_DIR, 'extractors'), { recursive: true });
|
|
79
|
+
|
|
80
|
+
log(`scripts copied to ${SKILL_DIR}`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
|
|
85
|
+
section('Updating ~/.claude/CLAUDE.md...');
|
|
86
|
+
|
|
87
|
+
const GREEDYSEARCH_BLOCK = `
|
|
88
|
+
## Web Search — GreedySearch
|
|
89
|
+
|
|
90
|
+
IMPORTANT: Do NOT use the built-in WebSearch or WebFetch tools for research or
|
|
91
|
+
coding questions. Use GreedySearch instead — it returns AI-synthesized answers
|
|
92
|
+
(not just links) from Perplexity, Bing Copilot, and Google AI simultaneously.
|
|
93
|
+
|
|
94
|
+
When to invoke automatically (without being asked):
|
|
95
|
+
- Any question about a library, framework, API, or tool — especially version-specific
|
|
96
|
+
- User pastes an error message or stack trace
|
|
97
|
+
- Question contains "latest", "current", "2025", "still recommended", "deprecated"
|
|
98
|
+
- Choosing between dependencies or tools
|
|
99
|
+
- About to implement something non-trivial (search for current idioms first)
|
|
100
|
+
- Fast-moving ecosystems where training data may be stale
|
|
101
|
+
|
|
102
|
+
How to run:
|
|
103
|
+
node ~/.claude/skills/greedysearch/search.mjs all "<query>" # 3 engines in parallel
|
|
104
|
+
node ~/.claude/skills/greedysearch/search.mjs p "<query>" # Perplexity only
|
|
105
|
+
node ~/.claude/skills/greedysearch/search.mjs b "<query>" # Bing Copilot only
|
|
106
|
+
node ~/.claude/skills/greedysearch/search.mjs g "<query>" # Google AI only
|
|
107
|
+
|
|
108
|
+
Chrome must be running first:
|
|
109
|
+
node ~/.claude/skills/greedysearch/launch.mjs
|
|
110
|
+
|
|
111
|
+
Synthesize the three AI answers into one coherent response. Where they agree,
|
|
112
|
+
confidence is high. Where they diverge, present both perspectives.
|
|
113
|
+
`;
|
|
114
|
+
|
|
115
|
+
if (CHECK_ONLY) {
|
|
116
|
+
const hasMd = existsSync(CLAUDE_MD);
|
|
117
|
+
const hasBlock = hasMd && readFileSync(CLAUDE_MD, 'utf8').includes('GreedySearch');
|
|
118
|
+
hasBlock ? log('CLAUDE.md already has GreedySearch block') : warn('CLAUDE.md missing GreedySearch block');
|
|
119
|
+
} else {
|
|
120
|
+
const hasMd = existsSync(CLAUDE_MD);
|
|
121
|
+
const content = hasMd ? readFileSync(CLAUDE_MD, 'utf8') : '';
|
|
122
|
+
|
|
123
|
+
if (content.includes('GreedySearch')) {
|
|
124
|
+
log('CLAUDE.md already configured (skipped)');
|
|
125
|
+
} else {
|
|
126
|
+
appendFileSync(CLAUDE_MD, GREEDYSEARCH_BLOCK, 'utf8');
|
|
127
|
+
log('GreedySearch block appended to CLAUDE.md');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
|
|
133
|
+
section('Done.\n');
|
|
134
|
+
console.log(' Start Chrome: node ~/.claude/skills/greedysearch/launch.mjs');
|
|
135
|
+
console.log(' Test search: node ~/.claude/skills/greedysearch/search.mjs all "what is memoization"');
|
|
136
|
+
console.log(' Stop Chrome: node ~/.claude/skills/greedysearch/launch.mjs --kill');
|
|
137
|
+
console.log('');
|
|
138
|
+
console.log(' Restart your Claude Code session to pick up the skill and CLAUDE.md changes.\n');
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: greedy-search
|
|
3
|
+
description: Multi-engine AI web search — Perplexity, Bing Copilot, Google AI in parallel. Use for current library docs, error messages, version diffs, and any research where training data may be stale.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Greedy Search Skill
|
|
7
|
+
|
|
8
|
+
Use the `greedy_search` tool when you need current information from the web.
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
- Questions about libraries, APIs, or frameworks — especially version-specific
|
|
13
|
+
- User pastes an error message or stack trace
|
|
14
|
+
- Question contains "latest", "current", "2025", "2026", "deprecated", "still recommended"
|
|
15
|
+
- Choosing between dependencies or tools
|
|
16
|
+
- Architecture validation or best-practice confirmation
|
|
17
|
+
- Any research question where training data may be stale
|
|
18
|
+
|
|
19
|
+
## How to Use
|
|
20
|
+
|
|
21
|
+
Call `greedy_search` with the user's question as `query`. Use `engine: "all"` (default) to fan out to all three engines in parallel for the highest-confidence answer.
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
greedy_search({ query: "how to use X in Y version", engine: "all" })
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
For quick lookups where one source is sufficient:
|
|
28
|
+
- `engine: "perplexity"` — best for technical Q&A
|
|
29
|
+
- `engine: "bing"` — best for recent news and Microsoft ecosystem
|
|
30
|
+
- `engine: "google"` — best for broad coverage
|
|
31
|
+
|
|
32
|
+
## Interpreting Results
|
|
33
|
+
|
|
34
|
+
Each engine returns an AI-synthesized answer plus sources. Where all three agree, confidence is high. Where they diverge, present both perspectives to the user.
|
|
35
|
+
|
|
36
|
+
## Requirements
|
|
37
|
+
|
|
38
|
+
Chrome must be running. The extension auto-launches a dedicated GreedySearch Chrome instance if needed (via `launch.mjs`).
|