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 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` to enable automatic Perplexity lookups, no need to configure MCPs:
45
+ Add this rule to your `CLAUDE.md` or `AGENTS.md`:
46
46
 
47
47
  ```markdown
48
- # Rule: `askpplx` CLI Usage
48
+ # Rule: Use `askpplx` for Current Facts
49
49
 
50
- **MANDATORY:** Run `npx -y askpplx --help` at the start of every agent session to learn available options and confirm the tool is working.
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
- About Perplexity:
10
- Perplexity AI is an AI-powered search engine and answer engine that delivers
11
- concise, accurate responses to user queries by combining real-time web
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
- JSON output (--json):
20
- Returns { text, sources[], usage, providerMetadata } - not structured AI output.
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
- System prompt:
24
- Default prompt is optimized for technical/coding questions.
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
- Examples:
28
- askpplx "What is the capital of France?" -S ""
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
- import { fileURLToPath } from "node:url";
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.0",
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.24.0",
39
+ "packageManager": "pnpm@10.30.1",
40
40
  "engines": {
41
41
  "node": ">=22.14.0"
42
42
  },
43
43
  "dependencies": {
44
- "@ai-sdk/perplexity": "^2.0.21",
44
+ "@ai-sdk/perplexity": "^3.0.19",
45
45
  "@commander-js/extra-typings": "^14.0.0",
46
- "ai": "^5.0.108",
47
- "commander": "^14.0.2",
48
- "conf": "^15.0.2",
49
- "zod": "^4.1.13"
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": "^24.10.1",
56
- "@vitest/coverage-v8": "^4.0.15",
57
- "@vitest/eslint-plugin": "^1.5.1",
58
- "eslint": "^9.39.1",
59
- "eslint-config-prettier": "^10.1.8",
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
- "globals": "^16.5.0",
64
- "knip": "^5.71.0",
65
- "prettier": "3.7.4",
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
- "typescript-eslint": "^8.48.1",
69
- "vitest": "^4.0.15"
63
+ "vitest": "^4.0.18"
70
64
  }
71
65
  }