@kindgi/cli 0.1.4 → 0.1.5

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 (325) hide show
  1. package/README.md +13 -7
  2. package/dist/build/bundle.d.ts +11 -3
  3. package/dist/build/bundle.d.ts.map +1 -1
  4. package/dist/build/bundle.js +17 -3
  5. package/dist/build/bundle.js.map +1 -1
  6. package/dist/build/defaults.d.ts +3 -1
  7. package/dist/build/defaults.d.ts.map +1 -1
  8. package/dist/build/defaults.js +44 -1
  9. package/dist/build/defaults.js.map +1 -1
  10. package/dist/build/java-image.d.ts +31 -0
  11. package/dist/build/java-image.d.ts.map +1 -0
  12. package/dist/build/java-image.js +146 -0
  13. package/dist/build/java-image.js.map +1 -0
  14. package/dist/build/pack-root.d.ts +1 -31
  15. package/dist/build/pack-root.d.ts.map +1 -1
  16. package/dist/build/pack-root.js +22 -2
  17. package/dist/build/pack-root.js.map +1 -1
  18. package/dist/build/runners.d.ts +44 -0
  19. package/dist/build/runners.d.ts.map +1 -1
  20. package/dist/build/scala-image.d.ts +21 -0
  21. package/dist/build/scala-image.d.ts.map +1 -0
  22. package/dist/build/scala-image.js +150 -0
  23. package/dist/build/scala-image.js.map +1 -0
  24. package/dist/cli-pin.d.ts +16 -0
  25. package/dist/cli-pin.d.ts.map +1 -0
  26. package/dist/cli-pin.js +66 -0
  27. package/dist/cli-pin.js.map +1 -0
  28. package/dist/commands/agents.d.ts.map +1 -1
  29. package/dist/commands/agents.js +9 -8
  30. package/dist/commands/agents.js.map +1 -1
  31. package/dist/commands/approvals.d.ts.map +1 -1
  32. package/dist/commands/approvals.js +30 -4
  33. package/dist/commands/approvals.js.map +1 -1
  34. package/dist/commands/artifacts.d.ts.map +1 -1
  35. package/dist/commands/artifacts.js +100 -37
  36. package/dist/commands/artifacts.js.map +1 -1
  37. package/dist/commands/auth.js +2 -2
  38. package/dist/commands/blocks.d.ts.map +1 -1
  39. package/dist/commands/blocks.js +5 -4
  40. package/dist/commands/blocks.js.map +1 -1
  41. package/dist/commands/build.d.ts +10 -2
  42. package/dist/commands/build.d.ts.map +1 -1
  43. package/dist/commands/build.js +109 -16
  44. package/dist/commands/build.js.map +1 -1
  45. package/dist/commands/capabilities.d.ts.map +1 -1
  46. package/dist/commands/capabilities.js +37 -10
  47. package/dist/commands/capabilities.js.map +1 -1
  48. package/dist/commands/console.d.ts +21 -0
  49. package/dist/commands/console.d.ts.map +1 -0
  50. package/dist/commands/console.js +87 -0
  51. package/dist/commands/console.js.map +1 -0
  52. package/dist/commands/conversations.d.ts.map +1 -1
  53. package/dist/commands/conversations.js +13 -2
  54. package/dist/commands/conversations.js.map +1 -1
  55. package/dist/commands/deploy.d.ts.map +1 -1
  56. package/dist/commands/deploy.js +2 -2
  57. package/dist/commands/deploy.js.map +1 -1
  58. package/dist/commands/dev.d.ts +11 -0
  59. package/dist/commands/dev.d.ts.map +1 -1
  60. package/dist/commands/dev.js +212 -40
  61. package/dist/commands/dev.js.map +1 -1
  62. package/dist/commands/doctor.d.ts +14 -2
  63. package/dist/commands/doctor.d.ts.map +1 -1
  64. package/dist/commands/doctor.js +356 -20
  65. package/dist/commands/doctor.js.map +1 -1
  66. package/dist/commands/env-scoped.d.ts +44 -0
  67. package/dist/commands/env-scoped.d.ts.map +1 -0
  68. package/dist/commands/env-scoped.js +222 -0
  69. package/dist/commands/env-scoped.js.map +1 -0
  70. package/dist/commands/env.d.ts.map +1 -1
  71. package/dist/commands/env.js +85 -123
  72. package/dist/commands/env.js.map +1 -1
  73. package/dist/commands/eval-runs.d.ts +9 -0
  74. package/dist/commands/eval-runs.d.ts.map +1 -1
  75. package/dist/commands/eval-runs.js +20 -19
  76. package/dist/commands/eval-runs.js.map +1 -1
  77. package/dist/commands/eval-suites.d.ts.map +1 -1
  78. package/dist/commands/eval-suites.js +16 -8
  79. package/dist/commands/eval-suites.js.map +1 -1
  80. package/dist/commands/exports.d.ts +3 -0
  81. package/dist/commands/exports.d.ts.map +1 -0
  82. package/dist/commands/exports.js +82 -0
  83. package/dist/commands/exports.js.map +1 -0
  84. package/dist/commands/feedback.d.ts.map +1 -1
  85. package/dist/commands/feedback.js +6 -5
  86. package/dist/commands/feedback.js.map +1 -1
  87. package/dist/commands/flows.d.ts.map +1 -1
  88. package/dist/commands/flows.js +2 -1
  89. package/dist/commands/flows.js.map +1 -1
  90. package/dist/commands/gate-policies.d.ts.map +1 -1
  91. package/dist/commands/gate-policies.js +2 -1
  92. package/dist/commands/gate-policies.js.map +1 -1
  93. package/dist/commands/guardrails.d.ts.map +1 -1
  94. package/dist/commands/guardrails.js +3 -2
  95. package/dist/commands/guardrails.js.map +1 -1
  96. package/dist/commands/helpers.js +5 -5
  97. package/dist/commands/helpers.js.map +1 -1
  98. package/dist/commands/index.d.ts.map +1 -1
  99. package/dist/commands/index.js +14 -0
  100. package/dist/commands/index.js.map +1 -1
  101. package/dist/commands/init.d.ts +1 -1
  102. package/dist/commands/init.d.ts.map +1 -1
  103. package/dist/commands/init.js +254 -18
  104. package/dist/commands/init.js.map +1 -1
  105. package/dist/commands/judge-classes.d.ts.map +1 -1
  106. package/dist/commands/judge-classes.js +11 -10
  107. package/dist/commands/judge-classes.js.map +1 -1
  108. package/dist/commands/judgments.d.ts.map +1 -1
  109. package/dist/commands/judgments.js +7 -6
  110. package/dist/commands/judgments.js.map +1 -1
  111. package/dist/commands/key.js +4 -4
  112. package/dist/commands/memory.d.ts.map +1 -1
  113. package/dist/commands/memory.js +277 -25
  114. package/dist/commands/memory.js.map +1 -1
  115. package/dist/commands/people.d.ts +3 -0
  116. package/dist/commands/people.d.ts.map +1 -0
  117. package/dist/commands/people.js +166 -0
  118. package/dist/commands/people.js.map +1 -0
  119. package/dist/commands/proposals.d.ts.map +1 -1
  120. package/dist/commands/proposals.js +390 -69
  121. package/dist/commands/proposals.js.map +1 -1
  122. package/dist/commands/provenance.d.ts.map +1 -1
  123. package/dist/commands/provenance.js +6 -7
  124. package/dist/commands/provenance.js.map +1 -1
  125. package/dist/commands/providers.d.ts.map +1 -1
  126. package/dist/commands/providers.js +7 -5
  127. package/dist/commands/providers.js.map +1 -1
  128. package/dist/commands/reviewers.d.ts.map +1 -1
  129. package/dist/commands/reviewers.js +3 -2
  130. package/dist/commands/reviewers.js.map +1 -1
  131. package/dist/commands/runs.d.ts.map +1 -1
  132. package/dist/commands/runs.js +35 -15
  133. package/dist/commands/runs.js.map +1 -1
  134. package/dist/commands/schedules.d.ts +3 -0
  135. package/dist/commands/schedules.d.ts.map +1 -0
  136. package/dist/commands/schedules.js +275 -0
  137. package/dist/commands/schedules.js.map +1 -0
  138. package/dist/commands/secrets.d.ts.map +1 -1
  139. package/dist/commands/secrets.js +10 -11
  140. package/dist/commands/secrets.js.map +1 -1
  141. package/dist/commands/service-accounts.d.ts +3 -0
  142. package/dist/commands/service-accounts.d.ts.map +1 -0
  143. package/dist/commands/service-accounts.js +175 -0
  144. package/dist/commands/service-accounts.js.map +1 -0
  145. package/dist/commands/skills.d.ts +1 -1
  146. package/dist/commands/skills.d.ts.map +1 -1
  147. package/dist/commands/skills.js +11 -4
  148. package/dist/commands/skills.js.map +1 -1
  149. package/dist/commands/sso.d.ts +6 -0
  150. package/dist/commands/sso.d.ts.map +1 -0
  151. package/dist/commands/sso.js +318 -0
  152. package/dist/commands/sso.js.map +1 -0
  153. package/dist/commands/tokens.d.ts +11 -0
  154. package/dist/commands/tokens.d.ts.map +1 -1
  155. package/dist/commands/tokens.js +144 -11
  156. package/dist/commands/tokens.js.map +1 -1
  157. package/dist/commands/tools.d.ts.map +1 -1
  158. package/dist/commands/tools.js +4 -3
  159. package/dist/commands/tools.js.map +1 -1
  160. package/dist/commands/unwired.d.ts.map +1 -1
  161. package/dist/commands/unwired.js +1 -30
  162. package/dist/commands/unwired.js.map +1 -1
  163. package/dist/commands/upgrade.d.ts +11 -0
  164. package/dist/commands/upgrade.d.ts.map +1 -0
  165. package/dist/commands/upgrade.js +160 -0
  166. package/dist/commands/upgrade.js.map +1 -0
  167. package/dist/context.d.ts +7 -0
  168. package/dist/context.d.ts.map +1 -1
  169. package/dist/context.js +1 -0
  170. package/dist/context.js.map +1 -1
  171. package/dist/dev/defaults.d.ts +28 -11
  172. package/dist/dev/defaults.d.ts.map +1 -1
  173. package/dist/dev/defaults.js +114 -35
  174. package/dist/dev/defaults.js.map +1 -1
  175. package/dist/dev/google-credentials.d.ts +50 -0
  176. package/dist/dev/google-credentials.d.ts.map +1 -0
  177. package/dist/dev/google-credentials.js +157 -0
  178. package/dist/dev/google-credentials.js.map +1 -0
  179. package/dist/dev/java-builder.d.ts +56 -0
  180. package/dist/dev/java-builder.d.ts.map +1 -0
  181. package/dist/dev/java-builder.js +204 -0
  182. package/dist/dev/java-builder.js.map +1 -0
  183. package/dist/dev/jvm-run-files.d.ts +29 -0
  184. package/dist/dev/jvm-run-files.d.ts.map +1 -0
  185. package/dist/dev/jvm-run-files.js +94 -0
  186. package/dist/dev/jvm-run-files.js.map +1 -0
  187. package/dist/dev/lines.d.ts +13 -0
  188. package/dist/dev/lines.d.ts.map +1 -0
  189. package/dist/dev/lines.js +24 -0
  190. package/dist/dev/lines.js.map +1 -0
  191. package/dist/dev/log-view.d.ts +116 -0
  192. package/dist/dev/log-view.d.ts.map +1 -0
  193. package/dist/dev/log-view.js +233 -0
  194. package/dist/dev/log-view.js.map +1 -0
  195. package/dist/dev/pack-code.d.ts +79 -4
  196. package/dist/dev/pack-code.d.ts.map +1 -1
  197. package/dist/dev/pack-code.js +262 -3
  198. package/dist/dev/pack-code.js.map +1 -1
  199. package/dist/dev/pack-env.d.ts.map +1 -1
  200. package/dist/dev/pack-env.js +4 -0
  201. package/dist/dev/pack-env.js.map +1 -1
  202. package/dist/dev/pack-service.d.ts +11 -1
  203. package/dist/dev/pack-service.d.ts.map +1 -1
  204. package/dist/dev/pack-service.js +56 -20
  205. package/dist/dev/pack-service.js.map +1 -1
  206. package/dist/dev/paths.d.ts +6 -0
  207. package/dist/dev/paths.d.ts.map +1 -1
  208. package/dist/dev/paths.js +8 -0
  209. package/dist/dev/paths.js.map +1 -1
  210. package/dist/dev/project-database.js +1 -1
  211. package/dist/dev/project-database.js.map +1 -1
  212. package/dist/dev/runners.d.ts +35 -9
  213. package/dist/dev/runners.d.ts.map +1 -1
  214. package/dist/dev/runtime-container.d.ts +10 -2
  215. package/dist/dev/runtime-container.d.ts.map +1 -1
  216. package/dist/dev/runtime-container.js +48 -20
  217. package/dist/dev/runtime-container.js.map +1 -1
  218. package/dist/dev/runtime-env.d.ts +10 -0
  219. package/dist/dev/runtime-env.d.ts.map +1 -1
  220. package/dist/dev/runtime-env.js +8 -4
  221. package/dist/dev/runtime-env.js.map +1 -1
  222. package/dist/dev/runtime-image.d.ts +1 -1
  223. package/dist/dev/runtime-image.js +1 -1
  224. package/dist/dev/scala-builder.d.ts +72 -0
  225. package/dist/dev/scala-builder.d.ts.map +1 -0
  226. package/dist/dev/scala-builder.js +347 -0
  227. package/dist/dev/scala-builder.js.map +1 -0
  228. package/dist/env/project-env.d.ts.map +1 -1
  229. package/dist/env/project-env.js +3 -1
  230. package/dist/env/project-env.js.map +1 -1
  231. package/dist/errors.d.ts +9 -0
  232. package/dist/errors.d.ts.map +1 -1
  233. package/dist/errors.js +15 -0
  234. package/dist/errors.js.map +1 -1
  235. package/dist/init/augment-scaffolder.js +1 -1
  236. package/dist/init/augment-scaffolder.js.map +1 -1
  237. package/dist/init/dependency-specs.d.ts +26 -0
  238. package/dist/init/dependency-specs.d.ts.map +1 -1
  239. package/dist/init/dependency-specs.js +38 -0
  240. package/dist/init/dependency-specs.js.map +1 -1
  241. package/dist/init/java-augment.d.ts +24 -0
  242. package/dist/init/java-augment.d.ts.map +1 -0
  243. package/dist/init/java-augment.js +198 -0
  244. package/dist/init/java-augment.js.map +1 -0
  245. package/dist/init/mode-detect.d.ts +2 -2
  246. package/dist/init/mode-detect.d.ts.map +1 -1
  247. package/dist/init/mode-detect.js +12 -1
  248. package/dist/init/mode-detect.js.map +1 -1
  249. package/dist/init/python-augment.js +1 -1
  250. package/dist/init/python-augment.js.map +1 -1
  251. package/dist/init/scala-augment.d.ts +23 -0
  252. package/dist/init/scala-augment.d.ts.map +1 -0
  253. package/dist/init/scala-augment.js +213 -0
  254. package/dist/init/scala-augment.js.map +1 -0
  255. package/dist/init/template-files.d.ts +40 -2
  256. package/dist/init/template-files.d.ts.map +1 -1
  257. package/dist/init/template-files.js +56 -5
  258. package/dist/init/template-files.js.map +1 -1
  259. package/dist/main.d.ts +3 -0
  260. package/dist/main.d.ts.map +1 -1
  261. package/dist/main.js +20 -2
  262. package/dist/main.js.map +1 -1
  263. package/dist/open-url.d.ts +15 -0
  264. package/dist/open-url.d.ts.map +1 -0
  265. package/dist/open-url.js +41 -0
  266. package/dist/open-url.js.map +1 -0
  267. package/dist/package-manager.d.ts +10 -3
  268. package/dist/package-manager.d.ts.map +1 -1
  269. package/dist/package-manager.js +19 -1
  270. package/dist/package-manager.js.map +1 -1
  271. package/dist/providers/presets/anthropic.json +11 -3
  272. package/dist/sdk-skills/kindgi-authoring-agents/SKILL.md +30 -2
  273. package/dist/sdk-skills/kindgi-authoring-flows/SKILL.md +1 -1
  274. package/dist/sdk-skills/kindgi-authoring-guardrails/SKILL.md +47 -3
  275. package/dist/sdk-skills/kindgi-authoring-mcp-servers/SKILL.md +7 -5
  276. package/dist/sdk-skills/kindgi-authoring-providers/SKILL.md +40 -15
  277. package/dist/sdk-skills/kindgi-authoring-tools/SKILL.md +66 -2
  278. package/dist/sdk-skills/kindgi-framework-feedback/SKILL.md +5 -4
  279. package/dist/sdk-skills/kindgi-getting-started/SKILL.md +1 -1
  280. package/dist/sdk-skills/kindgi-java-authoring-agents/SKILL.md +220 -0
  281. package/dist/sdk-skills/kindgi-java-authoring-flows/SKILL.md +390 -0
  282. package/dist/sdk-skills/kindgi-java-authoring-guardrails/SKILL.md +209 -0
  283. package/dist/sdk-skills/kindgi-java-authoring-tools/SKILL.md +334 -0
  284. package/dist/sdk-skills/kindgi-java-getting-started/SKILL.md +270 -0
  285. package/dist/sdk-skills/kindgi-python-authoring-agents/SKILL.md +25 -3
  286. package/dist/sdk-skills/kindgi-python-authoring-flows/SKILL.md +1 -1
  287. package/dist/sdk-skills/kindgi-python-authoring-guardrails/SKILL.md +10 -3
  288. package/dist/sdk-skills/kindgi-python-authoring-tools/SKILL.md +45 -6
  289. package/dist/sdk-skills/kindgi-python-getting-started/SKILL.md +2 -2
  290. package/dist/sdk-skills/kindgi-scala-authoring-agents/SKILL.md +217 -0
  291. package/dist/sdk-skills/kindgi-scala-authoring-flows/SKILL.md +357 -0
  292. package/dist/sdk-skills/kindgi-scala-authoring-guardrails/SKILL.md +199 -0
  293. package/dist/sdk-skills/kindgi-scala-authoring-tools/SKILL.md +302 -0
  294. package/dist/sdk-skills/kindgi-scala-getting-started/SKILL.md +302 -0
  295. package/dist/templates/java/.mvn/wrapper/maven-wrapper.properties +3 -0
  296. package/dist/templates/java/AGENTS.md +31 -0
  297. package/dist/templates/java/README.md.tmpl +69 -0
  298. package/dist/templates/java/gitignore +9 -0
  299. package/dist/templates/java/kindgi.config.json.tmpl +8 -0
  300. package/dist/templates/java/kindgiw +33 -0
  301. package/dist/templates/java/kindgiw.cmd +28 -0
  302. package/dist/templates/java/mvnw +295 -0
  303. package/dist/templates/java/pom.xml.tmpl +65 -0
  304. package/dist/templates/java/src/main/java/__PACKAGE__/agents/EchoAgent.java.tmpl +27 -0
  305. package/dist/templates/java/src/main/java/__PACKAGE__/flows/EchoFlow.java.tmpl +18 -0
  306. package/dist/templates/java/src/main/java/__PACKAGE__/guardrails/ResponseNotEmpty.java.tmpl +28 -0
  307. package/dist/templates/java/src/main/java/__PACKAGE__/tools/Echo.java.tmpl +22 -0
  308. package/dist/templates/java/src/main/java/__PACKAGE__/tools/Greet.java.tmpl +23 -0
  309. package/dist/templates/java/src/test/java/__PACKAGE__/ToolsTest.java.tmpl +30 -0
  310. package/dist/templates/minimal/README.md.tmpl +6 -12
  311. package/dist/templates/python/README.md.tmpl +4 -4
  312. package/dist/templates/sample/README.md.tmpl +5 -11
  313. package/dist/templates/scala/AGENTS.md +32 -0
  314. package/dist/templates/scala/README.md.tmpl +75 -0
  315. package/dist/templates/scala/build.sbt.tmpl +16 -0
  316. package/dist/templates/scala/gitignore +13 -0
  317. package/dist/templates/scala/kindgi.config.json.tmpl +8 -0
  318. package/dist/templates/scala/project/build.properties +1 -0
  319. package/dist/templates/scala/src/main/scala/__PACKAGE__/agents/EchoAgent.scala.tmpl +23 -0
  320. package/dist/templates/scala/src/main/scala/__PACKAGE__/flows/EchoFlow.scala.tmpl +16 -0
  321. package/dist/templates/scala/src/main/scala/__PACKAGE__/guardrails/ResponseNotEmpty.scala.tmpl +21 -0
  322. package/dist/templates/scala/src/main/scala/__PACKAGE__/tools/Echo.scala.tmpl +16 -0
  323. package/dist/templates/scala/src/main/scala/__PACKAGE__/tools/Greet.scala.tmpl +17 -0
  324. package/dist/templates/scala/src/test/scala/__PACKAGE__/ToolsSuite.scala.tmpl +23 -0
  325. package/package.json +13 -12
