@oharness/engine 0.1.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 (256) hide show
  1. package/dist/agent/agent.d.ts +196 -0
  2. package/dist/agent/agent.js +758 -0
  3. package/dist/agent/agent.js.map +1 -0
  4. package/dist/agent/compaction.d.ts +68 -0
  5. package/dist/agent/compaction.js +179 -0
  6. package/dist/agent/compaction.js.map +1 -0
  7. package/dist/agent/hooks.d.ts +77 -0
  8. package/dist/agent/hooks.js +152 -0
  9. package/dist/agent/hooks.js.map +1 -0
  10. package/dist/agent/memory.d.ts +45 -0
  11. package/dist/agent/memory.js +147 -0
  12. package/dist/agent/memory.js.map +1 -0
  13. package/dist/agent/overflow.d.ts +35 -0
  14. package/dist/agent/overflow.js +69 -0
  15. package/dist/agent/overflow.js.map +1 -0
  16. package/dist/agent/permissions.d.ts +181 -0
  17. package/dist/agent/permissions.js +289 -0
  18. package/dist/agent/permissions.js.map +1 -0
  19. package/dist/agent/prompt.d.ts +25 -0
  20. package/dist/agent/prompt.js +63 -0
  21. package/dist/agent/prompt.js.map +1 -0
  22. package/dist/agent/session.d.ts +108 -0
  23. package/dist/agent/session.js +231 -0
  24. package/dist/agent/session.js.map +1 -0
  25. package/dist/agent/settings.d.ts +37 -0
  26. package/dist/agent/settings.js +113 -0
  27. package/dist/agent/settings.js.map +1 -0
  28. package/dist/agent/skills.d.ts +58 -0
  29. package/dist/agent/skills.js +225 -0
  30. package/dist/agent/skills.js.map +1 -0
  31. package/dist/agent/store.d.ts +308 -0
  32. package/dist/agent/store.js +596 -0
  33. package/dist/agent/store.js.map +1 -0
  34. package/dist/agent/subagent.d.ts +44 -0
  35. package/dist/agent/subagent.js +138 -0
  36. package/dist/agent/subagent.js.map +1 -0
  37. package/dist/agent/titles.d.ts +8 -0
  38. package/dist/agent/titles.js +23 -0
  39. package/dist/agent/titles.js.map +1 -0
  40. package/dist/agent/workspace.d.ts +60 -0
  41. package/dist/agent/workspace.js +156 -0
  42. package/dist/agent/workspace.js.map +1 -0
  43. package/dist/artifacts/publish.d.ts +94 -0
  44. package/dist/artifacts/publish.js +104 -0
  45. package/dist/artifacts/publish.js.map +1 -0
  46. package/dist/artifacts/store.d.ts +324 -0
  47. package/dist/artifacts/store.js +500 -0
  48. package/dist/artifacts/store.js.map +1 -0
  49. package/dist/auth/index.d.ts +13 -0
  50. package/dist/auth/index.js +10 -0
  51. package/dist/auth/index.js.map +1 -0
  52. package/dist/auth/manager.d.ts +83 -0
  53. package/dist/auth/manager.js +266 -0
  54. package/dist/auth/manager.js.map +1 -0
  55. package/dist/auth/oauth.d.ts +83 -0
  56. package/dist/auth/oauth.js +327 -0
  57. package/dist/auth/oauth.js.map +1 -0
  58. package/dist/auth/providers/account.d.ts +59 -0
  59. package/dist/auth/providers/account.js +282 -0
  60. package/dist/auth/providers/account.js.map +1 -0
  61. package/dist/auth/providers/anthropic.d.ts +24 -0
  62. package/dist/auth/providers/anthropic.js +209 -0
  63. package/dist/auth/providers/anthropic.js.map +1 -0
  64. package/dist/auth/providers/generic.d.ts +57 -0
  65. package/dist/auth/providers/generic.js +155 -0
  66. package/dist/auth/providers/generic.js.map +1 -0
  67. package/dist/auth/providers/official.d.ts +3 -0
  68. package/dist/auth/providers/official.js +90 -0
  69. package/dist/auth/providers/official.js.map +1 -0
  70. package/dist/auth/providers/ottoport.d.ts +3 -0
  71. package/dist/auth/providers/ottoport.js +60 -0
  72. package/dist/auth/providers/ottoport.js.map +1 -0
  73. package/dist/auth/store.d.ts +22 -0
  74. package/dist/auth/store.js +138 -0
  75. package/dist/auth/store.js.map +1 -0
  76. package/dist/auth/types.d.ts +167 -0
  77. package/dist/auth/types.js +16 -0
  78. package/dist/auth/types.js.map +1 -0
  79. package/dist/config.d.ts +197 -0
  80. package/dist/config.js +195 -0
  81. package/dist/config.js.map +1 -0
  82. package/dist/core/errors.d.ts +46 -0
  83. package/dist/core/errors.js +83 -0
  84. package/dist/core/errors.js.map +1 -0
  85. package/dist/core/tokens.d.ts +12 -0
  86. package/dist/core/tokens.js +56 -0
  87. package/dist/core/tokens.js.map +1 -0
  88. package/dist/core/types.d.ts +91 -0
  89. package/dist/core/types.js +49 -0
  90. package/dist/core/types.js.map +1 -0
  91. package/dist/harness.d.ts +302 -0
  92. package/dist/harness.js +695 -0
  93. package/dist/harness.js.map +1 -0
  94. package/dist/index.d.ts +32 -0
  95. package/dist/index.js +21 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/mcp/client.d.ts +55 -0
  98. package/dist/mcp/client.js +199 -0
  99. package/dist/mcp/client.js.map +1 -0
  100. package/dist/mcp/index.d.ts +13 -0
  101. package/dist/mcp/index.js +8 -0
  102. package/dist/mcp/index.js.map +1 -0
  103. package/dist/mcp/manager.d.ts +77 -0
  104. package/dist/mcp/manager.js +325 -0
  105. package/dist/mcp/manager.js.map +1 -0
  106. package/dist/mcp/oauth.d.ts +63 -0
  107. package/dist/mcp/oauth.js +302 -0
  108. package/dist/mcp/oauth.js.map +1 -0
  109. package/dist/mcp/protocol.d.ts +130 -0
  110. package/dist/mcp/protocol.js +14 -0
  111. package/dist/mcp/protocol.js.map +1 -0
  112. package/dist/mcp/registry.d.ts +52 -0
  113. package/dist/mcp/registry.js +100 -0
  114. package/dist/mcp/registry.js.map +1 -0
  115. package/dist/mcp/registry.json +293 -0
  116. package/dist/mcp/secrets.d.ts +20 -0
  117. package/dist/mcp/secrets.js +75 -0
  118. package/dist/mcp/secrets.js.map +1 -0
  119. package/dist/mcp/transport.d.ts +51 -0
  120. package/dist/mcp/transport.js +158 -0
  121. package/dist/mcp/transport.js.map +1 -0
  122. package/dist/paths.d.ts +37 -0
  123. package/dist/paths.js +63 -0
  124. package/dist/paths.js.map +1 -0
  125. package/dist/plugins.d.ts +55 -0
  126. package/dist/plugins.js +201 -0
  127. package/dist/plugins.js.map +1 -0
  128. package/dist/providers/builtin.d.ts +23 -0
  129. package/dist/providers/builtin.js +141 -0
  130. package/dist/providers/builtin.js.map +1 -0
  131. package/dist/providers/catalog.d.ts +129 -0
  132. package/dist/providers/catalog.js +254 -0
  133. package/dist/providers/catalog.js.map +1 -0
  134. package/dist/providers/catalog.json +472 -0
  135. package/dist/providers/discovery.d.ts +16 -0
  136. package/dist/providers/discovery.js +161 -0
  137. package/dist/providers/discovery.js.map +1 -0
  138. package/dist/providers/http.d.ts +24 -0
  139. package/dist/providers/http.js +139 -0
  140. package/dist/providers/http.js.map +1 -0
  141. package/dist/providers/index.d.ts +10 -0
  142. package/dist/providers/index.js +8 -0
  143. package/dist/providers/index.js.map +1 -0
  144. package/dist/providers/piai.d.ts +124 -0
  145. package/dist/providers/piai.js +551 -0
  146. package/dist/providers/piai.js.map +1 -0
  147. package/dist/providers/registry.d.ts +65 -0
  148. package/dist/providers/registry.js +195 -0
  149. package/dist/providers/registry.js.map +1 -0
  150. package/dist/providers/resilient.d.ts +46 -0
  151. package/dist/providers/resilient.js +117 -0
  152. package/dist/providers/resilient.js.map +1 -0
  153. package/dist/providers/types.d.ts +182 -0
  154. package/dist/providers/types.js +50 -0
  155. package/dist/providers/types.js.map +1 -0
  156. package/dist/schedule/cron.d.ts +35 -0
  157. package/dist/schedule/cron.js +125 -0
  158. package/dist/schedule/cron.js.map +1 -0
  159. package/dist/schedule/scheduler.d.ts +87 -0
  160. package/dist/schedule/scheduler.js +237 -0
  161. package/dist/schedule/scheduler.js.map +1 -0
  162. package/dist/storage/kv.d.ts +56 -0
  163. package/dist/storage/kv.js +173 -0
  164. package/dist/storage/kv.js.map +1 -0
  165. package/dist/storage/migrate.d.ts +11 -0
  166. package/dist/storage/migrate.js +93 -0
  167. package/dist/storage/migrate.js.map +1 -0
  168. package/dist/storage/project.d.ts +9 -0
  169. package/dist/storage/project.js +57 -0
  170. package/dist/storage/project.js.map +1 -0
  171. package/dist/storage/records.d.ts +32 -0
  172. package/dist/storage/records.js +48 -0
  173. package/dist/storage/records.js.map +1 -0
  174. package/dist/sync/client.d.ts +79 -0
  175. package/dist/sync/client.js +118 -0
  176. package/dist/sync/client.js.map +1 -0
  177. package/dist/sync/mirror.d.ts +85 -0
  178. package/dist/sync/mirror.js +389 -0
  179. package/dist/sync/mirror.js.map +1 -0
  180. package/dist/sync/protocol.d.ts +67 -0
  181. package/dist/sync/protocol.js +16 -0
  182. package/dist/sync/protocol.js.map +1 -0
  183. package/dist/sync/settings.d.ts +56 -0
  184. package/dist/sync/settings.js +60 -0
  185. package/dist/sync/settings.js.map +1 -0
  186. package/dist/tools/builtin/artifact.d.ts +16 -0
  187. package/dist/tools/builtin/artifact.js +134 -0
  188. package/dist/tools/builtin/artifact.js.map +1 -0
  189. package/dist/tools/builtin/bash.d.ts +3 -0
  190. package/dist/tools/builtin/bash.js +142 -0
  191. package/dist/tools/builtin/bash.js.map +1 -0
  192. package/dist/tools/builtin/fs.d.ts +19 -0
  193. package/dist/tools/builtin/fs.js +280 -0
  194. package/dist/tools/builtin/fs.js.map +1 -0
  195. package/dist/tools/builtin/index.d.ts +22 -0
  196. package/dist/tools/builtin/index.js +42 -0
  197. package/dist/tools/builtin/index.js.map +1 -0
  198. package/dist/tools/builtin/mcp-resource.d.ts +3 -0
  199. package/dist/tools/builtin/mcp-resource.js +220 -0
  200. package/dist/tools/builtin/mcp-resource.js.map +1 -0
  201. package/dist/tools/builtin/memory.d.ts +10 -0
  202. package/dist/tools/builtin/memory.js +76 -0
  203. package/dist/tools/builtin/memory.js.map +1 -0
  204. package/dist/tools/builtin/recall.d.ts +13 -0
  205. package/dist/tools/builtin/recall.js +163 -0
  206. package/dist/tools/builtin/recall.js.map +1 -0
  207. package/dist/tools/builtin/search.d.ts +3 -0
  208. package/dist/tools/builtin/search.js +240 -0
  209. package/dist/tools/builtin/search.js.map +1 -0
  210. package/dist/tools/builtin/skill.d.ts +10 -0
  211. package/dist/tools/builtin/skill.js +46 -0
  212. package/dist/tools/builtin/skill.js.map +1 -0
  213. package/dist/tools/builtin/task.d.ts +9 -0
  214. package/dist/tools/builtin/task.js +68 -0
  215. package/dist/tools/builtin/task.js.map +1 -0
  216. package/dist/tools/builtin/todo.d.ts +20 -0
  217. package/dist/tools/builtin/todo.js +63 -0
  218. package/dist/tools/builtin/todo.js.map +1 -0
  219. package/dist/tools/define.d.ts +19 -0
  220. package/dist/tools/define.js +39 -0
  221. package/dist/tools/define.js.map +1 -0
  222. package/dist/tools/index.d.ts +7 -0
  223. package/dist/tools/index.js +5 -0
  224. package/dist/tools/index.js.map +1 -0
  225. package/dist/tools/registry.d.ts +39 -0
  226. package/dist/tools/registry.js +101 -0
  227. package/dist/tools/registry.js.map +1 -0
  228. package/dist/tools/types.d.ts +112 -0
  229. package/dist/tools/types.js +22 -0
  230. package/dist/tools/types.js.map +1 -0
  231. package/dist/util/id.d.ts +9 -0
  232. package/dist/util/id.js +19 -0
  233. package/dist/util/id.js.map +1 -0
  234. package/dist/util/json.d.ts +25 -0
  235. package/dist/util/json.js +100 -0
  236. package/dist/util/json.js.map +1 -0
  237. package/dist/util/jwt.d.ts +74 -0
  238. package/dist/util/jwt.js +177 -0
  239. package/dist/util/jwt.js.map +1 -0
  240. package/dist/util/logger.d.ts +13 -0
  241. package/dist/util/logger.js +59 -0
  242. package/dist/util/logger.js.map +1 -0
  243. package/dist/util/queue.d.ts +26 -0
  244. package/dist/util/queue.js +106 -0
  245. package/dist/util/queue.js.map +1 -0
  246. package/dist/util/schema.d.ts +17 -0
  247. package/dist/util/schema.js +98 -0
  248. package/dist/util/schema.js.map +1 -0
  249. package/dist/util/shell.d.ts +20 -0
  250. package/dist/util/shell.js +24 -0
  251. package/dist/util/shell.js.map +1 -0
  252. package/official.json +4 -0
  253. package/package.json +38 -0
  254. package/skills/artifact-authoring/SKILL.md +81 -0
  255. package/skills/canvas/SKILL.md +85 -0
  256. package/skills/skill-authoring/SKILL.md +85 -0
