@bacnh85/pi-serena 0.1.4 → 0.3.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 (2) hide show
  1. package/index.ts +9 -60
  2. package/package.json +7 -1
package/index.ts CHANGED
@@ -3,6 +3,7 @@ import { Type } from "typebox";
3
3
  import { withFileMutationQueue } from "@earendil-works/pi-coding-agent";
4
4
  import path from "node:path";
5
5
  import { SerenaWorkerClient, type SerenaWorkerResponse } from "./worker";
6
+ import { SEMANTIC_MISS_THRESHOLD, pathLooksLikeCode, pathLooksNonSemantic, commandLooksLikeSemanticCodeSearch } from "./lib/detect";
6
7
 
7
8
  const DEFAULT_CONTEXT = "ide";
8
9
 
@@ -209,56 +210,6 @@ function resultText(response: SerenaWorkerResponse): string {
209
210
  return truncateText(text);
210
211
  }
211
212
 
212
- const CODE_FILE_EXTENSIONS = new Set([
213
- ".c",
214
- ".cc",
215
- ".cpp",
216
- ".cs",
217
- ".css",
218
- ".go",
219
- ".java",
220
- ".js",
221
- ".jsx",
222
- ".kt",
223
- ".lua",
224
- ".mjs",
225
- ".php",
226
- ".py",
227
- ".rb",
228
- ".rs",
229
- ".scala",
230
- ".sh",
231
- ".swift",
232
- ".ts",
233
- ".tsx",
234
- ".vue",
235
- ]);
236
-
237
- const NON_SEMANTIC_FILE_EXTENSIONS = new Set([".json", ".jsonl", ".lock", ".md", ".txt", ".yaml", ".yml"]);
238
-
239
- function pathLooksLikeCode(value: unknown): boolean {
240
- if (typeof value !== "string" || value.trim() === "") return false;
241
- const cleanPath = value.split(/[?#]/, 1)[0].toLowerCase();
242
- const dotIndex = cleanPath.lastIndexOf(".");
243
- if (dotIndex < 0) return false;
244
- return CODE_FILE_EXTENSIONS.has(cleanPath.slice(dotIndex));
245
- }
246
-
247
- function pathLooksNonSemantic(value: unknown): boolean {
248
- if (typeof value !== "string" || value.trim() === "") return false;
249
- const cleanPath = value.split(/[?#]/, 1)[0].toLowerCase();
250
- const dotIndex = cleanPath.lastIndexOf(".");
251
- if (dotIndex < 0) return false;
252
- return NON_SEMANTIC_FILE_EXTENSIONS.has(cleanPath.slice(dotIndex));
253
- }
254
-
255
- function commandLooksLikeSemanticCodeSearch(command: string): boolean {
256
- if (!/\b(rg|grep|fd|find)\b/.test(command)) return false;
257
- if (/\b(SKILL\.md|README\.md|AGENTS\.md|package\.json|skill-registry\.json|skill-history\.jsonl)\b/i.test(command)) return false;
258
- if (/\b(symbol|class|method|function|def|interface|references?|implementation|declaration|rename|refactor)\b/i.test(command)) return true;
259
- return /\.(c|cc|cpp|cs|go|java|js|jsx|kt|lua|mjs|php|py|rb|rs|scala|sh|swift|ts|tsx|vue)\b/i.test(command);
260
- }
261
-
262
213
  export default function serenaToolsExtension(pi: ExtensionAPI) {
263
214
  let worker: SerenaWorkerClient | undefined;
264
215
  let semanticMissCount = 0;
@@ -575,15 +526,13 @@ export default function serenaToolsExtension(pi: ExtensionAPI) {
575
526
  },
576
527
  });
577
528
 
529
+ // Unconditional Serena guidance on every session
578
530
  pi.on("before_agent_start", async (event) => {
579
- const prompt = event.prompt.toLowerCase();
580
- if (/\b(find references|rename|refactor|symbol|declaration|implementation|diagnostic|large repo|semantic|class|method|function)\b/.test(prompt)) {
581
- return {
582
- systemPrompt:
583
- event.systemPrompt +
584
- "\n\nSerena semantic tools are available as Pi-native tools. For symbol lookup, references, semantic code navigation, whole-symbol edits, safe deletion, or cross-file renames, prefer serena_* tools before repeated grep/read/edit operations. Use normal Pi tools for small exact text edits and non-code files.",
585
- };
586
- }
531
+ return {
532
+ systemPrompt:
533
+ event.systemPrompt +
534
+ "\n\nSerena semantic tools are available for code-symbol work. For finding symbols, references, declarations, implementations, and refactoring targets, prefer serena_find_symbol / serena_get_symbols_overview / serena_find_referencing_symbols over grep/read. Use grep/read for exact text searches, docs, configs, and non-code files.",
535
+ };
587
536
  });
588
537
 
589
538
  pi.on("tool_call", async (event) => {
@@ -603,13 +552,13 @@ export default function serenaToolsExtension(pi: ExtensionAPI) {
603
552
 
604
553
  if (!looksLikeSemanticMiss) return;
605
554
  semanticMissCount += 1;
606
- if (semanticMissCount >= 4) {
555
+ if (semanticMissCount >= 2) {
607
556
  semanticMissCount = 0;
608
557
  pi.sendMessage(
609
558
  {
610
559
  customType: "serena-reminder",
611
560
  content:
612
- "Reminder: Serena semantic tools are available for code-symbol work. If you are searching code for symbols, references, declarations, implementations, or refactor targets, switch to serena_find_symbol / serena_get_symbols_overview / serena_find_referencing_symbols instead of more grep/read calls. Normal read/search tools are still appropriate for Markdown, JSON/YAML, docs, and exact text edits.",
561
+ "Reminder: you are reading code files instead of using Serena semantic tools. For symbols, references, declarations, implementations, and refactoring, use serena_find_symbol / serena_get_symbols_overview / serena_find_referencing_symbols instead of more grep/read calls. Keep using read/grep for docs, configs, non-code files, and exact text searches.",
613
562
  display: true,
614
563
  },
615
564
  { deliverAs: "steer", triggerTurn: true },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bacnh85/pi-serena",
3
- "version": "0.1.4",
3
+ "version": "0.3.0",
4
4
  "description": "Pi extension that provides Serena semantic code tools through a persistent worker.",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -34,5 +34,11 @@
34
34
  "peerDependencies": {
35
35
  "@earendil-works/pi-coding-agent": "*",
36
36
  "typebox": "*"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^20.19.43",
40
+ "chai": "^4.5.0",
41
+ "mocha": "^10.8.2",
42
+ "tsx": "^4.22.4"
37
43
  }
38
44
  }