@autonav/core 1.6.0 → 1.8.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 (247) hide show
  1. package/README.md +2 -2
  2. package/dist/adapter/index.d.ts +3 -3
  3. package/dist/adapter/index.d.ts.map +1 -1
  4. package/dist/adapter/index.js +3 -3
  5. package/dist/adapter/index.js.map +1 -1
  6. package/dist/adapter/{claude-adapter.d.ts → navigator-adapter.d.ts} +18 -11
  7. package/dist/adapter/navigator-adapter.d.ts.map +1 -0
  8. package/dist/adapter/{claude-adapter.js → navigator-adapter.js} +165 -127
  9. package/dist/adapter/navigator-adapter.js.map +1 -0
  10. package/dist/cli/autonav.d.ts +2 -6
  11. package/dist/cli/autonav.d.ts.map +1 -1
  12. package/dist/cli/autonav.js +32 -53
  13. package/dist/cli/autonav.js.map +1 -1
  14. package/dist/cli/nav-chat.d.ts +2 -1
  15. package/dist/cli/nav-chat.d.ts.map +1 -1
  16. package/dist/cli/nav-chat.js +35 -4
  17. package/dist/cli/nav-chat.js.map +1 -1
  18. package/dist/cli/nav-init.d.ts +2 -1
  19. package/dist/cli/nav-init.d.ts.map +1 -1
  20. package/dist/cli/nav-init.js +12 -4
  21. package/dist/cli/nav-init.js.map +1 -1
  22. package/dist/cli/nav-install.d.ts +2 -1
  23. package/dist/cli/nav-install.d.ts.map +1 -1
  24. package/dist/cli/nav-install.js +4 -2
  25. package/dist/cli/nav-install.js.map +1 -1
  26. package/dist/cli/nav-memento.d.ts +3 -2
  27. package/dist/cli/nav-memento.d.ts.map +1 -1
  28. package/dist/cli/nav-memento.js +12 -6
  29. package/dist/cli/nav-memento.js.map +1 -1
  30. package/dist/cli/nav-mend.d.ts +2 -1
  31. package/dist/cli/nav-mend.d.ts.map +1 -1
  32. package/dist/cli/nav-mend.js +4 -1
  33. package/dist/cli/nav-mend.js.map +1 -1
  34. package/dist/cli/nav-migrate.d.ts +2 -1
  35. package/dist/cli/nav-migrate.d.ts.map +1 -1
  36. package/dist/cli/nav-migrate.js +2 -6
  37. package/dist/cli/nav-migrate.js.map +1 -1
  38. package/dist/cli/nav-query.d.ts +2 -1
  39. package/dist/cli/nav-query.d.ts.map +1 -1
  40. package/dist/cli/nav-query.js +12 -6
  41. package/dist/cli/nav-query.js.map +1 -1
  42. package/dist/cli/nav-standup.d.ts +18 -0
  43. package/dist/cli/nav-standup.d.ts.map +1 -0
  44. package/dist/cli/nav-standup.js +151 -0
  45. package/dist/cli/nav-standup.js.map +1 -0
  46. package/dist/cli/nav-uninstall.d.ts +2 -1
  47. package/dist/cli/nav-uninstall.d.ts.map +1 -1
  48. package/dist/cli/nav-uninstall.js +4 -2
  49. package/dist/cli/nav-uninstall.js.map +1 -1
  50. package/dist/cli/nav-update.d.ts +2 -1
  51. package/dist/cli/nav-update.d.ts.map +1 -1
  52. package/dist/cli/nav-update.js +11 -6
  53. package/dist/cli/nav-update.js.map +1 -1
  54. package/dist/conversation/App.d.ts +11 -2
  55. package/dist/conversation/App.d.ts.map +1 -1
  56. package/dist/conversation/App.js +305 -112
  57. package/dist/conversation/App.js.map +1 -1
  58. package/dist/conversation/index.d.ts +7 -0
  59. package/dist/conversation/index.d.ts.map +1 -1
  60. package/dist/conversation/index.js +17 -2
  61. package/dist/conversation/index.js.map +1 -1
  62. package/dist/conversation/prompts.d.ts +1 -1
  63. package/dist/conversation/prompts.d.ts.map +1 -1
  64. package/dist/conversation/prompts.js +42 -1
  65. package/dist/conversation/prompts.js.map +1 -1
  66. package/dist/harness/chibi-harness.d.ts +36 -0
  67. package/dist/harness/chibi-harness.d.ts.map +1 -0
  68. package/dist/harness/chibi-harness.js +383 -0
  69. package/dist/harness/chibi-harness.js.map +1 -0
  70. package/dist/harness/chibi-plugins/get_plugin_config +64 -0
  71. package/dist/harness/chibi-plugins/query_navigator +114 -0
  72. package/dist/harness/chibi-plugins/submit_answer +38 -0
  73. package/dist/harness/chibi-plugins/update_plugin_config +91 -0
  74. package/dist/harness/claude-code-harness.d.ts +24 -0
  75. package/dist/harness/claude-code-harness.d.ts.map +1 -0
  76. package/dist/harness/claude-code-harness.js +242 -0
  77. package/dist/harness/claude-code-harness.js.map +1 -0
  78. package/dist/harness/ephemeral-home.d.ts +34 -0
  79. package/dist/harness/ephemeral-home.d.ts.map +1 -0
  80. package/dist/harness/ephemeral-home.js +56 -0
  81. package/dist/harness/ephemeral-home.js.map +1 -0
  82. package/dist/harness/factory.d.ts +47 -0
  83. package/dist/harness/factory.d.ts.map +1 -0
  84. package/dist/harness/factory.js +84 -0
  85. package/dist/harness/factory.js.map +1 -0
  86. package/dist/harness/helpers.d.ts +58 -0
  87. package/dist/harness/helpers.d.ts.map +1 -0
  88. package/dist/harness/helpers.js +78 -0
  89. package/dist/harness/helpers.js.map +1 -0
  90. package/dist/harness/index.d.ts +14 -0
  91. package/dist/harness/index.d.ts.map +1 -0
  92. package/dist/harness/index.js +13 -0
  93. package/dist/harness/index.js.map +1 -0
  94. package/dist/harness/opencode-harness.d.ts +79 -0
  95. package/dist/harness/opencode-harness.d.ts.map +1 -0
  96. package/dist/harness/opencode-harness.js +537 -0
  97. package/dist/harness/opencode-harness.js.map +1 -0
  98. package/dist/harness/opencode-tools/get_plugin_config.ts +72 -0
  99. package/dist/harness/opencode-tools/query_navigator.ts +126 -0
  100. package/dist/harness/opencode-tools/submit_answer.ts +40 -0
  101. package/dist/harness/opencode-tools/update_plugin_config.ts +105 -0
  102. package/dist/harness/sandbox.d.ts +59 -0
  103. package/dist/harness/sandbox.d.ts.map +1 -0
  104. package/dist/harness/sandbox.js +152 -0
  105. package/dist/harness/sandbox.js.map +1 -0
  106. package/dist/harness/tool-server.d.ts +50 -0
  107. package/dist/harness/tool-server.d.ts.map +1 -0
  108. package/dist/harness/tool-server.js +27 -0
  109. package/dist/harness/tool-server.js.map +1 -0
  110. package/dist/harness/types.d.ts +168 -0
  111. package/dist/harness/types.d.ts.map +1 -0
  112. package/dist/harness/types.js +12 -0
  113. package/dist/harness/types.js.map +1 -0
  114. package/dist/index.d.ts +3 -2
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +4 -2
  117. package/dist/index.js.map +1 -1
  118. package/dist/interview/App.d.ts +4 -2
  119. package/dist/interview/App.d.ts.map +1 -1
  120. package/dist/interview/App.js +36 -56
  121. package/dist/interview/App.js.map +1 -1
  122. package/dist/interview/index.d.ts +3 -0
  123. package/dist/interview/index.d.ts.map +1 -1
  124. package/dist/interview/index.js +1 -0
  125. package/dist/interview/index.js.map +1 -1
  126. package/dist/interview/prompts.d.ts +3 -1
  127. package/dist/interview/prompts.d.ts.map +1 -1
  128. package/dist/interview/prompts.js +14 -1
  129. package/dist/interview/prompts.js.map +1 -1
  130. package/dist/interview/ui/ChatBanner.d.ts +17 -0
  131. package/dist/interview/ui/ChatBanner.d.ts.map +1 -0
  132. package/dist/interview/ui/ChatBanner.js +30 -0
  133. package/dist/interview/ui/ChatBanner.js.map +1 -0
  134. package/dist/interview/ui/ChatInput.d.ts +36 -0
  135. package/dist/interview/ui/ChatInput.d.ts.map +1 -0
  136. package/dist/interview/ui/ChatInput.js +304 -0
  137. package/dist/interview/ui/ChatInput.js.map +1 -0
  138. package/dist/interview/ui/MarkdownText.d.ts +13 -0
  139. package/dist/interview/ui/MarkdownText.d.ts.map +1 -0
  140. package/dist/interview/ui/MarkdownText.js +107 -0
  141. package/dist/interview/ui/MarkdownText.js.map +1 -0
  142. package/dist/interview/ui/index.d.ts +3 -0
  143. package/dist/interview/ui/index.d.ts.map +1 -1
  144. package/dist/interview/ui/index.js +3 -0
  145. package/dist/interview/ui/index.js.map +1 -1
  146. package/dist/memento/implementer-agent.d.ts +31 -0
  147. package/dist/memento/implementer-agent.d.ts.map +1 -0
  148. package/dist/memento/implementer-agent.js +95 -0
  149. package/dist/memento/implementer-agent.js.map +1 -0
  150. package/dist/memento/index.d.ts +6 -5
  151. package/dist/memento/index.d.ts.map +1 -1
  152. package/dist/memento/index.js +7 -5
  153. package/dist/memento/index.js.map +1 -1
  154. package/dist/memento/loop.d.ts +6 -5
  155. package/dist/memento/loop.d.ts.map +1 -1
  156. package/dist/memento/loop.js +872 -180
  157. package/dist/memento/loop.js.map +1 -1
  158. package/dist/memento/matrix-animation.d.ts +26 -0
  159. package/dist/memento/matrix-animation.d.ts.map +1 -1
  160. package/dist/memento/matrix-animation.js +93 -18
  161. package/dist/memento/matrix-animation.js.map +1 -1
  162. package/dist/memento/nav-protocol.d.ts +2 -2
  163. package/dist/memento/nav-protocol.d.ts.map +1 -1
  164. package/dist/memento/nav-protocol.js +39 -43
  165. package/dist/memento/nav-protocol.js.map +1 -1
  166. package/dist/memento/prompts.d.ts +21 -8
  167. package/dist/memento/prompts.d.ts.map +1 -1
  168. package/dist/memento/prompts.js +79 -39
  169. package/dist/memento/prompts.js.map +1 -1
  170. package/dist/memento/rate-limit.d.ts +85 -0
  171. package/dist/memento/rate-limit.d.ts.map +1 -0
  172. package/dist/memento/rate-limit.js +221 -0
  173. package/dist/memento/rate-limit.js.map +1 -0
  174. package/dist/memento/types.d.ts +6 -6
  175. package/dist/memento/types.d.ts.map +1 -1
  176. package/dist/memento/types.js +3 -3
  177. package/dist/registry.d.ts +35 -0
  178. package/dist/registry.d.ts.map +1 -0
  179. package/dist/registry.js +87 -0
  180. package/dist/registry.js.map +1 -0
  181. package/dist/repo-analyzer/index.d.ts +2 -1
  182. package/dist/repo-analyzer/index.d.ts.map +1 -1
  183. package/dist/repo-analyzer/index.js +6 -17
  184. package/dist/repo-analyzer/index.js.map +1 -1
  185. package/dist/standup/config.d.ts +19 -0
  186. package/dist/standup/config.d.ts.map +1 -0
  187. package/dist/standup/config.js +42 -0
  188. package/dist/standup/config.js.map +1 -0
  189. package/dist/standup/index.d.ts +24 -0
  190. package/dist/standup/index.d.ts.map +1 -0
  191. package/dist/standup/index.js +29 -0
  192. package/dist/standup/index.js.map +1 -0
  193. package/dist/standup/loop.d.ts +36 -0
  194. package/dist/standup/loop.d.ts.map +1 -0
  195. package/dist/standup/loop.js +508 -0
  196. package/dist/standup/loop.js.map +1 -0
  197. package/dist/standup/prompts.d.ts +62 -0
  198. package/dist/standup/prompts.d.ts.map +1 -0
  199. package/dist/standup/prompts.js +211 -0
  200. package/dist/standup/prompts.js.map +1 -0
  201. package/dist/standup/standup-protocol.d.ts +33 -0
  202. package/dist/standup/standup-protocol.d.ts.map +1 -0
  203. package/dist/standup/standup-protocol.js +189 -0
  204. package/dist/standup/standup-protocol.js.map +1 -0
  205. package/dist/standup/types.d.ts +185 -0
  206. package/dist/standup/types.d.ts.map +1 -0
  207. package/dist/standup/types.js +67 -0
  208. package/dist/standup/types.js.map +1 -0
  209. package/dist/tools/cross-nav.d.ts +21 -0
  210. package/dist/tools/cross-nav.d.ts.map +1 -0
  211. package/dist/tools/cross-nav.js +93 -0
  212. package/dist/tools/cross-nav.js.map +1 -0
  213. package/dist/tools/index.d.ts +1 -0
  214. package/dist/tools/index.d.ts.map +1 -1
  215. package/dist/tools/index.js +1 -0
  216. package/dist/tools/index.js.map +1 -1
  217. package/dist/tools/related-navs-config.d.ts +15 -0
  218. package/dist/tools/related-navs-config.d.ts.map +1 -0
  219. package/dist/tools/related-navs-config.js +132 -0
  220. package/dist/tools/related-navs-config.js.map +1 -0
  221. package/dist/tools/related-navs.d.ts +23 -0
  222. package/dist/tools/related-navs.d.ts.map +1 -0
  223. package/dist/tools/related-navs.js +107 -0
  224. package/dist/tools/related-navs.js.map +1 -0
  225. package/dist/tools/response.d.ts +3 -2
  226. package/dist/tools/response.d.ts.map +1 -1
  227. package/dist/tools/response.js +7 -11
  228. package/dist/tools/response.js.map +1 -1
  229. package/dist/tools/self-config.d.ts +2 -1
  230. package/dist/tools/self-config.d.ts.map +1 -1
  231. package/dist/tools/self-config.js +5 -9
  232. package/dist/tools/self-config.js.map +1 -1
  233. package/package.json +7 -4
  234. package/dist/adapter/claude-adapter.d.ts.map +0 -1
  235. package/dist/adapter/claude-adapter.js.map +0 -1
  236. package/dist/memento/state.d.ts +0 -56
  237. package/dist/memento/state.d.ts.map +0 -1
  238. package/dist/memento/state.js +0 -156
  239. package/dist/memento/state.js.map +0 -1
  240. package/dist/memento/worker-agent.d.ts +0 -30
  241. package/dist/memento/worker-agent.d.ts.map +0 -1
  242. package/dist/memento/worker-agent.js +0 -109
  243. package/dist/memento/worker-agent.js.map +0 -1
  244. package/dist/migrations/versions/v1.4.0-rfc2119-skills.d.ts +0 -18
  245. package/dist/migrations/versions/v1.4.0-rfc2119-skills.d.ts.map +0 -1
  246. package/dist/migrations/versions/v1.4.0-rfc2119-skills.js +0 -207
  247. package/dist/migrations/versions/v1.4.0-rfc2119-skills.js.map +0 -1