@@ -0,0 +1,60 @@
1
+ import path from "node:path";
2
+ /**
3
+ * Whether to mirror, and where to.
4
+ *
5
+ * Sync is on by default, which is a decision about defaults rather than about
6
+ * consent: it cannot do anything until there is a destination and a token, and
7
+ * the token comes from signing in. So the honest reading of "on" is "as soon
8
+ * as you have an account", and a machine that never signs in never sends
9
+ * anything.
10
+ *
11
+ * Three ways to stop it, in the order they are checked. Each exists because
12
+ * the others do not cover its case:
13
+ *
14
+ * `OHARNESS_SYNC=0` one run, or every run in CI, without editing a file.
15
+ * `sync.enabled` this machine, or this repository (off only — see
16
+ * `mergeSync` on why a project cannot switch it on).
17
+ * `sync.exclude` one project, while everything else keeps mirroring.
18
+ */
19
+ /** The official service. Overridden by `sync.url` for self-hosted servers. */
20
+ export const DEFAULT_SYNC_URL = "https://sync.oharness.ai";
21
+ export function resolveSync(inputs) {
22
+ const env = inputs.env ?? process.env;
23
+ const flag = env["OHARNESS_SYNC"];
24
+ if (flag !== undefined && OFF.has(flag.trim().toLowerCase())) {
25
+ return { on: false, reason: "disabled" };
26
+ }
27
+ if (inputs.config?.enabled === false)
28
+ return { on: false, reason: "disabled" };
29
+ const url = (inputs.config?.url ?? env["OHARNESS_SYNC_URL"] ?? DEFAULT_SYNC_URL).replace(/\/+$/, "");
30
+ const token = inputs.config?.token ?? env["OHARNESS_SYNC_TOKEN"] ?? inputs.accountToken;
31
+ // Not an error: an unauthenticated harness is the normal state before the
32
+ // first sign-in, and it should behave exactly like one with sync switched
33
+ // off rather than logging a failure on every write.
34
+ if (!token)
35
+ return { on: false, reason: "no-credential" };
36
+ return { on: true, target: { url, token } };
37
+ }
38
+ /**
39
+ * Whether one project is excluded.
40
+ *
41
+ * Matched against both the project id and the worktree path, because neither
42
+ * alone is what a person reaches for: the id is a commit hash nobody has
43
+ * memorised, and the path is what they would type.
44
+ */
45
+ export function isExcluded(config, project) {
46
+ const list = config?.exclude ?? [];
47
+ if (list.length === 0)
48
+ return false;
49
+ const cwd = project.cwd ? path.resolve(project.cwd) : undefined;
50
+ return list.some((entry) => {
51
+ const trimmed = entry.trim();
52
+ if (!trimmed)
53
+ return false;
54
+ if (trimmed === project.id)
55
+ return true;
56
+ return cwd !== undefined && path.resolve(trimmed) === cwd;
57
+ });
58
+ }
59
+ const OFF = new Set(["0", "false", "off", "no"]);
60
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/sync/settings.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B;;;;;;;;;;;;;;;;GAgBG;AAEH,8EAA8E;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAG,0BAA0B,CAAC;AAyB3D,MAAM,UAAU,WAAW,CAAC,MAAkB;IAC5C,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IAEtC,MAAM,IAAI,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC;IAClC,IAAI,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;QAC7D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAC3C,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,KAAK,KAAK;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAE/E,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,mBAAmB,CAAC,IAAI,gBAAgB,CAAC,CAAC,OAAO,CACtF,MAAM,EACN,EAAE,CACH,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,GAAG,CAAC,qBAAqB,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC;IACxF,0EAA0E;IAC1E,0EAA0E;IAC1E,oDAAoD;IACpD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAE1D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC;AAC9C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,MAA8B,EAC9B,OAAqC;IAErC,MAAM,IAAI,GAAG,MAAM,EAAE,OAAO,IAAI,EAAE,CAAC;IACnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEpC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChE,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QACzB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC;QAC3B,IAAI,OAAO,KAAK,OAAO,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QACxC,OAAO,GAAG,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { MAX_ARTIFACT_BYTES } from "../../artifacts/store.ts";
2
+ /**
3
+ * Where an artifact descriptor rides back to the agent loop.
4
+ *
5
+ * On `metadata`, which the type for it says is "not sent to the model;
6
+ * available to hooks and the UI" — exactly the channel this needs. The agent
7
+ * reads it after the tool returns and turns it into an `artifact` event, since
8
+ * a tool has no way to yield into the event stream itself.
9
+ */
10
+ export declare const ARTIFACT_METADATA_KEY = "artifact";
11
+ export declare const artifactTool: import("../types.ts").Tool;
12
+ /** Read an artifact back, for a model that needs to reason over what it made. */
13
+ export declare const artifactReadTool: import("../types.ts").Tool;
14
+ /** Both artifact tools, for registries that take the pair. */
15
+ export declare const artifactTools: import("../types.ts").Tool[];
16
+ export { MAX_ARTIFACT_BYTES };
@@ -0,0 +1,134 @@
1
+ import { z } from "zod";
2
+ import { defineTool } from "../define.js";
3
+ import { toolError, toolText } from "../types.js";
4
+ import { CANVAS_MIME, getArtifactStore, MAX_ARTIFACT_BYTES } from "../../artifacts/store.js";
5
+ import { errorMessage } from "../../core/errors.js";
6
+ /**
7
+ * Where an artifact descriptor rides back to the agent loop.
8
+ *
9
+ * On `metadata`, which the type for it says is "not sent to the model;
10
+ * available to hooks and the UI" — exactly the channel this needs. The agent
11
+ * reads it after the tool returns and turns it into an `artifact` event, since
12
+ * a tool has no way to yield into the event stream itself.
13
+ */
14
+ export const ARTIFACT_METADATA_KEY = "artifact";
15
+ export const artifactTool = defineTool({
16
+ name: "artifact_write",
17
+ description: [
18
+ "Create or revise a rendered artifact: a chart, a document, a self-contained HTML page, an SVG.",
19
+ "Use this for output whose value is in being *looked at* rather than read as a tool result,",
20
+ "and which does not belong in the working tree as a file.",
21
+ "Call it again with the same `id` to revise — that keeps one artifact with a version history",
22
+ "instead of littering the panel with near-duplicates. Send the complete new content every time.",
23
+ "Prefer the `write` tool for anything the user will keep: source files, configs, real documents.",
24
+ "An artifact lives only for this session.",
25
+ // Stated here rather than only in the artifact-authoring skill because a
26
+ // skill is opt-in and this is not: an artifact that breaks this rule is
27
+ // stored, published and rendered as a blank rectangle, with nothing
28
+ // anywhere saying why. See PUBLISHED_ARTIFACT_CSP.
29
+ "HTML artifacts MUST be a single self-contained file: they run under a sandbox that blocks",
30
+ "every external resource. Scripts, stylesheets, fonts and images from a CDN or any URL will",
31
+ "NOT load (so no React, Vue, Tailwind, Chart.js or D3 from a CDN, and no JSX — there is no",
32
+ "build step), and fetch/XHR/WebSocket are blocked. Inline <style> and inline <script> do run;",
33
+ "use plain DOM, canvas or SVG, embed data as literals, and use data: URIs for images.",
34
+ // Named here and not only in the skill for the same reason the CSP rule
35
+ // is: a model that has never heard of this mime will never author one, and
36
+ // the whole editing surface stays unreachable.
37
+ `Mime \`${CANVAS_MIME}\` makes a *canvas*: a pan-and-zoom board of artboards the user can`,
38
+ "select, edit and save directly. Write only `<artboard title=\"…\" width=… height=…>` blocks",
39
+ "(plus an optional leading `<style>`) — the editor, the layout and the chrome come from the",
40
+ "harness, so do not write `<html>`, a viewport, or any pan/zoom code of your own.",
41
+ "Read the artifact-authoring skill before writing one.",
42
+ ].join(" "),
43
+ parameters: z.object({
44
+ id: z
45
+ .string()
46
+ .describe("Stable identifier, e.g. `sales-chart`. Reuse it to revise the same artifact. Letters, digits, dot, dash, underscore."),
47
+ title: z.string().min(1).describe("Human-readable name shown in the artifact list"),
48
+ mime: z
49
+ .string()
50
+ .describe("Content type: text/plain, text/markdown, text/html, image/svg+xml, application/json, " +
51
+ `${CANVAS_MIME} (an editable canvas of artboards).`),
52
+ content: z.string().describe("The complete artifact body. Replaces any previous revision."),
53
+ language: z
54
+ .string()
55
+ .optional()
56
+ .describe("Language hint for syntax highlighting when the content is source code"),
57
+ }),
58
+ // Writes to the session's in-memory store and nothing else. Before this the
59
+ // approval dialog arrived *after* the model had already written the whole
60
+ // artifact — the content is the tool's argument — so it could not prevent the
61
+ // work, only the showing of it, and it presented several kilobytes of escaped
62
+ // source as the thing to judge.
63
+ sessionLocal: true,
64
+ renderTitle: (input) => `Artifact(${input.id})`,
65
+ async execute(input, ctx) {
66
+ const store = getArtifactStore(ctx.host.state);
67
+ // Read before writing, because after the put the previous revision is no
68
+ // longer the latest and this question can no longer be asked. The model
69
+ // has no other way to find out that the version it is revising was not the
70
+ // one it wrote: it sent content derived from its own last output, and a
71
+ // person's edits are about to stop being what the user sees.
72
+ const replaced = store.get(input.id)?.revision.author === "user";
73
+ let descriptor;
74
+ try {
75
+ descriptor = store.put({
76
+ id: input.id,
77
+ title: input.title,
78
+ mime: input.mime,
79
+ content: input.content,
80
+ ...(input.language !== undefined ? { language: input.language } : {}),
81
+ });
82
+ }
83
+ catch (err) {
84
+ // The store's rules (id shape, size ceiling) come back as tool errors so
85
+ // the model can correct itself on the next turn rather than the turn
86
+ // dying on an exception.
87
+ return toolError(errorMessage(err));
88
+ }
89
+ // What goes back to the model is a receipt, not the content: it just sent
90
+ // the content, and echoing it doubles the artifact's cost in the
91
+ // transcript for no information gained.
92
+ const revision = descriptor.version === 1
93
+ ? "created"
94
+ : `revised (version ${descriptor.version} of ${descriptor.versionCount} kept)`;
95
+ return toolText(`Artifact "${descriptor.title}" ${revision}. ` +
96
+ `id=${descriptor.id} kind=${descriptor.kind} ${descriptor.bytes} bytes.` +
97
+ (replaced
98
+ ? ` Note: version ${descriptor.version - 1} was edited by the user and your revision` +
99
+ ` replaced it. Nothing is lost — read version ${descriptor.version - 1} to see what` +
100
+ ` they changed — but say so, and offer to fold their edits back in.`
101
+ : ""), { [ARTIFACT_METADATA_KEY]: descriptor });
102
+ },
103
+ });
104
+ /** Read an artifact back, for a model that needs to reason over what it made. */
105
+ export const artifactReadTool = defineTool({
106
+ name: "artifact_read",
107
+ description: "Read back the content of an artifact you created earlier in this session, optionally at a specific version.",
108
+ readOnly: true,
109
+ parameters: z.object({
110
+ id: z.string().describe("The artifact's id"),
111
+ version: z
112
+ .number()
113
+ .int()
114
+ .positive()
115
+ .optional()
116
+ .describe("Which revision to read. Defaults to the latest."),
117
+ }),
118
+ renderTitle: (input) => `ArtifactRead(${input.id}${input.version ? `@${input.version}` : ""})`,
119
+ async execute(input, ctx) {
120
+ const store = getArtifactStore(ctx.host.state);
121
+ const found = store.get(input.id, input.version);
122
+ if (!found) {
123
+ const known = store.list().map((a) => a.id);
124
+ return toolError(known.length
125
+ ? `No artifact ${input.id}${input.version ? ` at version ${input.version}` : ""}. Known: ${known.join(", ")}.`
126
+ : `No artifact ${input.id}. Nothing has been created this session.`);
127
+ }
128
+ return toolText(found.revision.content);
129
+ },
130
+ });
131
+ /** Both artifact tools, for registries that take the pair. */
132
+ export const artifactTools = [artifactTool, artifactReadTool];
133
+ export { MAX_ARTIFACT_BYTES };
134
+ //# sourceMappingURL=artifact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact.js","sourceRoot":"","sources":["../../../src/tools/builtin/artifact.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ToolResult } from "../types.ts";
2
+ export declare const bashTool: import("../types.ts").Tool;
3
+ export declare function bashResultText(result: ToolResult): string;
@@ -0,0 +1,142 @@
1
+ import { spawn } from "node:child_process";
2
+ import { isWindowsShell, shellFor } from "../../util/shell.js";
3
+ import path from "node:path";
4
+ import { z } from "zod";
5
+ import { defineTool } from "../define.js";
6
+ import { toolText } from "../types.js";
7
+ const DEFAULT_TIMEOUT_MS = 120_000;
8
+ const MAX_TIMEOUT_MS = 600_000;
9
+ const MAX_OUTPUT_CHARS = 30_000;
10
+ /**
11
+ * `cd` inside one command would otherwise be lost, because each call is its
12
+ * own process. We keep a per-session working directory instead of holding a
13
+ * long-lived shell open, which avoids a whole class of wedged-process bugs.
14
+ */
15
+ const CWD_KEY = "bash:cwd";
16
+ export const bashTool = defineTool({
17
+ name: "bash",
18
+ description: [
19
+ "Run a shell command. The working directory persists across calls within a session, so `cd` works as expected.",
20
+ "Prefer the dedicated read/write/edit/glob/grep tools for file work — they are safer and produce better output.",
21
+ "Output is truncated at 30k characters; redirect to a file and read it if you need more.",
22
+ ].join(" "),
23
+ parameters: z.object({
24
+ command: z.string().min(1).describe("The command to run"),
25
+ description: z
26
+ .string()
27
+ .optional()
28
+ .describe("Short description of what the command does, shown to the user"),
29
+ timeoutMs: z
30
+ .number()
31
+ .int()
32
+ .min(1_000)
33
+ .max(MAX_TIMEOUT_MS)
34
+ .optional()
35
+ .describe(`Timeout in milliseconds (default ${DEFAULT_TIMEOUT_MS}, max ${MAX_TIMEOUT_MS})`),
36
+ }),
37
+ renderTitle: (input) => `Bash(${input.command})`,
38
+ async execute(input, ctx) {
39
+ const cwd = sessionCwd(ctx);
40
+ const timeout = input.timeoutMs ?? DEFAULT_TIMEOUT_MS;
41
+ const result = await runShell(input.command, cwd, timeout, ctx);
42
+ if (result.newCwd)
43
+ ctx.host.state.set(CWD_KEY, result.newCwd);
44
+ const parts = [];
45
+ if (result.stdout)
46
+ parts.push(result.stdout);
47
+ if (result.stderr)
48
+ parts.push(result.stderr);
49
+ let body = parts.join("\n").trimEnd();
50
+ if (body.length > MAX_OUTPUT_CHARS) {
51
+ const kept = body.slice(0, MAX_OUTPUT_CHARS);
52
+ body = `${kept}\n\n… output truncated (${body.length - MAX_OUTPUT_CHARS} more characters).`;
53
+ }
54
+ if (result.timedOut) {
55
+ return {
56
+ content: [
57
+ {
58
+ type: "text",
59
+ text: `Command timed out after ${timeout}ms and was killed.\n${body}`.trimEnd(),
60
+ },
61
+ ],
62
+ isError: true,
63
+ metadata: { exitCode: null, timedOut: true, cwd },
64
+ };
65
+ }
66
+ if (result.code !== 0) {
67
+ return {
68
+ content: [
69
+ { type: "text", text: `Exit code ${result.code}\n${body}`.trimEnd() },
70
+ ],
71
+ isError: true,
72
+ metadata: { exitCode: result.code, cwd },
73
+ };
74
+ }
75
+ return toolText(body === "" ? "(no output)" : body, { exitCode: 0, cwd });
76
+ },
77
+ });
78
+ function sessionCwd(ctx) {
79
+ const stored = ctx.host.state.get(CWD_KEY);
80
+ return typeof stored === "string" ? stored : ctx.cwd;
81
+ }
82
+ /**
83
+ * Runs the command and then echoes the resulting directory on a sentinel line,
84
+ * so a `cd` performed by the command carries into the next call.
85
+ */
86
+ function runShell(command, cwd, timeoutMs, ctx) {
87
+ const sentinel = "__OHARNESS_CWD__";
88
+ // cmd.exe has no $PWD, no `printf` and no `exit $?` — the probe that tracks
89
+ // directory changes has to be written in each shell's own dialect.
90
+ const wrapped = isWindowsShell()
91
+ ? `${command}\r\n@set __oh_status=%ERRORLEVEL%\r\n@echo.\r\n@echo ${sentinel}%CD%\r\n@exit /b %__oh_status%`
92
+ : `${command}\n__oh_status=$?\nprintf '\\n${sentinel}%s\\n' "$PWD"\nexit $__oh_status`;
93
+ const shell = shellFor(wrapped);
94
+ return new Promise((resolve) => {
95
+ const child = spawn(shell.command, shell.args, {
96
+ cwd,
97
+ env: { ...process.env, OHARNESS_SESSION: ctx.sessionId },
98
+ });
99
+ let stdout = "";
100
+ let stderr = "";
101
+ let timedOut = false;
102
+ let settled = false;
103
+ const timer = setTimeout(() => {
104
+ timedOut = true;
105
+ child.kill("SIGKILL");
106
+ }, timeoutMs);
107
+ const onAbort = () => child.kill("SIGKILL");
108
+ ctx.signal.addEventListener("abort", onAbort, { once: true });
109
+ const finish = (code) => {
110
+ if (settled)
111
+ return;
112
+ settled = true;
113
+ clearTimeout(timer);
114
+ ctx.signal.removeEventListener("abort", onAbort);
115
+ let newCwd;
116
+ const marker = stdout.lastIndexOf(sentinel);
117
+ if (marker !== -1) {
118
+ const end = stdout.indexOf("\n", marker);
119
+ const value = stdout.slice(marker + sentinel.length, end === -1 ? undefined : end).trim();
120
+ if (value)
121
+ newCwd = path.resolve(value);
122
+ stdout = stdout.slice(0, marker).trimEnd();
123
+ }
124
+ resolve({ code, stdout, stderr, timedOut, newCwd });
125
+ };
126
+ child.stdout.on("data", (chunk) => {
127
+ stdout += chunk.toString();
128
+ });
129
+ child.stderr.on("data", (chunk) => {
130
+ stderr += chunk.toString();
131
+ });
132
+ child.on("error", (err) => {
133
+ stderr += `\n${String(err)}`;
134
+ finish(127);
135
+ });
136
+ child.on("close", (code) => finish(code));
137
+ });
138
+ }
139
+ export function bashResultText(result) {
140
+ return result.content.map((b) => (b.type === "text" ? b.text : "")).join("");
141
+ }
142
+ //# sourceMappingURL=bash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../../src/tools/builtin/bash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,MAAM,kBAAkB,GAAG,OAAO,CAAC;AACnC,MAAM,cAAc,GAAG,OAAO,CAAC;AAC/B,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC;;;;GAIG;AACH,MAAM,OAAO,GAAG,UAAU,CAAC;AAE3B,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;IACjC,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE;QACX,+GAA+G;QAC/G,gHAAgH;QAChH,yFAAyF;KAC1F,CAAC,IAAI,CAAC,GAAG,CAAC;IACX,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;QACnB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QACzD,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,+DAA+D,CAAC;QAC5E,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,KAAK,CAAC;aACV,GAAG,CAAC,cAAc,CAAC;aACnB,QAAQ,EAAE;aACV,QAAQ,CAAC,oCAAoC,kBAAkB,SAAS,cAAc,GAAG,CAAC;KAC9F,CAAC;IACF,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,KAAK,CAAC,OAAO,GAAG;IAChD,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG;QACtB,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,IAAI,kBAAkB,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;QAEhE,IAAI,MAAM,CAAC,MAAM;YAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAE9D,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,MAAM,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7C,IAAI,MAAM,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7C,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QAEtC,IAAI,IAAI,CAAC,MAAM,GAAG,gBAAgB,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;YAC7C,IAAI,GAAG,GAAG,IAAI,2BAA2B,IAAI,CAAC,MAAM,GAAG,gBAAgB,oBAAoB,CAAC;QAC9F,CAAC;QAED,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,2BAA2B,OAAO,uBAAuB,IAAI,EAAE,CAAC,OAAO,EAAE;qBAChF;iBACF;gBACD,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE;aAClD,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE;iBACtE;gBACD,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;aACzC,CAAC;QACJ,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5E,CAAC;CACF,CAAC,CAAC;AAEH,SAAS,UAAU,CAAC,GAAgB;IAClC,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3C,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACvD,CAAC;AAUD;;;GAGG;AACH,SAAS,QAAQ,CACf,OAAe,EACf,GAAW,EACX,SAAiB,EACjB,GAAgB;IAEhB,MAAM,QAAQ,GAAG,kBAAkB,CAAC;IACpC,4EAA4E;IAC5E,mEAAmE;IACnE,MAAM,OAAO,GAAG,cAAc,EAAE;QAC9B,CAAC,CAAC,GAAG,OAAO,wDAAwD,QAAQ,gCAAgC;QAC5G,CAAC,CAAC,GAAG,OAAO,gCAAgC,QAAQ,kCAAkC,CAAC;IAEzF,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAEhC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE;YAC7C,GAAG;YACH,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,gBAAgB,EAAE,GAAG,CAAC,SAAS,EAAE;SACzD,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,QAAQ,GAAG,IAAI,CAAC;YAChB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxB,CAAC,EAAE,SAAS,CAAC,CAAC;QAEd,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5C,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAE9D,MAAM,MAAM,GAAG,CAAC,IAAmB,EAAE,EAAE;YACrC,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,GAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAEjD,IAAI,MAA0B,CAAC;YAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YAC5C,IAAI,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;gBAClB,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBACzC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC1F,IAAI,KAAK;oBAAE,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBACxC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;YAC7C,CAAC;YAED,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QACtD,CAAC,CAAC;QAEF,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACxC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACxC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,MAAM,IAAI,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAkB;IAC/C,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC/E,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { ToolContext } from "../types.ts";
2
+ /**
3
+ * Resolve a model-supplied path and keep it inside the roots the agent is
4
+ * allowed to touch.
5
+ *
6
+ * Defers to the host, which owns the workspace policy and therefore knows
7
+ * about roots beyond the working directory — the user-level skills directory
8
+ * the skill registry loads from, for one, which this used to refuse to read or
9
+ * write while the harness happily loaded skills out of it.
10
+ *
11
+ * The fallback is for a host without a policy: confine to the working
12
+ * directory, which is what this did unconditionally before.
13
+ */
14
+ export declare function resolvePath(ctx: ToolContext, input: string, access?: "read" | "write"): string;
15
+ export declare const readTool: import("../types.ts").Tool;
16
+ export declare const writeTool: import("../types.ts").Tool;
17
+ export declare const editTool: import("../types.ts").Tool;
18
+ export declare const listTool: import("../types.ts").Tool;
19
+ export declare const fileTools: import("../types.ts").Tool[];