kibi-cursor 1.0.1 → 2.0.1
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/.cursor-plugin/plugin.json +1 -1
- package/CHANGELOG.md +63 -0
- package/README.md +10 -4
- package/agent-plugin/plugin.json +1 -1
- package/agent-plugin/skills/kibi-usage/SKILL.md +8 -1
- package/agent-plugin/skills/kibi-usage/resources/proof.md +45 -0
- package/bin/launch-kibi-mcp.d.mts +38 -0
- package/bin/launch-kibi-mcp.mjs +66 -33
- package/dist/.cursor-plugin/plugin.json +1 -1
- package/dist/bin/launch-kibi-mcp.d.mts +38 -0
- package/dist/bin/launch-kibi-mcp.mjs +66 -33
- package/dist/hook-input.js +7 -4
- package/dist/hook-runner.d.ts +4 -0
- package/dist/hook-runner.js +32 -11
- package/dist/hook-state-storage.js +52 -2
- package/dist/hook-state.js +14 -4
- package/dist/kb-mcp-tools.js +20 -0
- package/dist/mcp.json +4 -1
- package/dist/messages.js +3 -8
- package/dist/path-policy.d.ts +1 -0
- package/dist/path-policy.js +23 -10
- package/dist/skills/.canon-hash.json +2 -2
- package/dist/skills/kibi-usage/SKILL.md +8 -1
- package/dist/skills/kibi-usage/resources/proof.md +45 -0
- package/mcp.json +4 -1
- package/package.json +1 -1
- package/skills/.canon-hash.json +2 -2
- package/skills/kibi-usage/SKILL.md +8 -1
- package/skills/kibi-usage/resources/proof.md +45 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-cursor",
|
|
3
3
|
"displayName": "Kibi",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.1",
|
|
5
5
|
"description": "Optional Cursor adapter for Kibi. Requires SWI-Prolog 9+ and project-local kibi-cli, kibi-mcp, and kibi-core before the bundled MCP server can start.",
|
|
6
6
|
"license": "AGPL-3.0-or-later",
|
|
7
7
|
"author": {
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,68 @@
|
|
|
1
1
|
# kibi-cursor
|
|
2
2
|
|
|
3
|
+
## 2.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 96a1ebd: Local Cursor MCP builds now compile plugin SDK/builtin dist before the CLI, so a fresh checkout no longer fails with a missing `kibi-plugin-builtin` type package.
|
|
8
|
+
|
|
9
|
+
- `build:cli-stack` runs plugin-sdk + plugin-builtin + CLI
|
|
10
|
+
- Worktree resolver uses that stack instead of `build:cli` alone
|
|
11
|
+
|
|
12
|
+
- 188f875: No user-facing behavior change: `kibi-runtime` now resolves its bundled-skills directory lazily on first use instead of at import time, `isWithinRoot` drops a redundant same-path comparison, `kibi-cursor` drops a provably dead `planDelivered` early return and an always-true stdin branch, and the hook runners' stdin buffering is simplified to an unconditional `Buffer.from`. The reshaping lets the new mutation-testing suite (`docs/mutation-testing.md`, run via `bun run test:mutation`) prove these paths exhaustively — the suite holds a 100% mutation score over `kibi-runtime`, `kibi-codex`, and `kibi-cursor` sources.
|
|
13
|
+
- db07d8f: Proof diagnostics now agree with the Prolog decision: a structural type-shape unit contract is shown as qualifying, `kibi proof impact` compares against the Git HEAD baseline and exits 0 after a successful report, and mixed-role symbols fail the strict proof integrity gate.
|
|
14
|
+
|
|
15
|
+
- Mode-aware candidate evaluation in Prolog; receipt fallback uses `test_receipt_evidence(Context, TestId, Evidence)`.
|
|
16
|
+
- `proof impact` reads `HEAD:proof/baseline.json` with no worktree fallback; diagnostic exit 0.
|
|
17
|
+
- Strict proof workflow and baseline checker include canonical `symbol-traceability`.
|
|
18
|
+
|
|
19
|
+
- f33a665: Proof failures now name the exact requirement, symbol, and why each `covered_by` candidate did not qualify, without changing what counts as proven. Agents can inspect a requirement with `kibi proof explain` and compare current proof state to the committed `proof/baseline.json` snapshot with `kibi proof impact`, instead of reverse-engineering Prolog or guessing from aggregate counts.
|
|
20
|
+
|
|
21
|
+
- Keep `kibi.requirement-proof.v3` and add additive production-symbol `explanations` plus TEST `testResolutions` on the same Proof.
|
|
22
|
+
- Ratchet `proof/baseline.json` to v2 with compact requirement fingerprints; aggregate counts stay the ratchet.
|
|
23
|
+
- Add `kibi proof explain` and `kibi proof impact` as Proof projections, mixed-role leftovers in `symbol-traceability`, and advisory `proof-contract-symbols`.
|
|
24
|
+
- Document the proof-regression workflow in `kibi-usage` 2.1.3.
|
|
25
|
+
|
|
26
|
+
## 2.0.0
|
|
27
|
+
|
|
28
|
+
### Major Changes
|
|
29
|
+
|
|
30
|
+
- 812c201: Kibi's proof layer is now runner-neutral: any test runner, script, or harness can prove requirements, and Playwright is no longer built into the proof model.
|
|
31
|
+
|
|
32
|
+
- `kibi prove` replaces `kibi verify` as the single command to run configured proof producers and record evidence. Proof contracts (`kibi.proof-contract.v1`) declare explicit obligations (`symbol_id` + `target`) executed by a configured integration in `.kb/proof/integrations.json`; `kibi proof inspect` discovers test infrastructure deterministically; one producer run can satisfy many test contracts, and re-ingestion is idempotent.
|
|
33
|
+
- Evidence moves to the `kibi.proof-run.v1` artifact (typed environment, run-level outcome, factual attempt history with `native_case`/`aggregate_run` provenance) evaluated into `kibi.proof-receipt.v1` receipts bound to the live snapshot, contract hash, and effective execution fingerprint. Command proof is the universal fallback, so every project can prove requirements without a first-party framework adapter; strict first-attempt policy never upgrades unknown attempt history into passing evidence.
|
|
34
|
+
- Breaking removals: `kibi verify`, `kb_ingest_verification`, `kibi.playwright-run.v1`, `verification_contract`/`verification_receipts` entity fields (replaced by `proof_contract`/`proof_bindings`/`proof_receipts`), the `required_case_symbols`×`required_projects` Cartesian contract, and `retries` fields. Migrate by re-running `kibi prove` after bootstrap configures proof for your repository.
|
|
35
|
+
|
|
36
|
+
DRY: hard cutover to the proof-evidence protocol across CLI, MCP, runtime skills, Prolog proof evaluation, coverage/repair/report surfaces, agent skills, and repository self-proof (packed e2e steps now execute through `kibi prove --all`).
|
|
37
|
+
|
|
38
|
+
### Patch Changes
|
|
39
|
+
|
|
40
|
+
- b0271ac: Cursor now starts the bundled Kibi MCP server reliably when it launches plugin processes from a home directory or another unrelated working directory. Consumer workspaces with spaces continue to resolve their project-local `kibi-mcp` installation, while the portable Agent Plugin keeps its separate `npx --no-install` configuration.
|
|
41
|
+
|
|
42
|
+
- Fix `kibi-cursor` MCP launcher arguments to use Cursor's `${CURSOR_PLUGIN_ROOT}` expansion.
|
|
43
|
+
- Add source-install manifest regression coverage for consumer-local resolution from unrelated host directories.
|
|
44
|
+
|
|
45
|
+
- b1682f1: Agents receive clearer guidance for repairing the actual supplied mutation request and preserving approved predicate bindings. The scoped additions retain the existing workflow while separating payload recovery from conditional relational modeling.
|
|
46
|
+
|
|
47
|
+
- Update `kibi-usage` to 2.1.2 in CLI/runtime sources and the generated Codex/Cursor distributions.
|
|
48
|
+
- Preserve the other three skills and all existing resource content.
|
|
49
|
+
- Retain production-adoption safeguards; development comparisons are not held-out evidence.
|
|
50
|
+
|
|
51
|
+
- ee0dc49: Plugin hooks, the Cursor MCP launcher, and skill validation now expose the
|
|
52
|
+
same entry paths tests already spawn as processes. In-process coverage can
|
|
53
|
+
exercise stdin, CLI guards, and realpath failures instead of leaving those
|
|
54
|
+
lines invisible to Codecov.
|
|
55
|
+
|
|
56
|
+
- Export hook CLI helpers and Agent Plugin / launcher internals for tests.
|
|
57
|
+
- Use a namespace `fs` import in skill validation so realpath errors are testable.
|
|
58
|
+
|
|
59
|
+
- 5999143: Agent-facing skill docs now use the current status field names, so agents following the freshness and E2E receipt workflows look for fields that actually exist in `kb_status` output instead of stale ones.
|
|
60
|
+
|
|
61
|
+
- Bundled `kibi-freshness` and `kibi-usage` skills (all agent mirrors) now reference `proofSnapshotChanges` and `proofSnapshot` (previously `verificationSnapshotChanges`/`verificationSnapshot` from the pre-proof-architecture status schema).
|
|
62
|
+
- The skillopt-eval harness reads `proofSnapshot*` status fields and its held-out eval prompts name the current fields, so "dirty editor path" evidence gathering works against live status output again.
|
|
63
|
+
|
|
64
|
+
Dry: completes the `verificationSnapshot*` → `proofSnapshot*` rename from the proof architecture change in the surfaces that earlier commit missed.
|
|
65
|
+
|
|
3
66
|
## 1.0.1
|
|
4
67
|
|
|
5
68
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -56,16 +56,19 @@ cp -r "$(npm root)/kibi-cursor" ~/.cursor/plugins/local/kibi-cursor
|
|
|
56
56
|
## MCP configuration
|
|
57
57
|
|
|
58
58
|
The plugin bundles `mcp.json` with a thin launcher that locates and starts the
|
|
59
|
-
`kibi-mcp` package installed in the opened project. The launcher
|
|
60
|
-
consumer workspace and sets `KIBI_WORKSPACE` to that
|
|
61
|
-
bundles, or falls back to a global Kibi runtime:
|
|
59
|
+
`kibi-mcp` package installed in the opened project. The launcher starts the
|
|
60
|
+
resolved child from the consumer workspace and sets `KIBI_WORKSPACE` to that
|
|
61
|
+
root; it never downloads, bundles, or falls back to a global Kibi runtime:
|
|
62
62
|
|
|
63
63
|
```json
|
|
64
64
|
{
|
|
65
65
|
"mcpServers": {
|
|
66
66
|
"kibi": {
|
|
67
67
|
"command": "node",
|
|
68
|
-
"args": [
|
|
68
|
+
"args": [
|
|
69
|
+
"${CURSOR_PLUGIN_ROOT}/bin/launch-kibi-mcp.mjs",
|
|
70
|
+
"${workspaceFolder}"
|
|
71
|
+
]
|
|
69
72
|
}
|
|
70
73
|
}
|
|
71
74
|
}
|
|
@@ -73,6 +76,9 @@ bundles, or falls back to a global Kibi runtime:
|
|
|
73
76
|
|
|
74
77
|
Toggle the bundled MCP server from **Settings → Features → Model Context Protocol** after installing the plugin.
|
|
75
78
|
|
|
79
|
+
Cursor expands `${CURSOR_PLUGIN_ROOT}` to the installed plugin directory and
|
|
80
|
+
`${workspaceFolder}` to the opened workspace before starting the command.
|
|
81
|
+
|
|
76
82
|
Manual MCP fallback (no plugin install required):
|
|
77
83
|
|
|
78
84
|
```json
|
package/agent-plugin/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
3
3
|
"name": "kibi",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.1",
|
|
5
5
|
"description": "Repo-local, per-branch, queryable knowledge base. Portable Agent Plugin packaging Kibi's Agent Skills and MCP server.",
|
|
6
6
|
"author": { "name": "Kibi" },
|
|
7
7
|
"homepage": "https://github.com/Looted/kibi/blob/develop/docs/install.md",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-usage
|
|
3
3
|
name: Kibi Usage
|
|
4
4
|
description: Use Kibi's source-first, exact-Git, migration-aware, proof-aware operations safely across MCP or the trusted local CLI, including partial completion repair.
|
|
5
|
-
version: 2.1.
|
|
5
|
+
version: 2.1.3
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -75,6 +75,8 @@ check. Never fire `kb_upsert` calls in parallel; create or confirm endpoint
|
|
|
75
75
|
entities before linking them. The canonical MCP names are `kb_search`,
|
|
76
76
|
`kb_query`, `kb_upsert`, and `kb_check`.
|
|
77
77
|
|
|
78
|
+
For a task that explicitly supplies a malformed concrete mutation payload, locate and read that public request artifact before choosing an entity, preserving its exact entity ID, type, requested changes, and every intended relationship and endpoint. Do not substitute a seeded or convenient entity for the requested target. Start with kb_search, then exact-filter those targets with kb_query, and run kb_validate_upsert on that same payload; validation is not completion. Correct only diagnosed pre-commit errors and revalidate the corrected payload. Once authorized, apply the identical corrected and authorized payload with kb_upsert. If it returns committed_with_repairs, treat the mutation as committed, follow only the required repair actions, and neither retry it nor trigger unrelated semantic backfill for a schema-only repair. Exact-read every changed entity and relationship endpoint with kb_query, then finish with an unfiltered kb_check followed by a final kb_status.
|
|
79
|
+
|
|
78
80
|
## Closeout fields
|
|
79
81
|
|
|
80
82
|
End every task with these five independent fields:
|
|
@@ -131,6 +133,9 @@ safe normative claims; use `observation` or `meta` for bug/workaround notes and
|
|
|
131
133
|
tests, symbol ownership, and fresh proof-bearing receipts before claiming proof.
|
|
132
134
|
For an existing product KB that needs semantic backfill, read
|
|
133
135
|
`resources/kb-improvement.md`, and `resources/proof.md` for the proof workflow.
|
|
136
|
+
When a proof ratchet fails, follow Debugging proof regressions in
|
|
137
|
+
`resources/proof.md`: use `kibi proof explain` and compare current proof state
|
|
138
|
+
to committed `proof/baseline.json` with `kibi proof impact`.
|
|
134
139
|
|
|
135
140
|
## Predicate Ontology Decision Tree
|
|
136
141
|
|
|
@@ -147,6 +152,8 @@ grounding: run `logic-coverage` so each key binds to one ground fact.
|
|
|
147
152
|
Relationship direction is fixed, and every `from` in a relationship batch
|
|
148
153
|
must equal the upserted entity ID.
|
|
149
154
|
|
|
155
|
+
For conditional relational claims, after the initial `kb_suggest_predicates` and before any `kb_upsert`—including one needed for a missing schema—call read-only `kb_model_requirement` to preview suitable scalar or typed-rule modeling. Treat the preview as advisory: do not apply an irrelevant result or create unrequested facts, and retain an approved ground-predicate plan when it captures the whole claim. Preserve supplied arity, ordered argument roles, polarity, bound values, and one claim key per actual assertion; never split arguments across clauses or schemas or alter values to force uniqueness.
|
|
156
|
+
|
|
150
157
|
## Symbol-First Traceability
|
|
151
158
|
|
|
152
159
|
Represent implementation ownership with a `symbol` entity that has
|
|
@@ -103,3 +103,48 @@ re-run `kibi prove` for the affected selection, then confirm `kb_status` and
|
|
|
103
103
|
`kb_coverage` before handoff.
|
|
104
104
|
|
|
105
105
|
Full reference: `docs/proving-requirements.md`.
|
|
106
|
+
|
|
107
|
+
## Debugging proof regressions
|
|
108
|
+
|
|
109
|
+
When a proof ratchet fails, diagnose first. Do not treat
|
|
110
|
+
`proof/baseline.json` as the thing to edit.
|
|
111
|
+
|
|
112
|
+
1. Do not refresh `proof/baseline.json` as the first fix.
|
|
113
|
+
2. Identify the exact requirement and symbol responsible for the regression.
|
|
114
|
+
3. Use Kibi proof diagnostics rather than reverse-engineering
|
|
115
|
+
`requirement_proof.pl`:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
kibi proof explain REQ-<id>
|
|
119
|
+
kibi proof explain SYM-<id>
|
|
120
|
+
kibi proof impact
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`kibi proof impact` compares the current Proof projection to
|
|
124
|
+
`HEAD:proof/baseline.json` (the committed ratchet snapshot, not the
|
|
125
|
+
working-tree file). It is diagnostic: fingerprint differences are reported
|
|
126
|
+
and the command exits 0 on successful evaluation. The strict ratchet remains
|
|
127
|
+
`scripts/check-proof-baseline.mjs`.
|
|
128
|
+
4. For `missing_production_symbol_coverage`, inspect symbol role, owning
|
|
129
|
+
requirement, `covered_by`, candidate test scope, the requirement scenario
|
|
130
|
+
chain, and the current proof receipt. `kibi proof explain` prints those as
|
|
131
|
+
three labeled blocks so they cannot be confused:
|
|
132
|
+
`required_proofs` (TEST contract obligations), `executable_for` (test-code
|
|
133
|
+
identity), and `covered_by` (production coverage candidates with primary
|
|
134
|
+
plus optional secondary reasons).
|
|
135
|
+
5. A behavioral production symbol requires qualifying behavioral/E2E evidence
|
|
136
|
+
under the current proof model.
|
|
137
|
+
6. Unit coverage can satisfy structural/type-shape requirements only when the
|
|
138
|
+
symbol genuinely represents structural shape and the proof model allows it.
|
|
139
|
+
7. `executable_for` identifies executable test code. Never use it on
|
|
140
|
+
production helpers merely to remove production coverage obligations.
|
|
141
|
+
8. Do not trust TEST names. Resolve
|
|
142
|
+
`TEST -> proof_contract.required_proofs -> SYM -> source` and inspect what
|
|
143
|
+
the executable test actually exercises. Kibi does not infer “this TEST name
|
|
144
|
+
does not match that source file.”
|
|
145
|
+
9. A passing proof producer does not automatically make every authored
|
|
146
|
+
`covered_by` relationship semantically correct.
|
|
147
|
+
10. Prefer one meaningful E2E scenario covering multiple internal functions
|
|
148
|
+
plus focused unit tests for edge cases, rather than an E2E test per helper.
|
|
149
|
+
11. Refresh the baseline only after a genuine intentional proof-state
|
|
150
|
+
improvement requires the ratchet snapshot to be updated.
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
export function parseWorkspaceFolderPaths(value: unknown): string[];
|
|
2
2
|
|
|
3
|
+
export function nextAncestorDirectory(current: string): string | undefined;
|
|
4
|
+
|
|
5
|
+
export function packageJsonForResolvedFile(startPath: string): {
|
|
6
|
+
packageJsonPath: string;
|
|
7
|
+
packageRoot: string;
|
|
8
|
+
packageJson: Record<string, unknown>;
|
|
9
|
+
} | null;
|
|
10
|
+
|
|
11
|
+
export function hasConsumerNodeModulesLink(
|
|
12
|
+
workspaceRoot: string,
|
|
13
|
+
packageRoot: string,
|
|
14
|
+
): boolean;
|
|
15
|
+
|
|
16
|
+
export function isProjectScopedPackage(
|
|
17
|
+
workspaceRoot: string,
|
|
18
|
+
packageRoot: string,
|
|
19
|
+
): boolean;
|
|
20
|
+
|
|
3
21
|
export function resolveProjectLocalMcp(workspaceRoot: string): {
|
|
4
22
|
packageRoot: string;
|
|
5
23
|
packageJsonPath: string;
|
|
@@ -7,12 +25,32 @@ export function resolveProjectLocalMcp(workspaceRoot: string): {
|
|
|
7
25
|
binPath: string;
|
|
8
26
|
};
|
|
9
27
|
|
|
28
|
+
export function hasDeclaredProjectDependency(workspaceRoot: string): boolean;
|
|
29
|
+
|
|
10
30
|
export function resolveWorkspaceRoot(
|
|
11
31
|
explicitWorkspace?: string,
|
|
12
32
|
options?: { cwd?: string; env?: NodeJS.ProcessEnv },
|
|
13
33
|
): string;
|
|
14
34
|
|
|
35
|
+
export function signalExitCode(signal: NodeJS.Signals | string): number;
|
|
36
|
+
|
|
37
|
+
export function isLaunchEntrypoint(
|
|
38
|
+
argv1: string | undefined,
|
|
39
|
+
moduleUrl: string,
|
|
40
|
+
): boolean;
|
|
41
|
+
|
|
42
|
+
export function runLaunchEntrypoint(
|
|
43
|
+
argv?: string[],
|
|
44
|
+
env?: NodeJS.ProcessEnv,
|
|
45
|
+
): Promise<number>;
|
|
46
|
+
|
|
15
47
|
export function launchKibiMcp(
|
|
16
48
|
argv?: string[],
|
|
17
49
|
env?: NodeJS.ProcessEnv,
|
|
50
|
+
spawnImpl?: typeof import("node:child_process").spawn,
|
|
18
51
|
): Promise<number>;
|
|
52
|
+
|
|
53
|
+
export function runLaunchIfEntrypoint(
|
|
54
|
+
isEntrypoint?: boolean,
|
|
55
|
+
start?: () => Promise<number> | Promise<void>,
|
|
56
|
+
): Promise<void>;
|
package/bin/launch-kibi-mcp.mjs
CHANGED
|
@@ -7,14 +7,17 @@
|
|
|
7
7
|
/**
|
|
8
8
|
* Launch the kibi-mcp package installed by the consumer project.
|
|
9
9
|
*
|
|
10
|
-
* Cursor
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* Cursor resolves this command from the plugin-root manifest, but the process
|
|
11
|
+
* cwd is host-controlled and is not a reliable consumer workspace (it may be
|
|
12
|
+
* the plugin directory or another host directory). This adapter deliberately
|
|
13
|
+
* knows nothing about the Kibi source tree: it resolves the unrelated consumer
|
|
14
|
+
* workspace from Cursor's workspace-folder data or explicit environment,
|
|
15
|
+
* finds that workspace's kibi-mcp package, and runs its declared bin with the
|
|
16
|
+
* consumer as both cwd and KIBI_WORKSPACE.
|
|
14
17
|
*/
|
|
15
18
|
|
|
16
19
|
import { spawn } from "node:child_process";
|
|
17
|
-
import
|
|
20
|
+
import * as fs from "node:fs";
|
|
18
21
|
import { createRequire } from "node:module";
|
|
19
22
|
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
20
23
|
import { fileURLToPath } from "node:url";
|
|
@@ -29,12 +32,12 @@ const SIGNAL_EXIT_CODES = {
|
|
|
29
32
|
};
|
|
30
33
|
|
|
31
34
|
function readJson(path) {
|
|
32
|
-
return JSON.parse(readFileSync(path, "utf8"));
|
|
35
|
+
return JSON.parse(fs.readFileSync(path, "utf8"));
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
function isDirectory(path) {
|
|
36
39
|
try {
|
|
37
|
-
return statSync(path).isDirectory();
|
|
40
|
+
return fs.statSync(path).isDirectory();
|
|
38
41
|
} catch {
|
|
39
42
|
return false;
|
|
40
43
|
}
|
|
@@ -86,17 +89,22 @@ export function parseWorkspaceFolderPaths(value) {
|
|
|
86
89
|
.filter(Boolean);
|
|
87
90
|
}
|
|
88
91
|
|
|
89
|
-
function
|
|
92
|
+
export function nextAncestorDirectory(current) {
|
|
93
|
+
const parent = dirname(current);
|
|
94
|
+
return parent === current ? undefined : parent;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function packageJsonForResolvedFile(startPath) {
|
|
90
98
|
let current = resolve(startPath);
|
|
91
99
|
try {
|
|
92
|
-
if (!statSync(current).isDirectory()) current = dirname(current);
|
|
100
|
+
if (!fs.statSync(current).isDirectory()) current = dirname(current);
|
|
93
101
|
} catch {
|
|
94
102
|
current = dirname(current);
|
|
95
103
|
}
|
|
96
104
|
|
|
97
|
-
while (
|
|
105
|
+
while (current !== undefined) {
|
|
98
106
|
const packageJsonPath = join(current, "package.json");
|
|
99
|
-
if (existsSync(packageJsonPath)) {
|
|
107
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
100
108
|
try {
|
|
101
109
|
const packageJson = readJson(packageJsonPath);
|
|
102
110
|
if (packageJson.name === PACKAGE_NAME) {
|
|
@@ -106,10 +114,9 @@ function packageJsonForResolvedFile(startPath) {
|
|
|
106
114
|
// Keep walking if a parent package manifest is malformed.
|
|
107
115
|
}
|
|
108
116
|
}
|
|
109
|
-
|
|
110
|
-
if (parent === current) return null;
|
|
111
|
-
current = parent;
|
|
117
|
+
current = nextAncestorDirectory(current);
|
|
112
118
|
}
|
|
119
|
+
return null;
|
|
113
120
|
}
|
|
114
121
|
|
|
115
122
|
function isWithinRoot(rootPath, candidatePath) {
|
|
@@ -120,10 +127,10 @@ function isWithinRoot(rootPath, candidatePath) {
|
|
|
120
127
|
);
|
|
121
128
|
}
|
|
122
129
|
|
|
123
|
-
function hasConsumerNodeModulesLink(workspaceRoot, packageRoot) {
|
|
130
|
+
export function hasConsumerNodeModulesLink(workspaceRoot, packageRoot) {
|
|
124
131
|
try {
|
|
125
132
|
const linkPath = join(workspaceRoot, "node_modules", PACKAGE_NAME);
|
|
126
|
-
const linkedRoot = realpathSync(linkPath);
|
|
133
|
+
const linkedRoot = fs.realpathSync(linkPath);
|
|
127
134
|
return (
|
|
128
135
|
isWithinRoot(linkedRoot, packageRoot) ||
|
|
129
136
|
isWithinRoot(packageRoot, linkedRoot)
|
|
@@ -133,7 +140,7 @@ function hasConsumerNodeModulesLink(workspaceRoot, packageRoot) {
|
|
|
133
140
|
}
|
|
134
141
|
}
|
|
135
142
|
|
|
136
|
-
function isProjectScopedPackage(workspaceRoot, packageRoot) {
|
|
143
|
+
export function isProjectScopedPackage(workspaceRoot, packageRoot) {
|
|
137
144
|
if (isWithinRoot(workspaceRoot, packageRoot)) return true;
|
|
138
145
|
|
|
139
146
|
// pnpm can expose a package through a symlink whose realpath is outside the
|
|
@@ -197,7 +204,7 @@ export function resolveProjectLocalMcp(workspaceRoot) {
|
|
|
197
204
|
}
|
|
198
205
|
|
|
199
206
|
const binPath = resolve(packageInfo.packageRoot, binEntry);
|
|
200
|
-
if (!existsSync(binPath)) {
|
|
207
|
+
if (!fs.existsSync(binPath)) {
|
|
201
208
|
throw new Error(
|
|
202
209
|
`[KIBI-CURSOR] Project-local ${PACKAGE_NAME} declares a missing executable: ${binPath}. Reinstall the workspace dependency and reload Cursor.`,
|
|
203
210
|
);
|
|
@@ -211,9 +218,9 @@ export function resolveProjectLocalMcp(workspaceRoot) {
|
|
|
211
218
|
};
|
|
212
219
|
}
|
|
213
220
|
|
|
214
|
-
function hasDeclaredProjectDependency(workspaceRoot) {
|
|
221
|
+
export function hasDeclaredProjectDependency(workspaceRoot) {
|
|
215
222
|
const packageJsonPath = join(workspaceRoot, "package.json");
|
|
216
|
-
if (!existsSync(packageJsonPath)) return false;
|
|
223
|
+
if (!fs.existsSync(packageJsonPath)) return false;
|
|
217
224
|
try {
|
|
218
225
|
const packageJson = readJson(packageJsonPath);
|
|
219
226
|
return [
|
|
@@ -235,8 +242,8 @@ function hasDeclaredProjectDependency(workspaceRoot) {
|
|
|
235
242
|
|
|
236
243
|
function isDemonstrablyProjectWorkspace(workspaceRoot) {
|
|
237
244
|
return (
|
|
238
|
-
existsSync(join(workspaceRoot, ".git")) ||
|
|
239
|
-
existsSync(join(workspaceRoot, ".kb")) ||
|
|
245
|
+
fs.existsSync(join(workspaceRoot, ".git")) ||
|
|
246
|
+
fs.existsSync(join(workspaceRoot, ".kb")) ||
|
|
240
247
|
hasDeclaredProjectDependency(workspaceRoot)
|
|
241
248
|
);
|
|
242
249
|
}
|
|
@@ -311,12 +318,30 @@ export function resolveWorkspaceRoot(explicitWorkspace, options = {}) {
|
|
|
311
318
|
);
|
|
312
319
|
}
|
|
313
320
|
|
|
314
|
-
function signalExitCode(signal) {
|
|
321
|
+
export function signalExitCode(signal) {
|
|
315
322
|
return SIGNAL_EXIT_CODES[signal] ?? 1;
|
|
316
323
|
}
|
|
317
324
|
|
|
325
|
+
export function isLaunchEntrypoint(argv1, moduleUrl) {
|
|
326
|
+
const entrypoint = argv1 ? resolve(argv1) : undefined;
|
|
327
|
+
return entrypoint === resolve(fileURLToPath(moduleUrl));
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export async function runLaunchEntrypoint(
|
|
331
|
+
argv = process.argv.slice(2),
|
|
332
|
+
env = process.env,
|
|
333
|
+
) {
|
|
334
|
+
const exitCode = await launchKibiMcp(argv, env);
|
|
335
|
+
process.exitCode = exitCode;
|
|
336
|
+
return exitCode;
|
|
337
|
+
}
|
|
338
|
+
|
|
318
339
|
/** Spawn the project-local MCP server and mirror its transport and exit state. */
|
|
319
|
-
export function launchKibiMcp(
|
|
340
|
+
export function launchKibiMcp(
|
|
341
|
+
argv = process.argv.slice(2),
|
|
342
|
+
env = process.env,
|
|
343
|
+
spawnImpl = spawn,
|
|
344
|
+
) {
|
|
320
345
|
const [explicitWorkspace, ...childArgs] = argv;
|
|
321
346
|
let workspaceRoot;
|
|
322
347
|
let projectLocal;
|
|
@@ -332,11 +357,15 @@ export function launchKibiMcp(argv = process.argv.slice(2), env = process.env) {
|
|
|
332
357
|
return Promise.resolve(1);
|
|
333
358
|
}
|
|
334
359
|
|
|
335
|
-
const child =
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
360
|
+
const child = spawnImpl(
|
|
361
|
+
process.execPath,
|
|
362
|
+
[projectLocal.binPath, ...childArgs],
|
|
363
|
+
{
|
|
364
|
+
cwd: workspaceRoot,
|
|
365
|
+
env: { ...env, KIBI_WORKSPACE: workspaceRoot },
|
|
366
|
+
stdio: ["inherit", "inherit", "inherit"],
|
|
367
|
+
},
|
|
368
|
+
);
|
|
340
369
|
|
|
341
370
|
return new Promise((resolveExit) => {
|
|
342
371
|
let finished = false;
|
|
@@ -371,8 +400,12 @@ export function launchKibiMcp(argv = process.argv.slice(2), env = process.env) {
|
|
|
371
400
|
});
|
|
372
401
|
}
|
|
373
402
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
403
|
+
export async function runLaunchIfEntrypoint(
|
|
404
|
+
isEntrypoint = isLaunchEntrypoint(process.argv[1], import.meta.url),
|
|
405
|
+
start = runLaunchEntrypoint,
|
|
406
|
+
) {
|
|
407
|
+
if (!isEntrypoint) return;
|
|
408
|
+
await start();
|
|
378
409
|
}
|
|
410
|
+
|
|
411
|
+
await runLaunchIfEntrypoint();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-cursor",
|
|
3
3
|
"displayName": "Kibi",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.1",
|
|
5
5
|
"description": "Optional Cursor adapter for Kibi. Requires SWI-Prolog 9+ and project-local kibi-cli, kibi-mcp, and kibi-core before the bundled MCP server can start.",
|
|
6
6
|
"license": "AGPL-3.0-or-later",
|
|
7
7
|
"author": {
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
export function parseWorkspaceFolderPaths(value: unknown): string[];
|
|
2
2
|
|
|
3
|
+
export function nextAncestorDirectory(current: string): string | undefined;
|
|
4
|
+
|
|
5
|
+
export function packageJsonForResolvedFile(startPath: string): {
|
|
6
|
+
packageJsonPath: string;
|
|
7
|
+
packageRoot: string;
|
|
8
|
+
packageJson: Record<string, unknown>;
|
|
9
|
+
} | null;
|
|
10
|
+
|
|
11
|
+
export function hasConsumerNodeModulesLink(
|
|
12
|
+
workspaceRoot: string,
|
|
13
|
+
packageRoot: string,
|
|
14
|
+
): boolean;
|
|
15
|
+
|
|
16
|
+
export function isProjectScopedPackage(
|
|
17
|
+
workspaceRoot: string,
|
|
18
|
+
packageRoot: string,
|
|
19
|
+
): boolean;
|
|
20
|
+
|
|
3
21
|
export function resolveProjectLocalMcp(workspaceRoot: string): {
|
|
4
22
|
packageRoot: string;
|
|
5
23
|
packageJsonPath: string;
|
|
@@ -7,12 +25,32 @@ export function resolveProjectLocalMcp(workspaceRoot: string): {
|
|
|
7
25
|
binPath: string;
|
|
8
26
|
};
|
|
9
27
|
|
|
28
|
+
export function hasDeclaredProjectDependency(workspaceRoot: string): boolean;
|
|
29
|
+
|
|
10
30
|
export function resolveWorkspaceRoot(
|
|
11
31
|
explicitWorkspace?: string,
|
|
12
32
|
options?: { cwd?: string; env?: NodeJS.ProcessEnv },
|
|
13
33
|
): string;
|
|
14
34
|
|
|
35
|
+
export function signalExitCode(signal: NodeJS.Signals | string): number;
|
|
36
|
+
|
|
37
|
+
export function isLaunchEntrypoint(
|
|
38
|
+
argv1: string | undefined,
|
|
39
|
+
moduleUrl: string,
|
|
40
|
+
): boolean;
|
|
41
|
+
|
|
42
|
+
export function runLaunchEntrypoint(
|
|
43
|
+
argv?: string[],
|
|
44
|
+
env?: NodeJS.ProcessEnv,
|
|
45
|
+
): Promise<number>;
|
|
46
|
+
|
|
15
47
|
export function launchKibiMcp(
|
|
16
48
|
argv?: string[],
|
|
17
49
|
env?: NodeJS.ProcessEnv,
|
|
50
|
+
spawnImpl?: typeof import("node:child_process").spawn,
|
|
18
51
|
): Promise<number>;
|
|
52
|
+
|
|
53
|
+
export function runLaunchIfEntrypoint(
|
|
54
|
+
isEntrypoint?: boolean,
|
|
55
|
+
start?: () => Promise<number> | Promise<void>,
|
|
56
|
+
): Promise<void>;
|