@hailer/mcp 1.1.4 → 1.1.6
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/.claude/CLAUDE.md +370 -0
- package/.claude/agents/agent-helga-workflow-config.md +14 -1
- package/.claude/commands/autoplan.md +2 -2
- package/.claude/commands/help:commands.md +0 -5
- package/.claude/commands/help:faq.md +0 -5
- package/.claude/commands/plan-workspace.md +1 -1
- package/.claude/commands/prd.md +1 -2
- package/.claude/commands/restore.md +3 -3
- package/.claude/hooks/_utils.cjs +1 -27
- package/.claude/hooks/agent-failure-detector.cjs +0 -12
- package/.claude/hooks/app-edit-guard.cjs +0 -7
- package/.claude/hooks/auto-learn.cjs +0 -12
- package/.claude/hooks/bash-guard.cjs +4 -14
- package/.claude/hooks/builder-mode-manager.cjs +0 -12
- package/.claude/hooks/bulk-activity-guard.cjs +0 -12
- package/.claude/hooks/context-watchdog.cjs +18 -80
- package/.claude/hooks/delegation-reminder.cjs +58 -71
- package/.claude/hooks/design-system-lint.cjs +0 -12
- package/.claude/hooks/post-scaffold-hook.cjs +0 -7
- package/.claude/hooks/prompt-guard.cjs +6 -18
- package/.claude/hooks/publish-template-guard.cjs +0 -10
- package/.claude/hooks/src-edit-guard.cjs +0 -7
- package/.claude/hooks/sync-marketplace-agents.cjs +0 -14
- package/.opencode/agent/agent-helga-workflow-config.md +180 -19
- package/package.json +1 -1
- package/.claude/commands/yolo-off.md +0 -17
- package/.claude/commands/yolo.md +0 -82
- package/.claude/scripts/yolo-toggle.cjs +0 -142
- package/.opencode/commands/yolo-off.md +0 -17
- package/.opencode/commands/yolo.md +0 -82
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* 1. PreCompact (auto) - escalating response by compaction count:
|
|
9
9
|
* 1st: inform (context still good after one compaction)
|
|
10
10
|
* 2nd: strongly urge handoff (summary-of-summary, quality degrades)
|
|
11
|
-
* 3rd+:
|
|
11
|
+
* 3rd+: force handoff
|
|
12
12
|
* 2. PostToolUse (Task) - count agent calls, warn at thresholds
|
|
13
|
-
* 3. Stop - if
|
|
13
|
+
* 3. Stop - if heavily compacted, block stop until handoff written
|
|
14
14
|
* </purpose>
|
|
15
15
|
*
|
|
16
16
|
* <triggers>
|
|
@@ -72,16 +72,6 @@ function saveState(projectRoot, state) {
|
|
|
72
72
|
} catch {}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
function isYoloMode(projectRoot) {
|
|
76
|
-
try {
|
|
77
|
-
const statePath = path.join(projectRoot, '.claude', 'yolo-state.json');
|
|
78
|
-
const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
|
|
79
|
-
return state.mode === 'yolo';
|
|
80
|
-
} catch {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
75
|
function handoffRecentlyWritten(projectRoot) {
|
|
86
76
|
const fp = path.join(projectRoot, 'SESSION-HANDOFF.md');
|
|
87
77
|
try {
|
|
@@ -143,7 +133,6 @@ function processHook(data) {
|
|
|
143
133
|
const projectRoot = getProjectRoot();
|
|
144
134
|
const sessionId = data.session_id || '';
|
|
145
135
|
const state = loadState(projectRoot, sessionId);
|
|
146
|
-
const yolo = isYoloMode(projectRoot);
|
|
147
136
|
const event = data.hook_event_name;
|
|
148
137
|
_hookEvent = event; // Set for allow/block output formatting
|
|
149
138
|
|
|
@@ -156,63 +145,28 @@ function processHook(data) {
|
|
|
156
145
|
|
|
157
146
|
// 1st compaction: inform — context is still usable
|
|
158
147
|
if (state.compactCount === 1) {
|
|
159
|
-
|
|
160
|
-
allow(
|
|
161
|
-
`📋 Context compacting (1st time). Still usable.\n\n` +
|
|
162
|
-
`Save progress soon:\n` +
|
|
163
|
-
`1. Update DEVELOPMENT.md with current progress\n` +
|
|
164
|
-
`2. Write SESSION-HANDOFF.md\n` +
|
|
165
|
-
`3. Run /save\n\n` +
|
|
166
|
-
`You can continue working after this compaction.`
|
|
167
|
-
);
|
|
168
|
-
} else {
|
|
169
|
-
allow(`📋 Context compacting (1st time). Context is still good — consider running /handoff soon to preserve state.`);
|
|
170
|
-
}
|
|
148
|
+
allow(`📋 Context compacting (1st time). Context is still good — consider running /handoff soon to preserve state.`);
|
|
171
149
|
}
|
|
172
150
|
|
|
173
151
|
// 2nd compaction: strongly urge handoff — quality starts degrading
|
|
174
152
|
if (state.compactCount === 2) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
`2. Write SESSION-HANDOFF.md with full current state and next steps\n` +
|
|
181
|
-
`3. Run /save "Handoff: 2nd compaction"\n` +
|
|
182
|
-
`4. Tell user: "Context compacted twice. Recommend starting fresh with /recap."\n\n` +
|
|
183
|
-
`Do this BEFORE any other work. After handoff, you may continue but expect degraded recall.`
|
|
184
|
-
);
|
|
185
|
-
} else {
|
|
186
|
-
allow(
|
|
187
|
-
`⚠️ Context compacting for the 2nd time. Earlier details are now a summary-of-a-summary.\n\n` +
|
|
188
|
-
`Strongly recommended: run /handoff now and start a fresh session with /recap.\n` +
|
|
189
|
-
`Continuing risks: forgetting decisions, re-reading files, repeating mistakes.`
|
|
190
|
-
);
|
|
191
|
-
}
|
|
153
|
+
allow(
|
|
154
|
+
`⚠️ Context compacting for the 2nd time. Earlier details are now a summary-of-a-summary.\n\n` +
|
|
155
|
+
`Strongly recommended: run /handoff now and start a fresh session with /recap.\n` +
|
|
156
|
+
`Continuing risks: forgetting decisions, re-reading files, repeating mistakes.`
|
|
157
|
+
);
|
|
192
158
|
}
|
|
193
159
|
|
|
194
160
|
// 3rd+ compaction: force handoff
|
|
195
161
|
if (state.compactCount >= 3) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
`Do NOT continue working. Quality is too degraded.`
|
|
205
|
-
);
|
|
206
|
-
} else {
|
|
207
|
-
allow(
|
|
208
|
-
`🛑 Context compacting for the ${ordinal(state.compactCount)} time — session is significantly degraded.\n\n` +
|
|
209
|
-
`You should run /handoff and start fresh. Continuing will lead to:\n` +
|
|
210
|
-
`- Forgotten decisions and context\n` +
|
|
211
|
-
`- Re-reading files already read\n` +
|
|
212
|
-
`- Potential mistakes from lost context\n\n` +
|
|
213
|
-
`Please run /handoff now.`
|
|
214
|
-
);
|
|
215
|
-
}
|
|
162
|
+
allow(
|
|
163
|
+
`🛑 Context compacting for the ${ordinal(state.compactCount)} time — session is significantly degraded.\n\n` +
|
|
164
|
+
`You should run /handoff and start fresh. Continuing will lead to:\n` +
|
|
165
|
+
`- Forgotten decisions and context\n` +
|
|
166
|
+
`- Re-reading files already read\n` +
|
|
167
|
+
`- Potential mistakes from lost context\n\n` +
|
|
168
|
+
`Please run /handoff now.`
|
|
169
|
+
);
|
|
216
170
|
}
|
|
217
171
|
}
|
|
218
172
|
|
|
@@ -230,30 +184,14 @@ function processHook(data) {
|
|
|
230
184
|
if (state.toolCalls === URGENT_WARNING_CALLS && state.lastWarning !== 'urgent') {
|
|
231
185
|
state.lastWarning = 'urgent';
|
|
232
186
|
saveState(projectRoot, state);
|
|
233
|
-
|
|
234
|
-
if (yolo) {
|
|
235
|
-
allow(
|
|
236
|
-
`⚠️ Context getting full: ${state.toolCalls} agent calls this session.\n\n` +
|
|
237
|
-
`Save progress NOW before auto-compaction hits:\n` +
|
|
238
|
-
`1. Update DEVELOPMENT.md with progress\n` +
|
|
239
|
-
`2. Write SESSION-HANDOFF.md\n` +
|
|
240
|
-
`3. Run /save\n` +
|
|
241
|
-
`Then continue working (or tell user to start fresh).`
|
|
242
|
-
);
|
|
243
|
-
} else {
|
|
244
|
-
allow(`📊 ${state.toolCalls} agent calls this session. Context may be getting full - consider /handoff.`);
|
|
245
|
-
}
|
|
187
|
+
allow(`📊 ${state.toolCalls} agent calls this session. Context may be getting full - consider /handoff.`);
|
|
246
188
|
}
|
|
247
189
|
|
|
248
190
|
// Early warning
|
|
249
191
|
if (state.toolCalls === EARLY_WARNING_CALLS && state.lastWarning === 'none') {
|
|
250
192
|
state.lastWarning = 'early';
|
|
251
193
|
saveState(projectRoot, state);
|
|
252
|
-
|
|
253
|
-
if (yolo) {
|
|
254
|
-
allow(`📊 Context check: ${state.toolCalls} agent calls. Consider saving progress with /save soon.`);
|
|
255
|
-
}
|
|
256
|
-
// Silent in non-yolo mode at early threshold
|
|
194
|
+
allow(`📊 Context check: ${state.toolCalls} agent calls. Consider /handoff soon.`);
|
|
257
195
|
}
|
|
258
196
|
|
|
259
197
|
allow();
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
* SKIPS:
|
|
30
30
|
* - When called from within a subagent (checks agent stack + env vars)
|
|
31
31
|
*
|
|
32
|
-
* NOTE:
|
|
33
|
-
*
|
|
32
|
+
* NOTE: File read/write suggestions are ALWAYS soft (allow + message).
|
|
33
|
+
* Only MCP write tools and built-in agent types are hard-blocked.
|
|
34
34
|
*
|
|
35
35
|
* Hook type: PreToolUse
|
|
36
36
|
*/
|
|
@@ -132,33 +132,9 @@ const FILE_PATTERN_AGENTS = {
|
|
|
132
132
|
'.claude/skills/': 'agent-ada-skill-builder',
|
|
133
133
|
};
|
|
134
134
|
|
|
135
|
-
//
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const statePath = path.join(process.env.CLAUDE_PROJECT_DIR || process.cwd(), '.claude', 'yolo-state.json');
|
|
139
|
-
const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
|
|
140
|
-
_isYolo = state.mode === 'yolo';
|
|
141
|
-
} catch {}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* In normal mode: soft suggestion (allow + message)
|
|
145
|
-
* In yolo mode: hard block (force delegation)
|
|
146
|
-
*
|
|
147
|
-
* Yolo means "autonomous via agents", not "orchestrator does everything".
|
|
148
|
-
*/
|
|
149
|
-
function suggest(message, agentHint) {
|
|
150
|
-
if (_isYolo) {
|
|
151
|
-
console.log(JSON.stringify({
|
|
152
|
-
decision: "block",
|
|
153
|
-
reason: `🚫 YOLO DELEGATION: In autonomous mode, delegate to agents.\n\n${message}${agentHint ? `\n\nDelegate to: ${agentHint}` : ''}`,
|
|
154
|
-
}));
|
|
155
|
-
} else {
|
|
156
|
-
console.log(JSON.stringify({
|
|
157
|
-
decision: "allow",
|
|
158
|
-
message: message,
|
|
159
|
-
}));
|
|
160
|
-
}
|
|
161
|
-
}
|
|
135
|
+
// All file read/write suggestions always allow with a soft message.
|
|
136
|
+
// Only MCP write tools (create_activity, update_activity, install_workflow)
|
|
137
|
+
// and built-in agent types are hard-blocked.
|
|
162
138
|
|
|
163
139
|
// Read stdin asynchronously for better cross-platform support
|
|
164
140
|
let stdinData = '';
|
|
@@ -260,7 +236,7 @@ function processInput(input) {
|
|
|
260
236
|
}
|
|
261
237
|
|
|
262
238
|
// SOFT SUGGEST: Glob/Grep code searches - always soft (orchestrator needs these for delegation)
|
|
263
|
-
// These are orchestration tools, not domain work - never block
|
|
239
|
+
// These are orchestration tools, not domain work - never block always
|
|
264
240
|
if (tool_name === 'Glob' || tool_name === 'Grep') {
|
|
265
241
|
console.log(JSON.stringify({
|
|
266
242
|
decision: "allow",
|
|
@@ -281,7 +257,7 @@ function processInput(input) {
|
|
|
281
257
|
// MCP tools - block writes, suggest for reads
|
|
282
258
|
if (tool_name?.startsWith('mcp__hailer__')) {
|
|
283
259
|
// HARD BLOCK: install_workflow should use SDK, not MCP
|
|
284
|
-
// Enforced
|
|
260
|
+
// Enforced always mode - delegation is about correctness, not permissions
|
|
285
261
|
if (tool_name === 'mcp__hailer__install_workflow') {
|
|
286
262
|
console.log(JSON.stringify({
|
|
287
263
|
decision: "block",
|
|
@@ -297,7 +273,7 @@ The install_workflow MCP tool is for admin/dev use only.`,
|
|
|
297
273
|
}
|
|
298
274
|
|
|
299
275
|
// HARD BLOCK: Activity writes must go through Dmitri
|
|
300
|
-
// Enforced
|
|
276
|
+
// Enforced always mode - Dmitri validates field formats
|
|
301
277
|
if (tool_name === 'mcp__hailer__create_activity' || tool_name === 'mcp__hailer__update_activity') {
|
|
302
278
|
console.log(JSON.stringify({
|
|
303
279
|
decision: "block",
|
|
@@ -313,7 +289,7 @@ Task(subagent_type="agent-dmitri-activity-crud", prompt='{"task":"create","workf
|
|
|
313
289
|
return;
|
|
314
290
|
}
|
|
315
291
|
|
|
316
|
-
// MCP READ TOOLS: Always allow with soft message (never block,
|
|
292
|
+
// MCP READ TOOLS: Always allow with soft message (never block, always)
|
|
317
293
|
// Subagent detection is unreliable — we can't tell if Viktor or the orchestrator
|
|
318
294
|
// is calling preview_insight. Blocking would break agents using their own tools.
|
|
319
295
|
const suggestedAgent = MCP_TOOL_AGENTS[tool_name];
|
|
@@ -352,15 +328,19 @@ Task(subagent_type="agent-dmitri-activity-crud", prompt='{"task":"create","workf
|
|
|
352
328
|
if (tool_name === 'Read') {
|
|
353
329
|
const filePath = tool_input?.file_path || '';
|
|
354
330
|
|
|
355
|
-
// workspace/ reads -
|
|
331
|
+
// workspace/ reads - ALWAYS ALLOW (never block, always)
|
|
356
332
|
// Multiple specialist agents (Helga, Viktor, Alejandro, Ingrid) need workspace access
|
|
357
|
-
// Subagent detection isn't reliable, so we
|
|
333
|
+
// Subagent detection isn't reliable, so we can't distinguish orchestrator from agents
|
|
358
334
|
if (filePath.includes('workspace/') || filePath.includes('/workspace/')) {
|
|
359
|
-
|
|
335
|
+
console.log(JSON.stringify({
|
|
336
|
+
decision: "allow",
|
|
337
|
+
message: `💡 WORKSPACE READ: If you're the orchestrator, consider delegating to Kenji.\n\nTask(subagent_type="agent-kenji-data-reader", prompt='{"task":"read_workspace_file","path":"${filePath}"}')\n\n(Specialist agents like Helga/Viktor need direct access - this is just a reminder.)`,
|
|
338
|
+
}));
|
|
360
339
|
return;
|
|
361
340
|
}
|
|
362
341
|
|
|
363
|
-
// Other file patterns -
|
|
342
|
+
// Other file patterns - ALWAYS ALLOW reads (never block, always)
|
|
343
|
+
// Agents need to read files in their domain (Giuseppe reads apps/, etc.)
|
|
364
344
|
for (const [pattern, agent] of Object.entries(FILE_PATTERN_AGENTS)) {
|
|
365
345
|
if (filePath.includes(pattern) && !pattern.includes('workspace')) {
|
|
366
346
|
const suggestions = {
|
|
@@ -370,7 +350,10 @@ Task(subagent_type="agent-dmitri-activity-crud", prompt='{"task":"create","workf
|
|
|
370
350
|
};
|
|
371
351
|
const suggestion = suggestions[pattern];
|
|
372
352
|
if (suggestion) {
|
|
373
|
-
|
|
353
|
+
console.log(JSON.stringify({
|
|
354
|
+
decision: "allow",
|
|
355
|
+
message: `💡 CONSIDER DELEGATING: ${suggestion}\n\nAgent: ${agent}`,
|
|
356
|
+
}));
|
|
374
357
|
return;
|
|
375
358
|
}
|
|
376
359
|
}
|
|
@@ -378,52 +361,47 @@ Task(subagent_type="agent-dmitri-activity-crud", prompt='{"task":"create","workf
|
|
|
378
361
|
}
|
|
379
362
|
|
|
380
363
|
// SOFT REMIND: Write/Edit on various files
|
|
364
|
+
// ALWAYS ALLOW writes — agents need to write in their domains
|
|
365
|
+
// Subagent detection is unreliable, so blocking writes breaks agents
|
|
381
366
|
if (tool_name === 'Write' || tool_name === 'Edit') {
|
|
382
367
|
const filePath = tool_input?.file_path || '';
|
|
383
368
|
|
|
384
|
-
// WORKSPACE WRITES: Suggest appropriate specialist
|
|
369
|
+
// WORKSPACE WRITES: Suggest appropriate specialist (always allow)
|
|
385
370
|
if (filePath.includes('workspace/')) {
|
|
386
|
-
|
|
371
|
+
let message;
|
|
387
372
|
if (filePath.includes('/functions/')) {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
if (filePath.includes('
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
// Document templates
|
|
399
|
-
if (filePath.includes('/templates/')) {
|
|
400
|
-
suggest(`💡 DOCUMENT TEMPLATES: Use agent-ingrid-doc-templates.\n\nIngrid handles PDF/CSV templates, pdfmake structure, and field mappings.`, 'agent-ingrid-doc-templates');
|
|
401
|
-
return;
|
|
373
|
+
message = `💡 FUNCTION FIELD CODE: If you're the orchestrator, use agent-alejandro-function-fields.`;
|
|
374
|
+
} else if (filePath.includes('fields.ts')) {
|
|
375
|
+
message = `💡 FIELD DEFINITIONS: If you're the orchestrator, use agent-helga-workflow-config for field config, agent-alejandro-function-fields for function code.`;
|
|
376
|
+
} else if (filePath.includes('/templates/')) {
|
|
377
|
+
message = `💡 DOCUMENT TEMPLATES: If you're the orchestrator, use agent-ingrid-doc-templates.`;
|
|
378
|
+
} else if (filePath.includes('insights.ts')) {
|
|
379
|
+
message = `💡 INSIGHTS: If you're the orchestrator, use agent-viktor-sql-insights.`;
|
|
380
|
+
} else {
|
|
381
|
+
message = `💡 WORKSPACE CONFIG: If you're the orchestrator, use agent-helga-workflow-config.`;
|
|
402
382
|
}
|
|
403
|
-
|
|
404
|
-
// Insights
|
|
405
|
-
if (filePath.includes('insights.ts')) {
|
|
406
|
-
suggest(`💡 INSIGHTS: Use agent-viktor-sql-insights.\n\nViktor creates SQL queries, data sources, and insight configurations.`, 'agent-viktor-sql-insights');
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
// General workspace config
|
|
411
|
-
suggest(`💡 WORKSPACE CONFIG: Use agent-helga-workflow-config.\n\nHelga manages workflows, fields, phases via SDK. Knows correct field types and push/pull order.`, 'agent-helga-workflow-config');
|
|
383
|
+
console.log(JSON.stringify({ decision: "allow", message }));
|
|
412
384
|
return;
|
|
413
385
|
}
|
|
414
386
|
|
|
415
|
-
// Suggest delegation for agent/skill modifications
|
|
387
|
+
// Suggest delegation for agent/skill modifications (always allow)
|
|
416
388
|
if (filePath.includes('.claude/agents/')) {
|
|
417
|
-
|
|
389
|
+
console.log(JSON.stringify({
|
|
390
|
+
decision: "allow",
|
|
391
|
+
message: `💡 CONSIDER DELEGATING: Use agent-builder-agent-creator for agent modifications.`,
|
|
392
|
+
}));
|
|
418
393
|
return;
|
|
419
394
|
}
|
|
420
395
|
|
|
421
396
|
if (filePath.includes('.claude/skills/')) {
|
|
422
|
-
|
|
397
|
+
console.log(JSON.stringify({
|
|
398
|
+
decision: "allow",
|
|
399
|
+
message: `💡 CONSIDER DELEGATING: Use agent-ada-skill-builder for skill modifications.`,
|
|
400
|
+
}));
|
|
423
401
|
return;
|
|
424
402
|
}
|
|
425
403
|
|
|
426
|
-
// .claude/ config files - allow
|
|
404
|
+
// .claude/ config files - always allow
|
|
427
405
|
if (filePath.includes('.claude/') && (filePath.endsWith('.json') || filePath.endsWith('.cjs'))) {
|
|
428
406
|
console.log(JSON.stringify({
|
|
429
407
|
decision: "allow",
|
|
@@ -433,17 +411,23 @@ Task(subagent_type="agent-dmitri-activity-crud", prompt='{"task":"create","workf
|
|
|
433
411
|
}
|
|
434
412
|
|
|
435
413
|
if (filePath.includes('apps/') && (filePath.endsWith('.tsx') || filePath.endsWith('.ts'))) {
|
|
436
|
-
|
|
414
|
+
console.log(JSON.stringify({
|
|
415
|
+
decision: "allow",
|
|
416
|
+
message: `💡 CONSIDER DELEGATING: If you're the orchestrator, use agent-giuseppe-app-builder for app code.`,
|
|
417
|
+
}));
|
|
437
418
|
return;
|
|
438
419
|
}
|
|
439
420
|
|
|
440
421
|
// Integration files
|
|
441
422
|
if (filePath.includes('integrations/') || filePath.includes('activity-mover')) {
|
|
442
|
-
|
|
423
|
+
console.log(JSON.stringify({
|
|
424
|
+
decision: "allow",
|
|
425
|
+
message: `💡 INTEGRATIONS: If you're the orchestrator, consider: agent-igor (movers), agent-ivan (monolith), agent-zara (Zapier).`,
|
|
426
|
+
}));
|
|
443
427
|
return;
|
|
444
428
|
}
|
|
445
429
|
|
|
446
|
-
// General .ts/.tsx code edits -
|
|
430
|
+
// General .ts/.tsx code edits - allow with test reminder
|
|
447
431
|
if ((filePath.endsWith('.ts') || filePath.endsWith('.tsx')) &&
|
|
448
432
|
!filePath.includes('workspace/') &&
|
|
449
433
|
!filePath.includes('apps/') &&
|
|
@@ -467,7 +451,10 @@ Task(subagent_type="agent-dmitri-activity-crud", prompt='{"task":"create","workf
|
|
|
467
451
|
if ((agentType.includes('general') || agentType.includes('explore')) &&
|
|
468
452
|
(prompt.includes('bug') || prompt.includes('debug') || prompt.includes('error') ||
|
|
469
453
|
prompt.includes('not working') || prompt.includes('broken') || prompt.includes('why'))) {
|
|
470
|
-
|
|
454
|
+
console.log(JSON.stringify({
|
|
455
|
+
decision: "allow",
|
|
456
|
+
message: `💡 FOR CODE ISSUES: Consider agent-lars-code-inspector for dead code, unused imports, and type errors.`,
|
|
457
|
+
}));
|
|
471
458
|
return;
|
|
472
459
|
}
|
|
473
460
|
}
|
|
@@ -29,18 +29,6 @@
|
|
|
29
29
|
const fs = require('fs');
|
|
30
30
|
const path = require('path');
|
|
31
31
|
|
|
32
|
-
// Skip in yolo mode
|
|
33
|
-
try {
|
|
34
|
-
const statePath = path.join(process.env.CLAUDE_PROJECT_DIR || process.cwd(), '.claude', 'yolo-state.json');
|
|
35
|
-
const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
|
|
36
|
-
if (state.mode === 'yolo') process.exit(0);
|
|
37
|
-
} catch (e) {
|
|
38
|
-
// ENOENT is expected when not in yolo mode - only warn on unexpected errors
|
|
39
|
-
if (e.code !== 'ENOENT' && !e.message.includes('Unexpected')) {
|
|
40
|
-
console.error(`[design-system-lint] Warning: ${e.message}`);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
32
|
// Read hook input from stdin
|
|
45
33
|
let input = '';
|
|
46
34
|
process.stdin.setEncoding('utf8');
|
|
@@ -31,13 +31,6 @@ const path = require('path');
|
|
|
31
31
|
const fs = require('fs');
|
|
32
32
|
const os = require('os');
|
|
33
33
|
|
|
34
|
-
// Skip in yolo mode
|
|
35
|
-
try {
|
|
36
|
-
const statePath = path.join(process.env.CLAUDE_PROJECT_DIR || process.cwd(), '.claude', 'yolo-state.json');
|
|
37
|
-
const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
|
|
38
|
-
if (state.mode === 'yolo') process.exit(0);
|
|
39
|
-
} catch {}
|
|
40
|
-
|
|
41
34
|
const TEMP_DIR = os.tmpdir();
|
|
42
35
|
const TRACKER_DIR = path.join(TEMP_DIR, '.claude-scaffolded-apps');
|
|
43
36
|
|
|
@@ -23,14 +23,6 @@ const os = require('os');
|
|
|
23
23
|
const ALLOW = JSON.stringify({ decision: 'allow' });
|
|
24
24
|
const projectDir = process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
25
25
|
|
|
26
|
-
// --- Yolo mode check ---
|
|
27
|
-
let isYolo = false;
|
|
28
|
-
try {
|
|
29
|
-
const statePath = path.join(projectDir, '.claude', 'yolo-state.json');
|
|
30
|
-
const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
|
|
31
|
-
isYolo = state.mode === 'yolo';
|
|
32
|
-
} catch {}
|
|
33
|
-
|
|
34
26
|
// Skip if stdin is TTY (no piped input)
|
|
35
27
|
if (process.stdin.isTTY) {
|
|
36
28
|
console.log(ALLOW);
|
|
@@ -63,12 +55,10 @@ function processHook(data) {
|
|
|
63
55
|
console.error('[prompt-guard] checkSessionStructure crashed:', e.message);
|
|
64
56
|
}
|
|
65
57
|
|
|
66
|
-
// 2. Interactive mode (every message
|
|
58
|
+
// 2. Interactive mode (every message)
|
|
67
59
|
try {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (interactiveMsg) messages.push(interactiveMsg);
|
|
71
|
-
}
|
|
60
|
+
const interactiveMsg = checkInteractiveMode(data.prompt);
|
|
61
|
+
if (interactiveMsg) messages.push(interactiveMsg);
|
|
72
62
|
} catch (e) {
|
|
73
63
|
console.error('[prompt-guard] checkInteractiveMode crashed:', e.message);
|
|
74
64
|
}
|
|
@@ -78,12 +68,10 @@ function processHook(data) {
|
|
|
78
68
|
console.error('[prompt-guard] Marketplace sync crashed:', e.message);
|
|
79
69
|
}
|
|
80
70
|
|
|
81
|
-
// 4. Git hooks check (once per session
|
|
71
|
+
// 4. Git hooks check (once per session)
|
|
82
72
|
try {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (gitMsg) console.error(gitMsg);
|
|
86
|
-
}
|
|
73
|
+
const gitMsg = checkGitHooks();
|
|
74
|
+
if (gitMsg) console.error(gitMsg);
|
|
87
75
|
} catch (e) {
|
|
88
76
|
console.error('[prompt-guard] checkGitHooks crashed:', e.message);
|
|
89
77
|
}
|
|
@@ -33,16 +33,6 @@
|
|
|
33
33
|
* </workflow>
|
|
34
34
|
*/
|
|
35
35
|
|
|
36
|
-
const fs = require('fs');
|
|
37
|
-
const path = require('path');
|
|
38
|
-
|
|
39
|
-
// Skip in yolo mode
|
|
40
|
-
try {
|
|
41
|
-
const statePath = path.join(process.env.CLAUDE_PROJECT_DIR || process.cwd(), '.claude', 'yolo-state.json');
|
|
42
|
-
const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
|
|
43
|
-
if (state.mode === 'yolo') process.exit(0);
|
|
44
|
-
} catch {}
|
|
45
|
-
|
|
46
36
|
// Skip in subagent context - subagents can't use AskUserQuestion to recover
|
|
47
37
|
if (process.env.CLAUDE_AGENT_ID || process.env.CLAUDE_SUBAGENT) {
|
|
48
38
|
console.log(JSON.stringify({ decision: 'allow' }));
|
|
@@ -39,13 +39,6 @@ const fs = require('fs');
|
|
|
39
39
|
const path = require('path');
|
|
40
40
|
const os = require('os');
|
|
41
41
|
|
|
42
|
-
// Skip in yolo mode
|
|
43
|
-
try {
|
|
44
|
-
const statePath = path.join(process.env.CLAUDE_PROJECT_DIR || process.cwd(), '.claude', 'yolo-state.json');
|
|
45
|
-
const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
|
|
46
|
-
if (state.mode === 'yolo') process.exit(0);
|
|
47
|
-
} catch {}
|
|
48
|
-
|
|
49
42
|
// Skip in subagent context - subagents can't use AskUserQuestion or Bash to recover
|
|
50
43
|
if (process.env.CLAUDE_AGENT_ID || process.env.CLAUDE_SUBAGENT) {
|
|
51
44
|
console.log(JSON.stringify({ decision: 'allow' }));
|
|
@@ -14,24 +14,10 @@ const crypto = require('crypto');
|
|
|
14
14
|
|
|
15
15
|
const ALLOW = JSON.stringify({ decision: 'allow' });
|
|
16
16
|
|
|
17
|
-
// Skip in yolo mode
|
|
18
|
-
try {
|
|
19
|
-
const statePath = path.join(process.env.CLAUDE_PROJECT_DIR || process.cwd(), '.claude', 'yolo-state.json');
|
|
20
|
-
const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
|
|
21
|
-
if (state.mode === 'yolo') { console.log(ALLOW); process.exit(0); }
|
|
22
|
-
} catch (e) {
|
|
23
|
-
// ENOENT is expected when not in yolo mode - only warn on unexpected errors
|
|
24
|
-
if (e.code !== 'ENOENT' && !e.message.includes('Unexpected')) {
|
|
25
|
-
console.error(`[sync-marketplace-agents] Warning: ${e.message}`);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
17
|
const PLUGINS_DIR = path.join(os.homedir(), '.claude', 'plugins', 'marketplaces');
|
|
30
18
|
const INSTALLED_PLUGINS = path.join(os.homedir(), '.claude', 'plugins', 'installed_plugins.json');
|
|
31
19
|
const PROJECT_DIR = process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
32
20
|
const CLAUDE_MD = path.join(PROJECT_DIR, 'CLAUDE.md');
|
|
33
|
-
const PROJECT_SETTINGS = path.join(PROJECT_DIR, '.claude', 'settings.json');
|
|
34
|
-
const USER_SETTINGS = path.join(os.homedir(), '.claude', 'settings.json');
|
|
35
21
|
|
|
36
22
|
// Store sync state in user's home, keyed by project path hash
|
|
37
23
|
const SYNC_STATE_DIR = path.join(os.homedir(), '.claude', 'sync-state');
|