ac-framework 1.9.5 → 1.9.7

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 (82) hide show
  1. package/LICENSE +1 -0
  2. package/README.md +16 -1
  3. package/framework/mobile_development/.agent/workflows/ac.md +57 -4
  4. package/framework/mobile_development/.amazonq/prompts/ac.md +57 -4
  5. package/framework/mobile_development/.antigravity/workflows/ac.md +57 -4
  6. package/framework/mobile_development/.augment/commands/ac.md +57 -4
  7. package/framework/mobile_development/.claude/commands/opsx/ac.md +57 -4
  8. package/framework/mobile_development/.cline/commands/opsx/ac.md +57 -4
  9. package/framework/mobile_development/.clinerules/workflows/ac.md +57 -4
  10. package/framework/mobile_development/.codebuddy/commands/opsx/ac.md +57 -4
  11. package/framework/mobile_development/.continue/prompts/ac.md +57 -4
  12. package/framework/mobile_development/.cospec/openspec/commands/ac.md +57 -4
  13. package/framework/mobile_development/.crush/commands/opsx/ac.md +57 -4
  14. package/framework/mobile_development/.cursor/commands/ac.md +57 -4
  15. package/framework/mobile_development/.factory/commands/ac.md +57 -4
  16. package/framework/mobile_development/.gemini/commands/opsx/ac.md +57 -4
  17. package/framework/mobile_development/.github/prompts/ac.md +57 -4
  18. package/framework/mobile_development/.iflow/commands/ac.md +57 -4
  19. package/framework/mobile_development/.kilocode/workflows/ac.md +57 -4
  20. package/framework/mobile_development/.kimi/workflows/ac.md +57 -4
  21. package/framework/mobile_development/.opencode/command/ac.md +57 -4
  22. package/framework/mobile_development/.qoder/commands/opsx/ac.md +57 -4
  23. package/framework/mobile_development/.qwen/commands/ac.md +57 -4
  24. package/framework/mobile_development/.roo/commands/ac.md +57 -4
  25. package/framework/mobile_development/.windsurf/workflows/ac.md +57 -4
  26. package/framework/new_project/.agent/workflows/ac.md +39 -0
  27. package/framework/new_project/.amazonq/prompts/ac.md +39 -0
  28. package/framework/new_project/.antigravity/workflows/ac.md +39 -0
  29. package/framework/new_project/.augment/commands/ac.md +39 -0
  30. package/framework/new_project/.claude/commands/opsx/ac.md +39 -0
  31. package/framework/new_project/.cline/commands/opsx/ac.md +39 -0
  32. package/framework/new_project/.clinerules/workflows/ac.md +39 -0
  33. package/framework/new_project/.codebuddy/commands/opsx/ac.md +39 -0
  34. package/framework/new_project/.continue/prompts/ac.md +39 -0
  35. package/framework/new_project/.cospec/openspec/commands/ac.md +39 -0
  36. package/framework/new_project/.crush/commands/opsx/ac.md +39 -0
  37. package/framework/new_project/.cursor/commands/ac.md +39 -0
  38. package/framework/new_project/.factory/commands/ac.md +39 -0
  39. package/framework/new_project/.gemini/commands/opsx/ac.md +39 -0
  40. package/framework/new_project/.github/prompts/ac.md +39 -0
  41. package/framework/new_project/.iflow/commands/ac.md +39 -0
  42. package/framework/new_project/.kilocode/workflows/ac.md +39 -0
  43. package/framework/new_project/.kimi/workflows/ac.md +39 -0
  44. package/framework/new_project/.opencode/command/ac.md +16 -4
  45. package/framework/new_project/.qoder/commands/opsx/ac.md +39 -0
  46. package/framework/new_project/.qwen/commands/ac.md +39 -0
  47. package/framework/new_project/.roo/commands/ac.md +39 -0
  48. package/framework/new_project/.windsurf/workflows/ac.md +39 -0
  49. package/framework/web_development/.agent/workflows/ac.md +39 -0
  50. package/framework/web_development/.amazonq/prompts/ac.md +39 -0
  51. package/framework/web_development/.antigravity/workflows/ac.md +39 -0
  52. package/framework/web_development/.augment/commands/ac.md +39 -0
  53. package/framework/web_development/.claude/commands/opsx/ac.md +39 -0
  54. package/framework/web_development/.cline/commands/opsx/ac.md +39 -0
  55. package/framework/web_development/.clinerules/workflows/ac.md +39 -0
  56. package/framework/web_development/.codebuddy/commands/opsx/ac.md +39 -0
  57. package/framework/web_development/.continue/prompts/ac.md +39 -0
  58. package/framework/web_development/.cospec/openspec/commands/ac.md +39 -0
  59. package/framework/web_development/.crush/commands/opsx/ac.md +39 -0
  60. package/framework/web_development/.cursor/commands/ac.md +39 -0
  61. package/framework/web_development/.factory/commands/ac.md +39 -0
  62. package/framework/web_development/.gemini/commands/opsx/ac.md +39 -0
  63. package/framework/web_development/.github/prompts/ac.md +39 -0
  64. package/framework/web_development/.iflow/commands/ac.md +39 -0
  65. package/framework/web_development/.kilocode/workflows/ac.md +39 -0
  66. package/framework/web_development/.kimi/workflows/ac.md +39 -0
  67. package/framework/web_development/.opencode/command/ac.md +16 -4
  68. package/framework/web_development/.qoder/commands/opsx/ac.md +39 -0
  69. package/framework/web_development/.qwen/commands/ac.md +39 -0
  70. package/framework/web_development/.roo/commands/ac.md +39 -0
  71. package/framework/web_development/.windsurf/workflows/ac.md +39 -0
  72. package/package.json +1 -1
  73. package/src/agents/config-store.js +49 -0
  74. package/src/agents/constants.js +1 -0
  75. package/src/agents/model-selection.js +38 -0
  76. package/src/agents/opencode-client.js +68 -9
  77. package/src/agents/orchestrator.js +10 -3
  78. package/src/agents/runtime.js +82 -0
  79. package/src/agents/state-store.js +3 -1
  80. package/src/commands/agents.js +319 -83
  81. package/src/mcp/collab-server.js +105 -4
  82. package/src/services/dependency-installer.js +20 -1
