kaniscope 0.26.0 → 0.27.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.
package/README.md CHANGED
@@ -5,10 +5,19 @@ AI pull-request reviewer: fetches a PR's diff, reviews it, and posts line-anchor
5
5
  This package ships a native binary — there is no Rust toolchain to install, no compile step, and no postinstall download. The binary lives in a small per-platform package that npm picks by `os`/`cpu`, so you download one, not five.
6
6
 
7
7
  ```bash
8
- npm install kaniscope
8
+ npm install -g kaniscope # want the `kaniscope` command on PATH
9
+ kaniscope --provider github --repo me/app --pr 12 --dry-run
10
+ ```
11
+
12
+ ```bash
13
+ npm install kaniscope # building a bot? this is the one you want
9
14
  npx kaniscope --provider github --repo me/app --pr 12 --dry-run
10
15
  ```
11
16
 
17
+ A plain `npm install kaniscope` is a **local** install, so it does not put `kaniscope` on your `PATH` — running it bare gives `command not found`. That is ordinary npm behaviour, not a broken install: reach it with `npx kaniscope`, or `./node_modules/.bin/kaniscope`, or install with `-g`.
18
+
19
+ For a bot, the local install is the right one anyway — `require("kaniscope")` works from it immediately and never touches `PATH`.
20
+
12
21
  ## As a library
13
22
 
14
23
  Build a bot in TypeScript and drive the engine from it:
