@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.
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwJlC,CAAC"}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jungjaehoon/mama-os",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "MAMA OS - Your AI Operating System. Control + Visibility for AI-Powered Automation",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -80,10 +80,7 @@ export class ChatModule {
80
80
  }
81
81
  }
82
82
  async autoCheckpoint() {
83
- // DISABLED: Auto-checkpoint was saving raw conversation history to MAMA memory.
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
- this.data = await API.get('/api/dashboard/status');
79
- // Load multi-agent status (Sprint 3 F2)
80
- try {
81
- this.multiAgentData = await API.get('/api/multi-agent/status');
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
- catch (e) {
84
- logger.warn('[Dashboard] Multi-agent status unavailable:', e);
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
- // Load delegations (F4 endpoint)
88
- try {
89
- this.delegationsData = await API.get('/api/multi-agent/delegations?limit=10');
103
+ // Process delegations
104
+ if (delegationsResult.status === 'fulfilled') {
105
+ this.delegationsData = delegationsResult.value;
90
106
  }
91
- catch (e) {
92
- logger.warn('[Dashboard] Delegations unavailable:', e);
107
+ else {
108
+ logger.warn('[Dashboard] Delegations unavailable:', delegationsResult.reason);
93
109
  this.delegationsData = { delegations: [], count: 0 };
94
110
  }
95
- // Load cron jobs
96
- try {
97
- this.cronData = await API.getCronJobs();
111
+ // Process cron jobs
112
+ if (cronResult.status === 'fulfilled') {
113
+ this.cronData = cronResult.value;
98
114
  }
99
- catch (e) {
100
- logger.warn('[Dashboard] Cron data unavailable:', e);
115
+ else {
116
+ logger.warn('[Dashboard] Cron data unavailable:', cronResult.reason);
101
117
  this.cronData = null;
102
118
  }
103
- // Load token summary
104
- try {
105
- const [summary, byAgent] = await Promise.all([
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
- catch (e) {
112
- logger.warn('[Dashboard] Token data unavailable:', e);
124
+ else {
125
+ logger.warn('[Dashboard] Token data unavailable:', tokenResult.reason);
113
126
  this.tokenData = null;
114
127
  }
115
- // Load MCP servers
116
- await this.loadMCPServers();
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
- // DISABLED: Auto-checkpoint was saving raw conversation history to MAMA memory.
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
- this.data = await API.get<DashboardData>('/api/dashboard/status');
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
- // Load multi-agent status (Sprint 3 F2)
186
- try {
187
- this.multiAgentData = await API.get<MultiAgentDashboardStatus>('/api/multi-agent/status');
188
- } catch (e) {
189
- logger.warn('[Dashboard] Multi-agent status unavailable:', e);
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
- // Load delegations (F4 endpoint)
194
- try {
195
- this.delegationsData = await API.get<DashboardDelegationsData>(
196
- '/api/multi-agent/delegations?limit=10'
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
- // Load cron jobs
204
- try {
205
- this.cronData = await API.getCronJobs();
206
- } catch (e) {
207
- logger.warn('[Dashboard] Cron data unavailable:', e);
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
- // Load token summary
212
- try {
213
- const [summary, byAgent] = await Promise.all([
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
- } catch (e) {
219
- logger.warn('[Dashboard] Token data unavailable:', e);
236
+ } else {
237
+ logger.warn('[Dashboard] Token data unavailable:', tokenResult.reason);
220
238
  this.tokenData = null;
221
239
  }
222
240
 
223
- // Load MCP servers
224
- await this.loadMCPServers();
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
- <script src="https://unpkg.com/vis-network@9/dist/vis-network.min.js"></script>
29
- <script src="https://unpkg.com/lucide@latest"></script>
30
- <script src="https://cdn.jsdelivr.net/npm/marked@11/marked.min.js"></script>
31
- <script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.2.5/purify.min.js"></script>
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: