kibi-opencode 0.5.3 → 0.5.4
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 +16 -0
- package/dist/file-filter.d.ts +10 -0
- package/dist/file-filter.js +57 -9
- package/dist/workspace-health.js +40 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -203,6 +203,22 @@ Disable specific features while keeping others:
|
|
|
203
203
|
|
|
204
204
|
This repository's OpenCode setup dogfoods local built artifacts. `opencode.json` starts the local `kibi-mcp` server, `.opencode/plugins/kibi.ts` re-exports `packages/opencode/dist/index.js`, and the published npm package (`kibi-opencode`) remains the distribution artifact for external consumers. See [DEV.md](DEV.md) for the repo-local workflow and rebuild rule.
|
|
205
205
|
|
|
206
|
+
## Troubleshooting
|
|
207
|
+
|
|
208
|
+
If you see a false "workspace needs Kibi bootstrap" warning even though your workspace is already initialized with `.kb/config.json` pointing at relocated `kibi-docs/*` paths, this indicates a stale plugin cache. See [the main troubleshooting docs](../../docs/troubleshooting.md#opencode-shows-workspace-needs-kibi-bootstrap-before-the-tui) for recovery steps.
|
|
209
|
+
|
|
210
|
+
## Architecture
|
|
211
|
+
|
|
212
|
+
This is a thin bridge layer per ADR-016:
|
|
213
|
+
|
|
214
|
+
XY|This repository's OpenCode setup dogfoods local built artifacts. `opencode.json` starts the local `kibi-mcp` server, `.opencode/plugins/kibi.ts` re-exports `packages/opencode/dist/index.js`, and the published npm package (`kibi-opencode`) remains the distribution artifact for external consumers. See [DEV.md](DEV.md) for the repo-local workflow and rebuild rule.
|
|
215
|
+
|
|
216
|
+
## Troubleshooting
|
|
217
|
+
|
|
218
|
+
If you see a false "workspace needs Kibi bootstrap" warning even though your workspace is already initialized with `.kb/config.json` pointing at relocated `kibi-docs/*` paths, this indicates a stale plugin cache. See [the main troubleshooting docs](../../docs/troubleshooting.md#opencode-shows-workspace-needs-kibi-bootstrap-before-the-tui) for recovery steps.
|
|
219
|
+
|
|
220
|
+
## Architecture
|
|
221
|
+
|
|
206
222
|
## Architecture
|
|
207
223
|
|
|
208
224
|
This is a thin bridge layer per ADR-016:
|
package/dist/file-filter.d.ts
CHANGED
|
@@ -8,5 +8,15 @@ export declare function loadKbSyncPaths(cwd?: string): {
|
|
|
8
8
|
facts: string;
|
|
9
9
|
symbols: string;
|
|
10
10
|
};
|
|
11
|
+
export interface KbExistenceTarget {
|
|
12
|
+
key: string;
|
|
13
|
+
relativePath: string;
|
|
14
|
+
kind: "dir" | "file";
|
|
15
|
+
}
|
|
16
|
+
export declare function getKbExistenceTargets(cwd?: string): KbExistenceTarget[];
|
|
17
|
+
/** Strip the first path segment containing a glob character and everything
|
|
18
|
+
* after it, returning the directory root to check with existsSync.
|
|
19
|
+
*/
|
|
20
|
+
export declare function stripToRoot(p: string): string;
|
|
11
21
|
export declare function shouldHandleFile(filePath: string, cwd?: string): boolean;
|
|
12
22
|
export default shouldHandleFile;
|
package/dist/file-filter.js
CHANGED
|
@@ -22,16 +22,17 @@ catch {
|
|
|
22
22
|
},
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
|
-
// Local copy of
|
|
25
|
+
// Local copy of DEFAULT_CONFIG.paths to avoid cross-package TS rootDir issues.
|
|
26
|
+
// Must stay in sync with DEFAULT_CONFIG.paths in packages/cli/src/utils/config.ts.
|
|
26
27
|
const DEFAULT_SYNC_PATHS = {
|
|
27
|
-
requirements: "requirements/**/*.md",
|
|
28
|
-
scenarios: "scenarios/**/*.md",
|
|
29
|
-
tests: "tests/**/*.md",
|
|
30
|
-
adr: "adr/**/*.md",
|
|
31
|
-
flags: "flags/**/*.md",
|
|
32
|
-
events: "events/**/*.md",
|
|
33
|
-
facts: "facts/**/*.md",
|
|
34
|
-
symbols: "symbols.yaml",
|
|
28
|
+
requirements: "documentation/requirements/**/*.md",
|
|
29
|
+
scenarios: "documentation/scenarios/**/*.md",
|
|
30
|
+
tests: "documentation/tests/**/*.md",
|
|
31
|
+
adr: "documentation/adr/**/*.md",
|
|
32
|
+
flags: "documentation/flags/**/*.md",
|
|
33
|
+
events: "documentation/events/**/*.md",
|
|
34
|
+
facts: "documentation/facts/**/*.md",
|
|
35
|
+
symbols: "documentation/symbols.yaml",
|
|
35
36
|
};
|
|
36
37
|
function loadSyncConfigLocal(cwd = process.cwd()) {
|
|
37
38
|
const configPath = path.join(cwd, ".kb/config.json");
|
|
@@ -56,6 +57,53 @@ export function loadKbSyncPaths(cwd = process.cwd()) {
|
|
|
56
57
|
const cfg = loadSyncConfigLocal(cwd);
|
|
57
58
|
return cfg.paths ?? DEFAULT_SYNC_PATHS;
|
|
58
59
|
}
|
|
60
|
+
// implements REQ-opencode-kibi-plugin-v1
|
|
61
|
+
export function getKbExistenceTargets(cwd = process.cwd()) {
|
|
62
|
+
const paths = loadKbSyncPaths(cwd);
|
|
63
|
+
const keys = [
|
|
64
|
+
"requirements",
|
|
65
|
+
"scenarios",
|
|
66
|
+
"tests",
|
|
67
|
+
"adr",
|
|
68
|
+
"flags",
|
|
69
|
+
"events",
|
|
70
|
+
"facts",
|
|
71
|
+
"symbols",
|
|
72
|
+
];
|
|
73
|
+
const targets = [];
|
|
74
|
+
for (const key of keys) {
|
|
75
|
+
const raw = paths[key];
|
|
76
|
+
if (!raw)
|
|
77
|
+
continue;
|
|
78
|
+
const isFile = raw.endsWith(".yaml") || raw.endsWith(".yml");
|
|
79
|
+
if (isFile) {
|
|
80
|
+
targets.push({ key, relativePath: raw, kind: "file" });
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
// Contract: trim trailing slashes → normalizePattern → strip first glob segment
|
|
84
|
+
const trimmed = raw.replace(/\/+$/, "");
|
|
85
|
+
const normalized = normalizePattern(trimmed);
|
|
86
|
+
const relativePath = normalized ? stripToRoot(normalized) : ".";
|
|
87
|
+
targets.push({ key, relativePath, kind: "dir" });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return targets;
|
|
91
|
+
}
|
|
92
|
+
// implements REQ-opencode-kibi-plugin-v1
|
|
93
|
+
/** Strip the first path segment containing a glob character and everything
|
|
94
|
+
* after it, returning the directory root to check with existsSync.
|
|
95
|
+
*/
|
|
96
|
+
export function stripToRoot(p) {
|
|
97
|
+
const segments = p.split("/");
|
|
98
|
+
const rootSegments = [];
|
|
99
|
+
for (const seg of segments) {
|
|
100
|
+
if (seg.includes("*") || seg.includes("?") || seg.includes("["))
|
|
101
|
+
break;
|
|
102
|
+
rootSegments.push(seg);
|
|
103
|
+
}
|
|
104
|
+
const result = rootSegments.join("/");
|
|
105
|
+
return result || ".";
|
|
106
|
+
}
|
|
59
107
|
function normalizePattern(p) {
|
|
60
108
|
if (!p)
|
|
61
109
|
return null;
|
package/dist/workspace-health.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
// implements REQ-opencode-kibi-plugin-v1
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { getKbExistenceTargets } from "./file-filter.js";
|
|
4
5
|
const KB_CONFIG_FILE = ".kb/config.json";
|
|
6
|
+
// Fallback defaults used when .kb/config.json does not exist
|
|
5
7
|
const KIBI_DOC_DIRS = [
|
|
6
8
|
"documentation/requirements",
|
|
7
9
|
"documentation/scenarios",
|
|
@@ -12,6 +14,7 @@ const KIBI_DOC_DIRS = [
|
|
|
12
14
|
"documentation/facts",
|
|
13
15
|
"documentation/symbols.yaml",
|
|
14
16
|
];
|
|
17
|
+
// implements REQ-opencode-kibi-plugin-v1
|
|
15
18
|
/**
|
|
16
19
|
* Analyze workspace health for Kibi bootstrap and initialization.
|
|
17
20
|
*/
|
|
@@ -19,10 +22,43 @@ export function checkWorkspaceHealth(cwd) {
|
|
|
19
22
|
const configPath = path.join(cwd, KB_CONFIG_FILE);
|
|
20
23
|
const missingConfig = !fs.existsSync(configPath);
|
|
21
24
|
const missingDocDirs = [];
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
if (missingConfig) {
|
|
26
|
+
// No config file: fall back to hardcoded defaults
|
|
27
|
+
for (const docDir of KIBI_DOC_DIRS) {
|
|
28
|
+
const fullPath = path.join(cwd, docDir);
|
|
29
|
+
if (!fs.existsSync(fullPath)) {
|
|
30
|
+
missingDocDirs.push(docDir);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
// Config exists: check if user specified custom paths
|
|
36
|
+
let hasUserPaths = false;
|
|
37
|
+
try {
|
|
38
|
+
const raw = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
39
|
+
hasUserPaths = Boolean(raw && raw.paths);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
hasUserPaths = false;
|
|
43
|
+
}
|
|
44
|
+
if (hasUserPaths) {
|
|
45
|
+
// User has custom paths: resolve targets dynamically
|
|
46
|
+
const targets = getKbExistenceTargets(cwd);
|
|
47
|
+
for (const target of targets) {
|
|
48
|
+
const fullPath = path.join(cwd, target.relativePath);
|
|
49
|
+
if (!fs.existsSync(fullPath)) {
|
|
50
|
+
missingDocDirs.push(target.relativePath);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// Config exists but no custom paths: use hardcoded defaults
|
|
56
|
+
for (const docDir of KIBI_DOC_DIRS) {
|
|
57
|
+
const fullPath = path.join(cwd, docDir);
|
|
58
|
+
if (!fs.existsSync(fullPath)) {
|
|
59
|
+
missingDocDirs.push(docDir);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
26
62
|
}
|
|
27
63
|
}
|
|
28
64
|
// Check for any evidence of Kibi usage
|