@@ -0,0 +1,126 @@
1
+ /**
2
+ * query_navigator — OpenCode custom tool
3
+ *
4
+ * Queries another navigator by spawning an opencode subprocess.
5
+ * Cycle detection via AUTONAV_QUERY_DEPTH env var (max 3).
6
+ *
7
+ * Runs inside OpenCode's Bun runtime via .opencode/tools/.
8
+ */
9
+ import { tool } from "@opencode-ai/plugin"
10
+ import { execFileSync, type ExecFileSyncOptions } from "node:child_process"
11
+ import { readFileSync, existsSync } from "node:fs"
12
+ import { join, resolve } from "node:path"
13
+
14
+ export default tool({
15
+ name: "query_navigator",
16
+ description:
17
+ "Ask another navigator a question. Use this when you need information from a different navigator's knowledge base. The target navigator will search its own knowledge and return an answer.",
18
+ args: {
19
+ navigator: tool.schema
20
+ .string()
21
+ .describe(
22
+ "Path to the target navigator directory (relative to cwd or absolute)",
23
+ ),
24
+ question: tool.schema
25
+ .string()
26
+ .describe("The question to ask the target navigator"),
27
+ },
28
+ async execute(input: { navigator: string; question: string }) {
29
+ const { navigator, question } = input
30
+
31
+ if (!navigator || !question) {
32
+ return JSON.stringify({
33
+ success: false,
34
+ error: "Missing required fields: navigator and question",
35
+ })
36
+ }
37
+
38
+ // Cycle detection
39
+ const depth = parseInt(process.env.AUTONAV_QUERY_DEPTH || "0", 10)
40
+ if (depth >= 3) {
41
+ return JSON.stringify({
42
+ success: false,
43
+ error:
44
+ "Query depth limit reached (max 3). Cannot query another navigator from this depth.",
45
+ })
46
+ }
47
+
48
+ const navPath = resolve(navigator)
49
+ if (!existsSync(navPath)) {
50
+ return JSON.stringify({
51
+ success: false,
52
+ error: `Navigator directory not found: ${navPath}`,
53
+ })
54
+ }
55
+
56
+ const configFile = join(navPath, "config.json")
57
+ if (!existsSync(configFile)) {
58
+ return JSON.stringify({
59
+ success: false,
60
+ error: "Navigator config.json not found.",
61
+ })
62
+ }
63
+
64
+ let navName = "unknown"
65
+ let instructionsPath = "CLAUDE.md"
66
+ try {
67
+ const config = JSON.parse(readFileSync(configFile, "utf-8"))
68
+ navName = config.name || "unknown"
69
+ instructionsPath = config.instructionsPath || "CLAUDE.md"
70
+ } catch {
71
+ return JSON.stringify({
72
+ success: false,
73
+ error: "Failed to parse navigator config.json",
74
+ })
75
+ }
76
+
77
+ const promptFile = join(navPath, instructionsPath)
78
+ if (!existsSync(promptFile)) {
79
+ return JSON.stringify({
80
+ success: false,
81
+ error: `Navigator instructions file not found: ${instructionsPath}`,
82
+ })
83
+ }
84
+
85
+ try {
86
+ const opts: ExecFileSyncOptions = {
87
+ timeout: 120_000,
88
+ env: {
89
+ ...process.env,
90
+ AUTONAV_QUERY_DEPTH: String(depth + 1),
91
+ },
92
+ encoding: "utf-8",
93
+ }
94
+
95
+ // Use opencode run for a one-shot query
96
+ const result = execFileSync(
97
+ "opencode",
98
+ ["run", "--dir", navPath, question],
99
+ opts,
100
+ )
101
+
102
+ const response = typeof result === "string" ? result.trim() : ""
103
+
104
+ if (response) {
105
+ return JSON.stringify({
106
+ success: true,
107
+ navigator: navName,
108
+ response,
109
+ })
110
+ } else {
111
+ return JSON.stringify({
112
+ success: false,
113
+ navigator: navName,
114
+ error: "Navigator returned empty response.",
115
+ })
116
+ }
117
+ } catch (err) {
118
+ const msg = err instanceof Error ? err.message : String(err)
119
+ return JSON.stringify({
120
+ success: false,
121
+ navigator: navName,
122
+ error: `Query failed: ${msg}`,
123
+ })
124
+ }
125
+ },
126
+ })
@@ -0,0 +1,40 @@
1
+ /**
2
+ * submit_answer — OpenCode custom tool
3
+ *
4
+ * Provides the submit_answer tool so the LLM can return structured responses
5
+ * with source citations. The NavigatorAdapter intercepts the tool_use event
6
+ * from the event stream — this tool just needs to exist and return success.
7
+ *
8
+ * Runs inside OpenCode's Bun runtime via .opencode/tools/.
9
+ */
10
+ import { tool } from "@opencode-ai/plugin"
11
+
12
+ export default tool({
13
+ name: "submit_answer",
14
+ description:
15
+ "Submit your final answer. You MUST use this tool to provide your response with proper source citations.",
16
+ args: {
17
+ answer: tool.schema
18
+ .string()
19
+ .describe("Your complete answer grounded in the knowledge base."),
20
+ sources: tool.schema
21
+ .string()
22
+ .describe(
23
+ 'JSON array of source citations from the knowledge base. Each with "file", "section", "relevance".',
24
+ ),
25
+ confidence: tool.schema
26
+ .number()
27
+ .describe(
28
+ "Confidence score from 0.0 (no confidence) to 1.0 (fully confident). 0.9+ = high, 0.45-0.89 = medium, below 0.45 = low.",
29
+ ),
30
+ confidenceReason: tool.schema
31
+ .string()
32
+ .describe("Brief explanation of your confidence level."),
33
+ outOfDomain: tool.schema
34
+ .boolean()
35
+ .describe("Whether the question is outside your knowledge domain."),
36
+ },
37
+ async execute() {
38
+ return "Answer submitted successfully."
39
+ },
40
+ })
@@ -0,0 +1,105 @@
1
+ /**
2
+ * update_plugin_config — OpenCode custom tool
3
+ *
4
+ * Reads plugins.json, merges updates into a plugin's config section,
5
+ * and writes back. Requires AUTONAV_PLUGINS_PATH.
6
+ *
7
+ * Runs inside OpenCode's Bun runtime via .opencode/tools/.
8
+ */
9
+ import { tool } from "@opencode-ai/plugin"
10
+ import { readFileSync, writeFileSync, existsSync } from "node:fs"
11
+
12
+ export default tool({
13
+ name: "update_plugin_config",
14
+ description:
15
+ "Update your own plugin configuration. Use this to schedule check-ins, change notification settings, enable/disable plugins, update channel preferences, or modify any plugin behavior.",
16
+ args: {
17
+ plugin: tool.schema
18
+ .string()
19
+ .describe(
20
+ 'The plugin to configure ("slack", "signal", "github", "email")',
21
+ ),
22
+ updates: tool.schema
23
+ .string()
24
+ .describe(
25
+ "JSON object of config key-value pairs to merge into the plugin's config section",
26
+ ),
27
+ reason: tool.schema
28
+ .string()
29
+ .describe("Brief explanation of why you're making this change"),
30
+ },
31
+ async execute(input: { plugin: string; updates: string; reason: string }) {
32
+ const { plugin, reason } = input
33
+
34
+ let updates: Record<string, unknown>
35
+ try {
36
+ updates = JSON.parse(input.updates)
37
+ } catch {
38
+ return JSON.stringify({
39
+ success: false,
40
+ error: "Invalid JSON in updates field",
41
+ })
42
+ }
43
+
44
+ if (!plugin || !updates || !reason) {
45
+ return JSON.stringify({
46
+ success: false,
47
+ error: "Missing required fields: plugin, updates, and reason",
48
+ })
49
+ }
50
+
51
+ const validPlugins = ["slack", "signal", "github", "email"]
52
+ if (!validPlugins.includes(plugin)) {
53
+ return JSON.stringify({
54
+ success: false,
55
+ error: `Unknown plugin: ${plugin}. Valid: ${validPlugins.join(", ")}`,
56
+ })
57
+ }
58
+
59
+ const configPath = process.env.AUTONAV_PLUGINS_PATH
60
+ if (!configPath) {
61
+ return JSON.stringify({
62
+ success: false,
63
+ error: "AUTONAV_PLUGINS_PATH not set. Plugin configuration unavailable.",
64
+ })
65
+ }
66
+
67
+ if (!existsSync(configPath)) {
68
+ return JSON.stringify({
69
+ success: false,
70
+ error: "Plugin configuration file not found.",
71
+ })
72
+ }
73
+
74
+ try {
75
+ const current = JSON.parse(readFileSync(configPath, "utf-8"))
76
+
77
+ // Ensure plugin section exists
78
+ if (!current[plugin]) {
79
+ current[plugin] = { enabled: false, config: {} }
80
+ }
81
+ if (!current[plugin].config) {
82
+ current[plugin].config = {}
83
+ }
84
+
85
+ // Merge updates into the plugin's config section
86
+ Object.assign(current[plugin].config, updates)
87
+
88
+ // Write back
89
+ writeFileSync(configPath, JSON.stringify(current, null, 2) + "\n")
90
+
91
+ return JSON.stringify({
92
+ success: true,
93
+ plugin,
94
+ message: `Updated ${plugin} config: ${reason}`,
95
+ changes: updates,
96
+ })
97
+ } catch (err) {
98
+ const msg = err instanceof Error ? err.message : String(err)
99
+ return JSON.stringify({
100
+ success: false,
101
+ error: `Failed to update plugin config: ${msg}`,
102
+ })
103
+ }
104
+ },
105
+ })
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Sandbox Utility (nono)
3
+ *
4
+ * Wraps subprocess commands with nono.sh for kernel-enforced sandboxing
5
+ * (Landlock on Linux, Seatbelt on macOS). Used by ChibiHarness to sandbox
6
+ * chibi-json subprocesses.
7
+ *
8
+ * ClaudeCodeHarness uses the SDK's built-in sandbox instead (also
9
+ * Seatbelt/bubblewrap). Both harnesses read from AgentConfig.sandbox —
10
+ * callers never need to know which mechanism is active.
11
+ *
12
+ * Per-operation sandbox profiles:
13
+ * - query: read-only access to navigator directory
14
+ * - update: read+write access to navigator directory
15
+ * - chat/standup: configured per-operation (default: enabled)
16
+ * - memento: default disabled (worker needs full code access)
17
+ *
18
+ * Note: blockNetwork should NOT be used with harnesses that make their
19
+ * own API calls (chibi). It's only useful for scenarios where the API
20
+ * connection is managed in-process.
21
+ *
22
+ * Falls back gracefully when nono is not installed — the process runs
23
+ * without sandboxing.
24
+ */
25
+ import type { SandboxConfig } from "./types.js";
26
+ /**
27
+ * Check if nono is available on PATH (result is cached).
28
+ */
29
+ export declare function isNonoAvailable(): boolean;
30
+ /**
31
+ * Resolve whether sandboxing should be active for this session.
32
+ *
33
+ * Priority:
34
+ * 1. config.enabled (explicit opt-in/out)
35
+ * 2. AUTONAV_SANDBOX env var ("0" to disable)
36
+ * 3. Auto-detect nono on PATH
37
+ */
38
+ export declare function isSandboxEnabled(config?: SandboxConfig): boolean;
39
+ /**
40
+ * Build nono CLI arguments for a given sandbox config.
41
+ *
42
+ * Returns the full argument list: ["run", "--silent", ...flags, "--"]
43
+ * Returns empty array if sandbox is disabled.
44
+ */
45
+ export declare function buildSandboxArgs(config: SandboxConfig): string[];
46
+ /**
47
+ * Wrap a command with nono sandbox if enabled.
48
+ *
49
+ * If sandboxing is active:
50
+ * { command: "nono", args: ["run", ...flags, "--", originalCommand, ...originalArgs] }
51
+ *
52
+ * If disabled:
53
+ * { command: originalCommand, args: originalArgs } (passthrough)
54
+ */
55
+ export declare function wrapCommand(command: string, args: string[], config?: SandboxConfig): {
56
+ command: string;
57
+ args: string[];
58
+ };
59
+ //# sourceMappingURL=sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/harness/sandbox.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAgBzC;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAahE;AA4BD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,EAAE,CAmChE;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,CAAC,EAAE,aAAa,GACrB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAcrC"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Sandbox Utility (nono)
3
+ *
4
+ * Wraps subprocess commands with nono.sh for kernel-enforced sandboxing
5
+ * (Landlock on Linux, Seatbelt on macOS). Used by ChibiHarness to sandbox
6
+ * chibi-json subprocesses.
7
+ *
8
+ * ClaudeCodeHarness uses the SDK's built-in sandbox instead (also
9
+ * Seatbelt/bubblewrap). Both harnesses read from AgentConfig.sandbox —
10
+ * callers never need to know which mechanism is active.
11
+ *
12
+ * Per-operation sandbox profiles:
13
+ * - query: read-only access to navigator directory
14
+ * - update: read+write access to navigator directory
15
+ * - chat/standup: configured per-operation (default: enabled)
16
+ * - memento: default disabled (worker needs full code access)
17
+ *
18
+ * Note: blockNetwork should NOT be used with harnesses that make their
19
+ * own API calls (chibi). It's only useful for scenarios where the API
20
+ * connection is managed in-process.
21
+ *
22
+ * Falls back gracefully when nono is not installed — the process runs
23
+ * without sandboxing.
24
+ */
25
+ import { execFileSync } from "node:child_process";
26
+ import * as fs from "node:fs";
27
+ import * as os from "node:os";
28
+ let nonoAvailableCache = null;
29
+ /**
30
+ * Check if nono is available on PATH (result is cached).
31
+ */
32
+ export function isNonoAvailable() {
33
+ if (nonoAvailableCache !== null) {
34
+ return nonoAvailableCache;
35
+ }
36
+ try {
37
+ execFileSync("nono", ["--version"], {
38
+ stdio: ["ignore", "ignore", "ignore"],
39
+ timeout: 3_000,
40
+ });
41
+ nonoAvailableCache = true;
42
+ }
43
+ catch {
44
+ nonoAvailableCache = false;
45
+ }
46
+ return nonoAvailableCache;
47
+ }
48
+ /**
49
+ * Resolve whether sandboxing should be active for this session.
50
+ *
51
+ * Priority:
52
+ * 1. config.enabled (explicit opt-in/out)
53
+ * 2. AUTONAV_SANDBOX env var ("0" to disable)
54
+ * 3. Auto-detect nono on PATH
55
+ */
56
+ export function isSandboxEnabled(config) {
57
+ // Explicit config takes priority
58
+ if (config?.enabled !== undefined) {
59
+ return config.enabled && isNonoAvailable();
60
+ }
61
+ // Env var override
62
+ if (process.env.AUTONAV_SANDBOX === "0") {
63
+ return false;
64
+ }
65
+ // Auto-detect
66
+ return isNonoAvailable();
67
+ }
68
+ /**
69
+ * System paths needed for sandboxed subprocesses to execute shell scripts
70
+ * and common tools. Without these, plugin scripts can't run bash/jq/etc.
71
+ */
72
+ function getSystemReadPaths() {
73
+ const paths = [];
74
+ if (os.platform() === "darwin") {
75
+ // macOS system binaries and libraries
76
+ for (const p of ["/bin", "/usr/bin", "/usr/lib", "/usr/libexec"]) {
77
+ if (fs.existsSync(p))
78
+ paths.push(p);
79
+ }
80
+ // Homebrew (Apple Silicon and Intel)
81
+ for (const p of ["/opt/homebrew", "/usr/local"]) {
82
+ if (fs.existsSync(p))
83
+ paths.push(p);
84
+ }
85
+ }
86
+ else {
87
+ // Linux system paths
88
+ for (const p of ["/bin", "/usr/bin", "/usr/lib", "/usr/lib64", "/lib", "/lib64"]) {
89
+ if (fs.existsSync(p))
90
+ paths.push(p);
91
+ }
92
+ }
93
+ return paths;
94
+ }
95
+ /**
96
+ * Build nono CLI arguments for a given sandbox config.
97
+ *
98
+ * Returns the full argument list: ["run", "--silent", ...flags, "--"]
99
+ * Returns empty array if sandbox is disabled.
100
+ */
101
+ export function buildSandboxArgs(config) {
102
+ if (!isSandboxEnabled(config)) {
103
+ return [];
104
+ }
105
+ const args = ["run", "--silent", "--allow-cwd"];
106
+ // System binary paths (read-only) — needed for plugin script execution
107
+ for (const p of getSystemReadPaths()) {
108
+ args.push("--read", p);
109
+ }
110
+ // Read-only paths
111
+ if (config.readPaths) {
112
+ for (const p of config.readPaths) {
113
+ args.push("--read", p);
114
+ }
115
+ }
116
+ // Read+write paths
117
+ if (config.writePaths) {
118
+ for (const p of config.writePaths) {
119
+ args.push("--allow", p);
120
+ }
121
+ }
122
+ // Network blocking
123
+ if (config.blockNetwork) {
124
+ args.push("--net-block");
125
+ }
126
+ // Separator between nono args and the wrapped command
127
+ args.push("--");
128
+ return args;
129
+ }
130
+ /**
131
+ * Wrap a command with nono sandbox if enabled.
132
+ *
133
+ * If sandboxing is active:
134
+ * { command: "nono", args: ["run", ...flags, "--", originalCommand, ...originalArgs] }
135
+ *
136
+ * If disabled:
137
+ * { command: originalCommand, args: originalArgs } (passthrough)
138
+ */
139
+ export function wrapCommand(command, args, config) {
140
+ if (!config || !isSandboxEnabled(config)) {
141
+ return { command, args };
142
+ }
143
+ const sandboxArgs = buildSandboxArgs(config);
144
+ if (sandboxArgs.length === 0) {
145
+ return { command, args };
146
+ }
147
+ return {
148
+ command: "nono",
149
+ args: [...sandboxArgs, command, ...args],
150
+ };
151
+ }
152
+ //# sourceMappingURL=sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/harness/sandbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Tool Server Abstraction
3
+ *
4
+ * Defines harness-agnostic tool types and a pure data constructor.
5
+ * Each harness implementation adapts these definitions to its native
6
+ * tool hosting mechanism (SDK MCP servers, chibi JSONL, etc.).
7
+ *
8
+ * Key design: `defineTool()` creates a plain data object with no SDK
9
+ * dependency. The handler closure runs in-process regardless of harness,
10
+ * so closure-based data capture (the "stop hook" pattern) works identically.
11
+ */
12
+ import type { z } from "zod";
13
+ /**
14
+ * Result returned by a tool handler.
15
+ *
16
+ * Matches the MCP tool result format used by Claude Agent SDK.
17
+ */
18
+ export interface ToolResult {
19
+ content: Array<{
20
+ type: "text";
21
+ text: string;
22
+ }>;
23
+ isError: boolean;
24
+ }
25
+ /**
26
+ * A harness-agnostic tool definition.
27
+ *
28
+ * Pure data — no runtime dependency. Each harness converts these
29
+ * into its native tool format via `createToolServer()`.
30
+ */
31
+ export interface ToolDefinition {
32
+ name: string;
33
+ description: string;
34
+ inputSchema: z.ZodRawShape;
35
+ handler: (args: any) => Promise<ToolResult>;
36
+ }
37
+ /**
38
+ * Create a tool definition (pure data constructor).
39
+ *
40
+ * Drop-in replacement for SDK's `tool()` — same argument signature,
41
+ * but returns a plain object instead of an SDK-specific tool.
42
+ *
43
+ * @param name - Tool name (e.g. "submit_answer")
44
+ * @param description - Tool description shown to the agent
45
+ * @param inputSchema - Zod shape defining the tool's input parameters
46
+ * @param handler - Async function that processes tool calls
47
+ * @returns A ToolDefinition object
48
+ */
49
+ export declare function defineTool<T extends z.ZodRawShape>(name: string, description: string, inputSchema: T, handler: (args: z.infer<z.ZodObject<T>>) => Promise<ToolResult>): ToolDefinition;
50
+ //# sourceMappingURL=tool-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-server.d.ts","sourceRoot":"","sources":["../../src/harness/tool-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,CAAC,CAAC,WAAW,CAAC;IAC3B,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CAC7C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,WAAW,EAChD,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,CAAC,EACd,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,GAC9D,cAAc,CAEhB"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Tool Server Abstraction
3
+ *
4
+ * Defines harness-agnostic tool types and a pure data constructor.
5
+ * Each harness implementation adapts these definitions to its native
6
+ * tool hosting mechanism (SDK MCP servers, chibi JSONL, etc.).
7
+ *
8
+ * Key design: `defineTool()` creates a plain data object with no SDK
9
+ * dependency. The handler closure runs in-process regardless of harness,
10
+ * so closure-based data capture (the "stop hook" pattern) works identically.
11
+ */
12
+ /**
13
+ * Create a tool definition (pure data constructor).
14
+ *
15
+ * Drop-in replacement for SDK's `tool()` — same argument signature,
16
+ * but returns a plain object instead of an SDK-specific tool.
17
+ *
18
+ * @param name - Tool name (e.g. "submit_answer")
19
+ * @param description - Tool description shown to the agent
20
+ * @param inputSchema - Zod shape defining the tool's input parameters
21
+ * @param handler - Async function that processes tool calls
22
+ * @returns A ToolDefinition object
23
+ */
24
+ export function defineTool(name, description, inputSchema, handler) {
25
+ return { name, description, inputSchema, handler };
26
+ }
27
+ //# sourceMappingURL=tool-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-server.js","sourceRoot":"","sources":["../../src/harness/tool-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA2BH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CACxB,IAAY,EACZ,WAAmB,EACnB,WAAc,EACd,OAA+D;IAE/D,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AACrD,CAAC"}