@songsid/agend 2.1.4-beta.5 → 2.1.4-beta.50

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 (175) hide show
  1. package/README.md +1 -1
  2. package/README.zh-TW.md +1 -1
  3. package/dist/agent-endpoint.js +1 -1
  4. package/dist/agent-endpoint.js.map +1 -1
  5. package/dist/backend/antigravity.d.ts +12 -8
  6. package/dist/backend/antigravity.js +189 -42
  7. package/dist/backend/antigravity.js.map +1 -1
  8. package/dist/backend/claude-code.d.ts +62 -23
  9. package/dist/backend/claude-code.js +296 -43
  10. package/dist/backend/claude-code.js.map +1 -1
  11. package/dist/backend/codex.d.ts +18 -0
  12. package/dist/backend/codex.js +148 -8
  13. package/dist/backend/codex.js.map +1 -1
  14. package/dist/backend/gemini-cli.js +2 -2
  15. package/dist/backend/gemini-cli.js.map +1 -1
  16. package/dist/backend/grok.js +2 -2
  17. package/dist/backend/grok.js.map +1 -1
  18. package/dist/backend/kiro.d.ts +52 -2
  19. package/dist/backend/kiro.js +267 -12
  20. package/dist/backend/kiro.js.map +1 -1
  21. package/dist/backend/opencode.d.ts +27 -11
  22. package/dist/backend/opencode.js +65 -41
  23. package/dist/backend/opencode.js.map +1 -1
  24. package/dist/backend/types.d.ts +97 -3
  25. package/dist/backend/types.js +12 -1
  26. package/dist/backend/types.js.map +1 -1
  27. package/dist/backend-outage.d.ts +61 -0
  28. package/dist/backend-outage.js +71 -0
  29. package/dist/backend-outage.js.map +1 -0
  30. package/dist/channel/adapters/discord.d.ts +44 -2
  31. package/dist/channel/adapters/discord.js +526 -78
  32. package/dist/channel/adapters/discord.js.map +1 -1
  33. package/dist/channel/adapters/telegram.d.ts +30 -0
  34. package/dist/channel/adapters/telegram.js +221 -19
  35. package/dist/channel/adapters/telegram.js.map +1 -1
  36. package/dist/channel/agy-mcp-launcher.d.ts +2 -0
  37. package/dist/channel/agy-mcp-launcher.js +28 -0
  38. package/dist/channel/agy-mcp-launcher.js.map +1 -0
  39. package/dist/channel/ipc-bridge.d.ts +2 -1
  40. package/dist/channel/ipc-bridge.js +33 -4
  41. package/dist/channel/ipc-bridge.js.map +1 -1
  42. package/dist/channel/mcp-server.js +28 -25
  43. package/dist/channel/mcp-server.js.map +1 -1
  44. package/dist/channel/mcp-tools.js +4 -2
  45. package/dist/channel/mcp-tools.js.map +1 -1
  46. package/dist/channel/message-queue.js +62 -1
  47. package/dist/channel/message-queue.js.map +1 -1
  48. package/dist/channel/types.d.ts +31 -1
  49. package/dist/classic-channel-manager.d.ts +61 -3
  50. package/dist/classic-channel-manager.js +256 -31
  51. package/dist/classic-channel-manager.js.map +1 -1
  52. package/dist/cli.js +109 -37
  53. package/dist/cli.js.map +1 -1
  54. package/dist/config-validator.js +48 -7
  55. package/dist/config-validator.js.map +1 -1
  56. package/dist/config.d.ts +4 -0
  57. package/dist/config.js +12 -1
  58. package/dist/config.js.map +1 -1
  59. package/dist/cross-instance-envelope.d.ts +6 -0
  60. package/dist/cross-instance-envelope.js +30 -0
  61. package/dist/cross-instance-envelope.js.map +1 -0
  62. package/dist/daemon.d.ts +429 -9
  63. package/dist/daemon.js +1843 -289
  64. package/dist/daemon.js.map +1 -1
  65. package/dist/doctor.d.ts +41 -0
  66. package/dist/doctor.js +267 -0
  67. package/dist/doctor.js.map +1 -0
  68. package/dist/fleet-context.d.ts +54 -0
  69. package/dist/fleet-manager.d.ts +398 -11
  70. package/dist/fleet-manager.js +2756 -499
  71. package/dist/fleet-manager.js.map +1 -1
  72. package/dist/fleet-yaml-slim.d.ts +10 -0
  73. package/dist/fleet-yaml-slim.js +59 -0
  74. package/dist/fleet-yaml-slim.js.map +1 -0
  75. package/dist/general-knowledge/skills/backend-providers/SKILL.md +114 -0
  76. package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +3 -1
  77. package/dist/general-knowledge/skills/delegation-playbook/SKILL.md +52 -0
  78. package/dist/general-knowledge/skills/development-workflow/SKILL.md +28 -0
  79. package/dist/general-knowledge/skills/fleet-config/SKILL.md +1 -0
  80. package/dist/general-knowledge/skills/fleet-health/SKILL.md +1 -0
  81. package/dist/general-knowledge/skills/fleet-restart/SKILL.md +1 -0
  82. package/dist/general-knowledge/skills/instance-lifecycle/SKILL.md +1 -0
  83. package/dist/general-knowledge/skills/model-discovery/SKILL.md +64 -16
  84. package/dist/general-knowledge/skills/multi-channel/SKILL.md +1 -0
  85. package/dist/general-knowledge/skills/scheduling/SKILL.md +1 -0
  86. package/dist/general-knowledge/skills/session-management/SKILL.md +172 -8
  87. package/dist/general-knowledge/skills/tui-effort/SKILL.md +1 -0
  88. package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +30 -0
  89. package/dist/instance-lifecycle.d.ts +99 -0
  90. package/dist/instance-lifecycle.js +339 -11
  91. package/dist/instance-lifecycle.js.map +1 -1
  92. package/dist/instructions.d.ts +12 -0
  93. package/dist/instructions.js +35 -1
  94. package/dist/instructions.js.map +1 -1
  95. package/dist/locale.js +1004 -288
  96. package/dist/locale.js.map +1 -1
  97. package/dist/login-flows.d.ts +91 -0
  98. package/dist/login-flows.js +170 -0
  99. package/dist/login-flows.js.map +1 -0
  100. package/dist/login-manager.d.ts +63 -0
  101. package/dist/login-manager.js +134 -0
  102. package/dist/login-manager.js.map +1 -0
  103. package/dist/network-family.d.ts +18 -0
  104. package/dist/network-family.js +20 -0
  105. package/dist/network-family.js.map +1 -0
  106. package/dist/outbound-handlers.d.ts +8 -0
  107. package/dist/outbound-handlers.js +101 -18
  108. package/dist/outbound-handlers.js.map +1 -1
  109. package/dist/outbound-schemas.d.ts +7 -1
  110. package/dist/outbound-schemas.js +9 -0
  111. package/dist/outbound-schemas.js.map +1 -1
  112. package/dist/pane-input-residue.d.ts +52 -0
  113. package/dist/pane-input-residue.js +107 -0
  114. package/dist/pane-input-residue.js.map +1 -0
  115. package/dist/reply-dedup.d.ts +7 -8
  116. package/dist/reply-dedup.js +0 -0
  117. package/dist/reply-dedup.js.map +1 -1
  118. package/dist/restart-progress.d.ts +2 -0
  119. package/dist/restart-progress.js +3 -0
  120. package/dist/restart-progress.js.map +1 -1
  121. package/dist/scheduler/db.d.ts +12 -0
  122. package/dist/scheduler/db.js +59 -0
  123. package/dist/scheduler/db.js.map +1 -1
  124. package/dist/service-installer.d.ts +11 -0
  125. package/dist/service-installer.js +84 -18
  126. package/dist/service-installer.js.map +1 -1
  127. package/dist/settings-api.js +1 -1
  128. package/dist/settings-api.js.map +1 -1
  129. package/dist/setup-wizard.js +2 -2
  130. package/dist/setup-wizard.js.map +1 -1
  131. package/dist/spawn-gate.d.ts +30 -0
  132. package/dist/spawn-gate.js +79 -0
  133. package/dist/spawn-gate.js.map +1 -0
  134. package/dist/storm-window.d.ts +83 -0
  135. package/dist/storm-window.js +251 -0
  136. package/dist/storm-window.js.map +1 -0
  137. package/dist/tips.d.ts +44 -0
  138. package/dist/tips.js +355 -0
  139. package/dist/tips.js.map +1 -0
  140. package/dist/tmux-manager.d.ts +16 -0
  141. package/dist/tmux-manager.js +110 -25
  142. package/dist/tmux-manager.js.map +1 -1
  143. package/dist/tool-progress.d.ts +40 -0
  144. package/dist/tool-progress.js +289 -0
  145. package/dist/tool-progress.js.map +1 -0
  146. package/dist/topic-commands.d.ts +42 -4
  147. package/dist/topic-commands.js +372 -67
  148. package/dist/topic-commands.js.map +1 -1
  149. package/dist/transcript-monitor.d.ts +15 -2
  150. package/dist/transcript-monitor.js +63 -17
  151. package/dist/transcript-monitor.js.map +1 -1
  152. package/dist/transcript-sources.d.ts +131 -0
  153. package/dist/transcript-sources.js +580 -0
  154. package/dist/transcript-sources.js.map +1 -0
  155. package/dist/types.d.ts +13 -0
  156. package/dist/ui/dashboard.html +55 -32
  157. package/dist/ui/settings.html +200 -60
  158. package/dist/ui/view.html +147 -30
  159. package/dist/usage/format-rich.d.ts +1 -1
  160. package/dist/usage/format-rich.js +28 -24
  161. package/dist/usage/format-rich.js.map +1 -1
  162. package/dist/usage/i18n-keys.d.ts +7 -0
  163. package/dist/usage/i18n-keys.js +34 -0
  164. package/dist/usage/i18n-keys.js.map +1 -0
  165. package/dist/usage/i18n.d.ts +5 -0
  166. package/dist/usage/i18n.js +27 -0
  167. package/dist/usage/i18n.js.map +1 -0
  168. package/dist/usage/providers.d.ts +21 -0
  169. package/dist/usage/providers.js +153 -75
  170. package/dist/usage/providers.js.map +1 -1
  171. package/dist/usage/usage-api.d.ts +11 -3
  172. package/dist/usage/usage-api.js +61 -24
  173. package/dist/usage/usage-api.js.map +1 -1
  174. package/dist/workflow-templates/default.md +2 -1
  175. package/package.json +2 -2
