@kindgi/cli 0.1.10 → 0.2.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (347) hide show
  1. package/README.md +78 -32
  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 +159 -34
  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.d.ts.map +1 -1
  55. package/dist/commands/doctor.js +8 -4
  56. package/dist/commands/doctor.js.map +1 -1
  57. package/dist/commands/env-scoped.d.ts.map +1 -1
  58. package/dist/commands/env-scoped.js +37 -22
  59. package/dist/commands/env-scoped.js.map +1 -1
  60. package/dist/commands/env.d.ts.map +1 -1
  61. package/dist/commands/env.js +35 -22
  62. package/dist/commands/env.js.map +1 -1
  63. package/dist/commands/eval-runs.js +6 -6
  64. package/dist/commands/eval-runs.js.map +1 -1
  65. package/dist/commands/eval-suites.js +9 -9
  66. package/dist/commands/eval-suites.js.map +1 -1
  67. package/dist/commands/exports.d.ts.map +1 -1
  68. package/dist/commands/exports.js +35 -9
  69. package/dist/commands/exports.js.map +1 -1
  70. package/dist/commands/feedback.d.ts.map +1 -1
  71. package/dist/commands/feedback.js +4 -3
  72. package/dist/commands/feedback.js.map +1 -1
  73. package/dist/commands/gate-policies.d.ts.map +1 -1
  74. package/dist/commands/gate-policies.js +7 -7
  75. package/dist/commands/gate-policies.js.map +1 -1
  76. package/dist/commands/helpers.d.ts +9 -0
  77. package/dist/commands/helpers.d.ts.map +1 -1
  78. package/dist/commands/helpers.js +20 -0
  79. package/dist/commands/helpers.js.map +1 -1
  80. package/dist/commands/index.d.ts.map +1 -1
  81. package/dist/commands/index.js +8 -0
  82. package/dist/commands/index.js.map +1 -1
  83. package/dist/commands/init.d.ts +1 -1
  84. package/dist/commands/init.d.ts.map +1 -1
  85. package/dist/commands/init.js +57 -45
  86. package/dist/commands/init.js.map +1 -1
  87. package/dist/commands/judge-classes.js +4 -4
  88. package/dist/commands/judge-classes.js.map +1 -1
  89. package/dist/commands/judging-queue.d.ts +3 -0
  90. package/dist/commands/judging-queue.d.ts.map +1 -0
  91. package/dist/commands/judging-queue.js +105 -0
  92. package/dist/commands/judging-queue.js.map +1 -0
  93. package/dist/commands/judging-rules.d.ts +3 -0
  94. package/dist/commands/judging-rules.d.ts.map +1 -0
  95. package/dist/commands/judging-rules.js +351 -0
  96. package/dist/commands/judging-rules.js.map +1 -0
  97. package/dist/commands/judgments.d.ts.map +1 -1
  98. package/dist/commands/judgments.js +78 -36
  99. package/dist/commands/judgments.js.map +1 -1
  100. package/dist/commands/key.d.ts.map +1 -1
  101. package/dist/commands/key.js +107 -9
  102. package/dist/commands/key.js.map +1 -1
  103. package/dist/commands/license.d.ts.map +1 -1
  104. package/dist/commands/license.js +80 -23
  105. package/dist/commands/license.js.map +1 -1
  106. package/dist/commands/mcp.d.ts.map +1 -1
  107. package/dist/commands/mcp.js +4 -4
  108. package/dist/commands/mcp.js.map +1 -1
  109. package/dist/commands/people.js +8 -14
  110. package/dist/commands/people.js.map +1 -1
  111. package/dist/commands/promote.js +1 -1
  112. package/dist/commands/promote.js.map +1 -1
  113. package/dist/commands/proposals.d.ts.map +1 -1
  114. package/dist/commands/proposals.js +83 -30
  115. package/dist/commands/proposals.js.map +1 -1
  116. package/dist/commands/run-waits.d.ts +68 -19
  117. package/dist/commands/run-waits.d.ts.map +1 -1
  118. package/dist/commands/run-waits.js +82 -8
  119. package/dist/commands/run-waits.js.map +1 -1
  120. package/dist/commands/runs.d.ts.map +1 -1
  121. package/dist/commands/runs.js +70 -30
  122. package/dist/commands/runs.js.map +1 -1
  123. package/dist/commands/schedules.d.ts.map +1 -1
  124. package/dist/commands/schedules.js +35 -12
  125. package/dist/commands/schedules.js.map +1 -1
  126. package/dist/commands/secrets-copy.d.ts.map +1 -1
  127. package/dist/commands/secrets-copy.js +20 -12
  128. package/dist/commands/secrets-copy.js.map +1 -1
  129. package/dist/commands/secrets.d.ts.map +1 -1
  130. package/dist/commands/secrets.js +13 -8
  131. package/dist/commands/secrets.js.map +1 -1
  132. package/dist/commands/sign-in.js +2 -2
  133. package/dist/commands/sign-in.js.map +1 -1
  134. package/dist/commands/sites.d.ts.map +1 -1
  135. package/dist/commands/sites.js +13 -6
  136. package/dist/commands/sites.js.map +1 -1
  137. package/dist/commands/skills.d.ts +54 -3
  138. package/dist/commands/skills.d.ts.map +1 -1
  139. package/dist/commands/skills.js +169 -38
  140. package/dist/commands/skills.js.map +1 -1
  141. package/dist/commands/tokens.d.ts.map +1 -1
  142. package/dist/commands/tokens.js +9 -1
  143. package/dist/commands/tokens.js.map +1 -1
  144. package/dist/commands/upgrade.d.ts.map +1 -1
  145. package/dist/commands/upgrade.js +9 -8
  146. package/dist/commands/upgrade.js.map +1 -1
  147. package/dist/commands/webhooks.d.ts.map +1 -1
  148. package/dist/commands/webhooks.js +62 -24
  149. package/dist/commands/webhooks.js.map +1 -1
  150. package/dist/config.d.ts +6 -0
  151. package/dist/config.d.ts.map +1 -1
  152. package/dist/config.js +18 -3
  153. package/dist/config.js.map +1 -1
  154. package/dist/context.d.ts +12 -0
  155. package/dist/context.d.ts.map +1 -1
  156. package/dist/context.js +2 -0
  157. package/dist/context.js.map +1 -1
  158. package/dist/deploy/pack-blocks-gate.d.ts +12 -0
  159. package/dist/deploy/pack-blocks-gate.d.ts.map +1 -0
  160. package/dist/deploy/pack-blocks-gate.js +34 -0
  161. package/dist/deploy/pack-blocks-gate.js.map +1 -0
  162. package/dist/deploy/post.d.ts +9 -0
  163. package/dist/deploy/post.d.ts.map +1 -1
  164. package/dist/deploy/post.js +20 -3
  165. package/dist/deploy/post.js.map +1 -1
  166. package/dist/dev/defaults.d.ts.map +1 -1
  167. package/dist/dev/defaults.js +8 -1
  168. package/dist/dev/defaults.js.map +1 -1
  169. package/dist/dev/dev-only-imports.d.ts +7 -4
  170. package/dist/dev/dev-only-imports.d.ts.map +1 -1
  171. package/dist/dev/dev-only-imports.js +5 -5
  172. package/dist/dev/dev-only-imports.js.map +1 -1
  173. package/dist/dev/log-view.d.ts +4 -4
  174. package/dist/dev/log-view.d.ts.map +1 -1
  175. package/dist/dev/log-view.js +4 -4
  176. package/dist/dev/log-view.js.map +1 -1
  177. package/dist/dev/pack-service.d.ts +7 -1
  178. package/dist/dev/pack-service.d.ts.map +1 -1
  179. package/dist/dev/pack-service.js +36 -3
  180. package/dist/dev/pack-service.js.map +1 -1
  181. package/dist/dev/preview-expiry.d.ts +6 -7
  182. package/dist/dev/preview-expiry.d.ts.map +1 -1
  183. package/dist/dev/preview-expiry.js +7 -8
  184. package/dist/dev/preview-expiry.js.map +1 -1
  185. package/dist/dev/providers.d.ts +2 -1
  186. package/dist/dev/providers.d.ts.map +1 -1
  187. package/dist/dev/providers.js +28 -12
  188. package/dist/dev/providers.js.map +1 -1
  189. package/dist/dev/runners.d.ts +19 -0
  190. package/dist/dev/runners.d.ts.map +1 -1
  191. package/dist/dev/runtime-container.js +2 -3
  192. package/dist/dev/runtime-container.js.map +1 -1
  193. package/dist/dev/runtime-env.d.ts +2 -1
  194. package/dist/dev/runtime-env.d.ts.map +1 -1
  195. package/dist/dev/runtime-env.js +5 -5
  196. package/dist/dev/runtime-env.js.map +1 -1
  197. package/dist/dev/runtime-image.d.ts +14 -4
  198. package/dist/dev/runtime-image.d.ts.map +1 -1
  199. package/dist/dev/runtime-image.js +16 -4
  200. package/dist/dev/runtime-image.js.map +1 -1
  201. package/dist/dev/runtime-registry.d.ts +10 -2
  202. package/dist/dev/runtime-registry.d.ts.map +1 -1
  203. package/dist/dev/runtime-registry.js +30 -6
  204. package/dist/dev/runtime-registry.js.map +1 -1
  205. package/dist/dev/sandbox/index.js +1 -1
  206. package/dist/dev/sandbox/notices.d.ts +2 -0
  207. package/dist/dev/sandbox/notices.d.ts.map +1 -1
  208. package/dist/dev/sandbox/notices.js +5 -2
  209. package/dist/dev/sandbox/notices.js.map +1 -1
  210. package/dist/env/defaults.d.ts.map +1 -1
  211. package/dist/env/defaults.js +3 -1
  212. package/dist/env/defaults.js.map +1 -1
  213. package/dist/env/pack-env-plan.d.ts +4 -0
  214. package/dist/env/pack-env-plan.d.ts.map +1 -1
  215. package/dist/env/pack-env-plan.js +8 -2
  216. package/dist/env/pack-env-plan.js.map +1 -1
  217. package/dist/exports/create.d.ts +2 -0
  218. package/dist/exports/create.d.ts.map +1 -1
  219. package/dist/exports/create.js +10 -2
  220. package/dist/exports/create.js.map +1 -1
  221. package/dist/exports/plan.d.ts.map +1 -1
  222. package/dist/exports/plan.js +20 -0
  223. package/dist/exports/plan.js.map +1 -1
  224. package/dist/feedback/store.d.ts.map +1 -1
  225. package/dist/feedback/store.js +8 -19
  226. package/dist/feedback/store.js.map +1 -1
  227. package/dist/help.d.ts +6 -0
  228. package/dist/help.d.ts.map +1 -1
  229. package/dist/help.js +35 -1
  230. package/dist/help.js.map +1 -1
  231. package/dist/init/agent-access.d.ts +3 -2
  232. package/dist/init/agent-access.d.ts.map +1 -1
  233. package/dist/init/agent-access.js +5 -1
  234. package/dist/init/agent-access.js.map +1 -1
  235. package/dist/init/augment-scaffolder.d.ts +7 -0
  236. package/dist/init/augment-scaffolder.d.ts.map +1 -1
  237. package/dist/init/augment-scaffolder.js +15 -14
  238. package/dist/init/augment-scaffolder.js.map +1 -1
  239. package/dist/init/dependency-specs.d.ts +1 -0
  240. package/dist/init/dependency-specs.d.ts.map +1 -1
  241. package/dist/init/dependency-specs.js +27 -7
  242. package/dist/init/dependency-specs.js.map +1 -1
  243. package/dist/init/java-augment.d.ts +3 -0
  244. package/dist/init/java-augment.d.ts.map +1 -1
  245. package/dist/init/java-augment.js +16 -15
  246. package/dist/init/java-augment.js.map +1 -1
  247. package/dist/init/python-augment.d.ts +3 -0
  248. package/dist/init/python-augment.d.ts.map +1 -1
  249. package/dist/init/python-augment.js +15 -14
  250. package/dist/init/python-augment.js.map +1 -1
  251. package/dist/init/scala-augment.d.ts +8 -1
  252. package/dist/init/scala-augment.d.ts.map +1 -1
  253. package/dist/init/scala-augment.js +32 -17
  254. package/dist/init/scala-augment.js.map +1 -1
  255. package/dist/key/defaults.d.ts.map +1 -1
  256. package/dist/key/defaults.js +6 -1
  257. package/dist/key/defaults.js.map +1 -1
  258. package/dist/key/runners.d.ts +4 -1
  259. package/dist/key/runners.d.ts.map +1 -1
  260. package/dist/license/protocol.d.ts +3 -2
  261. package/dist/license/protocol.d.ts.map +1 -1
  262. package/dist/license/protocol.js +3 -2
  263. package/dist/license/protocol.js.map +1 -1
  264. package/dist/license/renew.d.ts +6 -0
  265. package/dist/license/renew.d.ts.map +1 -1
  266. package/dist/license/renew.js +9 -6
  267. package/dist/license/renew.js.map +1 -1
  268. package/dist/main.d.ts +10 -0
  269. package/dist/main.d.ts.map +1 -1
  270. package/dist/main.js +19 -5
  271. package/dist/main.js.map +1 -1
  272. package/dist/output.d.ts +6 -0
  273. package/dist/output.d.ts.map +1 -1
  274. package/dist/output.js +8 -0
  275. package/dist/output.js.map +1 -1
  276. package/dist/parse.d.ts +1 -1
  277. package/dist/parse.d.ts.map +1 -1
  278. package/dist/parse.js +1 -1
  279. package/dist/parse.js.map +1 -1
  280. package/dist/private-file.d.ts +23 -0
  281. package/dist/private-file.d.ts.map +1 -0
  282. package/dist/private-file.js +65 -0
  283. package/dist/private-file.js.map +1 -0
  284. package/dist/progress-head.d.ts +13 -0
  285. package/dist/progress-head.d.ts.map +1 -0
  286. package/dist/progress-head.js +30 -0
  287. package/dist/progress-head.js.map +1 -0
  288. package/dist/progress-lines.d.ts +29 -0
  289. package/dist/progress-lines.d.ts.map +1 -0
  290. package/dist/progress-lines.js +35 -0
  291. package/dist/progress-lines.js.map +1 -0
  292. package/dist/sdk-skills/kindgi-authoring-agents/SKILL.md +6 -6
  293. package/dist/sdk-skills/kindgi-authoring-flows/SKILL.md +1 -1
  294. package/dist/sdk-skills/kindgi-authoring-guardrails/SKILL.md +2 -2
  295. package/dist/sdk-skills/kindgi-authoring-mcp-servers/SKILL.md +1 -1
  296. package/dist/sdk-skills/kindgi-authoring-providers/SKILL.md +3 -3
  297. package/dist/sdk-skills/kindgi-authoring-tools/SKILL.md +39 -6
  298. package/dist/sdk-skills/kindgi-fix-corrections/SKILL.md +262 -0
  299. package/dist/sdk-skills/kindgi-framework-feedback/SKILL.md +1 -1
  300. package/dist/sdk-skills/kindgi-getting-started/SKILL.md +43 -9
  301. package/dist/sdk-skills/kindgi-java-authoring-agents/SKILL.md +5 -5
  302. package/dist/sdk-skills/kindgi-java-authoring-flows/SKILL.md +1 -1
  303. package/dist/sdk-skills/kindgi-java-authoring-guardrails/SKILL.md +1 -1
  304. package/dist/sdk-skills/kindgi-java-authoring-tools/SKILL.md +91 -9
  305. package/dist/sdk-skills/kindgi-java-getting-started/SKILL.md +38 -9
  306. package/dist/sdk-skills/kindgi-python-authoring-agents/SKILL.md +4 -4
  307. package/dist/sdk-skills/kindgi-python-authoring-flows/SKILL.md +1 -1
  308. package/dist/sdk-skills/kindgi-python-authoring-guardrails/SKILL.md +1 -1
  309. package/dist/sdk-skills/kindgi-python-authoring-tools/SKILL.md +43 -8
  310. package/dist/sdk-skills/kindgi-python-getting-started/SKILL.md +39 -11
  311. package/dist/sdk-skills/kindgi-scala-authoring-agents/SKILL.md +5 -5
  312. package/dist/sdk-skills/kindgi-scala-authoring-flows/SKILL.md +1 -1
  313. package/dist/sdk-skills/kindgi-scala-authoring-guardrails/SKILL.md +1 -1
  314. package/dist/sdk-skills/kindgi-scala-authoring-tools/SKILL.md +82 -7
  315. package/dist/sdk-skills/kindgi-scala-getting-started/SKILL.md +38 -9
  316. package/dist/sdk-skills/kindgi-using/SKILL.md +50 -21
  317. package/dist/templates/drupal/AGENTS.md +2 -1
  318. package/dist/templates/follow-up/.nvmrc +1 -0
  319. package/dist/templates/follow-up/AGENTS.md +83 -0
  320. package/dist/templates/follow-up/README.md.tmpl +111 -0
  321. package/dist/templates/follow-up/agents/follow-up/index.test.ts.tmpl +26 -0
  322. package/dist/templates/follow-up/agents/follow-up/index.ts.tmpl +53 -0
  323. package/dist/templates/follow-up/gitignore +8 -0
  324. package/dist/templates/follow-up/kindgi.config.ts.tmpl +45 -0
  325. package/dist/templates/follow-up/package.json.tmpl +30 -0
  326. package/dist/templates/follow-up/pnpm-workspace.yaml +9 -0
  327. package/dist/templates/follow-up/tools/gmail-send/index.test.ts.tmpl +60 -0
  328. package/dist/templates/follow-up/tools/gmail-send/index.ts.tmpl +14 -0
  329. package/dist/templates/follow-up/tsconfig.json.tmpl +27 -0
  330. package/dist/templates/follow-up/vitest.config.ts.tmpl +14 -0
  331. package/dist/templates/java/AGENTS.md +2 -1
  332. package/dist/templates/minimal/AGENTS.md +2 -1
  333. package/dist/templates/python/AGENTS.md +2 -1
  334. package/dist/templates/sample/AGENTS.md +2 -1
  335. package/dist/templates/scala/AGENTS.md +2 -1
  336. package/dist/templates/woocommerce/AGENTS.md +12 -3
  337. package/dist/templates/woocommerce/README.md.tmpl +29 -5
  338. package/dist/templates/woocommerce/agents/store-agent/index.test.ts.tmpl +38 -7
  339. package/dist/templates/woocommerce/agents/store-agent/index.ts.tmpl +7 -12
  340. package/dist/templates/woocommerce/blocks/store-agent-prompt.json.tmpl +10 -0
  341. package/dist/templates/woocommerce/blocks/store-agent-prompt.liquid.tmpl +7 -0
  342. package/dist/templates/woocommerce/kindgi.config.ts.tmpl +1 -0
  343. package/dist/value-target.d.ts +4 -2
  344. package/dist/value-target.d.ts.map +1 -1
  345. package/dist/value-target.js +8 -5
  346. package/dist/value-target.js.map +1 -1
  347. package/package.json +13 -13
