osborn 0.9.150 → 0.9.151
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/dist/claude-llm.js +74 -5
- package/dist/index.js +5 -1
- package/package.json +1 -1
package/dist/claude-llm.js
CHANGED
|
@@ -14,7 +14,7 @@ import { statusManager } from './status-manager.js';
|
|
|
14
14
|
import { getResearchSystemPrompt, getDirectModeResearchPrompt } from './prompts.js';
|
|
15
15
|
import { getIndexPath } from './summary-index.js';
|
|
16
16
|
import { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
17
|
-
import { join, dirname } from 'node:path';
|
|
17
|
+
import { join, dirname, resolve, basename } from 'node:path';
|
|
18
18
|
import { fileURLToPath } from 'node:url';
|
|
19
19
|
import { homedir } from 'node:os';
|
|
20
20
|
// Directory of this module — used to locate co-located prompt files (e.g., turn-shape reminder).
|
|
@@ -183,6 +183,11 @@ export const NAMED_AGENTS = {
|
|
|
183
183
|
'Gather information the main agent needs to answer the user\'s question or make a decision.',
|
|
184
184
|
'You are a scout — go find things, read them carefully, and report back.',
|
|
185
185
|
'',
|
|
186
|
+
'## Grounding — check the session index first',
|
|
187
|
+
'Before researching, locate the session index (search-index.txt — a compact line-per-message log of this mission, under .claude/projects/<slug>/osb/<session>/; if several exist pick the most recently modified) and Grep it for the topic you are about to investigate. Read ONLY the matching slice, never the whole file.',
|
|
188
|
+
'Purpose: find what has ALREADY been decided, answered, or ruled out so you do not re-research a settled question. If the index already establishes the answer, report that (with the index reference) instead of redoing the work.',
|
|
189
|
+
'If you cannot find the index, proceed normally — this is an optimization, not a hard dependency.',
|
|
190
|
+
'',
|
|
186
191
|
'## How to work',
|
|
187
192
|
'1. Understand what information is needed and why.',
|
|
188
193
|
'2. Search broadly first (Glob, Grep, WebSearch), then read deeply (Read specific files).',
|
|
@@ -278,6 +283,10 @@ export const NAMED_AGENTS = {
|
|
|
278
283
|
'Handle ALL file operations — code, config, documentation, scripts, data files.',
|
|
279
284
|
'You are the only agent that writes. The main agent and reasoner produce plans; you execute them.',
|
|
280
285
|
'',
|
|
286
|
+
'## Grounding — consult the session index (light touch)',
|
|
287
|
+
'Before editing, locate the session index (search-index.txt under .claude/projects/<slug>/osb/<session>/; newest if several) and Grep it ONLY for: (a) the files/symbols you are about to change, and (b) any recorded DECISIONS or known GOTCHAS relevant to this change. Read only the matching lines — do NOT read the whole index (thousands of lines). This is a lighter dose than the reviewer: a targeted lookup.',
|
|
288
|
+
'If a decision or gotcha contradicts your task, STOP and report to the main agent before editing. If you find nothing or no index exists, proceed normally.',
|
|
289
|
+
'',
|
|
281
290
|
'## VERIFY-FIRST workflow (mandatory)',
|
|
282
291
|
'',
|
|
283
292
|
'### Step 1: Verify assumptions',
|
|
@@ -317,7 +326,7 @@ export const NAMED_AGENTS = {
|
|
|
317
326
|
'CI failures, checking compilation errors, verifying that a change did not break anything.',
|
|
318
327
|
'Returns structured pass/fail results with exact output — does NOT edit files.',
|
|
319
328
|
].join(' '),
|
|
320
|
-
tools: ['Bash', 'Read', 'Glob', 'Grep'],
|
|
329
|
+
tools: ['Bash', 'Read', 'Glob', 'Grep', 'Write', 'Edit'],
|
|
321
330
|
model: 'sonnet',
|
|
322
331
|
prompt: [
|
|
323
332
|
'You are Osborn\'s tester agent. Your job is running tests and builds, then reporting results.',
|
|
@@ -326,6 +335,11 @@ export const NAMED_AGENTS = {
|
|
|
326
335
|
'Execute test suites, build commands, and linters. Interpret failures clearly.',
|
|
327
336
|
'You are a quality gate — find out whether the code works, and say exactly what broke.',
|
|
328
337
|
'',
|
|
338
|
+
'## Grounding — consult shared context before writing or running tests',
|
|
339
|
+
'Before deciding what to test, locate the session index (search-index.txt under .claude/projects/<slug>/osb/<session>/; newest if several) and Grep it for the changes/work under test. Also check any project docs and known-issues files (e.g. CONVENTIONS.md, docs/, a known-issues or gotchas doc if present) for: (a) KNOWN ISSUES and gotchas already recorded, and (b) what behavior is ALREADY covered by existing tests.',
|
|
340
|
+
'Purpose: target regression coverage at real GAPS and known-risk areas rather than testing blind or duplicating coverage — and stay IN SYNC with the reviewer, which reads the same sources.',
|
|
341
|
+
'Read only the relevant slice of the index, never the whole file. If you find nothing or no index/docs exist, proceed normally — this is an optimization, not a hard dependency.',
|
|
342
|
+
'',
|
|
329
343
|
'## Backward-compatibility / regression mandate (CRITICAL)',
|
|
330
344
|
'Existing test suites MUST still pass — any pre-existing test that breaks is a BLOCKER; report it as such.',
|
|
331
345
|
'The public API surface (function signatures, exported types, return shapes, behavior) must NOT silently change.',
|
|
@@ -354,6 +368,16 @@ export const NAMED_AGENTS = {
|
|
|
354
368
|
'- REGRESSIONS / COMPAT BREAKS: explicit list of any pre-existing tests that now fail or API changes that could break existing callers — tag each as BLOCKER',
|
|
355
369
|
'- What you checked but found to be unrelated',
|
|
356
370
|
'',
|
|
371
|
+
'## Backward-compatibility testing & building the test library',
|
|
372
|
+
'GROW THE LIBRARY OVER TIME: where coverage is missing for the behavior being verified,',
|
|
373
|
+
'CREATE a targeted regression test so the suite accumulates over time. If NO test suite or',
|
|
374
|
+
'test infrastructure exists yet, establish a MINIMAL one — a single test file plus the',
|
|
375
|
+
'smallest runner wiring needed — do NOT stand up a heavy framework; keep it small and incremental.',
|
|
376
|
+
'',
|
|
377
|
+
'HARD RESTRICTION: you may ONLY write TEST files — files whose names contain `.test.` or `.spec.`,',
|
|
378
|
+
'or files located under a `__tests__/` or `tests/` directory.',
|
|
379
|
+
'NEVER write source, config, or other files. The write-gate enforces this and will deny any non-test path.',
|
|
380
|
+
'',
|
|
357
381
|
'## What NOT to do',
|
|
358
382
|
'- Do NOT edit or write production files — report failures so the writer agent can fix them',
|
|
359
383
|
'- Do NOT run destructive commands (no rm, no git push, no npm publish)',
|
|
@@ -382,6 +406,18 @@ export const NAMED_AGENTS = {
|
|
|
382
406
|
'Turn a vague or large request into a precise, ordered implementation plan the writer can execute',
|
|
383
407
|
'step by step without guessing. You are the bridge between "what" and "how".',
|
|
384
408
|
'',
|
|
409
|
+
'## Grounding — plan against what already exists',
|
|
410
|
+
'Before drafting a plan, locate the session index (search-index.txt under .claude/projects/<slug>/osb/<session>/; newest if several) and Grep it for prior DECISIONS, constraints, and known GOTCHAS relevant to the task. Read only the matching slice, never the whole file.',
|
|
411
|
+
'Purpose: make the plan fit what has already been decided or tried — do not propose an approach the mission already ruled out. If a prior decision conflicts with the obvious plan, surface it in the plan rather than silently contradicting it.',
|
|
412
|
+
'If you cannot find the index, proceed normally.',
|
|
413
|
+
'',
|
|
414
|
+
'## Documentation at delivery milestones',
|
|
415
|
+
'Plans should account for documentation reconciliation at the point work is DELIVERED — when it ships,',
|
|
416
|
+
'goes live, or reaches a release milestone. Include a step (or an explicit note in VERIFY) to check',
|
|
417
|
+
'whether existing documentation still reflects what is changing, and flag it as a task if updates are',
|
|
418
|
+
'needed. Do NOT schedule doc updates for every incremental step; anchor them to the delivery boundary',
|
|
419
|
+
'so documentation stays stable between releases and does not silently drift out of sync when the work ships.',
|
|
420
|
+
'',
|
|
385
421
|
'## How to work',
|
|
386
422
|
'1. Read enough of the codebase to understand the current structure (Glob, Grep, Read).',
|
|
387
423
|
'2. Identify every file that needs to change and why.',
|
|
@@ -439,10 +475,18 @@ export const NAMED_AGENTS = {
|
|
|
439
475
|
'## Maintain documentation',
|
|
440
476
|
'You MAY create and maintain project standards and conventions files. Specifically: adopt an existing',
|
|
441
477
|
'standards doc if one is found, or create one (e.g. CONVENTIONS.md, docs/standards.md) when none exists',
|
|
442
|
-
'and the review reveals patterns worth recording.
|
|
478
|
+
'and the review reveals patterns worth recording.',
|
|
479
|
+
'',
|
|
480
|
+
'WHEN to reconcile docs: at the moment work is being DELIVERED — when a unit of work ships, goes live,',
|
|
481
|
+
'or reaches a release milestone. That is the checkpoint to verify whether existing documentation still',
|
|
482
|
+
'reflects what actually changed and update it if it has drifted. Do NOT update docs on every small',
|
|
483
|
+
'incremental change; wait for the natural delivery boundary so docs stay stable between releases.',
|
|
484
|
+
'Between delivery milestones, note discrepancies as findings in your verdict (MINOR or NIT) rather',
|
|
485
|
+
'than immediately rewriting documentation.',
|
|
486
|
+
'',
|
|
443
487
|
'RESTRICTION: you may ONLY write files with documentation extensions: .md, .markdown, .mdx, .txt, .rst, .adoc.',
|
|
444
|
-
'You must NEVER write
|
|
445
|
-
'
|
|
488
|
+
'You must NEVER write source, config, or executable files — the write gate enforces this at the system',
|
|
489
|
+
'level and will deny any such attempt.',
|
|
446
490
|
'',
|
|
447
491
|
'## Backward-compatibility mandate',
|
|
448
492
|
'For every change, explicitly verify:',
|
|
@@ -453,6 +497,15 @@ export const NAMED_AGENTS = {
|
|
|
453
497
|
'- Existing callers and consumers of the changed code still work',
|
|
454
498
|
'Tag any violation BLOCKER — silent compat breaks are the hardest bugs to catch after the fact.',
|
|
455
499
|
'',
|
|
500
|
+
'## Regression test suite — run and correlate',
|
|
501
|
+
'If a backward-compatibility/regression test suite exists in the project (any test/ or __tests__/',
|
|
502
|
+
'directory, *.test.* or *.spec.* files, or a test script in package.json), RUN IT as part of your',
|
|
503
|
+
'review using Bash. Correlate the results into your verdict:',
|
|
504
|
+
'- A passing suite with no regressions: note it in WHAT IT CHECKED-AND-CLEARED.',
|
|
505
|
+
'- Any pre-existing test that now fails is a BLOCKER — include it as an ISSUES entry tagged BLOCKER.',
|
|
506
|
+
'Do not skip this step when a suite exists; a failing regression test is a hard blocker regardless',
|
|
507
|
+
'of whether the diff looks clean.',
|
|
508
|
+
'',
|
|
456
509
|
'## How to work',
|
|
457
510
|
'0. **Get the diff first (MANDATORY):** Run `git diff HEAD~1 HEAD --stat` then `git diff HEAD~1 HEAD`.',
|
|
458
511
|
' Build your entire review around what ACTUALLY changed — not the writer\'s narrative alone.',
|
|
@@ -1621,6 +1674,22 @@ class ClaudeLLMStream extends llm.LLMStream {
|
|
|
1621
1674
|
console.log(`📝 Reviewer doc write allowed: ${reviewerPath}`);
|
|
1622
1675
|
return { hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'ask' } };
|
|
1623
1676
|
}
|
|
1677
|
+
// Tester agent: ONLY test files allowed — fail closed
|
|
1678
|
+
if (agentType === 'tester') {
|
|
1679
|
+
const testerPath = String(toolInput.file_path || '');
|
|
1680
|
+
const STRICT_TEST_FILE = /\.(test|spec)\.[jt]sx?$/;
|
|
1681
|
+
const resolvedBase = testerPath ? basename(resolve(testerPath)) : '';
|
|
1682
|
+
if (!testerPath || !STRICT_TEST_FILE.test(resolvedBase)) {
|
|
1683
|
+
const reason = testerPath
|
|
1684
|
+
? `Tester write denied: ${testerPath} is not a test file (basename must match .test.ts/tsx/js/jsx or .spec.ts/tsx/js/jsx). Tester may only write test files.`
|
|
1685
|
+
: 'Tester write denied: could not determine target file path. Failing closed.';
|
|
1686
|
+
console.log(`🚫 Tester write blocked: ${testerPath || '(no path)'} — not a test file`);
|
|
1687
|
+
this.#eventEmitter.emit('tool_blocked', { name: toolName, reason });
|
|
1688
|
+
return { hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'deny' }, reason };
|
|
1689
|
+
}
|
|
1690
|
+
console.log(`🧪 Tester test-file write allowed: ${testerPath}`);
|
|
1691
|
+
return { hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'ask' } };
|
|
1692
|
+
}
|
|
1624
1693
|
// All other agents (main, researcher, reasoner, etc.): workspace only
|
|
1625
1694
|
const filePath = String(toolInput.file_path || '');
|
|
1626
1695
|
if (filePath && !filePath.includes('/osb/') && !filePath.includes('.osborn/sessions/') && !filePath.includes('.osborn/research/')) {
|
package/dist/index.js
CHANGED
|
@@ -1496,7 +1496,11 @@ function startApiServer(workingDir, port) {
|
|
|
1496
1496
|
console.error('❌ startCodeServer() from /editor failed:', err);
|
|
1497
1497
|
});
|
|
1498
1498
|
}
|
|
1499
|
-
res.writeHead(200, {
|
|
1499
|
+
res.writeHead(200, {
|
|
1500
|
+
'Content-Type': 'text/html; charset=utf-8',
|
|
1501
|
+
'Cache-Control': 'no-store, must-revalidate',
|
|
1502
|
+
'Pragma': 'no-cache',
|
|
1503
|
+
});
|
|
1500
1504
|
res.end(`<!DOCTYPE html><html><head>
|
|
1501
1505
|
<meta charset="utf-8">
|
|
1502
1506
|
<meta http-equiv="refresh" content="3;url=/editor">
|