@@ -0,0 +1,10 @@
1
+ import type { RawFleetConfig } from "./types.js";
2
+ /**
3
+ * Instance identity/routing fields remain explicit even when they currently
4
+ * equal a fleet default. Removing one of these makes the YAML harder to audit
5
+ * and can change which external resource an instance represents.
6
+ */
7
+ export declare const PRESERVED_INSTANCE_FIELDS: Set<string>;
8
+ export type FleetConfigPath = Array<string | number>;
9
+ /** Return raw YAML leaf paths that are redundant with effective defaults. */
10
+ export declare function collectRedundantInstanceDefaultPaths(raw: RawFleetConfig): FleetConfigPath[];
@@ -0,0 +1,59 @@
1
+ import { isDeepStrictEqual } from "node:util";
2
+ import { getEffectiveInstanceDefaults } from "./config.js";
3
+ /**
4
+ * Instance identity/routing fields remain explicit even when they currently
5
+ * equal a fleet default. Removing one of these makes the YAML harder to audit
6
+ * and can change which external resource an instance represents.
7
+ */
8
+ export const PRESERVED_INSTANCE_FIELDS = new Set([
9
+ "working_directory",
10
+ "topic_id",
11
+ "channel_id",
12
+ "general_topic",
13
+ "description",
14
+ "tags",
15
+ "model",
16
+ "backend",
17
+ "backend_options",
18
+ "display_name",
19
+ "systemPrompt",
20
+ "worktree_source",
21
+ "profile",
22
+ ]);
23
+ function isRecord(value) {
24
+ return typeof value === "object" && value !== null && !Array.isArray(value);
25
+ }
26
+ function collectMatchingLeaves(value, inherited, path, output) {
27
+ if (isRecord(value) && isRecord(inherited)) {
28
+ for (const [key, child] of Object.entries(value)) {
29
+ if (Object.prototype.hasOwnProperty.call(inherited, key)) {
30
+ collectMatchingLeaves(child, inherited[key], [...path, key], output);
31
+ }
32
+ }
33
+ return;
34
+ }
35
+ // Arrays are leaf values here: a partial array cannot inherit safely.
36
+ if (isDeepStrictEqual(value, inherited))
37
+ output.push(path);
38
+ }
39
+ /** Return raw YAML leaf paths that are redundant with effective defaults. */
40
+ export function collectRedundantInstanceDefaultPaths(raw) {
41
+ const instances = raw.instances;
42
+ if (!instances || !isRecord(instances))
43
+ return [];
44
+ const effectiveDefaults = getEffectiveInstanceDefaults((raw.defaults ?? {}));
45
+ const redundant = [];
46
+ for (const [name, instance] of Object.entries(instances)) {
47
+ if (!isRecord(instance))
48
+ continue;
49
+ for (const [key, value] of Object.entries(instance)) {
50
+ if (PRESERVED_INSTANCE_FIELDS.has(key))
51
+ continue;
52
+ if (!Object.prototype.hasOwnProperty.call(effectiveDefaults, key))
53
+ continue;
54
+ collectMatchingLeaves(value, effectiveDefaults[key], ["instances", name, key], redundant);
55
+ }
56
+ }
57
+ return redundant;
58
+ }
59
+ //# sourceMappingURL=fleet-yaml-slim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fleet-yaml-slim.js","sourceRoot":"","sources":["../src/fleet-yaml-slim.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAG3D;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,GAAG,CAAC;IAC/C,mBAAmB;IACnB,UAAU;IACV,YAAY;IACZ,eAAe;IACf,aAAa;IACb,MAAM;IACN,OAAO;IACP,SAAS;IACT,iBAAiB;IACjB,cAAc;IACd,cAAc;IACd,iBAAiB;IACjB,SAAS;CACV,CAAC,CAAC;AAIH,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,qBAAqB,CAC5B,KAAc,EACd,SAAkB,EAClB,IAAqB,EACrB,MAAyB;IAEzB,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,CAAC;gBACzD,qBAAqB,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;QACD,OAAO;IACT,CAAC;IAED,sEAAsE;IACtE,IAAI,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7D,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,oCAAoC,CAClD,GAAmB;IAEnB,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;IAChC,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,EAAE,CAAC;IAElD,MAAM,iBAAiB,GAAG,4BAA4B,CACpD,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAA4B,CACrB,CAAC;IAC7B,MAAM,SAAS,GAAsB,EAAE,CAAC;IAExC,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACzD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,SAAS;QAClC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpD,IAAI,yBAAyB,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YACjD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,iBAAiB,EAAE,GAAG,CAAC;gBAAE,SAAS;YAC5E,qBAAqB,CACnB,KAAK,EACL,iBAAiB,CAAC,GAAG,CAAC,EACtB,CAAC,WAAW,EAAE,IAAI,EAAE,GAAG,CAAC,EACxB,SAAS,CACV,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: backend-providers
3
+ description: Configure custom model providers when creating or editing AgEnD Codex or OpenCode instances. Use for local, OpenAI-compatible, GLM, or other non-default provider endpoints and for backend_options provider selection.
4
+ roles: [general]
5
+ ---
6
+
7
+ # Backend Providers
8
+
9
+ AgEnD selects a provider; the backend CLI owns endpoint and credential definitions.
10
+
11
+ ## Choose the backend
12
+
13
+ | Backend | Provider configuration |
14
+ |---|---|
15
+ | Codex | Select with `backend_options.codex.provider`; define the provider in Codex `config.toml`. |
16
+ | OpenCode | Define the provider in `opencode.json`; use model ID `<provider>/<model>`. |
17
+ | Claude Code, Kiro CLI, Antigravity, Grok | Provider is fixed by the CLI; do not set `backend_options` for provider selection. |
18
+
19
+ ## Create a Codex custom-provider instance
20
+
21
+ 1. Define the provider in the fleet user's `~/.codex/config.toml`. The table name is the provider ID used by AgEnD:
22
+
23
+ ```toml
24
+ [model_providers.glm]
25
+ name = "GLM"
26
+ base_url = "https://provider.example.com/v1"
27
+ env_key = "GLM_API_KEY"
28
+ ```
29
+
30
+ Keep credentials out of `config.toml`. `env_key` names an environment variable; it is not the secret itself.
31
+
32
+ 2. Put the credential in the fleet process environment before startup. `~/.agend/.env` is the usual location:
33
+
34
+ ```dotenv
35
+ GLM_API_KEY=replace-with-the-real-secret
36
+ ```
37
+
38
+ Restart the fleet after changing its environment. Exporting a variable in an unrelated shell after the fleet has started does not update the running fleet process.
39
+
40
+ 3. Create the instance with the MCP tool:
41
+
42
+ ```json
43
+ {
44
+ "directory": "/home/user/projects/my-project",
45
+ "topic_name": "glm-worker",
46
+ "backend": "codex",
47
+ "model": "GLM-5.2",
48
+ "backend_options": {
49
+ "codex": {
50
+ "provider": "glm"
51
+ }
52
+ }
53
+ }
54
+ ```
55
+
56
+ The equivalent per-instance fleet.yaml override is:
57
+
58
+ ```yaml
59
+ instances:
60
+ glm-worker:
61
+ working_directory: /home/user/projects/my-project
62
+ backend: codex
63
+ model: GLM-5.2
64
+ backend_options:
65
+ codex:
66
+ provider: glm
67
+ ```
68
+
69
+ AgEnD copies the user's Codex settings into the instance-isolated `CODEX_HOME`, then launches Codex with `model_provider="glm"`. Provider IDs may contain only letters, digits, `_`, and `-`.
70
+
71
+ ## Configure OpenCode
72
+
73
+ Define the endpoint, SDK adapter, credentials, and models in OpenCode's `opencode.json` provider block:
74
+
75
+ ```json
76
+ {
77
+ "$schema": "https://opencode.ai/config.json",
78
+ "provider": {
79
+ "glm": {
80
+ "npm": "@ai-sdk/openai-compatible",
81
+ "name": "GLM",
82
+ "options": {
83
+ "baseURL": "https://provider.example.com/v1",
84
+ "apiKey": "{env:GLM_API_KEY}"
85
+ },
86
+ "models": {
87
+ "GLM-5.2": {
88
+ "name": "GLM-5.2"
89
+ }
90
+ }
91
+ }
92
+ }
93
+ }
94
+ ```
95
+
96
+ Then use the fully qualified model ID in AgEnD:
97
+
98
+ ```yaml
99
+ instances:
100
+ glm-opencode:
101
+ working_directory: /home/user/projects/my-project
102
+ backend: opencode
103
+ model: glm/GLM-5.2
104
+ ```
105
+
106
+ OpenCode provider IDs and model IDs come from its own config. Do not use `backend_options.codex.provider` for OpenCode.
107
+
108
+ ## Verify and troubleshoot
109
+
110
+ - Run `validate_config` before reload or restart.
111
+ - Use `describe_instance` to verify the effective backend and model after creation.
112
+ - If Codex says the provider is unknown, verify the `[model_providers.<id>]` table is in `~/.codex/config.toml` before the instance starts.
113
+ - If authentication fails, verify the variable named by `env_key` exists in the fleet process environment; never paste the secret into fleet.yaml or `backend_options`.
114
+ - A model-metadata fallback warning can be normal for a custom model with no built-in metadata. Provider connection, authentication, or unsupported-model errors are not normal and should still be investigated.
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: cross-instance-messaging
3
3
  description: Fire-and-queue cross-instance tools — send once, never resend on queued