@@ -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.10"
19
+ version: "0.3.16"
20
+ sdk_version: "0.2.0-rc.0"
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,32 @@ 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. The module
350
+ README's Upgrading section has the rest:
351
+ https://github.com/kindgi/kindgi-sdk/tree/main/deploy/gcp-cloud-run#upgrading
352
+ - **Any other Cloud Run deployment, or one on Azure Container Apps:** the
353
+ "Operate it" section of its page,
354
+ https://docs.kindgi.com/v0.2/deploy/self-hosted/cloud-run/#operate-it or
355
+ https://docs.kindgi.com/v0.2/deploy/self-hosted/azure-container-apps/#operate-it.
356
+ - **Otherwise:** the operate page's upgrade steps,
357
+ https://docs.kindgi.com/v0.2/deploy/self-hosted/operate/#upgrade-the-runtime.
358
+
359
+ An upgrade changes a running deployment: give the person the commands to run
360
+ in their own terminal (`./upgrade.sh` waits for them to type `yes`).
327
361
 
328
362
  ## References
329
363
 
@@ -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.10"
19
+ sdk_version: "0.2.0-rc.0"
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.10"
19
+ sdk_version: "0.2.0-rc.0"
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.10"
20
+ sdk_version: "0.2.0-rc.0"
21
21
  pack_languages: [java]