@@ -98,6 +98,45 @@ acfm memory stats
98
98
 
99
99
  **User communication:** "Memory saved: [brief description]" when auto-saving occurs.
100
100
 
101
+ ### SynapseGrid Collaborative MCP Protocol (Optional)
102
+
103
+ If SynapseGrid is enabled in `acfm init`, AC Framework installs the collaborative MCP server automatically for detected assistants.
104
+
105
+ **Session-start requirement when collaboration is enabled:**
106
+ 1. Prefer the available SynapseGrid MCP tools for collaborative session control before falling back to direct CLI.
107
+ 2. Use shared session state and transcript as the source of truth for role-by-role collaboration.
108
+ 3. If collaborative MCP is unavailable, use CLI fallback commands and keep behavior equivalent.
109
+
110
+ **How to use SynapseGrid collaboration:**
111
+ ```text
112
+ Preferred: use SynapseGrid MCP tools (ac-framework-collab) for start/status/step/resume/stop.
113
+ Fallback: use AC Framework agents CLI commands directly.
114
+ ```
115
+ ```bash
116
+ # Install/update collaborative MCP server integrations
117
+ acfm agents install-mcps
118
+
119
+ # Start collaborative runtime with visible 4-pane tmux war-room
120
+ acfm agents start --task "design and implement feature X" --attach --model-coder provider/model
121
+
122
+ # If already running in background, attach to panes and inspect logs
123
+ acfm agents live
124
+ acfm agents logs --role all --lines 120
125
+
126
+ # Resume/list/export operations
127
+ acfm agents resume
128
+ acfm agents list
129
+ acfm agents export --format md --out synapse-session.md
130
+
131
+ # Fast diagnostics for OpenCode resolution errors
132
+ acfm agents setup
133
+ ```
134
+
135
+ **Troubleshooting notes:**
136
+ - If transcript shows `Agent failed: spawn opencode ENOENT`, run `acfm agents setup` and restart/resume session.
137
+ - If session exists but panes are not visible, use `acfm agents live` (or `acfm agents attach`) or `tmux attach -t <session-name>`.
138
+ - For MCP-first flows, ensure session start enables worker spawning so tmux panes are created.
139
+ - Per-role models can be set at start (`--model-planner`, `--model-critic`, `--model-coder`, `--model-reviewer`) or persisted via `acfm agents model set`.
101
140
 
102
141
  ### OpenSpec Skills (The heart of the framework)
103
142
 
@@ -98,6 +98,45 @@ acfm memory stats
98
98
 
99
99
  **User communication:** "Memory saved: [brief description]" when auto-saving occurs.
100
100
 