@@ -33,9 +42,24 @@ for (const f of out.findingsDetail ?? []) {
33
42
 
34
43
  `review()` runs the binary and parses its JSON. It rejects when the engine exits non-zero, with `exitCode`, `signal` and the full `stderr` on the error.
35
44
 
45
+ ## A complete bot
46
+
47
+ [`packaging/examples/node-bot`](https://github.com/nhatvu148/pr-review-core/tree/main/packaging/examples/node-bot) is a working GitHub review bot on this package — an HTTP server, webhook signature verification, and one `review()` call. It ships with tests that run against a fake engine, so they need no API key and no pull request.
48
+
36
49
  ## Configuration
37
50
 
38
- Everything beyond the flags above — the model, the API key, provider tokens, file globs, confidence floors, bot identity — is read from the environment, exactly as it is for the Rust library. Pass overrides in `env` (merged over `process.env`, unless `inheritEnv: false`).
51
+ Everything beyond the flags above — the model, provider tokens, file globs, confidence floors, bot identity — is engine configuration. Pass it typed:
52
+
53
+ ```ts
54
+ await review({
55
+ provider: "github", repo, pr,
56
+ config: { openrouterModel: "anthropic/claude-sonnet-5", minConfidence: 70, agentic: true },
57
+ });
58
+ ```
59
+
60
+ `ReviewConfig` is **generated from the engine's own spec** — every option with its type, default and documentation — so it cannot drift from what the binary actually reads, and your editor completes them.
61
+
62
+ `env` still takes raw strings and is applied *after* `config`, so it wins. That is deliberate: it stays the escape hatch for anything the typed layer does not model.
39
63
 
40
64
  The essentials: `OPENROUTER_API_KEY`, plus `GH_TOKEN` / `GITLAB_TOKEN` / Bitbucket credentials for the provider you use. See the [engine README](https://github.com/nhatvu148/pr-review-core#injecting-identity-and-prompt) for the full list, and `.prbot.toml` for per-repo settings.
41
65
 
package/config.d.ts ADDED
@@ -0,0 +1,130 @@
1
+ // GENERATED by packaging/generate-types.mjs — do not edit.
2
+ // Regenerate with: node packaging/generate-types.mjs
3
+
4
+ /**
5
+ * Typed overrides for the engine's environment-driven configuration.
6
+ *
7
+ * Every field maps to one environment variable. Passing `config` is exactly
8
+ * equivalent to setting those variables, and `env` still wins over it — the raw
9
+ * escape hatch stays authoritative for anything not modelled here.
10
+ */
11
+ export interface ReviewConfig {
12
+ /** Clone the repo and let the model investigate cross-file context (grep / read_file / list_dir) before writing findings. Default: `false`. (`AGENTIC`) */
13
+ agentic?: boolean;
14
+ /** Atlassian API token for Bitbucket. (`BB_API_TOKEN`) */
15
+ bbApiToken?: string;
16
+ /** Atlassian account email, paired with BB_API_TOKEN for Bitbucket basic auth. (`BB_EMAIL`) */
17
+ bbEmail?: string;
18
+ /** HMAC secret for Bitbucket webhook deliveries. (`BITBUCKET_WEBHOOK_SECRET`) */
19
+ bitbucketWebhookSecret?: string;
20
+ /** References reported per symbol by the blast-radius scan. Default: `8`. (`BLAST_MAX_REFS`) */
21
+ blastMaxRefs?: number;
22
+ /** Changed symbols the blast-radius scan will follow. Default: `12`. (`BLAST_MAX_SYMBOLS`) */
23
+ blastMaxSymbols?: number;
24
+ /** Precompute callers, tests and type uses of changed symbols and seed the agentic reviewer with them. Measured no recall gain on well-named repos; may help on large monorepos. Default: `true`. (`BLAST_RADIUS`) */
25
+ blastRadius?: boolean;
26
+ /** Fetch the head commit's CI results so the reviewer cannot assert a broken build CI already decided. One extra API call per review. Default: `true`. (`CI_STATUS`) */
27
+ ciStatus?: boolean;
28
+ /** Signature appended to every comment, and the dedupe key for finding the bot's own comments on re-review. Default: `🤖 ai-pr-review`. (`COMMENT_MARKER`) */
29
+ commentMarker?: string;
30
+ /** Report cyclomatic and cognitive complexity (A-F) for touched functions. Deterministic; no model call. Default: `true`. (`COMPLEXITY_METRICS`) */
31
+ complexityMetrics?: boolean;
32
+ /** Only surface functions at or above this cyclomatic complexity. Default: `8`. (`COMPLEXITY_MIN_CYCLOMATIC`) */
33
+ complexityMinCyclomatic?: number;
34
+ /** Distinct packages queried against OSV per review. Default: `100`. (`CVE_MAX_PACKAGES`) */
35
+ cveMaxPackages?: number;
36
+ /** Check added lockfile entries against OSV.dev for known vulnerabilities. Default: `true`. (`CVE_SCAN`) */
37
+ cveScan?: boolean;
38
+ /** Free-form instructions shaping /describe output. Outranks the built-in layout. (`DESCRIBE_INSTRUCTIONS`) */
39
+ describeInstructions?: string;
40
+ /** Append the mermaid change diagram. Skipped on Bitbucket, and whenever there are no edges to draw. Default: `false`. (`DIAGRAM`) */
41
+ diagram?: boolean;
42
+ /** Symbols considered for edge linking, and so the diagram's node budget. Default: `12`. (`DIAGRAM_MAX_NODES`) */
43
+ diagramMaxNodes?: number;
44
+ /** Globs skipped before the model call. Setting this REPLACES the lockfile/generated/vendored/minified defaults. (`EXCLUDE_GLOBS`) */
45
+ excludeGlobs?: string[];
46
+ /** Appended to the built-in system prompts. Your conventions, in plain language. Set but empty is the same as unset: EXTRA_SYSTEM_PROMPT_FILE is consulted either way. (`EXTRA_SYSTEM_PROMPT`) */
47
+ extraSystemPrompt?: string;
48
+ /** Path whose contents are used when EXTRA_SYSTEM_PROMPT is unset OR empty. For baking a large conventions block into an image. (`EXTRA_SYSTEM_PROMPT_FILE`) */
49
+ extraSystemPromptFile?: string;
50
+ /** Keep related files (a source and its test, i18n siblings) adjacent when packing, so the model reviews them together. Default: `true`. (`FILE_BUNDLING`) */
51
+ fileBundling?: boolean;
52
+ /** GitHub API base. Point at a GitHub Enterprise host. Default: `https://api.github.com`. (`GH_API_BASE`) */
53
+ ghApiBase?: string;
54
+ /** GitHub token used to read the PR and post comments. (`GH_TOKEN`) */
55
+ ghToken?: string;
56
+ /** HMAC secret GitHub signs webhook deliveries with. (`GITHUB_WEBHOOK_SECRET`) */
57
+ githubWebhookSecret?: string;
58
+ /** GitLab API base. Point at a self-hosted instance. Default: `https://gitlab.com/api/v4`. (`GITLAB_API_BASE`) */
59
+ gitlabApiBase?: string;
60
+ /** GitLab token used to read the MR and post notes. (`GITLAB_TOKEN`) */
61
+ gitlabToken?: string;
62
+ /** Token GitLab sends as X-Gitlab-Token on webhook deliveries. (`GITLAB_WEBHOOK_SECRET`) */
63
+ gitlabWebhookSecret?: string;
64
+ /** Let the agentic reviewer's grep request 1-8 lines of context per match, so it can judge a second site without a read_file round trip. Default: `true`. (`GREP_CONTEXT`) */
65
+ grepContext?: boolean;
66
+ /** If set, ONLY files matching these globs are reviewed. (`INCLUDE_GLOBS`) */
67
+ includeGlobs?: string[];
68
+ /** OpenAI-compatible endpoint, e.g. http://localhost:11434/v1 for Ollama. Default: `https://openrouter.ai/api/v1`. (`LLM_BASE_URL`) */
69
+ llmBaseUrl?: string;
70
+ /** Size budget for the packed diff. Beyond it, whole files are ranked and dropped rather than truncated mid-hunk. Default: `200000`. (`MAX_DIFF_CHARS`) */
71
+ maxDiffChars?: number;
72
+ /** Cap findings per PR, ranked by severity then confidence. Default: `20`. (`MAX_FINDINGS`) */
73
+ maxFindings?: number;
74
+ /** Cap on the agentic conversation carried between turns. Default: `45000`. (`MAX_HISTORY_CHARS`) */
75
+ maxHistoryChars?: number;
76
+ /** Tool-call turns the agentic reviewer may take before it must conclude. Default: `6`. (`MAX_TURNS`) */
77
+ maxTurns?: number;
78
+ /** Drop findings below this confidence (0-100). Default: `0`. (`MIN_CONFIDENCE`) */
79
+ minConfidence?: number;
80
+ /** API key for the OpenAI-compatible endpoint. Required for every review. (`OPENROUTER_API_KEY`) */
81
+ openrouterApiKey?: string;
82
+ /** HTTP-Referer sent to OpenRouter, for its dashboard attribution. Default: `https://github.com/nhatvu148/pr-review-core`. (`OPENROUTER_HTTP_REFERER`) */
83
+ openrouterHttpReferer?: string;
84
+ /** Retries on a failed or rate-limited model call. Default: `3`. (`OPENROUTER_MAX_RETRIES`) */
85
+ openrouterMaxRetries?: number;
86
+ /** Cap on completion tokens per model call. Default: `4000`. (`OPENROUTER_MAX_TOKENS`) */
87
+ openrouterMaxTokens?: number;
88
+ /** Model that writes the review, and the synthesis half of the agentic split. Default: `anthropic/claude-sonnet-4.5`. (`OPENROUTER_MODEL`) */
89
+ openrouterModel?: string;
90
+ /** Cheaper model for the agentic explore turns, before synthesis. Default: `moonshotai/kimi-k2-0905`. (`OPENROUTER_MODEL_EXPLORE`) */
91
+ openrouterModelExplore?: string;
92
+ /** Sampling temperature. Low on purpose: a review should be reproducible. Default: `0.2`. (`OPENROUTER_TEMPERATURE`) */
93
+ openrouterTemperature?: number;
94
+ /** Per-request timeout for a model call. Default: `120`. (`OPENROUTER_TIMEOUT_SECS`) */
95
+ openrouterTimeoutSecs?: number;
96
+ /** X-Title sent to OpenRouter, for its dashboard attribution. Default: `pr-review`. (`OPENROUTER_X_TITLE`) */
97
+ openrouterXTitle?: string;
98
+ /** OSV API base. Override for a mirror or a test double. Default: `https://api.osv.dev`. (`OSV_API_BASE`) */
99
+ osvApiBase?: string;
100
+ /** HTTP port for a bot serving webhooks. 8088 locally to dodge the usual Docker Desktop clash on 8080. Default: `8088`. (`PORT`) */
101
+ port?: number;
102
+ /** Path to append one JSON record per review to. `-` means stdout; empty means off, so a line in an env file can disable it without being deleted. (`PRBOT_RUN_LOG`) */
103
+ prbotRunLog?: string;
104
+ /** Give the reviewer the PR's own description as a statement of intent to check the diff against. Rendered inside an untrusted fence, so it can never direct the review. Default: `true`. (`PR_BODY`) */
105
+ prBody?: boolean;
106
+ /** Cap on the description handed to the reviewer. A clipped one is marked truncated, so absence is not read as out-of-scope. Default: `12000`. (`PR_BODY_MAX_CHARS`) */
107
+ prBodyMaxChars?: number;
108
+ /** Snap a finding that drifted just off a diff line onto the nearest diff line sharing its code symbol, instead of folding it into the summary. Default: `true`. (`REANCHOR_FINDINGS`) */
109
+ reanchorFindings?: boolean;
110
+ /** Re-review automatically when a PR gets new commits. Off by default: pushing is the inner loop, and every round costs a full review. Default: `false`. (`REVIEW_ON_UPDATE`) */
111
+ reviewOnUpdate?: boolean;
112
+ /** Second skeptical pass that removes false positives and low-value nits. Default: `true`. (`SELF_CRITIQUE`) */
113
+ selfCritique?: boolean;
114
+ /** Name the enclosing function or symbol of each changed line, via tree-sitter, with no clone. Default: `true`. (`STRUCTURAL_CONTEXT`) */
115
+ structuralContext?: boolean;
116
+ /** Files fetched for structural context before it stops. Default: `15`. (`STRUCTURAL_MAX_FILES`) */
117
+ structuralMaxFiles?: number;
118
+ /** Attach a committable suggestion block when the model proposed replacement text that validates against the anchored line. Never on a re-anchored finding. Default: `true`. (`SUGGESTIONS`) */
119
+ suggestions?: boolean;
120
+ /** User-Agent sent to provider APIs. Default: `pr-review-core`. (`USER_AGENT`) */
121
+ userAgent?: string;
122
+ /** Globs marking third-party source: hygiene findings are suppressed inside them and the reviewer is told not to edit there. Setting this REPLACES the defaults. (`VENDORED_GLOBS`) */
123
+ vendoredGlobs?: string[];
124
+ /** Append the per-file walkthrough table to the summary comment. Default: `false`. (`WALKTHROUGH`) */
125
+ walkthrough?: boolean;
126
+ /** Symbols listed per file before the cell collapses to (+N more). Default: `4`. (`WALKTHROUGH_MAX_SYMBOLS`) */
127
+ walkthroughMaxSymbols?: number;
128
+ /** Shared secret authenticating a bot's own async worker callback. (`WORKER_TOKEN`) */
129
+ workerToken?: string;
130
+ }
package/config.js ADDED
@@ -0,0 +1,94 @@
1
+ // GENERATED by packaging/generate-types.mjs — do not edit.
2
+ // Regenerate with: node packaging/generate-types.mjs
3
+
4
+ // Option name -> [environment variable, kind]. The kind drives coercion: the
5
+ // engine reads strings, so a boolean has to arrive as "true", a glob list as a
6
+ // comma-separated string, and a number as its decimal form.
7
+ const CONFIG_ENV = {
8
+ agentic: ["AGENTIC", "Bool"],
9
+ bbApiToken: ["BB_API_TOKEN", "Secret"],
10
+ bbEmail: ["BB_EMAIL", "Str"],
11
+ bitbucketWebhookSecret: ["BITBUCKET_WEBHOOK_SECRET", "Secret"],
12
+ blastMaxRefs: ["BLAST_MAX_REFS", "Int"],
13
+ blastMaxSymbols: ["BLAST_MAX_SYMBOLS", "Int"],
14
+ blastRadius: ["BLAST_RADIUS", "Bool"],
15
+ ciStatus: ["CI_STATUS", "Bool"],
16
+ commentMarker: ["COMMENT_MARKER", "Str"],
17
+ complexityMetrics: ["COMPLEXITY_METRICS", "Bool"],
18
+ complexityMinCyclomatic: ["COMPLEXITY_MIN_CYCLOMATIC", "Int"],
19
+ cveMaxPackages: ["CVE_MAX_PACKAGES", "Int"],
20
+ cveScan: ["CVE_SCAN", "Bool"],
21
+ describeInstructions: ["DESCRIBE_INSTRUCTIONS", "Str"],
22
+ diagram: ["DIAGRAM", "Bool"],
23
+ diagramMaxNodes: ["DIAGRAM_MAX_NODES", "Int"],
24
+ excludeGlobs: ["EXCLUDE_GLOBS", "Globs"],
25
+ extraSystemPrompt: ["EXTRA_SYSTEM_PROMPT", "Str"],
26
+ extraSystemPromptFile: ["EXTRA_SYSTEM_PROMPT_FILE", "Path"],
27
+ fileBundling: ["FILE_BUNDLING", "Bool"],
28
+ ghApiBase: ["GH_API_BASE", "Str"],
29
+ ghToken: ["GH_TOKEN", "Secret"],
30
+ githubWebhookSecret: ["GITHUB_WEBHOOK_SECRET", "Secret"],
31
+ gitlabApiBase: ["GITLAB_API_BASE", "Str"],
32
+ gitlabToken: ["GITLAB_TOKEN", "Secret"],
33
+ gitlabWebhookSecret: ["GITLAB_WEBHOOK_SECRET", "Secret"],
34
+ grepContext: ["GREP_CONTEXT", "Bool"],
35
+ includeGlobs: ["INCLUDE_GLOBS", "Globs"],
36
+ llmBaseUrl: ["LLM_BASE_URL", "Str"],
37
+ maxDiffChars: ["MAX_DIFF_CHARS", "Int"],
38
+ maxFindings: ["MAX_FINDINGS", "Int"],
39
+ maxHistoryChars: ["MAX_HISTORY_CHARS", "Int"],
40
+ maxTurns: ["MAX_TURNS", "Int"],
41
+ minConfidence: ["MIN_CONFIDENCE", "Int"],
42
+ openrouterApiKey: ["OPENROUTER_API_KEY", "Secret"],
43
+ openrouterHttpReferer: ["OPENROUTER_HTTP_REFERER", "Str"],
44
+ openrouterMaxRetries: ["OPENROUTER_MAX_RETRIES", "Int"],
45
+ openrouterMaxTokens: ["OPENROUTER_MAX_TOKENS", "Int"],
46
+ openrouterModel: ["OPENROUTER_MODEL", "Str"],
47
+ openrouterModelExplore: ["OPENROUTER_MODEL_EXPLORE", "Str"],
48
+ openrouterTemperature: ["OPENROUTER_TEMPERATURE", "Float"],
49
+ openrouterTimeoutSecs: ["OPENROUTER_TIMEOUT_SECS", "Int"],
50
+ openrouterXTitle: ["OPENROUTER_X_TITLE", "Str"],
51
+ osvApiBase: ["OSV_API_BASE", "Str"],
52
+ port: ["PORT", "Int"],
53
+ prbotRunLog: ["PRBOT_RUN_LOG", "Path"],
54
+ prBody: ["PR_BODY", "Bool"],
55
+ prBodyMaxChars: ["PR_BODY_MAX_CHARS", "Int"],
56
+ reanchorFindings: ["REANCHOR_FINDINGS", "Bool"],
57
+ reviewOnUpdate: ["REVIEW_ON_UPDATE", "Bool"],
58
+ selfCritique: ["SELF_CRITIQUE", "Bool"],
59
+ structuralContext: ["STRUCTURAL_CONTEXT", "Bool"],
60
+ structuralMaxFiles: ["STRUCTURAL_MAX_FILES", "Int"],
61
+ suggestions: ["SUGGESTIONS", "Bool"],
62
+ userAgent: ["USER_AGENT", "Str"],
63
+ vendoredGlobs: ["VENDORED_GLOBS", "Globs"],
64
+ walkthrough: ["WALKTHROUGH", "Bool"],
65
+ walkthroughMaxSymbols: ["WALKTHROUGH_MAX_SYMBOLS", "Int"],
66
+ workerToken: ["WORKER_TOKEN", "Secret"],
67
+ };
68
+
69
+ /** Turn a `config` object into the environment variables the engine reads. */
70
+ function configToEnv(config) {
71
+ const env = {};
72
+ for (const [key, value] of Object.entries(config || {})) {
73
+ // `hasOwnProperty`, not a bare lookup: `CONFIG_ENV["toString"]` finds
74
+ // Object.prototype's method, which is truthy, so the unknown-key check below
75
+ // passes and the destructuring then fails with "entry is not iterable" —
76
+ // a confusing error for what is simply a typo.
77
+ if (!Object.prototype.hasOwnProperty.call(CONFIG_ENV, key)) {
78
+ // Unknown keys are rejected rather than dropped, for the same reason
79
+ // unknown review options are: a silently ignored `dryRun` posts a live
80
+ // review, and a silently ignored `minConfidence` ships every nit.
81
+ throw new TypeError(`kaniscope: unknown config option ${JSON.stringify(key)}`);
82
+ }
83
+ const entry = CONFIG_ENV[key];
84
+ if (value === undefined || value === null) continue;
85
+ const [name, kind] = entry;
86
+ env[name] =
87
+ kind === "Bool" ? (value ? "true" : "false")
88
+ : kind === "Globs" ? (Array.isArray(value) ? value.join(",") : String(value))
89
+ : String(value);
90
+ }
91
+ return env;
92
+ }
93
+
94
+ module.exports = { CONFIG_ENV, configToEnv };
package/index.d.ts CHANGED
@@ -2,8 +2,19 @@ import type { RunReviewOutput } from "./types";
2
2
 
3
3
  export type { RunReviewOutput, Finding, InlineComment, Usage } from "./types";
4
4
 
5
+ export type { ReviewConfig } from "./config";
6
+
5
7
  /** Options common to every call: how the binary is found and run. */
6
8
  export interface SpawnOptions {
9
+ /**
10
+ * Typed overrides for the engine's configuration — the same variables `env`
11
+ * carries, with names, types and documentation generated from the engine's
12
+ * own spec.
13
+ *
14
+ * `env` is applied *after* this and therefore wins, so the raw escape hatch
15
+ * stays authoritative for anything not modelled.
16
+ */
17
+ config?: import("./config").ReviewConfig;
7
18
  /**
8
19
  * Environment overrides, merged over `process.env` (see {@link inheritEnv}).
9
20
  * This is where the engine's configuration lives — `OPENROUTER_API_KEY`,
package/index.js CHANGED
@@ -14,6 +14,7 @@
14
14
  const { spawn } = require("node:child_process");
15
15
  const { StringDecoder } = require("node:string_decoder");
16
16
  const { binaryPath } = require("./binary.js");
17
+ const { configToEnv } = require("./config.js");
17
18
 
18
19
  /** Flags that take a value, mapped from the camelCase option name. */
19
20
  const VALUE_FLAGS = {
@@ -41,7 +42,7 @@ const BOOL_FLAGS = {
41
42
  * one mistake in this API with consequences that cannot be undone.
42
43
  */
43
44
  function buildArgs(options) {
44
- const known = new Set([...Object.keys(VALUE_FLAGS), ...Object.keys(BOOL_FLAGS), "env", "inheritEnv", "timeoutMs", "onLog", "binary", "diff"]);
45
+ const known = new Set([...Object.keys(VALUE_FLAGS), ...Object.keys(BOOL_FLAGS), "env", "inheritEnv", "timeoutMs", "onLog", "binary", "diff", "config"]);
45
46
  for (const key of Object.keys(options)) {
46
47
  if (!known.has(key)) {
47
48
  throw new TypeError(`kaniscope: unknown option ${JSON.stringify(key)}`);
@@ -78,7 +79,15 @@ function run(bin, args, options) {
78
79
  // no diff on stdin and would block or read junk. Explicit both ways.
79
80
  const wantsStdin = options.diff !== undefined && options.diff !== null;
80
81
  const child = spawn(bin, args, {
81
- env: options.inheritEnv === false ? { ...options.env } : { ...process.env, ...options.env },
82
+ // Order is the contract: inherited, then `config`, then raw `env`. The
83
+ // typed layer is a convenience over the same variables, so anything it
84
+ // does not model — or models wrongly — must remain reachable, and the
85
+ // escape hatch is only an escape hatch if it wins.
86
+ env: {
87
+ ...(options.inheritEnv === false ? {} : process.env),
88
+ ...configToEnv(options.config),
89
+ ...options.env,
90
+ },
82
91
  stdio: [wantsStdin ? "pipe" : "ignore", "pipe", "pipe"],
83
92
  });
84
93
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kaniscope",
3
- "version": "0.26.0",
3
+ "version": "0.27.0",
4
4
  "description": "AI pull-request reviewer — line-anchored inline comments plus a summary, for GitHub, GitLab and Bitbucket. Ships a native binary; no Rust toolchain required.",
5
5
  "keywords": [
6
6
  "code-review",
@@ -27,15 +27,17 @@
27
27
  "index.js",
28
28
  "index.d.ts",
29
29
  "types.d.ts",
30
+ "config.js",
31
+ "config.d.ts",
30
32
  "binary.js",
31
33
  "bin/kaniscope.js",
32
34
  "README.md"
33
35
  ],
34
36
  "optionalDependencies": {
35
- "@nhatvu148/kaniscope-darwin-arm64": "0.26.0",
36
- "@nhatvu148/kaniscope-darwin-x64": "0.26.0",
37
- "@nhatvu148/kaniscope-linux-arm64": "0.26.0",
38
- "@nhatvu148/kaniscope-linux-x64": "0.26.0",
39
- "@nhatvu148/kaniscope-win32-x64": "0.26.0"
37
+ "@nhatvu148/kaniscope-darwin-arm64": "0.27.0",
38
+ "@nhatvu148/kaniscope-darwin-x64": "0.27.0",
39
+ "@nhatvu148/kaniscope-linux-arm64": "0.27.0",
40
+ "@nhatvu148/kaniscope-linux-x64": "0.27.0",
41
+ "@nhatvu148/kaniscope-win32-x64": "0.27.0"
40
42
  }
41
43
  }