promptscout 1.1.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 (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +251 -0
  3. package/claude-plugin/.claude-plugin/plugin.json +5 -0
  4. package/claude-plugin/hooks/hooks.json +16 -0
  5. package/claude-plugin/hooks/scripts/user-prompt-submit.sh +47 -0
  6. package/dist/commands/history.d.ts +3 -0
  7. package/dist/commands/history.js +56 -0
  8. package/dist/commands/history.js.map +1 -0
  9. package/dist/commands/rewrite.d.ts +3 -0
  10. package/dist/commands/rewrite.js +25 -0
  11. package/dist/commands/rewrite.js.map +1 -0
  12. package/dist/commands/setup.d.ts +2 -0
  13. package/dist/commands/setup.js +38 -0
  14. package/dist/commands/setup.js.map +1 -0
  15. package/dist/commands/system-prompt.d.ts +3 -0
  16. package/dist/commands/system-prompt.js +36 -0
  17. package/dist/commands/system-prompt.js.map +1 -0
  18. package/dist/constants.d.ts +15 -0
  19. package/dist/constants.js +114 -0
  20. package/dist/constants.js.map +1 -0
  21. package/dist/core/history-service.d.ts +15 -0
  22. package/dist/core/history-service.js +25 -0
  23. package/dist/core/history-service.js.map +1 -0
  24. package/dist/core/orchestrator.d.ts +11 -0
  25. package/dist/core/orchestrator.js +48 -0
  26. package/dist/core/orchestrator.js.map +1 -0
  27. package/dist/core/rewriter.d.ts +7 -0
  28. package/dist/core/rewriter.js +62 -0
  29. package/dist/core/rewriter.js.map +1 -0
  30. package/dist/core/system-prompt-service.d.ts +15 -0
  31. package/dist/core/system-prompt-service.js +30 -0
  32. package/dist/core/system-prompt-service.js.map +1 -0
  33. package/dist/index.d.ts +2 -0
  34. package/dist/index.js +50 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/llm/inference.d.ts +2 -0
  37. package/dist/llm/inference.js +52 -0
  38. package/dist/llm/inference.js.map +1 -0
  39. package/dist/llm/model-manager.d.ts +1 -0
  40. package/dist/llm/model-manager.js +5 -0
  41. package/dist/llm/model-manager.js.map +1 -0
  42. package/dist/llm/prompts/tool-calling.d.ts +3 -0
  43. package/dist/llm/prompts/tool-calling.js +46 -0
  44. package/dist/llm/prompts/tool-calling.js.map +1 -0
  45. package/dist/llm/tokenizer.d.ts +1 -0
  46. package/dist/llm/tokenizer.js +30 -0
  47. package/dist/llm/tokenizer.js.map +1 -0
  48. package/dist/output/clipboard.d.ts +1 -0
  49. package/dist/output/clipboard.js +12 -0
  50. package/dist/output/clipboard.js.map +1 -0
  51. package/dist/output/file-writer.d.ts +1 -0
  52. package/dist/output/file-writer.js +8 -0
  53. package/dist/output/file-writer.js.map +1 -0
  54. package/dist/storage/config-repo.d.ts +11 -0
  55. package/dist/storage/config-repo.js +42 -0
  56. package/dist/storage/config-repo.js.map +1 -0
  57. package/dist/storage/database.d.ts +4 -0
  58. package/dist/storage/database.js +54 -0
  59. package/dist/storage/database.js.map +1 -0
  60. package/dist/storage/history-repo.d.ts +10 -0
  61. package/dist/storage/history-repo.js +48 -0
  62. package/dist/storage/history-repo.js.map +1 -0
  63. package/dist/storage/schema.d.ts +183 -0
  64. package/dist/storage/schema.js +16 -0
  65. package/dist/storage/schema.js.map +1 -0
  66. package/dist/tools/implementations.d.ts +6 -0
  67. package/dist/tools/implementations.js +96 -0
  68. package/dist/tools/implementations.js.map +1 -0
  69. package/dist/tools/index.d.ts +24 -0
  70. package/dist/tools/index.js +119 -0
  71. package/dist/tools/index.js.map +1 -0
  72. package/dist/tools/search-utils.d.ts +7 -0
  73. package/dist/tools/search-utils.js +73 -0
  74. package/dist/tools/search-utils.js.map +1 -0
  75. package/dist/types.d.ts +34 -0
  76. package/dist/types.js +2 -0
  77. package/dist/types.js.map +1 -0
  78. package/dist/utils/editor.d.ts +1 -0
  79. package/dist/utils/editor.js +25 -0
  80. package/dist/utils/editor.js.map +1 -0
  81. package/dist/utils/paths.d.ts +3 -0
  82. package/dist/utils/paths.js +15 -0
  83. package/dist/utils/paths.js.map +1 -0
  84. package/dist/utils/text.d.ts +2 -0
  85. package/dist/utils/text.js +11 -0
  86. package/dist/utils/text.js.map +1 -0
  87. package/package.json +68 -0
@@ -0,0 +1,7 @@
1
+ import { type Ignore } from "ignore";
2
+ export declare function escapeRegex(str: string): string;
3
+ export declare function loadIgnoreFilter(dir: string): Ignore;
4
+ export declare function filterLines(lines: string[], dir: string, ig: Ignore): string[];
5
+ export declare function stripDirPrefix(line: string, dir: string): string;
6
+ export declare function grepSync(args: string[], cwd: string): string;
7
+ export declare function gitSync(args: string[], cwd: string): string;
@@ -0,0 +1,73 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { readFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import ignore from "ignore";
5
+ const GREP_TIMEOUT = 5_000;
6
+ const GIT_TIMEOUT = 5_000;
7
+ // Hardcoded for grep traversal performance only.
8
+ // .git is never in .gitignore (git handles it internally).
9
+ // node_modules is virtually always gitignored and huge.
10
+ // -I: skip binary files (images, fonts, compiled assets)
11
+ // --exclude-dir: skip dirs that are huge and almost always irrelevant
12
+ const BASE_GREP_FLAGS = [
13
+ "-I",
14
+ "--exclude-dir", ".git",
15
+ "--exclude-dir", "node_modules",
16
+ ];
17
+ export function escapeRegex(str) {
18
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
19
+ }
20
+ export function loadIgnoreFilter(dir) {
21
+ const ig = ignore();
22
+ try {
23
+ const content = readFileSync(join(dir, ".gitignore"), "utf-8");
24
+ ig.add(content);
25
+ }
26
+ catch {
27
+ // No .gitignore — no extra filtering
28
+ }
29
+ return ig;
30
+ }
31
+ function extractRelativePath(line, dir) {
32
+ const relative = line.startsWith(dir + "/")
33
+ ? line.slice(dir.length + 1)
34
+ : line;
35
+ const match = relative.match(/^(.+?):\d+:/);
36
+ return match ? match[1] : relative;
37
+ }
38
+ export function filterLines(lines, dir, ig) {
39
+ return lines.filter((line) => {
40
+ const rel = extractRelativePath(line, dir);
41
+ return !ig.ignores(rel);
42
+ });
43
+ }
44
+ export function stripDirPrefix(line, dir) {
45
+ return line.replace(dir + "/", "");
46
+ }
47
+ export function grepSync(args, cwd) {
48
+ try {
49
+ return execFileSync("grep", [...BASE_GREP_FLAGS, ...args], {
50
+ cwd,
51
+ timeout: GREP_TIMEOUT,
52
+ encoding: "utf-8",
53
+ maxBuffer: 1024 * 1024,
54
+ }).trim();
55
+ }
56
+ catch {
57
+ return "";
58
+ }
59
+ }
60
+ export function gitSync(args, cwd) {
61
+ try {
62
+ return execFileSync("git", args, {
63
+ cwd,
64
+ timeout: GIT_TIMEOUT,
65
+ encoding: "utf-8",
66
+ maxBuffer: 1024 * 1024,
67
+ }).trim();
68
+ }
69
+ catch {
70
+ return "";
71
+ }
72
+ }
73
+ //# sourceMappingURL=search-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-utils.js","sourceRoot":"","sources":["../../src/tools/search-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ export interface HistoryEntry {
2
+ id: number;
3
+ directory: string;
4
+ raw_input: string;
5
+ improved_output: string;
6
+ final_output: string;
7
+ model_name: string | null;
8
+ created_at: string;
9
+ }
10
+ export interface ConfigEntry {
11
+ key: string;
12
+ value: string;
13
+ }
14
+ export interface InferenceParams {
15
+ temperature: number;
16
+ topP: number;
17
+ topK: number;
18
+ minP: number;
19
+ repeatPenalty: {
20
+ lastTokens: number;
21
+ penalty: number;
22
+ frequencyPenalty: number;
23
+ presencePenalty: number;
24
+ penalizeNewLine: boolean;
25
+ };
26
+ }
27
+ export interface ProcessOptions {
28
+ rawPrompt: string;
29
+ dryRun?: boolean;
30
+ outputFile?: string;
31
+ jsonOutput?: boolean;
32
+ noClipboard?: boolean;
33
+ projectDir?: string;
34
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ export declare function openInEditor(initialContent?: string): string;
@@ -0,0 +1,25 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { mkdtempSync, writeFileSync, readFileSync, unlinkSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ export function openInEditor(initialContent = "") {
6
+ const editor = process.env.VISUAL || process.env.EDITOR || "vi";
7
+ const tmpDir = mkdtempSync(join(tmpdir(), "promptscout-"));
8
+ const tmpFile = join(tmpDir, "edit.md");
9
+ writeFileSync(tmpFile, initialContent, "utf-8");
10
+ const result = spawnSync(editor, [tmpFile], { stdio: "inherit" });
11
+ if (result.status !== 0) {
12
+ try {
13
+ unlinkSync(tmpFile);
14
+ }
15
+ catch { }
16
+ throw new Error(`Editor exited with code ${result.status}`);
17
+ }
18
+ const content = readFileSync(tmpFile, "utf-8");
19
+ try {
20
+ unlinkSync(tmpFile);
21
+ }
22
+ catch { }
23
+ return content;
24
+ }
25
+ //# sourceMappingURL=editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/utils/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,UAAU,YAAY,CAAC,iBAAyB,EAAE;IACtD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC;IAChE,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAExC,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;IAEhD,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAElE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,IAAI,CAAC;YAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAE/C,IAAI,CAAC;QAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAErC,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function resolveDataDir(): string;
2
+ export declare function resolveDbPath(): string;
3
+ export declare function resolveModelDir(): string;
@@ -0,0 +1,15 @@
1
+ import { mkdirSync } from "node:fs";
2
+ import { DATA_DIR, DB_PATH, MODEL_DIR } from "../constants.js";
3
+ export function resolveDataDir() {
4
+ mkdirSync(DATA_DIR, { recursive: true });
5
+ return DATA_DIR;
6
+ }
7
+ export function resolveDbPath() {
8
+ resolveDataDir();
9
+ return DB_PATH;
10
+ }
11
+ export function resolveModelDir() {
12
+ mkdirSync(MODEL_DIR, { recursive: true });
13
+ return MODEL_DIR;
14
+ }
15
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE/D,MAAM,UAAU,cAAc;IAC5B,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,cAAc,EAAE,CAAC;IACjB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function truncate(text: string, maxLength: number): string;
2
+ export declare function formatTokenCount(used: number, max: number): string;
@@ -0,0 +1,11 @@
1
+ export function truncate(text, maxLength) {
2
+ const flat = text.replace(/\n/g, " ");
3
+ if (flat.length <= maxLength)
4
+ return flat;
5
+ return flat.slice(0, maxLength) + "...";
6
+ }
7
+ export function formatTokenCount(used, max) {
8
+ const remaining = max - used;
9
+ return `Tokens: ${used} / ${max} | Remaining: ${remaining}`;
10
+ }
11
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/utils/text.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,SAAiB;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACtC,IAAI,IAAI,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,GAAW;IACxD,MAAM,SAAS,GAAG,GAAG,GAAG,IAAI,CAAC;IAC7B,OAAO,WAAW,IAAI,MAAM,GAAG,iBAAiB,SAAS,EAAE,CAAC;AAC9D,CAAC"}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "promptscout",
3
+ "version": "1.1.0",
4
+ "description": "Enrich coding agent prompts with codebase context using a local LLM",
5
+ "type": "module",
6
+ "bin": {
7
+ "promptscout": "./dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "claude-plugin",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "clean": "rm -rf dist",
18
+ "prepublishOnly": "pnpm run clean && pnpm run build",
19
+ "release:patch": "npm version patch && npm publish && git push --follow-tags",
20
+ "release:minor": "npm version minor && npm publish && git push --follow-tags",
21
+ "release:major": "npm version major && npm publish && git push --follow-tags"
22
+ },
23
+ "keywords": [
24
+ "cli",
25
+ "llm",
26
+ "prompt",
27
+ "coding-agent",
28
+ "codebase",
29
+ "context",
30
+ "claude",
31
+ "local-llm",
32
+ "gguf"
33
+ ],
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/obsfx/promptscout.git"
37
+ },
38
+ "homepage": "https://github.com/obsfx/promptscout",
39
+ "bugs": {
40
+ "url": "https://github.com/obsfx/promptscout/issues"
41
+ },
42
+ "author": "obsfx",
43
+ "license": "MIT",
44
+ "engines": {
45
+ "node": ">=20.0.0"
46
+ },
47
+ "dependencies": {
48
+ "@inquirer/prompts": "^8.2.0",
49
+ "better-sqlite3": "^12.6.2",
50
+ "clipboardy": "^5.2.1",
51
+ "commander": "^14.0.3",
52
+ "drizzle-orm": "^0.45.1",
53
+ "ignore": "^7.0.5",
54
+ "node-llama-cpp": "^3.15.1",
55
+ "ora": "^9.3.0"
56
+ },
57
+ "devDependencies": {
58
+ "@types/better-sqlite3": "^7.6.13",
59
+ "@types/node": "^25.2.3",
60
+ "typescript": "^5.9.3"
61
+ },
62
+ "pnpm": {
63
+ "onlyBuiltDependencies": [
64
+ "better-sqlite3",
65
+ "node-llama-cpp"
66
+ ]
67
+ }
68
+ }