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
@@ -0,0 +1,262 @@
1
+ import * as crypto from "node:crypto";
2
+ function isRecord(value) {
3
+ return typeof value === "object" && value !== null;
4
+ }
5
+ function isStringArray(value) {
6
+ return (Array.isArray(value) && value.every((entry) => typeof entry === "string"));
7
+ }
8
+ function isCitation(value) {
9
+ return isRecord(value) && typeof value.id === "string";
10
+ }
11
+ function isStatement(value) {
12
+ return (isRecord(value) &&
13
+ typeof value.statement === "string" &&
14
+ isStringArray(value.citationIds));
15
+ }
16
+ function isValidationViolation(value) {
17
+ return (isRecord(value) &&
18
+ typeof value.rule === "string" &&
19
+ typeof value.entityId === "string" &&
20
+ typeof value.description === "string");
21
+ }
22
+ function isValidationDiagnostic(value) {
23
+ return (isRecord(value) &&
24
+ typeof value.category === "string" &&
25
+ typeof value.severity === "string" &&
26
+ typeof value.message === "string");
27
+ }
28
+ function isAuditCursor(value) {
29
+ return (isRecord(value) &&
30
+ typeof value.lastTimestamp === "string" &&
31
+ typeof value.lastOperation === "string" &&
32
+ typeof value.entryCount === "number" &&
33
+ typeof value.fileSize === "number");
34
+ }
35
+ function isValidation(value) {
36
+ return (isRecord(value) &&
37
+ Array.isArray(value.violations) &&
38
+ value.violations.every(isValidationViolation) &&
39
+ typeof value.count === "number" &&
40
+ Array.isArray(value.diagnostics) &&
41
+ value.diagnostics.every(isValidationDiagnostic));
42
+ }
43
+ function isBriefingBase(value) {
44
+ return (isRecord(value) &&
45
+ typeof value.tldr === "string" &&
46
+ typeof value.promptBlock === "string" &&
47
+ Array.isArray(value.citations) &&
48
+ value.citations.every(isCitation) &&
49
+ (value.constraints === undefined ||
50
+ (Array.isArray(value.constraints) &&
51
+ value.constraints.every(isStatement))) &&
52
+ (value.regressionRisks === undefined ||
53
+ (Array.isArray(value.regressionRisks) &&
54
+ value.regressionRisks.every(isStatement))) &&
55
+ (value.missingEvidence === undefined ||
56
+ (Array.isArray(value.missingEvidence) &&
57
+ value.missingEvidence.every(isStatement))));
58
+ }
59
+ function isBriefingV2(value) {
60
+ return (isBriefingBase(value) &&
61
+ isStringArray(value.changeNarrative) &&
62
+ (value.deliveryReasons === undefined ||
63
+ isDeliveryReasons(value.deliveryReasons)));
64
+ }
65
+ function isReasonItem(value) {
66
+ return (isRecord(value) &&
67
+ typeof value.kind === "string" &&
68
+ typeof value.text === "string" &&
69
+ isStringArray(value.entityIds) &&
70
+ (value.citationIds === undefined || isStringArray(value.citationIds)) &&
71
+ (value.severity === undefined ||
72
+ value.severity === "info" ||
73
+ value.severity === "warning" ||
74
+ value.severity === "error"));
75
+ }
76
+ function isDeliveryReasons(value) {
77
+ return (isRecord(value) &&
78
+ value.version === 1 &&
79
+ isRecord(value.toast) &&
80
+ typeof value.toast.title === "string" &&
81
+ typeof value.toast.summary === "string" &&
82
+ typeof value.toast.whyItMatters === "string" &&
83
+ Array.isArray(value.items) &&
84
+ value.items.every(isReasonItem));
85
+ }
86
+ function isChangeItem(value) {
87
+ return (isRecord(value) &&
88
+ typeof value.id === "string" &&
89
+ typeof value.type === "string");
90
+ }
91
+ function hasRenderableText(value) {
92
+ return value.trim().replace(/\s+/g, " ").length > 0;
93
+ }
94
+ export function isIdleBriefEnvelope(
95
+ // implements REQ-opencode-kibi-briefing-v4
96
+ value) {
97
+ if (!isRecord(value))
98
+ return false;
99
+ const hasBaseFields = (value.schemaVersion === "1.0" || value.schemaVersion === "2.0") &&
100
+ typeof value.briefId === "string" &&
101
+ (value.type === "success" || value.type === "warning") &&
102
+ typeof value.sessionId === "string" &&
103
+ typeof value.branch === "string" &&
104
+ typeof value.createdAt === "string" &&
105
+ typeof value.unread === "boolean" &&
106
+ isAuditCursor(value.auditCursor) &&
107
+ typeof value.summary === "string" &&
108
+ isValidation(value.validation) &&
109
+ typeof value.contentHash === "string";
110
+ if (!hasBaseFields)
111
+ return false;
112
+ if (value.schemaVersion === "1.0") {
113
+ return (isRecord(value.counts) &&
114
+ typeof value.counts.requirementsAdded === "number" &&
115
+ typeof value.counts.relationshipsAdded === "number" &&
116
+ typeof value.counts.entitiesDeleted === "number" &&
117
+ isBriefingBase(value.briefing));
118
+ }
119
+ return (isRecord(value.counts) &&
120
+ typeof value.counts.entitiesAdded === "number" &&
121
+ typeof value.counts.entitiesModified === "number" &&
122
+ typeof value.counts.entitiesRemoved === "number" &&
123
+ typeof value.counts.relationshipsChanged === "number" &&
124
+ isRecord(value.changes) &&
125
+ isRecord(value.changes.entities) &&
126
+ Array.isArray(value.changes.entities.added) &&
127
+ value.changes.entities.added.every(isChangeItem) &&
128
+ Array.isArray(value.changes.entities.modified) &&
129
+ value.changes.entities.modified.every(isChangeItem) &&
130
+ Array.isArray(value.changes.entities.removed) &&
131
+ value.changes.entities.removed.every(isChangeItem) &&
132
+ isRecord(value.changes.relationships) &&
133
+ typeof value.changes.relationships.changed === "number" &&
134
+ isBriefingV2(value.briefing));
135
+ }
136
+ export function createBriefId() {
137
+ // implements REQ-opencode-kibi-briefing-v4
138
+ return `brief-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
139
+ }
140
+ export function computeContentHash(payload) {
141
+ // implements REQ-opencode-kibi-briefing-v4
142
+ const env = payload;
143
+ // Normalize string: trim and collapse internal whitespace
144
+ const norm = (s) => s.trim().replace(/\s+/g, " ");
145
+ const normalizeCitations = (citations) => citations.map((c) => ({
146
+ id: c.id,
147
+ ...(c.type ? { type: norm(c.type) } : {}),
148
+ ...(c.title ? { title: norm(c.title) } : {}),
149
+ ...(c.source ? { source: norm(c.source) } : {}),
150
+ ...(c.textRef ? { textRef: norm(c.textRef) } : {}),
151
+ }));
152
+ const normalizeStatements = (statements = []) => statements.map((statement) => ({
153
+ statement: norm(statement.statement),
154
+ citationIds: statement.citationIds,
155
+ }));
156
+ const normalizeReasonItems = (items = []) => items
157
+ .map((item) => ({
158
+ kind: item.kind,
159
+ text: norm(item.text),
160
+ entityIds: [...item.entityIds].sort(),
161
+ ...(item.citationIds ? { citationIds: [...item.citationIds].sort() } : {}),
162
+ ...(item.severity ? { severity: item.severity } : {}),
163
+ }))
164
+ .filter((item) => hasRenderableText(item.text));
165
+ const normalizeDeliveryReasons = (deliveryReasons) => {
166
+ if (!deliveryReasons)
167
+ return undefined;
168
+ const items = normalizeReasonItems(deliveryReasons.items);
169
+ if (items.length === 0)
170
+ return undefined;
171
+ return {
172
+ version: deliveryReasons.version,
173
+ toast: {
174
+ title: norm(deliveryReasons.toast.title),
175
+ summary: norm(deliveryReasons.toast.summary),
176
+ whyItMatters: norm(deliveryReasons.toast.whyItMatters),
177
+ },
178
+ items,
179
+ };
180
+ };
181
+ const normalizeChangeItems = (items) => items.map((item) => ({
182
+ id: item.id,
183
+ type: norm(item.type),
184
+ ...(item.title ? { title: norm(item.title) } : {}),
185
+ ...(item.source ? { source: norm(item.source) } : {}),
186
+ ...(item.textRef ? { textRef: norm(item.textRef) } : {}),
187
+ }));
188
+ // Build canonical visible-content projection (ignoring volatile fields)
189
+ const projection = env.schemaVersion === "2.0"
190
+ ? {
191
+ schemaVersion: "2.0",
192
+ type: env.type,
193
+ summary: norm(env.summary),
194
+ counts: env.counts,
195
+ changes: {
196
+ entities: {
197
+ added: normalizeChangeItems(env.changes.entities.added),
198
+ modified: normalizeChangeItems(env.changes.entities.modified),
199
+ removed: normalizeChangeItems(env.changes.entities.removed),
200
+ },
201
+ relationships: {
202
+ changed: env.changes.relationships.changed,
203
+ },
204
+ },
205
+ briefing: {
206
+ tldr: norm(env.briefing.tldr),
207
+ normalizedPromptBlock: norm(env.briefing.promptBlock),
208
+ citations: normalizeCitations(env.briefing.citations ?? []),
209
+ changeNarrative: env.briefing.changeNarrative.map((line) => norm(line)),
210
+ deliveryReasons: normalizeDeliveryReasons(env.briefing.deliveryReasons),
211
+ constraints: normalizeStatements(env.briefing.constraints),
212
+ regressionRisks: normalizeStatements(env.briefing.regressionRisks),
213
+ missingEvidence: normalizeStatements(env.briefing.missingEvidence),
214
+ },
215
+ validation: {
216
+ count: env.validation.count,
217
+ violations: env.validation.violations.map((v) => ({
218
+ rule: v.rule,
219
+ entityId: v.entityId,
220
+ description: norm(v.description),
221
+ })),
222
+ },
223
+ }
224
+ : {
225
+ type: env.type,
226
+ summary: norm(env.summary),
227
+ counts: env.counts,
228
+ briefing: {
229
+ tldr: norm(env.briefing.tldr),
230
+ normalizedPromptBlock: norm(env.briefing.promptBlock),
231
+ citations: (env.briefing.citations ?? []).map((c) => ({
232
+ id: c.id,
233
+ title: c.title ?? "",
234
+ })),
235
+ constraints: (env.briefing.constraints ?? []).map((c) => ({
236
+ statement: norm(c.statement),
237
+ citationIds: c.citationIds,
238
+ })),
239
+ regressionRisks: (env.briefing.regressionRisks ?? []).map((r) => ({
240
+ statement: norm(r.statement),
241
+ citationIds: r.citationIds,
242
+ })),
243
+ missingEvidence: (env.briefing.missingEvidence ?? []).map((m) => ({
244
+ statement: norm(m.statement),
245
+ citationIds: m.citationIds,
246
+ })),
247
+ deliveryReasons: normalizeDeliveryReasons(env.briefing.deliveryReasons),
248
+ },
249
+ validation: {
250
+ count: env.validation.count,
251
+ violations: env.validation.violations.map((v) => ({
252
+ rule: v.rule,
253
+ entityId: v.entityId,
254
+ description: norm(v.description),
255
+ })),
256
+ },
257
+ };
258
+ return crypto
259
+ .createHash("sha256")
260
+ .update(JSON.stringify(projection))
261
+ .digest("hex");
262
+ }
package/dist/index.d.ts CHANGED
@@ -1,39 +1,2 @@
1
- export interface PluginInput {
2
- worktree: string;
3
- directory: string;
4
- workspace?: string;
5
- project?: unknown;
6
- serverUrl?: unknown;
7
- $?: unknown;
8
- client?: {
9
- tui?: {
10
- toast?: (payload: {
11
- variant?: "info" | "success" | "warning" | "error";
12
- title?: string;
13
- message: string;
14
- duration?: number;
15
- }) => void | Promise<void>;
16
- };
17
- app: {
18
- log: (payload: Record<string, unknown>) => Promise<void>;
19
- };
20
- };
21
- }
22
- interface OpencodeEventPayload {
23
- type: string;
24
- properties?: Record<string, unknown>;
25
- }
26
- interface EventHookInput {
27
- event: OpencodeEventPayload;
28
- }
29
- interface SystemTransformOutput {
30
- system: string[];
31
- }
32
- export interface Hooks {
33
- event?: (input: EventHookInput) => void | Promise<void>;
34
- "experimental.chat.system.transform"?: (input: unknown, output: SystemTransformOutput) => void | Promise<void>;
35
- "chat.params"?: (input: unknown, output: unknown) => void | Promise<void>;
36
- }
37
- export type Plugin = (input: PluginInput) => Hooks | Promise<Hooks>;
38
- declare const kibiOpencodePlugin: Plugin;
39
- export default kibiOpencodePlugin;
1
+ export { default } from "./plugin.js";
2
+ export type { Hooks, Plugin, PluginInput } from "./plugin.js";