@someonegg/agent-hub 0.0.0-stage → 0.7.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 (185) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +104 -2
  3. package/README.zh-CN.md +99 -0
  4. package/README.zh-TW.md +99 -0
  5. package/dist/client/apple-touch-icon.png +0 -0
  6. package/dist/client/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  7. package/dist/client/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  8. package/dist/client/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  9. package/dist/client/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  10. package/dist/client/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  11. package/dist/client/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  12. package/dist/client/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  13. package/dist/client/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  14. package/dist/client/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  15. package/dist/client/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  16. package/dist/client/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  17. package/dist/client/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  18. package/dist/client/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  19. package/dist/client/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  20. package/dist/client/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  21. package/dist/client/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  22. package/dist/client/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  23. package/dist/client/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  24. package/dist/client/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  25. package/dist/client/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  26. package/dist/client/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  27. package/dist/client/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  28. package/dist/client/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  29. package/dist/client/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  30. package/dist/client/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  31. package/dist/client/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  32. package/dist/client/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  33. package/dist/client/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  34. package/dist/client/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  35. package/dist/client/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  36. package/dist/client/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  37. package/dist/client/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  38. package/dist/client/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  39. package/dist/client/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  40. package/dist/client/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  41. package/dist/client/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  42. package/dist/client/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  43. package/dist/client/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  44. package/dist/client/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  45. package/dist/client/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  46. package/dist/client/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  47. package/dist/client/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  48. package/dist/client/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  49. package/dist/client/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  50. package/dist/client/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  51. package/dist/client/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  52. package/dist/client/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  53. package/dist/client/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  54. package/dist/client/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  55. package/dist/client/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  56. package/dist/client/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  57. package/dist/client/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  58. package/dist/client/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  59. package/dist/client/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  60. package/dist/client/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  61. package/dist/client/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  62. package/dist/client/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  63. package/dist/client/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  64. package/dist/client/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  65. package/dist/client/assets/index-4ejyszaV.css +1 -0
  66. package/dist/client/assets/index-CKKT4cMK.js +309 -0
  67. package/dist/client/favicon.ico +0 -0
  68. package/dist/client/favicon.svg +6 -0
  69. package/dist/client/icons/icon-192.png +0 -0
  70. package/dist/client/icons/icon-512.png +0 -0
  71. package/dist/client/icons/icon-maskable-512.png +0 -0
  72. package/dist/client/index.html +22 -0
  73. package/dist/client/manifest.webmanifest +21 -0
  74. package/dist/server/server/adapters/claude/claude-session-source.js +220 -0
  75. package/dist/server/server/adapters/claude/identity.js +28 -0
  76. package/dist/server/server/adapters/claude/interaction.js +68 -0
  77. package/dist/server/server/adapters/claude/prompt-readiness.js +12 -0
  78. package/dist/server/server/adapters/claude/ready-script.js +25 -0
  79. package/dist/server/server/adapters/claude/session-manager.js +106 -0
  80. package/dist/server/server/adapters/claude/session-normalizer.js +173 -0
  81. package/dist/server/server/adapters/claude/user-input-normalizer.js +71 -0
  82. package/dist/server/server/adapters/codex/catalog-source.js +2 -0
  83. package/dist/server/server/adapters/codex/codex-session-source.js +250 -0
  84. package/dist/server/server/adapters/codex/identity-resolver.js +104 -0
  85. package/dist/server/server/adapters/codex/interaction-parser.js +70 -0
  86. package/dist/server/server/adapters/codex/io-errors.js +2 -0
  87. package/dist/server/server/adapters/codex/jsonl-catalog-source.js +84 -0
  88. package/dist/server/server/adapters/codex/limits.js +2 -0
  89. package/dist/server/server/adapters/codex/message-normalizer.js +66 -0
  90. package/dist/server/server/adapters/codex/response-item-parser.js +64 -0
  91. package/dist/server/server/adapters/codex/rollout-descriptor.js +2 -0
  92. package/dist/server/server/adapters/codex/session-index-reader.js +101 -0
  93. package/dist/server/server/adapters/codex/session-manager.js +51 -0
  94. package/dist/server/server/adapters/codex/session-normalizer.js +175 -0
  95. package/dist/server/server/adapters/codex/subagent-identity.js +9 -0
  96. package/dist/server/server/adapters/codex/user-input-normalizer.js +121 -0
  97. package/dist/server/server/adapters/codex/value-readers.js +4 -0
  98. package/dist/server/server/adapters/shared/binding-protocol.js +54 -0
  99. package/dist/server/server/adapters/shared/io-errors.js +13 -0
  100. package/dist/server/server/adapters/shared/jsonl-decoder.js +263 -0
  101. package/dist/server/server/adapters/shared/limits.js +4 -0
  102. package/dist/server/server/adapters/shared/session-management.js +43 -0
  103. package/dist/server/server/adapters/shared/source-cache.js +23 -0
  104. package/dist/server/server/api/session-api-mapper.js +65 -0
  105. package/dist/server/server/application/interaction-session-reader.js +17 -0
  106. package/dist/server/server/application/session-read-service.js +86 -0
  107. package/dist/server/server/application/session-reader.js +2 -0
  108. package/dist/server/server/application/session-response.js +11 -0
  109. package/dist/server/server/catalog/config.js +4 -0
  110. package/dist/server/server/catalog/session-catalog-service.js +112 -0
  111. package/dist/server/server/cli/command-error.js +27 -0
  112. package/dist/server/server/cli/main.js +42 -0
  113. package/dist/server/server/cli/output.js +52 -0
  114. package/dist/server/server/cli/resource.js +104 -0
  115. package/dist/server/server/cli/session-client.js +64 -0
  116. package/dist/server/server/cli/session-follow.js +58 -0
  117. package/dist/server/server/cli/session-output.js +184 -0
  118. package/dist/server/server/cli/session-wait.js +44 -0
  119. package/dist/server/server/cli/session.js +318 -0
  120. package/dist/server/server/cli/skill.js +37 -0
  121. package/dist/server/server/config.js +196 -0
  122. package/dist/server/server/create-hub.js +91 -0
  123. package/dist/server/server/directory-lock.js +65 -0
  124. package/dist/server/server/domain/project-directory.js +5 -0
  125. package/dist/server/server/domain/session-domain.js +2 -0
  126. package/dist/server/server/domain/session-text.js +45 -0
  127. package/dist/server/server/hosting/diff-store.js +103 -0
  128. package/dist/server/server/hosting/routes.js +168 -0
  129. package/dist/server/server/hosting/store.js +162 -0
  130. package/dist/server/server/hosting/validation-error.js +4 -0
  131. package/dist/server/server/http/api-route-handler.js +2 -0
  132. package/dist/server/server/http/api-router.js +54 -0
  133. package/dist/server/server/http/create-server.js +218 -0
  134. package/dist/server/server/http/query-params.js +19 -0
  135. package/dist/server/server/http/request-body.js +48 -0
  136. package/dist/server/server/http/request-errors.js +59 -0
  137. package/dist/server/server/http/router.js +16 -0
  138. package/dist/server/server/http/security.js +19 -0
  139. package/dist/server/server/http/session-interaction-routes.js +128 -0
  140. package/dist/server/server/http/session-management-routes.js +105 -0
  141. package/dist/server/server/http/session-path.js +10 -0
  142. package/dist/server/server/http/session-read-routes.js +143 -0
  143. package/dist/server/server/http/terminal-preview-websocket.js +179 -0
  144. package/dist/server/server/http/upload-routes.js +124 -0
  145. package/dist/server/server/interaction/interaction-service.js +276 -0
  146. package/dist/server/server/interaction/message.js +19 -0
  147. package/dist/server/server/interaction/pane-binding-manager.js +62 -0
  148. package/dist/server/server/interaction/pane-observation.js +31 -0
  149. package/dist/server/server/interaction/reconcile-session-state.js +21 -0
  150. package/dist/server/server/interaction/runtime-capabilities.js +2 -0
  151. package/dist/server/server/interaction/session-runtime.js +86 -0
  152. package/dist/server/server/interaction/terminal-activity-service.js +81 -0
  153. package/dist/server/server/interaction/terminal-preview-diff.js +71 -0
  154. package/dist/server/server/interaction/terminal-preview-service.js +184 -0
  155. package/dist/server/server/interaction/tmux-launcher.js +84 -0
  156. package/dist/server/server/interaction/tmux-preview-listener.js +107 -0
  157. package/dist/server/server/interaction/tmux-service.js +334 -0
  158. package/dist/server/server/interaction/tmux-target.js +13 -0
  159. package/dist/server/server/interaction/transport.js +9 -0
  160. package/dist/server/server/main.js +54 -0
  161. package/dist/server/server/management/operation-service.js +307 -0
  162. package/dist/server/server/management/operation-state.js +3 -0
  163. package/dist/server/server/management/session-exit-service.js +50 -0
  164. package/dist/server/server/management/session-launch-executor.js +164 -0
  165. package/dist/server/server/management/session-lifecycle-executor.js +158 -0
  166. package/dist/server/server/management/session-manager.js +64 -0
  167. package/dist/server/server/repository/catalog-snapshot-store.js +318 -0
  168. package/dist/server/server/repository/diagnostic-logger.js +70 -0
  169. package/dist/server/server/repository/refresh-coordinator.js +14 -0
  170. package/dist/server/server/repository/session-queries.js +72 -0
  171. package/dist/server/server/security/opaque-id.js +17 -0
  172. package/dist/server/server/source/session-source.js +2 -0
  173. package/dist/server/server/updates/session-updates-service.js +151 -0
  174. package/dist/server/server/updates/update-revision.js +22 -0
  175. package/dist/server/server/uploads/store.js +304 -0
  176. package/dist/server/server/version.js +21 -0
  177. package/dist/server/shared/api-contract.js +2 -0
  178. package/dist/server/shared/diff.js +158 -0
  179. package/dist/server/shared/domain.js +2 -0
  180. package/dist/server/shared/interaction.js +22 -0
  181. package/dist/server/shared/task-name.js +6 -0
  182. package/dist/server/shared/uploads.js +8 -0
  183. package/package.json +98 -4
  184. package/skills/ahub-control/SKILL.md +93 -0
  185. package/skills/ahub-publish/SKILL.md +54 -0