4
+ roles: [general, worker]
4
5
  ---
5
6
 
6
7
  ## How to send
@@ -18,5 +19,6 @@ Use fleet tools only (`send_to_instance`, `delegate_task`, `request_information`
18
19
 
19
20
  ## Task flow
20
21
 
21
- - `delegate_task` → silent work → `report_result` (zero ack-only pings)
22
+ - Coordinator flow: `delegate_task` → silent work → `report_result` (zero ack-only pings).
23
+ - Worker flow: finish with `report_result`, or use `request_information` when blocked. A normal worker must not call `delegate_task` or re-delegate work.
22
24
  - Cross-instance traffic is `[from:name]` → answer with `send_to_instance` / `report_result`, never `reply`
@@ -0,0 +1,52 @@
1
+ ---
2
+ name: delegation-playbook
3
+ description: Delegation protocol, loop prevention, parallel vs sequential execution, result/failure handling, team management, and instance configuration tips for the fleet coordinator
4
+ roles: [general]
5
+ ---
6
+
7
+ ## Delegation Protocol
8
+
9
+ Every delegation via send_to_instance() MUST include:
10
+
11
+ 1. Task scope — what exactly to do, bounded clearly
12
+ 2. Expected output — what to return and in what form
13
+ 3. Policy reminder — "Follow Development Workflow policy" (for code tasks)
14
+
15
+ ### Loop Prevention
16
+
17
+ - Never re-delegate a task back to the instance that sent it to you
18
+ - If a task has bounced 3 times, stop and solve locally or reduce scope
19
+
20
+ ### Execution Strategy
21
+
22
+ - Parallel — use only when tasks are independent with no shared state
23
+ - Sequential — use when one task's output feeds into the next
24
+
25
+ ## Result Handling
26
+
27
+ When an instance reports back, classify the outcome:
28
+
29
+ - Success → Summarize key results for user. Omit internal coordination noise.
30
+ - Partial → State what succeeded, what remains, proposed next steps.
31
+ - Failure → Retry up to 2 times. If still failing: try alternative instance, reduce scope, or return partial result clearly marked.
32
+ - No response → Ping again after reasonable wait. If still silent: report to user with options.
33
+
34
+ ## Shared Decisions
35
+
36
+ Use post_decision() / list_decisions() for any choice that affects more than 1 instance, changes an API contract, introduces a new dependency, or alters deployment process.
37
+
38
+ When instances disagree, collect both viewpoints, make a decision, and record it via post_decision.
39
+
40
+ ## Team Management
41
+
42
+ - Always check existing teams before creating new ones
43
+ - Default to ephemeral teams (created for a specific task, dissolved after completion)
44
+ - Clean up ephemeral teams and instances after task completion
45
+
46
+ ## Instance Configuration Tips
47
+
48
+ When users create specialized instances, suggest these configurations:
49
+
50
+ - **Reviewer instances**: Add `pre_task_command: "/chat load reviewer-base"` to reset context before each review, preventing influence from previous conversations.
51
+ - **Collab mode**: For multi-bot channels, use `/collab` to enable @mention-based triggering.
52
+ - **Cost control**: Set per-instance `cost_guard` for expensive backends.
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: development-workflow
3
+ description: The fleet-wide code-change policy the coordinator enforces when delegating code tasks — stages, review pairing, merge conditions
4
+ roles: [general]
5
+ ---
6
+
7
+ All code changes across the fleet should follow this workflow.
8
+ The coordinator enforces compliance but does not perform these steps directly.
9
+ Remind instances of this policy when delegating code tasks.
10
+
11
+ ## Workflow Stages
12
+
13
+ Design Proposed → Design Approved → Implementation → Submit for Review → Under Review → Approved → Merge
14
+
15
+ ## Policy Rules
16
+
17
+ 1. Design before code — developer sends design proposal to reviewer before implementation. Consensus required before proceeding.
18
+ 2. Challenger pairing — every code task should have a developer + reviewer. Reviewer actively questions decisions and finds risks.
19
+ 3. Verify by execution — backend/CLI changes must be tested by running them. Do not trust documentation alone.
20
+ 4. Independent review — every merge requires code review from someone other than the author.
21
+ 5. Root cause first — bug fixes require confirmed root cause before proposing a fix.
22
+ 6. Merge conditions: tests pass, reviewer approved, branch and worktree cleaned up.
23
+
24
+ ## Specialist Instance Rules
25
+
26
+ - Execute within defined scope only
27
+ - Return structured output: result, assumptions, uncertainties, verification status
28
+ - Do NOT create new instances without coordinator approval
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: fleet-config
3
3
  description: fleet.yaml and classicBot.yaml structure, validation, common mistakes
4
+ roles: [general]
4
5
  ---
5
6
 
6
7
  ## Configuration Quick Reference
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: fleet-health
3
3
  description: Check instance health and what an agent is doing; recover a stuck instance
4
+ roles: [general]
4
5
  ---
5
6
 
6
7
  ## Check health
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: fleet-restart
3
3
  description: Fleet restart types, recovery from tmux crash, rate limit handling, safe update
4
+ roles: [general]
4
5
  ---
5
6
 
6
7
  ## Fleet Restart & Recovery
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: instance-lifecycle
3
3
  description: restart vs replace vs pause/wake; when to use each
4
+ roles: [general]
4
5
  ---
5
6
 
6
7
  ## Restart vs Replace
@@ -1,27 +1,75 @@
1
1
  ---
2
2
  name: model-discovery
3
- description: Set and discover models — pass-through to the CLI, no AgEnD allowlist gate
3
+ description: Choose and discover models — when to omit, per-backend defaults, pass-through
4
+ roles: [general, worker]
4
5
  ---
5
6
 
6
- ## How to set a model
7
+ ## Omit the model unless you have a reason
7
8
 
8
- - fleet.yaml: `defaults.model` or per-instance `model`
9
- - **Pass-through:** AgEnD no longer blocks unknown model ids — it may **warn**, then still pass the string to the CLI
10
- - **CLI is source of truth** — if the model is invalid, the backend CLI errors (fix the name there)
9
+ Precedence: **explicit arg > `fleet.defaults.model` > CLI/account default**
10
+
11
+ Omitting is the default answer. It inherits the fleet default, or the CLI's own —
12
+ which is the account's current best model and stays right as the vendor ships new
13
+ ones. A model you pin today is a model someone has to un-pin later.
14
+
15
+ Pass a model only when: the user named one, the instance needs a *specific*
16
+ capability (cheap/fast vs deep reasoning), or the backend needs one to behave
17
+ (see kiro below).
18
+
19
+ ## Per-backend default behaviour
20
+
21
+ | Backend | Omit `model` means | Notes |
22
+ |---|---|---|
23
+ | kiro-cli | account default | **`model: auto`** lets kiro pick per turn — usually what you want |
24
+ | claude-code | account default | ids are aliases: `sonnet`, `opus`, `haiku`, `opusplan`, `default` |
25
+ | codex | account default | |
26
+ | grok | account default | |
27
+ | antigravity | account default | |
28
+ | opencode | provider default | ids are **`provider/model`**, e.g. `opencode/big-pickle` |
11
29
 
12
30
  ## Discover real names
13
31
 
14
- | Backend | How |
15
- |---------|-----|
16
- | kiro-cli | In pane: `/model` (gpt-*, deepseek-*, minimax-*, glm-*, qwen* supported) |
17
- | claude-code | `sonnet` / `opus` / `haiku` / `opusplan` / `Fable` / aliases |
18
- | codex | pane `/model` or docs (`gpt-*`, `o*`) |
32
+ **Use the `list_models` tool** — it reads the fleet's probe cache (refreshed every
33
+ 24h) and falls back to a live probe:
34
+
35
+ - `list_models({ backend: "kiro-cli" })` → the account catalog
36
+ - `list_models({ instance_name: "x" })` → read through **that instance's** config
37
+
38
+ Check `scope` in the reply. An instance on a custom provider can offer a
39
+ different catalog than the account (a Codex instance with `provider: glm` reads
40
+ its own catalog), so `scope: "instance"` is authoritative for that instance and
41
+ `scope: "global"` is only the account-wide list. `source` tells you `cache` /
42
+ `live` / `fallback`.
43
+
44
+ An empty list is **not** a failure — see pass-through below.
45
+
46
+ Underlying commands, if you need them by hand:
47
+
48
+ | Backend | Command |
49
+ |---|---|
50
+ | kiro-cli | `kiro-cli --list-models` |
19
51
  | grok | `grok models` |