22
22
  sources:
23
23
  - sdks/java/kindgi-pack/README.md
@@ -15,7 +15,7 @@ description: >
15
15
  type: core
16
16
  library: "kindgi-pack (Java)"
17
17
  version: "0.1.3"
18
- sdk_version: "0.1.10"
18
+ sdk_version: "0.2.0-rc.0"
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, unless it's marked `.mutating(false)` (mark read-only tools so). 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).
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
@@ -244,8 +272,57 @@ effect. `set(field, value)` sets the index entry's other fields: `needs`,
244
272
  `needsSpec`, `sandbox`, `limits`, `network`. They are recorded for policy and
245
273
  review, so declare what the tool really does.
246
274
 
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.
275
+ A tool that calls an HTTP API can be a handler with `java.net.http.HttpClient`,
276
+ as above, or the request declared as data with no handler — see **HTTP tool (as
277
+ data)** below.
278
+
279
+ ## HTTP tool (as data)
280
+
281
+ A tool that calls an HTTP API can be the request itself, declared as data,
282
+ instead of a handler: `.http(spec)` in place of `.handler(...)`. The Kindgi
283
+ runtime makes the request from the spec — the SDK only builds and validates it,
284
+ so calling such a tool in this JVM throws. Build the spec with
285
+ `HttpToolSpec.builder()` (package `com.kindgi.pack.http`):
286
+
287
+ ```java
288
+ import com.kindgi.pack.Tool;
289
+ import com.kindgi.pack.http.HttpAuthSpec;
290
+ import com.kindgi.pack.http.HttpMethod;
291
+ import com.kindgi.pack.http.HttpToolSpec;
292
+ import com.kindgi.pack.http.ToolSecretRef;
293
+
294
+ public record FetchOrder(String orderId) {}
295
+
296
+ public record Order(String id, String status, double total) {}
297
+
298
+ public static final Tool<FetchOrder, Order> TOOL =
299
+ Tool.define("shop.fetch-order")
300
+ .description("Fetch an order by id from the storefront API.")
301
+ .version("0.1.0")
302
+ .mutating(false)
303
+ .input(FetchOrder.class)
304
+ .output(Order.class)
305
+ .http(
306
+ HttpToolSpec.builder()
307
+ .method(HttpMethod.GET)
308
+ .urlTemplate("https://api.shop.example/orders/{orderId}")
309
+ .authorization(
310
+ new HttpAuthSpec.Bearer(new ToolSecretRef("production", "shop-api-token")))
311
+ .successStatus(200, 299)
312
+ .build());
313
+ ```
314
+
315
+ Every `{placeholder}` in the URL — in the path and query only, never in the
316
+ host or port — is a field of the input, and so is one in a
317
+ `HttpRequestBodySpec.Text` body; `.http(...)` throws if it isn't. Authorization
318
+ is a `secretRef` (`HttpAuthSpec.Bearer` or `HttpAuthSpec.Header`), named for the
319
+ runtime to resolve, never a literal credential. A request body is
320
+ `HttpRequestBodySpec.JsonInput` (the input as JSON), `InputPassthrough` or
321
+ `Text`. `timeoutMs` (default 30 seconds) covers the whole call, the response
322
+ read included, and a run's cancel does too; a response body over 10 MiB,
323
+ measured decompressed, fails the call — so point a tool at an endpoint that
324
+ pages or filters, not one that returns everything. Scala declares the same tool
325
+ the same way, with the same `HttpToolSpec`.
249
326
 