101
+ ### SynapseGrid Collaborative MCP Protocol (Optional)
102
+
103
+ If SynapseGrid is enabled in `acfm init`, AC Framework installs the collaborative MCP server automatically for detected assistants.
104
+
105
+ **Session-start requirement when collaboration is enabled:**
106
+ 1. Prefer the available SynapseGrid MCP tools for collaborative session control before falling back to direct CLI.
107
+ 2. Use shared session state and transcript as the source of truth for role-by-role collaboration.
108
+ 3. If collaborative MCP is unavailable, use CLI fallback commands and keep behavior equivalent.
109
+
110
+ **How to use SynapseGrid collaboration:**
111
+ ```text
112
+ Preferred: use SynapseGrid MCP tools (ac-framework-collab) for start/status/step/resume/stop.
113
+ Fallback: use AC Framework agents CLI commands directly.
114
+ ```
115
+ ```bash
116
+ # Install/update collaborative MCP server integrations
117
+ acfm agents install-mcps
118
+
119
+ # Start collaborative runtime with visible 4-pane tmux war-room
120
+ acfm agents start --task "design and implement feature X" --attach --model-coder provider/model
121
+
122
+ # If already running in background, attach to panes and inspect logs
123
+ acfm agents live
124
+ acfm agents logs --role all --lines 120
125
+
126
+ # Resume/list/export operations
127
+ acfm agents resume
128
+ acfm agents list
129
+ acfm agents export --format md --out synapse-session.md
130
+
131
+ # Fast diagnostics for OpenCode resolution errors
132
+ acfm agents setup
133
+ ```
134
+
135
+ **Troubleshooting notes:**
136
+ - If transcript shows `Agent failed: spawn opencode ENOENT`, run `acfm agents setup` and restart/resume session.
137
+ - If session exists but panes are not visible, use `acfm agents live` (or `acfm agents attach`) or `tmux attach -t <session-name>`.
138
+ - For MCP-first flows, ensure session start enables worker spawning so tmux panes are created.
139
+ - Per-role models can be set at start (`--model-planner`, `--model-critic`, `--model-coder`, `--model-reviewer`) or persisted via `acfm agents model set`.
101
140
 
102
141
  ### OpenSpec Skills (The heart of the framework)
103
142
 
@@ -98,6 +98,45 @@ acfm memory stats
98
98
 
99
99
  **User communication:** "Memory saved: [brief description]" when auto-saving occurs.
100
100
 
101
+ ### SynapseGrid Collaborative MCP Protocol (Optional)
102
+
103
+ If SynapseGrid is enabled in `acfm init`, AC Framework installs the collaborative MCP server automatically for detected assistants.
104
+
105
+ **Session-start requirement when collaboration is enabled:**
106
+ 1. Prefer the available SynapseGrid MCP tools for collaborative session control before falling back to direct CLI.
107
+ 2. Use shared session state and transcript as the source of truth for role-by-role collaboration.
108
+ 3. If collaborative MCP is unavailable, use CLI fallback commands and keep behavior equivalent.
109
+
110
+ **How to use SynapseGrid collaboration:**
111
+ ```text
112
+ Preferred: use SynapseGrid MCP tools (ac-framework-collab) for start/status/step/resume/stop.
113
+ Fallback: use AC Framework agents CLI commands directly.
114
+ ```
115
+ ```bash
116
+ # Install/update collaborative MCP server integrations
117
+ acfm agents install-mcps
118
+
119
+ # Start collaborative runtime with visible 4-pane tmux war-room
120
+ acfm agents start --task "design and implement feature X" --attach --model-coder provider/model
121
+
122
+ # If already running in background, attach to panes and inspect logs
123
+ acfm agents live
124
+ acfm agents logs --role all --lines 120
125
+
126
+ # Resume/list/export operations
127
+ acfm agents resume
128
+ acfm agents list
129
+ acfm agents export --format md --out synapse-session.md
130
+
131
+ # Fast diagnostics for OpenCode resolution errors
132
+ acfm agents setup
133
+ ```
134
+
135
+ **Troubleshooting notes:**
136
+ - If transcript shows `Agent failed: spawn opencode ENOENT`, run `acfm agents setup` and restart/resume session.
137
+ - If session exists but panes are not visible, use `acfm agents live` (or `acfm agents attach`) or `tmux attach -t <session-name>`.
138
+ - For MCP-first flows, ensure session start enables worker spawning so tmux panes are created.
139
+ - Per-role models can be set at start (`--model-planner`, `--model-critic`, `--model-coder`, `--model-reviewer`) or persisted via `acfm agents model set`.
101
140
 
102
141
  ### OpenSpec Skills (The heart of the framework)
103
142
 
