@shield-agent/kya 0.32.9 → 0.33.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.
Files changed (279) hide show
  1. package/.cursor-plugin/plugin.json +1 -1
  2. package/.mcp.json +1 -1
  3. package/LIMITATIONS.md +2 -2
  4. package/README.md +178 -12
  5. package/amp/settings.example.json +1 -1
  6. package/claude/claude_desktop_config.example.json +1 -1
  7. package/cline/cline_mcp_settings.example.json +1 -1
  8. package/copilot/mcp-config.example.json +1 -1
  9. package/data/iocs.json +17 -0
  10. package/dist/cli.d.ts +1 -1
  11. package/dist/cli.d.ts.map +1 -1
  12. package/dist/cli.js +149 -16
  13. package/dist/cli.js.map +1 -1
  14. package/dist/commands/connect.d.ts +1 -1
  15. package/dist/commands/connect.d.ts.map +1 -1
  16. package/dist/commands/connect.js +11 -3
  17. package/dist/commands/connect.js.map +1 -1
  18. package/dist/commands/dash.d.ts.map +1 -1
  19. package/dist/commands/dash.js +25 -1
  20. package/dist/commands/dash.js.map +1 -1
  21. package/dist/commands/doctor.d.ts +8 -0
  22. package/dist/commands/doctor.d.ts.map +1 -0
  23. package/dist/commands/doctor.js +26 -0
  24. package/dist/commands/doctor.js.map +1 -0
  25. package/dist/commands/eval-tool.d.ts +3 -0
  26. package/dist/commands/eval-tool.d.ts.map +1 -1
  27. package/dist/commands/eval-tool.js +2 -1
  28. package/dist/commands/eval-tool.js.map +1 -1
  29. package/dist/commands/export.d.ts +33 -0
  30. package/dist/commands/export.d.ts.map +1 -0
  31. package/dist/commands/export.js +121 -0
  32. package/dist/commands/export.js.map +1 -0
  33. package/dist/commands/hook.d.ts.map +1 -1
  34. package/dist/commands/hook.js +120 -26
  35. package/dist/commands/hook.js.map +1 -1
  36. package/dist/commands/hosted-hook.d.ts +8 -1
  37. package/dist/commands/hosted-hook.d.ts.map +1 -1
  38. package/dist/commands/hosted-hook.js +15 -5
  39. package/dist/commands/hosted-hook.js.map +1 -1
  40. package/dist/commands/map.d.ts +21 -0
  41. package/dist/commands/map.d.ts.map +1 -0
  42. package/dist/commands/map.js +76 -0
  43. package/dist/commands/map.js.map +1 -0
  44. package/dist/commands/notify-flush.d.ts.map +1 -1
  45. package/dist/commands/notify-flush.js +7 -1
  46. package/dist/commands/notify-flush.js.map +1 -1
  47. package/dist/commands/posture.d.ts +21 -0
  48. package/dist/commands/posture.d.ts.map +1 -0
  49. package/dist/commands/posture.js +177 -0
  50. package/dist/commands/posture.js.map +1 -0
  51. package/dist/commands/receipt-serve.d.ts +7 -0
  52. package/dist/commands/receipt-serve.d.ts.map +1 -1
  53. package/dist/commands/receipt-serve.js +50 -0
  54. package/dist/commands/receipt-serve.js.map +1 -1
  55. package/dist/commands/start.d.ts.map +1 -1
  56. package/dist/commands/start.js +5 -1
  57. package/dist/commands/start.js.map +1 -1
  58. package/dist/commands/team.d.ts.map +1 -1
  59. package/dist/commands/team.js +30 -11
  60. package/dist/commands/team.js.map +1 -1
  61. package/dist/commands/wire-hooks.d.ts +5 -1
  62. package/dist/commands/wire-hooks.d.ts.map +1 -1
  63. package/dist/commands/wire-hooks.js +23 -8
  64. package/dist/commands/wire-hooks.js.map +1 -1
  65. package/dist/commands/wrap.d.ts +38 -1
  66. package/dist/commands/wrap.d.ts.map +1 -1
  67. package/dist/commands/wrap.js +82 -6
  68. package/dist/commands/wrap.js.map +1 -1
  69. package/dist/daily-slot.d.ts +2 -0
  70. package/dist/daily-slot.d.ts.map +1 -0
  71. package/dist/daily-slot.js +29 -0
  72. package/dist/daily-slot.js.map +1 -0
  73. package/dist/dash/dash.d.ts.map +1 -1
  74. package/dist/dash/dash.js +10 -0
  75. package/dist/dash/dash.js.map +1 -1
  76. package/dist/dash/entitlement.d.ts +1 -1
  77. package/dist/dash/entitlement.d.ts.map +1 -1
  78. package/dist/dash/entitlement.js +1 -0
  79. package/dist/dash/entitlement.js.map +1 -1
  80. package/dist/dash/input.d.ts +1 -1
  81. package/dist/dash/input.d.ts.map +1 -1
  82. package/dist/dash/input.js +3 -0
  83. package/dist/dash/input.js.map +1 -1
  84. package/dist/dash/render.js +1 -1
  85. package/dist/dash/render.js.map +1 -1
  86. package/dist/dash/screens/free.js +1 -1
  87. package/dist/dash/screens/free.js.map +1 -1
  88. package/dist/device-id.d.ts +5 -0
  89. package/dist/device-id.d.ts.map +1 -0
  90. package/dist/device-id.js +78 -0
  91. package/dist/device-id.js.map +1 -0
  92. package/dist/fs-atomic.d.ts +9 -3
  93. package/dist/fs-atomic.d.ts.map +1 -1
  94. package/dist/fs-atomic.js +17 -11
  95. package/dist/fs-atomic.js.map +1 -1
  96. package/dist/gate/config-gen.d.ts +26 -2
  97. package/dist/gate/config-gen.d.ts.map +1 -1
  98. package/dist/gate/config-gen.js +53 -4
  99. package/dist/gate/config-gen.js.map +1 -1
  100. package/dist/gate/otlp-receiver.d.ts.map +1 -1
  101. package/dist/gate/otlp-receiver.js +3 -1
  102. package/dist/gate/otlp-receiver.js.map +1 -1
  103. package/dist/guard-pack.d.ts +58 -0
  104. package/dist/guard-pack.d.ts.map +1 -0
  105. package/dist/guard-pack.js +753 -0
  106. package/dist/guard-pack.js.map +1 -0
  107. package/dist/ioc/exec.d.ts +19 -0
  108. package/dist/ioc/exec.d.ts.map +1 -0
  109. package/dist/ioc/exec.js +49 -0
  110. package/dist/ioc/exec.js.map +1 -0
  111. package/dist/ioc/format.d.ts +4 -0
  112. package/dist/ioc/format.d.ts.map +1 -0
  113. package/dist/ioc/format.js +23 -0
  114. package/dist/ioc/format.js.map +1 -0
  115. package/dist/ioc/list.d.ts +29 -0
  116. package/dist/ioc/list.d.ts.map +1 -0
  117. package/dist/ioc/list.js +25 -0
  118. package/dist/ioc/list.js.map +1 -0
  119. package/dist/ioc/result.d.ts +18 -0
  120. package/dist/ioc/result.d.ts.map +1 -0
  121. package/dist/ioc/result.js +26 -0
  122. package/dist/ioc/result.js.map +1 -0
  123. package/dist/ioc/scan.d.ts +21 -0
  124. package/dist/ioc/scan.d.ts.map +1 -0
  125. package/dist/ioc/scan.js +247 -0
  126. package/dist/ioc/scan.js.map +1 -0
  127. package/dist/ioc/spawn.d.ts +26 -0
  128. package/dist/ioc/spawn.d.ts.map +1 -0
  129. package/dist/ioc/spawn.js +52 -0
  130. package/dist/ioc/spawn.js.map +1 -0
  131. package/dist/map/build.d.ts +58 -0
  132. package/dist/map/build.d.ts.map +1 -0
  133. package/dist/map/build.js +439 -0
  134. package/dist/map/build.js.map +1 -0
  135. package/dist/map/heat.d.ts +44 -0
  136. package/dist/map/heat.d.ts.map +1 -0
  137. package/dist/map/heat.js +96 -0
  138. package/dist/map/heat.js.map +1 -0
  139. package/dist/map/load.d.ts +38 -0
  140. package/dist/map/load.d.ts.map +1 -0
  141. package/dist/map/load.js +38 -0
  142. package/dist/map/load.js.map +1 -0
  143. package/dist/map/page.d.ts +90 -0
  144. package/dist/map/page.d.ts.map +1 -0
  145. package/dist/map/page.js +374 -0
  146. package/dist/map/page.js.map +1 -0
  147. package/dist/map/target-class.d.ts +22 -0
  148. package/dist/map/target-class.d.ts.map +1 -0
  149. package/dist/map/target-class.js +151 -0
  150. package/dist/map/target-class.js.map +1 -0
  151. package/dist/map/types.d.ts +102 -0
  152. package/dist/map/types.d.ts.map +1 -0
  153. package/dist/map/types.js +3 -0
  154. package/dist/map/types.js.map +1 -0
  155. package/dist/mcp/protocol.d.ts.map +1 -1
  156. package/dist/mcp/protocol.js +16 -5
  157. package/dist/mcp/protocol.js.map +1 -1
  158. package/dist/never-code.d.ts +7 -0
  159. package/dist/never-code.d.ts.map +1 -0
  160. package/dist/never-code.js +9 -0
  161. package/dist/never-code.js.map +1 -0
  162. package/dist/never-list-input.d.ts +48 -12
  163. package/dist/never-list-input.d.ts.map +1 -1
  164. package/dist/never-list-input.js +696 -29
  165. package/dist/never-list-input.js.map +1 -1
  166. package/dist/notify/dispatch.d.ts +4 -0
  167. package/dist/notify/dispatch.d.ts.map +1 -1
  168. package/dist/notify/dispatch.js +3 -1
  169. package/dist/notify/dispatch.js.map +1 -1
  170. package/dist/offline-evaluate.d.ts +26 -1
  171. package/dist/offline-evaluate.d.ts.map +1 -1
  172. package/dist/offline-evaluate.js +33 -4
  173. package/dist/offline-evaluate.js.map +1 -1
  174. package/dist/otel/exporter.d.ts +15 -2
  175. package/dist/otel/exporter.d.ts.map +1 -1
  176. package/dist/otel/exporter.js +52 -6
  177. package/dist/otel/exporter.js.map +1 -1
  178. package/dist/otel/map-attrs-optin.d.ts +39 -0
  179. package/dist/otel/map-attrs-optin.d.ts.map +1 -0
  180. package/dist/otel/map-attrs-optin.js +109 -0
  181. package/dist/otel/map-attrs-optin.js.map +1 -0
  182. package/dist/parse-args.d.ts +2 -0
  183. package/dist/parse-args.d.ts.map +1 -1
  184. package/dist/parse-args.js +4 -2
  185. package/dist/parse-args.js.map +1 -1
  186. package/dist/posture/card.d.ts +26 -0
  187. package/dist/posture/card.d.ts.map +1 -0
  188. package/dist/posture/card.js +46 -0
  189. package/dist/posture/card.js.map +1 -0
  190. package/dist/posture/collect.d.ts +19 -0
  191. package/dist/posture/collect.d.ts.map +1 -0
  192. package/dist/posture/collect.js +182 -0
  193. package/dist/posture/collect.js.map +1 -0
  194. package/dist/posture/send.d.ts +24 -0
  195. package/dist/posture/send.d.ts.map +1 -0
  196. package/dist/posture/send.js +162 -0
  197. package/dist/posture/send.js.map +1 -0
  198. package/dist/posture/spawn.d.ts +20 -0
  199. package/dist/posture/spawn.d.ts.map +1 -0
  200. package/dist/posture/spawn.js +33 -0
  201. package/dist/posture/spawn.js.map +1 -0
  202. package/dist/posture/store.d.ts +34 -0
  203. package/dist/posture/store.d.ts.map +1 -0
  204. package/dist/posture/store.js +107 -0
  205. package/dist/posture/store.js.map +1 -0
  206. package/dist/posture/validate.d.ts +33 -0
  207. package/dist/posture/validate.d.ts.map +1 -0
  208. package/dist/posture/validate.js +232 -0
  209. package/dist/posture/validate.js.map +1 -0
  210. package/dist/project-policy.d.ts +23 -0
  211. package/dist/project-policy.d.ts.map +1 -0
  212. package/dist/project-policy.js +95 -0
  213. package/dist/project-policy.js.map +1 -0
  214. package/dist/receipt/daemon.d.ts +9 -9
  215. package/dist/receipt/daemon.d.ts.map +1 -1
  216. package/dist/receipt/daemon.js +26 -11
  217. package/dist/receipt/daemon.js.map +1 -1
  218. package/dist/receipt/embeddings.d.ts +28 -10
  219. package/dist/receipt/embeddings.d.ts.map +1 -1
  220. package/dist/receipt/embeddings.js +221 -35
  221. package/dist/receipt/embeddings.js.map +1 -1
  222. package/dist/receipt/gate-page.d.ts.map +1 -1
  223. package/dist/receipt/gate-page.js +5 -22
  224. package/dist/receipt/gate-page.js.map +1 -1
  225. package/dist/receipt/live-server.d.ts +8 -0
  226. package/dist/receipt/live-server.d.ts.map +1 -1
  227. package/dist/receipt/live-server.js +136 -4
  228. package/dist/receipt/live-server.js.map +1 -1
  229. package/dist/receipt/render-receipt.d.ts +7 -1
  230. package/dist/receipt/render-receipt.d.ts.map +1 -1
  231. package/dist/receipt/render-receipt.js +118 -13
  232. package/dist/receipt/render-receipt.js.map +1 -1
  233. package/dist/receipt/search.d.ts +5 -0
  234. package/dist/receipt/search.d.ts.map +1 -1
  235. package/dist/receipt/search.js +23 -2
  236. package/dist/receipt/search.js.map +1 -1
  237. package/dist/receipt/semantic-setup.d.ts +21 -0
  238. package/dist/receipt/semantic-setup.d.ts.map +1 -0
  239. package/dist/receipt/semantic-setup.js +111 -0
  240. package/dist/receipt/semantic-setup.js.map +1 -0
  241. package/dist/receipt/semantic-status.d.ts +7 -0
  242. package/dist/receipt/semantic-status.d.ts.map +1 -0
  243. package/dist/receipt/semantic-status.js +26 -0
  244. package/dist/receipt/semantic-status.js.map +1 -0
  245. package/dist/sdk/govern.d.ts.map +1 -1
  246. package/dist/sdk/govern.js +7 -3
  247. package/dist/sdk/govern.js.map +1 -1
  248. package/dist/telemetry.d.ts.map +1 -1
  249. package/dist/telemetry.js +3 -23
  250. package/dist/telemetry.js.map +1 -1
  251. package/dist/trail-map-fields.d.ts +10 -0
  252. package/dist/trail-map-fields.d.ts.map +1 -0
  253. package/dist/trail-map-fields.js +53 -0
  254. package/dist/trail-map-fields.js.map +1 -0
  255. package/dist/trail-summary.d.ts.map +1 -1
  256. package/dist/trail-summary.js +11 -3
  257. package/dist/trail-summary.js.map +1 -1
  258. package/dist/trail.d.ts +9 -1
  259. package/dist/trail.d.ts.map +1 -1
  260. package/dist/trail.js +24 -1
  261. package/dist/trail.js.map +1 -1
  262. package/droid/README.md +1 -1
  263. package/droid/mcp.example.json +1 -1
  264. package/gemini/settings.example.json +1 -1
  265. package/grok/README.md +1 -1
  266. package/kilo/kilo.example.json +1 -1
  267. package/kimi/mcp.example.json +1 -1
  268. package/kiro/mcp.example.json +1 -1
  269. package/manifest.json +1 -1
  270. package/mastracode/mcp.example.json +1 -1
  271. package/mcp.json +1 -1
  272. package/openai/codex.config.example.toml +1 -1
  273. package/opencode/opencode.example.json +1 -1
  274. package/package.json +8 -4
  275. package/qwen/settings.example.json +1 -1
  276. package/server.json +2 -2
  277. package/vendor/cytoscape/LICENSE +19 -0
  278. package/vendor/cytoscape/README.md +7 -0
  279. package/vendor/cytoscape/cytoscape.min.js +31 -0
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Builds the posture report v1 (spec: shield-agent contract, "Posture report v1") from local
3
+ * facts only. Minimised on purpose: agent hosts, agent-related extensions, MCP server names with
4
+ * transport and command basename, the IoC result and the never-list status. No args, env values,
5
+ * file contents, paths, user names or addresses. The validator (validate.ts) is the last word.
6
+ */
7
+ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
8
+ import { basename, join } from "node:path";
9
+ import { scanCliBinaries } from "../discover/scan.js";
10
+ import { CLI_VERSION } from "../version.js";
11
+ /** Agent-related extensions the client may report (plus any id an IoC check names). */
12
+ export const AGENT_EXTENSIONS = {
13
+ "anthropic.claude-code": "claude-code",
14
+ "openai.chatgpt": "codex",
15
+ "github.copilot": "copilot",
16
+ "github.copilot-chat": "copilot",
17
+ "saoudrizwan.claude-dev": "cline",
18
+ "rooveterinaryinc.roo-cline": "roo-code",
19
+ "continue.continue": "continue",
20
+ "google.geminicodeassist": "gemini",
21
+ "sourcegraph.cody-ai": "cody",
22
+ "kilocode.kilo-code": "kilo-code",
23
+ "amazonwebservices.amazon-q-vscode": "amazon-q",
24
+ "codeium.codeium": "codeium",
25
+ "tabnine.tabnine-vscode": "tabnine",
26
+ };
27
+ /** Catalog id (discover/catalog.ts) to the host id the report uses. Only CLI agents appear here. */
28
+ const CLI_HOSTS = {
29
+ claude: "claude-code",
30
+ "cursor-agent": "cursor",
31
+ codex: "codex",
32
+ gemini: "gemini",
33
+ opencode: "opencode",
34
+ aider: "aider",
35
+ };
36
+ const EXTENSION_ROOTS = [
37
+ [".vscode/extensions", "vscode"],
38
+ [".vscode-insiders/extensions", "vscode"],
39
+ [".cursor/extensions", "cursor"],
40
+ [".windsurf/extensions", "windsurf"],
41
+ [".vscode-oss/extensions", "vscodium"],
42
+ ];
43
+ const MCP_FILES = [".mcp.json", join(".cursor", "mcp.json"), ".claude.json", join(".gemini", "settings.json")];
44
+ const MAX_HOSTS = 32;
45
+ const MAX_EXTENSIONS = 200;
46
+ const MAX_MCP = 100;
47
+ const MAX_FINDINGS = 50;
48
+ const nodeFs = () => ({
49
+ existsSync,
50
+ statSync: (p) => statSync(p),
51
+ readdirSync: (p) => readdirSync(p),
52
+ readFileSync: (p, enc) => readFileSync(p, enc),
53
+ });
54
+ function readJson(path) {
55
+ try {
56
+ return JSON.parse(readFileSync(path, "utf8"));
57
+ }
58
+ catch {
59
+ return undefined;
60
+ }
61
+ }
62
+ function hostsFrom(input, extensions) {
63
+ const out = new Map();
64
+ for (const f of scanCliBinaries(input.pathDirs, nodeFs(), input.platform)) {
65
+ if (f.category !== "cli-agent")
66
+ continue;
67
+ const host = CLI_HOSTS[f.id];
68
+ if (host && !out.has(host))
69
+ out.set(host, { id: host, version: null, kyaHook: false });
70
+ }
71
+ for (const e of extensions) {
72
+ const host = AGENT_EXTENSIONS[e.id];
73
+ if (host && !out.has(host))
74
+ out.set(host, { id: host, version: null, kyaHook: false });
75
+ }
76
+ const claude = out.get("claude-code");
77
+ if (claude) {
78
+ // kyaHook is true only when the host's own settings file names kya. Checked for Claude Code only.
79
+ const settings = readFileSync0(join(input.home, ".claude", "settings.json"));
80
+ out.set("claude-code", { ...claude, kyaHook: settings !== undefined && settings.includes("kya") });
81
+ }
82
+ return [...out.values()].slice(0, MAX_HOSTS);
83
+ }
84
+ function readFileSync0(path) {
85
+ try {
86
+ return readFileSync(path, "utf8");
87
+ }
88
+ catch {
89
+ return undefined;
90
+ }
91
+ }
92
+ function extensionsFrom(input) {
93
+ const allowed = [...new Set([...Object.keys(AGENT_EXTENSIONS), ...input.iocExtensionIds])];
94
+ const out = [];
95
+ const seen = new Set();
96
+ for (const [rel, editor] of EXTENSION_ROOTS) {
97
+ let names;
98
+ try {
99
+ names = readdirSync(join(input.home, rel));
100
+ }
101
+ catch {
102
+ continue;
103
+ }
104
+ for (const name of names) {
105
+ const lower = name.toLowerCase();
106
+ // Longest id wins: github.copilot-chat-x must not be read as github.copilot.
107
+ const id = allowed.filter((a) => lower.startsWith(`${a}-`)).sort((a, b) => b.length - a.length)[0];
108
+ if (id === undefined)
109
+ continue;
110
+ const m = /^(\d+(?:\.\d+)*)/.exec(lower.slice(id.length + 1));
111
+ const version = m ? m[1] : null;
112
+ const key = `${id}|${version}|${editor}`;
113
+ if (seen.has(key))
114
+ continue;
115
+ seen.add(key);
116
+ out.push({ id, version, editor });
117
+ }
118
+ }
119
+ return out.slice(0, MAX_EXTENSIONS);
120
+ }
121
+ function mcpFrom(home) {
122
+ const out = [];
123
+ const seen = new Set();
124
+ for (const rel of MCP_FILES) {
125
+ const root = readJson(join(home, rel));
126
+ if (root === null || typeof root !== "object")
127
+ continue;
128
+ const servers = root["mcpServers"];
129
+ if (servers === null || typeof servers !== "object" || Array.isArray(servers))
130
+ continue;
131
+ for (const [name, raw] of Object.entries(servers)) {
132
+ const s = (raw !== null && typeof raw === "object" ? raw : {});
133
+ const kind = String(s["type"] ?? s["transport"] ?? "");
134
+ const isHttp = typeof s["url"] === "string" || ["http", "sse", "streamable-http"].includes(kind);
135
+ const transport = isHttp ? "http" : "stdio";
136
+ // Basename of the program only: no args, no directories.
137
+ const first = typeof s["command"] === "string" ? s["command"].trim().split(/\s+/)[0] ?? "" : "";
138
+ const command = !isHttp && first !== "" ? basename(first.replace(/\\/g, "/")) : null;
139
+ const key = `${name}|${transport}|${command ?? ""}`;
140
+ if (seen.has(key))
141
+ continue;
142
+ seen.add(key);
143
+ out.push({ name, transport, command });
144
+ }
145
+ }
146
+ return out.slice(0, MAX_MCP);
147
+ }
148
+ /** The report object before validation. Callers must run checkReport on it before any send. */
149
+ export function collectReport(input) {
150
+ const extensions = extensionsFrom(input);
151
+ const hosts = hostsFrom(input, extensions);
152
+ const mcp = mcpFrom(input.home);
153
+ const ioc = input.ioc;
154
+ return {
155
+ schema: 1,
156
+ reportedAt: input.now.toISOString(),
157
+ kyaVersion: CLI_VERSION,
158
+ deviceId: input.deviceId,
159
+ deviceLabel: input.label,
160
+ os: input.platform,
161
+ arch: input.arch,
162
+ hosts,
163
+ extensions,
164
+ mcpServers: mcp,
165
+ ioc: ioc === undefined
166
+ ? undefined
167
+ : {
168
+ listVersion: ioc.listVersion,
169
+ checkedAt: ioc.checkedAt,
170
+ skipped: ioc.skipped,
171
+ findings: ioc.findings.slice(0, MAX_FINDINGS).map((f) => ({
172
+ ioc: f.ioc,
173
+ check: f.check,
174
+ severity: f.severity,
175
+ evidence: f.evidence,
176
+ hint: f.hint,
177
+ })),
178
+ },
179
+ never: { listActive: true, mode: input.hosted ? "hosted" : "advisory" },
180
+ };
181
+ }
182
+ //# sourceMappingURL=collect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collect.js","sourceRoot":"","sources":["../../src/posture/collect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { type Violation } from "./validate.js";
2
+ export declare const POLICY_PATH = "/api/v1/kya/posture/policy";
3
+ export declare const REPORT_PATH = "/api/v1/kya/posture";
4
+ export declare const POLICY_TTL_MS: number;
5
+ export declare const REQUEST_TIMEOUT_MS = 5000;
6
+ export type PostureOutcome = "off" | "no-credentials" | "policy-disabled" | "policy-unavailable" | "invalid" | "sent" | "rejected" | "failed";
7
+ export interface PostureResult {
8
+ readonly outcome: PostureOutcome;
9
+ readonly detail?: string;
10
+ }
11
+ export interface BuiltReport {
12
+ readonly report: Record<string, unknown>;
13
+ readonly violations: readonly Violation[];
14
+ }
15
+ /** Full report for `posture send --dry-run`, `posture on` and the detached send. Scans once if no result is stored. */
16
+ export declare function buildPostureReport(env: NodeJS.ProcessEnv, now?: Date): Promise<BuiltReport>;
17
+ /** Sync preview for the dashboards: no scan, no network. The IoC part is absent until a result is stored. */
18
+ export declare function previewPosture(env: NodeJS.ProcessEnv, now?: Date): BuiltReport;
19
+ /** One send attempt. Never throws. Returns what happened, with a detail that carries no user data. */
20
+ export declare function runPostureSend(env: NodeJS.ProcessEnv, deps?: {
21
+ readonly fetch?: typeof fetch;
22
+ readonly now?: Date;
23
+ }): Promise<PostureResult>;
24
+ //# sourceMappingURL=send.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/posture/send.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAS9E,eAAO,MAAM,WAAW,+BAA+B,CAAC;AACxD,eAAO,MAAM,WAAW,wBAAwB,CAAC;AACjD,eAAO,MAAM,aAAa,QAAmB,CAAC;AAC9C,eAAO,MAAM,kBAAkB,OAAQ,CAAC;AAExC,MAAM,MAAM,cAAc,GACtB,KAAK,GACL,gBAAgB,GAChB,iBAAiB,GACjB,oBAAoB,GACpB,SAAS,GACT,MAAM,GACN,UAAU,GACV,QAAQ,CAAC;AAEb,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,CAAC;CAC3C;AAoCD,uHAAuH;AACvH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,GAAE,IAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAG7G;AAED,6GAA6G;AAC7G,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,GAAE,IAAiB,GAAG,WAAW,CAE1F;AAyCD,sGAAsG;AACtG,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,IAAI,GAAE;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAA;CAAO,GAChE,OAAO,CAAC,aAAa,CAAC,CA2DxB"}
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Posture sending. Order of gates, each one stops the send before any later step:
3
+ * 1. local toggle (~/.kya/config.json posture.share === true), checked before every request;
4
+ * 2. hosted credentials from `kya login` (remote http is refused by the credentials reader);
5
+ * 3. workspace policy (GET .../posture/policy), cached for one day; a 403 from the report
6
+ * endpoint stops sending until the next policy check;
7
+ * 4. the report is built, checked by the validator, and only then posted (5 s timeout,
8
+ * no redirects, https or loopback http only).
9
+ * Fail open for the user: every failure returns an outcome, never throws, never blocks a hook.
10
+ */
11
+ import { hostname, userInfo } from "node:os";
12
+ import { readCredentials } from "../login/credentials.js";
13
+ import { validateConsoleUrl } from "../login/device-flow.js";
14
+ import { applyPlaneAuth } from "../client.js";
15
+ import { kyaHome } from "../config.js";
16
+ import { readIocResult } from "../ioc/result.js";
17
+ import { loadIocList } from "../ioc/list.js";
18
+ import { runIocScan } from "../ioc/scan.js";
19
+ import { collectReport } from "./collect.js";
20
+ import { checkReport, forbiddenContext } from "./validate.js";
21
+ import { deviceId, effectiveLabel, readPostureState, shareOn, writePostureState, } from "./store.js";
22
+ export const POLICY_PATH = "/api/v1/kya/posture/policy";
23
+ export const REPORT_PATH = "/api/v1/kya/posture";
24
+ export const POLICY_TTL_MS = 24 * 60 * 60_000;
25
+ export const REQUEST_TIMEOUT_MS = 5_000;
26
+ function identity() {
27
+ let user = "";
28
+ try {
29
+ user = userInfo().username;
30
+ }
31
+ catch {
32
+ /* no user database entry: nothing to hide */
33
+ }
34
+ return { user, host: hostname() };
35
+ }
36
+ /** Read-only views pass create=false: they never write the device id file. */
37
+ const PREVIEW_ID = "00000000-0000-4000-8000-000000000000";
38
+ function build(env, ioc, now, create) {
39
+ const id = deviceId(env, create) ?? PREVIEW_ID;
40
+ const { user, host } = identity();
41
+ const report = collectReport({
42
+ deviceId: id,
43
+ label: effectiveLabel(env, id),
44
+ now,
45
+ home: kyaHome(env),
46
+ pathDirs: (env["PATH"] ?? "").split(process.platform === "win32" ? ";" : ":").filter((p) => p.trim() !== ""),
47
+ platform: process.platform,
48
+ arch: process.arch,
49
+ ioc,
50
+ iocExtensionIds: loadIocList()
51
+ .iocs.flatMap((i) => i.checks.filter((c) => c.kind === "extension").map((c) => c.id ?? ""))
52
+ .filter((s) => s !== ""),
53
+ hosted: readCredentials(env) !== undefined,
54
+ });
55
+ const violations = checkReport(report, forbiddenContext(env, user, host, kyaHome(env)));
56
+ return { report, violations };
57
+ }
58
+ /** Full report for `posture send --dry-run`, `posture on` and the detached send. Scans once if no result is stored. */
59
+ export async function buildPostureReport(env, now = new Date()) {
60
+ const ioc = readIocResult(env) ?? (await runIocScan({ env, now }));
61
+ return build(env, ioc, now, true);
62
+ }
63
+ /** Sync preview for the dashboards: no scan, no network. The IoC part is absent until a result is stored. */
64
+ export function previewPosture(env, now = new Date()) {
65
+ return build(env, readIocResult(env), now, false);
66
+ }
67
+ async function request(method, url, apiKey, body, fetchImpl) {
68
+ const controller = new AbortController();
69
+ const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
70
+ const headers = { Accept: "application/json" };
71
+ if (body !== undefined)
72
+ headers["Content-Type"] = "application/json";
73
+ applyPlaneAuth(headers, apiKey);
74
+ try {
75
+ const res = await fetchImpl(url.toString(), {
76
+ method,
77
+ headers,
78
+ body,
79
+ signal: controller.signal,
80
+ redirect: "error",
81
+ });
82
+ let json;
83
+ try {
84
+ json = await res.json();
85
+ }
86
+ catch {
87
+ json = undefined;
88
+ }
89
+ return { status: res.status, json };
90
+ }
91
+ finally {
92
+ clearTimeout(timer);
93
+ }
94
+ }
95
+ const isObj = (v) => v !== null && typeof v === "object";
96
+ /** One send attempt. Never throws. Returns what happened, with a detail that carries no user data. */
97
+ export async function runPostureSend(env, deps = {}) {
98
+ try {
99
+ if (!shareOn(env))
100
+ return { outcome: "off" };
101
+ const creds = readCredentials(env);
102
+ if (creds === undefined)
103
+ return { outcome: "no-credentials", detail: "no hosted login (kya login)" };
104
+ const base = validateConsoleUrl(creds.baseUrl);
105
+ const fetchImpl = deps.fetch ?? fetch;
106
+ const now = deps.now ?? new Date();
107
+ let state = readPostureState(env);
108
+ const fresh = state.policy !== undefined &&
109
+ now.getTime() - Date.parse(state.policy.checkedAt) < POLICY_TTL_MS &&
110
+ Date.parse(state.policy.checkedAt) <= now.getTime();
111
+ let enabled;
112
+ if (fresh && state.policy) {
113
+ enabled = state.policy.enabled;
114
+ }
115
+ else {
116
+ let res;
117
+ try {
118
+ res = await request("GET", new URL(POLICY_PATH, base), creds.apiKey, undefined, fetchImpl);
119
+ }
120
+ catch {
121
+ return { outcome: "policy-unavailable", detail: "network" };
122
+ }
123
+ if (res.status !== 200 || !isObj(res.json) || typeof res.json["enabled"] !== "boolean") {
124
+ return { outcome: "policy-unavailable", detail: `status ${res.status}` };
125
+ }
126
+ enabled = res.json["enabled"];
127
+ writePostureState(env, { ...state, policy: { enabled, checkedAt: now.toISOString() } });
128
+ }
129
+ if (!enabled)
130
+ return { outcome: "policy-disabled" };
131
+ // The toggle may have been switched off while the policy request was in flight.
132
+ if (!shareOn(env))
133
+ return { outcome: "off" };
134
+ const { report, violations } = await buildPostureReport(env, now);
135
+ if (violations.length > 0) {
136
+ return { outcome: "invalid", detail: violations.map((v) => `${v.path || "report"}: ${v.reason}`).join("; ") };
137
+ }
138
+ let res;
139
+ try {
140
+ res = await request("POST", new URL(REPORT_PATH, base), creds.apiKey, JSON.stringify(report), fetchImpl);
141
+ }
142
+ catch {
143
+ return { outcome: "failed", detail: "network" };
144
+ }
145
+ if (res.status === 403) {
146
+ // Workspace toggle is off: stop until the next daily policy check.
147
+ state = readPostureState(env);
148
+ writePostureState(env, { ...state, policy: { enabled: false, checkedAt: now.toISOString() } });
149
+ return { outcome: "rejected", detail: "workspace has posture sharing off" };
150
+ }
151
+ if (res.status >= 200 && res.status < 300) {
152
+ state = readPostureState(env);
153
+ writePostureState(env, { ...state, lastSentAt: now.toISOString() });
154
+ return { outcome: "sent" };
155
+ }
156
+ return { outcome: "failed", detail: `status ${res.status}` };
157
+ }
158
+ catch {
159
+ return { outcome: "failed", detail: "internal" };
160
+ }
161
+ }
162
+ //# sourceMappingURL=send.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/posture/send.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export declare const POSTURE_SEND_INTERVAL_MS: number;
2
+ type SpawnLike = (command: string, args: readonly string[], options: {
3
+ detached: boolean;
4
+ stdio: "ignore";
5
+ env: NodeJS.ProcessEnv;
6
+ cwd: string;
7
+ windowsHide: boolean;
8
+ }) => {
9
+ unref(): void;
10
+ on(event: "error", listener: () => void): unknown;
11
+ };
12
+ /** Never throws, never waits. Returns whether a send was started. */
13
+ export declare function maybeSpawnPostureSend(deps: {
14
+ readonly env: NodeJS.ProcessEnv;
15
+ readonly entry?: string;
16
+ readonly spawnImpl?: SpawnLike;
17
+ readonly nowMs?: number;
18
+ }): boolean;
19
+ export {};
20
+ //# sourceMappingURL=spawn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../src/posture/spawn.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,wBAAwB,QAAmB,CAAC;AAEzD,KAAK,SAAS,GAAG,CACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,KACvG;IAAE,KAAK,IAAI,IAAI,CAAC;IAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAA;CAAE,CAAC;AAE1E,qEAAqE;AACrE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAiBV"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Hook-side start of the daily posture send. Lean on purpose: `kya hook` imports this module and
3
+ * nothing heavy. With the local toggle off this returns before it claims a slot or spawns
4
+ * anything. Otherwise it starts `kya posture-send` detached, at most once per 24 h, and never
5
+ * waits for it. Same shape as ioc/spawn.ts, but the child keeps the caller PATH: host detection
6
+ * reads PATH directories and never executes anything.
7
+ */
8
+ import { spawn } from "node:child_process";
9
+ import { isAbsolute } from "node:path";
10
+ import { claimDailySlot } from "../daily-slot.js";
11
+ import { childCwd } from "../ioc/exec.js";
12
+ import { postureStampPath, shareOn } from "./store.js";
13
+ export const POSTURE_SEND_INTERVAL_MS = 24 * 60 * 60_000;
14
+ /** Never throws, never waits. Returns whether a send was started. */
15
+ export function maybeSpawnPostureSend(deps) {
16
+ try {
17
+ if (!shareOn(deps.env))
18
+ return false; // toggle off: no slot, no process
19
+ const entry = deps.entry ?? process.argv[1];
20
+ if (entry === undefined || !isAbsolute(entry))
21
+ return false;
22
+ if (!claimDailySlot(postureStampPath(deps.env), POSTURE_SEND_INTERVAL_MS, deps.nowMs))
23
+ return false;
24
+ const child = (deps.spawnImpl ?? spawn)(process.execPath, [entry, "posture-send"], { detached: true, stdio: "ignore", env: { ...deps.env }, cwd: childCwd(), windowsHide: true });
25
+ child.on("error", () => undefined);
26
+ child.unref();
27
+ return true;
28
+ }
29
+ catch {
30
+ return false;
31
+ }
32
+ }
33
+ //# sourceMappingURL=spawn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../src/posture/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEvD,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;AAQzD,qEAAqE;AACrE,MAAM,UAAU,qBAAqB,CAAC,IAKrC;IACC,IAAI,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC,CAAC,kCAAkC;QACxE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5C,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAC5D,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,wBAAwB,EAAE,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACpG,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,SAAS,IAAK,KAA8B,CAAC,CAC/D,OAAO,CAAC,QAAQ,EAChB,CAAC,KAAK,EAAE,cAAc,CAAC,EACvB,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAC9F,CAAC;QACF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACnC,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,34 @@
1
+ export interface PostureConfig {
2
+ /** Local toggle. Default false: nothing is sent until `kya posture on`. */
3
+ readonly share?: boolean;
4
+ /** User-chosen label. Absent: the default label is derived from the device id. */
5
+ readonly label?: string;
6
+ }
7
+ export interface PolicyCache {
8
+ readonly enabled: boolean;
9
+ /** When the hosted policy was last read (ISO). Re-read at most once a day. */
10
+ readonly checkedAt: string;
11
+ }
12
+ export interface PostureState {
13
+ readonly policy?: PolicyCache;
14
+ readonly lastSentAt?: string;
15
+ }
16
+ export declare const devicePath: (env: NodeJS.ProcessEnv) => string;
17
+ export declare const postureStatePath: (env: NodeJS.ProcessEnv) => string;
18
+ export declare const postureStampPath: (env: NodeJS.ProcessEnv) => string;
19
+ export declare function readPostureConfig(env: NodeJS.ProcessEnv): PostureConfig;
20
+ /** Sharing is on only when the file says exactly `true`. */
21
+ export declare function shareOn(env: NodeJS.ProcessEnv): boolean;
22
+ /** Merges into ~/.kya/config.json. Other keys (for example `ioc`) are kept as they are. */
23
+ export declare function writePostureConfig(env: NodeJS.ProcessEnv, patch: PostureConfig): void;
24
+ /** The random device id. Created on first use with mode 0600. Not hardware based. */
25
+ export declare function deviceId(env: NodeJS.ProcessEnv, create: boolean): string | undefined;
26
+ /** Default label: first 8 hex of sha256(hostname + deviceId). The hostname itself is never sent. */
27
+ export declare function defaultLabel(id: string, host?: string): string;
28
+ export declare function effectiveLabel(env: NodeJS.ProcessEnv, id: string): string;
29
+ export declare function readPostureState(env: NodeJS.ProcessEnv): PostureState;
30
+ export declare function writePostureState(env: NodeJS.ProcessEnv, state: PostureState): void;
31
+ export declare function hasDeviceFile(env: NodeJS.ProcessEnv): boolean;
32
+ /** Label rules: 1 to 64 characters, no control characters, and nothing the local check forbids (user, host, paths). */
33
+ export declare function labelProblem(label: string, problemOf: (v: string) => string | undefined): string | undefined;
34
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/posture/store.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,aAAa;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,kFAAkF;IAClF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAMD,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,CAAC,UAAU,KAAG,MAAiD,CAAC;AACtG,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,CAAC,UAAU,KAAG,MAA0D,CAAC;AACrH,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,CAAC,UAAU,KAAG,MAA0D,CAAC;AAWrH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,aAAa,CAQvE;AAED,4DAA4D;AAC5D,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAEvD;AAED,2FAA2F;AAC3F,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CAQrF;AAED,qFAAqF;AACrF,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAapF;AAED,oGAAoG;AACpG,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,GAAE,MAAmB,GAAG,MAAM,CAE1E;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,YAAY,CAYrE;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAGnF;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAE7D;AAED,uHAAuH;AACvH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAK5G"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Local state for the developer posture client: the sharing toggle and label (both in
3
+ * ~/.kya/config.json, key `posture`), the random device id (~/.kya/device-id, 0600) and the
4
+ * policy cache (~/.kya/posture-state.json). Reads fail closed: a missing or damaged file means
5
+ * "sharing off", never an error in the caller. Nothing here touches the network.
6
+ */
7
+ import { randomUUID, createHash } from "node:crypto";
8
+ import { hostname } from "node:os";
9
+ import { existsSync, mkdirSync, readFileSync } from "node:fs";
10
+ import { join } from "node:path";
11
+ import { globalConfigDir } from "../config.js";
12
+ import { atomicWriteSecretSync, atomicWriteSync } from "../fs-atomic.js";
13
+ const DEVICE_ID_RE = /^[A-Za-z0-9-]{8,64}$/;
14
+ const LABEL_MAX = 64;
15
+ const configPath = (env) => join(globalConfigDir(env), "config.json");
16
+ export const devicePath = (env) => join(globalConfigDir(env), "device-id");
17
+ export const postureStatePath = (env) => join(globalConfigDir(env), "posture-state.json");
18
+ export const postureStampPath = (env) => join(globalConfigDir(env), "posture-send-stamp");
19
+ function readJsonObject(path) {
20
+ try {
21
+ const raw = JSON.parse(readFileSync(path, "utf8"));
22
+ return raw !== null && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
23
+ }
24
+ catch {
25
+ return {};
26
+ }
27
+ }
28
+ export function readPostureConfig(env) {
29
+ const posture = readJsonObject(configPath(env))["posture"];
30
+ if (posture === null || typeof posture !== "object")
31
+ return {};
32
+ const p = posture;
33
+ return {
34
+ share: p["share"] === true,
35
+ label: typeof p["label"] === "string" ? p["label"] : undefined,
36
+ };
37
+ }
38
+ /** Sharing is on only when the file says exactly `true`. */
39
+ export function shareOn(env) {
40
+ return readPostureConfig(env).share === true;
41
+ }
42
+ /** Merges into ~/.kya/config.json. Other keys (for example `ioc`) are kept as they are. */
43
+ export function writePostureConfig(env, patch) {
44
+ const dir = globalConfigDir(env);
45
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
46
+ const file = readJsonObject(configPath(env));
47
+ const merged = { ...readPostureConfig(env), ...patch };
48
+ const clean = Object.fromEntries(Object.entries(merged).filter(([, v]) => v !== undefined));
49
+ file["posture"] = clean;
50
+ atomicWriteSync(configPath(env), `${JSON.stringify(file, null, 2)}\n`);
51
+ }
52
+ /** The random device id. Created on first use with mode 0600. Not hardware based. */
53
+ export function deviceId(env, create) {
54
+ const path = devicePath(env);
55
+ try {
56
+ const raw = readFileSync(path, "utf8").trim();
57
+ if (DEVICE_ID_RE.test(raw))
58
+ return raw;
59
+ }
60
+ catch {
61
+ /* missing: create below */
62
+ }
63
+ if (!create)
64
+ return undefined;
65
+ mkdirSync(globalConfigDir(env), { recursive: true, mode: 0o700 });
66
+ const id = randomUUID();
67
+ atomicWriteSecretSync(path, `${id}\n`);
68
+ return id;
69
+ }
70
+ /** Default label: first 8 hex of sha256(hostname + deviceId). The hostname itself is never sent. */
71
+ export function defaultLabel(id, host = hostname()) {
72
+ return createHash("sha256").update(host + id).digest("hex").slice(0, 8);
73
+ }
74
+ export function effectiveLabel(env, id) {
75
+ return readPostureConfig(env).label ?? defaultLabel(id);
76
+ }
77
+ export function readPostureState(env) {
78
+ const raw = readJsonObject(postureStatePath(env));
79
+ const out = {};
80
+ const p = raw["policy"];
81
+ if (p && typeof p === "object") {
82
+ const pc = p;
83
+ if (typeof pc["enabled"] === "boolean" && typeof pc["checkedAt"] === "string") {
84
+ out.policy = { enabled: pc["enabled"], checkedAt: pc["checkedAt"] };
85
+ }
86
+ }
87
+ if (typeof raw["lastSentAt"] === "string")
88
+ out.lastSentAt = raw["lastSentAt"];
89
+ return out;
90
+ }
91
+ export function writePostureState(env, state) {
92
+ mkdirSync(globalConfigDir(env), { recursive: true, mode: 0o700 });
93
+ atomicWriteSync(postureStatePath(env), `${JSON.stringify(state, null, 2)}\n`);
94
+ }
95
+ export function hasDeviceFile(env) {
96
+ return existsSync(devicePath(env));
97
+ }
98
+ /** Label rules: 1 to 64 characters, no control characters, and nothing the local check forbids (user, host, paths). */
99
+ export function labelProblem(label, problemOf) {
100
+ if (label.length < 1 || label.length > LABEL_MAX)
101
+ return `label must be 1 to ${LABEL_MAX} characters`;
102
+ if (/[\u0000-\u001f\u007f]/.test(label))
103
+ return "label must not contain control characters";
104
+ const why = problemOf(label);
105
+ return why === undefined ? undefined : `label must not contain: ${why}`;
106
+ }
107
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/posture/store.ts"],"names":[],"mappings":"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"}