250
327
  ## A person's yes when no one is watching: `needsApprovalWhenUnattended`
251
328
 
@@ -253,6 +330,7 @@ an HTTP API is a handler with `java.net.http.HttpClient`, as above.
253
330
 
254
331
  - **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
332
  - **A flow's tool step that calls it is refused.** Put the tool behind an agent step instead, whose call waits.
333
+ - **A trigger can lift both, for its own runs only.** A project admin names the tool in a webhook trigger's or a schedule's `toolsAllowedUnattended` (`--allow-unattended=<tool-id>` on `kindgi webhooks` and `kindgi schedules`). In that trigger's runs, the tool is then as in a run a person started. The tenant's approval rules still apply.
256
334
 
257
335
  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
336
 
@@ -262,17 +340,21 @@ In a run a person started (signed in, or with their own API key), the agent's ru
262
340
  .needsApprovalWhenUnattended(true)
263
341
  ```
264
342
 
265
- Docs: https://docs.kindgi.com/v0.1/guides/approvals/ask-before-a-tool-runs/#when-no-person-started-the-run
343
+ Docs: https://docs.kindgi.com/v0.2/guides/approvals/ask-before-a-tool-runs/#when-no-person-started-the-run
266
344
 
267
345
  ## Testing
268
346
 
269
347
  `Tool.call(input, ctx)` runs the handler with the input as given (no schema
270
348
  check). `ToolContext.forTest()` is a context with a test tenant and run and
271
- nothing else; `new ToolContext(…)` builds one with secrets:
349
+ nothing else. `ToolContext.forTest(tool, env, secrets)` adds the env values
350
+ the tool declares in `needsSpec`, decided as a run decides them (a schema
351
+ `default` fills a name the test doesn't set, each value is checked, and a
352
+ missing or invalid one throws `IllegalArgumentException`), and the secrets as
353
+ given. `ToolContext.Builder` sets the rest:
272
354
 
273
355
  ```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());
