@shield-agent/kya 0.29.0 → 0.31.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/.cursor-plugin/plugin.json +1 -1
- package/.mcp.json +1 -1
- package/README.md +4 -4
- package/amp/settings.example.json +1 -1
- package/claude/claude_desktop_config.example.json +1 -1
- package/cline/cline_mcp_settings.example.json +1 -1
- package/copilot/mcp-config.example.json +1 -1
- package/dist/certify/attest.js +4 -4
- package/dist/certify/attest.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +8 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/certify.js +6 -6
- package/dist/commands/certify.js.map +1 -1
- package/dist/commands/connect.d.ts +1 -1
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +15 -8
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/init.js +5 -5
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/orr.d.ts.map +1 -1
- package/dist/commands/orr.js +6 -4
- package/dist/commands/orr.js.map +1 -1
- package/dist/commands/receipt.d.ts.map +1 -1
- package/dist/commands/receipt.js +5 -5
- package/dist/commands/receipt.js.map +1 -1
- package/dist/commands/start.d.ts +1 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +9 -2
- package/dist/commands/start.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -4
- package/dist/config.js.map +1 -1
- package/dist/fs-atomic.d.ts +40 -0
- package/dist/fs-atomic.d.ts.map +1 -1
- package/dist/fs-atomic.js +140 -1
- package/dist/fs-atomic.js.map +1 -1
- package/dist/receipt/auto-open.d.ts.map +1 -1
- package/dist/receipt/auto-open.js +4 -3
- package/dist/receipt/auto-open.js.map +1 -1
- package/dist/receipt/daemon.d.ts.map +1 -1
- package/dist/receipt/daemon.js +7 -4
- package/dist/receipt/daemon.js.map +1 -1
- package/dist/receipt/live-server.d.ts +11 -0
- package/dist/receipt/live-server.d.ts.map +1 -1
- package/dist/receipt/live-server.js +155 -11
- package/dist/receipt/live-server.js.map +1 -1
- package/dist/receipt/openshell-card.d.ts +13 -5
- package/dist/receipt/openshell-card.d.ts.map +1 -1
- package/dist/receipt/openshell-card.js +25 -7
- package/dist/receipt/openshell-card.js.map +1 -1
- package/dist/receipt/render-receipt.d.ts.map +1 -1
- package/dist/receipt/render-receipt.js +156 -26
- package/dist/receipt/render-receipt.js.map +1 -1
- package/dist/receipt/share.d.ts +6 -0
- package/dist/receipt/share.d.ts.map +1 -1
- package/dist/receipt/share.js +12 -1
- package/dist/receipt/share.js.map +1 -1
- package/dist/sandbox/openshell-policy.d.ts.map +1 -1
- package/dist/sandbox/openshell-policy.js +2 -3
- package/dist/sandbox/openshell-policy.js.map +1 -1
- package/dist/sandbox/runtime.d.ts.map +1 -1
- package/dist/sandbox/runtime.js +4 -4
- package/dist/sandbox/runtime.js.map +1 -1
- package/dist/star-cta.js +4 -4
- package/dist/star-cta.js.map +1 -1
- package/droid/README.md +1 -1
- package/droid/mcp.example.json +1 -1
- package/gemini/settings.example.json +1 -1
- package/grok/README.md +1 -1
- package/kilo/kilo.example.json +1 -1
- package/kimi/mcp.example.json +1 -1
- package/kiro/mcp.example.json +1 -1
- package/manifest.json +1 -1
- package/mastracode/mcp.example.json +1 -1
- package/mcp.json +1 -1
- package/openai/codex.config.example.toml +1 -1
- package/opencode/opencode.example.json +1 -1
- package/package.json +1 -1
- package/qwen/settings.example.json +1 -1
- package/server.json +2 -2
package/dist/fs-atomic.js
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
* team init, gate config, telemetry state and the certify attestation store.
|
|
4
4
|
*/
|
|
5
5
|
import { randomBytes } from "node:crypto";
|
|
6
|
-
import { closeSync, fchmodSync, lstatSync, openSync, renameSync, rmSync, writeSync } from "node:fs";
|
|
6
|
+
import { closeSync, fchmodSync, lstatSync, mkdirSync, openSync, realpathSync, renameSync, rmSync, writeSync, } from "node:fs";
|
|
7
|
+
import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
|
|
8
|
+
import { KyaError } from "./errors.js";
|
|
7
9
|
/**
|
|
8
10
|
* Crash-safe write: tmp file in the same directory, then rename onto the
|
|
9
11
|
* target (atomic on POSIX and win32 within one volume). A mid-write crash
|
|
@@ -66,4 +68,141 @@ export function atomicWriteSync(target, content, beforeRename) {
|
|
|
66
68
|
throw err;
|
|
67
69
|
}
|
|
68
70
|
}
|
|
71
|
+
/** A project-scope write refused because its path leaves the project (exit 1, never a silent skip). */
|
|
72
|
+
export class ProjectPathError extends KyaError {
|
|
73
|
+
constructor(message) {
|
|
74
|
+
super(message, "PROJECT_PATH_REFUSED", 1);
|
|
75
|
+
this.name = "ProjectPathError";
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function lstatOrUndefined(p) {
|
|
79
|
+
try {
|
|
80
|
+
return lstatSync(p);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Where a project-scope write to `target` may land, or throw ProjectPathError.
|
|
88
|
+
* User-level files (~/.claude.json and co.) never come here: following a
|
|
89
|
+
* dotfiles symlink there is a feature. Inside a project (a cloned repo can
|
|
90
|
+
* ship any symlink) the rules are:
|
|
91
|
+
* - every existing parent must resolve inside realpath(root) (covers a
|
|
92
|
+
* symlinked .kya, .cursor or .kiro directory);
|
|
93
|
+
* - a symlinked leaf is followed only when it resolves inside the root;
|
|
94
|
+
* - a dangling symlink, anywhere on the path, is refused;
|
|
95
|
+
* - a regular file with other hard links (nlink > 1) is refused;
|
|
96
|
+
* - an existing leaf must be a regular file (or a directory when dir=true).
|
|
97
|
+
* Returns the resolved path for a symlinked leaf, else the path itself.
|
|
98
|
+
*/
|
|
99
|
+
export function projectWritePath(target, root, dir = false) {
|
|
100
|
+
const realRoot = realpathSync(root);
|
|
101
|
+
const abs = resolve(target);
|
|
102
|
+
const inside = (p) => {
|
|
103
|
+
const r = relative(realRoot, p);
|
|
104
|
+
return r === "" || (r !== ".." && !r.startsWith(`..${sep}`) && !isAbsolute(r));
|
|
105
|
+
};
|
|
106
|
+
const fix = "Replace the symlink with a regular file or directory (remove the link, or copy the content in its place), then re-run. To write to that location on purpose, pass its resolved path (for example --out <resolved path>) instead of the link.";
|
|
107
|
+
const real = (p) => {
|
|
108
|
+
try {
|
|
109
|
+
return realpathSync(p);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
throw new ProjectPathError(`${p} is a dangling symlink inside the project; refusing to write ${target}. ${fix}`);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
let parent = dirname(abs);
|
|
116
|
+
while (!lstatOrUndefined(parent) && dirname(parent) !== parent)
|
|
117
|
+
parent = dirname(parent);
|
|
118
|
+
const realParent = real(parent);
|
|
119
|
+
if (!inside(realParent)) {
|
|
120
|
+
throw new ProjectPathError(`${target} is reached through ${parent}, which resolves to ${realParent}, outside the project ${realRoot}; refusing to write through a symlink. ${fix}`);
|
|
121
|
+
}
|
|
122
|
+
const st = lstatOrUndefined(abs);
|
|
123
|
+
if (!st)
|
|
124
|
+
return abs;
|
|
125
|
+
let out = abs;
|
|
126
|
+
let leaf = st;
|
|
127
|
+
if (st.isSymbolicLink()) {
|
|
128
|
+
out = real(abs);
|
|
129
|
+
if (!inside(out)) {
|
|
130
|
+
throw new ProjectPathError(`${target} is a symlink to ${out}, outside the project ${realRoot}; refusing to write through it. ${fix}`);
|
|
131
|
+
}
|
|
132
|
+
leaf = lstatSync(out);
|
|
133
|
+
}
|
|
134
|
+
if (dir ? !leaf.isDirectory() : !leaf.isFile()) {
|
|
135
|
+
throw new ProjectPathError(`${target} is not a regular ${dir ? "directory" : "file"}; refusing to write it`);
|
|
136
|
+
}
|
|
137
|
+
if (!dir && leaf.nlink > 1) {
|
|
138
|
+
throw new ProjectPathError(`${target} has other hard links (${leaf.nlink}), possibly outside the project or elsewhere in the repo; refusing to write a file shared with another path. Replace it with a regular copy (cp it to a new name, then move it over), then re-run.`);
|
|
139
|
+
}
|
|
140
|
+
return out;
|
|
141
|
+
}
|
|
142
|
+
/** mkdir -p for a project directory (for example .kya) after projectWritePath accepts it. */
|
|
143
|
+
export function ensureProjectDir(dir, root, mode) {
|
|
144
|
+
mkdirSync(projectWritePath(dir, root, true), { recursive: true, mode });
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* atomicWriteSync for a project-scope file: refuses paths that leave the
|
|
148
|
+
* project (projectWritePath) before writing and re-checks right before the
|
|
149
|
+
* rename. Residual: a same-user process can still swap a parent between that
|
|
150
|
+
* re-check and the rename (TOCTOU); the temp file is O_EXCL and the rename
|
|
151
|
+
* replaces a link instead of following it. Returns the path written.
|
|
152
|
+
*/
|
|
153
|
+
export function writeProjectFile(target, content, root) {
|
|
154
|
+
const out = projectWritePath(target, root);
|
|
155
|
+
mkdirSync(dirname(out), { recursive: true });
|
|
156
|
+
atomicWriteSync(out, content, () => {
|
|
157
|
+
if (projectWritePath(target, root) !== out) {
|
|
158
|
+
throw new ProjectPathError(`${target} changed while writing; nothing was written`);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
return out;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Whether an output path goes through the project: lexically inside root, or
|
|
165
|
+
* one of its existing ancestors is the project itself reached through an
|
|
166
|
+
* alias (a symlinked path to the repo). Decides which output rule applies.
|
|
167
|
+
*/
|
|
168
|
+
function underRoot(path, root) {
|
|
169
|
+
const r = relative(resolve(root), resolve(path));
|
|
170
|
+
if (r === "" || (r !== ".." && !r.startsWith(`..${sep}`) && !isAbsolute(r)))
|
|
171
|
+
return true;
|
|
172
|
+
const realRoot = realpathSync(root);
|
|
173
|
+
for (let a = resolve(path);; a = dirname(a)) {
|
|
174
|
+
if (lstatOrUndefined(a)) {
|
|
175
|
+
try {
|
|
176
|
+
if (realpathSync(a) === realRoot)
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
/* dangling: keep walking up */
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (dirname(a) === a)
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Report/output dir (kya certify --out, kya orr --out, kya receipt --out-dir):
|
|
189
|
+
* inside the project it gets the project rules, outside it is the user's
|
|
190
|
+
* explicit choice and is created as asked.
|
|
191
|
+
*/
|
|
192
|
+
export function ensureOutDir(dir, root) {
|
|
193
|
+
if (underRoot(dir, root))
|
|
194
|
+
ensureProjectDir(dir, root);
|
|
195
|
+
else
|
|
196
|
+
mkdirSync(dir, { recursive: true });
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Report/output file: project rules inside root; outside, an atomic write
|
|
200
|
+
* that replaces a planted leaf link instead of following it.
|
|
201
|
+
*/
|
|
202
|
+
export function writeOutFile(path, content, root) {
|
|
203
|
+
if (underRoot(path, root))
|
|
204
|
+
writeProjectFile(path, content, root);
|
|
205
|
+
else
|
|
206
|
+
atomicWriteSync(path, content);
|
|
207
|
+
}
|
|
69
208
|
//# sourceMappingURL=fs-atomic.js.map
|
package/dist/fs-atomic.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs-atomic.js","sourceRoot":"","sources":["../src/fs-atomic.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,
|
|
1
|
+
{"version":3,"file":"fs-atomic.js","sourceRoot":"","sources":["../src/fs-atomic.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-open.d.ts","sourceRoot":"","sources":["../../src/receipt/auto-open.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"auto-open.d.ts","sourceRoot":"","sources":["../../src/receipt/auto-open.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAKnD,wBAAgB,qBAAqB,CACnC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,KAAK,GAAE,OAAuC,GAC7C,OAAO,CAMT;AAyBD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,cAAc,EACtB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GACvE,OAAO,CAAC,cAAc,CAAC,CAuBzB"}
|
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
* per cwd (always on DENY/never-event). Disable with KYA_RECEIPT_AUTO=0.
|
|
7
7
|
* Force with KYA_RECEIPT_AUTO=1 (even non-TTY / CI).
|
|
8
8
|
*/
|
|
9
|
-
import { existsSync
|
|
9
|
+
import { existsSync } from "node:fs";
|
|
10
10
|
import { join } from "node:path";
|
|
11
11
|
import { spawn } from "node:child_process";
|
|
12
12
|
import { configDir } from "../config.js";
|
|
13
|
+
import { ensureProjectDir, writeProjectFile } from "../fs-atomic.js";
|
|
13
14
|
import { runReceipt } from "../commands/receipt.js";
|
|
14
15
|
export function shouldAutoOpenReceipt(env = process.env, isTty = Boolean(process.stdout.isTTY)) {
|
|
15
16
|
const flag = (env.KYA_RECEIPT_AUTO ?? "").trim().toLowerCase();
|
|
@@ -28,8 +29,8 @@ function alreadyOpened(cwd) {
|
|
|
28
29
|
return existsSync(markerPath(cwd));
|
|
29
30
|
}
|
|
30
31
|
function markOpened(cwd) {
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
ensureProjectDir(configDir(cwd), cwd);
|
|
33
|
+
writeProjectFile(markerPath(cwd), `${new Date().toISOString()}\n`, cwd);
|
|
33
34
|
}
|
|
34
35
|
function openBrowser(target) {
|
|
35
36
|
const platform = process.platform;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-open.js","sourceRoot":"","sources":["../../src/receipt/auto-open.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"auto-open.js","sourceRoot":"","sources":["../../src/receipt/auto-open.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/receipt/daemon.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/receipt/daemon.ts"],"names":[],"mappings":"AAqBA,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAK7E,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAiB3E;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAc7E;AAUD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAMxE;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAS7C;AAcD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAY3D;AAED,MAAM,WAAW,WAAW;IAC1B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,UAAU,EAAE,CAmB7F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,EAAE,CAU5E;AAoDD;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,GACnE,OAAO,CAAC,mBAAmB,CAAC,CAmD9B"}
|
package/dist/receipt/daemon.js
CHANGED
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
* command, which writes the state file once it is listening and removes it on
|
|
7
7
|
* shutdown.
|
|
8
8
|
*/
|
|
9
|
-
import { closeSync, existsSync, fchmodSync, lstatSync,
|
|
9
|
+
import { closeSync, existsSync, fchmodSync, lstatSync, openSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
|
|
10
10
|
import { execFileSync, spawn } from "node:child_process";
|
|
11
11
|
import { join } from "node:path";
|
|
12
12
|
import { fileURLToPath } from "node:url";
|
|
13
13
|
import { configDir, isLoopbackUrl } from "../config.js";
|
|
14
14
|
import { KyaError } from "../errors.js";
|
|
15
|
+
import { ensureProjectDir, projectWritePath } from "../fs-atomic.js";
|
|
15
16
|
import { CLI_VERSION } from "../version.js";
|
|
16
17
|
export function daemonStatePath(cwd) {
|
|
17
18
|
return join(configDir(cwd), "receipt-server.json");
|
|
@@ -38,11 +39,12 @@ export function readDaemonState(cwd) {
|
|
|
38
39
|
return undefined;
|
|
39
40
|
}
|
|
40
41
|
export function writeDaemonState(cwd, state) {
|
|
41
|
-
|
|
42
|
+
ensureProjectDir(configDir(cwd), cwd);
|
|
42
43
|
const path = daemonStatePath(cwd);
|
|
43
44
|
// Never write through a planted symlink; force 0600 on pre-existing files
|
|
44
|
-
// (the mode argument only applies at creation).
|
|
45
|
+
// (the mode argument only applies at creation). A hard linked file is refused.
|
|
45
46
|
removeIfSymlink(path);
|
|
47
|
+
projectWritePath(path, cwd);
|
|
46
48
|
const fd = openSync(path, "w", 0o600);
|
|
47
49
|
try {
|
|
48
50
|
fchmodSync(fd, 0o600);
|
|
@@ -245,9 +247,10 @@ export async function ensureReceiptDaemon(config, input) {
|
|
|
245
247
|
}
|
|
246
248
|
}
|
|
247
249
|
clearDaemonState(config.cwd);
|
|
248
|
-
|
|
250
|
+
ensureProjectDir(configDir(config.cwd), config.cwd);
|
|
249
251
|
const logPath = daemonLogPath(config.cwd);
|
|
250
252
|
removeIfSymlink(logPath);
|
|
253
|
+
projectWritePath(logPath, config.cwd);
|
|
251
254
|
const logFd = openSync(logPath, "a");
|
|
252
255
|
const args = [cliJsPath(), "receipt-serve", "--days", String(input.days)];
|
|
253
256
|
if (input.sessionId)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/receipt/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,SAAS,EACT,UAAU,EACV,UAAU,EACV,SAAS,EACT,
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/receipt/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,6 +29,17 @@ export interface ReportActionResult {
|
|
|
29
29
|
readonly status: number;
|
|
30
30
|
readonly body: Record<string, unknown>;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Run the ORR board against cwd and write <cwd>/orr-report/report.json (+ .md).
|
|
34
|
+
* Read-only probes; never throws (a failed board must not break the report
|
|
35
|
+
* server). The first-party producer set keeps it dependency-free.
|
|
36
|
+
*/
|
|
37
|
+
export declare function runOrrBoard(cwd: string): {
|
|
38
|
+
ok: boolean;
|
|
39
|
+
detail: string;
|
|
40
|
+
};
|
|
41
|
+
/** POST /action/orr-run: regenerate the ORR board on demand. */
|
|
42
|
+
export declare function runReportOrrAction(cwd: string): Promise<ReportActionResult>;
|
|
32
43
|
/**
|
|
33
44
|
* POST /action/import: validate the empty-state form body and run one import.
|
|
34
45
|
* `file` must be an absolute path to an existing regular file; agt may omit it
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live-server.d.ts","sourceRoot":"","sources":["../../src/receipt/live-server.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,KAAK,mBAAmB,EAIzB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAA2B,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"live-server.d.ts","sourceRoot":"","sources":["../../src/receipt/live-server.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,KAAK,mBAAmB,EAIzB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAA2B,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AA4B5E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAKzD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,QAAQ,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CAChD;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAmBD,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE;IACpC,MAAM,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,OAAO,EAAE,mBAAmB,CAAC;CAC9B,GAAG,OAAO,CAYV;AAED,iFAAiF;AACjF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC;AA2DD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAmBxE;AAED,gEAAgE;AAChE,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAQjF;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,OAAO,CAAC,kBAAkB,CAAC,CA0B7B;AAED,qFAAqF;AACrF,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,OAAO,CAAC,kBAAkB,CAAC,CAK7B;AAED,2EAA2E;AAC3E,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,OAAO,CAAC,kBAAkB,CAAC,CAI7B;AAED,wFAAwF;AACxF,wBAAsB,yBAAyB,CAC7C,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,OAAO,CAAC,kBAAkB,CAAC,CAmC7B;AAED,sFAAsF;AACtF,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,OAAO,CAAC,kBAAkB,CAAC,CA8B7B;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CAyf5B"}
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
import { randomBytes } from "node:crypto";
|
|
6
6
|
import { mkdirSync, statSync, watch } from "node:fs";
|
|
7
7
|
import { createServer, } from "node:http";
|
|
8
|
-
import { dirname, isAbsolute } from "node:path";
|
|
8
|
+
import { dirname, isAbsolute, join } from "node:path";
|
|
9
9
|
import { kyaHome, readFileConfig } from "../config.js";
|
|
10
10
|
import { runGateDoctor, runGateRun, runGateStop } from "../commands/gate.js";
|
|
11
11
|
import { runInvestigate } from "../commands/investigate.js";
|
|
12
|
+
import { runOrr } from "../commands/orr.js";
|
|
12
13
|
import { loadInvestigateLastRun } from "../investigate/last-run.js";
|
|
13
14
|
import { defaultAgtAuditPath, importTraces, } from "../importers/index.js";
|
|
14
15
|
import { notifyOnTrailEvent, resolveWebhooks, } from "../notify/index.js";
|
|
@@ -54,10 +55,92 @@ export function isLoopbackClient(req) {
|
|
|
54
55
|
}
|
|
55
56
|
const IMPORT_SOURCES = ["langsmith", "langfuse", "phoenix", "otel", "agt", "adr-sensor", "openshell"];
|
|
56
57
|
const OTEL_CONFIG_HINT = "configure otlpExport.endpoint in .kya/config.json or KYA_OTLP_EXPORT_ENDPOINT";
|
|
58
|
+
/**
|
|
59
|
+
* Ephemeral 127.0.0.1 HTTP sink that answers 200 to every POST. Lets the
|
|
60
|
+
* zero-config self-tests (notify, otel) exercise the real delivery/export
|
|
61
|
+
* pipeline end to end instead of dead-ending with a config error; the sink
|
|
62
|
+
* closes as soon as the handler finishes.
|
|
63
|
+
*/
|
|
64
|
+
async function withLoopbackSink(run) {
|
|
65
|
+
const server = createServer((req, res) => {
|
|
66
|
+
if (req.method === "POST") {
|
|
67
|
+
req.resume();
|
|
68
|
+
req.on("end", () => {
|
|
69
|
+
res.writeHead(200, { "content-type": "application/json" });
|
|
70
|
+
res.end("{}");
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
res.writeHead(405).end();
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
await new Promise((resolve) => server.listen(0, LOOPBACK, resolve));
|
|
78
|
+
const addr = server.address();
|
|
79
|
+
const port = typeof addr === "object" && addr !== null ? addr.port : 0;
|
|
80
|
+
try {
|
|
81
|
+
return await run(`http://127.0.0.1:${port}`);
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
server.closeAllConnections?.();
|
|
85
|
+
server.close();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
57
88
|
/** Merged global + project .kya/config.json, project wins (same as notify dispatch). */
|
|
58
89
|
function mergedFileConfig(cwd, env) {
|
|
59
90
|
return { ...readFileConfig(kyaHome(env)), ...readFileConfig(cwd) };
|
|
60
91
|
}
|
|
92
|
+
const ORR_REPORT_REL = join("orr-report", "report.json");
|
|
93
|
+
/** Re-run the board when the report is older than this (30 minutes). */
|
|
94
|
+
const ORR_REFRESH_MS = 30 * 60 * 1000;
|
|
95
|
+
function orrReportPath(cwd) {
|
|
96
|
+
return join(cwd, ORR_REPORT_REL);
|
|
97
|
+
}
|
|
98
|
+
/** True when <cwd>/orr-report/report.json is missing or older than ORR_REFRESH_MS. */
|
|
99
|
+
function orrReportStale(cwd) {
|
|
100
|
+
try {
|
|
101
|
+
const st = statSync(orrReportPath(cwd));
|
|
102
|
+
return Date.now() - st.mtimeMs > ORR_REFRESH_MS;
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Run the ORR board against cwd and write <cwd>/orr-report/report.json (+ .md).
|
|
110
|
+
* Read-only probes; never throws (a failed board must not break the report
|
|
111
|
+
* server). The first-party producer set keeps it dependency-free.
|
|
112
|
+
*/
|
|
113
|
+
export function runOrrBoard(cwd) {
|
|
114
|
+
try {
|
|
115
|
+
const result = runOrr({
|
|
116
|
+
path: cwd,
|
|
117
|
+
out: join(cwd, "orr-report"),
|
|
118
|
+
rubric: "0",
|
|
119
|
+
disableCategories: [],
|
|
120
|
+
formats: ["json", "md"],
|
|
121
|
+
producers: ["sa.first_party"],
|
|
122
|
+
skipOptionalProducers: true,
|
|
123
|
+
quiet: true,
|
|
124
|
+
jsonStdout: false,
|
|
125
|
+
});
|
|
126
|
+
const overall = result.report.overall;
|
|
127
|
+
const disposition = result.report.disposition.replace(/_/g, " ");
|
|
128
|
+
return { ok: true, detail: `overall ${overall} · ${disposition}` };
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
return { ok: false, detail: err instanceof Error ? err.message : String(err) };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/** POST /action/orr-run: regenerate the ORR board on demand. */
|
|
135
|
+
export async function runReportOrrAction(cwd) {
|
|
136
|
+
const ran = runOrrBoard(cwd);
|
|
137
|
+
return {
|
|
138
|
+
status: 200,
|
|
139
|
+
body: ran.ok
|
|
140
|
+
? { ok: true, detail: `ORR board regenerated: ${ran.detail}` }
|
|
141
|
+
: { ok: false, error: `ORR run failed: ${ran.detail}` },
|
|
142
|
+
};
|
|
143
|
+
}
|
|
61
144
|
/**
|
|
62
145
|
* POST /action/import: validate the empty-state form body and run one import.
|
|
63
146
|
* `file` must be an absolute path to an existing regular file; agt may omit it
|
|
@@ -109,15 +192,6 @@ export async function runReportDiscoverAction(cwd, env) {
|
|
|
109
192
|
export async function runReportNotifyTestAction(cwd, env) {
|
|
110
193
|
const config = mergedFileConfig(cwd, env);
|
|
111
194
|
const targets = resolveWebhooks(config, env);
|
|
112
|
-
if (targets.length === 0) {
|
|
113
|
-
return {
|
|
114
|
-
status: 200,
|
|
115
|
-
body: {
|
|
116
|
-
ok: false,
|
|
117
|
-
error: "no webhooks configured - set notify.webhooks in .kya/config.json or KYA_NOTIFY_WEBHOOK",
|
|
118
|
-
},
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
195
|
const event = {
|
|
122
196
|
ts: new Date().toISOString(),
|
|
123
197
|
sessionId: "kya-report-test",
|
|
@@ -127,12 +201,50 @@ export async function runReportNotifyTestAction(cwd, env) {
|
|
|
127
201
|
mode: "observe",
|
|
128
202
|
summary: "test alert from the kya report",
|
|
129
203
|
};
|
|
204
|
+
if (targets.length === 0) {
|
|
205
|
+
// Zero-config self-test: deliver through the real sender to an ephemeral
|
|
206
|
+
// loopback sink so the button proves the pipeline instead of dead-ending.
|
|
207
|
+
// The delivery lands in notify-log.jsonl and shows up in the Alerts panel.
|
|
208
|
+
return withLoopbackSink(async (url) => {
|
|
209
|
+
const loopbackConfig = {
|
|
210
|
+
notify: { webhooks: [{ url, events: ["DENY"], template: "generic" }] },
|
|
211
|
+
};
|
|
212
|
+
await notifyOnTrailEvent(event, loopbackConfig, env);
|
|
213
|
+
return {
|
|
214
|
+
status: 200,
|
|
215
|
+
body: {
|
|
216
|
+
ok: true,
|
|
217
|
+
targets: 1,
|
|
218
|
+
loopback: true,
|
|
219
|
+
detail: "test alert delivered to a temporary loopback receiver (delivery recorded in the Alerts panel). Set notify.webhooks in .kya/config.json or KYA_NOTIFY_WEBHOOK to alert a real target.",
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
});
|
|
223
|
+
}
|
|
130
224
|
await notifyOnTrailEvent(event, config, env);
|
|
131
225
|
return { status: 200, body: { ok: true, targets: targets.length } };
|
|
132
226
|
}
|
|
133
227
|
/** POST /action/otel-test: run the OTLP self-test against the configured endpoint. */
|
|
134
228
|
export async function runReportOtelTestAction(cwd, env) {
|
|
135
229
|
const config = resolveOtlpExportConfig(env, mergedFileConfig(cwd, env));
|
|
230
|
+
if (!config) {
|
|
231
|
+
// Zero-config self-test: stand up an ephemeral loopback collector and run
|
|
232
|
+
// the real exporter against it, so the button proves the export path
|
|
233
|
+
// instead of dead-ending with a config error.
|
|
234
|
+
return withLoopbackSink(async (url) => {
|
|
235
|
+
const result = await otlpExportSelfTest({ endpoint: url });
|
|
236
|
+
return {
|
|
237
|
+
status: 200,
|
|
238
|
+
body: {
|
|
239
|
+
ok: result.ok,
|
|
240
|
+
loopback: true,
|
|
241
|
+
detail: result.ok
|
|
242
|
+
? `span accepted by a temporary loopback collector (${result.detail}). Set otlpExport.endpoint in .kya/config.json or KYA_OTLP_EXPORT_ENDPOINT to export for real.`
|
|
243
|
+
: `${result.detail} - ${OTEL_CONFIG_HINT}`,
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
});
|
|
247
|
+
}
|
|
136
248
|
try {
|
|
137
249
|
const result = await otlpExportSelfTest(config);
|
|
138
250
|
return {
|
|
@@ -152,6 +264,7 @@ export function startLiveReceiptServer(options) {
|
|
|
152
264
|
const clients = new Set();
|
|
153
265
|
let watcher;
|
|
154
266
|
let debounce;
|
|
267
|
+
let orrTimer;
|
|
155
268
|
let closed = false;
|
|
156
269
|
let onSignal;
|
|
157
270
|
const cache = new EventEmbeddingCache();
|
|
@@ -250,7 +363,8 @@ export function startLiveReceiptServer(options) {
|
|
|
250
363
|
url.pathname === "/action/discover" ||
|
|
251
364
|
url.pathname === "/action/import" ||
|
|
252
365
|
url.pathname === "/action/notify-test" ||
|
|
253
|
-
url.pathname === "/action/otel-test"
|
|
366
|
+
url.pathname === "/action/otel-test" ||
|
|
367
|
+
url.pathname === "/action/orr-run");
|
|
254
368
|
if (isPostAction && !isLoopbackClient(req)) {
|
|
255
369
|
return forbidden(res, { ok: false, error: "loopback only" });
|
|
256
370
|
}
|
|
@@ -429,6 +543,21 @@ export function startLiveReceiptServer(options) {
|
|
|
429
543
|
})();
|
|
430
544
|
return;
|
|
431
545
|
}
|
|
546
|
+
if (req.method === "POST" && url.pathname === "/action/orr-run") {
|
|
547
|
+
void (async () => {
|
|
548
|
+
try {
|
|
549
|
+
const result = await runReportOrrAction(cwd);
|
|
550
|
+
return jsonOk(res, result.body);
|
|
551
|
+
}
|
|
552
|
+
catch (err) {
|
|
553
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
554
|
+
res.writeHead(500, { "Content-Type": "application/json; charset=utf-8" });
|
|
555
|
+
res.end(`${JSON.stringify({ ok: false, error: message })}\n`);
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
})();
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
432
561
|
if (req.method === "POST" && url.pathname === "/feed") {
|
|
433
562
|
void (async () => {
|
|
434
563
|
try {
|
|
@@ -541,6 +670,8 @@ export function startLiveReceiptServer(options) {
|
|
|
541
670
|
closed = true;
|
|
542
671
|
if (debounce)
|
|
543
672
|
clearTimeout(debounce);
|
|
673
|
+
if (orrTimer)
|
|
674
|
+
clearInterval(orrTimer);
|
|
544
675
|
if (onSignal) {
|
|
545
676
|
process.removeListener("SIGINT", onSignal);
|
|
546
677
|
process.removeListener("SIGTERM", onSignal);
|
|
@@ -576,6 +707,19 @@ export function startLiveReceiptServer(options) {
|
|
|
576
707
|
const addr = server.address();
|
|
577
708
|
const port = typeof addr === "object" && addr ? addr.port : 0;
|
|
578
709
|
const url = `http://${LOOPBACK}:${port}/?t=${token}`;
|
|
710
|
+
// ORR board: generate at start when missing/stale, then re-run on a
|
|
711
|
+
// 30-minute cadence while the report server lives. Background, never
|
|
712
|
+
// blocking; the SSE broadcast makes the panel pick the result up live.
|
|
713
|
+
const refreshOrr = () => {
|
|
714
|
+
if (closed || !orrReportStale(cwd))
|
|
715
|
+
return;
|
|
716
|
+
const ran = runOrrBoard(cwd);
|
|
717
|
+
if (ran.ok)
|
|
718
|
+
scheduleBroadcast();
|
|
719
|
+
};
|
|
720
|
+
setTimeout(refreshOrr, 1_500);
|
|
721
|
+
orrTimer = setInterval(refreshOrr, ORR_REFRESH_MS);
|
|
722
|
+
orrTimer.unref?.();
|
|
579
723
|
try {
|
|
580
724
|
mkdirSync(dirname(path), { recursive: true });
|
|
581
725
|
watcher = watch(dirname(path), { persistent: true }, (_event, filename) => {
|