@abot-ai/runtime 1.8.0 → 1.9.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 (423) hide show
  1. package/README.md +216 -222
  2. package/dist/scripts/runtime-setup-files.js +46 -2
  3. package/dist/src/capabilities/tool-definition-validator/definition-parser.js +8 -0
  4. package/dist/src/capabilities/tool-types.d.ts +4 -0
  5. package/dist/src/model-gateway/client/chat.js +9 -5
  6. package/dist/src/model-gateway/client/invocation-error.d.ts +9 -0
  7. package/dist/src/model-gateway/client/invocation-error.js +30 -0
  8. package/dist/src/model-gateway/client/stream-consumer.js +9 -2
  9. package/dist/src/model-gateway/client/stream-parser.js +2 -1
  10. package/dist/src/model-gateway/protocol/message-contract.d.ts +1 -0
  11. package/dist/src/model-gateway/protocol/message-contract.js +1 -1
  12. package/dist/src/model-gateway/server/chat-handler.js +5 -7
  13. package/dist/src/model-gateway/server/chat-stream-response.d.ts +7 -0
  14. package/dist/src/model-gateway/server/chat-stream-response.js +25 -0
  15. package/dist/src/runtime/adapters/registered-tool-normal-invocations/execution/approval.d.ts +5 -1
  16. package/dist/src/runtime/adapters/registered-tool-normal-invocations/execution/approval.js +15 -1
  17. package/dist/src/runtime/adapters/registered-tool-normal-invocations/execution/prepared-execution.js +7 -5
  18. package/dist/src/runtime/adapters/registered-tool-normal-invocations/execution/prepared-snapshot.js +9 -2
  19. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-rejection.d.ts +2 -2
  20. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-rejection.js +2 -2
  21. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/prepared-execution.js +17 -11
  22. package/dist/src/runtime/automations/service.d.ts +1 -1
  23. package/dist/src/runtime/capabilities/automation-builder/tool-module.js +4 -4
  24. package/dist/src/runtime/capabilities/automations/draft-index.d.ts +1 -1
  25. package/dist/src/runtime/capabilities/automations/tool-module.js +4 -4
  26. package/dist/src/runtime/capabilities/core-tool-contracts.d.ts +29 -0
  27. package/dist/src/runtime/capabilities/core-tool-contracts.js +38 -0
  28. package/dist/src/runtime/capabilities/knowledge-skills/read-many.d.ts +4 -0
  29. package/dist/src/runtime/capabilities/knowledge-skills/read-many.js +21 -0
  30. package/dist/src/runtime/capabilities/knowledge-skills/read-targets.d.ts +13 -0
  31. package/dist/src/runtime/capabilities/knowledge-skills/read-targets.js +44 -0
  32. package/dist/src/runtime/capabilities/knowledge-skills/tool-contract.d.ts +141 -0
  33. package/dist/src/runtime/capabilities/knowledge-skills/tool-contract.js +58 -0
  34. package/dist/src/runtime/capabilities/knowledge-skills/tool-module.d.ts +4 -0
  35. package/dist/src/runtime/capabilities/knowledge-skills/tool-module.js +78 -0
  36. package/dist/src/runtime/capabilities/knowledge-skills/tool-output.d.ts +12 -0
  37. package/dist/src/runtime/capabilities/knowledge-skills/tool-output.js +21 -0
  38. package/dist/src/runtime/capabilities/knowledge-skills/write-contract.d.ts +77 -0
  39. package/dist/src/runtime/capabilities/knowledge-skills/write-contract.js +28 -0
  40. package/dist/src/runtime/capabilities/knowledge-skills/write-operations.d.ts +3 -0
  41. package/dist/src/runtime/capabilities/knowledge-skills/write-operations.js +34 -0
  42. package/dist/src/runtime/capabilities/scheduling/tool-module.js +3 -3
  43. package/dist/src/runtime/capabilities/tool-availability.js +6 -0
  44. package/dist/src/runtime/composition.d.ts +5 -0
  45. package/dist/src/runtime/context/capability-brief.d.ts +2 -2
  46. package/dist/src/runtime/context/capability-brief.js +3 -3
  47. package/dist/src/runtime/context/capability-descriptions.d.ts +3 -2
  48. package/dist/src/runtime/context/capability-descriptions.js +57 -20
  49. package/dist/src/runtime/context/capability-result-compaction-source.d.ts +3 -1
  50. package/dist/src/runtime/context/capability-result-compaction-source.js +13 -1
  51. package/dist/src/runtime/context/core-skill-read-context.d.ts +16 -0
  52. package/dist/src/runtime/context/core-skill-read-context.js +76 -0
  53. package/dist/src/runtime/context/exact-evidence-match.d.ts +3 -0
  54. package/dist/src/runtime/context/exact-evidence-match.js +34 -0
  55. package/dist/src/runtime/context/model-step-compaction.js +20 -6
  56. package/dist/src/runtime/context/semantic-compaction/core-skill-read-source.d.ts +9 -0
  57. package/dist/src/runtime/context/semantic-compaction/core-skill-read-source.js +38 -0
  58. package/dist/src/runtime/context/semantic-compaction/generation-contracts.d.ts +2 -0
  59. package/dist/src/runtime/context/semantic-compaction/prompt.js +7 -7
  60. package/dist/src/runtime/context/semantic-compaction/run.js +10 -3
  61. package/dist/src/runtime/context/semantic-compaction/super-source-integrity.js +33 -3
  62. package/dist/src/runtime/context/session-artifact-paths.d.ts +2 -1
  63. package/dist/src/runtime/context/session-artifact-paths.js +2 -1
  64. package/dist/src/runtime/context/session-memory/model-step-controller.d.ts +2 -2
  65. package/dist/src/runtime/context/super-worker-compaction-failure.d.ts +1 -1
  66. package/dist/src/runtime/context/super-worker-compaction-failure.js +2 -1
  67. package/dist/src/runtime/context/super-worker-compaction-sidecar.d.ts +2 -1
  68. package/dist/src/runtime/context/super-worker-compaction-sidecar.js +9 -3
  69. package/dist/src/runtime/default-environment-adapters.d.ts +2 -1
  70. package/dist/src/runtime/default-environment-adapters.js +5 -1
  71. package/dist/src/runtime/knowledge-skills/available-skills-projection.d.ts +17 -0
  72. package/dist/src/runtime/knowledge-skills/available-skills-projection.js +66 -0
  73. package/dist/src/runtime/knowledge-skills/available-skills.d.ts +7 -0
  74. package/dist/src/runtime/knowledge-skills/available-skills.js +17 -0
  75. package/dist/src/runtime/knowledge-skills/builtins/abot-studio.d.ts +2 -0
  76. package/dist/src/runtime/knowledge-skills/builtins/abot-studio.js +27 -0
  77. package/dist/src/runtime/knowledge-skills/builtins/computer-use.d.ts +2 -0
  78. package/dist/src/runtime/knowledge-skills/builtins/computer-use.js +34 -0
  79. package/dist/src/runtime/knowledge-skills/builtins/skill-creator.d.ts +2 -0
  80. package/dist/src/runtime/knowledge-skills/builtins/skill-creator.js +29 -0
  81. package/dist/src/runtime/knowledge-skills/builtins/technical-work.d.ts +2 -0
  82. package/dist/src/runtime/knowledge-skills/builtins/technical-work.js +27 -0
  83. package/dist/src/runtime/knowledge-skills/catalog.d.ts +2 -0
  84. package/dist/src/runtime/knowledge-skills/catalog.js +12 -0
  85. package/dist/src/runtime/knowledge-skills/personal-contracts.d.ts +48 -0
  86. package/dist/src/runtime/knowledge-skills/personal-contracts.js +29 -0
  87. package/dist/src/runtime/knowledge-skills/personal-documents.d.ts +6 -0
  88. package/dist/src/runtime/knowledge-skills/personal-documents.js +56 -0
  89. package/dist/src/runtime/knowledge-skills/personal-management.d.ts +9 -0
  90. package/dist/src/runtime/knowledge-skills/personal-management.js +64 -0
  91. package/dist/src/runtime/knowledge-skills/personal-repository.d.ts +6 -0
  92. package/dist/src/runtime/knowledge-skills/personal-repository.js +76 -0
  93. package/dist/src/runtime/knowledge-skills/personal-store.d.ts +4 -0
  94. package/dist/src/runtime/knowledge-skills/personal-store.js +33 -0
  95. package/dist/src/runtime/knowledge-skills/read-evidence.d.ts +3 -0
  96. package/dist/src/runtime/knowledge-skills/read-evidence.js +13 -0
  97. package/dist/src/runtime/knowledge-skills/store.d.ts +19 -0
  98. package/dist/src/runtime/knowledge-skills/store.js +41 -0
  99. package/dist/src/runtime/local-application.d.ts +2 -1
  100. package/dist/src/runtime/local-host/app-service-dispatch.d.ts +1 -0
  101. package/dist/src/runtime/local-host/app-service-dispatch.js +5 -0
  102. package/dist/src/runtime/local-host/client-services.d.ts +3 -1
  103. package/dist/src/runtime/local-host/client-services.js +3 -2
  104. package/dist/src/runtime/long-term-memory/conversation-authoring/context.d.ts +7 -1
  105. package/dist/src/runtime/long-term-memory/conversation-authoring/context.js +51 -25
  106. package/dist/src/runtime/long-term-memory/conversation-authoring/plain-text-context.d.ts +5 -0
  107. package/dist/src/runtime/long-term-memory/conversation-authoring/plain-text-context.js +28 -0
  108. package/dist/src/runtime/long-term-memory/initial-context.d.ts +18 -0
  109. package/dist/src/runtime/long-term-memory/initial-context.js +57 -0
  110. package/dist/src/runtime/long-term-memory/projection.js +1 -1
  111. package/dist/src/runtime/model/context-compaction-admission.d.ts +1 -0
  112. package/dist/src/runtime/model/context-compaction-admission.js +35 -1
  113. package/dist/src/runtime/model/context-compaction-contracts.d.ts +9 -1
  114. package/dist/src/runtime/model/invoke-step.js +6 -2
  115. package/dist/src/runtime/model/provider-failure.d.ts +13 -0
  116. package/dist/src/runtime/model/provider-failure.js +37 -0
  117. package/dist/src/runtime/orchestration/role-calls/activation-budget.js +1 -0
  118. package/dist/src/runtime/orchestration/role-calls/candidate-validation.js +4 -1
  119. package/dist/src/runtime/orchestration/role-calls/checkpoint-state.d.ts +1 -1
  120. package/dist/src/runtime/orchestration/role-calls/checkpoint-state.js +7 -3
  121. package/dist/src/runtime/orchestration/role-calls/command-decoder.js +3 -0
  122. package/dist/src/runtime/orchestration/role-calls/command-dispatch/skill-read-transition.d.ts +4 -0
  123. package/dist/src/runtime/orchestration/role-calls/command-dispatch/skill-read-transition.js +48 -0
  124. package/dist/src/runtime/orchestration/role-calls/command-dispatch.js +3 -0
  125. package/dist/src/runtime/orchestration/role-calls/contracts.d.ts +8 -4
  126. package/dist/src/runtime/orchestration/role-calls/contracts.js +3 -3
  127. package/dist/src/runtime/orchestration/role-calls/ledger.d.ts +2 -1
  128. package/dist/src/runtime/orchestration/role-calls/ledger.js +2 -2
  129. package/dist/src/runtime/orchestration/role-calls/memory-recall-contract.d.ts +7 -0
  130. package/dist/src/runtime/orchestration/role-calls/memory-recall-state-validation.d.ts +2 -0
  131. package/dist/src/runtime/orchestration/role-calls/memory-recall-state-validation.js +88 -0
  132. package/dist/src/runtime/orchestration/role-calls/reducer.d.ts +1 -1
  133. package/dist/src/runtime/orchestration/role-calls/reducer.js +2 -1
  134. package/dist/src/runtime/orchestration/role-calls/skill-read.d.ts +47 -0
  135. package/dist/src/runtime/orchestration/role-calls/skill-read.js +196 -0
  136. package/dist/src/runtime/orchestration/role-executors/activation/model-output-failure.d.ts +1 -1
  137. package/dist/src/runtime/orchestration/role-executors/activation/model-output-failure.js +4 -2
  138. package/dist/src/runtime/orchestration/worker-capabilities/binding/create-binding.js +4 -1
  139. package/dist/src/runtime/orchestration/worker-capabilities/contracts.d.ts +4 -2
  140. package/dist/src/runtime/orchestration/worker-capabilities/contracts.js +2 -2
  141. package/dist/src/runtime/orchestration/worker-capabilities/execution/approval-group.js +10 -4
  142. package/dist/src/runtime/orchestration/worker-capabilities/execution/execution-freshness.d.ts +5 -0
  143. package/dist/src/runtime/orchestration/worker-capabilities/execution/execution-freshness.js +31 -0
  144. package/dist/src/runtime/orchestration/worker-capabilities/payload-compaction-transport.d.ts +2 -0
  145. package/dist/src/runtime/orchestration/worker-capabilities/payload-compaction-transport.js +7 -2
  146. package/dist/src/runtime/orchestration/worker-capabilities/supervisor-skill-authority.d.ts +19 -0
  147. package/dist/src/runtime/orchestration/worker-capabilities/supervisor-skill-authority.js +43 -0
  148. package/dist/src/runtime/plugins/loader.js +7 -6
  149. package/dist/src/runtime/plugins/manifest-projection.js +3 -0
  150. package/dist/src/runtime/request/approval-wait/preflight.js +1 -0
  151. package/dist/src/runtime/request/bound-runtime-handler.js +1 -0
  152. package/dist/src/runtime/request/capability-execution-freshness.js +6 -1
  153. package/dist/src/runtime/request/contracts.d.ts +2 -0
  154. package/dist/src/runtime/request/execution-agent-root-execution.js +11 -1
  155. package/dist/src/runtime/request/execution-payload-compacted-evidence.d.ts +2 -2
  156. package/dist/src/runtime/request/execution-scope-surfaces.d.ts +2 -0
  157. package/dist/src/runtime/request/execution-scope-surfaces.js +7 -0
  158. package/dist/src/runtime/request/execution-scope.d.ts +6 -2
  159. package/dist/src/runtime/request/execution-scope.js +11 -0
  160. package/dist/src/runtime/request/payload-settled-evidence.d.ts +11 -0
  161. package/dist/src/runtime/request/payload-settled-evidence.js +29 -0
  162. package/dist/src/runtime/request/prepared-execution.js +2 -0
  163. package/dist/src/runtime/request/role-call-delegation-events.d.ts +19 -0
  164. package/dist/src/runtime/request/role-call-delegation-events.js +52 -0
  165. package/dist/src/runtime/request/role-call-return-events.d.ts +19 -0
  166. package/dist/src/runtime/request/role-call-return-events.js +63 -0
  167. package/dist/src/runtime/request/role-executor-composition.js +2 -2
  168. package/dist/src/runtime/request/root-capability-binding.d.ts +24 -0
  169. package/dist/src/runtime/request/root-capability-binding.js +57 -0
  170. package/dist/src/runtime/request/root-capability-catalog.d.ts +16 -0
  171. package/dist/src/runtime/request/root-capability-catalog.js +20 -0
  172. package/dist/src/runtime/request/root-contract.d.ts +13 -1
  173. package/dist/src/runtime/request/root-execution-kernel.js +36 -68
  174. package/dist/src/runtime/request/root-reference-action.d.ts +15 -0
  175. package/dist/src/runtime/request/root-reference-action.js +48 -0
  176. package/dist/src/runtime/request/root-skill-read.d.ts +13 -0
  177. package/dist/src/runtime/request/root-skill-read.js +102 -0
  178. package/dist/src/runtime/request/runner.js +19 -3
  179. package/dist/src/runtime/request/super-payload-context-failure.js +13 -4
  180. package/dist/src/runtime/request/supervisor-root-execution.js +54 -1
  181. package/dist/src/runtime/request/supervisor-skill-edit-target.d.ts +9 -0
  182. package/dist/src/runtime/request/supervisor-skill-edit-target.js +25 -0
  183. package/dist/src/runtime/request/supervisor-skill-payload-context.d.ts +21 -0
  184. package/dist/src/runtime/request/supervisor-skill-payload-context.js +91 -0
  185. package/dist/src/runtime/request/supervisor-skill-write-preparation.d.ts +25 -0
  186. package/dist/src/runtime/request/supervisor-skill-write-preparation.js +71 -0
  187. package/dist/src/runtime/request/worker-capability-composition.d.ts +4 -1
  188. package/dist/src/runtime/request/worker-capability-composition.js +4 -1
  189. package/dist/src/runtime/request/worker-capability-payload.d.ts +1 -1
  190. package/dist/src/runtime/request/worker-capability-payload.js +44 -37
  191. package/dist/src/runtime/runtime-environment.d.ts +2 -0
  192. package/dist/src/runtime/runtime-environment.js +12 -1
  193. package/dist/src/runtime/scheduler/contracts.d.ts +4 -0
  194. package/dist/src/runtime/scheduler/run-list-filter.d.ts +11 -0
  195. package/dist/src/runtime/scheduler/run-list-filter.js +56 -0
  196. package/dist/src/runtime/scheduler/run-list-query.d.ts +2 -2
  197. package/dist/src/runtime/scheduler/run-list-query.js +4 -1
  198. package/dist/src/runtime/steps/auditor-decision/contracts.d.ts +2 -0
  199. package/dist/src/runtime/steps/auditor-decision/evidence-representation.d.ts +2 -2
  200. package/dist/src/runtime/steps/auditor-decision/evidence-representation.js +2 -34
  201. package/dist/src/runtime/steps/auditor-decision/input.js +21 -3
  202. package/dist/src/runtime/steps/auditor-decision/projection.js +5 -0
  203. package/dist/src/runtime/steps/auditor-decision/prompt.d.ts +1 -1
  204. package/dist/src/runtime/steps/auditor-decision/prompt.js +14 -3
  205. package/dist/src/runtime/steps/capability-execution-guidance.d.ts +7 -0
  206. package/dist/src/runtime/steps/capability-execution-guidance.js +28 -0
  207. package/dist/src/runtime/steps/capability-execution-instructions.d.ts +0 -2
  208. package/dist/src/runtime/steps/capability-execution-instructions.js +0 -2
  209. package/dist/src/runtime/steps/execution-agent/capability-result-context.d.ts +5 -2
  210. package/dist/src/runtime/steps/execution-agent/capability-result-context.js +22 -3
  211. package/dist/src/runtime/steps/execution-agent/compaction.d.ts +3 -2
  212. package/dist/src/runtime/steps/execution-agent/compaction.js +9 -1
  213. package/dist/src/runtime/steps/execution-agent/contracts.d.ts +10 -0
  214. package/dist/src/runtime/steps/execution-agent/decision-parsing.js +13 -1
  215. package/dist/src/runtime/steps/execution-agent/direct-response-configuration.d.ts +3 -0
  216. package/dist/src/runtime/steps/execution-agent/direct-response-configuration.js +64 -0
  217. package/dist/src/runtime/steps/execution-agent/direct-response-contract.d.ts +7 -0
  218. package/dist/src/runtime/steps/execution-agent/direct-response-contract.js +56 -0
  219. package/dist/src/runtime/steps/execution-agent/direct-response-policy.d.ts +9 -0
  220. package/dist/src/runtime/steps/execution-agent/direct-response-policy.js +30 -0
  221. package/dist/src/runtime/steps/execution-agent/direct-response-prompt.d.ts +7 -0
  222. package/dist/src/runtime/steps/execution-agent/direct-response-prompt.js +43 -0
  223. package/dist/src/runtime/steps/execution-agent/format.js +2 -0
  224. package/dist/src/runtime/steps/execution-agent/input.d.ts +2 -0
  225. package/dist/src/runtime/steps/execution-agent/input.js +35 -2
  226. package/dist/src/runtime/steps/execution-agent/plugin-catalog.d.ts +4 -0
  227. package/dist/src/runtime/steps/execution-agent/plugin-catalog.js +8 -0
  228. package/dist/src/runtime/steps/execution-agent/prompt.d.ts +1 -0
  229. package/dist/src/runtime/steps/execution-agent/prompt.js +42 -41
  230. package/dist/src/runtime/steps/execution-agent/refinement-input.d.ts +1 -0
  231. package/dist/src/runtime/steps/execution-agent/refinement-prompt.js +4 -1
  232. package/dist/src/runtime/steps/execution-agent/response-prompt.js +1 -0
  233. package/dist/src/runtime/steps/execution-agent/response-run.js +6 -12
  234. package/dist/src/runtime/steps/execution-agent/run.js +5 -2
  235. package/dist/src/runtime/steps/execution-agent/state-context.d.ts +2 -3
  236. package/dist/src/runtime/steps/execution-agent/state-context.js +3 -40
  237. package/dist/src/runtime/steps/knowledge-skill-instructions.d.ts +3 -0
  238. package/dist/src/runtime/steps/knowledge-skill-instructions.js +3 -0
  239. package/dist/src/runtime/steps/planner-decision/capability-brief.d.ts +4 -2
  240. package/dist/src/runtime/steps/planner-decision/capability-brief.js +5 -1
  241. package/dist/src/runtime/steps/planner-decision/input.d.ts +2 -2
  242. package/dist/src/runtime/steps/planner-decision/input.js +7 -1
  243. package/dist/src/runtime/steps/planner-decision/prompt.js +29 -49
  244. package/dist/src/runtime/steps/planner-graph/input.d.ts +2 -2
  245. package/dist/src/runtime/steps/planner-graph/input.js +9 -8
  246. package/dist/src/runtime/steps/planner-graph/prompt.js +2 -2
  247. package/dist/src/runtime/steps/planner-graph/run.d.ts +2 -2
  248. package/dist/src/runtime/steps/planner-graph/run.js +5 -5
  249. package/dist/src/runtime/steps/planner-graph/skill-guidance.d.ts +5 -0
  250. package/dist/src/runtime/steps/planner-graph/skill-guidance.js +62 -0
  251. package/dist/src/runtime/steps/reviewer-decision/final-evidence.d.ts +1 -0
  252. package/dist/src/runtime/steps/reviewer-decision/final-evidence.js +3 -1
  253. package/dist/src/runtime/steps/reviewer-decision/input.d.ts +3 -1
  254. package/dist/src/runtime/steps/reviewer-decision/input.js +2 -22
  255. package/dist/src/runtime/steps/reviewer-decision/model-context.d.ts +21 -0
  256. package/dist/src/runtime/steps/reviewer-decision/model-context.js +32 -1
  257. package/dist/src/runtime/steps/reviewer-decision/projection.js +4 -0
  258. package/dist/src/runtime/steps/reviewer-decision/prompt.d.ts +1 -1
  259. package/dist/src/runtime/steps/reviewer-decision/prompt.js +15 -4
  260. package/dist/src/runtime/steps/reviewer-decision/run.d.ts +2 -0
  261. package/dist/src/runtime/steps/reviewer-decision/run.js +6 -0
  262. package/dist/src/runtime/steps/skill-read-decision.d.ts +34 -0
  263. package/dist/src/runtime/steps/skill-read-decision.js +91 -0
  264. package/dist/src/runtime/steps/supervisor-decision/artifact-paths.d.ts +22 -0
  265. package/dist/src/runtime/steps/supervisor-decision/artifact-paths.js +132 -0
  266. package/dist/src/runtime/steps/supervisor-decision/capability-brief.d.ts +2 -0
  267. package/dist/src/runtime/steps/supervisor-decision/capability-brief.js +9 -2
  268. package/dist/src/runtime/steps/supervisor-decision/contracts.d.ts +12 -3
  269. package/dist/src/runtime/steps/supervisor-decision/contracts.js +3 -0
  270. package/dist/src/runtime/steps/supervisor-decision/decision-phases.d.ts +37 -0
  271. package/dist/src/runtime/steps/supervisor-decision/decision-phases.js +124 -0
  272. package/dist/src/runtime/steps/supervisor-decision/diagnostics.d.ts +5 -1
  273. package/dist/src/runtime/steps/supervisor-decision/diagnostics.js +4 -0
  274. package/dist/src/runtime/steps/supervisor-decision/format.d.ts +1 -0
  275. package/dist/src/runtime/steps/supervisor-decision/format.js +2 -0
  276. package/dist/src/runtime/steps/supervisor-decision/input.d.ts +8 -1
  277. package/dist/src/runtime/steps/supervisor-decision/input.js +35 -11
  278. package/dist/src/runtime/steps/supervisor-decision/parser.d.ts +1 -0
  279. package/dist/src/runtime/steps/supervisor-decision/parser.js +11 -0
  280. package/dist/src/runtime/steps/supervisor-decision/preparation-input.d.ts +26 -0
  281. package/dist/src/runtime/steps/supervisor-decision/preparation-input.js +39 -0
  282. package/dist/src/runtime/steps/supervisor-decision/preparation.d.ts +17 -0
  283. package/dist/src/runtime/steps/supervisor-decision/preparation.js +65 -0
  284. package/dist/src/runtime/steps/supervisor-decision/presentation.d.ts +13 -0
  285. package/dist/src/runtime/steps/supervisor-decision/presentation.js +47 -0
  286. package/dist/src/runtime/steps/supervisor-decision/prompt.d.ts +5 -0
  287. package/dist/src/runtime/steps/supervisor-decision/prompt.js +97 -106
  288. package/dist/src/runtime/steps/supervisor-decision/response-recommendation.d.ts +2 -0
  289. package/dist/src/runtime/steps/supervisor-decision/response-recommendation.js +2 -0
  290. package/dist/src/runtime/steps/supervisor-decision/resume.d.ts +3 -0
  291. package/dist/src/runtime/steps/supervisor-decision/resume.js +20 -0
  292. package/dist/src/runtime/steps/supervisor-decision/run.d.ts +7 -0
  293. package/dist/src/runtime/steps/supervisor-decision/run.js +76 -158
  294. package/dist/src/runtime/steps/supervisor-decision/skill-selection-input.d.ts +21 -0
  295. package/dist/src/runtime/steps/supervisor-decision/skill-selection-input.js +29 -0
  296. package/dist/src/runtime/steps/supervisor-decision/skill-selection.d.ts +16 -0
  297. package/dist/src/runtime/steps/supervisor-decision/skill-selection.js +44 -0
  298. package/dist/src/runtime/steps/supervisor-response/input.d.ts +3 -0
  299. package/dist/src/runtime/steps/supervisor-response/input.js +5 -0
  300. package/dist/src/runtime/steps/supervisor-response/prompt.js +2 -0
  301. package/dist/src/runtime/steps/supervisor-response/response-recommendation.d.ts +3 -0
  302. package/dist/src/runtime/steps/supervisor-response/response-recommendation.js +24 -4
  303. package/dist/src/runtime/steps/supervisor-response/run.d.ts +7 -0
  304. package/dist/src/runtime/steps/supervisor-response/run.js +3 -6
  305. package/dist/src/runtime/steps/supervisor-skill-authoring/contract.d.ts +43 -0
  306. package/dist/src/runtime/steps/supervisor-skill-authoring/contract.js +85 -0
  307. package/dist/src/runtime/steps/supervisor-skill-authoring/input.d.ts +35 -0
  308. package/dist/src/runtime/steps/supervisor-skill-authoring/input.js +87 -0
  309. package/dist/src/runtime/steps/supervisor-skill-authoring/run.d.ts +10 -0
  310. package/dist/src/runtime/steps/supervisor-skill-authoring/run.js +35 -0
  311. package/dist/src/runtime/steps/supervisor-skill-instructions.d.ts +4 -0
  312. package/dist/src/runtime/steps/supervisor-skill-instructions.js +4 -0
  313. package/dist/src/runtime/steps/worker-capability-scope-decision.js +14 -1
  314. package/dist/src/runtime/steps/worker-decision/contracts.d.ts +1 -0
  315. package/dist/src/runtime/steps/worker-decision/input/execution-guidance.d.ts +5 -0
  316. package/dist/src/runtime/steps/worker-decision/input/execution-guidance.js +31 -0
  317. package/dist/src/runtime/steps/worker-decision/input/prompt-context.js +2 -25
  318. package/dist/src/runtime/steps/worker-decision/input/reference-context.js +4 -0
  319. package/dist/src/runtime/steps/worker-decision/prompt.js +6 -2
  320. package/dist/src/runtime/steps/worker-decision/result-author.js +6 -0
  321. package/dist/src/web-ui/app/ARCHITECTURE.md +1 -1
  322. package/dist/src/web-ui/app/app-bootstrap.js +3 -0
  323. package/dist/src/web-ui/app/app.js +7 -1
  324. package/dist/src/web-ui/app/components/automations/run-history-controls.js +77 -0
  325. package/dist/src/web-ui/app/components/automations/run-history.js +55 -0
  326. package/dist/src/web-ui/app/components/automations/run.js +3 -8
  327. package/dist/src/web-ui/app/components/automations/timeline.js +3 -2
  328. package/dist/src/web-ui/app/components/automations/workspace.js +11 -2
  329. package/dist/src/web-ui/app/components/conversation-role-cards.js +27 -0
  330. package/dist/src/web-ui/app/components/conversation-role-delegations.d.ts +12 -0
  331. package/dist/src/web-ui/app/components/conversation-role-delegations.js +24 -0
  332. package/dist/src/web-ui/app/components/conversation-role-history.d.ts +13 -0
  333. package/dist/src/web-ui/app/components/conversation-role-history.js +81 -0
  334. package/dist/src/web-ui/app/components/conversation-role-returns.d.ts +12 -0
  335. package/dist/src/web-ui/app/components/conversation-role-returns.js +23 -0
  336. package/dist/src/web-ui/app/components/dashboard/compact-layout.js +137 -0
  337. package/dist/src/web-ui/app/components/dashboard/icons.js +5 -0
  338. package/dist/src/web-ui/app/components/dashboard/widget-card.js +85 -0
  339. package/dist/src/web-ui/app/components/dashboard/widget-dialog.js +83 -0
  340. package/dist/src/web-ui/app/components/dashboard/widget-summaries.js +155 -0
  341. package/dist/src/web-ui/app/components/dashboard/workspace.js +28 -4
  342. package/dist/src/web-ui/app/components/onboarding-workspace-access.js +1 -1
  343. package/dist/src/web-ui/app/components/operations-summary.js +2 -1
  344. package/dist/src/web-ui/app/components/passive-learning/home-widget-preview.js +32 -0
  345. package/dist/src/web-ui/app/components/passive-learning/home.js +4 -1
  346. package/dist/src/web-ui/app/components/schedules/details.js +3 -2
  347. package/dist/src/web-ui/app/components/skills/workspace.js +119 -0
  348. package/dist/src/web-ui/app/components/spark-chat/panel.js +1 -1
  349. package/dist/src/web-ui/app/components/spark-chat/settings.js +1 -1
  350. package/dist/src/web-ui/app/components/system-host/home-widget-permission-preview.js +75 -0
  351. package/dist/src/web-ui/app/components/system-host/home-widget-summary.js +93 -0
  352. package/dist/src/web-ui/app/components/system-host/macos-permission-rendering.js +2 -2
  353. package/dist/src/web-ui/app/components/system-host/native-windows-access.js +1 -1
  354. package/dist/src/web-ui/app/components/system-host/rendering.js +3 -3
  355. package/dist/src/web-ui/app/components/system-host/windows-store-setup.js +2 -2
  356. package/dist/src/web-ui/app/components/workspace-shell.js +11 -1
  357. package/dist/src/web-ui/app/computer-access-feature.js +13 -1
  358. package/dist/src/web-ui/app/configuration-feature.js +2 -0
  359. package/dist/src/web-ui/app/controllers/automation-read-projection.js +8 -4
  360. package/dist/src/web-ui/app/controllers/automation-run-actions.js +3 -1
  361. package/dist/src/web-ui/app/controllers/automation-run-history.js +159 -0
  362. package/dist/src/web-ui/app/controllers/automations-controller.js +27 -11
  363. package/dist/src/web-ui/app/controllers/environment-workspace-preparation.js +6 -2
  364. package/dist/src/web-ui/app/controllers/operations-controller.js +2 -1
  365. package/dist/src/web-ui/app/controllers/realtime-event-controller.js +22 -1
  366. package/dist/src/web-ui/app/controllers/reasoning-mode-controller.js +1 -1
  367. package/dist/src/web-ui/app/controllers/runtime-selection-controller.js +7 -1
  368. package/dist/src/web-ui/app/controllers/skills-controller.js +237 -0
  369. package/dist/src/web-ui/app/dashboard-feature.js +9 -0
  370. package/dist/src/web-ui/app/lib/conversation-role-model.d.ts +5 -0
  371. package/dist/src/web-ui/app/lib/conversation-role-model.js +63 -5
  372. package/dist/src/web-ui/app/lib/event-presentation.js +34 -0
  373. package/dist/src/web-ui/app/lib/reasoning-controls.js +6 -1
  374. package/dist/src/web-ui/app/lib/role-delegation-event.d.ts +18 -0
  375. package/dist/src/web-ui/app/lib/role-delegation-event.js +47 -0
  376. package/dist/src/web-ui/app/lib/role-return-event.d.ts +19 -0
  377. package/dist/src/web-ui/app/lib/role-return-event.js +36 -0
  378. package/dist/src/web-ui/app/lib/tool-activity-event.js +8 -6
  379. package/dist/src/web-ui/app/lib/tool-skill-activity-fields.js +50 -0
  380. package/dist/src/web-ui/app/lib/workspace-route.js +1 -0
  381. package/dist/src/web-ui/app/passive-learning-feature.js +2 -2
  382. package/dist/src/web-ui/app/services/runtime-web-client/automations.d.ts +9 -1
  383. package/dist/src/web-ui/app/services/runtime-web-client/automations.js +10 -2
  384. package/dist/src/web-ui/app/services/runtime-web-client/skills.js +23 -0
  385. package/dist/src/web-ui/app/services/runtime-web-client.js +2 -0
  386. package/dist/src/web-ui/app/skills-feature.js +36 -0
  387. package/dist/src/web-ui/app/styles/24-conversation-role-cards.css +58 -0
  388. package/dist/src/web-ui/app/styles/40-skills.css +34 -0
  389. package/dist/src/web-ui/app/styles/50-automations.css +24 -3
  390. package/dist/src/web-ui/app/styles/95-home-widgets.css +110 -0
  391. package/dist/src/web-ui/app/styles.css +2 -0
  392. package/dist/src/web-ui/app/ui-behavior.d.ts +1 -1
  393. package/dist/src/web-ui/app/ui-behavior.js +1 -0
  394. package/dist/src/web-ui/client-state/store.js +3 -2
  395. package/dist/src/web-ui/client-state/transaction-order.d.ts +2 -0
  396. package/dist/src/web-ui/client-state/transaction-order.js +18 -0
  397. package/dist/src/web-ui/local-runtime/api-router.d.ts +1 -0
  398. package/dist/src/web-ui/local-runtime/api-router.js +7 -0
  399. package/dist/src/web-ui/local-runtime/automation-routes.js +2 -1
  400. package/dist/src/web-ui/local-runtime/automation-run-page.d.ts +5 -0
  401. package/dist/src/web-ui/local-runtime/automation-run-page.js +26 -0
  402. package/dist/src/web-ui/local-runtime/skill-management-routes.d.ts +18 -0
  403. package/dist/src/web-ui/local-runtime/skill-management-routes.js +118 -0
  404. package/docs/configuration.md +8 -0
  405. package/docs/plugins.md +37 -32
  406. package/docs/runtime-public-contracts.md +37 -0
  407. package/examples/request-runner.config.example.json +3 -0
  408. package/package.json +1 -1
  409. package/plugins/capability-brief/plugin.json +1 -1
  410. package/plugins/code-outline/plugin.json +1 -1
  411. package/plugins/document-reader/plugin.json +1 -1
  412. package/plugins/exec/plugin.json +1 -1
  413. package/plugins/filesystem/plugin.json +1 -1
  414. package/plugins/json-inspector/plugin.json +1 -1
  415. package/plugins/local-search/plugin.json +1 -1
  416. package/plugins/memory/plugin.json +1 -1
  417. package/plugins/project-orientation/plugin.json +1 -1
  418. package/plugins/system/plugin.json +1 -1
  419. package/plugins/system-probe/plugin.json +1 -1
  420. package/plugins/web/plugin.json +1 -1
  421. package/plugins/web/skills/web_fetch_skill/SKILL.md +1 -2
  422. package/plugins/web/skills/web_search_skill/SKILL.md +3 -7
  423. package/src/runtime/README.md +96 -1
