askpplx 1.4.0 → 1.4.2
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/README.md +4 -16
- package/dist/cli.js +12 -24
- package/dist/format-requires-help-text.d.ts +1 -0
- package/dist/format-requires-help-text.js +11 -0
- package/dist/load-system-prompt.js +10 -5
- package/package.json +16 -22
package/README.md
CHANGED
|
@@ -42,23 +42,11 @@ askpplx "Latest TypeScript release notes" --json | jq -r '.sources[].url' | sort
|
|
|
42
42
|
|
|
43
43
|
## Agent Rule
|
|
44
44
|
|
|
45
|
-
Add this rule to your `CLAUDE.md` or `AGENTS.md
|
|
45
|
+
Add this rule to your `CLAUDE.md` or `AGENTS.md`:
|
|
46
46
|
|
|
47
47
|
```markdown
|
|
48
|
-
# Rule: `askpplx`
|
|
48
|
+
# Rule: Use `askpplx` for Current Facts
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Use `askpplx` to query Perplexity, an AI search engine combining real-time web search with advanced language models.
|
|
53
|
-
|
|
54
|
-
## Why This Matters
|
|
55
|
-
|
|
56
|
-
- **Ground your knowledge:** Your training data has a cutoff date. Real-time search ensures you work with current information—correct API signatures, latest versions, up-to-date best practices.
|
|
57
|
-
- **Save time and resources:** A quick lookup is far cheaper than debugging hallucinated code or explaining why an approach failed. When in doubt, verify first.
|
|
58
|
-
- **Reduce false confidence:** Even when you feel certain, external verification catches subtle errors before they compound into larger problems.
|
|
59
|
-
- **Stay current:** Libraries change, APIs deprecate, patterns evolve. What was correct six months ago may be wrong today.
|
|
60
|
-
|
|
61
|
-
## Usage Guidelines
|
|
62
|
-
|
|
63
|
-
Use concise prompts for quick facts and focused questions for deeper topics. If results are unexpected, refine your query and ask again. Verification is fast and cheap—prefer looking up information over making assumptions.
|
|
50
|
+
At the start of each session, run `npx -y askpplx --help` to verify the CLI is available and configured properly and check available options.
|
|
51
|
+
When a task depends on current or uncertain external information, query `askpplx` instead of relying on memory.
|
|
64
52
|
```
|
package/dist/cli.js
CHANGED
|
@@ -2,37 +2,23 @@
|
|
|
2
2
|
import { Command, Option } from "@commander-js/extra-typings";
|
|
3
3
|
import packageJson from "../package.json" with { type: "json" };
|
|
4
4
|
import { clearPerplexityApiKey, getConfigPath, getPerplexityApiKey, maskApiKey, setPerplexityApiKey, } from "./config.js";
|
|
5
|
+
import { formatRequiresHelpText } from "./format-requires-help-text.js";
|
|
5
6
|
import { runCli } from "./run-cli.js";
|
|
6
7
|
import { collectStdinText } from "./collect-stdin-text.js";
|
|
7
8
|
import { resolveCliPrompt } from "./resolve-cli-prompt.js";
|
|
8
9
|
const usageExamples = `
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
searches with advanced language models.
|
|
13
|
-
|
|
14
|
-
Models:
|
|
15
|
-
sonar Fast, lightweight for quick searches (128K context)
|
|
16
|
-
sonar-pro Advanced multi-step research queries
|
|
17
|
-
sonar-reasoning-pro Deep reasoning with R1-1776 backend (default)
|
|
10
|
+
Examples:
|
|
11
|
+
# Quick factual lookup in plain text
|
|
12
|
+
askpplx "Node.js LTS version"
|
|
18
13
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Use jq to extract fields: --json | jq -r '.text' or '.sources[].url'
|
|
14
|
+
# Summarize local text from stdin (filter style)
|
|
15
|
+
cat article.txt | askpplx -S "Summarize this article"
|
|
22
16
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
Use -s <file> or -S <text> to customize. Use -S "" to disable.
|
|
17
|
+
# Extract citation URLs for source auditing
|
|
18
|
+
askpplx "Latest TypeScript release notes" --json | jq -r '.sources[].url' | sort -u
|
|
26
19
|
|
|
27
|
-
|
|
28
|
-
askpplx "What
|
|
29
|
-
askpplx "Explain quantum computing" --model sonar-pro
|
|
30
|
-
askpplx "Latest news on AI" -c medium
|
|
31
|
-
askpplx "$(cat article.txt)" -s ./summarize.md
|
|
32
|
-
askpplx "$(cat article.txt)" -S "Summarize this article"
|
|
33
|
-
cat article.txt | askpplx -S "Summarize this article"
|
|
34
|
-
askpplx "Node.js LTS version" --json | jq -r '.text'
|
|
35
|
-
askpplx "Show reasoning" --show-thinking`;
|
|
20
|
+
# Capture only answer text for scripts
|
|
21
|
+
askpplx "What changed in React 19?" --json | jq -r '.text'`;
|
|
36
22
|
const program = new Command()
|
|
37
23
|
.name(packageJson.name)
|
|
38
24
|
.description(packageJson.description)
|
|
@@ -50,6 +36,7 @@ const program = new Command()
|
|
|
50
36
|
.option("--show-thinking", "Show model thinking/reasoning blocks")
|
|
51
37
|
.option("--no-stream", "Disable streaming output")
|
|
52
38
|
.addOption(new Option("--no-streaming", "Alias for --no-stream").hideHelp())
|
|
39
|
+
.addHelpText("before", () => `${formatRequiresHelpText(getPerplexityApiKey())}\n`)
|
|
53
40
|
.addHelpText("after", usageExamples)
|
|
54
41
|
.action(async (prompt, options) => {
|
|
55
42
|
try {
|
|
@@ -79,6 +66,7 @@ const program = new Command()
|
|
|
79
66
|
catch (error) {
|
|
80
67
|
const message = error instanceof Error ? error.message : "An unexpected error occurred";
|
|
81
68
|
console.error(`Error: ${message}`);
|
|
69
|
+
// eslint-disable-next-line require-atomic-updates -- False positive: no race condition in catch block
|
|
82
70
|
process.exitCode = 1;
|
|
83
71
|
}
|
|
84
72
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function formatRequiresHelpText(apiKey?: string): string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
function getApiKeySuffix(apiKey) {
|
|
2
|
+
return apiKey.slice(-4);
|
|
3
|
+
}
|
|
4
|
+
export function formatRequiresHelpText(apiKey) {
|
|
5
|
+
if (!apiKey) {
|
|
6
|
+
return ("Requires:\n" +
|
|
7
|
+
" - PERPLEXITY_API_KEY - MISSING! Set PERPLEXITY_API_KEY=<token> " +
|
|
8
|
+
"or run: askpplx config --set-api-key <token>");
|
|
9
|
+
}
|
|
10
|
+
return `Requires: PERPLEXITY_API_KEY (configured: last4=${getApiKeySuffix(apiKey)})`;
|
|
11
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
|
|
4
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
3
|
+
const __dirname = import.meta.dirname;
|
|
5
4
|
const DEFAULT_SYSTEM_PROMPT_PATH = path.join(__dirname, "prompts", "default-system.md");
|
|
6
5
|
export async function loadSystemPrompt(customPath) {
|
|
7
6
|
const promptPath = customPath ?? DEFAULT_SYSTEM_PROMPT_PATH;
|
|
@@ -12,11 +11,17 @@ export async function loadSystemPrompt(customPath) {
|
|
|
12
11
|
catch (error) {
|
|
13
12
|
const code = error.code;
|
|
14
13
|
if (code === "ENOENT") {
|
|
15
|
-
throw new Error(`System prompt file not found: ${promptPath}
|
|
14
|
+
throw new Error(`System prompt file not found: ${promptPath}`, {
|
|
15
|
+
cause: error,
|
|
16
|
+
});
|
|
16
17
|
}
|
|
17
18
|
if (code === "EACCES") {
|
|
18
|
-
throw new Error(`Permission denied reading system prompt: ${promptPath}
|
|
19
|
+
throw new Error(`Permission denied reading system prompt: ${promptPath}`, {
|
|
20
|
+
cause: error,
|
|
21
|
+
});
|
|
19
22
|
}
|
|
20
|
-
throw new Error(`Failed to read system prompt file: ${promptPath}
|
|
23
|
+
throw new Error(`Failed to read system prompt file: ${promptPath}`, {
|
|
24
|
+
cause: error,
|
|
25
|
+
});
|
|
21
26
|
}
|
|
22
27
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "askpplx",
|
|
3
3
|
"author": "Łukasz Jerciński",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "1.4.
|
|
5
|
+
"version": "1.4.2",
|
|
6
6
|
"description": "Minimal Unix-style CLI for querying Perplexity Sonar API.",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -36,36 +36,30 @@
|
|
|
36
36
|
"typecheck": "tsc -b --noEmit"
|
|
37
37
|
},
|
|
38
38
|
"keywords": [],
|
|
39
|
-
"packageManager": "pnpm@10.
|
|
39
|
+
"packageManager": "pnpm@10.30.1",
|
|
40
40
|
"engines": {
|
|
41
41
|
"node": ">=22.14.0"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@ai-sdk/perplexity": "^
|
|
44
|
+
"@ai-sdk/perplexity": "^3.0.19",
|
|
45
45
|
"@commander-js/extra-typings": "^14.0.0",
|
|
46
|
-
"ai": "^
|
|
47
|
-
"commander": "^14.0.
|
|
48
|
-
"conf": "^15.0
|
|
49
|
-
"zod": "^4.
|
|
46
|
+
"ai": "^6.0.97",
|
|
47
|
+
"commander": "^14.0.3",
|
|
48
|
+
"conf": "^15.1.0",
|
|
49
|
+
"zod": "^4.3.6"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@eslint/compat": "^2.0.0",
|
|
53
|
-
"@eslint/js": "^9.39.1",
|
|
54
52
|
"@total-typescript/ts-reset": "^0.6.1",
|
|
55
|
-
"@types/node": "^
|
|
56
|
-
"@vitest/coverage-v8": "^4.0.
|
|
57
|
-
"
|
|
58
|
-
"eslint": "^
|
|
59
|
-
"
|
|
60
|
-
"eslint-plugin-unicorn": "^62.0.0",
|
|
61
|
-
"fta-check": "^1.2.0",
|
|
53
|
+
"@types/node": "^25.3.0",
|
|
54
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
55
|
+
"eslint": "^10.0.1",
|
|
56
|
+
"eslint-config-axkit": "^1.2.1",
|
|
57
|
+
"fta-check": "^1.5.1",
|
|
62
58
|
"fta-cli": "^3.0.0",
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"semantic-release": "^25.0.2",
|
|
59
|
+
"knip": "^5.85.0",
|
|
60
|
+
"prettier": "3.8.1",
|
|
61
|
+
"semantic-release": "^25.0.3",
|
|
67
62
|
"typescript": "^5.9.3",
|
|
68
|
-
"
|
|
69
|
-
"vitest": "^4.0.15"
|
|
63
|
+
"vitest": "^4.0.18"
|
|
70
64
|
}
|
|
71
65
|
}
|