osborn 0.9.144 → 0.9.146

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/claude-llm.js +74 -0
  2. package/package.json +1 -1
@@ -12,6 +12,7 @@ import { EventEmitter } from 'events';
12
12
  import { saveSessionMetadata, getSessionWorkspace } from './config.js';
13
13
  import { statusManager } from './status-manager.js';
14
14
  import { getResearchSystemPrompt, getDirectModeResearchPrompt } from './prompts.js';
15
+ import { getIndexPath } from './summary-index.js';
15
16
  import { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
16
17
  import { join, dirname } from 'node:path';
17
18
  import { fileURLToPath } from 'node:url';
@@ -1133,9 +1134,13 @@ export class ClaudeLLM extends llm.LLM {
1133
1134
  return;
1134
1135
  this.#dispatchedFor.add(agentId);
1135
1136
  try {
1137
+ const idxPathReviewer = (this.#sessionId && this.#opts.workingDirectory)
1138
+ ? getIndexPath(this.#sessionId, this.#opts.workingDirectory)
1139
+ : null;
1136
1140
  const prompt = [
1137
1141
  'Use the reviewer sub-agent to review this writer output for correctness/spec-adherence/obvious bugs.',
1138
1142
  'End your reply with exactly `VERDICT: ACCEPT` or `VERDICT: REJECT`.',
1143
+ ...(idxPathReviewer ? [`The session index is at ${idxPathReviewer} — you MUST read it before reviewing.`] : []),
1139
1144
  '',
1140
1145
  '<writer_output>',
1141
1146
  writerOutput.slice(0, 8000),
@@ -1148,6 +1153,49 @@ export class ClaudeLLM extends llm.LLM {
1148
1153
  const reviewerOptions = {
1149
1154
  cwd: this.#opts.workingDirectory,
1150
1155
  permissionMode: 'default',
1156
+ systemPrompt: NAMED_AGENTS.reviewer.prompt,
1157
+ allowedTools: ['Read', 'Glob', 'Grep', 'Bash', 'Write', 'Edit'],
1158
+ hooks: {
1159
+ PreToolUse: [
1160
+ {
1161
+ matcher: '.*',
1162
+ hooks: [async (input) => {
1163
+ const toolName = input?.tool_name || 'unknown';
1164
+ const toolInput = input?.tool_input || {};
1165
+ emitter.emit('tool_use', { name: toolName, input: toolInput, agentRole: 'reviewer' });
1166
+ return {};
1167
+ }],
1168
+ },
1169
+ {
1170
+ matcher: '.*',
1171
+ hooks: [async (input) => {
1172
+ const toolName = input?.tool_name || '';
1173
+ const toolInput = input?.tool_input;
1174
+ if ((toolName === 'Write' || toolName === 'Edit' || toolName === 'MultiEdit') &&
1175
+ !/\.(md|markdown|mdx|txt|rst|adoc)$/i.test(String(toolInput?.file_path))) {
1176
+ return {
1177
+ hookSpecificOutput: {
1178
+ hookEventName: 'PreToolUse',
1179
+ permissionDecision: 'deny',
1180
+ },
1181
+ reason: 'reviewer may only write documentation files (.md/.markdown/.mdx/.txt/.rst/.adoc)',
1182
+ };
1183
+ }
1184
+ return {};
1185
+ }],
1186
+ },
1187
+ ],
1188
+ PostToolUse: [{
1189
+ matcher: '.*',
1190
+ hooks: [async (input) => {
1191
+ const toolName = input?.tool_name || 'unknown';
1192
+ const toolInput = input?.tool_input || {};
1193
+ const toolResponse = input?.tool_response;
1194
+ emitter.emit('tool_result', { name: toolName, input: toolInput, response: toolResponse, agentRole: 'reviewer' });
1195
+ return {};
1196
+ }],
1197
+ }],
1198
+ },
1151
1199
  };
1152
1200
  console.log(`[DISPATCH] spawning reviewer for agentId=${agentId.slice(0, 8)}`);
1153
1201
  const reviewerQuery = query({ prompt, options: reviewerOptions });
@@ -1190,10 +1238,14 @@ export class ClaudeLLM extends llm.LLM {
1190
1238
  return;
1191
1239
  this.#dispatchedFor.add(agentId);
1192
1240
  try {
1241
+ const idxPathGate = (this.#sessionId && this.#opts.workingDirectory)
1242
+ ? getIndexPath(this.#sessionId, this.#opts.workingDirectory)
1243
+ : null;
1193
1244
  const prompt = [
1194
1245
  'Use the reasoner sub-agent to vet this research output.',
1195
1246
  'Determine whether the research is sufficient to answer the original question.',
1196
1247
  'End your reply with exactly `GATE: PASS` or `GATE: NEEDS-MORE`.',
1248
+ ...(idxPathGate ? [`The session index is at ${idxPathGate} — you MUST read it before reviewing.`] : []),
1197
1249
  '',
1198
1250
  '<research_output>',
1199
1251
  researchOutput.slice(0, 8000),
@@ -1206,6 +1258,28 @@ export class ClaudeLLM extends llm.LLM {
1206
1258
  const gateOptions = {
1207
1259
  cwd: this.#opts.workingDirectory,
1208
1260
  permissionMode: 'default',
1261
+ systemPrompt: NAMED_AGENTS.reasoner.prompt,
1262
+ hooks: {
1263
+ PreToolUse: [{
1264
+ matcher: '.*',
1265
+ hooks: [async (input) => {
1266
+ const toolName = input?.tool_name || 'unknown';
1267
+ const toolInput = input?.tool_input || {};
1268
+ emitter.emit('tool_use', { name: toolName, input: toolInput, agentRole: 'reasoner' });
1269
+ return {};
1270
+ }],
1271
+ }],
1272
+ PostToolUse: [{
1273
+ matcher: '.*',
1274
+ hooks: [async (input) => {
1275
+ const toolName = input?.tool_name || 'unknown';
1276
+ const toolInput = input?.tool_input || {};
1277
+ const toolResponse = input?.tool_response;
1278
+ emitter.emit('tool_result', { name: toolName, input: toolInput, response: toolResponse, agentRole: 'reasoner' });
1279
+ return {};
1280
+ }],
1281
+ }],
1282
+ },
1209
1283
  };
1210
1284
  console.log(`[DISPATCH] spawning research-gate for agentId=${agentId.slice(0, 8)}`);
1211
1285
  const gateQuery = query({ prompt, options: gateOptions });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "osborn",
3
- "version": "0.9.144",
3
+ "version": "0.9.146",
4
4
  "description": "Voice AI coding assistant - local agent that connects to Osborn frontend",
5
5
  "type": "module",
6
6
  "bin": {