20
- | antigravity | `agy models` — set **base name only** (drop `(Medium)` / `(Thinking)` effort suffix) |
21
52
  | opencode | `opencode models` |
53
+ | antigravity | `agy models` |
54
+ | codex | **no command** — the CLI writes `models_cache.json` in its CODEX_HOME |
55
+ | claude-code | fixed alias set (no command) |
56
+
57
+ ## Setting one on create_instance
58
+
59
+ - No specific need → **omit `model`**
60
+ - Kiro, want per-turn selection → `model: "auto"`
61
+ - Custom provider → pass the **full id** and set `backend_options`, e.g.
62
+ `backend: "codex"`, `backend_options: { codex: { provider: "glm" } }`
63
+ - opencode → always `provider/model`, never a bare model name
64
+
65
+ ## Two traps
66
+
67
+ **antigravity: keep the effort suffix.** The suffix is part of the selectable id,
68
+ not decoration — `gemini-3.6-flash-medium` and `gemini-3.6-flash-low` are
69
+ different models. Take the id from `list_models`, not the display label the TUI
70
+ shows (`Gemini 3.5 Flash (Medium)`).
22
71
 
23
- ```yaml
24
- defaults:
25
- backend: kiro-cli
26
- model: claude-sonnet-4-20250514
27
- ```
72
+ **Pass-through: AgEnD does not gate model names.** An unknown id is warned about,
73
+ then handed to the CLI anyway. So a name missing from `list_models` may still be
74
+ valid, and a typo fails *in the CLI at launch*, not at config time — if an
75
+ instance won't start after a model change, suspect the name first.
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: multi-channel
3
3
  description: Setting up multiple platforms (Telegram + Discord) with proper general routing