@@ -109,22 +109,34 @@ If SynapseGrid is enabled in `acfm init`, AC Framework installs the collaborativ
109
109
 
110
110
  **How to use SynapseGrid collaboration:**
111
111
  ```text
112
- Preferred: use SynapseGrid MCP tools (ac-framework-collab) for session start/status/step/stop.
112
+ Preferred: use SynapseGrid MCP tools (ac-framework-collab) for start/status/step/resume/stop.
113
113
  Fallback: use AC Framework agents CLI commands directly.
114
114
  ```
115
115
  ```bash
116
- # Optional install/reinstall of collaborative MCP servers
116
+ # Install/update collaborative MCP server integrations
117
117
  acfm agents install-mcps
118
118
 
119
- # Start collaborative runtime manually
120
- acfm agents start --task "design and implement feature X"
119
+ # Start collaborative runtime with visible 4-pane tmux war-room
120
+ acfm agents start --task "design and implement feature X" --attach --model-coder provider/model
121
+
122
+ # If already running in background, attach to panes and inspect logs
123
+ acfm agents live
124
+ acfm agents logs --role all --lines 120
121
125
 
122
126
  # Resume/list/export operations
123
127
  acfm agents resume
124
128
  acfm agents list
125
129
  acfm agents export --format md --out synapse-session.md
130
+
131
+ # Fast diagnostics for OpenCode resolution errors
132
+ acfm agents setup
126
133
  ```
127
134
 
135
+ **Troubleshooting notes:**
136
+ - If transcript shows `Agent failed: spawn opencode ENOENT`, run `acfm agents setup` and restart/resume session.
137
+ - If session exists but panes are not visible, use `acfm agents live` (or `acfm agents attach`) or `tmux attach -t <session-name>`.
138
+ - For MCP-first flows, ensure session start enables worker spawning so tmux panes are created.
139
+ - Per-role models can be set at start (`--model-planner`, `--model-critic`, `--model-coder`, `--model-reviewer`) or persisted via `acfm agents model set`.
128
140
 
129
141
  ### OpenSpec Skills (The heart of the framework)
130
142
 
@@ -98,6 +98,45 @@ acfm memory stats
98
98
 
99
99
  **User communication:** "Memory saved: [brief description]" when auto-saving occurs.
100
100
 
101
+ ### SynapseGrid Collaborative MCP Protocol (Optional)
102
+
103
+ If SynapseGrid is enabled in `acfm init`, AC Framework installs the collaborative MCP server automatically for detected assistants.
104
+
105
+ **Session-start requirement when collaboration is enabled:**
106
+ 1. Prefer the available SynapseGrid MCP tools for collaborative session control before falling back to direct CLI.
107
+ 2. Use shared session state and transcript as the source of truth for role-by-role collaboration.
108
+ 3. If collaborative MCP is unavailable, use CLI fallback commands and keep behavior equivalent.
109
+
110
+ **How to use SynapseGrid collaboration:**
111
+ ```text
112
+ Preferred: use SynapseGrid MCP tools (ac-framework-collab) for start/status/step/resume/stop.
113
+ Fallback: use AC Framework agents CLI commands directly.
114
+ ```
115
+ ```bash
116
+ # Install/update collaborative MCP server integrations
117
+ acfm agents install-mcps
118
+
119
+ # Start collaborative runtime with visible 4-pane tmux war-room
120
+ acfm agents start --task "design and implement feature X" --attach --model-coder provider/model
121
+
122
+ # If already running in background, attach to panes and inspect logs
123
+ acfm agents live
124
+ acfm agents logs --role all --lines 120
125
+
126
+ # Resume/list/export operations
127
+ acfm agents resume
128
+ acfm agents list
129
+ acfm agents export --format md --out synapse-session.md
130
+
131
+ # Fast diagnostics for OpenCode resolution errors
132
+ acfm agents setup
133
+ ```
134
+
135
+ **Troubleshooting notes:**
136
+ - If transcript shows `Agent failed: spawn opencode ENOENT`, run `acfm agents setup` and restart/resume session.
137
+ - If session exists but panes are not visible, use `acfm agents live` (or `acfm agents attach`) or `tmux attach -t <session-name>`.
138
+ - For MCP-first flows, ensure session start enables worker spawning so tmux panes are created.
139
+ - Per-role models can be set at start (`--model-planner`, `--model-critic`, `--model-coder`, `--model-reviewer`) or persisted via `acfm agents model set`.
101
140
 
102
141
  ### OpenSpec Skills (The heart of the framework)
103
142
 