@@ -12,8 +12,8 @@ description: >
12
12
  authoring agents is covered by kindgi-authoring-agents.
13
13
  type: core
14
14
  library: "@kindgi/sdk"
15
- version: "0.4.4"
16
- sdk_version: "0.1.4"
15
+ version: "0.4.5"
16
+ sdk_version: "0.1.5"
17
17
  pack_languages: [node]
18
18
  sources:
19
19
  - packages/tools/src/types.ts
@@ -115,6 +115,16 @@ The handler gets the **parsed** input, typed `z.infer` of `input` (Zod's output
115
115
 
116
116
  The output side is the reverse: the advertised output schema requires every field, defaulted ones included. Return them all.
117
117
 
118
+ ### Logging from the handler
119
+
120
+ `ctx.log` is a logger bound to the call: its records carry the run's ids, the tool's id and the trace id. It has `info`, `warn`, `error`, `debug` and `trace`, each `(message, fields?)`. The pack service sets it; a context your own code builds (a test's) may not, so write `ctx.log?.`:
121
+
122
+ ```ts
123
+ ctx.log?.info('refund issued', { orderId, amountCents });
124
+ ```
125
+
126
+ Put values in `fields`, never in the message. Log ids, amounts and outcomes, never what a person typed (a refund's reason, a message, an address): the log is read by whoever operates the runtime, not only by the person the data is about. Docs: https://docs.kindgi.com/v0.1/guides/tools/write-a-tool/#log-from-a-tool
127
+
118
128
  ### Configuration and secrets
119
129
 
120
130
  A secret that belongs to the tenant — an API key a customer gives you — is declared, and read from `ctx.secrets`:
@@ -132,6 +142,32 @@ const defined = defineTool({
132
142
 
133
143
  The runtime resolves every declared secret on every call, for the call's tenant, in its env (`KINDGI_ENV`; in `kindgi dev`, `local`: the pack's `.env` and `.env.local`). It checks each value against its schema, and fails the call, naming the secret, when one is missing or doesn't match. Every declared secret is required, so in a runtime call `ctx.secrets` holds them all; it's optional in the type because a unit test builds its own context and passes `secrets: { CITATOR_KEY: '…' }`.
134
144
 
145
+ A value that differs per tenant, org or project but isn't secret (a base URL, a region, an account id) is an **env value**: declared in `needsSpec.env`, read from `ctx.env`:
146
+
147
+ ```ts
148
+ const defined = defineTool({
149
+ // …id, description, version, input, output, effects…
150
+ needsSpec: {
151
+ env: {
152
+ ORDERS_BASE_URL: { type: 'string', pattern: '^https://' },
153
+ ORDERS_REGION: { type: 'string', enum: ['eu', 'us'], default: 'eu' },
154
+ },
155
+ },
156
+ handler: async ({ orderId }, ctx) => ({
157
+ url: `${ctx.env?.ORDERS_BASE_URL}/${ctx.env?.ORDERS_REGION}/orders/${orderId}`,
158
+ }),
159
+ });
160
+ ```
161
+
162
+ - **Which value a call gets:** its project's, else its org's, else the tenant's, in the runtime's env; a schema `default` makes a name optional. The values a call used are recorded with it, so a retry or a resume sees the same ones.
163
+ - **Setting them:** `kindgi env set ORDERS_REGION us --scope=project:<project-id> --env=local` (or `--scope=tenant`, for every project). Changing a value that's already set takes `--force`.
164
+ - **A declared value nobody set** stops the call before the tool runs. For a tool `acme-orders.needs-account` that declares `ACME_ACCOUNT_ID`, the message reads:
165
+ ```text
166
+ 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)
167
+ ```
168
+ - **Not secret:** env values are recorded with each run that uses them and shown in its journal. A credential is a secret (`needsSpec.secrets`), never an env value.
169
+ - **In a unit test:** pass `env: { … }` in the context `invokeTool` gets.
170
+
135
171
  Everything else comes from the process environment: `process.env.CITATOR_URL`. The pack service runs with the pack's env files in `kindgi dev`, and with the container's environment in an image. Declare the names your code reads in `kindgi.config.ts`, `env: { required: ['CITATOR_URL'], optional: [...] }`: a deployment injects exactly those, a pack service missing a required one isn't ready and says which, and `kindgi dev` warns about it. Values per environment go in `environments.<name>.env`, secrets only as references.
136
172
 
137
173
  ## Declarative HTTP spec
@@ -176,6 +212,15 @@ export default defined.value;
176
212
 
177
213
  So declare `mutating: false` on every tool that only reads, and never on one that writes.
178
214
 
215
+ A tool that writes also says what it writes, in `effects`, beside `mutating: true`:
216
+
217
+ ```ts
218
+ effects: [{ kind: 'writes', resource: 'acme:refunds' }],
219
+ mutating: true,
220
+ ```
221
+
222
+ The kinds are `reads`, `writes`, `deletes`, `network`, `spawns-run`, `emits-event`, `external-side-effect` and `sensitive-data-egress` (`EFFECT_KINDS` in `@kindgi/tools`); `defineTool` refuses any other. `resource` is free text naming what the tool touches. A read-only tool keeps `effects: []`.
223
+
179
224
  ## Tool id convention
180
225
 
181
226
  `<pack-id>.<tool-name>` — kebab-case, dot-namespaced. The `<pack-id>`
@@ -210,6 +255,25 @@ range at run start. Compatible tool updates (patch, minor) reach the
210
255
  agent without editing agent source; breaking updates (major) require
211
256
  the agent-author to opt in.
212
257
 
258
+ ## Testing a tool
259
+
260
+ Put a tool's tests beside it, `tools/<tool>/index.test.ts`. Discovery skips `*.test.*` and `*.spec.*` files (`.ts`, `.js`, `.mjs`, `.cjs`), so the indexer never loads a test as a primitive: don't move tests elsewhere to keep them out. `invokeTool(tool, input, ctx)` from `@kindgi/sdk/define` calls the tool the way Kindgi does, schemas included, and returns a `Result`. Its `ctx` needs a `tenantId` and an `abortSignal` (`ToolContext` in `@kindgi/tools`); the rest is optional. vitest doesn't typecheck, so a context missing them still passes the test: run `tsc --noEmit` too.
261
+
262
+ ```ts
263
+ import { invokeTool } from '@kindgi/sdk/define';
264
+ import type { TenantId } from '@kindgi/sdk/types';
265
+
266
+ const ctx = { tenantId: 'test' as TenantId, abortSignal: new AbortController().signal };
267
+ // add `env: { STORE_URL: '…' }` for a tool that reads a declared env value
268
+ const result = await invokeTool(lookupOrder, { orderId: 'ord_1001' }, ctx);
269
+ ```
270
+
271
+ `kindgi test` runs the pack's tests with vitest (`vitest run`; `--watch` keeps watching).
272
+
273
+ ## Shared code
274
+
275
+ Code several tools share (schemas, a client, helpers) goes outside `tools/`, for example in `lib/` beside it. Discovery loads every `.ts`, `.js` and `.mjs` file under `tools/` (tests aside) as a primitive, so a helper there fails the index. Don't put it in the app's own source either: import the app's functions from where they are, and keep what's Kindgi's in the pack's folder.
276
+
213
277
  ## Wiring the tool onto an agent
214
278
 
215
279
  Agents reference tools via `ToolRef[]`, NOT `string[]`. Each entry is
@@ -14,9 +14,9 @@ description: >
14
14
  diagnostic output into durable input for framework improvement.
15
15
  type: core
16
16
  library: "@kindgi/sdk"
17
- version: "0.4.0"
18
- sdk_version: "0.1.4"
19
- pack_languages: [node, python]
17
+ version: "0.4.2"
18
+ sdk_version: "0.1.5"
19
+ pack_languages: [node, python, java, scala]
20
20
  ---
21
21
 
22
22
  # Capturing framework feedback
@@ -25,7 +25,8 @@ pack_languages: [node, python]
25
25
  > (`@kindgi/cli`), not a global command. Run it through the project's
26
26
  > package manager — `pnpm exec kindgi …`, `npx --no kindgi …` (npm),
27
27
  > `yarn kindgi …` or `bun run kindgi …`. A Python pack (`[tool.kindgi]` in
28
- > `pyproject.toml`) has no Node project: run the `kindgi` on `PATH`.
28
+ > `pyproject.toml`) has no Node project: run the `kindgi` on `PATH`. A Java
29
+ > or Scala pack (`kindgi.config.json`) runs the CLI it pins: `./kindgiw …`.
29
30
  > Commands below are written `kindgi …` for brevity.
30
31
 
31
32
  You just spent time diagnosing a Kindgi-framework issue. That diagnostic
@@ -15,7 +15,7 @@ description: >
15
15
  type: core
16
16
  library: "@kindgi/sdk"
17
17
  version: "0.3.8"
18
- sdk_version: "0.1.4"
18
+ sdk_version: "0.1.5"
19
19
  pack_languages: [node]
20
20
  ---
21
21
 
@@ -0,0 +1,220 @@
1
+ ---
2
+ name: kindgi-java-authoring-agents
3
+ description: >
4
+ Covers writing agents for a Kindgi pack in Java (`com.kindgi:kindgi-pack`):
5
+ `Agent.define(id)` as a `public static final` field, wiring tools (`Tool`
6
+ objects or an id with a version range) and guardrails, capabilities and
7
+ model choice (preferredProvider / preferredModel), conversation policy,
8
+ turn budgets, prompt parameters, a typed answer from a record, and
9
+ tool-error retries, all as data. Load this whenever you are authoring or
10
+ editing code in a Java pack's agents packages (a pack whose
11
+ `kindgi.config.json` says `"language": "java"`), defining an agent, or
12
+ when the user asks to add, change or refactor one. Java tools are covered
13
+ by kindgi-java-authoring-tools, Java guardrails by
14
+ kindgi-java-authoring-guardrails, connecting a real model by
15
+ kindgi-authoring-providers.
16
+ type: core
17
+ library: "kindgi-pack (Java)"
18
+ version: "0.1.0"
19
+ sdk_version: "0.1.5"
20
+ pack_languages: [java]
21
+ sources:
22
+ - sdks/java/kindgi-pack/README.md
23
+ - sdks/java/kindgi-pack/src/main/java/com/kindgi/pack/Agent.java
24
+ - packages/specs/schemas/agent.schema.json
25
+ - packages/specs/schemas/pack-index.schema.json
26
+ ---
27
+
28
+ # Authoring Kindgi agents in Java
29
+
30
+ > **Running `kindgi`:** the pack pins its CLI (`"cli"` in
31
+ > `kindgi.config.json`), and `./kindgiw` runs that version, so every
32
+ > `kindgi <command>` below runs as `./kindgiw <command>`. Maven runs as
33
+ > `./mvnw`.
34
+ >
35
+ > Java support is in preview: tested and supported, but the API may still
36
+ > change in 0.1.6 without the usual deprecation period.
37
+
38
+ An **agent** is a versioned, model-driven orchestrator. It's made of:
39
+ - instructions (a prompt template);
40
+ - the tools it may call;
41
+ - the capabilities its model needs;
42
+ - guardrails that gate its answer;
43
+ - optionally, a conversation policy.
44
+
45
+ In a Java pack it is **data**: a `public static final Agent` field of a class
46
+ in an `agents` package. The model runs in the Kindgi runtime, not in your
47
+ JVM. Your Java code runs only inside the agent's tools and guardrail checks.
48
+
49
+ ## Ask before building
50
+
51
+ "Add an agent" is a conversation opener, not a ticket. Before writing a
52
+ file, ask:
53
+
54
+ - **What should the agent do?** The purpose drives everything else.
55
+ - **Which tools does it need?** New ones, or existing ones?
56
+ - **Multi-turn or one-shot?** History changes the shape.
57
+ - **Any rules it must respect?** Those become guardrails.
58
+
59
+ The pack's sample agent proves the runtime works end to end. It is not the
60
+ shape to imitate unless the user asks for that.
61
+
62
+ ## An agent
63
+
64
+ ```java
65
+ // src/main/java/acme/agents/BriefWriter.java
66
+ package acme.agents;
67
+
68
+ import acme.guardrails.ResponseNotEmpty;
69
+ import acme.tools.Echo;
70
+ import com.kindgi.pack.Agent;
71
+ import java.util.List;
72
+ import java.util.Map;
73
+
74
+ /** acme.brief-writer: drafts a brief's argument from the case facts. */
75
+ public final class BriefWriter {
76
+ /** The typed answer: the final message must be JSON of this shape. */
77
+ public record Brief(String argument, List<String> citations) {}
78
+
79
+ public static final Agent AGENT = Agent.define("acme.brief-writer")
80
+ .version("0.1.0")
81
+ .name("Brief Writer")
82
+ .description("Drafts appellate briefs from a case file; cites precedents.")
83
+ .instructions("You are drafting a brief in {{ jurisdiction }}. The user gives the case facts; you write "
84
+ + "a Section IV argument citing at least two precedents. Check every cite with the echo tool "
85
+ + "before using it. Never invent one.")
86
+ .capability(Map.of("needs", List.of(Map.of("feature", "tool-use"))))
87
+ .tool(Echo.TOOL)
88
+ .guardrail(ResponseNotEmpty.GUARDRAIL)
89
+ .set("parameters", List.of(Map.of("name", "jurisdiction", "type", "string", "required", true)))
90
+ .set("conversationPolicy", Map.of("historyLimit", 20))
91
+ .set("budget", Map.of("maxSteps", 8, "maxCostUsd", 0.5, "maxWallMs", 60_000))
92
+ .set("toolErrors", Map.of("maxRetries", 1, "retryOn", List.of("invalid-arguments", "unknown-tool")))
93
+ .output(Brief.class)
94
+ .build();
95
+
96
+ private BriefWriter() {}
97
+ }
98
+ ```
99
+
100
+ - Tools and guardrails are the pack's own fields, imported like any class:
101
+ `.tool(Echo.TOOL)`, `.guardrail(ResponseNotEmpty.GUARDRAIL)`.
102
+ - **`build()` needs a version, a name and instructions.** Anything missing
103
+ is an error where the agent is defined, and the indexer reports it with
104
+ the file.
105
+ - **Every other field is `set(field, value)`, keyed as on the wire:** the
106
+ field and its maps are camelCase (`conversationPolicy`, `maxSteps`,
107
+ `historyLimit`), as `agent.schema.json` names them. The indexer checks
108
+ each agent against the pack index's schema, and `kindgi dev` reports a
109
+ mistake with its file.
110
+ - A class may hold several agents, each in its own `static final` field.
111
+
112
+ ## Field by field
113
+
114
+ - **`id`:** `<pack-id>.<agent-name>`, kebab-case, dot-namespaced.
115
+ - **`version`:** an exact semver. Conversations pin the version they started
116
+ on.
117
+ - **`name`, `description`**, and `set("tags", List.of(…))`: for people and
118
+ listings. The model never sees the description.
119
+ - **`instructions`:** a LiquidJS template. `{{ variable }}` comes from
120
+ `parameters` or the runtime's own variables (`today`, `now`, `agent.*`,
121
+ `conversation.*`). It's rendered strictly: an unknown variable fails the
122
+ turn. Write it as a brief for a capable colleague: what to do, which tools
123
+ to prefer, what to refuse, the quality bar. Name a tool by what it does
124
+ ("the verify-citation tool"), never by its dotted id. The model sees ids in
125
+ its provider's form (`acme__verify-citation` for Anthropic and
126
+ OpenAI-compatible models), and a dotted id in the instructions can make it
127
+ call a name it wasn't given. `instructions(Map.of("prompt", …, "version", …))`
128
+ references a registered prompt block instead.
129
+ - **`capability(Map)`:** what the model must support, such as
130
+ `Map.of("needs", List.of(Map.of("feature", "tool-use")))`. Call it once per
131
+ capability. The turn routes its first capability to pick a provider and
132
+ model; with none declared, the turn fails.
133
+ - **`tool(Tool)`:** pins that tool's version (its own, or the pack's).
134
+ **`tool(id, range)`** is a tool of another pack, with a semver **range**
135
+ (`"^1.0.0"`); the highest active matching version is picked at turn
136
+ start. An agent with no tools is chat-only.
137
+ - **`guardrail(Guardrail)`** or **`guardrail(id)`:** evaluated once per turn
138
+ on the final answer, before it is stored. An id with no registered
139
+ guardrail fails the turn.
140
+ - **`set("parameters", List.of(Map.of("name", …, "type", …, "required", …)))`:**
141
+ inputs the caller supplies per run. They fill `{{ … }}` in the
142
+ instructions.
143
+ - **`set("preferredProvider", "anthropic")`, `set("preferredModel", "claude-haiku-4-5")`:**
144
+ soft hints. The router prefers them when they satisfy the capabilities.
145
+ To *require* a model, put it in the capability:
146
+ `Map.of("needs", List.of(Map.of("feature", "tool-use"), Map.of("models", Map.of("allow", List.of("claude-haiku-4-5")))))`.
147
+ - **`set("conversationPolicy", …)`:** `historyLimit` caps the prior messages
148
+ loaded, and `hitl` configures approval gates. Absent, the turn loads the
149
+ full history with no gates. A tenant's `hitl` policy can tighten the gates
150
+ (a shorter timeout, a higher reviewer role, stricter per tool), never
151
+ loosen them.
152
+ - **`set("budget", …)`:** per turn. `maxSteps` counts model calls (default
153
+ 8); `maxCostUsd`; `maxWallMs` (default 120 000). Exceeding the steps or the
154
+ cost fails the turn (`budget-exceeded`); running out of wall time aborts
155
+ it. Leave room for real models: a turn with tool calls can take tens of
156
+ seconds.
157
+ - **`output(Type.class)`:** a typed answer, with its schema derived from the
158
+ record. The final answer must be JSON matching it. A wrong one goes back
159
+ to the model with the problems (`maxRepairs`, default 1), and then the
160
+ turn fails (`output-schema-violation`). For `maxRepairs` or a schema of
161
+ your own, use `set("output", Map.of("schema", …, "maxRepairs", 2))`. The
162
+ parsed answer is the turn result's `output`. In a flow it is
163
+ `nodeOutputs.<step>.output.<field>`.
164
+ - **`set("toolErrors", …)`:** `maxRetries` and `retryOn`. A failed tool call
165
+ goes back to the model as the call's result, so it can fix the call. The
166
+ default kinds are `invalid-arguments` and `unknown-tool` (nothing ran). Add
167
+ `tool-error` only when retrying the tool is safe. Each retry costs a step.
168
+
169
+ ## Which model answers
170
+
171
+ Agents run on a registered model provider: the router picks one whose
172
+ models satisfy the capabilities. `kindgi dev` gives a new pack `dev-echo`, a
173
+ **fallback** that answers only while no other provider fits. It calls the
174
+ first tool and replies "⚠ dev-echo isn't a real model: …", then "Tool
175
+ responded: …". The turn carries the `fallback-provider` and
176
+ `dev-echo-not-a-model` warnings. dev-echo can't fill in any other tool
177
+ input, and can't give a typed answer: an agent with `output` fails with
178
+ `output-schema-violation` until a real model is registered. To register one,
179
+ see `kindgi-authoring-providers` (`./kindgiw providers register --preset=anthropic`,
180
+ or `"providers": [{"preset": "anthropic"}]` in `kindgi.config.json`).
181
+
182
+ ## Iterating
183
+
184
+ Save the file: `kindgi dev` recompiles, re-indexes, and the next run uses
185
+ it, with no restart. Bump `version` when you break what callers rely on (a
186
+ removed parameter, an incompatible output), not on every save.
187
+
188
+ Run an agent from another terminal in the pack directory:
189
+
190
+ ```sh
191
+ ./kindgiw runs start --agent=acme.brief-writer --input='{"userMessage":"…","parameters":{"jurisdiction":"US"}}'
192
+ ```
193
+
194
+ or from a Java app with the client (`kindgi-java-getting-started`).
195
+
196
+ ## Common mistakes
197
+
198
+ 1. **Building an agent without asking what it should do.** Copying the
199
+ sample's shape answers the wrong question.
200
+ 2. **No `capability(…)`.** The turn can't pick a model.
201
+ 3. **Java names inside the maps.** `set("budget", Map.of("max_steps", 4))`
202
+ isn't a budget: the keys are the wire's camelCase (`maxSteps`,
203
+ `historyLimit`, `maxRetries`).
204
+ 4. **An unregistered guardrail id.** Pass the `Guardrail` field, or make sure
205
+ the id is one the tenant has.
206
+ 5. **`{{ variable }}` not in `parameters`.** The turn fails when the
207
+ instructions render.
208
+ 6. **An agent that isn't a `static final` field.** Only static fields are
209
+ indexed.
210
+ 7. **A tight `maxWallMs` with a real model.** 15 s aborts real turns under
211
+ load; 60 s is a safer start.
212
+ 8. **Expecting dev-echo to give a typed answer.** It can't: register a real
213
+ model first.
214
+
215
+ ## When the framework itself is the problem
216
+
217
+ If the bug is in Kindgi or kindgi-pack (the index dropping a field, a
218
+ misleading error, the router picking the wrong model) and not in the pack's
219
+ code, load `kindgi-framework-feedback` and file it with
220
+ `./kindgiw feedback write`.