kibi-agent-core 0.8.1 → 0.9.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.
- package/CHANGELOG.md +11 -0
- package/dist/decision-guard.d.ts +16 -1
- package/dist/decision-guard.js +51 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# kibi-agent-core
|
|
2
2
|
|
|
3
|
+
## 0.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 180196c: The requirements signoff view now reads well on every host, not only in the hosts that draw Kibi's fenced block.
|
|
8
|
+
- `kibi signoff` prints plain Markdown by default (`--format chat`): headings, quoted statements and lists that render in any chat window, and in messaging tools for agents whose replies go through one (cloud and project sessions). The path of the self-contained page `.kb/briefs/signoff/latest.html` goes to stderr, so an agent can attach or publish it next to the message. `--format md` keeps the fenced block for the OpenCode terminal card, and `KIBI_SIGNOFF_FORMAT` sets the default per host.
|
|
9
|
+
- After a session writes a requirement, the Claude Code, Codex, Cursor and ZCode stop hooks ask once for the signoff view before the work is reported done, unless `kibi signoff` already ran since. A requirement the agent wrote is put to the person through the view, not retold in the agent's words.
|
|
10
|
+
- `/kibi-signoff` is a new command in Claude Code, Cursor and ZCode.
|
|
11
|
+
- The `kibi-decisions` and `kibi-commit-review` skills (1.2.0) say how to show the view on each host, and `kibi-usage` (2.22.0) points to `kibi signoff` when it says to leave `approved_by` to the person. The OpenCode guidance asks for `--format md` so the terminal card still renders.
|
|
12
|
+
- The Claude Code plugin README shows the `.claude/settings.json` snippet that loads the plugin in cloud sessions.
|
|
13
|
+
|
|
3
14
|
## 0.8.1
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
package/dist/decision-guard.d.ts
CHANGED
|
@@ -55,7 +55,7 @@ export type DecisionSession = {
|
|
|
55
55
|
sessionId: string | undefined;
|
|
56
56
|
};
|
|
57
57
|
/** Session markers the decision guard keeps. */
|
|
58
|
-
export type DecisionFlag = "source-edited" | "kb-recorded" | "rule-prompt" | "capture-asked";
|
|
58
|
+
export type DecisionFlag = "source-edited" | "kb-recorded" | "rule-prompt" | "capture-asked" | "requirement-recorded" | "signoff-asked";
|
|
59
59
|
/** Set a session marker; best effort. */
|
|
60
60
|
export declare function markDecisionFlag(session: DecisionSession, flag: DecisionFlag): void;
|
|
61
61
|
export declare function hasDecisionFlag(session: DecisionSession, flag: DecisionFlag): boolean;
|
|
@@ -77,6 +77,21 @@ export declare function requestWords(session: DecisionSession): string[];
|
|
|
77
77
|
* not been asked yet (claiming the ask).
|
|
78
78
|
*/
|
|
79
79
|
export declare function claimCaptureReminder(session: DecisionSession): boolean;
|
|
80
|
+
/** Where `kibi signoff` keeps the latest view, relative to the workspace. */
|
|
81
|
+
export declare const SIGNOFF_LATEST_JSON: string;
|
|
82
|
+
/**
|
|
83
|
+
* Whether a kb_upsert call's input writes a requirement (not a dry run).
|
|
84
|
+
* Hosts pass the MCP arguments, sometimes wrapped in `arguments`.
|
|
85
|
+
*/
|
|
86
|
+
export declare function isRequirementUpsert(toolInput: unknown): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Whether the stop should ask for a signoff view: the session wrote a
|
|
89
|
+
* requirement, `kibi signoff` has not written a view since, and the session
|
|
90
|
+
* has not been asked yet (claiming the ask).
|
|
91
|
+
*/
|
|
92
|
+
export declare function claimSignoffReminder(session: DecisionSession, workspaceRoot: string): boolean;
|
|
93
|
+
/** Stop-time note for a session that recorded requirements without a signoff view. */
|
|
94
|
+
export declare function signoffReminder(): string;
|
|
80
95
|
/** Firm requirements the agent was already told about this session. */
|
|
81
96
|
export declare function settledFirmRequirements(session: DecisionSession): Set<string>;
|
|
82
97
|
/** Remember that the agent was told about these firm requirements. */
|
package/dist/decision-guard.js
CHANGED
|
@@ -212,6 +212,57 @@ export function claimCaptureReminder(session) {
|
|
|
212
212
|
!hasDecisionFlag(session, "kb-recorded") &&
|
|
213
213
|
claimDecisionFlag(session, "capture-asked"));
|
|
214
214
|
}
|
|
215
|
+
// implements REQ-kibi-signoff-views
|
|
216
|
+
/** Where `kibi signoff` keeps the latest view, relative to the workspace. */
|
|
217
|
+
export const SIGNOFF_LATEST_JSON = path.join(".kb", "briefs", "signoff", "latest.json");
|
|
218
|
+
function record(value) {
|
|
219
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
220
|
+
? value
|
|
221
|
+
: undefined;
|
|
222
|
+
}
|
|
223
|
+
// implements REQ-kibi-signoff-views
|
|
224
|
+
/**
|
|
225
|
+
* Whether a kb_upsert call's input writes a requirement (not a dry run).
|
|
226
|
+
* Hosts pass the MCP arguments, sometimes wrapped in `arguments`.
|
|
227
|
+
*/
|
|
228
|
+
export function isRequirementUpsert(toolInput) {
|
|
229
|
+
const input = record(toolInput);
|
|
230
|
+
const args = record(input?.arguments) ?? record(input?.args) ?? input;
|
|
231
|
+
return args?.type === "req" && args.dryRun !== true;
|
|
232
|
+
}
|
|
233
|
+
function mtimeMs(file) {
|
|
234
|
+
if (!file)
|
|
235
|
+
return undefined;
|
|
236
|
+
try {
|
|
237
|
+
return fs.statSync(file).mtimeMs;
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
return undefined;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// implements REQ-kibi-signoff-views
|
|
244
|
+
/**
|
|
245
|
+
* Whether the stop should ask for a signoff view: the session wrote a
|
|
246
|
+
* requirement, `kibi signoff` has not written a view since, and the session
|
|
247
|
+
* has not been asked yet (claiming the ask).
|
|
248
|
+
*/
|
|
249
|
+
export function claimSignoffReminder(session, workspaceRoot) {
|
|
250
|
+
const recorded = mtimeMs(sessionPath(session, "requirement-recorded"));
|
|
251
|
+
if (recorded === undefined)
|
|
252
|
+
return false;
|
|
253
|
+
const shown = mtimeMs(path.join(workspaceRoot, SIGNOFF_LATEST_JSON));
|
|
254
|
+
if (shown !== undefined && shown >= recorded)
|
|
255
|
+
return false;
|
|
256
|
+
return claimDecisionFlag(session, "signoff-asked");
|
|
257
|
+
}
|
|
258
|
+
// implements REQ-kibi-signoff-views
|
|
259
|
+
/** Stop-time note for a session that recorded requirements without a signoff view. */
|
|
260
|
+
export function signoffReminder() {
|
|
261
|
+
return [
|
|
262
|
+
"Kibi: this session recorded or changed requirements, and the person has not seen them as a signoff view.",
|
|
263
|
+
"Before reporting the work done or asking to commit, run `kibi signoff` and put its output in the reply unchanged; a requirement the agent wrote waits for the person's approval, so ask for it with this view, never in your own words. When replies go through a messaging tool, pass the output there, and attach or publish `.kb/briefs/signoff/latest.html` when the host can show a page (kibi-decisions, resources/signoff-views.md).",
|
|
264
|
+
].join("\n");
|
|
265
|
+
}
|
|
215
266
|
function readSettled(file) {
|
|
216
267
|
if (!file)
|
|
217
268
|
return [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-agent-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Shared low-latency hook helpers for Kibi agent adapters",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -66,6 +66,6 @@
|
|
|
66
66
|
"@types/node": "^25.9.8",
|
|
67
67
|
"semver": "^7.8.5",
|
|
68
68
|
"typescript": "^5.7.0",
|
|
69
|
-
"yaml": "^2.9.
|
|
69
|
+
"yaml": "^2.9.1"
|
|
70
70
|
}
|
|
71
71
|
}
|