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 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:
@@ -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;
@@ -22,16 +22,17 @@ catch {
22
22
  },
23
23
  };
24
24
  }
25
- // Local copy of DEFAULT_SYNC_PATHS to avoid cross-package TS rootDir issues
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;
@@ -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
- for (const docDir of KIBI_DOC_DIRS) {
23
- const fullPath = path.join(cwd, docDir);
24
- if (!fs.existsSync(fullPath)) {
25
- missingDocDirs.push(docDir);
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kibi-opencode",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "Kibi OpenCode plugin - thin adapter to integrate Kibi with OpenCode sessions",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",