kibi-opencode 0.9.0 → 0.11.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.
Files changed (61) hide show
  1. package/README.md +38 -13
  2. package/dist/brief-delivery-reasons.d.ts +12 -0
  3. package/dist/brief-delivery-reasons.js +132 -0
  4. package/dist/brief-intent.d.ts +15 -4
  5. package/dist/brief-intent.js +78 -25
  6. package/dist/briefing-runtime.js +2 -1
  7. package/dist/config.d.ts +3 -0
  8. package/dist/config.js +9 -0
  9. package/dist/e2e-coverage-signals.d.ts +6 -0
  10. package/dist/e2e-coverage-signals.js +186 -0
  11. package/dist/file-entity-links.d.ts +15 -0
  12. package/dist/file-entity-links.js +254 -0
  13. package/dist/file-operation-reminders.d.ts +24 -0
  14. package/dist/file-operation-reminders.js +55 -0
  15. package/dist/file-operation-state.d.ts +29 -0
  16. package/dist/file-operation-state.js +113 -0
  17. package/dist/idle-brief-audit.d.ts +36 -0
  18. package/dist/idle-brief-audit.js +186 -0
  19. package/dist/idle-brief-paths.d.ts +6 -0
  20. package/dist/idle-brief-paths.js +120 -0
  21. package/dist/idle-brief-reader.d.ts +37 -0
  22. package/dist/idle-brief-reader.js +163 -0
  23. package/dist/idle-brief-runtime.d.ts +48 -0
  24. package/dist/idle-brief-runtime.js +478 -0
  25. package/dist/idle-brief-store.d.ts +113 -0
  26. package/dist/idle-brief-store.js +262 -0
  27. package/dist/index.d.ts +2 -39
  28. package/dist/index.js +1 -492
  29. package/dist/init-kibi-alias.d.ts +14 -0
  30. package/dist/init-kibi-alias.js +38 -0
  31. package/dist/init-kibi-capability.d.ts +32 -0
  32. package/dist/init-kibi-capability.js +202 -0
  33. package/dist/logger.d.ts +1 -0
  34. package/dist/logger.js +17 -4
  35. package/dist/plugin-startup.d.ts +1 -0
  36. package/dist/plugin-startup.js +11 -2
  37. package/dist/plugin.d.ts +52 -0
  38. package/dist/plugin.js +1068 -0
  39. package/dist/prompt.d.ts +15 -3
  40. package/dist/prompt.js +106 -36
  41. package/dist/reconcile-engine.d.ts +15 -0
  42. package/dist/reconcile-engine.js +112 -0
  43. package/dist/scheduler.d.ts +13 -2
  44. package/dist/scheduler.js +86 -7
  45. package/dist/session-edit-state.d.ts +25 -0
  46. package/dist/session-edit-state.js +177 -0
  47. package/dist/session-fingerprint.d.ts +11 -0
  48. package/dist/session-fingerprint.js +21 -0
  49. package/dist/source-linked-guidance.d.ts +1 -2
  50. package/dist/source-linked-guidance.js +5 -168
  51. package/dist/startup-notifier.js +42 -31
  52. package/dist/toast.d.ts +23 -22
  53. package/dist/toast.js +36 -14
  54. package/dist/tui-brief-delivery.d.ts +67 -0
  55. package/dist/tui-brief-delivery.js +279 -0
  56. package/dist/tui-brief-view-model.d.ts +63 -0
  57. package/dist/tui-brief-view-model.js +209 -0
  58. package/dist/tui.d.ts +8 -0
  59. package/dist/tui.js +413 -0
  60. package/dist/tui.jsx +120 -0
  61. package/package.json +13 -4
