@kindgi/cli 0.1.11-rc.0 → 0.2.0-rc.1

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 (350) hide show
  1. package/README.md +77 -33
  2. package/dist/build/containerfile.d.ts +2 -0
  3. package/dist/build/containerfile.d.ts.map +1 -1
  4. package/dist/build/containerfile.js +14 -3
  5. package/dist/build/containerfile.js.map +1 -1
  6. package/dist/build/defaults.d.ts +2 -0
  7. package/dist/build/defaults.d.ts.map +1 -1
  8. package/dist/build/defaults.js +8 -0
  9. package/dist/build/defaults.js.map +1 -1
  10. package/dist/build/hosted.d.ts +2 -9
  11. package/dist/build/hosted.d.ts.map +1 -1
  12. package/dist/build/hosted.js +4 -2
  13. package/dist/build/hosted.js.map +1 -1
  14. package/dist/build/pack-blocks.d.ts +51 -0
  15. package/dist/build/pack-blocks.d.ts.map +1 -0
  16. package/dist/build/pack-blocks.js +98 -0
  17. package/dist/build/pack-blocks.js.map +1 -0
  18. package/dist/build/runners.d.ts +5 -1
  19. package/dist/build/runners.d.ts.map +1 -1
  20. package/dist/cli.js +4 -0
  21. package/dist/cli.js.map +1 -1
  22. package/dist/commands/adapters.d.ts.map +1 -1
  23. package/dist/commands/adapters.js +12 -6
  24. package/dist/commands/adapters.js.map +1 -1
  25. package/dist/commands/agents.js +8 -8
  26. package/dist/commands/agents.js.map +1 -1
  27. package/dist/commands/auth.d.ts.map +1 -1
  28. package/dist/commands/auth.js +155 -39
  29. package/dist/commands/auth.js.map +1 -1
  30. package/dist/commands/blocks.d.ts.map +1 -1
  31. package/dist/commands/blocks.js +1 -1
  32. package/dist/commands/blocks.js.map +1 -1
  33. package/dist/commands/build.d.ts +17 -6
  34. package/dist/commands/build.d.ts.map +1 -1
  35. package/dist/commands/build.js +136 -89
  36. package/dist/commands/build.js.map +1 -1
  37. package/dist/commands/connection-apps.d.ts +3 -0
  38. package/dist/commands/connection-apps.d.ts.map +1 -0
  39. package/dist/commands/connection-apps.js +239 -0
  40. package/dist/commands/connection-apps.js.map +1 -0
  41. package/dist/commands/connections.d.ts +44 -0
  42. package/dist/commands/connections.d.ts.map +1 -0
  43. package/dist/commands/connections.js +385 -0
  44. package/dist/commands/connections.js.map +1 -0
  45. package/dist/commands/conversations.js +1 -1
  46. package/dist/commands/conversations.js.map +1 -1
  47. package/dist/commands/deploy.d.ts.map +1 -1
  48. package/dist/commands/deploy.js +178 -97
  49. package/dist/commands/deploy.js.map +1 -1
  50. package/dist/commands/dev.d.ts +10 -0
  51. package/dist/commands/dev.d.ts.map +1 -1
  52. package/dist/commands/dev.js +177 -87
  53. package/dist/commands/dev.js.map +1 -1
  54. package/dist/commands/doctor.js +7 -7
  55. package/dist/commands/doctor.js.map +1 -1
  56. package/dist/commands/env-scoped.d.ts.map +1 -1
  57. package/dist/commands/env-scoped.js +37 -22
  58. package/dist/commands/env-scoped.js.map +1 -1
  59. package/dist/commands/env.d.ts.map +1 -1
  60. package/dist/commands/env.js +35 -22
  61. package/dist/commands/env.js.map +1 -1
  62. package/dist/commands/eval-runs.js +6 -6
  63. package/dist/commands/eval-runs.js.map +1 -1
  64. package/dist/commands/eval-suites.js +9 -9
  65. package/dist/commands/eval-suites.js.map +1 -1
  66. package/dist/commands/exports.d.ts.map +1 -1
  67. package/dist/commands/exports.js +35 -9
  68. package/dist/commands/exports.js.map +1 -1
  69. package/dist/commands/feedback.d.ts.map +1 -1
  70. package/dist/commands/feedback.js +4 -3
  71. package/dist/commands/feedback.js.map +1 -1
  72. package/dist/commands/gate-policies.d.ts.map +1 -1
  73. package/dist/commands/gate-policies.js +7 -7
  74. package/dist/commands/gate-policies.js.map +1 -1
  75. package/dist/commands/helpers.d.ts +33 -0
  76. package/dist/commands/helpers.d.ts.map +1 -1
  77. package/dist/commands/helpers.js +49 -0
  78. package/dist/commands/helpers.js.map +1 -1
  79. package/dist/commands/index.d.ts.map +1 -1
  80. package/dist/commands/index.js +10 -0
  81. package/dist/commands/index.js.map +1 -1
  82. package/dist/commands/init.d.ts +1 -1
  83. package/dist/commands/init.d.ts.map +1 -1
  84. package/dist/commands/init.js +57 -45
  85. package/dist/commands/init.js.map +1 -1
  86. package/dist/commands/judge-classes.js +4 -4
  87. package/dist/commands/judge-classes.js.map +1 -1
  88. package/dist/commands/judging-queue.d.ts +3 -0
  89. package/dist/commands/judging-queue.d.ts.map +1 -0
  90. package/dist/commands/judging-queue.js +105 -0
  91. package/dist/commands/judging-queue.js.map +1 -0
  92. package/dist/commands/judging-rules.d.ts +3 -0
  93. package/dist/commands/judging-rules.d.ts.map +1 -0
  94. package/dist/commands/judging-rules.js +351 -0
  95. package/dist/commands/judging-rules.js.map +1 -0
  96. package/dist/commands/judgments.d.ts.map +1 -1
  97. package/dist/commands/judgments.js +78 -36
  98. package/dist/commands/judgments.js.map +1 -1
  99. package/dist/commands/key.d.ts.map +1 -1
  100. package/dist/commands/key.js +107 -9
  101. package/dist/commands/key.js.map +1 -1
  102. package/dist/commands/license.d.ts.map +1 -1
  103. package/dist/commands/license.js +67 -15
  104. package/dist/commands/license.js.map +1 -1
  105. package/dist/commands/mail-triggers.d.ts +3 -0
  106. package/dist/commands/mail-triggers.d.ts.map +1 -0
  107. package/dist/commands/mail-triggers.js +290 -0
  108. package/dist/commands/mail-triggers.js.map +1 -0
  109. package/dist/commands/mcp.d.ts.map +1 -1
  110. package/dist/commands/mcp.js +4 -4
  111. package/dist/commands/mcp.js.map +1 -1
  112. package/dist/commands/people.js +8 -14
  113. package/dist/commands/people.js.map +1 -1
  114. package/dist/commands/promote.js +1 -1
  115. package/dist/commands/promote.js.map +1 -1
  116. package/dist/commands/proposals.d.ts.map +1 -1
  117. package/dist/commands/proposals.js +83 -30
  118. package/dist/commands/proposals.js.map +1 -1
  119. package/dist/commands/run-waits.d.ts +68 -19
  120. package/dist/commands/run-waits.d.ts.map +1 -1
  121. package/dist/commands/run-waits.js +82 -8
  122. package/dist/commands/run-waits.js.map +1 -1
  123. package/dist/commands/runs.d.ts.map +1 -1
  124. package/dist/commands/runs.js +70 -30
  125. package/dist/commands/runs.js.map +1 -1
  126. package/dist/commands/schedules.d.ts.map +1 -1
  127. package/dist/commands/schedules.js +44 -20
  128. package/dist/commands/schedules.js.map +1 -1
  129. package/dist/commands/secrets-copy.d.ts.map +1 -1
  130. package/dist/commands/secrets-copy.js +20 -12
  131. package/dist/commands/secrets-copy.js.map +1 -1
  132. package/dist/commands/secrets.d.ts.map +1 -1
  133. package/dist/commands/secrets.js +13 -8
  134. package/dist/commands/secrets.js.map +1 -1
  135. package/dist/commands/service-accounts.d.ts.map +1 -1
  136. package/dist/commands/service-accounts.js +4 -2
  137. package/dist/commands/service-accounts.js.map +1 -1
  138. package/dist/commands/sign-in.js +2 -2
  139. package/dist/commands/sign-in.js.map +1 -1
  140. package/dist/commands/sites.d.ts.map +1 -1
  141. package/dist/commands/sites.js +13 -6
  142. package/dist/commands/sites.js.map +1 -1
  143. package/dist/commands/skills.d.ts +54 -3
  144. package/dist/commands/skills.d.ts.map +1 -1
  145. package/dist/commands/skills.js +169 -38
  146. package/dist/commands/skills.js.map +1 -1
  147. package/dist/commands/tokens.d.ts.map +1 -1
  148. package/dist/commands/tokens.js +9 -1
  149. package/dist/commands/tokens.js.map +1 -1
  150. package/dist/commands/upgrade.d.ts.map +1 -1
  151. package/dist/commands/upgrade.js +9 -8
  152. package/dist/commands/upgrade.js.map +1 -1
  153. package/dist/commands/webhooks.d.ts.map +1 -1
  154. package/dist/commands/webhooks.js +72 -33
  155. package/dist/commands/webhooks.js.map +1 -1
  156. package/dist/config.d.ts +6 -0
  157. package/dist/config.d.ts.map +1 -1
  158. package/dist/config.js +18 -3
  159. package/dist/config.js.map +1 -1
  160. package/dist/context.d.ts +12 -0
  161. package/dist/context.d.ts.map +1 -1
  162. package/dist/context.js +2 -0
  163. package/dist/context.js.map +1 -1
  164. package/dist/deploy/pack-blocks-gate.d.ts +12 -0
  165. package/dist/deploy/pack-blocks-gate.d.ts.map +1 -0
  166. package/dist/deploy/pack-blocks-gate.js +34 -0
  167. package/dist/deploy/pack-blocks-gate.js.map +1 -0
  168. package/dist/deploy/post.d.ts +9 -0
  169. package/dist/deploy/post.d.ts.map +1 -1
  170. package/dist/deploy/post.js +20 -3
  171. package/dist/deploy/post.js.map +1 -1
  172. package/dist/dev/defaults.d.ts.map +1 -1
  173. package/dist/dev/defaults.js +8 -1
  174. package/dist/dev/defaults.js.map +1 -1
  175. package/dist/dev/dev-only-imports.d.ts +7 -4
  176. package/dist/dev/dev-only-imports.d.ts.map +1 -1
  177. package/dist/dev/dev-only-imports.js +5 -5
  178. package/dist/dev/dev-only-imports.js.map +1 -1
  179. package/dist/dev/log-view.d.ts +4 -4
  180. package/dist/dev/log-view.d.ts.map +1 -1
  181. package/dist/dev/log-view.js +4 -4
  182. package/dist/dev/log-view.js.map +1 -1
  183. package/dist/dev/pack-service.d.ts +7 -1
  184. package/dist/dev/pack-service.d.ts.map +1 -1
  185. package/dist/dev/pack-service.js +36 -3
  186. package/dist/dev/pack-service.js.map +1 -1
  187. package/dist/dev/preview-expiry.d.ts +6 -7
  188. package/dist/dev/preview-expiry.d.ts.map +1 -1
  189. package/dist/dev/preview-expiry.js +7 -8
  190. package/dist/dev/preview-expiry.js.map +1 -1
  191. package/dist/dev/providers.d.ts +2 -1
  192. package/dist/dev/providers.d.ts.map +1 -1
  193. package/dist/dev/providers.js +28 -12
  194. package/dist/dev/providers.js.map +1 -1
  195. package/dist/dev/runners.d.ts +19 -0
  196. package/dist/dev/runners.d.ts.map +1 -1
  197. package/dist/dev/runtime-container.d.ts.map +1 -1
  198. package/dist/dev/runtime-container.js +2 -2
  199. package/dist/dev/runtime-container.js.map +1 -1
  200. package/dist/dev/runtime-env.d.ts +2 -1
  201. package/dist/dev/runtime-env.d.ts.map +1 -1
  202. package/dist/dev/runtime-env.js +5 -5
  203. package/dist/dev/runtime-env.js.map +1 -1
  204. package/dist/dev/runtime-image.d.ts +2 -2
  205. package/dist/dev/runtime-image.d.ts.map +1 -1
  206. package/dist/dev/runtime-image.js +2 -2
  207. package/dist/dev/runtime-image.js.map +1 -1
  208. package/dist/dev/runtime-registry.d.ts +8 -10
  209. package/dist/dev/runtime-registry.d.ts.map +1 -1
  210. package/dist/dev/runtime-registry.js +27 -27
  211. package/dist/dev/runtime-registry.js.map +1 -1
  212. package/dist/dev/sandbox/index.js +1 -1
  213. package/dist/dev/sandbox/notices.d.ts +2 -0
  214. package/dist/dev/sandbox/notices.d.ts.map +1 -1
  215. package/dist/dev/sandbox/notices.js +5 -2
  216. package/dist/dev/sandbox/notices.js.map +1 -1
  217. package/dist/env/defaults.d.ts.map +1 -1
  218. package/dist/env/defaults.js +3 -1
  219. package/dist/env/defaults.js.map +1 -1
  220. package/dist/env/pack-env-plan.d.ts +4 -0
  221. package/dist/env/pack-env-plan.d.ts.map +1 -1
  222. package/dist/env/pack-env-plan.js +8 -2
  223. package/dist/env/pack-env-plan.js.map +1 -1
  224. package/dist/exports/create.d.ts +2 -0
  225. package/dist/exports/create.d.ts.map +1 -1
  226. package/dist/exports/create.js +10 -2
  227. package/dist/exports/create.js.map +1 -1
  228. package/dist/exports/plan.d.ts.map +1 -1
  229. package/dist/exports/plan.js +32 -0
  230. package/dist/exports/plan.js.map +1 -1
  231. package/dist/feedback/store.d.ts.map +1 -1
  232. package/dist/feedback/store.js +8 -19
  233. package/dist/feedback/store.js.map +1 -1
  234. package/dist/help.d.ts +6 -0
  235. package/dist/help.d.ts.map +1 -1
  236. package/dist/help.js +35 -1
  237. package/dist/help.js.map +1 -1
  238. package/dist/init/agent-access.d.ts +3 -2
  239. package/dist/init/agent-access.d.ts.map +1 -1
  240. package/dist/init/agent-access.js +5 -1
  241. package/dist/init/agent-access.js.map +1 -1
  242. package/dist/init/augment-scaffolder.d.ts +7 -0
  243. package/dist/init/augment-scaffolder.d.ts.map +1 -1
  244. package/dist/init/augment-scaffolder.js +15 -14
  245. package/dist/init/augment-scaffolder.js.map +1 -1
  246. package/dist/init/dependency-specs.d.ts +1 -0
  247. package/dist/init/dependency-specs.d.ts.map +1 -1
  248. package/dist/init/dependency-specs.js +27 -7
  249. package/dist/init/dependency-specs.js.map +1 -1
  250. package/dist/init/java-augment.d.ts +3 -0
  251. package/dist/init/java-augment.d.ts.map +1 -1
  252. package/dist/init/java-augment.js +16 -15
  253. package/dist/init/java-augment.js.map +1 -1
  254. package/dist/init/python-augment.d.ts +3 -0
  255. package/dist/init/python-augment.d.ts.map +1 -1
  256. package/dist/init/python-augment.js +15 -14
  257. package/dist/init/python-augment.js.map +1 -1
  258. package/dist/init/scala-augment.d.ts +8 -1
  259. package/dist/init/scala-augment.d.ts.map +1 -1
  260. package/dist/init/scala-augment.js +32 -17
  261. package/dist/init/scala-augment.js.map +1 -1
  262. package/dist/key/defaults.d.ts.map +1 -1
  263. package/dist/key/defaults.js +6 -1
  264. package/dist/key/defaults.js.map +1 -1
  265. package/dist/key/runners.d.ts +4 -1
  266. package/dist/key/runners.d.ts.map +1 -1
  267. package/dist/license/renew.d.ts +6 -0
  268. package/dist/license/renew.d.ts.map +1 -1
  269. package/dist/license/renew.js +8 -5
  270. package/dist/license/renew.js.map +1 -1
  271. package/dist/main.d.ts +10 -0
  272. package/dist/main.d.ts.map +1 -1
  273. package/dist/main.js +19 -5
  274. package/dist/main.js.map +1 -1
  275. package/dist/output.d.ts +6 -0
  276. package/dist/output.d.ts.map +1 -1
  277. package/dist/output.js +8 -0
  278. package/dist/output.js.map +1 -1
  279. package/dist/parse.d.ts +1 -1
  280. package/dist/parse.d.ts.map +1 -1
  281. package/dist/parse.js +1 -1
  282. package/dist/parse.js.map +1 -1
  283. package/dist/private-file.d.ts +23 -0
  284. package/dist/private-file.d.ts.map +1 -0
  285. package/dist/private-file.js +65 -0
  286. package/dist/private-file.js.map +1 -0
  287. package/dist/progress-head.d.ts +13 -0
  288. package/dist/progress-head.d.ts.map +1 -0
  289. package/dist/progress-head.js +30 -0
  290. package/dist/progress-head.js.map +1 -0
  291. package/dist/progress-lines.d.ts +29 -0
  292. package/dist/progress-lines.d.ts.map +1 -0
  293. package/dist/progress-lines.js +35 -0
  294. package/dist/progress-lines.js.map +1 -0
  295. package/dist/sdk-skills/kindgi-authoring-agents/SKILL.md +6 -6
  296. package/dist/sdk-skills/kindgi-authoring-flows/SKILL.md +1 -1
  297. package/dist/sdk-skills/kindgi-authoring-guardrails/SKILL.md +2 -2
  298. package/dist/sdk-skills/kindgi-authoring-mcp-servers/SKILL.md +1 -1
  299. package/dist/sdk-skills/kindgi-authoring-providers/SKILL.md +13 -3
  300. package/dist/sdk-skills/kindgi-authoring-tools/SKILL.md +47 -9
  301. package/dist/sdk-skills/kindgi-fix-corrections/SKILL.md +262 -0
  302. package/dist/sdk-skills/kindgi-framework-feedback/SKILL.md +1 -1
  303. package/dist/sdk-skills/kindgi-getting-started/SKILL.md +46 -9
  304. package/dist/sdk-skills/kindgi-java-authoring-agents/SKILL.md +5 -5
  305. package/dist/sdk-skills/kindgi-java-authoring-flows/SKILL.md +1 -1
  306. package/dist/sdk-skills/kindgi-java-authoring-guardrails/SKILL.md +1 -1
  307. package/dist/sdk-skills/kindgi-java-authoring-tools/SKILL.md +101 -11
  308. package/dist/sdk-skills/kindgi-java-getting-started/SKILL.md +41 -9
  309. package/dist/sdk-skills/kindgi-python-authoring-agents/SKILL.md +4 -4
  310. package/dist/sdk-skills/kindgi-python-authoring-flows/SKILL.md +1 -1
  311. package/dist/sdk-skills/kindgi-python-authoring-guardrails/SKILL.md +1 -1
  312. package/dist/sdk-skills/kindgi-python-authoring-tools/SKILL.md +53 -10
  313. package/dist/sdk-skills/kindgi-python-getting-started/SKILL.md +42 -11
  314. package/dist/sdk-skills/kindgi-scala-authoring-agents/SKILL.md +5 -5
  315. package/dist/sdk-skills/kindgi-scala-authoring-flows/SKILL.md +1 -1
  316. package/dist/sdk-skills/kindgi-scala-authoring-guardrails/SKILL.md +1 -1
  317. package/dist/sdk-skills/kindgi-scala-authoring-tools/SKILL.md +92 -9
  318. package/dist/sdk-skills/kindgi-scala-getting-started/SKILL.md +41 -9
  319. package/dist/sdk-skills/kindgi-using/SKILL.md +63 -21
  320. package/dist/templates/drupal/AGENTS.md +2 -1
  321. package/dist/templates/follow-up/.nvmrc +1 -0
  322. package/dist/templates/follow-up/AGENTS.md +83 -0
  323. package/dist/templates/follow-up/README.md.tmpl +111 -0
  324. package/dist/templates/follow-up/agents/follow-up/index.test.ts.tmpl +26 -0
  325. package/dist/templates/follow-up/agents/follow-up/index.ts.tmpl +53 -0
  326. package/dist/templates/follow-up/gitignore +8 -0
  327. package/dist/templates/follow-up/kindgi.config.ts.tmpl +45 -0
  328. package/dist/templates/follow-up/package.json.tmpl +30 -0
  329. package/dist/templates/follow-up/pnpm-workspace.yaml +9 -0
  330. package/dist/templates/follow-up/tools/gmail-send/index.test.ts.tmpl +60 -0
  331. package/dist/templates/follow-up/tools/gmail-send/index.ts.tmpl +14 -0
  332. package/dist/templates/follow-up/tsconfig.json.tmpl +27 -0
  333. package/dist/templates/follow-up/vitest.config.ts.tmpl +14 -0
  334. package/dist/templates/java/AGENTS.md +2 -1
  335. package/dist/templates/minimal/AGENTS.md +2 -1
  336. package/dist/templates/python/AGENTS.md +2 -1
  337. package/dist/templates/sample/AGENTS.md +2 -1
  338. package/dist/templates/scala/AGENTS.md +2 -1
  339. package/dist/templates/woocommerce/AGENTS.md +12 -3
  340. package/dist/templates/woocommerce/README.md.tmpl +29 -5
  341. package/dist/templates/woocommerce/agents/store-agent/index.test.ts.tmpl +38 -7
  342. package/dist/templates/woocommerce/agents/store-agent/index.ts.tmpl +7 -12
  343. package/dist/templates/woocommerce/blocks/store-agent-prompt.json.tmpl +10 -0
  344. package/dist/templates/woocommerce/blocks/store-agent-prompt.liquid.tmpl +7 -0
  345. package/dist/templates/woocommerce/kindgi.config.ts.tmpl +1 -0
  346. package/dist/value-target.d.ts +4 -2
  347. package/dist/value-target.d.ts.map +1 -1
  348. package/dist/value-target.js +8 -5
  349. package/dist/value-target.js.map +1 -1
  350. package/package.json +13 -13