@@ -0,0 +1,85 @@
1
+ import { escapeHtml } from "../../lib/text-format.js";
2
+ import { dashboardIcon } from "./icons.js";
3
+
4
+ const compactLabels = { conversations: "Conversations", approvals: "Approvals" };
5
+
6
+ function symbolMarkup(indicator) {
7
+ if (!indicator) return "";
8
+ const label = escapeHtml(indicator.label || "");
9
+ const value = indicator.value === undefined ? "" : `<span aria-hidden="true">${escapeHtml(String(indicator.value))}</span>`;
10
+ const glyph = indicator.icon ? dashboardIcon(indicator.icon) : "";
11
+ return `<span class="home-widget-symbol" data-tone="${escapeHtml(indicator.tone || "neutral")}" role="img" aria-label="${label}" title="${label}">${glyph}${value}</span>`;
12
+ }
13
+
14
+ function copyMarkup(title, detail = "") {
15
+ return `<span class="home-widget-copy"><span class="home-widget-item-title" dir="auto" title="${escapeHtml(title)}">${escapeHtml(title)}</span><span class="home-widget-meta" dir="auto" title="${escapeHtml(detail)}">${escapeHtml(detail)}</span></span>`;
16
+ }
17
+
18
+ function rowsMarkup(preview) {
19
+ return preview.items.map((item) => `<span class="home-widget-row">${copyMarkup(item.title, item.detail)}${symbolMarkup(item.indicator)}</span>`).join("");
20
+ }
21
+
22
+ function metricsMarkup(preview) {
23
+ return `<span class="home-widget-metrics">${preview.items.map((item) => `<span class="home-widget-metric">${symbolMarkup(item.indicator)}<span>${escapeHtml(item.label)}</span></span>`).join("")}</span>`;
24
+ }
25
+
26
+ function computerMarkup(preview) {
27
+ const checks = preview.items.map((item) => `<span class="home-widget-check"><span>${escapeHtml(item.label)}</span>${symbolMarkup(item.indicator)}</span>`).join("");
28
+ return `<span class="home-widget-computer"><span class="home-widget-device"><span class="home-widget-item-title" dir="auto">${escapeHtml(preview.title)}</span><span class="home-widget-meta">${escapeHtml(preview.detail || "")}</span></span><span class="home-widget-checks">${checks}</span></span>`;
29
+ }
30
+
31
+ function previewMarkup(summary) {
32
+ const preview = summary.preview;
33
+ if (preview?.kind === "rows") return rowsMarkup(preview);
34
+ if (preview?.kind === "metrics") return metricsMarkup(preview);
35
+ if (preview?.kind === "computer") return computerMarkup(preview);
36
+ if (preview?.kind === "automation")
37
+ return `<span class="home-widget-automation">${symbolMarkup(preview.indicator)}${copyMarkup(preview.title, preview.detail)}</span>`;
38
+ return `<span class="home-widget-fallback"><span class="home-widget-title" dir="auto">${escapeHtml(summary.title || "")}</span><span class="home-widget-detail" dir="auto">${escapeHtml(summary.detail || "")}</span><span class="home-widget-status" dir="auto">${escapeHtml(summary.status || "")}</span></span>`;
39
+ }
40
+
41
+ function previewDescriptions(summary) {
42
+ const preview = summary.preview;
43
+ if (!preview) return [];
44
+ const descriptions = [preview.title, preview.detail];
45
+ descriptions.push(...(preview.items || []).map((item) =>
46
+ [item.title, item.label, item.detail, item.indicator?.label].filter(Boolean).join(": "),
47
+ ));
48
+ if (preview.indicator) descriptions.push(preview.indicator.label);
49
+ return descriptions.filter(Boolean);
50
+ }
51
+
52
+ /** A stable button; only the read-only preview changes, never the live component. */
53
+ export function createHomeWidgetCard({ documentRoot, id, label, icon }) {
54
+ const button = documentRoot.createElement("button");
55
+ button.type = "button";
56
+ button.className = "home-widget";
57
+ button.dataset.homeWidget = id;
58
+ button.setAttribute("aria-haspopup", "dialog");
59
+ const glyph = id === "learning" ? '<img src="/spark-mascot.svg" alt="" />' : dashboardIcon(icon);
60
+ button.innerHTML = `<span class="home-widget-heading"><span class="home-widget-heading-icon">${glyph}</span><span data-widget-label></span><span class="home-widget-badge" hidden></span><span class="home-widget-arrow" aria-hidden="true">›</span></span><span class="home-widget-preview"></span>`;
61
+ button.querySelector("[data-widget-label]").textContent = compactLabels[id] || label;
62
+ const body = button.querySelector(".home-widget-preview");
63
+ const badge = button.querySelector(".home-widget-badge");
64
+ let previousMarkup;
65
+ let previousBadge;
66
+ function render(summary) {
67
+ const markup = previewMarkup(summary);
68
+ if (markup !== previousMarkup) {
69
+ body.innerHTML = markup;
70
+ previousMarkup = markup;
71
+ }
72
+ const badgeMarkup = symbolMarkup(summary.preview?.badge);
73
+ if (badgeMarkup !== previousBadge) {
74
+ badge.innerHTML = badgeMarkup;
75
+ previousBadge = badgeMarkup;
76
+ }
77
+ badge.hidden = !badgeMarkup;
78
+ button.dataset.tone = summary.tone || "neutral";
79
+ button.setAttribute("aria-label", `${label} — open details`);
80
+ const description = [...new Set([summary.title, summary.detail, summary.status, ...previewDescriptions(summary)].filter(Boolean))].join(". ");
81
+ button.setAttribute("aria-description", description);
82
+ button.setAttribute("title", description);
83
+ }
84
+ return { button, render };
85
+ }
@@ -0,0 +1,83 @@
1
+ /** The original live panel is borrowed temporarily, never rendered a second time. */
2
+ export function createHomeWidgetDialog({ root, onClosed }) {
3
+ const documentRoot = root.ownerDocument;
4
+ const dialog = documentRoot.createElement("dialog");
5
+ dialog.className = "home-widget-dialog";
6
+ dialog.setAttribute("aria-labelledby", "home-widget-detail-title");
7
+ dialog.innerHTML = `<header class="home-widget-dialog-header">
8
+ <h2 id="home-widget-detail-title"></h2>
9
+ <button type="button" class="home-text-button" data-home-widget-close aria-label="Close details">Close</button>
10
+ </header><div class="home-widget-dialog-body"></div>`;
11
+ root.appendChild(dialog);
12
+ const title = dialog.querySelector("h2");
13
+ const body = dialog.querySelector(".home-widget-dialog-body");
14
+ const closeButton = dialog.querySelector("[data-home-widget-close]");
15
+ const empty = documentRoot.createElement("p");
16
+ empty.className = "home-panel-state";
17
+ empty.setAttribute("role", "status");
18
+ let borrowed = null;
19
+
20
+ function restorePanel() {
21
+ if (!borrowed) return null;
22
+ const previous = borrowed;
23
+ borrowed = null;
24
+ previous.entry.element.classList.remove("home-widget-expanded");
25
+ const parent = previous.entry.getReturnParent?.() || previous.parent;
26
+ const next = previous.nextSibling;
27
+ const anchor = next?.parentNode === parent ? next : null;
28
+ parent.insertBefore(previous.entry.element, anchor);
29
+ empty.remove();
30
+ return previous.entry;
31
+ }
32
+
33
+ function close({ restoreFocus = true } = {}) {
34
+ const entry = restorePanel();
35
+ if (dialog.open) dialog.close();
36
+ if (entry) onClosed(entry, restoreFocus);
37
+ }
38
+
39
+ function refresh() {
40
+ if (!borrowed) return;
41
+ const summary = borrowed.entry.getSummary();
42
+ empty.textContent = borrowed.entry.emptyMessage || [summary.title, summary.detail].filter(Boolean).join(" · ");
43
+ empty.hidden = !borrowed.entry.element.hidden;
44
+ }
45
+
46
+ function open(entry) {
47
+ if (borrowed?.entry === entry) return;
48
+ close({ restoreFocus: false });
49
+ const element = entry.element;
50
+ borrowed = { entry, parent: element.parentNode, nextSibling: element.nextSibling };
51
+ title.textContent = entry.label;
52
+ element.classList.add("home-widget-expanded");
53
+ body.appendChild(element);
54
+ body.appendChild(empty);
55
+ refresh();
56
+ body.scrollTop = 0;
57
+ dialog.showModal();
58
+ closeButton.focus({ preventScroll: true });
59
+ }
60
+
61
+ closeButton.addEventListener("click", () => close());
62
+ dialog.addEventListener("cancel", (event) => {
63
+ event.preventDefault();
64
+ close();
65
+ });
66
+ dialog.addEventListener("close", () => {
67
+ if (dialog.open) return;
68
+ const entry = restorePanel();
69
+ if (entry) onClosed(entry, true);
70
+ });
71
+ dialog.addEventListener("click", (event) => {
72
+ if (event.target !== dialog) return;
73
+ const bounds = dialog.getBoundingClientRect();
74
+ const inside = event.clientX >= bounds.left && event.clientX <= bounds.right &&
75
+ event.clientY >= bounds.top && event.clientY <= bounds.bottom;
76
+ if (!inside) close();
77
+ });
78
+ return {
79
+ open, close, refresh,
80
+ isExpanded: (element) => borrowed?.entry.element === element,
81
+ dispose() { close({ restoreFocus: false }); dialog.remove(); },
82
+ };
83
+ }
@@ -0,0 +1,155 @@
1
+ import {
2
+ dashboardTimePresentation,
3
+ projectDashboardActivity,
4
+ projectDashboardConversations,
5
+ } from "../../lib/dashboard-presentation.js";
6
+ import { coWorkerAgentState } from "../passive-learning/agent-state.js";
7
+ import { learningWidgetPreview } from "../passive-learning/home-widget-preview.js";
8
+ import { formatToolName } from "../../lib/event-presentation.js";
9
+ import { projectToolActivityEvent } from "../../lib/tool-activity-event.js";
10
+ import { textOf } from "../../lib/text-format.js";
11
+
12
+ function learningSnapshotMatchesEnvironment(snapshot, learning) {
13
+ if (!snapshot.environmentId || !learning?.environmentId) return true;
14
+ return snapshot.environmentId === learning.environmentId;
15
+ }
16
+
17
+ function learningSummary(snapshot, learning) {
18
+ const current = learningSnapshotMatchesEnvironment(snapshot, learning) ? learning : null;
19
+ if (current?.statusError)
20
+ return { title: "Connection interrupted", detail: "Open Spark to check its current activity.", status: "Status unavailable", tone: "attention" };
21
+ const presentation = coWorkerAgentState(current || {});
22
+ const tones = { attention: "attention", collecting: "active", reviewing: "active" };
23
+ return {
24
+ title: presentation.title,
25
+ detail: presentation.description,
26
+ status: presentation.label,
27
+ tone: tones[presentation.mode] || "neutral",
28
+ preview: learningWidgetPreview(current?.status),
29
+ };
30
+ }
31
+
32
+ function conversationsSummary(snapshot) {
33
+ const overview = snapshot.sessionOverview;
34
+ const projection = projectDashboardConversations(overview?.sessions ?? snapshot.sessions ?? [], 2);
35
+ const latest = projection.recentConversations[0];
36
+ const title = latest?.title || "A fresh start.";
37
+ if (snapshot.sessionsError)
38
+ return { title: latest?.title || "Conversations unavailable", detail: "Recent conversations could not be refreshed.", status: "Status unavailable", tone: "attention" };
39
+ if (snapshot.loadingSessions)
40
+ return { title: latest?.title || "Loading conversations…", detail: "", status: "Loading", tone: "neutral" };
41
+ const unavailable = overview?.hasUnavailableReadState ?? projection.hasUnavailableReadState;
42
+ if (unavailable)
43
+ return { title, detail: "Unread status unavailable", status: "Open chats", tone: "attention" };
44
+ const unread = overview?.unreadCount ?? projection.unreadCount;
45
+ const preview = conversationsPreview(projection, unread);
46
+ if (unread > 0)
47
+ return { title, detail: latest ? "Latest conversation" : "Open chats to read replies.", status: `${unread} unread ${unread === 1 ? "message" : "messages"}`, tone: "active", preview };
48
+ return { title, detail: latest ? "Latest conversation" : "Your conversations will appear here.", status: latest ? "No unread messages" : "No conversations yet", tone: "neutral", preview };
49
+ }
50
+
51
+ function activitySummary(snapshot) {
52
+ if (snapshot.supportsSchedules === false)
53
+ return { title: "Jobs unavailable", detail: "Choose a Runtime environment to use scheduled jobs.", status: "Unavailable", tone: "neutral" };
54
+ const latest = projectDashboardActivity(snapshot.runs ?? [], 1)[0];
55
+ if (snapshot.activityError)
56
+ return { title: latest?.title || "Activity unavailable", detail: "Recent activity could not be refreshed.", status: "Status unavailable", tone: "attention" };
57
+ if (snapshot.loadingActivity)
58
+ return { title: latest?.title || "Loading activity…", detail: "", status: "Loading", tone: "neutral" };
59
+ if (!latest)
60
+ return { title: "No activity yet", detail: "Try a ready-to-use job.", status: "View jobs", tone: "neutral" };
61
+ return { title: latest.title, detail: "Latest scheduled run", status: latest.statusLabel, tone: latest.tone, preview: activityPreview(snapshot.runs) };
62
+ }
63
+
64
+ function automationsSummary(snapshot) {
65
+ const active = snapshot.activeAutomations ?? [];
66
+ if (snapshot.automationStatusUnavailable)
67
+ return { title: "Automation status unavailable", detail: active[0]?.title || "Open ABot Studio to check runs.", status: active.length ? `${active.length} last seen in progress` : "Status unavailable", tone: "attention" };
68
+ if (!active.length)
69
+ return { title: "No automations in progress", detail: "ABot Studio", status: "No active runs", tone: "neutral" };
70
+ return {
71
+ title: `${active.length} ${active.length === 1 ? "automation" : "automations"} in progress`,
72
+ detail: active[0].title || "ABot Automation",
73
+ status: "View live timeline",
74
+ tone: "active",
75
+ preview: {
76
+ kind: "automation", title: active[0].title || "ABot Automation", detail: "ABot Studio",
77
+ indicator: { icon: "active", label: `${active.length} ${active.length === 1 ? "automation" : "automations"} in progress`, value: active.length, tone: "active" },
78
+ },
79
+ };
80
+ }
81
+
82
+ function approvalsSummary(snapshot) {
83
+ if (snapshot.supportsToolApprovals === false)
84
+ return { title: "Home approvals unavailable", detail: "Open the conversation to review pending actions.", status: "Unavailable", tone: "neutral" };
85
+ const count = snapshot.approvals?.length || 0;
86
+ const pendingTitle = `${count} ${count === 1 ? "action" : "actions"} waiting`;
87
+ if (snapshot.approvalDecisionError)
88
+ return { title: count ? pendingTitle : "Approval decision failed", detail: "Open approvals to review the failed decision.", status: "Needs attention", tone: "attention" };
89
+ if (snapshot.approvalsError)
90
+ return { title: count ? pendingTitle : "Approvals unavailable", detail: "Pending actions could not be refreshed.", status: "Status unavailable", tone: "attention" };
91
+ if (snapshot.loadingApprovals)
92
+ return { title: count ? pendingTitle : "Checking approvals…", detail: "", status: "Loading", tone: "neutral" };
93
+ if (count)
94
+ return { title: pendingTitle, detail: "Review the action before allowing it.", status: "Needs review", tone: "attention", preview: approvalsPreview(snapshot) };
95
+ return { title: "No pending approvals", detail: "Actions waiting for your decision appear here.", status: "Nothing waiting", tone: "neutral" };
96
+ }
97
+
98
+ function conversationIndicator(session) {
99
+ if (session.readStateUnavailable)
100
+ return { icon: "unknown", label: "Unread status unavailable", tone: "attention" };
101
+ if (!session.unreadCount) return null;
102
+ return { icon: "unread", label: `${session.unreadCount} unread ${session.unreadCount === 1 ? "message" : "messages"}`, value: session.unreadCount, tone: "active" };
103
+ }
104
+
105
+ function conversationsPreview(projection, unread) {
106
+ if (!projection.recentConversations.length) return undefined;
107
+ return {
108
+ kind: "rows",
109
+ badge: unread > 0 ? { icon: "unread", label: `${unread} unread ${unread === 1 ? "message" : "messages"} in all conversations`, value: unread, tone: "active" } : undefined,
110
+ items: projection.recentConversations.map((session) => ({
111
+ title: session.title,
112
+ detail: dashboardTimePresentation(session.updatedAt)?.label || "",
113
+ indicator: conversationIndicator(session),
114
+ })),
115
+ };
116
+ }
117
+
118
+ function activityPreview(runs) {
119
+ return {
120
+ kind: "rows",
121
+ items: projectDashboardActivity(runs, 2).map((run) => ({
122
+ title: run.title,
123
+ detail: dashboardTimePresentation(run.timestamp)?.label || "",
124
+ indicator: { icon: run.tone, label: run.statusLabel, tone: run.tone },
125
+ })),
126
+ };
127
+ }
128
+
129
+ function approvalsPreview(snapshot) {
130
+ return {
131
+ kind: "rows",
132
+ badge: { value: snapshot.approvals.length, label: `${snapshot.approvals.length} pending ${snapshot.approvals.length === 1 ? "approval" : "approvals"}`, tone: "attention" },
133
+ items: snapshot.approvals.slice(0, 2).map((approval) => {
134
+ const event = approval.event || {};
135
+ const activity = projectToolActivityEvent(event);
136
+ const conversation = (snapshot.sessions || []).find((session) => session.id === approval.sessionId);
137
+ return {
138
+ title: formatToolName(event.tool) || "Tool",
139
+ detail: activity?.target || textOf(conversation?.displayName || conversation?.title),
140
+ indicator: { icon: "active", label: "Awaiting approval", tone: "attention" },
141
+ };
142
+ }),
143
+ };
144
+ }
145
+
146
+ /** Read-only presentation of the existing Home owners; no new reads or state. */
147
+ export function dashboardWidgetSummaries(snapshot = {}, learningSnapshot) {
148
+ return {
149
+ learning: learningSummary(snapshot, learningSnapshot),
150
+ conversations: conversationsSummary(snapshot),
151
+ activity: activitySummary(snapshot),
152
+ automations: automationsSummary(snapshot),
153
+ approvals: approvalsSummary(snapshot),
154
+ };
155
+ }
@@ -3,6 +3,8 @@ import { getDashboardJobTemplates } from "../../lib/dashboard-job-templates.js";
3
3
  import { renderDashboardActivity } from "./activity.js";