356
+ ToolContext ctx = ToolContext.forTest(new ToolContext.Builder()
357
+ .withSecrets(Map.of("CITATOR_KEY", "test-key-of-twenty-chars")));
276
358
  Greet.Output out = Greet.TOOL.call(new Greet.Input("Ada", "Hi"), ctx);
277
359
  ```
278
360
 
@@ -370,7 +452,7 @@ removed field, a narrower type), not on every save.
370
452
  folder, `~/.aws`) or any `.env*` file, and gets `EPERM` there. A tool that
371
453
  needs a path names it in `kindgi.config.json`: `"dev": {"sandbox": {"allowRead": ["~/.aws"]}}`.
372
454
  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/).
455
+ (https://docs.kindgi.com/v0.2/guides/secrets/dev-sandbox/).
374
456
 
375
457
  ## When the framework itself is the problem
376
458
 
@@ -10,14 +10,15 @@ description: >
10
10
  `kindgi.config.json` yet and the user asks to "add Kindgi", "make an
11
11
  agent", "set up a pack", or when you are orienting in a Java pack
12
12
  (`kindgi.config.json` with `"language": "java"`) for the first time.
13
- Authoring tools, guardrails, agents and flows is covered by
14
- kindgi-java-authoring-tools, kindgi-java-authoring-guardrails,
15
- kindgi-java-authoring-agents and kindgi-java-authoring-flows; models by
16
- kindgi-authoring-providers.
13
+ Load it too when upgrading a self-hosted deployment, or when asked for
14
+ a migration script (there is none). Authoring tools, guardrails, agents
15
+ and flows is covered by kindgi-java-authoring-tools,
16
+ kindgi-java-authoring-guardrails, kindgi-java-authoring-agents and
17
+ kindgi-java-authoring-flows; models by kindgi-authoring-providers.
17
18
  type: core
18
19
  library: "kindgi-pack (Java)"
19
- version: "0.1.3"
20
- sdk_version: "0.1.10"
20
+ version: "0.1.4"
21
+ sdk_version: "0.2.0-rc.0"
21
22
  pack_languages: [java]
22
23
  sources:
23
24
  - sdks/java/kindgi-pack/README.md
@@ -64,7 +65,7 @@ You need a JDK 17 or later (`JAVA_HOME`). Maven comes with the pack
64
65
  (`./mvnw`).
65
66
 
66
67
  ```sh