package/dist/tui.jsx ADDED
@@ -0,0 +1,120 @@
1
+ import { selectLatestPersistedBrief, markBriefTuiSeen, markBriefRead } from "./idle-brief-reader.js";
2
+ import { loadBriefConfig } from "kibi-cli/brief-config";
3
+ import { buildTuiBriefViewModel } from "./tui-brief-view-model.js";
4
+ const tui = async (api, _options, _meta) => {
5
+ // State: track the currently displayed contentHash for in-place refresh detection
6
+ let currentContentHash = null;
7
+ api.route.register([
8
+ {
9
+ name: "kibi.brief",
10
+ render: () => {
11
+ const workspace = api.state.path.worktree || "";
12
+ const branch = api.state.vcs?.branch || "main";
13
+ const brief = selectLatestPersistedBrief(workspace, branch);
14
+ if (!brief) {
15
+ currentContentHash = null;
16
+ return (<box flexDirection="column" gap={1} padding={1}>
17
+ <text fg={api.theme.current.error}>No meaningful KB update</text>
18
+ <text>There is no latest persisted brief for this branch.</text>
19
+ </box>);
20
+ }
21
+ const { envelope } = brief;
22
+ const isNewContent = envelope.contentHash !== currentContentHash;
23
+ currentContentHash = envelope.contentHash;
24
+ // Mark as TUI-seen when this is a new (previously unseen) brief and it's unread
25
+ if (isNewContent && envelope.unread) {
26
+ markBriefTuiSeen(workspace, branch, envelope.contentHash);
27
+ // When VSCode channel is disabled, TUI is the sole delivery channel —
28
+ // viewing the brief here should also mark it as fully read
29
+ try {
30
+ const config = loadBriefConfig(workspace);
31
+ if (!config.channels.vscode) {
32
+ markBriefRead(workspace, brief.filePath);
33
+ }
34
+ }
35
+ catch {
36
+ // Gracefully handle config load or markBriefRead failures
37
+ }
38
+ }
39
+ const viewModel = buildTuiBriefViewModel(envelope);
40
+ return (<scrollbox flexDirection="column" gap={1} padding={1}>
41
+ <text fg={api.theme.current.accent}><strong>{viewModel.title}</strong></text>
42
+
43
+ <box flexDirection="column">
44
+ <text><strong>What changed:</strong></text>
45
+ <text>{viewModel.whatChanged.map((line) => `- ${line}`).join("\n")}</text>
46
+ </box>
47
+
48
+ <box flexDirection="column">
49
+ <text><strong>Why it matters:</strong></text>
50
+ <text>{viewModel.whyItMatters}</text>
51
+ </box>
52
+
53
+ {(viewModel.knowledgeImpact.citations.length > 0 || viewModel.knowledgeImpact.constraints.length > 0 || viewModel.knowledgeImpact.regressionRisks.length > 0) && (<box flexDirection="column">
54
+ <text><strong>Project knowledge impact:</strong></text>
55
+ {viewModel.knowledgeImpact.citations.length > 0 && (<text>
56
+ {viewModel.knowledgeImpact.citations
57
+ .map((citation) => `- ${citation.id}${citation.title ? `: ${citation.title}` : ""}`)
58
+ .join("\n")}
59
+ </text>)}
60
+ {viewModel.knowledgeImpact.constraints.length > 0 && (<text>
61
+ {viewModel.knowledgeImpact.constraints
62
+ .map((constraint) => `- ${constraint.statement}`)
63
+ .join("\n")}
64
+ </text>)}
65
+ {viewModel.knowledgeImpact.regressionRisks.length > 0 && (<text>
66
+ {viewModel.knowledgeImpact.regressionRisks
67
+ .map((risk) => `- ${risk.statement}`)
68
+ .join("\n")}
69
+ </text>)}
70
+ </box>)}
71
+
72
+ {(viewModel.interpretationNote.validationCount > 0 || viewModel.interpretationNote.missingEvidence.length > 0) && (<box flexDirection="column">
73
+ <text fg={api.theme.current.warning}><strong>Interpretation note:</strong></text>
74
+ {viewModel.interpretationNote.validationCount > 0 && (<text>Validation checks reported unresolved items: {viewModel.interpretationNote.validationCount} issue(s).</text>)}
75
+ {viewModel.interpretationNote.missingEvidence.length > 0 && (<text>
76
+ {viewModel.interpretationNote.missingEvidence
77
+ .map((item) => `- ${item.statement}`)
78
+ .join("\n")}
79
+ </text>)}
80
+ </box>)}
81
+ </scrollbox>);
82
+ },
83
+ },
84
+ ]);
85
+ if (api.command?.register) {
86
+ api.command.register(() => [
87
+ {
88
+ title: "Kibi: Open Latest Brief",
89
+ value: "kibi.open_latest_brief",
90
+ description: "Opens the latest persisted brief for the current workspace and branch",
91
+ // implements REQ-opencode-kibi-briefing-v6
92
+ onSelect: () => {
93
+ api.route.navigate("kibi.brief");
94
+ },
95
+ },
96
+ {
97
+ title: "Kibi: Open Latest Brief",
98
+ value: "kibi-brief",
99
+ description: "Opens the latest persisted brief for the current workspace and branch",
100
+ // implements REQ-opencode-kibi-briefing-v6
101
+ onSelect: () => {
102
+ api.route.navigate("kibi.brief");
103
+ },
104
+ },
105
+ {
106
+ title: "Kibi: Refresh Brief",
107
+ value: "kibi.refresh_brief",
108
+ description: "Re-reads the latest persisted brief and refreshes the view",
109
+ onSelect: () => {
110
+ api.route.navigate("kibi.brief");
111
+ },
112
+ },
113
+ ]);
114
+ }
115
+ };
116
+ export { tui };
117
+ export default {
118
+ id: "kibi-opencode",
119
+ tui,
120
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kibi-opencode",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "Kibi OpenCode plugin - thin adapter to integrate Kibi with OpenCode sessions",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -30,6 +30,11 @@
30
30
  "types": "./dist/file-filter.d.ts",
31
31
  "import": "./dist/file-filter.js",
32
32
  "default": "./dist/file-filter.js"
33
+ },
34
+ "./tui": {
35
+ "types": "./dist/tui.d.ts",
36
+ "import": "./dist/tui.js",
37
+ "default": "./dist/tui.js"
33
38
  }
34
39
  },
35
40
  "files": [
@@ -47,16 +52,20 @@
47
52
  "access": "public"
48
53
  },
49
54
  "scripts": {
50
- "build": "tsc -p tsconfig.json",
55
+ "build": "tsc -p tsconfig.json && bun run scripts/build-tui.ts && tsc -p tsconfig.tui-types.json",
56
+ "build:tui": "bun run scripts/build-tui.ts && tsc -p tsconfig.tui-types.json",
51
57
  "dev": "tsc -p tsconfig.json --watch",
52
58
  "clean": "rm -rf dist",
53
59
  "prepack": "npm run build"
54
60
  },
55
61
  "dependencies": {
56
- "@opencode-ai/plugin": "^1.2.26"
62
+ "@opencode-ai/plugin": "^1.4.7",
63
+ "@opentui/core": "^0.1.99",
64
+ "@opentui/solid": "^0.1.99",
65
+ "kibi-cli": "^0.8.0"
57
66
  },
58
67
  "devDependencies": {
59
68
  "@types/node": "latest",
60
69
  "typescript": "^5.0.0"
61
70
  }
62
- }
71
+ }