4
4
  import { renderDashboardConversations } from "./recent-conversations.js";
5
5
  import { renderDashboardAutomations } from "./automations.js";
6
+ import { createCompactHomeLayout } from "./compact-layout.js";
7
+ import { dashboardWidgetSummaries } from "./widget-summaries.js";
6
8
  import {
7
9
  hasPendingDashboardApprovals,
8
10
  renderDashboardApprovals,
@@ -37,7 +39,26 @@ export function createDashboardWorkspace({ root, actions, passiveLearning }) {
37
39
  const setupHost = root.querySelector("[data-dashboard-setup]");
38
40
  const learningPanel = root.querySelector("[data-dashboard-learning]");
39
41
  const automationPanel = root.querySelector("[data-dashboard-automations]");
40
- passiveLearning?.mountHome(root.querySelector("[data-dashboard-learning-content]"));
42
+ let currentSnapshot = {};
43
+ function approvalHome() {
44
+ if (hasPendingDashboardApprovals(currentSnapshot)) return approvalDock;
45
+ return content;
46
+ }
47
+ const returnParents = { approvals: approvalHome };
48
+ const compactWidgets = createCompactHomeLayout({ root, content });
49
+ for (const [id, label, icon, element] of [
50
+ ["learning", "ABot Spark", "learning", learningPanel],
51
+ ["conversations", "Recent conversations", "conversations", conversations],
52
+ ["activity", "Recent activity", "active", activity],
53
+ ["automations", "Automations", "job", automationPanel],
54
+ ["approvals", "Pending approvals", "success", approvals],
55
+ ]) compactWidgets.register({
56
+ id, label, icon, element,
57
+ getReturnParent: returnParents[id],
58
+ isAvailable: () => id !== "learning" || Boolean(passiveLearning),
59
+ getSummary: () => dashboardWidgetSummaries(currentSnapshot, passiveLearning?.snapshot?.())[id],
60
+ });
61
+ passiveLearning?.mountHome(root.querySelector("[data-dashboard-learning-content]"), compactWidgets.refresh);
41
62
  const composerNote = root.querySelector(".home-composer-note");
42
63
  const handlers = {
43
64
  template: (button) => actions.createJob(button.dataset.templateId),
@@ -57,12 +78,14 @@ export function createDashboardWorkspace({ root, actions, passiveLearning }) {
57
78
  });
58
79
 
59
80
  function render(snapshot) {
81
+ currentSnapshot = snapshot;
60
82
  const setupRequired = snapshot.composerAvailable === false;
83
+ compactWidgets.setEnabled(!setupRequired);
61
84
  const pendingApprovals = hasPendingDashboardApprovals(snapshot);
62
85
  approvalDock.hidden = setupRequired || !pendingApprovals;
63
86
  // Keep pending actions beside the composer; refresh errors stay in content.
64
- const approvalParent = pendingApprovals ? approvalDock : content;
65
- if (approvals.parentElement !== approvalParent)
87
+ const approvalParent = approvalHome();
88
+ if (!compactWidgets.isExpanded(approvals) && approvals.parentElement !== approvalParent)
66
89
  approvalParent.appendChild(approvals);
67
90
  root.classList.toggle("home-setup-active", setupRequired);
68
91
  learningPanel.hidden = setupRequired || !passiveLearning;
@@ -118,7 +141,8 @@ export function createDashboardWorkspace({ root, actions, passiveLearning }) {
118
141
  "aria-busy",
119
142
  String(Boolean(snapshot.loadingSessions)),
120
143
  );
144
+ compactWidgets.refresh();
121
145
  }
122
146
 
123
- return { render, composerHost, setupHost };
147
+ return { render, composerHost, setupHost, compactWidgets };
124
148
  }
@@ -1,6 +1,6 @@
1
1
  const navigation = Object.freeze({
2
2
  home: "homeWorkspaceButton", chat: "chatWorkspaceButton", learning: "learningWorkspaceButton",
3
- memory: "memoryWorkspaceButton", schedules: "schedulesWorkspaceButton", automations: "automationsWorkspaceButton", models: "modelsWorkspaceButton",
3
+ skills: "skillsWorkspaceButton", memory: "memoryWorkspaceButton", schedules: "schedulesWorkspaceButton", automations: "automationsWorkspaceButton", models: "modelsWorkspaceButton",
4
4
  plugins: "pluginsWorkspaceButton", notifications: "notificationsWorkspaceButton", config: "configWorkspaceButton",
5
5
  });
6
6
 
@@ -1,3 +1,4 @@
1
+ import { displayReasoningMode } from "../lib/reasoning-controls.js";
1
2
  import { formatTime, textOf } from "../lib/text-format.js";
2
3
  import { getNumber } from "../lib/event-presentation.js";
3
4
 
@@ -91,7 +92,7 @@ function healthSummary(read) {
91
92
  label: "System health · all environments",
92
93
  items: [
93
94
  { label: "Health · all environments", value: unavailable || healthValue(payload.ok), status: true },
94
- { label: "Runtime mode", value: unavailable || textOf(payload.agentMode, "-") || "-" },
95
+ { label: "Runtime mode", value: unavailable || textOf(displayReasoningMode(payload.agentMode), "-") || "-" },
95
96
  { label: "Active streams", value: unavailable || activeStreamCount(payload) },
96
97
  { label: "Latest event", value: unavailable || textOf(latest?.lastEventName || latest?.lastEventType, "-") || "-" },
97
98
  ],
@@ -0,0 +1,32 @@
1
+ import { coWorkerActivityStates, coWorkerActivityTones } from "./agent-state.js";
2
+
3
+ const indicators = {
4
+ off: { icon: "paused", tone: "neutral" },
5
+ waiting: { icon: "active", tone: "neutral" },
6
+ ready: { icon: "success", tone: "success" },
7
+ active: { icon: "active", tone: "active" },
8
+ attention: { icon: "failed", tone: "attention" },
9
+ };
10
+
11
+ /** Read-only projection of the same activity states used by the expanded owner. */
12
+ export function learningWidgetPreview(status) {
13
+ if (!status?.preferences) return null;
14
+ const states = coWorkerActivityStates(status);
15
+ const tones = coWorkerActivityTones(status);
16
+ return {
17
+ kind: "metrics",
18
+ items: [
19
+ ["collection", "Collection"],
20
+ ["processing", "Learning"],
21
+ ["proactive", "Proactive"],
22
+ ].map(([key, label]) => {
23
+ const indicator = { ...(indicators[tones[key]] || indicators.off) };
24
+ indicator.label = [label, ...states[key]].filter(Boolean).join(": ");
25
+ if (key === "collection" && tones[key] === "active") indicator.icon = "collecting";
26
+ if (key === "processing" && ["ready", "waiting"].includes(tones[key])
27
+ && Number.isFinite(status.pendingObservations) && status.pendingObservations > 0)
28
+ indicator.value = status.pendingObservations;
29
+ return { label, indicator };
30
+ }),
31
+ };
32
+ }
@@ -37,8 +37,10 @@ export function createPassiveLearningHome({
37
37
  let root = null;
38
38
  let renderedSnapshot = {};
39
39
  let motion;
40
+ let onRendered = () => {};
40
41
 
41
- function mount(nextRoot) {
42
+ function mount(nextRoot, notify = () => {}) {
43
+ onRendered = notify;
42
44
  if (root === nextRoot) return;
43
45
  motion?.dispose();
44
46
  root?.removeEventListener("click", handleClick);
@@ -88,6 +90,7 @@ export function createPassiveLearningHome({
88
90
  const error = root.querySelector("[data-learning-status]");
89
91
  error.textContent = snapshot.statusError || "";
90
92
  error.hidden = !snapshot.statusError;
93
+ onRendered();
91
94
  }
92
95
 
93
96
  return Object.freeze({ mount, render });
@@ -1,3 +1,4 @@
1
+ import { displayReasoningMode } from "../../lib/reasoning-controls.js";
1
2
  import { toolPermissionModeMeta } from "../../lib/tool-permission-mode.js";
2
3
  import { updateLiveRegion } from "../../lib/live-region.js";
3
4
  import { escapeHtml } from "../../lib/text-format.js";
@@ -33,7 +34,7 @@ function runMarkup(run) {
33
34
  return `<article class="schedule-run" data-run-id="${escapeHtml(run.id)}">
34
35
  <div class="schedule-run-heading"><strong>${scheduleTimeLabel(run.scheduledAt, timeZone)}</strong><span class="schedule-badge" data-state="${escapeHtml(run.status)}">${escapeHtml(run.status)}</span></div>
35
36
  <div class="schedule-run-meta">${run.trigger === "manual" ? "Manual run" : "Scheduled run"}${run.startedAt ? ` · Started ${scheduleTimeLabel(run.startedAt, timeZone)}` : ""}${run.finishedAt ? ` · Finished ${scheduleTimeLabel(run.finishedAt, timeZone)}` : ""}</div>
36
- <dl class="schedule-run-settings">${fact("Model", run.modelProfileId)}${fact("Mode", run.agentMode)}${fact("Tool access", toolPermissionModeMeta(run.toolPermissionMode).label)}${fact("Time zone", run.timeZone)}${fact("Job revision", String(run.jobRevision ?? "—"))}</dl>
37
+ <dl class="schedule-run-settings">${fact("Model", run.modelProfileId)}${fact("Mode", displayReasoningMode(run.agentMode))}${fact("Tool access", toolPermissionModeMeta(run.toolPermissionMode).label)}${fact("Time zone", run.timeZone)}${fact("Job revision", String(run.jobRevision ?? "—"))}</dl>
37
38
  ${run.error ? `<p class="schedule-error" dir="auto">${escapeHtml(run.error)}</p>` : ""}
38
39
  ${run.resultText ? `<details class="schedule-result" data-disclosure-id="result:${escapeHtml(run.id)}"><summary>View result</summary><pre dir="auto">${escapeHtml(run.resultText)}</pre></details>` : ""}
39
40
  <details class="schedule-prompt-disclosure" data-disclosure-id="run:${escapeHtml(run.id)}"><summary>View invocation prompt</summary><pre dir="auto">${escapeHtml(run.prompt)}</pre></details>
@@ -67,7 +68,7 @@ export function renderScheduleDetails({ root, snapshot, actions }) {
67
68
  const conversationLabel = scheduleConversationLabel(job.sessionId, snapshot.sessions);
68
69
  const markup = `<div class="schedule-detail-heading"><span class="schedule-eyebrow">Scheduled task</span><h3 dir="auto">${escapeHtml(job.title)}</h3><span class="schedule-badge" data-state="${job.state}">${job.state}</span></div>
69
70
  <div class="schedule-action-row">${actionsMarkup(job, snapshot.mutation)}</div>
70
- <dl class="schedule-facts">${fact("Schedule", scheduleDescription(job))}${fact("Next run", scheduleTimeLabel(job.nextRunAt, job.timeZone))}${fact("Time zone", job.timeZone)}${fact("Model", job.modelProfileId)}${fact("Mode", job.agentMode)}${fact("Tool access", toolPermissionModeMeta(job.toolPermissionMode).label)}${fact("Created", scheduleTimeLabel(job.createdAt, job.timeZone))}${fact("Updated", scheduleTimeLabel(job.updatedAt, job.timeZone))}</dl>
71
+ <dl class="schedule-facts">${fact("Schedule", scheduleDescription(job))}${fact("Next run", scheduleTimeLabel(job.nextRunAt, job.timeZone))}${fact("Time zone", job.timeZone)}${fact("Model", job.modelProfileId)}${fact("Mode", displayReasoningMode(job.agentMode))}${fact("Tool access", toolPermissionModeMeta(job.toolPermissionMode).label)}${fact("Created", scheduleTimeLabel(job.createdAt, job.timeZone))}${fact("Updated", scheduleTimeLabel(job.updatedAt, job.timeZone))}</dl>
71
72
  <button type="button" class="schedule-conversation-link" data-open-conversation>↗ <span dir="auto">${escapeHtml(conversationLabel)}</span></button>
72
73
  <details class="schedule-prompt-disclosure" data-disclosure-id="job:${escapeHtml(job.id)}"><summary>View task prompt</summary><pre dir="auto">${escapeHtml(job.prompt)}</pre></details>
73
74
  <small class="schedule-id">Job ${escapeHtml(job.id)} · Revision ${job.revision}</small>
@@ -0,0 +1,119 @@
1
+ import { escapeAttribute, escapeHtml } from "../../lib/text-format.js";
2
+
3
+ /** Mounts the existing shell's navigation/panel contract without growing index.html. */
4
+ export function mountSkillsWorkspace(dom, documentRoot = document) {
5
+ const button = documentRoot.createElement("button");
6
+ button.id = "skillsWorkspaceButton";
7
+ button.className = "rail-button";
8
+ button.type = "button";
9
+ button.setAttribute("aria-label", "Open Skills");
10
+ button.setAttribute("aria-controls", "skillsWorkspacePanel");
11
+ button.title = "Skills";
12
+ button.innerHTML = `<span class="rail-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><rect x="5" y="3" width="14" height="18" rx="2" /><path d="m8 9 1 1 2-2m2 1h3m-8 6 1 1 2-2m2 1h3" /></svg></span><span class="rail-button-label">Skills</span>`;
13
+ dom.memoryWorkspaceButton.after(button);
14
+ const panel = documentRoot.createElement("section");
15
+ panel.id = "skillsWorkspacePanel";
16
+ panel.className = "workspace-page-panel skills-workspace-panel";
17
+ panel.hidden = true;
18
+ panel.inert = true;
19
+ panel.setAttribute("aria-hidden", "true");
20
+ panel.setAttribute("aria-labelledby", "skillsWorkspaceTitle");
21
+ panel.innerHTML = `<header class="workspace-page-header"><div class="workspace-page-heading"><p class="eyebrow">Personal guidance</p><h2 id="skillsWorkspaceTitle">Skills</h2></div><button type="button" class="workspace-page-back" data-skills-close>Back to chat</button></header><div class="workspace-page-body" data-skills-root></div>`;
22
+ dom.app.append(panel);
23
+ Object.assign(dom, { skillsWorkspaceButton: button, skillsWorkspacePanel: panel,
24
+ closeSkillsWorkspaceButton: panel.querySelector("[data-skills-close]"), skillsRoot: panel.querySelector("[data-skills-root]") });
25
+ }
26
+
27
+ export function renderSkillRows(snapshot) {
28
+ const items = snapshot.items.filter((item) => item.source === "personal" && item.archived === snapshot.archived);
29
+ if (!items.length) return `<p class="skills-empty">${snapshot.loading ? "Loading Skills…" : snapshot.archived ? "No archived Skills." : "No personal Skills yet. Create one here or ask ABot to help."}</p>`;
30
+ return items.map((item) => `<button type="button" class="config-model-button skills-list-item" data-skill-id="${escapeAttribute(item.skillId)}" aria-pressed="${item.skillId === snapshot.skill?.skillId}"><strong dir="auto">${escapeHtml(item.name)}</strong><span dir="auto">${escapeHtml(item.description)}</span></button>`).join("");
31
+ }
32
+
33
+ export function createSkillsWorkspace({ root, actions, confirmArchive = (message) => window.confirm(message) }) {
34
+ root.innerHTML = `<div class="config-dashboard skills-workspace-content"><div class="skills-toolbar"><div class="skills-filters" role="group" aria-label="Skill status"><button type="button" class="config-category-tab" data-skills-filter="active" aria-pressed="true">Active</button><button type="button" class="config-category-tab" data-skills-filter="archived" aria-pressed="false">Archived</button></div><div class="skills-toolbar-actions"><button type="button" data-skills-refresh>Refresh</button><button type="button" class="primary-button" data-skills-new>New Skill</button></div></div><p class="skills-intro">Personal Skills guide how ABot works. Built-in Skills are maintained by ABot.</p><p class="skills-feedback" role="alert" data-skills-error hidden></p><p class="skills-feedback" role="status" data-skills-message hidden></p><div class="skills-layout"><div class="skills-list" data-skills-list></div><section class="skills-detail" data-skills-detail><p class="skills-empty" data-skills-placeholder>Select a Skill to read or edit it.</p><form data-skills-form hidden><div data-skills-creation-fields hidden><h3>New Skill</h3><label class="skills-creation-label">Name<input type="text" data-skills-new-name maxlength="160" dir="auto" required disabled></label><label class="skills-creation-label">Description<textarea data-skills-new-description rows="3" maxlength="512" dir="auto" required disabled></textarea></label></div><div data-skills-saved-metadata><h3 dir="auto" data-skills-name></h3><p dir="auto" class="skills-description" data-skills-description></p><p class="skills-id">ID: <span dir="ltr" data-skills-id></span></p></div><label class="skills-content-label">Content<textarea data-skills-content rows="16" dir="auto" maxlength="65536" required></textarea></label><p class="skills-archived-note" data-skills-archived-note hidden>Archived Skills are unavailable to models. Restore this Skill to use or edit it.</p><div class="skills-editor-actions"><button class="primary-button" type="submit" data-skills-save>Save changes</button><button type="button" data-skills-cancel hidden>Cancel</button><button type="button" data-skills-reload>Reload saved</button><button type="button" data-skills-archive>Archive</button><button type="button" data-skills-restore hidden>Restore</button></div></form></section></div></div>`;
35
+ const find = (selector) => root.querySelector(selector);
36
+ const list = find("[data-skills-list]");
37
+ const form = find("[data-skills-form]");
38
+ const content = find("[data-skills-content]");
39
+ const nameInput = find("[data-skills-new-name]");
40
+ const descriptionInput = find("[data-skills-new-description]");
41
+ let current;
42
+ let listMarkup = "";
43
+ root.addEventListener("click", (event) => {
44
+ const selected = event.target.closest?.("[data-skill-id]");
45
+ if (selected) void actions.select(selected.dataset.skillId);
46
+ const filter = event.target.closest?.("[data-skills-filter]");
47
+ if (filter) actions.setArchived(filter.dataset.skillsFilter === "archived");
48
+ if (event.target.closest?.("[data-skills-new]")) actions.beginCreate();
49
+ if (event.target.closest?.("[data-skills-cancel]")) actions.cancelCreate();
50
+ if (event.target.closest?.("[data-skills-refresh]")) void actions.refresh();
51
+ if (event.target.closest?.("[data-skills-reload]")) void actions.reloadSelected();
52
+ if (event.target.closest?.("[data-skills-restore]")) void actions.restore();
53
+ if (event.target.closest?.("[data-skills-archive]")) {
54
+ const warning = current?.dirty ? " Unsaved edits will be discarded." : "";
55
+ if (confirmArchive(`Archive this Skill? Models will no longer discover or read it.${warning}`)) void actions.archive();
56
+ }
57
+ });
58
+ nameInput.addEventListener("input", () => actions.setCreationField("name", nameInput.value));
59
+ descriptionInput.addEventListener("input", () => actions.setCreationField("description", descriptionInput.value));
60
+ content.addEventListener("input", () => actions.setDraft(content.value));
61
+ form.addEventListener("submit", (event) => { event.preventDefault(); void actions.save(); });
62
+ function render(snapshot) {
63
+ current = snapshot;
64
+ const nextList = renderSkillRows(snapshot);
65
+ if (nextList !== listMarkup) { list.innerHTML = nextList; listMarkup = nextList; }
66
+ list.setAttribute("aria-busy", String(snapshot.loading));
67
+ for (const button of root.querySelectorAll("[data-skills-filter]")) {
68
+ const selected = (button.dataset.skillsFilter === "archived") === snapshot.archived;
69
+ button.setAttribute("aria-pressed", String(selected));
70
+ button.className = selected ? "config-category-tab active" : "config-category-tab";
71
+ button.disabled = Boolean(snapshot.mutation);
72
+ }
73
+ for (const [selector, message] of [["[data-skills-error]", snapshot.error], ["[data-skills-message]", snapshot.message]]) {
74
+ const element = find(selector); element.textContent = message; element.hidden = !message;
75
+ }
76
+ const skill = snapshot.skill;
77
+ const creating = snapshot.creating === true;
78
+ const editing = Boolean(skill) || creating;
79
+ const archived = skill?.archived === true;
80
+ const busy = Boolean(snapshot.mutation);
81
+ find("[data-skills-new]").disabled = busy;
82
+ const placeholder = find("[data-skills-placeholder]");
83
+ placeholder.hidden = editing;
84
+ placeholder.textContent = snapshot.reading ? "Loading Skill…" : "Select a Skill to read or edit it.";
85
+ form.hidden = !editing;
86
+ if (!editing) return;
87
+ find("[data-skills-creation-fields]").hidden = !creating;
88
+ find("[data-skills-saved-metadata]").hidden = creating;
89
+ nameInput.disabled = !creating || busy;
90
+ descriptionInput.disabled = !creating || busy;
91
+ if (nameInput.value !== (snapshot.name || "")) nameInput.value = snapshot.name || "";
92
+ if (descriptionInput.value !== (snapshot.description || "")) descriptionInput.value = snapshot.description || "";
93
+ find("[data-skills-name]").textContent = skill?.name || "";
94
+ find("[data-skills-description]").textContent = skill?.description || "";
95
+ find("[data-skills-id]").textContent = skill?.skillId || "";
96
+ if (content.value !== snapshot.draft) content.value = snapshot.draft;
97
+ content.readOnly = archived;
98
+ content.disabled = busy;
99
+ find("[data-skills-archived-note]").hidden = !archived;
100
+ find("[data-skills-save]").hidden = archived;
101
+ find("[data-skills-save]").disabled = cannotSave(snapshot);
102
+ const saveLabels = { create: "Creating…", save: "Saving…" };
103
+ find("[data-skills-save]").textContent = saveLabels[snapshot.mutation] || (creating ? "Create Skill" : "Save changes");
104
+ find("[data-skills-cancel]").hidden = !creating;
105
+ find("[data-skills-reload]").hidden = creating;
106
+ find("[data-skills-archive]").hidden = creating || archived;
107
+ find("[data-skills-restore]").hidden = creating || !archived;
108
+ for (const selector of ["[data-skills-cancel]", "[data-skills-reload]", "[data-skills-archive]", "[data-skills-restore]"])
109
+ find(selector).disabled = busy;
110
+ }
111
+ return { render };
112
+ }
113
+
114
+ function cannotSave(snapshot) {
115
+ if (snapshot.mutation || !snapshot.dirty || !snapshot.draft.trim()) return true;
116
+ if (!snapshot.creating) return false;
117
+ if (!snapshot.name.trim()) return true;
118
+ return !snapshot.description.trim();
119
+ }
@@ -66,7 +66,7 @@ export function createSparkChatPanel({ documentRoot = document, launcherAnchor }
66
66
  placement.refresh();
67
67
  onToggle(value);
68
68
  if (!focus) return;
69
- if (value) dom.messagesList.focus({ preventScroll: true });
69
+ if (value) dom.composerInput.focus({ preventScroll: true });
70
70
  else (previousFocus?.isConnected ? previousFocus : dom.launcherButton)?.focus({ preventScroll: true });
71
71
  }
72
72
 
@@ -14,7 +14,7 @@ export function createSparkChatSettings({ root, onSave, onClear, onOpen, onReset
14
14
  </form>
15
15
  <div class="spark-settings-row">
16
16
  <label for="spark-agent-mode"><strong>Thinking mode</strong><span>Choose how deeply SPARK thinks before replying.</span></label>
17
- <select id="spark-agent-mode" data-spark-agent-mode aria-label="SPARK thinking mode"><option value="fast">Fast</option><option value="reasoning" selected>Reasoning</option><option value="deep">Deep</option></select>
17
+ <select id="spark-agent-mode" data-spark-agent-mode aria-label="SPARK thinking mode"><option value="fast">Low</option><option value="reasoning" selected>Reasoning</option><option value="deep">Deep</option></select>
18
18
  </div>
19
19
  <div class="spark-settings-row"><div><strong>Chat shortcut</strong><p>Drag SPARK wherever feels right. Use Alt + arrow keys to move it.</p></div>
20
20
  <button type="button" data-spark-reset-position>Return to sidebar</button></div>