pi-jev-find 0.1.0 → 0.2.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 (3) hide show
  1. package/README.md +2 -0
  2. package/package.json +4 -2
  3. package/src/index.ts +31 -10
package/README.md CHANGED
@@ -42,6 +42,8 @@ All knobs are environment variables; all are optional except the API key.
42
42
  | `JEV_BASE_URL` | `TYPESAFE_BASE_URL` | `https://api.typesafe.ai` | API root. |
43
43
  | `JEV_MODEL` | `TYPESAFE_DEFAULT_MODEL` | `jev-latest` | Judgment model. |
44
44
 
45
+ The `find` tool is only offered to the model when a key resolves at startup; without one, pi-jev-find logs a warning and skips tool registration entirely (`/find` remains available as a status check). A listed-but-broken tool burns one failed call and teaches the model to avoid `find` for the rest of the session.
46
+
45
47
  ### Cascade budgets
46
48
 
47
49
  | Variable | Default | Meaning |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-jev-find",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Semantic find tool for the pi coding agent — a cascade-search port of jegrep / oh-my-pi jfind",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -37,6 +37,8 @@
37
37
  "typescript": "^5.9.0"
38
38
  },
39
39
  "pi": {
40
- "extensions": ["src/index.ts"]
40
+ "extensions": [
41
+ "src/index.ts"
42
+ ]
41
43
  }
42
44
  }
package/src/index.ts CHANGED
@@ -30,22 +30,29 @@ const parameters = Type.Object({
30
30
  path: Type.Optional(Type.String({ description: "directory to search. Omitted -> the workspace root" })),
31
31
  });
32
32
 
33
- const DESCRIPTION = `Semantic grep: describe what you are looking for in plain language; returns the files and line ranges that implement it, each with a calibrated 0-1 relevance score. No index; searches the live workspace tree on every call.
33
+ const DESCRIPTION = `Semantic code search: describe what you want in plain language, get the files and exact line ranges that implement it, each with a calibrated 0-1 probability. No index; searches the live workspace tree on every call. A typical find takes a few seconds and costs a fraction of a cent.
34
34
 
35
- - \`query\`: a concept or behavior ("where do we verify JWT tokens?", "retry budget for failed requests"), not a regex. Quoted phrases in \`query\` are matched whole.
36
- - \`grep_keywords\`: identifiers, symbols, or terms likely to appear verbatim in matching source; they steer the lexical pre-ranking. Pass \`[]\` when nothing specific comes to mind.
35
+ WHEN TO USE (instead of grep):
36
+ - The words you'd use may NOT match the code's identifiers ("where do we expire sessions?" when the code says \`sess_ttl\`), or you don't know this codebase yet.
37
+ - One or two greps already missed or returned noise, and you would otherwise open many speculative files.
38
+ Do NOT use it for exact strings, regexes, or known symbols (that is grep/\`ffgrep\` territory), nor for file names (\`fffind\`/glob) — those are cheaper and faster.
39
+
40
+ USAGE
41
+ - \`query\`: a concept or behavior ("where do we verify webhook signatures?", "retry budget for failed requests"), not a regex. Quoted phrases in \`query\` are matched whole.
42
+ - \`grep_keywords\`: identifiers or terms likely to appear verbatim in matching source; they steer lexical pre-ranking. Pass \`[]\` when nothing specific comes to mind.
37
43
  - \`path\`: one directory to search; omit for the workspace root. Narrow it when you already know the subsystem.
38
- - Results are strongest first as \`path:start-end score snippet\`; open ranges with \`read\`.
39
- - Scores are absolute yes/no probabilities: comparable across calls; below ~0.4 is weak evidence, so widen the query or fall back to \`grep\` before concluding absence.
40
- - \`grep\` is for exact strings, regexes, and known symbols; \`glob\` is for file names. Reach for them after \`find\` has narrowed the files, or when the target is literally a string.
41
- - Every call spends judge requests over the search scope; batch related questions into one descriptive \`query\` instead of many narrow calls.`;
44
+
45
+ RESULTS
46
+ - Hits are strongest first as \`path:start-end score snippet\`; open the ranges with \`read\`.
47
+ - Scores are absolute yes/no probabilities, comparable across calls; below ~0.4 is weak evidence reword the query instead of concluding absence.
48
+ - Batch related questions into one descriptive \`query\` rather than several narrow calls.`;
42
49
 
43
50
  const PROMPT_SNIPPET =
44
- "find: semantic search — describe a behavior in plain language, get files and calibrated line ranges that implement it";
51
+ "find: semantic search — plain-language query in, files + calibrated line ranges out; for concept lookups, unfamiliar code, or after greps miss";
45
52
 
46
53
  const PROMPT_GUIDELINES = [
47
- "When you do not already know where a behavior lives, call `find` once with a descriptive query instead of chaining guessed `grep` patterns and `glob` sweeps followed by speculative reads.",
48
- "`grep` and `glob` come after `find` has narrowed the files, or when the target is an exact string or file name.",
54
+ "Exact strings, regexes, and known symbols belong to `ffgrep`/grep (or rg via bash); file names belong to `fffind`/glob.",
55
+ "When a grep missed or returned noise, or the concept's name in code may differ from your words, call `find` once with a descriptive query before reading files speculatively.",
49
56
  ];
50
57
 
51
58
  /** Line ranges shown per hit in the model-facing text, strongest first. */
@@ -126,6 +133,18 @@ export default function jfindExtension(pi: ExtensionAPI): void {
126
133
  const config = loadConfig();
127
134
  if (!config.enabled) return;
128
135
 
136
+ // Resolve the judge endpoint at startup. A listed-but-broken tool burns one
137
+ // failed call and then never gets picked again for the whole session — skip
138
+ // registration instead so the model only ever sees a working `find`.
139
+ let judgeReady = true;
140
+ try {
141
+ resolveJevConfig();
142
+ } catch (error) {
143
+ judgeReady = false;
144
+ console.error(`pi-jev-find: find tool NOT registered — ${error instanceof Error ? error.message : String(error)}`);
145
+ }
146
+
147
+ if (judgeReady) {
129
148
  pi.registerTool({
130
149
  name: "find",
131
150
  label: "Find",
@@ -193,7 +212,9 @@ export default function jfindExtension(pi: ExtensionAPI): void {
193
212
  return renderFindResult(details, isError, options.expanded, theme);
194
213
  },
195
214
  });
215
+ }
196
216
 
217
+ // Always available as a status/diagnostic command, even without a key.
197
218
  pi.registerCommand("find", {
198
219
  description: "pi-jev-find: show the resolved Jev judge and cascade budgets",
199
220
  handler: async (_args, ctx) => {