67
- npx --yes @kindgi/cli@0.1 init my-pack --template=java # or: uvx --from "kindgi-cli>=0.1,<0.2" kindgi init …
68
+ npx --yes @kindgi/cli@0.2 init my-pack --template=java # or: uvx --from "kindgi-cli>=0.2,<0.3" kindgi init …
68
69
  cd my-pack
69
70
  ./mvnw test # the template's tests: the tools, called directly
70
71
  ./kindgiw dev # boots Kindgi locally and runs this pack, recompiling on save
@@ -88,7 +89,7 @@ reported as `file:line:col`, and the last good code keeps serving.
88
89
  In the app's directory (where its `pom.xml` is):
89
90
 
90
91
  ```sh
91
- npx --yes @kindgi/cli@0.1 init # --pack-id=<id> if the app's artifactId doesn't make one
92
+ npx --yes @kindgi/cli@0.2 init # --pack-id=<id> if the app's artifactId doesn't make one
92
93
  ./kindgiw dev
93
94
  ```
94
95
 
@@ -235,7 +236,7 @@ Show it in the app's own UI. **Never:**
235
236
  gives no database access.
236
237
  - **link users to Kindgi's console**, or any Kindgi UI, for this data.
237
238
 
238
- Docs: https://docs.kindgi.com/v0.1/guides/runs/show-runs-in-your-app/
239
+ Docs: https://docs.kindgi.com/v0.2/guides/runs/show-runs-in-your-app/
239
240
 
240
241
  ## Build an image
241
242
 
@@ -254,6 +255,34 @@ deployed pack service missing a required one isn't ready, and its `/readyz`
254
255
  names it; one the pack doesn't declare is dropped before the code loads
255
256
  (`kindgi dev` keeps it).
256
257
 
258
+ ## Upgrading a deployment
259
+
260
+ There's no migration script, and none to write: a self-hosted runtime brings
261
+ its database up to date when it starts, applying the migrations the database
262
+ doesn't have yet, then serving. Migrations only go forward: an upgrade
263
+ starts with a backup of the database, and going back means restoring it and
264
+ running the older version on it.
265
+
266
+ - **On Cloud Run, a small dev deployment** (`network_mode = "none"`, on
267
+ runtime 0.1.8 or later): the Cloud Run module's `./upgrade.sh`, as of the
268
+ `@kindgi/sdk@<version>` tag of the release you're upgrading to, since it
269
+ knows the steps up to its own release. Run `./upgrade.sh --dry-run` first:
270
+ it changes nothing, and lists what a real run would change. The module
271
+ README's Upgrading section has the rest:
272
+ https://github.com/kindgi/kindgi-sdk/tree/main/deploy/gcp-cloud-run#upgrading
273
+ - **Any other Cloud Run deployment, or one on Azure Container Apps:** the
274
+ "Operate it" section of its page,
275
+ https://docs.kindgi.com/v0.2/deploy/self-hosted/cloud-run/#operate-it or
276
+ https://docs.kindgi.com/v0.2/deploy/self-hosted/azure-container-apps/#operate-it.
277
+ - **Otherwise:** the operate page's upgrade steps,
278
+ https://docs.kindgi.com/v0.2/deploy/self-hosted/operate/#upgrade-the-runtime.
279
+
280
+ An upgrade changes a running deployment: give the person the commands to run
281
+ in their own terminal (`./upgrade.sh` waits for them to type `yes`).
282
+
283
+ Not `./kindgiw upgrade`: that moves the pack's own pins (the CLI's and
284
+ kindgi-pack's), not a deployment's runtime.
285
+
257
286
  ## Two things need the human
258
287
 
259
288
  - **The pack id and version** in `kindgi.config.json`. The id prefixes every
@@ -16,7 +16,7 @@ description: >
16
16
  type: core
17
17
  library: "kindgi (Python)"
18
18
  version: "0.1.7"
19
- sdk_version: "0.1.10"
19
+ sdk_version: "0.2.0-rc.0"
20
20
  pack_languages: [python]
