oh-my-claude-sisyphus 3.2.3 → 3.3.0
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/README.md +37 -2
- package/agents/scientist-high.md +1003 -0
- package/agents/scientist-low.md +232 -0
- package/agents/scientist.md +1180 -0
- package/bridge/__pycache__/gyoshu_bridge.cpython-310.pyc +0 -0
- package/bridge/gyoshu_bridge.py +846 -0
- package/commands/autopilot.md +51 -3
- package/commands/ralph.md +17 -2
- package/commands/ultrawork.md +18 -1
- package/dist/__tests__/installer.test.js +1 -1
- package/dist/agents/definitions.d.ts +9 -0
- package/dist/agents/definitions.d.ts.map +1 -1
- package/dist/agents/definitions.js +25 -0
- package/dist/agents/definitions.js.map +1 -1
- package/dist/agents/index.d.ts +2 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +2 -1
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/scientist.d.ts +16 -0
- package/dist/agents/scientist.d.ts.map +1 -0
- package/dist/agents/scientist.js +370 -0
- package/dist/agents/scientist.js.map +1 -0
- package/dist/hooks/omc-orchestrator/audit.d.ts +30 -0
- package/dist/hooks/omc-orchestrator/audit.d.ts.map +1 -0
- package/dist/hooks/omc-orchestrator/audit.js +66 -0
- package/dist/hooks/omc-orchestrator/audit.js.map +1 -0
- package/dist/hooks/omc-orchestrator/constants.d.ts +6 -2
- package/dist/hooks/omc-orchestrator/constants.d.ts.map +1 -1
- package/dist/hooks/omc-orchestrator/constants.js +37 -1
- package/dist/hooks/omc-orchestrator/constants.js.map +1 -1
- package/dist/hooks/omc-orchestrator/index.d.ts +4 -0
- package/dist/hooks/omc-orchestrator/index.d.ts.map +1 -1
- package/dist/hooks/omc-orchestrator/index.js +34 -3
- package/dist/hooks/omc-orchestrator/index.js.map +1 -1
- package/dist/installer/hooks.d.ts +18 -0
- package/dist/installer/hooks.d.ts.map +1 -1
- package/dist/installer/hooks.js +24 -0
- package/dist/installer/hooks.js.map +1 -1
- package/dist/installer/index.d.ts +1 -1
- package/dist/installer/index.js +1 -1
- package/dist/lib/atomic-write.d.ts +29 -0
- package/dist/lib/atomic-write.d.ts.map +1 -0
- package/dist/lib/atomic-write.js +111 -0
- package/dist/lib/atomic-write.js.map +1 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +4 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/python-repl/bridge-manager.d.ts +65 -0
- package/dist/tools/python-repl/bridge-manager.d.ts.map +1 -0
- package/dist/tools/python-repl/bridge-manager.js +478 -0
- package/dist/tools/python-repl/bridge-manager.js.map +1 -0
- package/dist/tools/python-repl/index.d.ts +40 -0
- package/dist/tools/python-repl/index.d.ts.map +1 -0
- package/dist/tools/python-repl/index.js +36 -0
- package/dist/tools/python-repl/index.js.map +1 -0
- package/dist/tools/python-repl/paths.d.ts +84 -0
- package/dist/tools/python-repl/paths.d.ts.map +1 -0
- package/dist/tools/python-repl/paths.js +213 -0
- package/dist/tools/python-repl/paths.js.map +1 -0
- package/dist/tools/python-repl/session-lock.d.ts +111 -0
- package/dist/tools/python-repl/session-lock.d.ts.map +1 -0
- package/dist/tools/python-repl/session-lock.js +510 -0
- package/dist/tools/python-repl/session-lock.js.map +1 -0
- package/dist/tools/python-repl/socket-client.d.ts +42 -0
- package/dist/tools/python-repl/socket-client.d.ts.map +1 -0
- package/dist/tools/python-repl/socket-client.js +157 -0
- package/dist/tools/python-repl/socket-client.js.map +1 -0
- package/dist/tools/python-repl/tool.d.ts +100 -0
- package/dist/tools/python-repl/tool.d.ts.map +1 -0
- package/dist/tools/python-repl/tool.js +575 -0
- package/dist/tools/python-repl/tool.js.map +1 -0
- package/dist/tools/python-repl/types.d.ts +95 -0
- package/dist/tools/python-repl/types.d.ts.map +1 -0
- package/dist/tools/python-repl/types.js +2 -0
- package/dist/tools/python-repl/types.js.map +1 -0
- package/docs/CLAUDE.md +31 -0
- package/package.json +2 -1
- package/skills/deepinit/SKILL.md +1 -1
- package/skills/hud/SKILL.md +2 -0
- package/skills/research/SKILL.md +511 -0
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scientist Agent - Data Analysis & Research Execution
|
|
3
|
+
*
|
|
4
|
+
* Specialized agent for executing data analysis workflows using Python.
|
|
5
|
+
* Performs EDA, statistical analysis, and generates actionable findings.
|
|
6
|
+
*
|
|
7
|
+
* Enables:
|
|
8
|
+
* - Exploratory data analysis on CSV, JSON, Parquet files
|
|
9
|
+
* - Statistical computations and hypothesis testing
|
|
10
|
+
* - Data transformations and feature engineering
|
|
11
|
+
* - Generating structured findings with evidence
|
|
12
|
+
*/
|
|
13
|
+
export const SCIENTIST_PROMPT_METADATA = {
|
|
14
|
+
category: 'specialist',
|
|
15
|
+
cost: 'CHEAP',
|
|
16
|
+
promptAlias: 'scientist',
|
|
17
|
+
triggers: [
|
|
18
|
+
{ domain: 'Data analysis', trigger: 'Analyzing datasets and computing statistics' },
|
|
19
|
+
{ domain: 'Research execution', trigger: 'Running data experiments and generating findings' },
|
|
20
|
+
{ domain: 'Python data work', trigger: 'Using pandas, numpy, scipy for data tasks' },
|
|
21
|
+
{ domain: 'EDA', trigger: 'Exploratory data analysis on files' },
|
|
22
|
+
{ domain: 'Hypothesis testing', trigger: 'Statistical tests with confidence intervals and effect sizes' },
|
|
23
|
+
{ domain: 'Research stages', trigger: 'Multi-stage analysis with structured markers' },
|
|
24
|
+
],
|
|
25
|
+
useWhen: [
|
|
26
|
+
'Analyzing CSV, JSON, Parquet, or other data files',
|
|
27
|
+
'Computing descriptive statistics or aggregations',
|
|
28
|
+
'Performing exploratory data analysis (EDA)',
|
|
29
|
+
'Generating data-driven findings and insights',
|
|
30
|
+
'Simple ML tasks like clustering or regression',
|
|
31
|
+
'Data transformations and feature engineering',
|
|
32
|
+
'Generating data analysis reports with visualizations',
|
|
33
|
+
'Hypothesis testing with statistical evidence markers',
|
|
34
|
+
'Research stages with [STAGE:*] markers for orchestration',
|
|
35
|
+
],
|
|
36
|
+
avoidWhen: [
|
|
37
|
+
'Researching external documentation or APIs (use researcher)',
|
|
38
|
+
'Implementing production code features (use executor)',
|
|
39
|
+
'Architecture or system design questions (use architect)',
|
|
40
|
+
'No data files to analyze - just theoretical questions',
|
|
41
|
+
'Web scraping or external data fetching (use researcher)',
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
const SCIENTIST_PROMPT = `<Role>
|
|
45
|
+
Data Analysis & Research Execution Specialist
|
|
46
|
+
|
|
47
|
+
You are a data scientist who EXECUTES Python code to analyze data and generate findings.
|
|
48
|
+
You work with local data files, compute statistics, and produce actionable insights.
|
|
49
|
+
</Role>
|
|
50
|
+
|
|
51
|
+
<Critical_Identity>
|
|
52
|
+
You EXECUTE Python code. You are not advisory.
|
|
53
|
+
|
|
54
|
+
DO NOT:
|
|
55
|
+
- Describe what analysis "could be done"
|
|
56
|
+
- Suggest approaches without running them
|
|
57
|
+
- Provide theoretical explanations without code execution
|
|
58
|
+
|
|
59
|
+
DO:
|
|
60
|
+
- Write Python code and RUN it via Bash
|
|
61
|
+
- Extract concrete numbers, patterns, findings
|
|
62
|
+
- Produce evidence-backed conclusions
|
|
63
|
+
</Critical_Identity>
|
|
64
|
+
|
|
65
|
+
<Tools_Available>
|
|
66
|
+
## What You Have
|
|
67
|
+
- **Read**: Read data files and scripts
|
|
68
|
+
- **Glob**: Find data files by pattern
|
|
69
|
+
- **Grep**: Search for patterns in files
|
|
70
|
+
- **Bash**: Execute Python code and shell commands
|
|
71
|
+
|
|
72
|
+
## What You Do NOT Have
|
|
73
|
+
- **Write/Edit**: You cannot create or modify files directly
|
|
74
|
+
- **Task**: You cannot delegate to other agents
|
|
75
|
+
|
|
76
|
+
## Implication
|
|
77
|
+
All persistent outputs (cleaned data, results) must be created via Python code executed through Bash.
|
|
78
|
+
Use pickle, parquet, or JSON to persist intermediate results.
|
|
79
|
+
</Tools_Available>
|
|
80
|
+
|
|
81
|
+
<Prerequisites_Check>
|
|
82
|
+
## MANDATORY: Check Environment Before Analysis
|
|
83
|
+
|
|
84
|
+
### 1. Verify Python 3.8+ is available
|
|
85
|
+
\`\`\`bash
|
|
86
|
+
python3 --version || python --version
|
|
87
|
+
\`\`\`
|
|
88
|
+
|
|
89
|
+
### 2. Check required packages
|
|
90
|
+
\`\`\`bash
|
|
91
|
+
python3 -c "import pandas; import numpy; print('Core packages OK')" 2>/dev/null || echo "FAIL: Install pandas numpy"
|
|
92
|
+
\`\`\`
|
|
93
|
+
|
|
94
|
+
### 3. Optional packages (check as needed)
|
|
95
|
+
\`\`\`bash
|
|
96
|
+
python3 -c "import scipy; import sklearn; print('Scientific packages OK')" 2>/dev/null || echo "WARNING: scipy/sklearn not available"
|
|
97
|
+
\`\`\`
|
|
98
|
+
|
|
99
|
+
### 4. Verify data file exists
|
|
100
|
+
\`\`\`bash
|
|
101
|
+
ls -la <data-file-path>
|
|
102
|
+
head -5 <data-file-path> # Preview structure
|
|
103
|
+
\`\`\`
|
|
104
|
+
|
|
105
|
+
**Run these checks BEFORE starting analysis to fail fast.**
|
|
106
|
+
</Prerequisites_Check>
|
|
107
|
+
|
|
108
|
+
<Output_Markers>
|
|
109
|
+
## Structured Output Format
|
|
110
|
+
|
|
111
|
+
Use these markers to structure your findings:
|
|
112
|
+
|
|
113
|
+
| Marker | Purpose | Example |
|
|
114
|
+
|--------|---------|---------|
|
|
115
|
+
| \`[OBJECTIVE]\` | What you're analyzing | \`[OBJECTIVE] Identify churn predictors\` |
|
|
116
|
+
| \`[DATA]\` | Data source and shape | \`[DATA] customers.csv: 10,000 rows x 15 cols\` |
|
|
117
|
+
| \`[FINDING]\` | A discovered insight | \`[FINDING] 73% of churned users had <3 logins\` |
|
|
118
|
+
| \`[STAT:correlation]\` | Statistical result | \`[STAT:correlation] tenure vs churn: r=-0.45, p<0.001\` |
|
|
119
|
+
| \`[STAT:distribution]\` | Distribution info | \`[STAT:distribution] age: mean=34.2, std=12.1, skew=0.3\` |
|
|
120
|
+
| \`[STAT:test]\` | Hypothesis test | \`[STAT:test] t-test groups A/B: t=2.34, p=0.019\` |
|
|
121
|
+
| \`[LIMITATION]\` | Caveat or constraint | \`[LIMITATION] 15% missing values in income column\` |
|
|
122
|
+
|
|
123
|
+
### Example Output
|
|
124
|
+
\`\`\`
|
|
125
|
+
[OBJECTIVE] Analyze customer churn patterns
|
|
126
|
+
|
|
127
|
+
[DATA] churn_data.csv: 7,043 rows x 21 columns
|
|
128
|
+
[LIMITATION] 11 rows with missing TotalCharges (0.16%)
|
|
129
|
+
|
|
130
|
+
[FINDING] Month-to-month contracts have 42.7% churn vs 11.3% for 2-year contracts
|
|
131
|
+
[STAT:test] Chi-square test contract vs churn: χ²=849.3, p<0.001
|
|
132
|
+
|
|
133
|
+
[FINDING] Customers without tech support churn at 2.1x the rate of those with support
|
|
134
|
+
[STAT:correlation] TechSupport vs Churn: Cramér's V=0.31
|
|
135
|
+
\`\`\`
|
|
136
|
+
</Output_Markers>
|
|
137
|
+
|
|
138
|
+
<State_Persistence>
|
|
139
|
+
## Persisting Results Between Code Blocks
|
|
140
|
+
|
|
141
|
+
Since you execute discrete Python scripts, persist state to files:
|
|
142
|
+
|
|
143
|
+
### Pickle for DataFrames and objects
|
|
144
|
+
\`\`\`python
|
|
145
|
+
import pickle
|
|
146
|
+
import pandas as pd
|
|
147
|
+
|
|
148
|
+
# Save
|
|
149
|
+
df_cleaned = df.dropna()
|
|
150
|
+
with open('/tmp/analysis_state.pkl', 'wb') as f:
|
|
151
|
+
pickle.dump({'df': df_cleaned, 'stats': stats_dict}, f)
|
|
152
|
+
|
|
153
|
+
# Load in next script
|
|
154
|
+
with open('/tmp/analysis_state.pkl', 'rb') as f:
|
|
155
|
+
state = pickle.load(f)
|
|
156
|
+
df = state['df']
|
|
157
|
+
\`\`\`
|
|
158
|
+
|
|
159
|
+
### Parquet for large DataFrames
|
|
160
|
+
\`\`\`python
|
|
161
|
+
# Save
|
|
162
|
+
df.to_parquet('/tmp/cleaned_data.parquet')
|
|
163
|
+
|
|
164
|
+
# Load
|
|
165
|
+
df = pd.read_parquet('/tmp/cleaned_data.parquet')
|
|
166
|
+
\`\`\`
|
|
167
|
+
|
|
168
|
+
### JSON for simple results
|
|
169
|
+
\`\`\`python
|
|
170
|
+
import json
|
|
171
|
+
|
|
172
|
+
# Save findings
|
|
173
|
+
findings = {'correlation': 0.45, 'significant': True}
|
|
174
|
+
with open('/tmp/findings.json', 'w') as f:
|
|
175
|
+
json.dump(findings, f)
|
|
176
|
+
\`\`\`
|
|
177
|
+
|
|
178
|
+
**Use /tmp/ for ephemeral analysis artifacts.**
|
|
179
|
+
</State_Persistence>
|
|
180
|
+
|
|
181
|
+
<Analysis_Workflow>
|
|
182
|
+
## Four-Phase Analysis Process
|
|
183
|
+
|
|
184
|
+
### Phase 1: Setup
|
|
185
|
+
- Check prerequisites (Python, packages)
|
|
186
|
+
- Locate and validate data files
|
|
187
|
+
- Load data and check shape/dtypes
|
|
188
|
+
|
|
189
|
+
### Phase 2: Explore (EDA)
|
|
190
|
+
- Compute descriptive statistics
|
|
191
|
+
- Check missing values and data quality
|
|
192
|
+
- Identify outliers and distributions
|
|
193
|
+
- Examine relationships between variables
|
|
194
|
+
|
|
195
|
+
### Phase 3: Analyze
|
|
196
|
+
- Run targeted statistical tests
|
|
197
|
+
- Compute correlations and aggregations
|
|
198
|
+
- Build simple models if applicable
|
|
199
|
+
- Generate quantitative findings
|
|
200
|
+
|
|
201
|
+
### Phase 4: Synthesize
|
|
202
|
+
- Compile findings with markers
|
|
203
|
+
- Note limitations and caveats
|
|
204
|
+
- Provide actionable conclusions
|
|
205
|
+
- Suggest next steps if appropriate
|
|
206
|
+
|
|
207
|
+
### Phase 5: Report
|
|
208
|
+
- Generate markdown report in .omc/scientist/reports/
|
|
209
|
+
- Include visualizations saved in .omc/scientist/figures/
|
|
210
|
+
- Executive summary at top
|
|
211
|
+
- Detailed findings with statistics
|
|
212
|
+
- Limitations and recommendations
|
|
213
|
+
</Analysis_Workflow>
|
|
214
|
+
|
|
215
|
+
<Python_Execution_Library>
|
|
216
|
+
## Heredoc Patterns for Python Execution
|
|
217
|
+
|
|
218
|
+
### Basic script execution
|
|
219
|
+
\`\`\`bash
|
|
220
|
+
python3 << 'EOF'
|
|
221
|
+
import pandas as pd
|
|
222
|
+
df = pd.read_csv('/path/to/data.csv')
|
|
223
|
+
print(df.describe())
|
|
224
|
+
EOF
|
|
225
|
+
\`\`\`
|
|
226
|
+
|
|
227
|
+
### With error handling
|
|
228
|
+
\`\`\`bash
|
|
229
|
+
python3 << 'EOF'
|
|
230
|
+
import pandas as pd
|
|
231
|
+
import sys
|
|
232
|
+
|
|
233
|
+
try:
|
|
234
|
+
df = pd.read_csv('/path/to/data.csv')
|
|
235
|
+
print(f"Loaded {len(df)} rows")
|
|
236
|
+
except FileNotFoundError:
|
|
237
|
+
print("ERROR: Data file not found", file=sys.stderr)
|
|
238
|
+
sys.exit(1)
|
|
239
|
+
EOF
|
|
240
|
+
\`\`\`
|
|
241
|
+
|
|
242
|
+
### Multi-file analysis
|
|
243
|
+
\`\`\`bash
|
|
244
|
+
python3 << 'EOF'
|
|
245
|
+
import pandas as pd
|
|
246
|
+
from pathlib import Path
|
|
247
|
+
|
|
248
|
+
data_dir = Path('/path/to/data')
|
|
249
|
+
dfs = []
|
|
250
|
+
for csv_file in data_dir.glob('*.csv'):
|
|
251
|
+
df = pd.read_csv(csv_file)
|
|
252
|
+
df['source'] = csv_file.stem
|
|
253
|
+
dfs.append(df)
|
|
254
|
+
|
|
255
|
+
combined = pd.concat(dfs, ignore_index=True)
|
|
256
|
+
print(f"Combined {len(dfs)} files: {len(combined)} total rows")
|
|
257
|
+
EOF
|
|
258
|
+
\`\`\`
|
|
259
|
+
|
|
260
|
+
### Statistical analysis
|
|
261
|
+
\`\`\`bash
|
|
262
|
+
python3 << 'EOF'
|
|
263
|
+
import pandas as pd
|
|
264
|
+
import numpy as np
|
|
265
|
+
from scipy import stats
|
|
266
|
+
|
|
267
|
+
df = pd.read_csv('/path/to/data.csv')
|
|
268
|
+
|
|
269
|
+
# Correlation
|
|
270
|
+
corr, pval = stats.pearsonr(df['x'], df['y'])
|
|
271
|
+
print(f"[STAT:correlation] x vs y: r={corr:.3f}, p={pval:.4f}")
|
|
272
|
+
|
|
273
|
+
# T-test
|
|
274
|
+
group_a = df[df['group'] == 'A']['value']
|
|
275
|
+
group_b = df[df['group'] == 'B']['value']
|
|
276
|
+
t_stat, p_val = stats.ttest_ind(group_a, group_b)
|
|
277
|
+
print(f"[STAT:test] t-test A vs B: t={t_stat:.2f}, p={p_val:.4f}")
|
|
278
|
+
EOF
|
|
279
|
+
\`\`\`
|
|
280
|
+
</Python_Execution_Library>
|
|
281
|
+
|
|
282
|
+
<Output_Management>
|
|
283
|
+
## Managing Python Output
|
|
284
|
+
|
|
285
|
+
### NEVER dump raw data
|
|
286
|
+
Bad:
|
|
287
|
+
\`\`\`python
|
|
288
|
+
print(df) # Floods output with thousands of rows
|
|
289
|
+
\`\`\`
|
|
290
|
+
|
|
291
|
+
### Use summaries
|
|
292
|
+
Good:
|
|
293
|
+
\`\`\`python
|
|
294
|
+
print(f"Shape: {df.shape}")
|
|
295
|
+
print(f"Columns: {list(df.columns)}")
|
|
296
|
+
print(df.describe())
|
|
297
|
+
print(df.head(10))
|
|
298
|
+
\`\`\`
|
|
299
|
+
|
|
300
|
+
### Aggregate before printing
|
|
301
|
+
\`\`\`python
|
|
302
|
+
# Instead of printing all rows
|
|
303
|
+
summary = df.groupby('category').agg({
|
|
304
|
+
'value': ['mean', 'std', 'count']
|
|
305
|
+
}).round(2)
|
|
306
|
+
print(summary)
|
|
307
|
+
\`\`\`
|
|
308
|
+
|
|
309
|
+
### Limit output size
|
|
310
|
+
\`\`\`python
|
|
311
|
+
# For large value_counts
|
|
312
|
+
print(df['category'].value_counts().head(20))
|
|
313
|
+
|
|
314
|
+
# For correlations
|
|
315
|
+
corr_matrix = df.corr()
|
|
316
|
+
# Show only strong correlations
|
|
317
|
+
strong = corr_matrix[abs(corr_matrix) > 0.5]
|
|
318
|
+
print(strong.stack().dropna())
|
|
319
|
+
\`\`\`
|
|
320
|
+
</Output_Management>
|
|
321
|
+
|
|
322
|
+
<Anti_Patterns>
|
|
323
|
+
NEVER:
|
|
324
|
+
- Describe analysis without executing code
|
|
325
|
+
- Print entire DataFrames to stdout
|
|
326
|
+
- Skip prerequisite checks
|
|
327
|
+
- Ignore missing values without noting them
|
|
328
|
+
- Make claims without statistical evidence
|
|
329
|
+
- Use Write/Edit tools (you don't have them)
|
|
330
|
+
- Assume packages are installed without checking
|
|
331
|
+
|
|
332
|
+
ALWAYS:
|
|
333
|
+
- Execute Python via Bash heredocs
|
|
334
|
+
- Use [MARKERS] for structured findings
|
|
335
|
+
- Report actual numbers with context
|
|
336
|
+
- Note data quality issues as [LIMITATION]
|
|
337
|
+
- Check environment before analysis
|
|
338
|
+
- Persist state via files for multi-step analysis
|
|
339
|
+
</Anti_Patterns>
|
|
340
|
+
|
|
341
|
+
<Quality_Standards>
|
|
342
|
+
## Findings Must Be
|
|
343
|
+
|
|
344
|
+
### Specific
|
|
345
|
+
Bad: "There's a correlation between X and Y"
|
|
346
|
+
Good: "[STAT:correlation] X vs Y: r=0.67, p<0.001, n=1,234"
|
|
347
|
+
|
|
348
|
+
### Actionable
|
|
349
|
+
Bad: "The data shows some patterns"
|
|
350
|
+
Good: "[FINDING] Users with >5 sessions in week 1 have 3.2x higher retention - target onboarding to drive early engagement"
|
|
351
|
+
|
|
352
|
+
### Contextualized
|
|
353
|
+
Bad: "Mean value is 42.5"
|
|
354
|
+
Good: "[STAT:distribution] revenue: mean=$42.50, median=$28.00, std=$67.20 (right-skewed, median more representative)"
|
|
355
|
+
|
|
356
|
+
### Evidence-backed
|
|
357
|
+
Every [FINDING] should reference:
|
|
358
|
+
- Sample size
|
|
359
|
+
- Statistical test or metric
|
|
360
|
+
- Confidence level or p-value where applicable
|
|
361
|
+
</Quality_Standards>`;
|
|
362
|
+
export const scientistAgent = {
|
|
363
|
+
name: 'scientist',
|
|
364
|
+
description: 'Data analysis and research execution specialist. Executes Python code for EDA, statistical analysis, and generating data-driven findings. Works with CSV, JSON, Parquet files using pandas, numpy, scipy.',
|
|
365
|
+
prompt: SCIENTIST_PROMPT,
|
|
366
|
+
tools: ['Read', 'Glob', 'Grep', 'Bash', 'python_repl'],
|
|
367
|
+
model: 'sonnet',
|
|
368
|
+
metadata: SCIENTIST_PROMPT_METADATA
|
|
369
|
+
};
|
|
370
|
+
//# sourceMappingURL=scientist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scientist.js","sourceRoot":"","sources":["../../src/agents/scientist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,MAAM,CAAC,MAAM,yBAAyB,GAAwB;IAC5D,QAAQ,EAAE,YAAY;IACtB,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,WAAW;IACxB,QAAQ,EAAE;QACR,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,6CAA6C,EAAE;QACnF,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,kDAAkD,EAAE;QAC7F,EAAE,MAAM,EAAE,kBAAkB,EAAE,OAAO,EAAE,2CAA2C,EAAE;QACpF,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,oCAAoC,EAAE;QAChE,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,8DAA8D,EAAE;QACzG,EAAE,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,8CAA8C,EAAE;KACvF;IACD,OAAO,EAAE;QACP,mDAAmD;QACnD,kDAAkD;QAClD,4CAA4C;QAC5C,8CAA8C;QAC9C,+CAA+C;QAC/C,8CAA8C;QAC9C,sDAAsD;QACtD,sDAAsD;QACtD,0DAA0D;KAC3D;IACD,SAAS,EAAE;QACT,6DAA6D;QAC7D,sDAAsD;QACtD,yDAAyD;QACzD,uDAAuD;QACvD,yDAAyD;KAC1D;CACF,CAAC;AAEF,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA6TJ,CAAC;AAEtB,MAAM,CAAC,MAAM,cAAc,GAAgB;IACzC,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,2MAA2M;IACxN,MAAM,EAAE,gBAAgB;IACxB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC;IACtD,KAAK,EAAE,QAAQ;IACf,QAAQ,EAAE,yBAAyB;CACpC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit logging for delegation enforcement
|
|
3
|
+
* Logs all Edit/Write operations for analysis
|
|
4
|
+
*/
|
|
5
|
+
export interface AuditEntry {
|
|
6
|
+
timestamp: string;
|
|
7
|
+
tool: string;
|
|
8
|
+
filePath: string;
|
|
9
|
+
decision: 'allowed' | 'warned';
|
|
10
|
+
reason: 'allowed_path' | 'source_file' | 'other';
|
|
11
|
+
sessionId?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Log an audit entry for delegation enforcement
|
|
15
|
+
*/
|
|
16
|
+
export declare function logAuditEntry(entry: Omit<AuditEntry, 'timestamp'>): void;
|
|
17
|
+
/**
|
|
18
|
+
* Read audit log entries (for analysis)
|
|
19
|
+
*/
|
|
20
|
+
export declare function readAuditLog(directory?: string): AuditEntry[];
|
|
21
|
+
/**
|
|
22
|
+
* Get audit summary statistics
|
|
23
|
+
*/
|
|
24
|
+
export declare function getAuditSummary(directory?: string): {
|
|
25
|
+
total: number;
|
|
26
|
+
allowed: number;
|
|
27
|
+
warned: number;
|
|
28
|
+
byExtension: Record<string, number>;
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../../src/hooks/omc-orchestrator/audit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC/B,MAAM,EAAE,cAAc,GAAG,aAAa,GAAG,OAAO,CAAC;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,GAAG,IAAI,CAkBxE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE,CAa7D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC,CAiBA"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit logging for delegation enforcement
|
|
3
|
+
* Logs all Edit/Write operations for analysis
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import * as path from 'path';
|
|
7
|
+
const LOG_DIR = '.omc/logs';
|
|
8
|
+
const LOG_FILE = 'delegation-audit.jsonl';
|
|
9
|
+
/**
|
|
10
|
+
* Log an audit entry for delegation enforcement
|
|
11
|
+
*/
|
|
12
|
+
export function logAuditEntry(entry) {
|
|
13
|
+
try {
|
|
14
|
+
const fullEntry = {
|
|
15
|
+
...entry,
|
|
16
|
+
timestamp: new Date().toISOString(),
|
|
17
|
+
};
|
|
18
|
+
const logDir = path.join(process.cwd(), LOG_DIR);
|
|
19
|
+
const logPath = path.join(logDir, LOG_FILE);
|
|
20
|
+
// Create directory if it doesn't exist
|
|
21
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
22
|
+
// Append entry as JSONL
|
|
23
|
+
fs.appendFileSync(logPath, JSON.stringify(fullEntry) + '\n');
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// Silently fail - audit logging should not break main functionality
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Read audit log entries (for analysis)
|
|
31
|
+
*/
|
|
32
|
+
export function readAuditLog(directory) {
|
|
33
|
+
try {
|
|
34
|
+
const logPath = path.join(directory || process.cwd(), LOG_DIR, LOG_FILE);
|
|
35
|
+
if (!fs.existsSync(logPath))
|
|
36
|
+
return [];
|
|
37
|
+
const content = fs.readFileSync(logPath, 'utf-8');
|
|
38
|
+
return content
|
|
39
|
+
.split('\n')
|
|
40
|
+
.filter(line => line.trim())
|
|
41
|
+
.map(line => JSON.parse(line));
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get audit summary statistics
|
|
49
|
+
*/
|
|
50
|
+
export function getAuditSummary(directory) {
|
|
51
|
+
const entries = readAuditLog(directory);
|
|
52
|
+
const byExtension = {};
|
|
53
|
+
for (const entry of entries) {
|
|
54
|
+
if (entry.decision === 'warned') {
|
|
55
|
+
const ext = path.extname(entry.filePath) || 'unknown';
|
|
56
|
+
byExtension[ext] = (byExtension[ext] || 0) + 1;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
total: entries.length,
|
|
61
|
+
allowed: entries.filter(e => e.decision === 'allowed').length,
|
|
62
|
+
warned: entries.filter(e => e.decision === 'warned').length,
|
|
63
|
+
byExtension,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../../src/hooks/omc-orchestrator/audit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,MAAM,OAAO,GAAG,WAAW,CAAC;AAC5B,MAAM,QAAQ,GAAG,wBAAwB,CAAC;AAW1C;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAoC;IAChE,IAAI,CAAC;QACH,MAAM,SAAS,GAAe;YAC5B,GAAG,KAAK;YACR,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAE5C,uCAAuC;QACvC,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE1C,wBAAwB;QACxB,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,oEAAoE;IACtE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,SAAkB;IAC7C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QACzE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,OAAO,EAAE,CAAC;QAEvC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAClD,OAAO,OAAO;aACX,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;aAC3B,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAe,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,SAAkB;IAMhD,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,WAAW,GAA2B,EAAE,CAAC;IAE/C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC;YACtD,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,MAAM;QACrB,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,MAAM;QAC7D,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,MAAM;QAC3D,WAAW;KACZ,CAAC;AACJ,CAAC"}
|
|
@@ -6,14 +6,18 @@
|
|
|
6
6
|
* Adapted from oh-my-opencode's omc-orchestrator hook.
|
|
7
7
|
*/
|
|
8
8
|
export declare const HOOK_NAME = "omc-orchestrator";
|
|
9
|
-
/**
|
|
9
|
+
/** @deprecated Use ALLOWED_PATH_PATTERNS instead. Legacy single prefix. */
|
|
10
10
|
export declare const ALLOWED_PATH_PREFIX = ".omc/";
|
|
11
|
+
/** Path patterns that orchestrator IS allowed to modify directly */
|
|
12
|
+
export declare const ALLOWED_PATH_PATTERNS: RegExp[];
|
|
13
|
+
/** Source file extensions that should trigger delegation warnings */
|
|
14
|
+
export declare const WARNED_EXTENSIONS: string[];
|
|
11
15
|
/** Tools that perform file modifications */
|
|
12
16
|
export declare const WRITE_EDIT_TOOLS: string[];
|
|
13
17
|
/** Reminder when orchestrator performs direct file work */
|
|
14
18
|
export declare const DIRECT_WORK_REMINDER = "\n\n---\n\n[SYSTEM REMINDER - DELEGATION REQUIRED]\n\nYou just performed direct file modifications outside `.omc/`.\n\n**You are an ORCHESTRATOR, not an IMPLEMENTER.**\n\nAs an orchestrator, you should:\n- **DELEGATE** implementation work to subagents via the Task tool\n- **VERIFY** the work done by subagents\n- **COORDINATE** multiple tasks and ensure completion\n\nYou should NOT:\n- Write code directly (except for `.omc/` files like plans and notepads)\n- Make direct file edits outside `.omc/`\n- Implement features yourself\n\n**If you need to make changes:**\n1. Use the Task tool to delegate to an appropriate subagent\n2. Provide clear instructions in the prompt\n3. Verify the subagent's work after completion\n\n---\n";
|
|
15
19
|
/** Strong warning when orchestrator tries to modify source files */
|
|
16
|
-
export declare const ORCHESTRATOR_DELEGATION_REQUIRED = "\n\n---\n\n[CRITICAL SYSTEM DIRECTIVE - DELEGATION REQUIRED]\n\n**STOP. YOU ARE VIOLATING ORCHESTRATOR PROTOCOL.**\n\nYou (coordinator) are attempting to directly modify a file outside `.omc/`.\n\n**Path attempted:** $FILE_PATH\n\n---\n\n**THIS IS FORBIDDEN** (except for VERIFICATION purposes)\n\nAs an ORCHESTRATOR, you MUST:\n1. **DELEGATE** all implementation work via the Task tool\n2. **VERIFY** the work done by subagents (reading files is OK)\n3. **COORDINATE** - you orchestrate, you don't implement\n\n**ALLOWED direct file operations:**\n- Files inside `.omc/` (plans, notepads, drafts)\n- Reading files for verification\n- Running diagnostics/tests\n\n**FORBIDDEN direct file operations:**\n- Writing/editing source code\n- Creating new files outside `.omc/`\n- Any implementation work\n\n---\n\n**IF THIS IS FOR VERIFICATION:**\nProceed if you are verifying subagent work by making a small fix.\nBut for any substantial changes, USE the Task tool.\n\n**CORRECT APPROACH:**\n```\nTask tool with subagent_type=\"executor\"\nprompt=\"[specific single task with clear acceptance criteria]\"\n```\n\nDELEGATE. DON'T IMPLEMENT.\n\n---\n";
|
|
20
|
+
export declare const ORCHESTRATOR_DELEGATION_REQUIRED = "\n\n---\n\n[CRITICAL SYSTEM DIRECTIVE - DELEGATION REQUIRED]\n\n**STOP. YOU ARE VIOLATING ORCHESTRATOR PROTOCOL.**\n\nYou (coordinator) are attempting to directly modify a file outside `.omc/`.\n\n**Path attempted:** $FILE_PATH\n\n---\n\n**THIS IS FORBIDDEN** (except for VERIFICATION purposes)\n\nAs an ORCHESTRATOR, you MUST:\n1. **DELEGATE** all implementation work via the Task tool\n2. **VERIFY** the work done by subagents (reading files is OK)\n3. **COORDINATE** - you orchestrate, you don't implement\n\n**ALLOWED direct file operations:**\n- Files inside `.omc/` (plans, notepads, drafts)\n- Files inside `~/.claude/` (global config)\n- `CLAUDE.md` and `AGENTS.md` files\n- Reading files for verification\n- Running diagnostics/tests\n\n**FORBIDDEN direct file operations:**\n- Writing/editing source code\n- Creating new files outside `.omc/`\n- Any implementation work\n\n---\n\n**IF THIS IS FOR VERIFICATION:**\nProceed if you are verifying subagent work by making a small fix.\nBut for any substantial changes, USE the Task tool.\n\n**CORRECT APPROACH:**\n```\nTask tool with subagent_type=\"executor\"\nprompt=\"[specific single task with clear acceptance criteria]\"\n```\n\nDELEGATE. DON'T IMPLEMENT.\n\n---\n";
|
|
17
21
|
/** Continuation prompt for boulder state */
|
|
18
22
|
export declare const BOULDER_CONTINUATION_PROMPT = "[SYSTEM REMINDER - BOULDER CONTINUATION]\n\nYou have an active work plan with incomplete tasks. Continue working.\n\nRULES:\n- Proceed without asking for permission\n- Mark each checkbox [x] in the plan file when done\n- Use the notepad at .omc/notepads/{PLAN_NAME}/ to record learnings\n- Do not stop until all tasks are complete\n- If blocked, document the blocker and move to the next task";
|
|
19
23
|
/** Verification reminder for subagent work */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/hooks/omc-orchestrator/constants.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,SAAS,qBAAqB,CAAC;AAE5C,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/hooks/omc-orchestrator/constants.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,SAAS,qBAAqB,CAAC;AAE5C,2EAA2E;AAC3E,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAE3C,oEAAoE;AACpE,eAAO,MAAM,qBAAqB,UAOjC,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,UAuB7B,CAAC;AAEF,4CAA4C;AAC5C,eAAO,MAAM,gBAAgB,UAAqC,CAAC;AAEnE,2DAA2D;AAC3D,eAAO,MAAM,oBAAoB,+tBA0BhC,CAAC;AAEF,oEAAoE;AACpE,eAAO,MAAM,gCAAgC,8sCAgD5C,CAAC;AAEF,4CAA4C;AAC5C,eAAO,MAAM,2BAA2B,6YASqB,CAAC;AAE9D,8CAA8C;AAC9C,eAAO,MAAM,qBAAqB,yfAeU,CAAC;AAE7C,4DAA4D;AAC5D,eAAO,MAAM,qBAAqB,u0BAuBjC,CAAC"}
|
|
@@ -6,8 +6,42 @@
|
|
|
6
6
|
* Adapted from oh-my-opencode's omc-orchestrator hook.
|
|
7
7
|
*/
|
|
8
8
|
export const HOOK_NAME = 'omc-orchestrator';
|
|
9
|
-
/**
|
|
9
|
+
/** @deprecated Use ALLOWED_PATH_PATTERNS instead. Legacy single prefix. */
|
|
10
10
|
export const ALLOWED_PATH_PREFIX = '.omc/';
|
|
11
|
+
/** Path patterns that orchestrator IS allowed to modify directly */
|
|
12
|
+
export const ALLOWED_PATH_PATTERNS = [
|
|
13
|
+
/^\.omc\//, // .omc/**
|
|
14
|
+
/^\.claude\//, // .claude/** (local)
|
|
15
|
+
/^~?\/\.claude\//, // ~/.claude/** (global)
|
|
16
|
+
/\/\.claude\//, // any /.claude/ path
|
|
17
|
+
/CLAUDE\.md$/, // **/CLAUDE.md
|
|
18
|
+
/AGENTS\.md$/, // **/AGENTS.md
|
|
19
|
+
];
|
|
20
|
+
/** Source file extensions that should trigger delegation warnings */
|
|
21
|
+
export const WARNED_EXTENSIONS = [
|
|
22
|
+
// JavaScript/TypeScript
|
|
23
|
+
'.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',
|
|
24
|
+
// Python
|
|
25
|
+
'.py', '.pyw',
|
|
26
|
+
// Go
|
|
27
|
+
'.go',
|
|
28
|
+
// Rust
|
|
29
|
+
'.rs',
|
|
30
|
+
// Java/JVM
|
|
31
|
+
'.java', '.kt', '.scala',
|
|
32
|
+
// C/C++
|
|
33
|
+
'.c', '.cpp', '.cc', '.h', '.hpp',
|
|
34
|
+
// Ruby
|
|
35
|
+
'.rb',
|
|
36
|
+
// PHP
|
|
37
|
+
'.php',
|
|
38
|
+
// Frontend frameworks
|
|
39
|
+
'.svelte', '.vue',
|
|
40
|
+
// GraphQL
|
|
41
|
+
'.graphql', '.gql',
|
|
42
|
+
// Shell
|
|
43
|
+
'.sh', '.bash', '.zsh',
|
|
44
|
+
];
|
|
11
45
|
/** Tools that perform file modifications */
|
|
12
46
|
export const WRITE_EDIT_TOOLS = ['Write', 'Edit', 'write', 'edit'];
|
|
13
47
|
/** Reminder when orchestrator performs direct file work */
|
|
@@ -62,6 +96,8 @@ As an ORCHESTRATOR, you MUST:
|
|
|
62
96
|
|
|
63
97
|
**ALLOWED direct file operations:**
|
|
64
98
|
- Files inside \`.omc/\` (plans, notepads, drafts)
|
|
99
|
+
- Files inside \`~/.claude/\` (global config)
|
|
100
|
+
- \`CLAUDE.md\` and \`AGENTS.md\` files
|
|
65
101
|
- Reading files for verification
|
|
66
102
|
- Running diagnostics/tests
|
|
67
103
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/hooks/omc-orchestrator/constants.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,kBAAkB,CAAC;AAE5C,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/hooks/omc-orchestrator/constants.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,kBAAkB,CAAC;AAE5C,2EAA2E;AAC3E,MAAM,CAAC,MAAM,mBAAmB,GAAG,OAAO,CAAC;AAE3C,oEAAoE;AACpE,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,UAAU,EAAqB,UAAU;IACzC,aAAa,EAAkB,qBAAqB;IACpD,iBAAiB,EAAc,wBAAwB;IACvD,cAAc,EAAiB,qBAAqB;IACpD,aAAa,EAAkB,eAAe;IAC9C,aAAa,EAAkB,eAAe;CAC/C,CAAC;AAEF,qEAAqE;AACrE,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,wBAAwB;IACxB,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC5C,SAAS;IACT,KAAK,EAAE,MAAM;IACb,KAAK;IACL,KAAK;IACL,OAAO;IACP,KAAK;IACL,WAAW;IACX,OAAO,EAAE,KAAK,EAAE,QAAQ;IACxB,QAAQ;IACR,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM;IACjC,OAAO;IACP,KAAK;IACL,MAAM;IACN,MAAM;IACN,sBAAsB;IACtB,SAAS,EAAE,MAAM;IACjB,UAAU;IACV,UAAU,EAAE,MAAM;IAClB,QAAQ;IACR,KAAK,EAAE,OAAO,EAAE,MAAM;CACvB,CAAC;AAEF,4CAA4C;AAC5C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAEnE,2DAA2D;AAC3D,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BnC,CAAC;AAEF,oEAAoE;AACpE,MAAM,CAAC,MAAM,gCAAgC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgD/C,CAAC;AAEF,4CAA4C;AAC5C,MAAM,CAAC,MAAM,2BAA2B,GAAG;;;;;;;;;6DASkB,CAAC;AAE9D,8CAA8C;AAC9C,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;4CAeO,CAAC;AAE7C,4DAA4D;AAC5D,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;CAuBpC,CAAC"}
|
|
@@ -38,6 +38,10 @@ interface GitFileStat {
|
|
|
38
38
|
* Check if a file path is allowed for direct orchestrator modification
|
|
39
39
|
*/
|
|
40
40
|
export declare function isAllowedPath(filePath: string): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Check if a file path is a source file that should trigger delegation warning
|
|
43
|
+
*/
|
|
44
|
+
export declare function isSourceFile(filePath: string): boolean;
|
|
41
45
|
/**
|
|
42
46
|
* Check if a tool is a write/edit tool
|
|
43
47
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/omc-orchestrator/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/omc-orchestrator/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA2BH,cAAc,gBAAgB,CAAC;AAE/B;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;CAC1C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAIvD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAItD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE,CAmDhE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAkC9D;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAapE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAC9C,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAYR;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,MAAM,CAGR;AA2BD;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CA2CrF;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,MAAM,GACb,iBAAiB,CA2DnB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG;IAC3D,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAmBA;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,MAAM;IAE5D;;OAEG;;IAGH;;OAEG;wBACiB,MAAM,aAAa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAQ9D;;OAEG;yBACkB,MAAM,aAAa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,MAAM;IAO/E;;OAEG;;wBAxDW,OAAO;kBACb,MAAM;;IA4Dd;;OAEG;;EAGN"}
|
|
@@ -7,10 +7,12 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Adapted from oh-my-opencode's omc-orchestrator hook for shell-based hooks.
|
|
9
9
|
*/
|
|
10
|
+
import * as path from 'path';
|
|
10
11
|
import { execSync } from 'child_process';
|
|
11
|
-
import { HOOK_NAME,
|
|
12
|
+
import { HOOK_NAME, ALLOWED_PATH_PATTERNS, WARNED_EXTENSIONS, WRITE_EDIT_TOOLS, DIRECT_WORK_REMINDER, ORCHESTRATOR_DELEGATION_REQUIRED, BOULDER_CONTINUATION_PROMPT, VERIFICATION_REMINDER, SINGLE_TASK_DIRECTIVE, } from './constants.js';
|
|
12
13
|
import { readBoulderState, getPlanProgress, } from '../../features/boulder-state/index.js';
|
|
13
14
|
import { addWorkingMemoryEntry, setPriorityContext, } from '../notepad/index.js';
|
|
15
|
+
import { logAuditEntry } from './audit.js';
|
|
14
16
|
// Re-export constants
|
|
15
17
|
export * from './constants.js';
|
|
16
18
|
/**
|
|
@@ -19,7 +21,17 @@ export * from './constants.js';
|
|
|
19
21
|
export function isAllowedPath(filePath) {
|
|
20
22
|
if (!filePath)
|
|
21
23
|
return true;
|
|
22
|
-
|
|
24
|
+
// Check against all allowed patterns
|
|
25
|
+
return ALLOWED_PATH_PATTERNS.some(pattern => pattern.test(filePath));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Check if a file path is a source file that should trigger delegation warning
|
|
29
|
+
*/
|
|
30
|
+
export function isSourceFile(filePath) {
|
|
31
|
+
if (!filePath)
|
|
32
|
+
return false;
|
|
33
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
34
|
+
return WARNED_EXTENSIONS.includes(ext);
|
|
23
35
|
}
|
|
24
36
|
/**
|
|
25
37
|
* Check if a tool is a write/edit tool
|
|
@@ -180,7 +192,7 @@ function processRememberTags(output, directory) {
|
|
|
180
192
|
* Returns warning message if orchestrator tries to modify non-allowed paths
|
|
181
193
|
*/
|
|
182
194
|
export function processOrchestratorPreTool(input) {
|
|
183
|
-
const { toolName, toolInput } = input;
|
|
195
|
+
const { toolName, toolInput, sessionId } = input;
|
|
184
196
|
// Only check write/edit tools
|
|
185
197
|
if (!isWriteEditTool(toolName)) {
|
|
186
198
|
return { continue: true };
|
|
@@ -189,8 +201,27 @@ export function processOrchestratorPreTool(input) {
|
|
|
189
201
|
const filePath = (toolInput?.filePath ?? toolInput?.path ?? toolInput?.file);
|
|
190
202
|
// Allow if path is in allowed prefix
|
|
191
203
|
if (!filePath || isAllowedPath(filePath)) {
|
|
204
|
+
// Log allowed operation
|
|
205
|
+
if (filePath) {
|
|
206
|
+
logAuditEntry({
|
|
207
|
+
tool: toolName,
|
|
208
|
+
filePath,
|
|
209
|
+
decision: 'allowed',
|
|
210
|
+
reason: 'allowed_path',
|
|
211
|
+
sessionId,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
192
214
|
return { continue: true };
|
|
193
215
|
}
|
|
216
|
+
// Log warned operation
|
|
217
|
+
const isSource = isSourceFile(filePath);
|
|
218
|
+
logAuditEntry({
|
|
219
|
+
tool: toolName,
|
|
220
|
+
filePath,
|
|
221
|
+
decision: 'warned',
|
|
222
|
+
reason: isSource ? 'source_file' : 'other',
|
|
223
|
+
sessionId,
|
|
224
|
+
});
|
|
194
225
|
// Inject warning for non-allowed path modifications
|
|
195
226
|
const warning = ORCHESTRATOR_DELEGATION_REQUIRED.replace('$FILE_PATH', filePath);
|
|
196
227
|
return {
|