4
+ roles: [general]
4
5
  ---
5
6
 
6
7
  ## Multi-Channel Setup
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: scheduling
3
3
  description: Cron, one-shot, and silent schedules via the schedule MCP tools
4
+ roles: [general, worker]
4
5
  ---
5
6
 
6
7
  ## Tools
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: session-management
3
- description: Session stores, forking, and auth-pause recovery
3
+ description: Session stores, forking, cross-backend session recovery, and auth-pause recovery
4
+ roles: [general]
4
5
  ---
5
6
 
6
7
  ## Auth failure (auto-pause)
@@ -11,17 +12,180 @@ When AgEnD sees `auth_error` it **pauses** that instance (`pausePending` sticky)
11
12
  - Messages while paused stay in the **queue** — do not re-send.
12
13
  - After the user re-auths: `wake` / normal wake clears `pausePending`.
13
14
 
14
- ## Where sessions live
15
+ ## Session recovery: what each backend can do
15
16
 
16
- | | kiro-cli | claude-code |
17
- |---|---|---|
18
- | Store | `~/.kiro/sessions/cli/<uuid>.json` | `~/.claude/projects/<path-encoded>/*.jsonl` |
19
- | Reload | `/chat load <file>` | `--continue` / `--resume <id>` |
17
+ Verified by running each one, not read from docs.
20
18
 
