@jungjaehoon/mama-os 0.9.0 → 0.9.1
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.
- package/CHANGELOG.md +33 -0
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.js +37 -9
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/config/types.d.ts +17 -0
- package/dist/cli/config/types.d.ts.map +1 -1
- package/dist/cli/config/types.js.map +1 -1
- package/dist/gateways/discord.d.ts.map +1 -1
- package/dist/gateways/discord.js +8 -0
- package/dist/gateways/discord.js.map +1 -1
- package/dist/multi-agent/agent-process-pool.d.ts.map +1 -1
- package/dist/multi-agent/agent-process-pool.js +32 -4
- package/dist/multi-agent/agent-process-pool.js.map +1 -1
- package/dist/multi-agent/pr-review-poller.d.ts +16 -0
- package/dist/multi-agent/pr-review-poller.d.ts.map +1 -1
- package/dist/multi-agent/pr-review-poller.js +38 -0
- package/dist/multi-agent/pr-review-poller.js.map +1 -1
- package/dist/multi-agent/types.d.ts +10 -0
- package/dist/multi-agent/types.d.ts.map +1 -1
- package/dist/multi-agent/types.js.map +1 -1
- package/dist/setup/setup-prompt.d.ts +1 -1
- package/dist/setup/setup-prompt.d.ts.map +1 -1
- package/dist/setup/setup-prompt.js +25 -0
- package/dist/setup/setup-prompt.js.map +1 -1
- package/package.json +1 -1
- package/public/viewer/js/modules/chat.js +1 -4
- package/public/viewer/js/modules/dashboard.js +46 -41
- package/public/viewer/src/modules/chat.ts +1 -10
- package/public/viewer/src/modules/dashboard.ts +52 -43
- package/public/viewer/viewer.html +6 -4
- package/templates/personas/sisyphus.md +8 -0
|
@@ -93,6 +93,31 @@ update_config("agent.model", "gpt-5.3-codex") // for codex-mcp
|
|
|
93
93
|
- If using \`codex-mcp\`, user must have Codex credentials in \`~/.mama/.codex/\`
|
|
94
94
|
- Do NOT use \`backend: codex\` (legacy, broken) - always use \`codex-mcp\`
|
|
95
95
|
|
|
96
|
+
### Security & Permission Settings
|
|
97
|
+
|
|
98
|
+
Ask users about agent permission settings:
|
|
99
|
+
|
|
100
|
+
**Agent Autonomy (dangerouslySkipPermissions)**
|
|
101
|
+
|
|
102
|
+
This controls whether agents can execute tools (file writes, bash commands, git operations) without asking for permission.
|
|
103
|
+
|
|
104
|
+
**Options:**
|
|
105
|
+
- **true** (default): Agents run autonomously without approval prompts. Required for headless/daemon operation.
|
|
106
|
+
- **false**: Agents ask for permission before executing each tool.
|
|
107
|
+
|
|
108
|
+
⚠️ **Warning**: Setting this to \`true\` gives agents full system access. Only enable in trusted environments.
|
|
109
|
+
|
|
110
|
+
To configure:
|
|
111
|
+
\`\`\`
|
|
112
|
+
update_config("multi_agent.dangerouslySkipPermissions", true)
|
|
113
|
+
\`\`\`
|
|
114
|
+
|
|
115
|
+
**IMPORTANT**: This setting also requires \`MAMA_TRUSTED_ENV=true\` environment variable.
|
|
116
|
+
- For systemd service: Add \`Environment=MAMA_TRUSTED_ENV=true\` to the service file
|
|
117
|
+
- For manual start: Run with \`MAMA_TRUSTED_ENV=true mama start\`
|
|
118
|
+
|
|
119
|
+
If they want autonomous agents, save the config and remind them about the environment variable.
|
|
120
|
+
|
|
96
121
|
### Completion
|
|
97
122
|
|
|
98
123
|
After setup is done:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-prompt.js","sourceRoot":"","sources":["../../src/setup/setup-prompt.ts"],"names":[],"mappings":";;;AAAa,QAAA,mBAAmB,GAAG
|
|
1
|
+
{"version":3,"file":"setup-prompt.js","sourceRoot":"","sources":["../../src/setup/setup-prompt.ts"],"names":[],"mappings":";;;AAAa,QAAA,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiLlC,CAAC"}
|
package/package.json
CHANGED
|
@@ -80,10 +80,7 @@ export class ChatModule {
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
async autoCheckpoint() {
|
|
83
|
-
//
|
|
84
|
-
// Checkpoints should only be saved manually via /checkpoint command with proper summaries.
|
|
85
|
-
// The viewer chat uses localStorage for session persistence instead.
|
|
86
|
-
logger.info('Auto-checkpoint disabled (use /checkpoint for manual saves)');
|
|
83
|
+
// Auto-checkpoint disabled - use /checkpoint command for manual saves
|
|
87
84
|
return;
|
|
88
85
|
}
|
|
89
86
|
// =============================================
|
|
@@ -72,48 +72,68 @@ export class DashboardModule {
|
|
|
72
72
|
}
|
|
73
73
|
/**
|
|
74
74
|
* Load dashboard status from API
|
|
75
|
+
* Uses Promise.allSettled for parallel loading to improve performance
|
|
75
76
|
*/
|
|
76
77
|
async loadStatus() {
|
|
77
78
|
try {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
// Load all data in parallel for better performance
|
|
80
|
+
const [dashboardResult, multiAgentResult, delegationsResult, cronResult, tokenResult, mcpResult,] = await Promise.allSettled([
|
|
81
|
+
API.get('/api/dashboard/status'),
|
|
82
|
+
API.get('/api/multi-agent/status'),
|
|
83
|
+
API.get('/api/multi-agent/delegations?limit=10'),
|
|
84
|
+
API.getCronJobs(),
|
|
85
|
+
Promise.all([API.getTokenSummary(), API.getTokensByAgent()]),
|
|
86
|
+
API.get('/api/mcp-servers'),
|
|
87
|
+
]);
|
|
88
|
+
// Process dashboard status (required)
|
|
89
|
+
if (dashboardResult.status === 'fulfilled') {
|
|
90
|
+
this.data = dashboardResult.value;
|
|
82
91
|
}
|
|
83
|
-
|
|
84
|
-
|
|
92
|
+
else {
|
|
93
|
+
throw dashboardResult.reason;
|
|
94
|
+
}
|
|
95
|
+
// Process multi-agent status
|
|
96
|
+
if (multiAgentResult.status === 'fulfilled') {
|
|
97
|
+
this.multiAgentData = multiAgentResult.value;
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
logger.warn('[Dashboard] Multi-agent status unavailable:', multiAgentResult.reason);
|
|
85
101
|
this.multiAgentData = { enabled: false, agents: [] };
|
|
86
102
|
}
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
this.delegationsData =
|
|
103
|
+
// Process delegations
|
|
104
|
+
if (delegationsResult.status === 'fulfilled') {
|
|
105
|
+
this.delegationsData = delegationsResult.value;
|
|
90
106
|
}
|
|
91
|
-
|
|
92
|
-
logger.warn('[Dashboard] Delegations unavailable:',
|
|
107
|
+
else {
|
|
108
|
+
logger.warn('[Dashboard] Delegations unavailable:', delegationsResult.reason);
|
|
93
109
|
this.delegationsData = { delegations: [], count: 0 };
|
|
94
110
|
}
|
|
95
|
-
//
|
|
96
|
-
|
|
97
|
-
this.cronData =
|
|
111
|
+
// Process cron jobs
|
|
112
|
+
if (cronResult.status === 'fulfilled') {
|
|
113
|
+
this.cronData = cronResult.value;
|
|
98
114
|
}
|
|
99
|
-
|
|
100
|
-
logger.warn('[Dashboard] Cron data unavailable:',
|
|
115
|
+
else {
|
|
116
|
+
logger.warn('[Dashboard] Cron data unavailable:', cronResult.reason);
|
|
101
117
|
this.cronData = null;
|
|
102
118
|
}
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
const [summary, byAgent] =
|
|
106
|
-
API.getTokenSummary(),
|
|
107
|
-
API.getTokensByAgent(),
|
|
108
|
-
]);
|
|
119
|
+
// Process token data
|
|
120
|
+
if (tokenResult.status === 'fulfilled') {
|
|
121
|
+
const [summary, byAgent] = tokenResult.value;
|
|
109
122
|
this.tokenData = { summary, byAgent };
|
|
110
123
|
}
|
|
111
|
-
|
|
112
|
-
logger.warn('[Dashboard] Token data unavailable:',
|
|
124
|
+
else {
|
|
125
|
+
logger.warn('[Dashboard] Token data unavailable:', tokenResult.reason);
|
|
113
126
|
this.tokenData = null;
|
|
114
127
|
}
|
|
115
|
-
//
|
|
116
|
-
|
|
128
|
+
// Process MCP servers
|
|
129
|
+
if (mcpResult.status === 'fulfilled' && mcpResult.value && 'servers' in mcpResult.value) {
|
|
130
|
+
this.mcpServers = mcpResult.value.servers || [];
|
|
131
|
+
this.renderMCPServers();
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
logger.warn('[Dashboard] MCP servers unavailable');
|
|
135
|
+
this.mcpServers = [];
|
|
136
|
+
}
|
|
117
137
|
this.render();
|
|
118
138
|
this.setStatus(`Last updated: ${new Date().toLocaleTimeString()}`);
|
|
119
139
|
}
|
|
@@ -122,21 +142,6 @@ export class DashboardModule {
|
|
|
122
142
|
this.setStatus(`Error: ${getErrorMessage(error)}`, 'error');
|
|
123
143
|
}
|
|
124
144
|
}
|
|
125
|
-
/**
|
|
126
|
-
* Load MCP servers from API
|
|
127
|
-
*/
|
|
128
|
-
async loadMCPServers() {
|
|
129
|
-
try {
|
|
130
|
-
const data = await API.get('/api/mcp-servers');
|
|
131
|
-
if (data && 'servers' in data) {
|
|
132
|
-
this.mcpServers = data.servers || [];
|
|
133
|
-
this.renderMCPServers();
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
catch (error) {
|
|
137
|
-
logger.error('Failed to load MCP servers:', error);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
145
|
/**
|
|
141
146
|
* Render all dashboard sections
|
|
142
147
|
*/
|
|
@@ -66,12 +66,6 @@ type CheckpointRecord = {
|
|
|
66
66
|
summary: string;
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
-
// Reserved for future use - attachment message handling
|
|
70
|
-
type _ChatMessageWithAttachment = {
|
|
71
|
-
id?: string;
|
|
72
|
-
[key: string]: unknown;
|
|
73
|
-
};
|
|
74
|
-
|
|
75
69
|
/**
|
|
76
70
|
* Chat Module Class
|
|
77
71
|
*/
|
|
@@ -153,10 +147,7 @@ export class ChatModule {
|
|
|
153
147
|
}
|
|
154
148
|
|
|
155
149
|
async autoCheckpoint(): Promise<void> {
|
|
156
|
-
//
|
|
157
|
-
// Checkpoints should only be saved manually via /checkpoint command with proper summaries.
|
|
158
|
-
// The viewer chat uses localStorage for session persistence instead.
|
|
159
|
-
logger.info('Auto-checkpoint disabled (use /checkpoint for manual saves)');
|
|
150
|
+
// Auto-checkpoint disabled - use /checkpoint command for manual saves
|
|
160
151
|
return;
|
|
161
152
|
}
|
|
162
153
|
|
|
@@ -177,51 +177,75 @@ export class DashboardModule {
|
|
|
177
177
|
|
|
178
178
|
/**
|
|
179
179
|
* Load dashboard status from API
|
|
180
|
+
* Uses Promise.allSettled for parallel loading to improve performance
|
|
180
181
|
*/
|
|
181
182
|
async loadStatus(): Promise<void> {
|
|
182
183
|
try {
|
|
183
|
-
|
|
184
|
+
// Load all data in parallel for better performance
|
|
185
|
+
const [
|
|
186
|
+
dashboardResult,
|
|
187
|
+
multiAgentResult,
|
|
188
|
+
delegationsResult,
|
|
189
|
+
cronResult,
|
|
190
|
+
tokenResult,
|
|
191
|
+
mcpResult,
|
|
192
|
+
] = await Promise.allSettled([
|
|
193
|
+
API.get<DashboardData>('/api/dashboard/status'),
|
|
194
|
+
API.get<MultiAgentDashboardStatus>('/api/multi-agent/status'),
|
|
195
|
+
API.get<DashboardDelegationsData>('/api/multi-agent/delegations?limit=10'),
|
|
196
|
+
API.getCronJobs(),
|
|
197
|
+
Promise.all([API.getTokenSummary(), API.getTokensByAgent()]),
|
|
198
|
+
API.get<McpServersResponse>('/api/mcp-servers'),
|
|
199
|
+
]);
|
|
200
|
+
|
|
201
|
+
// Process dashboard status (required)
|
|
202
|
+
if (dashboardResult.status === 'fulfilled') {
|
|
203
|
+
this.data = dashboardResult.value;
|
|
204
|
+
} else {
|
|
205
|
+
throw dashboardResult.reason;
|
|
206
|
+
}
|
|
184
207
|
|
|
185
|
-
//
|
|
186
|
-
|
|
187
|
-
this.multiAgentData =
|
|
188
|
-
}
|
|
189
|
-
logger.warn('[Dashboard] Multi-agent status unavailable:',
|
|
208
|
+
// Process multi-agent status
|
|
209
|
+
if (multiAgentResult.status === 'fulfilled') {
|
|
210
|
+
this.multiAgentData = multiAgentResult.value;
|
|
211
|
+
} else {
|
|
212
|
+
logger.warn('[Dashboard] Multi-agent status unavailable:', multiAgentResult.reason);
|
|
190
213
|
this.multiAgentData = { enabled: false, agents: [] };
|
|
191
214
|
}
|
|
192
215
|
|
|
193
|
-
//
|
|
194
|
-
|
|
195
|
-
this.delegationsData =
|
|
196
|
-
|
|
197
|
-
);
|
|
198
|
-
} catch (e) {
|
|
199
|
-
logger.warn('[Dashboard] Delegations unavailable:', e);
|
|
216
|
+
// Process delegations
|
|
217
|
+
if (delegationsResult.status === 'fulfilled') {
|
|
218
|
+
this.delegationsData = delegationsResult.value;
|
|
219
|
+
} else {
|
|
220
|
+
logger.warn('[Dashboard] Delegations unavailable:', delegationsResult.reason);
|
|
200
221
|
this.delegationsData = { delegations: [], count: 0 };
|
|
201
222
|
}
|
|
202
223
|
|
|
203
|
-
//
|
|
204
|
-
|
|
205
|
-
this.cronData =
|
|
206
|
-
}
|
|
207
|
-
logger.warn('[Dashboard] Cron data unavailable:',
|
|
224
|
+
// Process cron jobs
|
|
225
|
+
if (cronResult.status === 'fulfilled') {
|
|
226
|
+
this.cronData = cronResult.value;
|
|
227
|
+
} else {
|
|
228
|
+
logger.warn('[Dashboard] Cron data unavailable:', cronResult.reason);
|
|
208
229
|
this.cronData = null;
|
|
209
230
|
}
|
|
210
231
|
|
|
211
|
-
//
|
|
212
|
-
|
|
213
|
-
const [summary, byAgent] =
|
|
214
|
-
API.getTokenSummary(),
|
|
215
|
-
API.getTokensByAgent(),
|
|
216
|
-
]);
|
|
232
|
+
// Process token data
|
|
233
|
+
if (tokenResult.status === 'fulfilled') {
|
|
234
|
+
const [summary, byAgent] = tokenResult.value;
|
|
217
235
|
this.tokenData = { summary, byAgent };
|
|
218
|
-
}
|
|
219
|
-
logger.warn('[Dashboard] Token data unavailable:',
|
|
236
|
+
} else {
|
|
237
|
+
logger.warn('[Dashboard] Token data unavailable:', tokenResult.reason);
|
|
220
238
|
this.tokenData = null;
|
|
221
239
|
}
|
|
222
240
|
|
|
223
|
-
//
|
|
224
|
-
|
|
241
|
+
// Process MCP servers
|
|
242
|
+
if (mcpResult.status === 'fulfilled' && mcpResult.value && 'servers' in mcpResult.value) {
|
|
243
|
+
this.mcpServers = mcpResult.value.servers || [];
|
|
244
|
+
this.renderMCPServers();
|
|
245
|
+
} else {
|
|
246
|
+
logger.warn('[Dashboard] MCP servers unavailable');
|
|
247
|
+
this.mcpServers = [];
|
|
248
|
+
}
|
|
225
249
|
|
|
226
250
|
this.render();
|
|
227
251
|
this.setStatus(`Last updated: ${new Date().toLocaleTimeString()}`);
|
|
@@ -231,21 +255,6 @@ export class DashboardModule {
|
|
|
231
255
|
}
|
|
232
256
|
}
|
|
233
257
|
|
|
234
|
-
/**
|
|
235
|
-
* Load MCP servers from API
|
|
236
|
-
*/
|
|
237
|
-
async loadMCPServers(): Promise<void> {
|
|
238
|
-
try {
|
|
239
|
-
const data = await API.get<McpServersResponse>('/api/mcp-servers');
|
|
240
|
-
if (data && 'servers' in data) {
|
|
241
|
-
this.mcpServers = data.servers || [];
|
|
242
|
-
this.renderMCPServers();
|
|
243
|
-
}
|
|
244
|
-
} catch (error) {
|
|
245
|
-
logger.error('Failed to load MCP servers:', error);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
258
|
/**
|
|
250
259
|
* Render all dashboard sections
|
|
251
260
|
*/
|
|
@@ -25,10 +25,12 @@
|
|
|
25
25
|
rel="stylesheet"
|
|
26
26
|
/>
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
<script src="https://unpkg.com/
|
|
30
|
-
<script src="https://
|
|
31
|
-
<script src="https://
|
|
28
|
+
<!-- External libraries with defer for non-blocking load -->
|
|
29
|
+
<script defer src="https://unpkg.com/vis-network@9/dist/vis-network.min.js"></script>
|
|
30
|
+
<script defer src="https://unpkg.com/lucide@latest"></script>
|
|
31
|
+
<script defer src="https://cdn.jsdelivr.net/npm/marked@11/marked.min.js"></script>
|
|
32
|
+
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.2.5/purify.min.js"></script>
|
|
33
|
+
<!-- Tailwind must load synchronously before config -->
|
|
32
34
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
33
35
|
<script>
|
|
34
36
|
tailwind.config = {
|
|
@@ -94,6 +94,14 @@ CONTEXT:
|
|
|
94
94
|
- Prior analysis: {sub-agent result summary or file path}
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
+
**Discord note (delegation trigger):**
|
|
98
|
+
|
|
99
|
+
- `DELEGATE::...` text is only parsed if the Discord gateway processes the message.
|
|
100
|
+
- If the guild/channel is configured with `requireMention: true`, normal messages without an @mention are ignored.
|
|
101
|
+
- Delegation commands are treated as explicit triggers: if any line starts with `DELEGATE::` / `DELEGATE_BG::`, it will still be processed (even without an @mention).
|
|
102
|
+
- Including the bot mention (example: `<@BOT_ID> DELEGATE::developer::...`) is still OK and makes intent obvious.
|
|
103
|
+
- For low-friction delegation, prefer a dedicated swarm channel with `requireMention: false`.
|
|
104
|
+
|
|
97
105
|
#### Asynchronous Delegation (background — do not wait for result)
|
|
98
106
|
|
|
99
107
|
Use when assigning **independent tasks** to another agent while continuing your own work:
|