@@ -0,0 +1,262 @@
1
+ ---
2
+ name: kindgi-fix-corrections
3
+ description: >
4
+ Turn the experts' corrections of a Kindgi agent into fixes. Load this when
5
+ the person says "fix what the experts corrected", "the agent keeps getting
6
+ <X> wrong, correct it", "turn the refund agent's corrections into changes",
7
+ or points you at an agent's "no" judgments. The loop: pull the runs an
8
+ expert marked wrong, read why, and sort each correction to where it belongs
9
+ — a rule in code, a setting, an approval rule, or the agent's instructions —
10
+ add a pack test per correction, then publish and ask a person to make the
11
+ new version live, naming the corrections it fixes. Making a version live
12
+ and approving it stay with the person, and a correction that would loosen
13
+ anything — raise a limit, widen a window, drop a check — goes to the owner,
14
+ not the agent.
15
+ type: core
16
+ library: "@kindgi/sdk"
17
+ version: "0.1.0"
18
+ sdk_version: "0.2.0-rc.1"
19
+ pack_languages: [node, python, java, scala]
20
+ sources:
21
+ - packages/cli/src/commands/judgments.ts
22
+ - packages/cli/src/commands/runs.ts
23
+ - packages/cli/src/commands/blocks.ts
24
+ - packages/cli/src/commands/agents.ts
25
+ - packages/cli/src/commands/eval-runs.ts
26
+ - packages/cli/src/commands/test.ts
27
+ ---
28
+
29
+ # Fixing what the experts corrected
30
+
31
+ > **Running `kindgi`:** in a Node project the CLI is a devDependency
32
+ > (`@kindgi/cli`), not a global command. Run it through the project's
33
+ > package manager — `pnpm exec kindgi …`, `npx --no -- kindgi …` (npm),
34
+ > `yarn kindgi …` or `bun run kindgi …`. A Python pack (`[tool.kindgi]` in
35
+ > `pyproject.toml`) has no Node project: run the `kindgi` on `PATH`. A Java
36
+ > or Scala pack (`kindgi.config.json`) runs the CLI it pins: `./kindgiw …`.
37
+ > Commands below are written `kindgi …` for brevity.
38
+
39
+ An expert — a support lead, a claims reviewer, an editor — marks a run's
40
+ answer wrong and says why. Your job is to turn those corrections into
41
+ changes to the agent, each at the layer where it belongs, so the agent
42
+ stops making the mistake and a person can see the mistake is gone.
43
+
44
+ A correction is not always a prompt change. A store's "never refund
45
+ shipping" belongs in the refund tool's code, where it's checked every time,
46
+ not in instructions a model may or may not follow. Sorting each correction
47
+ to the right layer is your call, not Kindgi's: Kindgi gives you the
48
+ corrections and the tools to change each layer.
49
+
50
+ ## What stays with the person
51
+
52
+ 1. **Never loosen a rule — a loosening correction goes to the owner.** Some
53
+ corrections ask for a policy *looser* than the one in force: with a 14-day
54
+ return window, "should have refunded — 20 days is fine for us" wants the
55
+ window widened; others want a limit raised, a check dropped, or a tool to
56
+ stop asking for approval. This skill makes none of those — it hands the
57
+ correction to the owner, quoted, and lets them decide. A refusal the
58
+ *current* rule already allows is not a loosening: the agent applied the rule
59
+ wrong ("should have refunded — it was inside the 14 days"), nothing about the
60
+ policy changes, so you fix it like any other correction — in code with a
61
+ test, or in the instructions through Improve. The corrections you make carry
62
+ out a rule the agent got wrong, tighten a rule, or change how the agent talks
63
+ — never loosen the policy.
64
+ 2. **Making a version live is the person's.** You publish a new version and
65
+ *ask* for it with `kindgi agents promote … --reason`. When the scope's
66
+ release gate policy has `approvals`, the promotion waits for a second person
67
+ (`pending-approval`) — don't try to get around it.
68
+ 3. **The pulled runs hold real conversations.** A run you pull is a real
69
+ customer's. Keep it out of git. Write every pack test with invented data
70
+ — made-up order ids, amounts and names — never a customer's words or
71
+ details. Never paste a whole run, or any customer's data, into the pack,
72
+ a commit, or a message.
73
+
74
+ ## Step 1 — Pull the corrections
75
+
76
+ The corrections are the agent's "no" judgments. Start from the version the
77
+ agent is running now, so you don't re-fix something an earlier version already
78
+ fixed:
79
+
80
+ ```sh
81
+ kindgi agents live acme-store.refunds --project=<project-id>
82
+ ```
83
+
84
+ `agents live` shows the version a run would use for the project (and
85
+ `agents live-versions` lists every scope with a live version). List that
86
+ version's "no" judgments — and, as you work through them, newer versions':
87
+
88
+ ```sh
89
+ kindgi judgments list --agent=acme-store.refunds --agent-version=1.0.3 --verdict=no
90
+ ```
91
+
92
+ - `--agent-version` (it needs `--agent`) scopes to one version — the live one,
93
+ to start. Older versions' corrections may already be fixed; without a version
94
+ you get every version's.
95
+ - `--verdict=no` keeps only the corrections. (Leave it off to see what the
96
+ experts confirmed as right, too.)
97
+ - `--class=<judge-class-id>` keeps only one judge class — use it to take
98
+ only the experts' corrections once the project names its experts.
99
+
100
+ Kindgi doesn't hand out corrections: two people's coding agents can pull the
101
+ same "no" judgments, so agree outside Kindgi who takes which before you start.
102
+
103
+ Read each one in full for the reason the expert gave and the run it's on:
104
+
105
+ ```sh
106
+ kindgi judgments show <judgment-id>
107
+ kindgi runs get <run-id>
108
+ kindgi runs journal <run-id>
109
+ ```
110
+
111
+ `runs get` is the run's snapshot; `runs journal` is its durable record,
112
+ step by step, where the agent's tool calls and their arguments are. Between
113
+ the correction's reason and the run, you have what the agent did and what it
114
+ should have done.
115
+
116
+ An expert can also have said exactly what the run should have done (runtime
117
+ 0.2.0 or later): the judgment then has a `correction`, with `calls` (each
118
+ `{ tool, args }`, with only the argument fields that matter) and `notCalled`
119
+ (the tools it shouldn't have called). Take those as what the pack test
120
+ asserts. It's the expert's: never record or change a correction yourself.
121
+ Test cases built from the run check each new version against it.
122
+
123
+ ## Step 2 — Sort each correction to its layer
124
+
125
+ | The expert wrote | Where it belongs | How you change it |
126
+ |---|---|---|
127
+ | "Never refund shipping", "final sale: no refund", "over 50 on a first order, ask a person" | a rule in **code** — the tool checks it every time; a cap sends the case to a tool that always asks | edit the tool and add a test (your language's `kindgi-authoring-tools`), then `kindgi deploy` |
128
+ | "Our return window is 14 days, not 30" | a **setting** the owner can change | publish the settings block, derive a version that pins it (Step 4) |
129
+ | "Always have a person approve a refund" | an **approval rule** — a tenant policy that makes a tool always ask; it keys on the tool, not its arguments | a person sets it (the owner or the approver); point them to it, don't change it in code |
130
+ | "Store credit before cash", "too stiff", "say when the money arrives" | the agent's **instructions** | leave it to Improve, run on the test cases (`kindgi proposals improve`, the improve guide) |
131
+
132
+ If a correction fits none of these, treat it as a code rule when it must
133
+ hold every time, and as instructions when it's a matter of judgment.
134
+
135
+ ## Step 3 — Make the change, with a test per correction
136
+
137
+ Make each change in the layer you sorted it to, and add **one pack test per
138
+ correction** so the mistake can't come back:
139
+
140
+ - **Code (a tool):** add the check in the tool, and a test that the corrected
141
+ case is now refused or handled right (the 20-day-old order is refused, the
142
+ final-sale item isn't refunded). Follow your pack's language:
143
+ `kindgi-authoring-tools` (TypeScript), `kindgi-python-authoring-tools`,
144
+ `kindgi-java-authoring-tools`, or `kindgi-scala-authoring-tools`. Run the
145
+ pack's tests the way that skill shows — `kindgi test` wraps `vitest` for a
146
+ Node pack; a Python, Java or Scala pack runs its own test runner.
147
+ - **A setting:** decide the key, its limits and its default, and publish the
148
+ settings block (Step 4). Add a test that the tool reads the setting and
149
+ acts on it.
150
+ - **Instructions for Improve:** you don't write the prompt — you make sure the
151
+ corrected cases are in the test cases, then let an Improve run try wordings
152
+ on them (`kindgi proposals improve`). It writes a *suggested* change only
153
+ when a wording does better on those cases, and a person
154
+ decides whether to take it; nothing is applied on its own.
155
+
156
+ Write tests with invented data (Step 1, rule 3). A correction that belongs
157
+ to the owner (a setting they'd rather own) or an approver (an approval rule)
158
+ is theirs to make — say so, and give them the one command or the console
159
+ page, don't do it for them.
160
+
161
+ ## Step 4 — Publish, and ask to make it live
162
+
163
+ For a **setting** change, publish the block, then derive a new agent version
164
+ that pins it — no code change:
165
+
166
+ ```sh
167
+ kindgi blocks publish acme.store-policy \
168
+ --block-version=1.0.1 --project=<project-id> \
169
+ --settings=@store-policy.json --schema=@store-policy.schema.json
170
+ kindgi agents derive acme-store.refunds \
171
+ --from=1.0.3 --setting=acme.store-policy=1.0.1 --label="return window 14 days"
172
+ ```
173
+
174
+ - `blocks publish` takes `--block-version` (a semver, not `--version`) and a
175
+ required `--project`. `--settings` is the block's values; `--schema`
176
+ constrains them. (`--prompt` publishes a prompt block instead; the two are
177
+ mutually exclusive.)
178
+ - `agents derive --setting=<block-id>=<version>` re-pins a block the version
179
+ *already* references to its new version (repeat `--setting`/`--prompt` for
180
+ several). It makes the first free patch after the agent's highest version and
181
+ prints it — read that version from its output rather than assuming one. If it
182
+ answers `reused`, an identical version already exists: use that, don't derive
183
+ again.
184
+
185
+ For a **code** change, `kindgi deploy` publishes the new version with the
186
+ changed tool.
187
+
188
+ Deriving needs `publish` on the agent, `blocks publish` needs `write` on the
189
+ project, and promoting needs `promote` — the permission that makes a version
190
+ live, which an agent's admins hold.
191
+
192
+ If the person keeps test cases built from the corrected runs, try the new
193
+ version on them first:
194
+
195
+ ```sh
196
+ kindgi eval-runs start <test-set-id> --project=<project-id> \
197
+ --agent=acme-store.refunds --agent-version=1.0.4 --wait
198
+ ```
199
+
200
+ Where an expert said what the run should have done, its summary's
201
+ `corrections` says how many of those the version now passes (`passed` of
202
+ `checked`). No release gate policy checks it: quote it in the promote
203
+ `--reason`.
204
+
205
+ Either way, ask a person to make the new version live, naming the
206
+ corrections it fixes. Check first what will happen, then ask:
207
+
208
+ ```sh
209
+ kindgi agents promote acme-store.refunds 1.0.4 --project=<project-id> --check
210
+ kindgi agents promote acme-store.refunds 1.0.4 --project=<project-id> \
211
+ --reason="Fixes 1 correction: our return window is 14 days"
212
+ ```
213
+
214
+ - The scope is `--tenant` (every project), `--org=<org-id>`, or
215
+ `--project=<project-id> [--segment=<key:value>]…` (one project).
216
+ - `--check` changes nothing and answers whether it *would* make it live,
217
+ needs an approval, or fails the release gate policy.
218
+ - `--reason` is kept on the record — write what the corrections were, so the
219
+ approver reads the change in plain words.
220
+ - The outcome is `promoted`, or `pending-approval` when the scope's release
221
+ gate policy has `approvals` and a second person must approve — the "a
222
+ second person checks it" step, working as it should. (Whoever asked can't
223
+ approve their own request, unless the policy sets `separateApprover: false`.)
224
+
225
+ ## A worked example: the return window
226
+
227
+ An expert corrects a refund: "Shouldn't have refunded — delivered 20 days
228
+ ago, our window is 14." You pull it (Step 1), and see the window is a store
229
+ policy, not a one-off.
230
+
231
+ - **If the agent already reads a `returnWindowDays` setting:** publish the
232
+ block with `returnWindowDays: 14` and derive a version that pins it
233
+ (Step 4). Tell the owner they can change this themselves in the console —
234
+ Edit as a new version, then Derive a version.
235
+ - **If it doesn't read one yet:** this is a code change, in two parts. First
236
+ publish the settings block with the key — `returnWindowDays` in its schema
237
+ (0–365, whole days) and `14` in its values — because a deploy that references
238
+ a block with no published version is refused ("publish the block first").
239
+ Then, in code, make the refund tool read `returnWindowDays` and refuse an
240
+ order delivered more than that many days ago (offering a person), add the
241
+ block to what the agent references, and add a test: an order delivered 20
242
+ days ago is refused (`kindgi-authoring-tools`). `kindgi deploy` publishes the
243
+ version with the new reference. (`agents derive` only re-pins a block the
244
+ version already references, so it can't introduce this one — the deploy
245
+ does.) The schema and value live outside the pack and outside code review, so
246
+ show them to the person and name them in the `--reason`.
247
+
248
+ Then ask to make it live: `kindgi agents promote … --reason="Fixes 1
249
+ correction: our return window is 14 days"`. The refund limit — the most a
250
+ refund can be without a person — is never raised here: the cap stays in the
251
+ tool's code, and the large-refund tool still always asks.
252
+
253
+ ## References
254
+
255
+ - Experts record corrections in the console, or with
256
+ `kindgi judgments add --run=<run-id> --item=<key> --no --reason=<text>`.
257
+ - The guide for a person:
258
+ <https://docs.kindgi.com/v0.2/guides/evals/fix-what-experts-corrected/>
259
+ - Letting Improve try wordings:
260
+ <https://docs.kindgi.com/v0.2/guides/evals/improve-an-agent/>
261
+ - Changing a setting or a prompt by hand:
262
+ <https://docs.kindgi.com/v0.2/guides/evals/change-a-prompt-or-setting/>
@@ -18,7 +18,7 @@ description: >
18
18
  type: core
19
19
  library: "@kindgi/sdk"
20
20
  version: "0.4.4"
21
- sdk_version: "0.1.11-rc.0"
21
+ sdk_version: "0.2.0-rc.1"
22
22
  pack_languages: [node, python, java, scala]
23
23
  ---
24
24
 
@@ -8,14 +8,16 @@ description: >
8
8
  project has no kindgi.config.ts yet and the user asks to "add
9
9
  Kindgi", "create a pack", "scaffold a Kindgi pack", "start a
10
10
  new pack", or when the user needs the mental model for what a Kindgi
11
- pack IS. Once the pack is scaffolded and you are authoring code,
11
+ pack IS. Load it too when upgrading a self-hosted deployment, or
12
+ when asked for a migration script (there is none). Once the pack is
13
+ scaffolded and you are authoring code,
12
14
  switch to kindgi-authoring-tools / kindgi-authoring-agents /
13
15
  kindgi-authoring-guardrails / kindgi-authoring-flows for the specific
14
16
  primitive.
15
17
  type: core
16
18
  library: "@kindgi/sdk"
17
- version: "0.3.14"
18
- sdk_version: "0.1.11-rc.0"
19
+ version: "0.3.16"
20
+ sdk_version: "0.2.0-rc.1"
19
21
  pack_languages: [node]
20
22
  ---
21
23
 
@@ -97,7 +99,7 @@ Either way, `init` adds `@kindgi/sdk` and `@kindgi/cli` to the project's
97
99
  one. (`npx @kindgi/cli` is the scoped package; a bare `npx kindgi` would
98
100
  fetch an unrelated package.)
99
101
 
100
- Four templates:
102
+ Five templates:
101
103
 
102
104
  - `--template=minimal` (default) — folder structure only, no example
103
105
  primitives. Right when you know what you want to build.
@@ -111,6 +113,10 @@ Four templates:
111
113
  Server signed in with OAuth: house-style fixes as drafts with every
112
114
  change approved, and a flow that checks each saved article before an
113
115
  agent sees it. Its README explains each choice.
116
+ - `--template=follow-up` — an agent that writes a follow-up mail from
117
+ your notes and sends it from your own Gmail, each send approved first.
118
+ Its send tool comes from `@kindgi/connections`, under the pack's own
119
+ id. Its README explains each choice.
114
120
 
115
121
  ## Boot the dev harness
116
122
 
@@ -120,8 +126,9 @@ pnpm exec kindgi dev
120
126
 
121
127
  `kindgi dev` boots a local Kindgi runtime (starting the services it
122
128
  needs on first run), indexes the pack, registers every primitive, and
123
- re-registers on every save. The banner prints the API URL, the seeded
124
- bearer token, and (if the console is bundled) the `/console/` URL.
129
+ re-registers on every save. The banner prints the API URL, the dev
130
+ token's last four characters (the pack's `.kindgirc.json` has it in full,
131
+ as `token`), and (if the console is bundled) the `/console/` URL.
125
132
 
126
133
  One `kindgi dev` per pack. When one is already running (the person's
127
134
  terminal, say), `kindgi dev` exits with code 3 and prints where it is
@@ -199,7 +206,9 @@ Most of the setup is automatable, but two require your knowledge:
199
206
  - **Real LLM provider credentials** — the built-in dev-echo provider
200
207
  returns canned responses (great for the loop test, useless for real
201
208
  agents). It is a fallback, so it steps aside once a real provider is
202
- registered. Declare it in `kindgi.config.ts`
209
+ registered. Anthropic is the example below; `kindgi providers presets`
210
+ lists OpenAI, Gemini, Groq and OpenRouter too.
211
+ Declare one in `kindgi.config.ts`
203
212
  (`providers: [{ preset: 'anthropic' }]`, the key stored by the person with
204
213
  `kindgi secrets set ANTHROPIC_API_KEY --env=local --scope=tenant`) and `kindgi dev`
205
214
  registers it on every boot, in every worktree and after `--reset`. Commit
@@ -312,7 +321,7 @@ const month = await kindgi.cost.usage.summary({
312
321
  // month.totalUsd; month.groups[i].key ({ month: '2026-10' }), .totalUsd, .tokens
313
322
  ```
314
323
 
315
- Docs: https://docs.kindgi.com/v0.1/guides/observability/cost-per-run/
324
+ Docs: https://docs.kindgi.com/v0.2/guides/observability/cost-per-run/
316
325
 
317
326
  Show it in the app's own UI. **Never:**
318
327
 
@@ -323,7 +332,35 @@ Show it in the app's own UI. **Never:**
323
332
  - **link users to Kindgi's console** or any Kindgi UI for this data.
324
333
 
325
334
  To keep a copy (reporting, search), pull it through the API into the app's
326
- own tables. Docs: https://docs.kindgi.com/v0.1/guides/runs/show-runs-in-your-app/
335
+ own tables. Docs: https://docs.kindgi.com/v0.2/guides/runs/show-runs-in-your-app/
336
+
337
+ ## Upgrading a deployment
338
+
339
+ There's no migration script, and none to write: a self-hosted runtime brings
340
+ its database up to date when it starts, applying the migrations the database
341
+ doesn't have yet, then serving. Migrations only go forward: an upgrade
342
+ starts with a backup of the database, and going back means restoring it and
343
+ running the older version on it.
344
+
345
+ - **On Cloud Run, a small dev deployment** (`network_mode = "none"`, on
346
+ runtime 0.1.8 or later): the Cloud Run module's `./upgrade.sh`, as of the
347
+ `@kindgi/sdk@<version>` tag of the release you're upgrading to, since it
348
+ knows the steps up to its own release. Run `./upgrade.sh --dry-run` first:
349
+ it changes nothing, and lists what a real run would change. Its plan also
350
+ reads every `*.auto.tfvars.json` in the module's folder (the pack's env),
351
+ and `yes` applies exactly the saved plan it showed. The module README's
352
+ Upgrading section has the rest:
353
+ https://github.com/kindgi/kindgi-sdk/tree/main/deploy/gcp-cloud-run#upgrading
354
+ - **Any other Cloud Run deployment:** by hand, staging first, as the Cloud
355
+ Run page's "Upgrade by hand" section says:
356
+ https://docs.kindgi.com/v0.2/deploy/self-hosted/cloud-run/#upgrade-by-hand
357
+ - **On Azure Container Apps:** the "Operate it" section of its page,
358
+ https://docs.kindgi.com/v0.2/deploy/self-hosted/azure-container-apps/#operate-it.
359
+ - **Otherwise:** the operate page's upgrade steps,
360
+ https://docs.kindgi.com/v0.2/deploy/self-hosted/operate/#upgrade-the-runtime.
361
+
362
+ An upgrade changes a running deployment: give the person the commands to run
363
+ in their own terminal (`./upgrade.sh` waits for them to type `yes`).
327
364
 
328
365
  ## References
329
366
 
@@ -16,7 +16,7 @@ description: >
16
16
  type: core
17
17
  library: "kindgi-pack (Java)"
18
18
  version: "0.1.4"
19
- sdk_version: "0.1.11-rc.0"
19
+ sdk_version: "0.2.0-rc.1"
20
20
  pack_languages: [java]
21
21
  sources:
22
22
  - sdks/java/kindgi-pack/README.md
@@ -152,10 +152,10 @@ public final class BriefWriter {
152
152
  `Map.of("overrides", Map.of("<tool id>", true))`) makes a tool's approval
153
153
  need someone other than whoever asked.
154
154
  - **`set("budget", …)`:** per turn. `maxSteps` counts model calls (default
155
- 8); `maxCostUsd`; `maxWallMs` (default 120 000). Exceeding the steps or the
156
- cost fails the turn (`budget-exceeded`); running out of wall time aborts
157
- it. Leave room for real models: a turn with tool calls can take tens of
158
- seconds.
155
+ 8, at most 32); `maxCostUsd`; `maxWallMs` (default 120 000). Exceeding
156
+ the steps or the cost fails the turn (`budget-exceeded`); running out of
157
+ wall time aborts it. Leave room for real models: a turn with tool calls
158
+ can take tens of seconds.
159
159
  - **`output(Type.class)`:** a typed answer, with its schema derived from the
160
160
  record. The final answer must be JSON matching it. A wrong one goes back
161
161
  to the model with the problems (`maxRepairs`, default 1), and then the
@@ -16,7 +16,7 @@ description: >
16
16
  type: core
17
17
  library: "kindgi-pack (Java)"
18
18
  version: "0.1.2"
19
- sdk_version: "0.1.11-rc.0"
19
+ sdk_version: "0.2.0-rc.1"
20
20
  pack_languages: [java]
21
21
  sources:
22
22
  - sdks/java/kindgi-pack/README.md
@@ -17,7 +17,7 @@ description: >
17
17
  type: core
18
18
  library: "kindgi-pack (Java)"
19
19
  version: "0.1.2"
20
- sdk_version: "0.1.11-rc.0"
20
+ sdk_version: "0.2.0-rc.1"
21
21
  pack_languages: [java]
22
22
  sources:
23
23
  - sdks/java/kindgi-pack/README.md
@@ -14,8 +14,8 @@ description: >
14
14
  by kindgi-java-getting-started.
15
15
  type: core
16
16
  library: "kindgi-pack (Java)"
17
- version: "0.1.3"
18
- sdk_version: "0.1.11-rc.0"
17
+ version: "0.1.4"
18
+ sdk_version: "0.2.0-rc.1"
19
19
  pack_languages: [java]
20
20
  sources:
21
21
  - sdks/java/kindgi-pack/README.md
@@ -170,7 +170,7 @@ final class Citator {
170
170
  it writes to (an `Idempotency-Key` header, a client reference, a unique
171
171
  column) or looks for it there first: a refund never goes out twice. A
172
172
  UUID; `null` outside a run and from a runtime before 0.1.6. Docs:
173
- https://docs.kindgi.com/v0.1/guides/tools/write-a-tool/#make-a-side-effect-happen-once
173
+ https://docs.kindgi.com/v0.2/guides/tools/write-a-tool/#make-a-side-effect-happen-once
174
174
  - `ctx.projectId()`, `ctx.orgId()`: the run's project, and its org (`null`
175
175
  when it has none). The runtime sets them from the run, never from the
176
176
  input. To check an id the input names, compare it with these.
@@ -217,6 +217,34 @@ every variable it doesn't declare is dropped before your code loads
217
217
  (`kindgi dev` keeps them), so an undeclared one works locally and is unset
218
218
  once deployed. `KINDGI_*` names are Kindgi's own: a pack can't declare one.
219
219
 
220
+ ### Connections to other apps
221
+
222
+ A tool that acts in another app as a person or as the company (sending mail, opening an issue) declares a **connection**, never a secret holding someone's token, and reads the call's short-lived token from `ctx.connections()` (runtime 0.2.0 or later):
223
+
224
+ ```java
225
+ public static final Tool<Input, Output> TOOL = Tool.define("my-pack.send-mail")
226
+ // …description, version, input, output, effects…
227
+ .set("needsSpec", Map.of("connections", Map.of(
228
+ "mail", Map.of("app", "google", "permissions", List.of("gmail.send"), "as", "person"))))
229
+ .handler((input, ctx) -> {
230
+ ToolConnection mail = ctx.connections().get("mail");
231
+ HttpResponse<String> res = http.send(
232
+ HttpRequest.newBuilder(uri).header("authorization", "Bearer " + mail.accessToken()).build(),
233
+ HttpResponse.BodyHandlers.ofString());
234
+ if (res.statusCode() == 401) throw new ConnectionRejectedException("mail");
235
+ // …
236
+ });
237
+ ```
238
+
239
+ - **Whose connection:** `"as", "person"` is the connection of the person the run acts as (whoever started it, or the owner of the schedule or webhook that did); `"as", "company"` is the company's. The runtime picks it from the run, never from the input or the model. A run that acts as nobody (a service account's, an event's) fails a `"person"` call with `connection-needs-a-person`.
240
+ - **The token:** `accessToken()` is current for this call only. Never keep, print, log or return it; it never reaches the journal. `account().label()` says whose account it is (`ana@acme.com`).
241
+ - **A 401 from the app:** `throw new ConnectionRejectedException("mail")`, with the connection's name (a second argument can say what the app answered, never the token), or your own exception with it as the cause. The runtime renews the token once and runs the call again; refused again, the call fails with `connection-rejected`.
242
+ - **An HTTP tool** sends the token with no code: `.authorization(new HttpAuthSpec.Connection("mail"))`.
243
+ - **Unattended runs:** in a run no person started, a tool that uses a `"person"` connection waits for that person's yes, reads included: `.mutating(false)` doesn't lift it. The agent's own approval settings can't lift it; only a trigger's `toolsAllowedUnattended` can, which a project admin sets, as for `needsApprovalWhenUnattended` (below). In a run a new mail started, the mail is a stranger's text, so two more calls wait: a call of a tool that isn't `.mutating(false)`, and, when the trigger reads the company's mailbox, a read with the company's connection to that app. The mail trigger's `toolsAllowedUnattended` lifts these too.
244
+ - **In a unit test:** `ToolContext.forTest(Map.of("mail", new ToolConnection("c-1", "google", "Google", "test", new ConnectionAccount("1", "ana@acme.com"), null)))`; the last argument, when the token expires, can be `null`. `ctx.connections()` is empty when the tool declares none.
245
+
246
+ Docs: https://docs.kindgi.com/v0.2/guides/connections/use-a-connection/
247
+
220
248
  ## Errors and output
221
249
 
222
250
  - Throw for a failure: the call fails with `handler-throw` and the
@@ -237,6 +265,10 @@ the tool's approval default: an agent that turns approval gates on
237
265
  (`conversationPolicy.hitl`) asks before any tool that isn't read-only on its
238
266
  first use.
239
267
 
268
+ In a run a new mail started, a call of a tool that isn't read-only waits
269
+ for a person's yes, unless the mail trigger's `toolsAllowedUnattended`
270
+ lists it.
271
+
240
272
  `effect(kind, resource)` declares a side effect, such as
241
273
  `.effect("writes", "db:ledger")`. A dry run also stops at a tool with a
242
274
  `writes`, `deletes`, `spawns-run`, `emits-event` or `external-side-effect`
@@ -244,15 +276,65 @@ effect. `set(field, value)` sets the index entry's other fields: `needs`,
244
276
  `needsSpec`, `sandbox`, `limits`, `network`. They are recorded for policy and
245
277
  review, so declare what the tool really does.
246
278
 
247
- Java has no HTTP-tool form (TypeScript's `kind: 'http'`). A tool that calls
248
- an HTTP API is a handler with `java.net.http.HttpClient`, as above.
279
+ A tool that calls an HTTP API can be a handler with `java.net.http.HttpClient`,
280
+ as above, or the request declared as data with no handler — see **HTTP tool (as
281
+ data)** below.
282
+
283
+ ## HTTP tool (as data)
284
+
285
+ A tool that calls an HTTP API can be the request itself, declared as data,
286
+ instead of a handler: `.http(spec)` in place of `.handler(...)`. The Kindgi
287
+ runtime makes the request from the spec — the SDK only builds and validates it,
288
+ so calling such a tool in this JVM throws. Build the spec with
289
+ `HttpToolSpec.builder()` (package `com.kindgi.pack.http`):
290
+
291
+ ```java
292
+ import com.kindgi.pack.Tool;
293
+ import com.kindgi.pack.http.HttpAuthSpec;
294
+ import com.kindgi.pack.http.HttpMethod;
295
+ import com.kindgi.pack.http.HttpToolSpec;
296
+ import com.kindgi.pack.http.ToolSecretRef;
297
+
298
+ public record FetchOrder(String orderId) {}
299
+
300
+ public record Order(String id, String status, double total) {}
301
+
302
+ public static final Tool<FetchOrder, Order> TOOL =
303
+ Tool.define("shop.fetch-order")
304
+ .description("Fetch an order by id from the storefront API.")
305
+ .version("0.1.0")
306
+ .mutating(false)
307
+ .input(FetchOrder.class)
308
+ .output(Order.class)
309
+ .http(
310
+ HttpToolSpec.builder()
311
+ .method(HttpMethod.GET)
312
+ .urlTemplate("https://api.shop.example/orders/{orderId}")
313
+ .authorization(
314
+ new HttpAuthSpec.Bearer(new ToolSecretRef("production", "shop-api-token")))
315
+ .successStatus(200, 299)
316
+ .build());
317
+ ```
318
+
319
+ Every `{placeholder}` in the URL — in the path and query only, never in the
320
+ host or port — is a field of the input, and so is one in a
321
+ `HttpRequestBodySpec.Text` body; `.http(...)` throws if it isn't. Authorization
322
+ is a `secretRef` (`HttpAuthSpec.Bearer` or `HttpAuthSpec.Header`), named for the
323
+ runtime to resolve, never a literal credential. A request body is
324
+ `HttpRequestBodySpec.JsonInput` (the input as JSON), `InputPassthrough` or
325
+ `Text`. `timeoutMs` (default 30 seconds) covers the whole call, the response
326
+ read included, and a run's cancel does too; a response body over 10 MiB,
327
+ measured decompressed, fails the call — so point a tool at an endpoint that
328
+ pages or filters, not one that returns everything. Scala declares the same tool
329
+ the same way, with the same `HttpToolSpec`.
249
330
 
250
331
  ## A person's yes when no one is watching: `needsApprovalWhenUnattended`
251
332
 
252
- `needsApprovalWhenUnattended(true)` declares that a person must say yes to every call of the tool in a run no person started: one a schedule, a webhook, an event or a service account's key started. In such a run:
333
+ `needsApprovalWhenUnattended(true)` declares that a person must say yes to every call of the tool in a run no person started: one a schedule, a webhook, a new mail, an event or a service account's key started. In such a run:
253
334
 
254
335
  - **An agent's call waits** for a person's yes, whatever the agent's `conversationPolicy.hitl.tools` says. The agent's rules can't lift it: agents are reused, and the tool's author knows what it does.
255
336
  - **A flow's tool step that calls it is refused.** Put the tool behind an agent step instead, whose call waits.
337
+ - **A trigger can lift both, for its own runs only.** A project admin names the tool in a webhook trigger's, a schedule's or a mail trigger's `toolsAllowedUnattended` (`--allow-unattended=<tool-id>` on `kindgi webhooks`, `kindgi schedules` and `kindgi mail-triggers`). In that trigger's runs, the tool is then as in a run a person started. The tenant's approval rules still apply.
256
338
 
257
339
  In a run a person started (signed in, or with their own API key), the agent's rules decide, as for any tool. Left unset, it counts as `false`. Declare it on a tool that moves money or changes something people rely on:
258
340
 
@@ -262,17 +344,25 @@ In a run a person started (signed in, or with their own API key), the agent's ru
262
344
  .needsApprovalWhenUnattended(true)
263
345
  ```
264
346
 
265
- Docs: https://docs.kindgi.com/v0.1/guides/approvals/ask-before-a-tool-runs/#when-no-person-started-the-run
347
+ Docs: https://docs.kindgi.com/v0.2/guides/approvals/ask-before-a-tool-runs/#when-no-person-started-the-run
348
+
349
+ ## Results that are text from outside: `resultIsOutsideData`
350
+
351
+ `resultIsOutsideData(true)` says the tool's results are text from outside that nobody checked, such as a mail someone sent or a page a search found. An agent reads each result of the tool as data, not instructions, in that turn and in every later turn's history. It changes what the model is told, not what the tool may do: pair it with approvals for anything an agent could do with what it read. Absent means `false`.
266
352
 
267
353
  ## Testing
268
354
 
269
355
  `Tool.call(input, ctx)` runs the handler with the input as given (no schema
270
356
  check). `ToolContext.forTest()` is a context with a test tenant and run and
271
- nothing else; `new ToolContext(…)` builds one with secrets:
357
+ nothing else. `ToolContext.forTest(tool, env, secrets)` adds the env values
358
+ the tool declares in `needsSpec`, decided as a run decides them (a schema
359
+ `default` fills a name the test doesn't set, each value is checked, and a
360
+ missing or invalid one throws `IllegalArgumentException`), and the secrets as
361
+ given. `ToolContext.Builder` sets the rest:
272
362
 
273
363
  ```java
274
- ToolContext ctx = new ToolContext("t-test", "run-test", null, null, null,
275
- Map.of(), Map.of("CITATOR_KEY", "test-key-of-twenty-chars"), Map.of(), Map.of(), new Cancellation());
364
+ ToolContext ctx = ToolContext.forTest(new ToolContext.Builder()
365
+ .withSecrets(Map.of("CITATOR_KEY", "test-key-of-twenty-chars")));
276
366
  Greet.Output out = Greet.TOOL.call(new Greet.Input("Ada", "Hi"), ctx);
277
367
  ```
278
368
 
@@ -370,7 +460,7 @@ removed field, a narrower type), not on every save.
370
460
  folder, `~/.aws`) or any `.env*` file, and gets `EPERM` there. A tool that
371
461
  needs a path names it in `kindgi.config.json`: `"dev": {"sandbox": {"allowRead": ["~/.aws"]}}`.
372
462
  Never set `KINDGI_DEV_SANDBOX=off` or `dev.sandbox: false` to get past it
373
- (https://docs.kindgi.com/v0.1/guides/secrets/dev-sandbox/).
463
+ (https://docs.kindgi.com/v0.2/guides/secrets/dev-sandbox/).
374
464
 
375
465
  ## When the framework itself is the problem
376
466