@platless/axom-cli 0.1.0 → 0.5.9

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 (281) hide show
  1. package/README.md +1 -1
  2. package/dist/authScopes.js +19 -0
  3. package/dist/axom-patch/cli/README.md +132 -0
  4. package/dist/axom-patch/cli/account-limits/README.md +27 -0
  5. package/dist/axom-patch/cli/account-limits/antigravity-proxy.mjs +47 -0
  6. package/dist/axom-patch/cli/account-limits/antigravity-read.mjs +90 -0
  7. package/dist/axom-patch/cli/account-limits/antigravity.mjs +46 -0
  8. package/dist/axom-patch/cli/account-limits/generate.py +120 -0
  9. package/dist/axom-patch/cli/account-limits/kimi-proxy.mjs +64 -0
  10. package/dist/axom-patch/cli/account-limits/normalize.mjs +151 -0
  11. package/dist/axom-patch/cli/claude-account-limits.json +37 -0
  12. package/dist/axom-patch/cli/codex-account-limits.json +37 -0
  13. package/dist/axom-patch/cli/commandcode-account-limits.json +30 -0
  14. package/dist/axom-patch/cli/nightly-task.md +152 -0
  15. package/dist/axom-patch/cli/pi-steering.json +37 -0
  16. package/dist/axom-patch/cli/pi-subagent-subwork.json +23 -0
  17. package/dist/axom-patch/cli/probes/claude-late-async-terminal.mjs +38 -0
  18. package/dist/axom-patch/cli/probes/pi-steering.mjs +80 -0
  19. package/dist/axom-patch/cli/probes/pi-subagent-subwork.mjs +211 -0
  20. package/dist/axom-patch/cli/probes/qoder-steering.mjs +89 -0
  21. package/dist/axom-patch/cli/probes/qoder-subagent-origin.mjs +61 -0
  22. package/dist/axom-patch/cli/probes/zcode-subagent-subwork.mjs +257 -0
  23. package/dist/axom-patch/cli/qoder-background-terminal.md +82 -0
  24. package/dist/axom-patch/cli/qoder-foreground-output.md +42 -0
  25. package/dist/axom-patch/cli/qoder-steering.json +52 -0
  26. package/dist/axom-patch/cli/qoder-steering.md +30 -0
  27. package/dist/axom-patch/cli/qoder-subagent-origin.json +73 -0
  28. package/dist/axom-patch/cli/qoder-subagent-subwork.md +73 -0
  29. package/dist/axom-patch/cli/runtime.json +63 -0
  30. package/dist/axom-patch/cli/steering/claude-steering-js.patch +89 -0
  31. package/dist/axom-patch/cli/steering/claude-steering-types.patch +28 -0
  32. package/dist/axom-patch/cli/steering/codex-steering.patch +57 -0
  33. package/dist/axom-patch/cli/steering/pi-steering.js +79 -0
  34. package/dist/axom-patch/cli/zcode-account-limits.json +31 -0
  35. package/dist/axom-patch/cli/zcode-models.json +38 -0
  36. package/dist/axom-patch/cli/zcode-subagent-subwork.json +73 -0
  37. package/dist/cli.js +36 -1
  38. package/dist/commands/auth.js +4 -13
  39. package/dist/commands/execute.js +4 -4
  40. package/dist/commands/record.js +6 -6
  41. package/dist/commands/struct.js +4 -4
  42. package/dist/commands/workstation.js +2 -2
  43. package/dist/credentials.js +2 -2
  44. package/dist/install/claude/commands.js +13 -13
  45. package/dist/keepers/acp/keeper.mjs +3083 -0
  46. package/dist/keepers/acp/manifest.json +9 -0
  47. package/dist/keepers/terminal/keeper.mjs +8469 -0
  48. package/dist/keepers/terminal/manifest.json +9 -0
  49. package/dist/keepers/terminal/node_modules/node-pty/lib/conpty_console_list_agent.js +25 -0
  50. package/dist/keepers/terminal/node_modules/node-pty/lib/eventEmitter2.js +47 -0
  51. package/dist/keepers/terminal/node_modules/node-pty/lib/index.js +52 -0
  52. package/dist/keepers/terminal/node_modules/node-pty/lib/interfaces.js +7 -0
  53. package/dist/keepers/terminal/node_modules/node-pty/lib/shared/conout.js +10 -0
  54. package/dist/keepers/terminal/node_modules/node-pty/lib/terminal.js +190 -0
  55. package/dist/keepers/terminal/node_modules/node-pty/lib/types.js +7 -0
  56. package/dist/keepers/terminal/node_modules/node-pty/lib/unixTerminal.js +351 -0
  57. package/dist/keepers/terminal/node_modules/node-pty/lib/utils.js +38 -0
  58. package/dist/keepers/terminal/node_modules/node-pty/lib/windowsConoutConnection.js +131 -0
  59. package/dist/keepers/terminal/node_modules/node-pty/lib/windowsPtyAgent.js +344 -0
  60. package/dist/keepers/terminal/node_modules/node-pty/lib/windowsTerminal.js +209 -0
  61. package/dist/keepers/terminal/node_modules/node-pty/lib/worker/conoutSocketWorker.js +22 -0
  62. package/dist/keepers/terminal/node_modules/node-pty/package.json +66 -0
  63. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/darwin-arm64/pty.node +0 -0
  64. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/darwin-arm64/spawn-helper +0 -0
  65. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/darwin-x64/pty.node +0 -0
  66. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/darwin-x64/spawn-helper +0 -0
  67. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/linux-arm64/pty.node +0 -0
  68. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/linux-x64/pty.node +0 -0
  69. package/dist/mcp.js +32 -14
  70. package/dist/runtime-deps/qoder-sdk/package-lock.json +1189 -0
  71. package/dist/runtime-deps/qoder-sdk/package.json +8 -0
  72. package/dist/test/keeperKit.js +67 -0
  73. package/dist/workstation/acp/acpAgents.js +2514 -681
  74. package/dist/workstation/acp/acpClient.js +95 -318
  75. package/dist/workstation/acp/activityBusy.js +43 -0
  76. package/dist/workstation/acp/activityReporting.js +54 -0
  77. package/dist/workstation/acp/adoption.js +28 -356
  78. package/dist/workstation/acp/authUrlSniffer.js +36 -0
  79. package/dist/workstation/acp/binaryInstall.js +100 -27
  80. package/dist/workstation/acp/builds/gc.js +245 -0
  81. package/dist/workstation/acp/builds/install/binary.js +28 -0
  82. package/dist/workstation/acp/builds/install/npm.js +235 -0
  83. package/dist/workstation/acp/builds/install/uv.js +254 -0
  84. package/dist/workstation/acp/builds/migrate.js +195 -0
  85. package/dist/workstation/acp/builds/model.js +128 -0
  86. package/dist/workstation/acp/builds/nodeGate.js +100 -0
  87. package/dist/workstation/acp/builds/store.js +352 -0
  88. package/dist/workstation/acp/commandTableProbe.js +68 -0
  89. package/dist/workstation/acp/configOptions.js +103 -1
  90. package/dist/workstation/acp/delegationMcp.js +24 -0
  91. package/dist/workstation/acp/envSecrets.js +27 -0
  92. package/dist/workstation/acp/initializeResponse.js +285 -0
  93. package/dist/workstation/acp/installErrors.js +12 -2
  94. package/dist/workstation/acp/installProbe.js +1 -1
  95. package/dist/workstation/acp/managedPatches.js +144 -0
  96. package/dist/workstation/acp/outbox.js +330 -0
  97. package/dist/workstation/acp/patchAssets.js +80 -0
  98. package/dist/workstation/acp/permission.js +335 -37
  99. package/dist/workstation/acp/processor/checkpoint.js +87 -0
  100. package/dist/workstation/acp/processor/commands.js +35 -0
  101. package/dist/workstation/acp/processor/control.js +355 -0
  102. package/dist/workstation/acp/processor/emit.js +26 -0
  103. package/dist/workstation/acp/processor/jsonrpc.js +172 -0
  104. package/dist/workstation/acp/processor/memoryLog.js +49 -0
  105. package/dist/workstation/acp/processor/origins.js +48 -0
  106. package/dist/workstation/acp/processor/output.js +67 -0
  107. package/dist/workstation/acp/processor/projection.js +42 -0
  108. package/dist/workstation/acp/processor/record.js +128 -0
  109. package/dist/workstation/acp/processor/runtime.js +181 -0
  110. package/dist/workstation/acp/processor/sdkSchemas.js +61 -0
  111. package/dist/workstation/acp/processor/session.js +525 -0
  112. package/dist/workstation/acp/processor/sideChannel.js +80 -0
  113. package/dist/workstation/acp/processor/state.js +74 -0
  114. package/dist/workstation/acp/processor/step.js +459 -0
  115. package/dist/workstation/acp/processor/test/fixtureLog.js +65 -0
  116. package/dist/workstation/acp/processor/test/harness.js +120 -0
  117. package/dist/workstation/acp/processor/test/largeIdEcho.js +50 -0
  118. package/dist/workstation/acp/processor/test/rawAgent.js +70 -0
  119. package/dist/workstation/acp/processor/transport/generations.js +76 -0
  120. package/dist/workstation/acp/processor/transport/keeper.js +130 -0
  121. package/dist/workstation/acp/processor/transport/local.js +269 -0
  122. package/dist/workstation/acp/processor/transport/types.js +78 -0
  123. package/dist/workstation/acp/processor/updates.js +364 -0
  124. package/dist/workstation/acp/processorSession.js +1512 -0
  125. package/dist/workstation/acp/qoderStartup.js +45 -0
  126. package/dist/workstation/acp/registry/catalog.js +385 -4
  127. package/dist/workstation/acp/registry/detect.js +55 -0
  128. package/dist/workstation/acp/registry/launch.js +61 -119
  129. package/dist/workstation/acp/sessionUpdateMapper.js +56 -27
  130. package/dist/workstation/acp/steering.js +58 -0
  131. package/dist/workstation/acp/switching.js +114 -0
  132. package/dist/workstation/acp/terminalLogin.js +171 -0
  133. package/dist/workstation/acp/terminalLoginSpec.js +41 -0
  134. package/dist/workstation/acp/test/adapterFixtures.js +256 -0
  135. package/dist/workstation/acp/test/daemonLife.js +106 -0
  136. package/dist/workstation/acp/test/fakeAgent.js +185 -9
  137. package/dist/workstation/acp/test/keeperWorld.js +267 -0
  138. package/dist/workstation/acp/test/memoryOutbox.js +55 -0
  139. package/dist/workstation/acp/test/raw/fixtures.js +196 -0
  140. package/dist/workstation/acp/test/raw/qoderCaptures.js +125 -0
  141. package/dist/workstation/acp/test/raw/sanitize.js +344 -0
  142. package/dist/workstation/acp/test/raw/sources.js +249 -0
  143. package/dist/workstation/acp/test/realAdapter.js +377 -0
  144. package/dist/workstation/acp/test/scriptAgent.js +206 -0
  145. package/dist/workstation/acp/test/sessionFrames.js +42 -0
  146. package/dist/workstation/acp/timedCommand.js +4 -2
  147. package/dist/workstation/acp/uvxInstall.js +72 -122
  148. package/dist/workstation/acp/validate.js +33 -5
  149. package/dist/workstation/agentFlow.js +103 -0
  150. package/dist/workstation/agentSessions.js +1686 -348
  151. package/dist/workstation/channels/agent.js +14 -6
  152. package/dist/workstation/channels/computer.js +203 -7
  153. package/dist/workstation/channels/computerExecs.js +200 -0
  154. package/dist/workstation/channels/management.js +86 -6
  155. package/dist/workstation/config.js +3 -1
  156. package/dist/workstation/connection/encryptedChannel.js +88 -21
  157. package/dist/workstation/daemon.js +309 -6
  158. package/dist/workstation/daemonctl.js +28 -2
  159. package/dist/workstation/desktop/binding.js +36 -0
  160. package/dist/workstation/desktop/bridge.js +212 -0
  161. package/dist/workstation/desktop/flow-control.js +52 -0
  162. package/dist/workstation/desktop/focused-text.js +130 -0
  163. package/dist/workstation/desktop/protocol.js +35 -0
  164. package/dist/workstation/exec/attach.js +126 -0
  165. package/dist/workstation/exec/command.js +40 -0
  166. package/dist/workstation/exec/durable.js +517 -0
  167. package/dist/workstation/exec/fallback.js +106 -0
  168. package/dist/workstation/exec/policy.js +837 -0
  169. package/dist/workstation/exec/shaping.js +211 -0
  170. package/dist/workstation/exec.js +3 -112
  171. package/dist/workstation/files/adapters/computerFileFrames.js +51 -0
  172. package/dist/workstation/files/adapters/toolRequests.js +121 -0
  173. package/dist/workstation/files/client.js +455 -0
  174. package/dist/workstation/files/errors.js +28 -0
  175. package/dist/workstation/files/fence.js +350 -0
  176. package/dist/workstation/files/find/fileIndex.js +153 -0
  177. package/dist/workstation/files/find/fuzzy.js +155 -0
  178. package/dist/workstation/files/host.js +122 -0
  179. package/dist/workstation/files/hostProtocol.js +2 -0
  180. package/dist/workstation/files/media/cache.js +620 -0
  181. package/dist/workstation/files/media/encoding.js +308 -0
  182. package/dist/workstation/files/media/estimator.js +100 -0
  183. package/dist/workstation/files/media/media.js +325 -0
  184. package/dist/workstation/files/media/packedAudio.js +23 -0
  185. package/dist/workstation/files/media/scheduler.js +551 -0
  186. package/dist/workstation/files/media/types.js +5 -0
  187. package/dist/workstation/files/scope.js +45 -0
  188. package/dist/workstation/files/structured.js +284 -0
  189. package/dist/workstation/files/text.js +356 -0
  190. package/dist/workstation/files/uploads.js +351 -0
  191. package/dist/workstation/journal.js +65 -236
  192. package/dist/workstation/keepers/acp/client.js +101 -0
  193. package/dist/workstation/keepers/acp/envelope.js +62 -0
  194. package/dist/workstation/keepers/acp/host.js +419 -0
  195. package/dist/workstation/keepers/acp/main.js +18 -0
  196. package/dist/workstation/keepers/acp/memoryStream.js +121 -0
  197. package/dist/workstation/keepers/acp/params.js +137 -0
  198. package/dist/workstation/keepers/acp/protocol.js +66 -0
  199. package/dist/workstation/keepers/acp/recover.js +120 -0
  200. package/dist/workstation/keepers/acp/session.js +584 -0
  201. package/dist/workstation/keepers/acp/stderr.js +154 -0
  202. package/dist/workstation/keepers/kit/activity.js +103 -0
  203. package/dist/workstation/keepers/kit/bootstrap.js +164 -0
  204. package/dist/workstation/keepers/kit/buildVersion.js +51 -0
  205. package/dist/workstation/keepers/kit/bundle.js +120 -0
  206. package/dist/workstation/keepers/kit/client.js +432 -0
  207. package/dist/workstation/keepers/kit/identity.js +21 -0
  208. package/dist/workstation/keepers/kit/ipc.js +112 -0
  209. package/dist/workstation/keepers/kit/launchConfig.js +8 -0
  210. package/dist/workstation/keepers/kit/launcher.js +249 -0
  211. package/dist/workstation/keepers/kit/lock.js +123 -0
  212. package/dist/workstation/keepers/kit/orphanSweep.js +86 -0
  213. package/dist/workstation/keepers/kit/paths.js +75 -0
  214. package/dist/workstation/keepers/kit/protocol.js +43 -0
  215. package/dist/workstation/keepers/kit/server.js +518 -0
  216. package/dist/workstation/keepers/kit/streamLog.js +697 -0
  217. package/dist/workstation/keepers/legacy.js +296 -0
  218. package/dist/workstation/keepers/policy.js +576 -0
  219. package/dist/workstation/keepers/stop.js +34 -0
  220. package/dist/workstation/keepers/terminal/client.js +213 -0
  221. package/dist/workstation/keepers/terminal/exec.js +981 -0
  222. package/dist/workstation/keepers/terminal/generations.js +129 -0
  223. package/dist/workstation/keepers/terminal/keeper.js +62 -0
  224. package/dist/workstation/keepers/terminal/main.js +43 -0
  225. package/dist/workstation/keepers/terminal/orphanSweep.js +3 -0
  226. package/dist/workstation/keepers/terminal/params.js +27 -0
  227. package/dist/workstation/keepers/terminal/protocol.js +56 -0
  228. package/dist/workstation/keepers/terminal/pty.js +330 -0
  229. package/dist/workstation/oauth/deviceAuthorization.js +21 -12
  230. package/dist/workstation/protocol/accountLimits.js +47 -0
  231. package/dist/workstation/protocol/agent.js +201 -8
  232. package/dist/workstation/protocol/common.js +36 -0
  233. package/dist/workstation/protocol/computer.js +107 -7
  234. package/dist/workstation/protocol/management.js +50 -2
  235. package/dist/workstation/qoderAdapter/backgroundProcess.js +118 -0
  236. package/dist/workstation/qoderAdapter/backgroundTerminal.js +193 -0
  237. package/dist/workstation/qoderAdapter/backgroundTerminalFold.js +372 -0
  238. package/dist/workstation/qoderAdapter/callbackContext.js +76 -0
  239. package/dist/workstation/qoderAdapter/completedContinuation.js +139 -0
  240. package/dist/workstation/qoderAdapter/contract.js +78 -0
  241. package/dist/workstation/qoderAdapter/foregroundOutput.js +36 -0
  242. package/dist/workstation/qoderAdapter/history.js +85 -0
  243. package/dist/workstation/qoderAdapter/identityIndex.js +191 -0
  244. package/dist/workstation/qoderAdapter/inputQueue.js +42 -0
  245. package/dist/workstation/qoderAdapter/main.js +95 -0
  246. package/dist/workstation/qoderAdapter/mapper.js +117 -0
  247. package/dist/workstation/qoderAdapter/observerPlugin.js +245 -0
  248. package/dist/workstation/qoderAdapter/observerReceiver.js +187 -0
  249. package/dist/workstation/qoderAdapter/permissions.js +61 -0
  250. package/dist/workstation/qoderAdapter/profile.js +93 -0
  251. package/dist/workstation/qoderAdapter/sdkDriver.js +48 -0
  252. package/dist/workstation/qoderAdapter/sdkRuntime.js +93 -0
  253. package/dist/workstation/qoderAdapter/sdkRuntimeInstall.js +145 -0
  254. package/dist/workstation/qoderAdapter/session.js +319 -0
  255. package/dist/workstation/qoderAdapter/subagentMeta.js +28 -0
  256. package/dist/workstation/qoderAdapter/subwork.js +85 -0
  257. package/dist/workstation/qoderAdapter/taskControl.js +38 -0
  258. package/dist/workstation/qoderAdapter/taskLedger.js +163 -0
  259. package/dist/workstation/qoderAdapter/types.js +1 -0
  260. package/dist/workstation/qoderAdapter/usage.js +37 -0
  261. package/dist/workstation/register.js +4 -0
  262. package/dist/workstation/systemMetrics.js +110 -1
  263. package/dist/workstation/tools/browser.js +394 -0
  264. package/dist/workstation/tools/client.js +277 -0
  265. package/dist/workstation/tools/info.js +50 -0
  266. package/dist/workstation/tools/keeperProcess.js +124 -0
  267. package/dist/workstation/tools/router.js +55 -0
  268. package/dist/workstation/tools/terminalRouter.js +222 -0
  269. package/dist/workstation/tools/validation.js +86 -0
  270. package/dist/workstation/update/coordinator.js +32 -0
  271. package/dist/workstation/update/npmInstaller.js +2 -0
  272. package/dist/workstation/update/ptyPreflight.js +45 -0
  273. package/dist/workstation/update/taskRegistry.js +141 -23
  274. package/dist/workstation/update/watchdog.js +66 -0
  275. package/package.json +20 -7
  276. package/skills/axom/SKILL.md +55 -17
  277. package/skills/axom-definition/SKILL.md +32 -32
  278. package/skills/axom-platform/SKILL.md +39 -39
  279. package/dist/workstation/acp/acpSession.js +0 -1047
  280. package/dist/workstation/acp/contract.js +0 -494
  281. package/dist/workstation/acp/draftInterceptor.js +0 -154