21
- `<path-encoded>` = absolute cwd with `/` → `-`.
19
+ | Backend | List all sessions | Restore a *specific* session | Read summary only |
20
+ |---|---|---|---|
21
+ | **kiro-cli** | ✅ `conversations_v2` | ✅ export → `/chat load` | ✅ `latest_summary` |
22
+ | **grok** | ✅ `session_search.sqlite` (FTS5) | ✅ `grok --resume <id>` | ✅ `summary.json` |
23
+ | **claude-code** | ✅ list `*.jsonl` in project dir | ✅ `claude -r <id>` | ✅ `ai-title` line |
24
+ | **codex** | ⚠️ no index — parse rollout files | ✅ `codex exec resume <id>` | ❌ must parse the rollout |
25
+ | **antigravity** | ❌ index covers ~23%, 2 months stale | ✅ `agy --conversation <id>` | ⚠️ `title` empty, use `preview` |
26
+
27
+ **Restoring a specific session is a manual operator action, not an AgEnD feature.** AgEnD always launches a backend on its *most recent* session (`--continue` / `--last` / `--resume`). To reach any other session someone must drive the pane or the CLI by hand.
28
+
29
+ **kiro is the exception worth knowing:** its export → `/chat load` works on a **live, idle instance** with no restart. Every other backend needs the instance stopped (or the CLI run manually) because the session is chosen by a launch flag.
30
+
31
+ ## Safety — applies to every backend below
32
+
33
+ 1. **Reads are read-only.** Open SQLite with `readonly` and never write to these databases; they belong to a running CLI, and the `-wal`/`-shm` files are live.
34
+ 2. **Restore through the CLI's own mechanism** — a resume flag, or kiro's `/chat load`. Never edit a session DB or JSONL to "fix" a conversation.
35
+ 3. **Confirm the target instance is idle first** (tmux shows the ready prompt). Restoring into a working pane interrupts a turn.
36
+ 4. Nothing here needs `sudo` or touches another user's files.
37
+
38
+ ---
39
+
40
+ ## kiro-cli
41
+
42
+ - **Store:** `~/.kiro/sessions/cli/<uuid>.json`
43
+ - **DB:** `~/.local/share/kiro-cli/data.sqlite3`, table `conversations_v2`
44
+ - `key` — the instance's working directory
45
+ - `conversation_id` — session ID
46
+ - `value` — full session state JSON (**same format as `/chat save`**)
47
+ - `created_at` / `updated_at` — epoch ms
48
+
49
+ **List sessions for an instance**
50
+ ```python
51
+ import sqlite3, os
52
+ db = os.path.expanduser('~/.local/share/kiro-cli/data.sqlite3')
53
+ cur = sqlite3.connect(f'file:{db}?mode=ro', uri=True).cursor()
54
+ cur.execute(
55
+ "SELECT conversation_id, updated_at FROM conversations_v2 WHERE key LIKE ? ORDER BY updated_at DESC LIMIT 5",
56
+ ('%<instance-name>%',)
57
+ )
58
+ # Most recent = currently active. De-duplicate by conversation_id.
59
+ ```
60
+
61
+ **Restore (works on a live idle instance — no restart)**
62
+ ```python
63
+ cur.execute("SELECT value FROM conversations_v2 WHERE conversation_id = ?", (target_cid,))
64
+ open('<instance-workspace>/restore.json', 'w').write(cur.fetchone()[0])
65
+ ```
66
+ ```bash
67
+ tmux send-keys -t agend:<instance> '/chat load restore.json' Enter
68
+ # Success: "✔ Imported chat session state", context % jumps up
69
+ ```
70
+
71
+ **Summary without restoring:** the session JSON has `latest_summary` (list; `[1]` is the text) and `history`.
72
+
73
+ ---
74
+
75
+ ## grok
76
+
77
+ The most capable backend here. It also ships its own manual at `~/.grok/docs/user-guide/17-sessions.md`.
78
+
79
+ - **Store:** `~/.grok/sessions/<URL-encoded cwd>/<session-id>/`
80
+ - `summary.json` — index entry: summary, timestamps, model, message counts
81
+ - `updates.jsonl` — the authoritative conversation log that drives resume
82
+ - also `chat_history.jsonl`, `plan.json`, `rewind_points.jsonl`, `signals.json`
83
+ - **Index:** `~/.grok/sessions/session_search.sqlite` → `session_docs(session_id, cwd, updated_at, title, content)` plus a `session_docs_fts` FTS5 table, so you can full-text search past conversations.
84
+
85
+ **List / search**
86
+ ```python
87
+ import sqlite3, os
88
+ db = os.path.expanduser('~/.grok/sessions/session_search.sqlite')
89
+ cur = sqlite3.connect(f'file:{db}?mode=ro', uri=True).cursor()
90
+ cur.execute("SELECT session_id, title, updated_at FROM session_docs ORDER BY updated_at DESC LIMIT 10")
91
+ # Full-text over conversation content:
92
+ cur.execute("SELECT session_id FROM session_docs_fts WHERE session_docs_fts MATCH ?", ('deploy',))
93
+ ```
94
+
95
+ **Restore:** `grok --resume <session-id-or-title>` (a UUID is always treated as an ID; anything else matches a title in the current directory). Bare `grok --resume` takes the most recent for that cwd. In the TUI, `/resume` opens a picker that searches conversation content as you type.
96
+
97
+ **Summary without restoring:** read `summary.json` directly.
98
+
99
+ > ⚠️ **Titles can be ours, not the user's.** Grok auto-titles from the first prompt, and AgEnD sometimes injects a session snapshot as that first prompt — so a title may read `[system:session-snapshot] ## Previous session…`. Filter that prefix before showing titles to a user, and fall back to `updated_at` + message count.
100
+
101
+ ---
102
+
103
+ ## claude-code
104
+
105
+ - **Store:** `~/.claude/projects/<path-encoded>/<session-uuid>.jsonl` — **the filename is the session ID**.
106
+ - `<path-encoded>` = the absolute cwd with every `/` replaced by `-`.
107
+
108
+ **List sessions for an instance**
109
+ ```bash
110
+ enc=$(echo "<instance-working-dir>" | sed 's|/|-|g')
111
+ ls -t ~/.claude/projects/"$enc"/*.jsonl # newest first; basename = session id
112
+ ```
113
+
114
+ **Summary without restoring** — the transcript contains auto-title lines; take the last one:
115
+ ```bash
116
+ grep -h '"type":"ai-title"' <file>.jsonl | tail -1
117
+ # {"type":"ai-title","aiTitle":"Review updated instructions","sessionId":"..."}
118
+ ```
119
+ A session with no `ai-title` line is simply untitled — say so rather than inventing a label.
120
+
121
+ **Restore:** `claude -r <session-id>` (or `claude --resume` for a picker that accepts a search term). `-c` / `--continue` takes the most recent for the cwd — that is what AgEnD launches with.
122
+
123
+ > ⚠️ **Check the ID exists before using it.** AgEnD guards `--continue` precisely because resuming a session that isn't there sends claude into a restart loop. Confirm the `<id>.jsonl` file is present in the encoded project dir first.
124
+
125
+ ---
126
+
127
+ ## codex
128
+
129
+ Restoring works well; **listing is the weak part — there is no index table.**
130
+
131
+ - **Store:** `~/.codex/sessions/YYYY/MM/DD/rollout-<timestamp>-<uuid>.jsonl`
132
+ - Line 0 of every rollout is the header:
133
+ `{"type":"session_meta","payload":{"session_id":…,"cwd":…,"timestamp":…}}`
134
+
135
+ **List sessions for a working directory** — walk the tree and read only the first line of each file:
136
+ ```python
137
+ import json, os, pathlib
138
+ root = pathlib.Path(os.path.expanduser('~/.codex/sessions'))
139
+ want = '<instance-working-dir>'
140
+ out = []
141
+ for p in root.rglob('*.jsonl'):
142
+ try:
143
+ head = json.loads(p.open(encoding='utf-8').readline())
144
+ except Exception:
145
+ continue
146
+ if head.get('type') == 'session_meta' and head['payload'].get('cwd') == want:
147
+ out.append((head['payload']['timestamp'], head['payload']['session_id']))
148
+ for ts, sid in sorted(out, reverse=True):
149
+ print(ts, sid)
150
+ ```
151
+ It opens many files, but only one line each, so it stays cheap.
152
+
153
+ **Restore:** `codex exec resume <session-id> "<prompt>"` non-interactively, or `codex resume <session-id>` for the TUI (bare `codex resume` opens a picker). `codex resume --last` is what AgEnD launches with. The ID argument also accepts a session *name*.
154
+
155
+ **Summary:** ❌ none available without parsing. `session_meta` carries only id/cwd/timestamp; to describe a session you must read further `event_msg` lines. Tell the user the timestamp and let them pick, rather than guessing at a topic.
156
+
157
+ ---
158
+
159
+ ## antigravity (agy)
160
+
161
+ Restore is reliable; **the session list is not — do not present it as complete.**
162
+
163
+ - **Store:** `~/.gemini/antigravity-cli/conversations/<uuid>.db` — one SQLite database per conversation.
164
+ - **Index:** `~/.gemini/antigravity-cli/conversation_summaries.db`, table `conversation_summaries`
165
+ (`conversation_id`, `title`, `preview`, `step_count`, `last_modified_time`, `workspace_uris`, …)
166
+
167
+ **List (with the caveat below)**
168
+ ```python
169
+ import sqlite3, os
170
+ db = os.path.expanduser('~/.gemini/antigravity-cli/conversation_summaries.db')
171
+ cur = sqlite3.connect(f'file:{db}?mode=ro', uri=True).cursor()
172
+ cur.execute("SELECT conversation_id, preview, step_count, last_modified_time "
173
+ "FROM conversation_summaries ORDER BY last_modified_time DESC")
174
+ ```
175
+
176
+ **Restore:** `agy --conversation <conversation-id>`. Verified: it loads the full prior conversation, not just a stub. `-c` / `--continue` takes the most recent — that is what AgEnD launches with.
177
+
178
+ > ⚠️ **The index is badly incomplete.** Measured on a live machine: 31 conversation databases on disk but only 14 index rows, of which just **7** matched a real conversation — about 23% coverage — and the newest row was **two months old**. Whatever you list, say plainly that it is a partial view and that older or recent conversations may be missing entirely. If the user knows a conversation ID, `--conversation` still works even when the index does not show it.
179
+ >
180
+ > ⚠️ **`title` is empty in practice** — use `preview` (the first user message) as the label, plus `step_count` for size.
181
+ >
182
+ > ⚠️ **`agy -p` (print mode) records nothing.** A non-interactive run leaves no conversation behind, so don't expect one to show up afterwards.
183
+
184
+ ---
22
185
 
23
186
  ## Fork (source must be idle)
24
187
 
25
188
  - **kiro:** `/chat save name.json -f` → `create_instance` → copy workspace file → `/chat load name.json`
26
- - **claude-code:** copy newest `*.jsonl` into target's encoded project dir → start (uses `--continue`)
189
+ - **claude-code:** copy the newest `*.jsonl` into the target's encoded project dir → start (uses `--continue`)
190
+ - **grok:** `/fork` inside the TUI branches the conversation into a peer session
27
191
  - Prefer `replace_instance` when the whole session is poisoned (see instance-lifecycle)
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: tui-effort
3
3
  description: 在 Kiro CLI TUI instance 中,透過 tmux 查看或設定模型的 reasoning effort
4
+ roles: [general]
4
5
  ---
5
6
 
6
7
  # Kiro TUI Effort