@@ -98,6 +98,45 @@ acfm memory stats
98
98
 
99
99
  **User communication:** "Memory saved: [brief description]" when auto-saving occurs.
100
100
 
101
+ ### SynapseGrid Collaborative MCP Protocol (Optional)
102
+
103
+ If SynapseGrid is enabled in `acfm init`, AC Framework installs the collaborative MCP server automatically for detected assistants.
104
+
105
+ **Session-start requirement when collaboration is enabled:**
106
+ 1. Prefer the available SynapseGrid MCP tools for collaborative session control before falling back to direct CLI.
107
+ 2. Use shared session state and transcript as the source of truth for role-by-role collaboration.
108
+ 3. If collaborative MCP is unavailable, use CLI fallback commands and keep behavior equivalent.
109
+
110
+ **How to use SynapseGrid collaboration:**
111
+ ```text
112
+ Preferred: use SynapseGrid MCP tools (ac-framework-collab) for start/status/step/resume/stop.
113
+ Fallback: use AC Framework agents CLI commands directly.
114
+ ```
115
+ ```bash
116
+ # Install/update collaborative MCP server integrations
117
+ acfm agents install-mcps
118
+
119
+ # Start collaborative runtime with visible 4-pane tmux war-room
120
+ acfm agents start --task "design and implement feature X" --attach --model-coder provider/model
121
+
122
+ # If already running in background, attach to panes and inspect logs
123
+ acfm agents live
124
+ acfm agents logs --role all --lines 120
125
+
126
+ # Resume/list/export operations
127
+ acfm agents resume
128
+ acfm agents list
129
+ acfm agents export --format md --out synapse-session.md
130
+
131
+ # Fast diagnostics for OpenCode resolution errors
132
+ acfm agents setup
133
+ ```
134
+
135
+ **Troubleshooting notes:**
136
+ - If transcript shows `Agent failed: spawn opencode ENOENT`, run `acfm agents setup` and restart/resume session.
137
+ - If session exists but panes are not visible, use `acfm agents live` (or `acfm agents attach`) or `tmux attach -t <session-name>`.
138
+ - For MCP-first flows, ensure session start enables worker spawning so tmux panes are created.
139
+ - Per-role models can be set at start (`--model-planner`, `--model-critic`, `--model-coder`, `--model-reviewer`) or persisted via `acfm agents model set`.
101
140
 
102
141
  ### OpenSpec Skills (The heart of the framework)
103
142
 
@@ -98,6 +98,45 @@ acfm memory stats
98
98
 
99
99
  **User communication:** "Memory saved: [brief description]" when auto-saving occurs.
100
100
 
101
+ ### SynapseGrid Collaborative MCP Protocol (Optional)
102
+
103
+ If SynapseGrid is enabled in `acfm init`, AC Framework installs the collaborative MCP server automatically for detected assistants.
104
+
105
+ **Session-start requirement when collaboration is enabled:**
106
+ 1. Prefer the available SynapseGrid MCP tools for collaborative session control before falling back to direct CLI.
107
+ 2. Use shared session state and transcript as the source of truth for role-by-role collaboration.
108
+ 3. If collaborative MCP is unavailable, use CLI fallback commands and keep behavior equivalent.
109
+
110
+ **How to use SynapseGrid collaboration:**
111
+ ```text
112
+ Preferred: use SynapseGrid MCP tools (ac-framework-collab) for start/status/step/resume/stop.
113
+ Fallback: use AC Framework agents CLI commands directly.
114
+ ```
115
+ ```bash
116
+ # Install/update collaborative MCP server integrations
117
+ acfm agents install-mcps
118
+
119
+ # Start collaborative runtime with visible 4-pane tmux war-room
120
+ acfm agents start --task "design and implement feature X" --attach --model-coder provider/model
121
+
122
+ # If already running in background, attach to panes and inspect logs
123
+ acfm agents live
124
+ acfm agents logs --role all --lines 120
125
+
126
+ # Resume/list/export operations
127
+ acfm agents resume
128
+ acfm agents list
129
+ acfm agents export --format md --out synapse-session.md
130
+
131
+ # Fast diagnostics for OpenCode resolution errors
132
+ acfm agents setup
133
+ ```
134
+
135
+ **Troubleshooting notes:**
136
+ - If transcript shows `Agent failed: spawn opencode ENOENT`, run `acfm agents setup` and restart/resume session.
137
+ - If session exists but panes are not visible, use `acfm agents live` (or `acfm agents attach`) or `tmux attach -t <session-name>`.
138
+ - For MCP-first flows, ensure session start enables worker spawning so tmux panes are created.
139
+ - Per-role models can be set at start (`--model-planner`, `--model-critic`, `--model-coder`, `--model-reviewer`) or persisted via `acfm agents model set`.
101
140
 
