kibi-opencode 0.7.1 → 0.7.2
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 +17 -8
- package/dist/index.js +6 -1
- package/dist/logger.d.ts +28 -0
- package/dist/logger.js +17 -1
- package/dist/plugin-startup.js +4 -1
- package/dist/prompt.js +11 -14
- package/dist/scheduler.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -110,8 +110,7 @@ The plugin injects guidance into OpenCode sessions to improve agent grounding. U
|
|
|
110
110
|
|
|
111
111
|
### Bootstrap Command
|
|
112
112
|
|
|
113
|
-
OpenCode exposes Kibi MCP prompts as slash commands. The
|
|
114
|
-
|
|
113
|
+
OpenCode exposes Kibi MCP prompts as slash commands. The \`/init-kibi\` command triggers the \`kb_autopilot_generate\` workflow to assist in retroactive bootstrap using only public MCP tools.
|
|
115
114
|
### Discovery-first MCP guidance
|
|
116
115
|
|
|
117
116
|
Agent-visible guidance is intentionally limited to the curated public MCP surface:
|
|
@@ -181,14 +180,24 @@ Smart enforcement keeps the plugin advisory-only: prompt injection can warn, exp
|
|
|
181
180
|
|
|
182
181
|
### Logging Policy
|
|
183
182
|
|
|
184
|
-
The plugin follows a **silent-except-errors** policy for terminal output:
|
|
183
|
+
The plugin follows a **silent-except-operational-errors** policy for terminal output, with a three-tier failure classification:
|
|
184
|
+
|
|
185
|
+
| Classification | Examples | Surface | Terminal | Structured |
|
|
186
|
+
|---------------|----------|---------|----------|------------|
|
|
187
|
+
| **Advisory (background)** | scheduler check failures, degraded-mode latches | `errorStructuredOnly()` | No | Yes, via `client.app.log()` |
|
|
188
|
+
| **Operational (plugin)** | bootstrap-needed, sync failure, hook/init failure | `error()` | Yes, via `console.error` | Yes, via `client.app.log()` |
|
|
189
|
+
| **Authoritative external** | git hooks, CLI checks | Outside plugin surface | N/A | N/A |
|
|
190
|
+
|
|
191
|
+
### Failure Routing Contract
|
|
192
|
+
|
|
193
|
+
The logger exposes two error-level surfaces with distinct routing semantics:
|
|
194
|
+
|
|
195
|
+
- **`error(msg, metadata?)`** — Operational plugin failures. Always emits to `console.error` for terminal visibility, plus `client.app.log()` when a client is bound. Use for bootstrap-needed, hook/init failures, and sync failures that require developer attention.
|
|
196
|
+
- **`errorStructuredOnly(msg, metadata?)`** — Advisory background maintenance failures. Routes through `client.app.log()` only when a client is bound; completely silent when no client is bound (no `console.error` fallback). Use for scheduler check failures and degraded-mode latches.
|
|
185
197
|
|
|
186
|
-
|
|
187
|
-
|---------|----------|---------------|
|
|
188
|
-
| Normal operation (sync success, guidance injection, session summaries) | No | Yes, via `client.app.log()` |
|
|
189
|
-
| Error-class events (bootstrap-needed, sync/check failure, hook/init failure) | Yes, via `console.error` | Yes, via `client.app.log()` |
|
|
198
|
+
**Contract rule:** Once `client` is bound (after `setClient()`), advisory logging MUST use `errorStructuredOnly()`. When no client is bound, `errorStructuredOnly()` is completely silent — it does not fall back to `console.error`.
|
|
190
199
|
|
|
191
|
-
Routine diagnostics route through [`client.app.log()`](https://opencode.ai/docs/plugins/) and never appear in the terminal. Only error-class events break terminal silence. This keeps the developer's workspace clean while preserving full visibility in structured logs for debugging.
|
|
200
|
+
Routine diagnostics route through [`client.app.log()`](https://opencode.ai/docs/plugins/) and never appear in the terminal. Only operational error-class events break terminal silence. This keeps the developer's workspace clean while preserving full visibility in structured logs for debugging.
|
|
192
201
|
|
|
193
202
|
The `experimental.chat.system.transform` hook handles prompt injection (see [Hook Policy](#hook-policy)). The `chat.params` hook is compatibility-only and never carries prompt text.
|
|
194
203
|
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import * as fs from "node:fs";
|
|
|
13
13
|
function deriveFileBucket(kind) {
|
|
14
14
|
return kind;
|
|
15
15
|
}
|
|
16
|
+
const startupNotifyGlobals = globalThis;
|
|
16
17
|
/**
|
|
17
18
|
* Lint requirement documents for embedded scenarios/tests and oversized content.
|
|
18
19
|
*/
|
|
@@ -426,7 +427,11 @@ const kibiOpencodePlugin = async (input) => {
|
|
|
426
427
|
logger.info("kibi-opencode: setup complete");
|
|
427
428
|
if (input.client && !maintenanceDegraded) {
|
|
428
429
|
const client = input.client;
|
|
429
|
-
|
|
430
|
+
const scheduleStartupNotify = startupNotifyGlobals.__kibi_test_schedule_startup_notify ??
|
|
431
|
+
((callback, delayMs) => {
|
|
432
|
+
setTimeout(callback, delayMs);
|
|
433
|
+
});
|
|
434
|
+
scheduleStartupNotify(() => {
|
|
430
435
|
notifyStartup(client, {
|
|
431
436
|
suppressToast: cfg.ux.toastStartup === false,
|
|
432
437
|
directory: input.directory,
|
package/dist/logger.d.ts
CHANGED
|
@@ -8,4 +8,32 @@ export declare function setClient(c: PluginClient): void;
|
|
|
8
8
|
export declare function resetClient(): void;
|
|
9
9
|
export declare function info(msg: string, metadata?: LogMetadata): void;
|
|
10
10
|
export declare function warn(msg: string, metadata?: LogMetadata): void;
|
|
11
|
+
/**
|
|
12
|
+
* Failure classification contract for kibi-opencode logging.
|
|
13
|
+
*
|
|
14
|
+
* Three categories of failures, each with distinct routing:
|
|
15
|
+
*
|
|
16
|
+
* 1. **Advisory (background maintenance)** — e.g. scheduler sync/check failures,
|
|
17
|
+
* degraded-mode latches. These are non-blocking and advisory-only.
|
|
18
|
+
* Route through `errorStructuredOnly()`: emits to `client.app.log()` when
|
|
19
|
+
* client is bound; completely silent (no console.error) when no client exists.
|
|
20
|
+
* Advisory noise must never pollute the TUI.
|
|
21
|
+
*
|
|
22
|
+
* 2. **Operational (plugin failures)** — e.g. bootstrap-needed, hook/init failures.
|
|
23
|
+
* Route through `error()`: always emits to `console.error` for terminal
|
|
24
|
+
* visibility, plus `client.app.log()` when client is bound.
|
|
25
|
+
*
|
|
26
|
+
* 3. **Authoritative external failures** — git hooks, CLI checks. These are
|
|
27
|
+
* outside the plugin's logging surface entirely.
|
|
28
|
+
*
|
|
29
|
+
* ## Contract Rules
|
|
30
|
+
*
|
|
31
|
+
* - Once `client` is bound (after `setClient()`), advisory logging MUST use
|
|
32
|
+
* `errorStructuredOnly()` which routes through `client.app.log()` only.
|
|
33
|
+
* - `errorStructuredOnly()` is completely silent when no client is bound
|
|
34
|
+
* (no console.error fallback). Advisory failures never pollute the terminal.
|
|
35
|
+
* - `error()` preserves full terminal visibility for operational failures.
|
|
36
|
+
*/
|
|
37
|
+
export type FailureClassification = "advisory_background" | "operational_plugin" | "authoritative_external";
|
|
38
|
+
export declare function errorStructuredOnly(msg: string, metadata?: LogMetadata): void;
|
|
11
39
|
export declare function error(msg: string, metadata?: LogMetadata): void;
|
package/dist/logger.js
CHANGED
|
@@ -41,8 +41,24 @@ export function warn(msg, metadata) {
|
|
|
41
41
|
// Fallback when no client is available
|
|
42
42
|
}
|
|
43
43
|
// implements REQ-opencode-kibi-plugin-v1
|
|
44
|
+
export function errorStructuredOnly(msg, metadata) {
|
|
45
|
+
if (client) {
|
|
46
|
+
void client.app
|
|
47
|
+
.log({
|
|
48
|
+
body: buildBody("error", msg, metadata),
|
|
49
|
+
})
|
|
50
|
+
.catch(() => {
|
|
51
|
+
// Advisory failures are intentionally silent even on client logging
|
|
52
|
+
// failures — advisory noise must never pollute the TUI or terminal.
|
|
53
|
+
});
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
// No client bound: advisory failures are intentionally silent
|
|
57
|
+
// (no console.error fallback — advisory noise must not pollute TUI)
|
|
58
|
+
}
|
|
59
|
+
// implements REQ-opencode-kibi-plugin-v1
|
|
44
60
|
export function error(msg, metadata) {
|
|
45
|
-
// Always emit to console for user visibility
|
|
61
|
+
// Always emit to console for user visibility (operational failures)
|
|
46
62
|
console.error("[kibi-opencode]", msg);
|
|
47
63
|
// Also emit to structured logs if client is available
|
|
48
64
|
if (client) {
|
package/dist/plugin-startup.js
CHANGED
|
@@ -136,7 +136,10 @@ export async function runPluginStartup(input) {
|
|
|
136
136
|
branch: currentBranch,
|
|
137
137
|
});
|
|
138
138
|
logger.info("kibi-opencode: setting up hooks");
|
|
139
|
-
const
|
|
139
|
+
const schedulerFactoryGlobals = globalThis;
|
|
140
|
+
const schedulerFactory = schedulerFactoryGlobals.__kibi_test_scheduler_factory_by_worktree?.get(input.worktree) ??
|
|
141
|
+
schedulerFactoryGlobals.__kibi_test_scheduler_factory ??
|
|
142
|
+
createSyncScheduler;
|
|
140
143
|
const scheduler = cfg.sync
|
|
141
144
|
.enabled
|
|
142
145
|
? (() => {
|
package/dist/prompt.js
CHANGED
|
@@ -80,10 +80,11 @@ export function postureGuidance(posture) {
|
|
|
80
80
|
return `🔧 **Bootstrap required**
|
|
81
81
|
|
|
82
82
|
This repository does not appear to have Kibi initialized. Agents should:
|
|
83
|
-
-
|
|
84
|
-
-
|
|
83
|
+
- Start with \`kb_autopilot_generate\` to discover entities and bootstrap the KB (preferred workflow)
|
|
84
|
+
- Use \`/init-kibi\` as the sanctioned slash command for initial repo setup
|
|
85
|
+
- Ask the user/operator to run setup or repair outside this session if bootstrap is insufficient
|
|
85
86
|
|
|
86
|
-
Do not run \`kibi\` CLI commands directly; use
|
|
87
|
+
Do not run \`kibi\` CLI commands directly; use public MCP tools (kb_autopilot_generate, kb_search, kb_query, kb_status, kb_find_gaps, kb_coverage, kb_graph, kb_upsert, kb_delete, kb_check).`;
|
|
87
88
|
case "root_partial":
|
|
88
89
|
return `⚠️ **Partial KB setup detected**
|
|
89
90
|
|
|
@@ -119,17 +120,17 @@ function buildContextualGuidance(context) {
|
|
|
119
120
|
if (postureBlock)
|
|
120
121
|
selectedBlock = postureBlock;
|
|
121
122
|
}
|
|
122
|
-
// Priority 4: Legacy workspace health bootstrap (only when no posture) — not cache-suppressed
|
|
123
123
|
else if (!context.posture && context.workspaceHealth?.needsBootstrap) {
|
|
124
124
|
selectedBlock = `🔧 **Bootstrap required**
|
|
125
125
|
|
|
126
126
|
This repository does not appear to have Kibi initialized. Agents should:
|
|
127
|
-
-
|
|
128
|
-
-
|
|
127
|
+
- Start with \`kb_autopilot_generate\` to discover entities and bootstrap the KB (preferred workflow)
|
|
128
|
+
- Use \`/init-kibi\` as the sanctioned slash command for initial repo setup
|
|
129
|
+
- Ask the user/operator to run setup or repair outside this session if bootstrap is insufficient
|
|
129
130
|
|
|
130
|
-
Do not run \`kibi\` CLI commands directly; use
|
|
131
|
+
Do not run \`kibi\` CLI commands directly; use public MCP tools (kb_autopilot_generate, kb_search, kb_query, kb_status, kb_find_gaps, kb_coverage, kb_graph, kb_upsert, kb_delete, kb_check).`;
|
|
132
|
+
// Advisory guidance: check cache before selecting, since these blocks can be safely suppressed
|
|
131
133
|
}
|
|
132
|
-
// Advisory guidance: check cache before selecting, since these blocks can be safely suppressed
|
|
133
134
|
else {
|
|
134
135
|
// Cache check: skip repeated advisory guidance — only after critical signals are handled above
|
|
135
136
|
// Allow degraded advisory to bypass cache so it is always visible
|
|
@@ -207,7 +208,7 @@ If you're adding long explanatory comments, consider routing that knowledge to:
|
|
|
207
208
|
selectedBlock = GUIDANCE_BY_RISK.kb_doc_structural;
|
|
208
209
|
}
|
|
209
210
|
}
|
|
210
|
-
}
|
|
211
|
+
} // closing brace for Priority 2-4 else block starting at 187
|
|
211
212
|
// Source-linked micro-brief: insert after header line for code risk classes
|
|
212
213
|
// Inserting after the header (not prepending before it) preserves the header
|
|
213
214
|
// under enforceBudget's trimming logic, which only collects non-bullet lines
|
|
@@ -354,11 +355,7 @@ Dogfood note for this repo: OpenCode here uses local built \`kibi-mcp\` and \`ki
|
|
|
354
355
|
5. **Link during work**: When creating KB entities, include relationship rows: specified_by (req→scenario), implements (symbol→req for ownership), covered_by (symbol→test for coverage), executable_for (test code→test).
|
|
355
356
|
6. **Validate**: Run kb_check after KB mutations to catch violations early.
|
|
356
357
|
|
|
357
|
-
**Public Kibi tools only:** kb_search, kb_query, kb_status, kb_find_gaps, kb_coverage, kb_graph, kb_upsert, kb_delete, kb_check
|
|
358
|
-
|
|
359
|
-
Do not invoke Kibi CLI commands directly from the agent.
|
|
360
|
-
|
|
361
|
-
Bootstrap existing repos: use \`/init-kibi\` to run the retroactive initialization workflow.`;
|
|
358
|
+
**Public Kibi tools only:** kb_autopilot_generate, kb_search, kb_query, kb_status, kb_find_gaps, kb_coverage, kb_graph, kb_upsert, kb_delete, kb_check.\n\nDo not invoke Kibi CLI commands directly from the agent.\n\nBootstrap existing repos: use \`/init-kibi\` to run the retroactive initialization (\`kb_autopilot_generate\`) workflow.`;
|
|
362
359
|
/**
|
|
363
360
|
* Build prompt with contextual guidance based on posture, risk class, and cache state.
|
|
364
361
|
*/
|
package/dist/scheduler.js
CHANGED
|
@@ -118,7 +118,7 @@ class WorktreeSyncScheduler {
|
|
|
118
118
|
const checkResult = await this.runCheck(this.worktree, checkRules);
|
|
119
119
|
checkExitCode = checkResult.exitCode;
|
|
120
120
|
if (checkExitCode !== 0) {
|
|
121
|
-
logger.
|
|
121
|
+
logger.errorStructuredOnly(`check.failed ${JSON.stringify({ rules: checkRules, exitCode: checkExitCode })}`);
|
|
122
122
|
}
|
|
123
123
|
else {
|
|
124
124
|
logger.info(`check.succeeded ${JSON.stringify({ rules: checkRules })}`);
|