@@ -0,0 +1,6 @@
1
+ /** Task names must fit on one binding-output line without shell block delimiters. */
2
+ export function validTaskName(value) {
3
+ return typeof value === "string" && !/[<>\0\r\n]/.test(value);
4
+ }
5
+ export const TASK_NAME_ERROR = "Task name must be a string without <, >, NUL, or line breaks";
6
+ //# sourceMappingURL=task-name.js.map
@@ -0,0 +1,8 @@
1
+ export const MAX_UPLOAD_BYTES = 20 * 1024 * 1024;
2
+ export function isPreviewableUploadType(type) {
3
+ return /^image\/(png|jpeg|gif|webp|avif|bmp)$/.test(type);
4
+ }
5
+ export function supportsUploadThumbnail(type) {
6
+ return isPreviewableUploadType(type) && type !== "image/bmp";
7
+ }
8
+ //# sourceMappingURL=uploads.js.map
package/package.json CHANGED
@@ -1,6 +1,100 @@
1
1
  {
2
2
  "name": "@someonegg/agent-hub",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.7.0",
4
+ "description": "Local project and session hub for coding agents",
5
+ "type": "module",
6
+ "engines": {
7
+ "node": ">=22.13"
8
+ },
9
+ "scripts": {
10
+ "dev": "vite --host 127.0.0.1",
11
+ "build": "vite build && tsc -p tsconfig.server.json",
12
+ "start": "node dist/server/server/main.js",
13
+ "benchmark:scale": "tsx scripts/benchmark-scale.ts",
14
+ "test": "vitest run",
15
+ "test:integration:codex": "vitest run --config vitest.integration.config.ts tests/integration/codex-management.integration.ts",
16
+ "test:all": "npm test && npm run test:integration:tmux && npm run test:integration:codex && npm run test:integration:claude",
17
+ "test:integration:tmux": "vitest run --config vitest.integration.config.ts tests/integration/tmux-service.integration.ts",
18
+ "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.server.json --noEmit && tsc -p tsconfig.tests-server.json",
19
+ "format": "prettier --write .",
20
+ "format:check": "prettier --check .",
21
+ "lint": "lint-client",
22
+ "prepack": "npm run build",
23
+ "test:package": "node scripts/test-package.mjs",
24
+ "test:hosting": "npm run build && node --import tsx scripts/test-hosting.mjs",
25
+ "test:integration:claude": "vitest run --config vitest.integration.config.ts tests/integration/claude-management.integration.ts"
26
+ },
27
+ "keywords": [
28
+ "agent",
29
+ "codex",
30
+ "claude",
31
+ "sessions",
32
+ "reader"
33
+ ],
34
+ "license": "MIT",
35
+ "dependencies": {
36
+ "@types/estree": "1.0.9",
37
+ "i18next": "^26.5.11",
38
+ "katex": "^0.18.10",
39
+ "mdast-util-from-markdown": "^2.0.3",
40
+ "mdast-util-gfm": "^3.1.0",
41
+ "mdast-util-to-string": "^4.0.0",
42
+ "micromark-extension-gfm": "^3.0.0",
43
+ "react": "^19.2.8",
44
+ "react-dom": "^19.2.8",
45
+ "react-i18next": "^17.1.9",
46
+ "react-markdown": "^10.1.0",
47
+ "rehype-katex": "^7.0.1",
48
+ "remark-gfm": "^4.0.1",
49
+ "remark-math": "^6.0.0",
50
+ "sharp": "^0.35.5",
51
+ "string-width": "^8.3.0",
52
+ "ws": "^8.22.0"
53
+ },
54
+ "overrides": {
55
+ "katex": "$katex",
56
+ "@ahub/client-lint": {
57
+ "minimatch": "^11.0.1"
58
+ }
59
+ },
60
+ "devDependencies": {
61
+ "@babel/parser": "^7.29.12",
62
+ "@ahub/client-lint": "file:tools/client-lint",
63
+ "@testing-library/jest-dom": "^7.0.0",
64
+ "@testing-library/react": "^16.3.2",
65
+ "@testing-library/user-event": "^14.6.1",
66
+ "@types/node": "^26.1.2",
67
+ "@types/react": "^19.2.17",
68
+ "@types/react-dom": "^19.2.3",
69
+ "@types/ws": "^8.18.2",
70
+ "@vitejs/plugin-react": "^6.0.4",
71
+ "jsdom": "^30.1.3",
72
+ "prettier": "3.6.2",
73
+ "tsx": "^4.23.1",
74
+ "typescript": "^7.0.2",
75
+ "vite": "^8.1.5",
76
+ "vitest": "^4.1.10"
77
+ },
78
+ "bin": {
79
+ "agent-hub": "dist/server/server/main.js",
80
+ "ahub-cli": "dist/server/server/cli/main.js"
81
+ },
82
+ "files": [
83
+ "skills/ahub-publish",
84
+ "skills/ahub-control",
85
+ "dist/client",
86
+ "dist/server",
87
+ "!dist/**/*.map"
88
+ ],
89
+ "publishConfig": {
90
+ "access": "public"
91
+ },
92
+ "repository": {
93
+ "type": "git",
94
+ "url": "git+https://github.com/someonegg/agent_hub.git"
95
+ },
96
+ "homepage": "https://github.com/someonegg/agent_hub#readme",
97
+ "bugs": {
98
+ "url": "https://github.com/someonegg/agent_hub/issues"
99
+ }
100
+ }
@@ -0,0 +1,93 @@
1
+ ---
2
+ name: ahub-control
3
+ description: Manage agent sessions through an existing Agent Hub using ahub-cli session. Use only when the user explicitly requests `ahub-control` by name.
4
+ ---
5
+
6
+ # Coordinate sessions through Agent Hub
7
+
8
+ The CLI reports runtime state, replies, input requests, and diagnostics. The caller verifies deliverables and decides whether the task is complete. Create, control, or clean up only sessions within the authorized task scope.
9
+
10
+ ## Check the environment and target
11
+
12
+ - Check `command -v ahub-cli` and `ahub-cli session --help` for the commands and options needed by the task. Report missing capabilities; install, update, or start services only when authorized.
13
+ - Address precedence is `--url`, `AGENT_HUB_URL`, then `http://127.0.0.1:4173`. Keep custom addresses consistent across commands.
14
+ - HTTP and HTTPS origins are supported. HTTPS uses Node.js certificate verification; for a private CA, set `NODE_EXTRA_CA_CERTS=/absolute/path/to/ca.pem` before starting the CLI.
15
+ - Select existing sessions with `list --project /absolute/project --json`. It lists main sessions. Known child IDs can be inspected directly. Treat IDs as opaque strings.
16
+
17
+ ## Create, resume, and send
18
+
19
+ - `create --project <directory>` sets project association and the default launch directory. Add `--cwd <directory>` to change the launch location while retaining the project association.
20
+ - Add `--task <name>` when creating a session to assign an optional task name. Use `list --task <name>` to find matching sessions across projects.
21
+ - Creation accepts `--agent <nickname>`, defaulting to the first configured Agent. Use `--worktree` and `--yolo` as authorized launch options, not universal defaults.
22
+ - `resume <id>` retains the original Agent and uses an available original working or project directory. It accepts `--yolo` but no directory overrides.
23
+ - Successful create/resume means the session was observed live, connected, and idle. Save `sessionId` and `tmux` (`socketPath`, `sessionName`); diagnostics may be null.
24
+ - Before sending, inspect and follow `nextAfter` until `hasMore=false`. Save the final `nextAfter` as the turn's baseline, then observe new replies from that position.
25
+ - Specify the objective, output location, constraints, and acceptance criteria. Prefer `--stdin` from a file or pipe for long messages to avoid shell interpolation and quoting errors. `sent` confirms delivery only.
26
+
27
+ Replace the example IDs, positions, and paths with actual values:
28
+
29
+ ```bash
30
+ ahub-cli session create --project /absolute/project --json
31
+ # Save sessionId; add --cwd /absolute/working-directory if needed.
32
+
33
+ ahub-cli session inspect SESSION_ID --json
34
+ # If hasMore, continue with --after <nextAfter>; save the final nextAfter as BASELINE.
35
+
36
+ ahub-cli session send SESSION_ID --stdin --json < /absolute/task.txt
37
+ ahub-cli session inspect SESSION_ID --after BASELINE --follow --count 10 --json
38
+ # Retain the latest nextAfter. Continue observing, respond, or verify deliverables.
39
+
40
+ # After verifying deliverables, if the user requested session exit:
41
+ ahub-cli session exit SESSION_ID --json
42
+ ```
43
+
44
+ ## Observe replies and input requests
45
+
46
+ - Prefer `--json`. Single inspection returns one object; follow emits NDJSON. Parse each line independently as a result or `error` object. Text follow emits separate blocks.
47
+ - Without `--after`, inspect returns the latest 10 visible records; `--after 0` starts from the beginning. Continue with the returned `nextAfter`.
48
+ - Follow drains available messages immediately, then long-polls for messages or state changes. Changes only to `session.updatedAt` do not wake a wait or produce output. `--count N` limits polling rounds, including rounds with no changes.
49
+ - Use continuous follow when the execution tool supports background processes and incremental output; otherwise use finite rounds and continue from the last received `nextAfter`. Allow opportunities to report progress to the user.
50
+ - Follow prints the first result, then only new messages or state changes. Unchanged rounds are silent; use inspect when you need to confirm the current state.
51
+ - Read `role`, `phase`, `itemType`, and message body. `phase=update` usually indicates progress; `phase=response` signals a reply. Neither idle nor response ends follow; verify completion separately.
52
+ - Input requests include question headers, questions, option labels/descriptions, and an `inputHint`; assistant response Plans retain their full message and add the same hint. Answered responses list selected content in order; cancelled/unavailable responses retain their outcome.
53
+
54
+ ## Choose actions by session state
55
+
56
+ Before each `send` or ordinary `keys` input, inspect and confirm `interaction.state=connected`. By default, `activity=idle` is also required; working sessions reject input rather than queue it, even after an input reminder. When input during working is intentional, add `--force` to `send` (with `--message` or `--stdin`) or `keys`; it skips the idle check, retaining connection, binding ownership, and management occupancy checks.
57
+
58
+ The CLI also rejects `send` messages whose first character is `/` (without trimming whitespace or checking subsequent lines); `--force` skips this guard too. This guard does not apply to the API.
59
+
60
+ | State | Next action |
61
+ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
62
+ | Connected and idle | Send a task or answer a question or Plan as described below. Idle does not guarantee an input menu. |
63
+ | Connected and working | Continue inspect/follow; use `terminal <id>` when useful. To adjust or stop execution, use `interrupt <id>`, then wait for connected and idle before further input. |
64
+ | Disconnected or unknown | Diagnose and observe again before input. Neither state establishes task success or failure. |
65
+
66
+ Interrupt does not require idle. Ctrl+C stops follow without interrupting session execution.
67
+
68
+ If inspect/follow reports idle while awaiting a task result and there is no unhandled reply, question, or Plan, run `terminal <id>` to inspect the prompt and diagnose the stall.
69
+
70
+ ## Answer questions and Plans
71
+
72
+ For a question or Plan reminder:
73
+
74
+ 1. Confirm connected and idle, then run `terminal <id>` to check the current prompt.
75
+ 2. Use `keys <id> <key...>`, preferring the number keys shown in its menu, for example `ahub-cli session keys SESSION_ID 1 --json`. If confirmation is required, reconfirm connected and idle before sending Enter separately.
76
+ 3. Inspect from the saved `nextAfter` to observe selected answers and subsequent progress.
77
+
78
+ For questions (not Plans), an alternative is to interrupt, organize the chosen answers by question, wait for connected and idle, then submit them together with `send`. This is useful for answering multiple questions at once.
79
+
80
+ ## Verify and finish
81
+
82
+ - Read and retain each new assistant `phase=response` reply. Continue observing until connected and idle, collecting any subsequent messages; if already connected and idle, proceed immediately.
83
+ - Use the collected replies and verification of deliverables against the task's acceptance criteria to decide whether to finish or address questions, blockers, or remaining work. Neither idle nor a reply alone proves completion. Resolve output locations against the actual `workingDirectory`, which may differ from `projectDirectory` with explicit cwd or worktrees.
84
+ - Perform lifecycle actions as requested, not automatically on a final reply. `exit <id>` ends session execution; delete permanently removes session history. Verify an uncertain exit before claiming success.
85
+ - Report deliverables, verification scope, and whether the session exited.
86
+
87
+ ## Recover from errors
88
+
89
+ - Follow defaults to 30 seconds per request. Other defaults are 15 seconds for list, inspect, terminal, send, keys, and interrupt; 45 seconds for create, resume, exit, and delete. `--timeout` limits the invocation, except in follow where it limits each HTTP request and there is no overall deadline.
90
+ - Exit code 0 means command success, not task completion; 1 means a definite failure or query error; 2 means a submitted write has an uncertain result.
91
+ - After a timeout or exit code 2, check state before repeating a write. Stopping the client does not cancel backend operations; resubmitting create/send can duplicate sessions or messages.
92
+ - For create/resume errors, read `error.code`, `error.message`, `error.sessionId`, and `error.tmux`. Use inspect/terminal when an ID is known; otherwise use the project list and tmux diagnostics.
93
+ - For exceptional tmux diagnosis, use `tmux -S SOCKET capture-pane -p -t =SESSION_NAME:`; a human can connect with `tmux -S SOCKET attach-session -t =SESSION_NAME:`. Use the returned `tmux.socketPath` for `SOCKET` and `tmux.sessionName` for `SESSION_NAME`; shell-quote each argument. Do not bypass the CLI to send tasks directly to a pane.
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: ahub-publish
3
+ description: Publish static pages or review diffs to an existing Agent Hub. Use only when the user explicitly requests `ahub-publish` by name.
4
+ ---
5
+
6
+ # Publish to Agent Hub
7
+
8
+ Publish static pages and review diffs using an existing Hub. Do not manage or probe services, or configure network access.
9
+
10
+ ## Check the environment
11
+
12
+ - Check `command -v ahub-cli` and read/write access to `~/.agent-hub/hosting`. If storage does not exist yet, check write and search access to its nearest existing parent; publication creates storage. If a custom Hub data root is already configured, pass `--home-dir /absolute/path/to/hub-root` to every resource command; storage is its `hosting/` subdirectory.
13
+ - If the command or storage is unavailable, report the blocker and follow environment approval rules. Do not install tools, create alternative storage, or start services on your own.
14
+ - Commands write directly to local storage; success does not verify browser access. Do not check HTTP, ports, or processes. If hosting is disabled, ask the user to maintain the existing Hub configuration.
15
+
16
+ ## Publish pages
17
+
18
+ 1. Prepare a static directory containing only the deliverable, with a regular file named `index.html` as its entry point. Hub does not build projects, proxy development servers, or run backends. Pages that depend on local APIs cannot be hosted directly. Replace those dependencies with embedded or static data within the authorized task scope, or explain the blocker.
19
+ 2. Inspect the entire directory, including hidden files, nested symbolic links, and special files. Exclude secrets, environment configuration, repository metadata, and other content that should not be published. Publication copies the entire directory; nested symbolic links and special files are rejected. The source directory and hosting storage must not contain one another.
20
+ 3. Use relative asset paths. Hub does not rewrite root-relative paths or provide SPA routing fallback. External resources depend on the viewer's network and cross-origin policies. Review included scripts and code before publishing: hosted pages have the same-origin authority as Hub and must be treated as trusted code.
21
+ 4. Specify the actual project directory, a stable name, and a title, and read the JSON result:
22
+
23
+ ```bash
24
+ ahub-cli page publish /absolute/path/to/static-output --project /absolute/path/to/project --name review-report --title "Review report" --json
25
+ ```
26
+
27
+ For custom storage, append the confirmed `--home-dir` option. Both the source and project directories must exist. For deliverables generated in a worktree, pass the original project path as `--project`, rather than the worktree path. Project association uses the project's canonical real path.
28
+
29
+ 5. When updating the same deliverable, reuse the project and `--name`, even if the output directory changes. This preserves the page URL and creates a new snapshot. Omitting `--title` preserves the previous title. To check an existing resource's identity, use `ahub-cli page list --json` to read storage metadata without probing the service.
30
+
31
+ ## Publish review diffs
32
+
33
+ Choose the comparison scope from the user's review goal, such as unstaged changes, staged changes, or changes relative to a particular commit or branch. Do not impose one comparison baseline on every task. Check the diff for information that should not be published.
34
+
35
+ Write the selected comparison as a Git unified diff to a unique temporary file, then publish it. For example, use the following only when reviewing tracked-file changes relative to `HEAD`:
36
+
37
+ ```bash
38
+ review_diff=$(mktemp)
39
+ git diff --no-ext-diff --no-color HEAD -- > "$review_diff"
40
+ ahub-cli diff publish "$review_diff" --title "Change review" --json
41
+ ```
42
+
43
+ Before publishing, confirm that diff generation succeeded and that the content matches the intended scope. Ordinary `git diff` excludes untracked files. If they belong in the review, explicitly generate their patches and verify the result. Do not claim that an ordinary diff covers them or stage files without authorization for this purpose. For custom storage, also append `--home-dir`.
44
+
45
+ Each diff publication creates an independent resource; it does not use the project-and-name update semantics of pages. After success, you may delete the temporary source file created for this operation. Deleting it does not delete the published copy.
46
+
47
+ ## Deliver and clean up
48
+
49
+ - Read `url` from the successful command's JSON result and use it unchanged as the target of a relative Markdown link, such as `[View report](returned url)`. Escape the link title correctly. Do not guess IDs, hosts, ports, or addresses. Report failures without inventing links.
50
+ - Retain the returned resource `id` when needed for management.
51
+ - Describe the published scope and note that the copy survives source removal and does not expire automatically.
52
+ - Treat published diffs as temporary review artifacts. Once the user confirms the review is complete with no remaining questions, proactively delete the relevant diff without asking for separate cleanup approval. Keep it while review questions remain open or if the user requests retention.
53
+ - Retain published pages unless the user requests deletion or an agreed cleanup scope applies.
54
+ - To delete authorized published resources, use `ahub-cli page delete <id> --json` or `ahub-cli diff delete <id> --json`. Continue using the same `--home-dir` for custom storage. Deleting a page also deletes all its snapshots; verify the target and authorization scope first.