102
141
  ### OpenSpec Skills (The heart of the framework)
103
142
 
@@ -98,6 +98,45 @@ acfm memory stats
98
98
 
99
99
  **User communication:** "Memory saved: [brief description]" when auto-saving occurs.
100
100
 
101
+ ### SynapseGrid Collaborative MCP Protocol (Optional)
102
+
103
+ If SynapseGrid is enabled in `acfm init`, AC Framework installs the collaborative MCP server automatically for detected assistants.
104
+
105
+ **Session-start requirement when collaboration is enabled:**
106
+ 1. Prefer the available SynapseGrid MCP tools for collaborative session control before falling back to direct CLI.
107
+ 2. Use shared session state and transcript as the source of truth for role-by-role collaboration.
108
+ 3. If collaborative MCP is unavailable, use CLI fallback commands and keep behavior equivalent.
109
+
110
+ **How to use SynapseGrid collaboration:**
111
+ ```text
112
+ Preferred: use SynapseGrid MCP tools (ac-framework-collab) for start/status/step/resume/stop.
113
+ Fallback: use AC Framework agents CLI commands directly.
114
+ ```
115
+ ```bash
116
+ # Install/update collaborative MCP server integrations
117
+ acfm agents install-mcps
118
+
119
+ # Start collaborative runtime with visible 4-pane tmux war-room
120
+ acfm agents start --task "design and implement feature X" --attach --model-coder provider/model
121
+
122
+ # If already running in background, attach to panes and inspect logs
123
+ acfm agents live
124
+ acfm agents logs --role all --lines 120
125
+
126
+ # Resume/list/export operations
127
+ acfm agents resume
128
+ acfm agents list
129
+ acfm agents export --format md --out synapse-session.md
130
+
131
+ # Fast diagnostics for OpenCode resolution errors
132
+ acfm agents setup
133
+ ```
134
+
135
+ **Troubleshooting notes:**
136
+ - If transcript shows `Agent failed: spawn opencode ENOENT`, run `acfm agents setup` and restart/resume session.
137
+ - If session exists but panes are not visible, use `acfm agents live` (or `acfm agents attach`) or `tmux attach -t <session-name>`.
138
+ - For MCP-first flows, ensure session start enables worker spawning so tmux panes are created.
139
+ - Per-role models can be set at start (`--model-planner`, `--model-critic`, `--model-coder`, `--model-reviewer`) or persisted via `acfm agents model set`.
101
140
 
102
141
  ### OpenSpec Skills (The heart of the framework)
103
142
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ac-framework",
3
- "version": "1.9.5",
3
+ "version": "1.9.7",
4
4
  "description": "Agentic Coding Framework - Multi-assistant configuration system with OpenSpec workflows",
5
5
  "main": "src/index.js",