21
21
  sources:
22
22
  - sdks/python/src/kindgi/pack/define.py
@@ -142,8 +142,8 @@ brief_writer = Agent(
142
142
  loosen them. `"separateApprover"` in `hitl` (`True`, or
143
143
  `{"overrides": {"<tool id>": True}}`) makes a tool's approval need
144
144
  someone other than whoever asked.
145
- - **`budget`** — per turn: `maxSteps` (model calls, default 8),
146
- `maxCostUsd`, `maxWallMs` (default 120 000). Steps or cost exceeded
145
+ - **`budget`** — per turn: `maxSteps` (model calls, default 8, at most
146
+ 32), `maxCostUsd`, `maxWallMs` (default 120 000). Steps or cost exceeded
147
147
  fails the turn (`budget-exceeded`); out of wall time aborts it. Leave
148
148
  room for real models: a turn with tool calls can take tens of seconds.
149
149
  - **`output`** — a typed answer: a pydantic model class (or any type
@@ -182,7 +182,7 @@ brief_writer = Agent(
182
182
  one person, or instruction-like text, waits for a person's approval.
183
183
  Use a model with reliable tool calling. `{"instructionTypes":
184
184
  ["acme.policy"]}` makes a retrieved, verified fact of those types an
185
- instruction. See https://docs.kindgi.com/v0.1/guides/agents/give-an-agent-memory/.
185
+ instruction. See https://docs.kindgi.com/v0.2/guides/agents/give-an-agent-memory/.
186
186
 
187
187
  **In a run a webhook or an event started**, the turn's message is data:
188
188
  it arrives inside an `<event note="kindgi event: data, not
@@ -17,7 +17,7 @@ description: >
17
17
  type: core
18
18
  library: "kindgi (Python)"
19
19
  version: "0.1.2"
20
- sdk_version: "0.1.10"
20
+ sdk_version: "0.2.0-rc.0"
21
21
  pack_languages: [python]
22
22
  sources:
23
23
  - sdks/python/src/kindgi/pack/define.py
@@ -16,7 +16,7 @@ description: >
16
16
  type: core
17
17
  library: "kindgi (Python)"
18
18
  version: "0.1.5"
19
- sdk_version: "0.1.10"
19
+ sdk_version: "0.2.0-rc.0"
20
20
  pack_languages: [python]
21
21
  sources:
22
22
  - sdks/python/src/kindgi/pack/define.py
@@ -15,7 +15,7 @@ description: >
15
15
  type: core
16
16
  library: "kindgi (Python)"
17
17
  version: "0.1.5"
18
- sdk_version: "0.1.10"
18
+ sdk_version: "0.2.0-rc.0"
19
19
  pack_languages: [python]
20
20
  sources:
21
21
  - sdks/python/src/kindgi/pack/define.py
@@ -95,8 +95,10 @@ def verify_citation(citation: Citation, ctx: ToolContext) -> Verdict:
95
95
  field's path (a bad output as `output-validation-failed`); the agent's
96
96
  `tool_errors` policy decides whether the model gets to fix the call.
97
97
  - **Problems in the declaration** (a missing docstring, an
98
- unannotated parameter, a non-object input) raise `DefinitionError`
99
- where the tool is declared; the indexer reports it with the file.
98
+ unannotated parameter, a non-object input, or an input or output
99
+ schema the runtime's compile refuses, such as one with a keyword it
100
+ doesn't know) raise `DefinitionError` where the tool is declared; the
101
+ indexer reports it with the file.
100
102
 
101
103
  ## `ToolContext`
102
104
 
@@ -112,7 +114,7 @@ def verify_citation(citation: Citation, ctx: ToolContext) -> Verdict:
112
114
  system it writes to (an `Idempotency-Key` header, a client reference, a
113
115
  unique column) or looks for it there first: a refund never goes out
114
116
  twice. A UUID; `None` outside a run and from a runtime before 0.1.6.
115
- Docs: https://docs.kindgi.com/v0.1/guides/tools/write-a-tool/#make-a-side-effect-happen-once
117
+ Docs: https://docs.kindgi.com/v0.2/guides/tools/write-a-tool/#make-a-side-effect-happen-once
116
118
  - `ctx.project_id`, `ctx.org_id` — the run's project, and that project's
117
119
  org (`None` when it has none). The runtime sets them from the run, never
118
120
  from the input: to check an org or project id the input names, compare
@@ -136,7 +138,7 @@ def verify_citation(citation: Citation, ctx: ToolContext) -> Verdict:
136
138
  amounts and outcomes, never what a person typed (a refund's reason, a
137
139
  message, an address): the log is read by whoever operates the runtime.
138
140
  `ToolContext.for_test(…)` logs nothing unless you pass it `log=`. Docs:
139
- https://docs.kindgi.com/v0.1/guides/tools/write-a-tool/#log-from-a-tool
141
+ https://docs.kindgi.com/v0.2/guides/tools/write-a-tool/#log-from-a-tool
140
142
 
141
143
  ## Configuration and secrets
142
144
 
@@ -189,7 +191,7 @@ def find_order(lookup: Lookup, ctx: ToolContext) -> Found:
189
191
  precondition-failed: Tool "acme-orders.needs-account" was not run: env-value-missing: tool "acme-orders.needs-account" needs env value "ACME_ACCOUNT_ID" in env "local", and none is set for project e889c1f5-eae7-45dc-8669-5bd029a5d85c, its org, or the tenant. Set it: kindgi env set ACME_ACCOUNT_ID <value> --scope=project:e889c1f5-eae7-45dc-8669-5bd029a5d85c --env=local (or --scope=tenant, for every project)
190
192
  ```
191
193
  - **Not secret:** env values are recorded with each run that uses them and shown in its journal. A credential is a secret, never an env value.
192
- - **In a test:** `ToolContext.for_test(env={"ORDERS_BASE_URL": "…"})`.
194
+ - **In a test:** `ToolContext.for_test(tool=find_order, env={"ORDERS_BASE_URL": "…"})` decides them as a run does: a schema `default` fills a name the test doesn't set, each value is checked, and a missing or invalid one raises `ValueError`.
193
195
 
194
196
  Everything else comes from the process environment: `os.environ["CITATOR_URL"]`.
195
197
  The pack service runs with the pack's environment — in `kindgi dev`
@@ -207,6 +209,38 @@ the pack service drops every other variable before your code loads
207
209
  unset once deployed. `KINDGI_*` names are Kindgi's own settings: a pack
208
210
  can't declare one.
209
211
 
212
+ ### Connections to other apps
213
+
214
+ 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):
215
+
216
+ ```python
217
+ import httpx
218
+
219
+ from kindgi import ConnectionRejected, ToolContext, tool
220
+
221
+
222
+ @tool(
223
+ id="my-pack.send-mail",
224
+ needs_spec={"connections": {"mail": {"app": "google", "permissions": ["gmail.send"], "as": "person"}}},
225
+ )
226
+ def send_mail(message: Message, ctx: ToolContext) -> Sent:
227
+ """Sends a message from the person's mailbox."""
228
+ mail = ctx.connections["mail"]
229
+ res = httpx.get(url, headers={"authorization": f"Bearer {mail.access_token}"})
230
+ if res.status_code == 401:
231
+ raise ConnectionRejected("mail")
232
+ # …
233
+ ```
234
+
235
+ - **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`.
236
+ - **The token:** `access_token` 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`).
237
+ - **A 401 from the app:** `raise ConnectionRejected("mail")`, with the connection's name (a second argument can say what the app answered, never the token), or raise your own error `from` it. The runtime renews the token once and runs the call again; refused again, the call fails with `connection-rejected`.
238
+ - **An HTTP tool** sends the token with no code: `authorization={"kind": "connection", "connection": "mail"}`.
239
+ - **Unattended runs:** in a run no person started, a tool that uses a `"person"` connection waits for that person's yes, unless it's marked `mutating=False` (mark read-only tools so). The agent's own approval settings can't lift it; only a trigger's `toolsAllowedUnattended` can, which a project admin sets, as for `needs_approval_when_unattended` (below).
240
+ - **In a unit test:** `ToolContext.for_test(connections={"mail": ToolConnection(connection_id="c-1", app="google", app_name="Google", access_token="test", account=ConnectionAccount(id="1", label="ana@acme.com"))})`, all from `kindgi`. `ctx.connections` is empty when the tool declares none.
241
+
242
+ Docs: https://docs.kindgi.com/v0.2/guides/connections/use-a-connection/
243
+
210
244
  ## Errors and output
211
245
 
212
246
  - Raise an exception for a failure: the call fails with
@@ -248,6 +282,7 @@ policy and review; declare what the tool really does.
248
282
 
249
283
  - **An agent's call waits** for a person's yes, whatever the agent's `conversation_policy` says in `hitl["tools"]`. The agent's rules can't lift it: agents are reused, and the tool's author knows what it does.
250
284
  - **A flow's tool step that calls it is refused.** Put the tool behind an agent step instead, whose call waits.
285
+ - **A trigger can lift both, for its own runs only.** A project admin names the tool in a webhook trigger's or a schedule's `toolsAllowedUnattended` (`--allow-unattended=<tool-id>` on `kindgi webhooks` and `kindgi schedules`). In that trigger's runs, the tool is then as in a run a person started. The tenant's approval rules still apply.
251
286
 
252
287
  In a run a person started (signed in, or with their own API key), the agent's rules decide, as for any tool. Left out, it counts as `False`. Declare it on a tool that moves money or changes something people rely on:
253
288
 
@@ -262,7 +297,7 @@ def refund(request: RefundRequest) -> Refunded:
262
297
  """Refunds an order."""
263
298
  ```
264
299
 
265
- Docs: https://docs.kindgi.com/v0.1/guides/approvals/ask-before-a-tool-runs/#when-no-person-started-the-run
300
+ Docs: https://docs.kindgi.com/v0.2/guides/approvals/ask-before-a-tool-runs/#when-no-person-started-the-run
266
301
 
267
302
  ## HTTP tools — one request, no code
268
303
 
@@ -394,7 +429,7 @@ removed field, a narrower type — not on every save.
394
429
  folder, `~/.aws`) or any `.env*` file, and gets `EPERM` there. A tool that
395
430
  needs a path names it in `pyproject.toml`: `[tool.kindgi.dev.sandbox]` `allowRead = ["~/.aws"]`.
396
431
  Never set `KINDGI_DEV_SANDBOX=off` or `dev.sandbox: false` to get past it
397
- (https://docs.kindgi.com/v0.1/guides/secrets/dev-sandbox/).
432
+ (https://docs.kindgi.com/v0.2/guides/secrets/dev-sandbox/).
398
433
 
399
434
  ## When the framework itself is the problem
400
435