@@ -3,19 +3,64 @@
3
3
  * forced update closes it permanently because this daemon is about to be replaced.
4
4
  */
5
5
  export class TaskRegistry {
6
- /** Every running shell's abort handle plus the promise that says its finally cleanup has run. */
6
+ /** Every running computer task's abort handle plus the promise that says its finally cleanup has run. */
7
7
  shellTasks = new Map();
8
- agentTasks = new Set();
9
8
  agentOpenReservations = new Map();
10
9
  agentSessions = new Map();
11
10
  idleWaiters = new Set();
12
11
  stopping = null;
13
12
  accepting = true;
13
+ /** Keeper-terminal execs also counted in `activeShellTasks` right now (see {@link countKeeperExec}). */
14
+ keeperExecsCounted = 0;
15
+ /**
16
+ * Work owned by another process that a daemon restart would interrupt (the files host's in-progress uploads plus
17
+ * running media encodes), sampled **now** on every snapshot — never an edge counter. Its owner calls
18
+ * [externalActivityChanged] when the level may have dropped, so a drain waiting on it wakes.
19
+ */
20
+ externalActivity = () => 0;
21
+ /**
22
+ * 忙碌是**现在采出来的**,不是攒出来的。
23
+ *
24
+ * 上一版把每个 `tool_call` / `permission_request` 记进一个 `Set`,指望 `turn_done` 来删。
25
+ * 任何一条没有配套 `turn_done` 的开始事件都会把那个 ref 永久钉住,`isIdle()` 于是永远假,
26
+ * 优雅更新白等满 drain 超时——2026-09-21 一次重装就这样卡在 BUSY。集合删掉之后这类缺陷
27
+ * **按构造**不存在:没有可泄漏的东西,而不是"记得要删"。
28
+ *
29
+ * `busy()` 由会话自己提供,两个来源取或(见 agentSessions.ts 的注册点):本进程发出的
30
+ * 提示词是否在途,以及 agent 自报的状态。两个都是层级量。
31
+ */
14
32
  snapshot() {
15
- const activeAgentRefs = new Set(this.agentTasks);
33
+ const activeAgentRefs = new Set();
34
+ for (const [sessionRef, session] of this.agentSessions) {
35
+ // Spec §8.2: `activeAgentTasks` counts only agent work a daemon restart would cut. A keeper-hosted (durable) session is not
36
+ // such work — its turn goes on in keeper-acp and the next daemon adopts it — so a busy one neither holds a graceful drain nor
37
+ // blocks an automatic patch. Fallback sessions (in this process) and in-flight open reservations are counted.
38
+ if (session.durable)
39
+ continue;
40
+ // 一个抛异常的采样器不得让心跳和更新准入一起垮掉;读不出来就当它不主张忙碌,
41
+ // 与未知 vendor 值的处置同一条推理。
42
+ let busy = false;
43
+ try {
44
+ busy = session.busy();
45
+ }
46
+ catch {
47
+ busy = false;
48
+ }
49
+ if (busy)
50
+ activeAgentRefs.add(sessionRef);
51
+ }
16
52
  for (const sessionRef of this.agentOpenReservations.keys())
17
53
  activeAgentRefs.add(sessionRef);
18
- return { activeShellTasks: this.shellTasks.size, activeAgentTasks: activeAgentRefs.size };
54
+ let external = 0;
55
+ // Same rule as the session sampler above: a failing sampler claims nothing rather than taking the heartbeat down.
56
+ try {
57
+ const sampled = this.externalActivity();
58
+ external = Number.isSafeInteger(sampled) && sampled > 0 ? sampled : 0;
59
+ }
60
+ catch {
61
+ external = 0;
62
+ }
63
+ return { activeShellTasks: this.shellTasks.size + external, activeAgentTasks: activeAgentRefs.size };
19
64
  }
20
65
  canUpdate() {
21
66
  const snapshot = this.snapshot();
@@ -56,7 +101,11 @@ export class TaskRegistry {
56
101
  for (const waiter of [...this.idleWaiters])
57
102
  waiter();
58
103
  }
59
- /** Run one shell task under an abort signal which force-update owns. */
104
+ /**
105
+ * Run one computer task under an abort signal which force-update owns. The method name preserves old callers.
106
+ * `release()` stops counting the task before it ends (work a daemon restart would no longer interrupt, spec §8.2): from then on it
107
+ * is not in `activeShellTasks`, a drain does not wait for it and `stopAll()` does not abort it. Idempotent.
108
+ */
60
109
  async withShellTask(run) {
61
110
  if (!this.accepting)
62
111
  throw new Error('Workstation is not accepting new work');
@@ -64,18 +113,72 @@ export class TaskRegistry {
64
113
  let complete;
65
114
  const cleanedUp = new Promise((resolve) => { complete = resolve; });
66
115
  this.shellTasks.set(controller, cleanedUp);
116
+ let counted = true;
117
+ const release = () => {
118
+ if (!counted)
119
+ return;
120
+ counted = false;
121
+ this.shellTasks.delete(controller);
122
+ complete();
123
+ this.notifyIfIdle();
124
+ };
67
125
  try {
68
- return await run(controller.signal);
126
+ return await run(controller.signal, release);
69
127
  }
70
128
  finally {
129
+ release();
130
+ }
131
+ }
132
+ /**
133
+ * Counts a short window of work in `activeShellTasks` WITHOUT the admission gate and without being stoppable: a drain (graceful
134
+ * or forced) waits for it, nothing aborts it. For work admitted while draining that a restart must not cut in half (a wire v5
135
+ * exec between `exec.start` and its first checkpoint, spec §8.2). Returns the release (idempotent).
136
+ */
137
+ holdShellTask() {
138
+ const controller = new AbortController();
139
+ let complete;
140
+ this.shellTasks.set(controller, new Promise((resolve) => { complete = resolve; }));
141
+ let held = true;
142
+ return () => {
143
+ if (!held)
144
+ return;
145
+ held = false;
71
146
  this.shellTasks.delete(controller);
72
147
  complete();
73
148
  this.notifyIfIdle();
74
- }
149
+ };
75
150
  }
76
- /** Register a live native agent for force-stop; idle sessions deliberately do not count as busy. */
77
- registerAgentSession(sessionRef, close) {
78
- this.agentSessions.set(sessionRef, close);
151
+ /**
152
+ * Marks one exec that runs in keeper-terminal AND is counted in `activeShellTasks` right now — a wire ≤ 4 exec (a shell task for
153
+ * its whole run) or a wire v5 exec before its first checkpoint (held). keeper-terminal's `execRunning` counts it too: the heartbeat
154
+ * reports this number (`execCounted`) so the Workstations page does not count it twice (final review minor 7). Returns the
155
+ * release (idempotent).
156
+ */
157
+ countKeeperExec() {
158
+ this.keeperExecsCounted += 1;
159
+ let counted = true;
160
+ return () => { if (!counted)
161
+ return; counted = false; this.keeperExecsCounted -= 1; };
162
+ }
163
+ /** How many keeper-terminal execs `activeShellTasks` includes now (see {@link countKeeperExec}). */
164
+ get countedKeeperExecs() { return this.keeperExecsCounted; }
165
+ /**
166
+ * Register a live native agent for force-stop, plus how to ask whether it is busy right now. A durable session's `close` must be
167
+ * its detach (see {@link AgentSessionRegistration}).
168
+ */
169
+ registerAgentSession(sessionRef, close, busy, registration = {}) {
170
+ this.agentSessions.set(sessionRef, { close, busy, durable: registration.durable === true });
171
+ }
172
+ /**
173
+ * 采样式判据没有"变空闲"这个事件可以挂钩,所以持有者在可能变空闲时喊一声。
174
+ * 多喊无害(`notifyIfIdle` 自己会再判一次),漏喊的代价只是等到下一次调用或超时。
175
+ */
176
+ sessionBusyChanged() {
177
+ this.notifyIfIdle();
178
+ }
179
+ /** The external activity level may have changed (see [externalActivity]). */
180
+ externalActivityChanged() {
181
+ this.notifyIfIdle();
79
182
  }
80
183
  /** Atomically admits and counts an asynchronous open before any journal or subprocess await. */
81
184
  tryReserveAgentOpen(sessionRef) {
@@ -96,25 +199,41 @@ export class TaskRegistry {
96
199
  isForceStopping() {
97
200
  return this.stopping !== null;
98
201
  }
202
+ /** Whether `sessionRef` is registered as a keeper-hosted (durable) session: a force stop leaves it admitted (see {@link stopAll}). */
203
+ isDurableSession(sessionRef) {
204
+ return this.agentSessions.get(sessionRef)?.durable === true;
205
+ }
99
206
  unregisterAgentSession(sessionRef) {
100
207
  this.agentSessions.delete(sessionRef);
101
- this.agentTasks.delete(sessionRef);
102
208
  this.notifyIfIdle();
103
209
  }
104
- /** Returns false whenever an update has closed the new-turn admission gate. */
105
- agentTurnStarted(sessionRef) {
106
- if (!this.accepting)
107
- return false;
108
- this.agentTasks.add(sessionRef);
109
- return true;
210
+ /**
211
+ * 排干期间拒收新回合。**只管准入**——它不再登记任何东西,忙碌由 [snapshot] 现场采样。
212
+ * 这两件事以前挤在一个方法里,删计数时极易把准入一起删掉,那会让 drain 期间照收新活。
213
+ */
214
+ tryAdmitTurn(sessionRef) {
215
+ // Spec §8.2: a keeper-hosted session's prompt is admitted while draining — it enters keeper-acp's log first and a restart
216
+ // continues it; a fallback session's would be cut by the restart.
217
+ return this.accepting || this.agentSessions.get(sessionRef)?.durable === true;
110
218
  }
111
- agentTurnFinished(sessionRef) {
112
- this.agentTasks.delete(sessionRef);
113
- this.notifyIfIdle();
219
+ /**
220
+ * The restart path of an update (Task 21, spec §5.5.5): every durable session is detached (its registered close), so the next daemon
221
+ * adopts it with a head checkpoint; fallback sessions are left as they are (they end with this process, their outboxes kept).
222
+ * Bounded by `timeoutMs`: a restart never waits on a session longer than that. All are attempted even when one fails.
223
+ */
224
+ async detachDurableSessions(timeoutMs = 5_000) {
225
+ const durable = [...this.agentSessions.values()].filter((session) => session.durable);
226
+ const all = Promise.allSettled(durable.map(async (session) => session.close()));
227
+ let timer;
228
+ await Promise.race([all, new Promise((resolve) => { timer = setTimeout(resolve, timeoutMs); })]);
229
+ clearTimeout(timer);
114
230
  }
115
231
  /**
116
232
  * Atomically refuse future work, signal every shell process group through its owning executor,
117
- * and close every native agent. All closes are attempted even when one bridge fails.
233
+ * and close every native agent that runs in this process. A durable (keeper-hosted) session is left alone: it stays registered,
234
+ * attached and admitted (spec §8.2, the same as a graceful drain) — the restart path detaches it right before the hand-off
235
+ * ({@link detachDurableSessions}), and a forced update that fails before that leaves it exactly as it was. All closes are
236
+ * attempted even when one bridge fails.
118
237
  */
119
238
  async stopAll() {
120
239
  if (this.stopping)
@@ -126,11 +245,10 @@ export class TaskRegistry {
126
245
  const shells = [...this.shellTasks.entries()];
127
246
  for (const [task] of shells)
128
247
  task.abort();
129
- this.agentTasks.clear();
130
248
  this.agentOpenReservations.clear();
131
249
  this.notifyIfIdle();
132
250
  const [outcomes] = await Promise.all([
133
- Promise.allSettled([...this.agentSessions.values()].map(async (close) => close())),
251
+ Promise.allSettled([...this.agentSessions.values()].filter((session) => !session.durable).map(async (session) => session.close())),
134
252
  Promise.all(shells.map(([, cleanedUp]) => cleanedUp)),
135
253
  ]);
136
254
  const failures = outcomes.filter((outcome) => outcome.status === 'rejected');
@@ -242,6 +242,72 @@ async function npmInstall(npmPath, npmPrefix, archive) {
242
242
  child.once('error', reject);
243
243
  child.once('close', (code) => code === 0 ? resolve() : reject(new Error(`npm rollback failed with exit ${code ?? 'unknown'}`)));
244
244
  });
245
+ await verifyOptionalPty(npmPrefix);
246
+ }
247
+ /**
248
+ * Whether the installed CLI's optional `node-pty` loads in this runtime. Kept in this standalone file
249
+ * because the rollback watchdog is copied out of the package.
250
+ *
251
+ * There is nothing to build: the pinned node-pty ships N-API prebuilds for all six desktop targets
252
+ * (linux included since 1.2.0-beta; 1.1.0 had none for linux, which is why this used to run
253
+ * `npm rebuild` and needed Python/make/a C++ compiler on the workstation). The check runs in a
254
+ * child process so a crashing addon cannot take the installer with it.
255
+ *
256
+ * Never fails the install. Terminal support is optional and the daemon already degrades only the
257
+ * terminal tool when the addon is missing; an update that rolled back over it left the whole
258
+ * workstation on the old client instead.
259
+ */
260
+ export async function verifyOptionalPty(npmPrefix, spawn = nodeSpawn, timeoutMs = 60_000, warn = console.warn) {
261
+ const root = path.join(npmPrefix, process.platform === 'win32' ? 'node_modules' : 'lib/node_modules', PACKAGE_NAME);
262
+ const addon = path.join(root, 'node_modules/node-pty');
263
+ try {
264
+ await fs.access(path.join(addon, 'package.json'));
265
+ }
266
+ catch (error) {
267
+ if (error.code === 'ENOENT')
268
+ return false; // Explicitly omitted optional dependency.
269
+ throw error;
270
+ }
271
+ try {
272
+ await new Promise((resolve, reject) => {
273
+ // A detached POSIX group lets a timeout stop the check and anything the addon started.
274
+ // It must finish well before the previous release's 120-second rollback deadline.
275
+ const child = spawn(process.execPath, ['-e', 'require(process.argv[1])', addon], { shell: false, stdio: 'ignore', windowsHide: true, detached: process.platform !== 'win32' });
276
+ let done = false;
277
+ const finish = (error) => {
278
+ if (done)
279
+ return;
280
+ done = true;
281
+ clearTimeout(timer);
282
+ if (error)
283
+ reject(error);
284
+ else
285
+ resolve();
286
+ };
287
+ const timer = setTimeout(() => {
288
+ try {
289
+ if (process.platform !== 'win32' && child.pid)
290
+ process.kill(-child.pid, 'SIGKILL');
291
+ else
292
+ child.kill('SIGKILL');
293
+ }
294
+ catch {
295
+ try {
296
+ child.kill('SIGKILL');
297
+ }
298
+ catch { /* Already exited. */ }
299
+ }
300
+ finish(new Error('timed out'));
301
+ }, timeoutMs);
302
+ child.once('error', () => finish(new Error('could not start the check')));
303
+ child.once('close', code => finish(code === 0 ? undefined : new Error(`exit ${code ?? 'unknown'}`)));
304
+ });
305
+ return true;
306
+ }
307
+ catch (error) {
308
+ warn(`[update] Optional node-pty does not load on this platform (${error.message}); the terminal tool stays unavailable.`);
309
+ return false;
310
+ }
245
311
  }
246
312
  /** How much of the child's own complaint is worth carrying into a 512-character status field. */
247
313
  const CAPTURED_STDERR_LIMIT = 300;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platless/axom-cli",
3
- "version": "0.1.0",
3
+ "version": "0.5.9",
4
4
  "description": "Axomwork CLI - manage Axomwork structures, records and executions over MCP",
5
5
  "type": "module",
6
6
  "bin": {
@@ -11,29 +11,42 @@
11
11
  "skills"
12
12
  ],
13
13
  "engines": {
14
- "node": ">=20"
14
+ "node": ">=24"
15
15
  },
16
16
  "scripts": {
17
- "build": "rm -rf dist && tsc",
17
+ "build": "rm -rf dist && tsc && node scripts/copy-patches.mjs && node scripts/copy-runtime-deps.mjs && node scripts/bundle-keepers.mjs",
18
+ "pretest": "npm run build",
18
19
  "test": "vitest run",
19
- "typecheck": "tsc --noEmit"
20
+ "typecheck": "tsc --noEmit",
21
+ "prepack": "node scripts/copy-patches.mjs --check && node scripts/copy-runtime-deps.mjs --check && node scripts/bundle-keepers.mjs --check"
20
22
  },
21
23
  "dependencies": {
22
- "@agentclientprotocol/sdk": "^1.4.0",
24
+ "@agentclientprotocol/sdk": "1.4.0",
23
25
  "@modelcontextprotocol/sdk": "^1.29.0",
24
26
  "@napi-rs/keyring": "^1.1.3",
27
+ "@xterm/addon-serialize": "^0.14.0",
28
+ "@xterm/headless": "^6.0.0",
25
29
  "commander": "^15.0.0",
26
30
  "js-yaml": "^4.1.0",
31
+ "proper-lockfile": "4.1.2",
27
32
  "semver": "^7.8.5",
28
33
  "ws": "^8.18.0",
29
34
  "zod": "^4.4.3"
30
35
  },
31
36
  "devDependencies": {
37
+ "@qoder-ai/qoder-agent-sdk": "1.0.50",
32
38
  "@types/js-yaml": "^4.0.9",
33
- "@types/node": "^20.11.0",
39
+ "@types/node": "^24.19.2",
40
+ "@types/proper-lockfile": "4.1.4",
34
41
  "@types/semver": "^7.8.0",
35
42
  "@types/ws": "^8.5.13",
43
+ "esbuild": "0.27.7",
36
44
  "typescript": "^5.2.2",
37
45
  "vitest": "^2.1.9"
38
- }
46
+ },
47
+ "optionalDependencies": {
48
+ "node-pty": "1.2.0-beta.15",
49
+ "playwright-core": "1.63.0"
50
+ },
51
+ "axomPatchBundle": true
39
52
  }
@@ -1,31 +1,31 @@
1
1
  ---
2
2
  name: axom
3
- description: "Work with Axomwork applications: inspect structures, query and mutate records, execute operations and services via Axomwork MCP tools"
3
+ description: "Work with Axomwork applications: inspect structures, query and mutate records, execute operations and services, manage projects and tasks, and read or update your own account via Axomwork MCP tools"
4
4
  ---
5
5
 
6
6
  # Axomwork
7
7
 
8
- Use this skill when an Axomwork MCP server is connected and you need to inspect application structure, read or change business records, or execute model operations and services.
8
+ Use this skill when an Axomwork MCP server is connected and you need to inspect application structure, read or change business records, execute model operations and services, manage projects and tasks, or read or update your own account.
9
9
 
10
10
  ## Workflow
11
11
 
12
- Start by discovering structure before changing records. Use `axom__struct__list_applications()` to find applications, then `axom__struct__get_model({ applicationName, modelName })` to inspect fields, operations, and record shape. Only then query, create, update, delete, upsert, or execute.
12
+ Start by discovering structure before changing records. Use `axom__app_struct__list_applications()` to find applications, then `axom__app_struct__get_model({ applicationName, modelName })` to inspect fields, operations, and record shape. Only then query, create, update, delete, upsert, or execute.
13
13
 
14
14
  ## Core Tools
15
15
 
16
16
  - `axom__system__whoami()` - returns the current authenticated user and role.
17
- - `axom__struct__list_applications()` - lists available applications.
18
- - `axom__struct__get_application({ applicationName })` - reads one application definition.
19
- - `axom__struct__list_models({ applicationName })` - lists models in an application.
20
- - `axom__struct__get_model({ applicationName, modelName })` - reads one model definition, including attributes and operations.
21
- - `axom__record__query({ applicationName, modelName, criteria?, page? })` - queries records using REST-compatible filters and sorts in `criteria`.
22
- - `axom__record__get({ applicationName, modelName, id })` - reads one record by id.
23
- - `axom__record__create({ applicationName, modelName, record })` - creates a record; `record` contains model field values.
24
- - `axom__record__update({ applicationName, modelName, id, changes })` - updates one record; `changes` contains only the fields to modify.
25
- - `axom__record__upsert({ applicationName, modelName, identityField, record })` - creates or updates a record matched by `identityField`; `record` must include that field. The model must declare a `unique` validation on `identityField`, or the call throws — check `get_model` for that before calling upsert on an unfamiliar model.
26
- - `axom__record__delete({ applicationName, modelName, id })` - deletes one record by id.
27
- - `axom__operation__execute({ applicationName, modelName, operationName, input })` - executes a model operation and waits for the result. Use `axom__operation__execute_async` with the same arguments when asynchronous continuation is intended; it returns a running status and a child run id.
28
- - `axom__service__execute({ applicationName?, serviceName, input })` - executes a reusable platform or application-scoped service, with `axom__service__execute_async` as its non-waiting counterpart.
17
+ - `axom__app_struct__list_applications()` - lists available applications.
18
+ - `axom__app_struct__get_application({ applicationName })` - reads one application definition.
19
+ - `axom__app_struct__list_models({ applicationName })` - lists models in an application.
20
+ - `axom__app_struct__get_model({ applicationName, modelName })` - reads one model definition, including attributes and operations.
21
+ - `axom__record_query__query_records({ applicationName, modelName, criteria?, page? })` - queries records using REST-compatible filters and sorts in `criteria`.
22
+ - `axom__record_query__get_record({ applicationName, modelName, id })` - reads one record by id.
23
+ - `axom__record_write__create_record({ applicationName, modelName, record })` - creates a record; `record` contains model field values.
24
+ - `axom__record_write__update_record({ applicationName, modelName, id, changes })` - updates one record; `changes` contains only the fields to modify.
25
+ - `axom__record_write__upsert_record({ applicationName, modelName, identityField, record })` - creates or updates a record matched by `identityField`; `record` must include that field. The model must declare a `unique` validation on `identityField`, or the call throws — check `get_model` for that before calling upsert on an unfamiliar model.
26
+ - `axom__record_write__delete_record({ applicationName, modelName, id })` - deletes one record by id.
27
+ - `axom__execute__run_operation({ applicationName, modelName, operationName, input })` - executes a model operation and waits for the result. Use `axom__execute__run_operation_async` with the same arguments when asynchronous continuation is intended; it returns a running status and a child run id.
28
+ - `axom__execute__run_service({ applicationName?, serviceName, input })` - executes a reusable platform or application-scoped service, with `axom__execute__run_service_async` as its non-waiting counterpart.
29
29
 
30
30
  ## Query Criteria
31
31
 
@@ -50,7 +50,7 @@ Filter `op` values are `eq|gt|lt|like|in|and|or`. Use nested `filters` for `and`
50
50
 
51
51
  ## Upserting a Record
52
52
 
53
- Use `axom__record__upsert` when a stable external identifier should select an existing record or create a new one. Supply the canonical fields in this order, and include the identity value inside `record`:
53
+ Use `axom__record_write__upsert_record` when a stable external identifier should select an existing record or create a new one. Supply the canonical fields in this order, and include the identity value inside `record`:
54
54
  For create/update/upsert safety, load guide
55
55
  `agent-integration/operating-patterns/safe-record-mutations.md`; before deletion, load
56
56
  `agent-integration/operating-patterns/destructive-actions.md`.
@@ -69,11 +69,49 @@ For create/update/upsert safety, load guide
69
69
 
70
70
  ## Execution Results
71
71
 
72
- `axom__operation__execute` and `axom__service__execute` return an OperationResult-style payload. Interpret `success` as the primary outcome, `text` as user-facing output, `data` as structured result data, `message` as diagnostic detail, `processing` as whether work continues asynchronously, and `runId` as the related run identifier when one is started.
72
+ `axom__execute__run_operation` and `axom__execute__run_service` return an OperationResult-style payload. Interpret `success` as the primary outcome, `text` as user-facing output, `data` as structured result data, `message` as diagnostic detail, `processing` as whether work continues asynchronously, and `runId` as the related run identifier when one is started.
73
73
  For asynchronous continuation, load guides
74
74
  `concepts/execution/synchronous-and-task-execution.md` and
75
75
  `agent-integration/operating-patterns/following-runs.md`.
76
76
 
77
+ ## Tasks
78
+
79
+ Requires the `task` scope. The acting user is always the authenticated account; never pass a user id to act as someone else.
80
+
81
+ - `axom__task__list_projects({ limit?, offset? })` - lists projects you can see.
82
+ - `axom__task__get_project({ projectId })` - reads one project.
83
+ - `axom__task__create_project({ name, description?, prompts? })` - creates a project owned by you; `prompts` is `[{ type, content }]` with `type` one of `brainstorm`, `execute`, `validate`, `archive` (at most one each).
84
+ - `axom__task__update_project({ projectId, name, description?, prompts? })` - renames or re-describes a project; other project settings are kept, and so are its prompts unless you pass `prompts`, which replaces them all.
85
+ - `axom__task__delete_project({ projectId })` - deletes a project. Confirm with the user first.
86
+ - `axom__task__list_project_members({ projectId })` - lists members and their roles.
87
+ - `axom__task__add_project_member({ projectId, userId, type })` - adds a member; `type` is `owner` or `member`.
88
+ - `axom__task__update_project_member({ projectId, userId, type })` - changes a member's role.
89
+ - `axom__task__remove_project_member({ projectId, userId })` - removes a member.
90
+ - `axom__task__list_tasks({ projectId?, parentTaskId?, status?, assigneeId?, limit?, offset? })` - lists tasks by filter.
91
+ - `axom__task__get_task({ taskId })` - reads one task.
92
+ - `axom__task__create_task({ projectId?, parentTaskId?, title, proposal?, status?, assigneeId? })` - creates a task; `proposal` is Markdown.
93
+ - `axom__task__update_task({ taskId, projectId?, parentTaskId?, title, proposal?, status, assigneeId? })` - replaces a task's fields; read it first and send every field you want to keep.
94
+ - `axom__task__delete_task({ taskId })` - deletes a task. Confirm with the user first.
95
+ - `axom__task__list_artifacts({ taskId, kind?, status?, limit?, offset? })` - lists one page (at most 50) of a task's artifacts (insights, decisions, specs, plans), newest first, without content; `summary` is a 100-character preview. Continue with `offset: nextOffset` until `nextOffset` is null.
96
+ - `axom__task__get_artifact({ artifactId, offset?, length? })` - reads one artifact; long content comes in windows of at most 12000 characters, continue from `nextContentOffset`.
97
+ - `axom__task__search_artifacts({ query, taskId?, projectId?, scope?, limit? })` - searches one task's artifacts (`scope: task`) or every task in a project (`scope: project`); without `scope`, passing only `projectId` searches the project, otherwise the task.
98
+ - `axom__task__create_artifact({ taskId, kind, title, summary, content, status? })` - records an artifact; a `final` `plan` moves a `brainstorming` task to `planned`.
99
+ - `axom__task__update_artifact({ artifactId, kind?, title?, summary?, content?, status? })` - changes only the fields you pass.
100
+ - `axom__task__delete_artifact({ artifactId })` - deletes an artifact; the task's status does not change. Confirm with the user first.
101
+ - `axom__task__import_artifact({ taskId, path, kind, title, summary, status? })` - imports a Markdown file from the task's worktree (`path` is relative to it); importing the same path again updates the same artifact.
102
+ - `axom__task__list_agent_members({ taskId })` - lists the task's live agent team.
103
+ - `axom__task__execute_plan({ taskId })` - starts a `planned` task (`planned` becomes `in_progress`).
104
+
105
+ ## Your account
106
+
107
+ Requires the `setting_user` scope. These tools only ever act on the authenticated user. Passwords, sessions, and access tokens are deliberately not available over MCP; manage them in Settings → Security.
108
+
109
+ - `axom__setting_user__get_profile()` - gets the calling user's profile.
110
+ - `axom__setting_user__update_profile({ displayName?, email? })` - replaces the calling user's display name and email; omitted or null fields are cleared.
111
+ - `axom__setting_user__list_memories({ limit?, offset? })` - lists the calling user's memory facts (deleted ones excluded), newest first; `limit` defaults to 50.
112
+ - `axom__setting_user__delete_memory({ factId })` - deletes one of the calling user's memory facts; another user's fact id answers not-found.
113
+ - `axom__setting_user__list_workstations()` - lists the calling user's personal workstations and their status.
114
+
77
115
  ## Guide
78
116
 
79
117
  Axomwork ships an AI-first manual. Call `axom__guide__load` with no arguments for the table of
@@ -5,7 +5,7 @@ description: "Develop Axomwork application definitions with independently callab
5
5
 
6
6
  # Axomwork Definition
7
7
 
8
- Use this skill to edit application definitions with the canonical `axom__definition__*` MCP tools. These tools require an ADMIN token. Check `tools/list` for the specific tool before calling it.
8
+ Use this skill to edit application definitions with the canonical `axom__app_studio__*` MCP tools. These tools require the `app_studio` scope and an administrator account. Check `tools/list` for the specific tool before calling it.
9
9
 
10
10
  Call each tool directly with camelCase arguments:
11
11
 
@@ -21,49 +21,49 @@ Load guides `agent-integration/operating-patterns/etag-write-workflow.md` and
21
21
 
22
22
  ## Applications
23
23
 
24
- - `axom__definition__list_applications`
25
- - `axom__definition__get_application` — `applicationName`
26
- - `axom__definition__create_application` — `application`, `expectedEtag`
27
- - `axom__definition__update_application` — `applicationName`, `application`, `expectedEtag`
28
- - `axom__definition__delete_application` — `applicationName`, `expectedEtag`
24
+ - `axom__app_studio__list_applications`
25
+ - `axom__app_studio__get_application` — `applicationName`
26
+ - `axom__app_studio__create_application` — `application`, `expectedEtag`
27
+ - `axom__app_studio__update_application` — `applicationName`, `application`, `expectedEtag`
28
+ - `axom__app_studio__delete_application` — `applicationName`, `expectedEtag`
29
29
 
30
30
  ## Models
31
31
 
32
- - `axom__definition__list_models` — `applicationName`
33
- - `axom__definition__get_model` — `applicationName`, `modelName`
34
- - `axom__definition__create_model` — `applicationName`, `model`, `expectedEtag`
35
- - `axom__definition__update_model` — `applicationName`, `modelName`, `model`, `expectedEtag`
36
- - `axom__definition__delete_model` — `applicationName`, `modelName`, `expectedEtag`
32
+ - `axom__app_studio__list_models` — `applicationName`
33
+ - `axom__app_studio__get_model` — `applicationName`, `modelName`
34
+ - `axom__app_studio__create_model` — `applicationName`, `model`, `expectedEtag`
35
+ - `axom__app_studio__update_model` — `applicationName`, `modelName`, `model`, `expectedEtag`
36
+ - `axom__app_studio__delete_model` — `applicationName`, `modelName`, `expectedEtag`
37
37
 
38
38
  ## Attributes and operations
39
39
 
40
- - `axom__definition__get_attribute` — `applicationName`, `modelName`, `attributeName`
41
- - `axom__definition__create_attribute` — `applicationName`, `modelName`, `attribute`, `expectedEtag`
42
- - `axom__definition__update_attribute` — `applicationName`, `modelName`, `attributeName`, `attribute`, `expectedEtag`
43
- - `axom__definition__delete_attribute` — `applicationName`, `modelName`, `attributeName`, `expectedEtag`
44
- - `axom__definition__get_operation` — `applicationName`, `modelName`, `operationName`
45
- - `axom__definition__create_operation` — `applicationName`, `modelName`, `operation`, `expectedEtag`
46
- - `axom__definition__update_operation` — `applicationName`, `modelName`, `operationName`, `operation`, `expectedEtag`
47
- - `axom__definition__delete_operation` — `applicationName`, `modelName`, `operationName`, `expectedEtag`
48
- - `axom__definition__get_operation_body` — `applicationName`, `modelName`, `operationName`
49
- - `axom__definition__update_operation_body` — `applicationName`, `modelName`, `operationName`, `content`, `expectedBodyEtag`
40
+ - `axom__app_studio__get_attribute` — `applicationName`, `modelName`, `attributeName`
41
+ - `axom__app_studio__create_attribute` — `applicationName`, `modelName`, `attribute`, `expectedEtag`
42
+ - `axom__app_studio__update_attribute` — `applicationName`, `modelName`, `attributeName`, `attribute`, `expectedEtag`
43
+ - `axom__app_studio__delete_attribute` — `applicationName`, `modelName`, `attributeName`, `expectedEtag`
44
+ - `axom__app_studio__get_operation` — `applicationName`, `modelName`, `operationName`
45
+ - `axom__app_studio__create_operation` — `applicationName`, `modelName`, `operation`, `expectedEtag`
46
+ - `axom__app_studio__update_operation` — `applicationName`, `modelName`, `operationName`, `operation`, `expectedEtag`
47
+ - `axom__app_studio__delete_operation` — `applicationName`, `modelName`, `operationName`, `expectedEtag`
48
+ - `axom__app_studio__get_operation_body` — `applicationName`, `modelName`, `operationName`
49
+ - `axom__app_studio__update_operation_body` — `applicationName`, `modelName`, `operationName`, `content`, `expectedBodyEtag`
50
50
 
51
51
  ## Triggers and lifecycle
52
52
 
53
- - `axom__definition__update_triggers` — `applicationName`, `modelName`, `triggers`, `expectedEtag`
54
- - `axom__definition__get_lifecycle` — `applicationName`, `modelName`
55
- - `axom__definition__update_lifecycle` — `applicationName`, `modelName`, `lifecycle`, `expectedEtag`
56
- - `axom__definition__delete_lifecycle` — `applicationName`, `modelName`, `expectedEtag`
53
+ - `axom__app_studio__update_triggers` — `applicationName`, `modelName`, `triggers`, `expectedEtag`
54
+ - `axom__app_studio__get_lifecycle` — `applicationName`, `modelName`
55
+ - `axom__app_studio__update_lifecycle` — `applicationName`, `modelName`, `lifecycle`, `expectedEtag`
56
+ - `axom__app_studio__delete_lifecycle` — `applicationName`, `modelName`, `expectedEtag`
57
57
 
58
58
  ## Workflows
59
59
 
60
- - `axom__definition__list_workflows` — `applicationName`, `modelName`
61
- - `axom__definition__get_workflow` — `applicationName`, `modelName`, `workflowName`
62
- - `axom__definition__create_workflow` — `applicationName`, `modelName`, `workflow`, `expectedEtag`
63
- - `axom__definition__update_workflow` — `applicationName`, `modelName`, `workflowName`, `workflow`, `expectedEtag`
64
- - `axom__definition__delete_workflow` — `applicationName`, `modelName`, `workflowName`, `expectedEtag`
65
- - `axom__definition__get_workflow_body` — `applicationName`, `modelName`, `workflowName`
66
- - `axom__definition__update_workflow_body` — `applicationName`, `modelName`, `workflowName`, `content`, `expectedBodyEtag`
60
+ - `axom__app_studio__list_workflows` — `applicationName`, `modelName`
61
+ - `axom__app_studio__get_workflow` — `applicationName`, `modelName`, `workflowName`
62
+ - `axom__app_studio__create_workflow` — `applicationName`, `modelName`, `workflow`, `expectedEtag`
63
+ - `axom__app_studio__update_workflow` — `applicationName`, `modelName`, `workflowName`, `workflow`, `expectedEtag`
64
+ - `axom__app_studio__delete_workflow` — `applicationName`, `modelName`, `workflowName`, `expectedEtag`
65
+ - `axom__app_studio__get_workflow_body` — `applicationName`, `modelName`, `workflowName`
66
+ - `axom__app_studio__update_workflow_body` — `applicationName`, `modelName`, `workflowName`, `content`, `expectedBodyEtag`
67
67
 
68
68
  ## Guide
69
69