6
6
  "exports": {
@@ -0,0 +1,49 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
3
+ import { homedir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { DEFAULT_SYNAPSE_MODEL } from './constants.js';
6
+ import { sanitizeRoleModels, normalizeModelId } from './model-selection.js';
7
+
8
+ const ACFM_DIR = join(homedir(), '.acfm');
9
+ const CONFIG_PATH = join(ACFM_DIR, 'config.json');
10
+
11
+ function normalizeConfig(raw) {
12
+ const agents = raw?.agents && typeof raw.agents === 'object' ? raw.agents : {};
13
+ return {
14
+ agents: {
15
+ defaultModel: normalizeModelId(agents.defaultModel) || DEFAULT_SYNAPSE_MODEL,
16
+ defaultRoleModels: sanitizeRoleModels(agents.defaultRoleModels),
17
+ },
18
+ };
19
+ }
20
+
21
+ export async function loadAgentsConfig() {
22
+ if (!existsSync(CONFIG_PATH)) {
23
+ return normalizeConfig({});
24
+ }
25
+
26
+ try {
27
+ const raw = JSON.parse(await readFile(CONFIG_PATH, 'utf8'));
28
+ return normalizeConfig(raw);
29
+ } catch {
30
+ return normalizeConfig({});
31
+ }
32
+ }
33
+
34
+ export async function saveAgentsConfig(config) {
35
+ const normalized = normalizeConfig(config);
36
+ await mkdir(ACFM_DIR, { recursive: true });
37
+ await writeFile(CONFIG_PATH, JSON.stringify(normalized, null, 2) + '\n', 'utf8');
38
+ return normalized;
39
+ }
40
+
41
+ export async function updateAgentsConfig(mutator) {
42
+ const current = await loadAgentsConfig();
43
+ const next = await mutator(current);
44
+ return saveAgentsConfig(next);
45
+ }
46
+
47
+ export function getAgentsConfigPath() {
48
+ return CONFIG_PATH;
49
+ }
@@ -4,5 +4,6 @@ import { join } from 'node:path';
4
4
  export const COLLAB_SYSTEM_NAME = 'SynapseGrid';
5
5
  export const COLLAB_ROLES = ['planner', 'critic', 'coder', 'reviewer'];
6
6
  export const DEFAULT_MAX_ROUNDS = 3;
7
+ export const DEFAULT_SYNAPSE_MODEL = 'opencode/minimax-m2.5-free';
7
8
  export const SESSION_ROOT_DIR = join(homedir(), '.acfm', 'synapsegrid');
8
9
  export const CURRENT_SESSION_FILE = join(SESSION_ROOT_DIR, 'current-session.json');
@@ -0,0 +1,38 @@
1
+ import { COLLAB_ROLES } from './constants.js';
2
+
3
+ export function normalizeModelId(value) {
4
+ if (typeof value !== 'string') return null;
5
+ const trimmed = value.trim();
6
+ return trimmed.length > 0 ? trimmed : null;
7
+ }
8
+
9
+ export function isValidModelId(value) {
10
+ const normalized = normalizeModelId(value);
11
+ if (!normalized) return false;
12
+ return normalized.includes('/');
13
+ }
14
+
15
+ export function sanitizeRoleModels(input) {
16
+ const out = {};
17
+ if (!input || typeof input !== 'object') return out;
18
+ for (const role of COLLAB_ROLES) {
19
+ const normalized = normalizeModelId(input[role]);
20
+ if (normalized) out[role] = normalized;
21
+ }
22
+ return out;
23
+ }
24
+
25
+ export function resolveRoleModel(state, role, fallbackModel = null) {
26
+ const roleModels = sanitizeRoleModels(state?.roleModels);
27
+ const roleModel = roleModels[role] || null;
28
+ const globalModel = normalizeModelId(state?.model) || normalizeModelId(fallbackModel);
29
+ return roleModel || globalModel || null;
30
+ }
31
+
32
+ export function buildEffectiveRoleModels(state, fallbackModel = null) {
33
+ const effective = {};
34
+ for (const role of COLLAB_ROLES) {
35
+ effective[role] = resolveRoleModel(state, role, fallbackModel);
36
+ }
37
+ return effective;
38
+ }
@@ -1,9 +1,29 @@
1
- import { execFile } from 'node:child_process';
2
- import { promisify } from 'node:util';
3
-
4
- const execFileAsync = promisify(execFile);
1
+ import { spawn } from 'node:child_process';
5
2
 
6
3
  function parseOpenCodeRunOutput(stdout) {
4
+ const ndjsonLines = stdout
5
+ .split('\n')
6
+ .map((line) => line.trim())
7
+ .filter(Boolean);
8
+
9
+ if (ndjsonLines.length > 0) {
10
+ const textChunks = [];
11
+ for (const line of ndjsonLines) {
12
+ try {
13
+ const event = JSON.parse(line);
14
+ const text = event?.part?.text;
15
+ if (typeof text === 'string' && text.trim()) {
16
+ textChunks.push(text.trim());
17
+ }
18
+ } catch {
19
+ // ignore malformed lines and continue
20
+ }
21
+ }
22
+ if (textChunks.length > 0) {
23
+ return textChunks.join('\n\n');
24
+ }
25
+ }
26
+
7
27
  try {
8
28
  const parsed = JSON.parse(stdout);
9
29
  if (Array.isArray(parsed)) {
@@ -22,7 +42,8 @@ function parseOpenCodeRunOutput(stdout) {
22
42
  return stdout.trim();
23
43
  }
24
44
 
25
- export async function runOpenCodePrompt({ prompt, cwd, model, agent, timeoutMs = 180000 }) {
45
+ export async function runOpenCodePrompt({ prompt, cwd, model, agent, timeoutMs = 180000, binaryPath }) {
46
+ const binary = binaryPath || process.env.ACFM_OPENCODE_BIN || 'opencode';
26
47
  const args = ['run', '--format', 'json'];
27
48
  if (model) {
28
49
  args.push('--model', model);
@@ -32,10 +53,48 @@ export async function runOpenCodePrompt({ prompt, cwd, model, agent, timeoutMs =
32
53
  }
33
54
  args.push('--', prompt);
34
55
 
35
- const { stdout, stderr } = await execFileAsync('opencode', args, {
36
- cwd,
37
- timeout: timeoutMs,
38
- maxBuffer: 10 * 1024 * 1024,
56
+ const { stdout, stderr } = await new Promise((resolvePromise, rejectPromise) => {
57
+ const child = spawn(binary, args, {
58
+ cwd,
59
+ env: process.env,
60
+ stdio: ['ignore', 'pipe', 'pipe'],
61
+ });
62
+
63
+ let out = '';
64
+ let err = '';
65
+ let timedOut = false;
66
+
67
+ const timer = setTimeout(() => {
68
+ timedOut = true;
69
+ child.kill('SIGTERM');
70
+ setTimeout(() => child.kill('SIGKILL'), 1500).unref();
71
+ }, timeoutMs);
72
+
73
+ child.stdout.on('data', (chunk) => {
74
+ out += chunk.toString();
75
+ });
76
+ child.stderr.on('data', (chunk) => {
77
+ err += chunk.toString();
78
+ });
79
+
80
+ child.on('error', (error) => {
81
+ clearTimeout(timer);
82
+ rejectPromise(error);
83
+ });
84
+
85
+ child.on('close', (code, signal) => {
86
+ clearTimeout(timer);
87
+ if (timedOut) {
88
+ rejectPromise(new Error(`opencode timed out after ${timeoutMs}ms`));
89
+ return;
90
+ }
91
+ if (code !== 0) {
92
+ const details = [err.trim(), out.trim()].filter(Boolean).join(' | ');
93
+ rejectPromise(new Error(details || `opencode exited with code ${code}${signal ? ` (${signal})` : ''}`));
94
+ return;
95
+ }
96
+ resolvePromise({ stdout: out, stderr: err });
97
+ });
39
98
  });
40
99
 
41
100
  const parsed = parseOpenCodeRunOutput(stdout);
@@ -1,6 +1,7 @@
1
1
  import { buildAgentPrompt, ROLE_SYSTEM_PROMPTS } from './role-prompts.js';
2
2
  import { runOpenCodePrompt } from './opencode-client.js';
3
3
  import { nextRole, shouldStop } from './scheduler.js';
4
+ import { resolveRoleModel } from './model-selection.js';
4
5
  import {
5
6
  addAgentMessage,
6
7
  loadSessionState,
@@ -42,11 +43,13 @@ export async function runTurn(sessionId, options = {}) {
42
43
  const prompt = buildRuntimePrompt({ state, role: scheduled.role });
43
44
  let content;
44
45
  try {
46
+ const effectiveModel = resolveRoleModel(state, scheduled.role, options.model);
45
47
  content = await runOpenCodePrompt({
46
48
  prompt,
47
49
  cwd: options.cwd || process.cwd(),
48
- model: options.model,
50
+ model: effectiveModel,
49
51
  agent: options.agent,
52
+ binaryPath: options.opencodeBin,
50
53
  timeoutMs: options.timeoutMs,
51
54
  });
52
55
  } catch (error) {
@@ -105,11 +108,13 @@ export async function executeActiveTurn(sessionId, role, options = {}) {
105
108
  const prompt = buildRuntimePrompt({ state, role });
106
109
  let content;
107
110
  try {
111
+ const effectiveModel = resolveRoleModel(state, role, options.model);
108
112
  content = await runOpenCodePrompt({
109
113
  prompt,
110
114
  cwd: options.cwd || process.cwd(),
111
- model: options.model,
115
+ model: effectiveModel,
112
116
  agent: options.agent,
117
+ binaryPath: options.opencodeBin,
113
118
  timeoutMs: options.timeoutMs,
114
119
  });
115
120
  } catch (error) {
@@ -153,11 +158,13 @@ export async function runWorkerIteration(sessionId, role, options = {}) {
153
158
  const prompt = buildRuntimePrompt({ state, role });
154
159
  let content;
155
160
  try {
161
+ const effectiveModel = resolveRoleModel(state, role, options.model);
156
162
  content = await runOpenCodePrompt({
157
163
  prompt,
158
164
  cwd: options.cwd || process.cwd(),
159
- model: options.model,
165
+ model: effectiveModel,
160
166
  agent: options.agent,
167
+ binaryPath: options.opencodeBin,
161
168
  timeoutMs: options.timeoutMs,
162
169
  });
163
170
  } catch (error) {