osborn 0.9.212 → 0.9.213
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/skills/browser-apply/SKILL.md +5 -0
- package/.claude/skills/browser-screen-recorder/SKILL.md +5 -0
- package/.claude/skills/deploy-workflow/SKILL.md +5 -0
- package/.claude/skills/ground-assumptions/SKILL.md +5 -0
- package/.claude/skills/markdown-to-pdf/SKILL.md +5 -0
- package/.claude/skills/meetings/SKILL.md +5 -0
- package/.claude/skills/pdf-to-markdown/SKILL.md +5 -0
- package/.claude/skills/playwright-browser/SKILL.md +5 -0
- package/.claude/skills/recall/SKILL.md +5 -0
- package/.claude/skills/send-media/SKILL.md +5 -0
- package/.claude/skills/shadcn/SKILL.md +5 -0
- package/.claude/skills/slack-readonly/SKILL.md +5 -0
- package/.claude/skills/voice-native-sync/SKILL.md +5 -0
- package/.claude/skills/youtube-transcript/SKILL.md +5 -0
- package/dist/claude-llm.js +84 -6
- package/package.json +1 -1
- package/dist/prompts/skill-learner-prompt.md +0 -46
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: browser-apply
|
|
3
|
+
description: Interactively automate Workday and other multi-step JS-heavy job application forms using Playwright MCP browser tools, filling one page at a time with a screenshot and user confirmation before advancing. Use when applying to a Workday ATS or any staged online job application needing visible, confirmable progress.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Skill: Browser Apply — Step-by-Step Workday Application
|
|
2
7
|
|
|
3
8
|
Automate Workday job applications interactively, one step at a time. Each step takes a screenshot, confirms what's on screen, fills the current page, and waits before proceeding.
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: browser-screen-recorder
|
|
3
|
+
description: Drive any web app in a real browser and record proof — per-action screenshots, video clips, audio capture, DevTools diagnostics, and metrics, with mic synthesis and natural-language clicking. Use as the QA protocol after building or changing any frontend, for debugging web-reachable issues, verifying deployed changes, or reproducing user reports.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Browser Screen Recorder — drive any web app (voice, hands + a brain) and record proof
|
|
2
7
|
|
|
3
8
|
## SKILL IDENTITY
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: deploy-workflow
|
|
3
|
+
description: The end-to-end release procedure for shipping osborn agent changes — build and verify locally, bump the package.json version, push to GitHub, publish to NPM from the Mac, and update the running Sprite from the registry. Use every time code or prompt changes are ready to ship.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Deploy Workflow
|
|
2
7
|
|
|
3
8
|
Use this every time changes are ready to ship.
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ground-assumptions
|
|
3
|
+
description: Treat every load-bearing assumption as a hypothesis to verify against real evidence before recommending an implementation strategy, rather than trusting training-data intuition or "it should work". Use whenever the conversation enters a planning, design, or architecture phase, or before making any performance, behavioral, or comparative claim.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Ground Assumptions
|
|
2
7
|
|
|
3
8
|
## SKILL IDENTITY
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: markdown-to-pdf
|
|
3
|
+
description: Export a Markdown document, spec, or research findings as a formatted PDF using md-to-pdf, pandoc, or markdown-pdf, saving the result to the session workspace. Use when the user wants to create or generate a PDF from a Markdown file.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Skill: Markdown to PDF
|
|
2
7
|
|
|
3
8
|
Export Markdown documents as formatted PDF files.
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: meetings
|
|
3
|
+
description: Silently take notes and track TODOs while osborn sits in a live meeting via a Recall.ai bot, and pull transcripts on demand, delegating file and transcript work to the writer sub-agent to avoid the tool-call budget. Use for auto-tagged [MEETING] transcript chunks or when the user asks to grab, summarize, or write notes/todos from a meeting.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Skill: Meetings
|
|
2
7
|
|
|
3
8
|
Silent note-taking and TODO-tracking when osborn is sitting in a live meeting,
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pdf-to-markdown
|
|
3
|
+
description: Convert a PDF document to readable Markdown text using the built-in Read tool, pdf-parse-cli, or pdftotext, preserving headings and tables and saving the result to the session workspace. Use when the user provides a PDF file path and wants to read, search, or work with its contents.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Skill: PDF to Markdown
|
|
2
7
|
|
|
3
8
|
Convert PDF documents to readable Markdown text.
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: playwright-browser
|
|
3
|
+
description: Automate web browser interactions via the @playwright/cli — navigate pages, click buttons and links, fill and submit forms, take screenshots, and extract text or structured data using token-efficient element references. Use to interact with a URL, automate a multi-step web workflow, or test a UI flow.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Skill: Playwright Browser Automation
|
|
2
7
|
|
|
3
8
|
Automate web browser interactions — navigate pages, click buttons, fill forms, take screenshots, and extract content.
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: recall
|
|
3
|
+
description: Query this session's full untruncated history — every message, thinking block, and tool call stored in a per-session SQLite database with keyword and semantic search via the osborn-recall command. Use when you need an earlier decision, file, error, number, or name no longer in context, or to check prior work before acting as a grounded agent.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Recall
|
|
2
7
|
|
|
3
8
|
## SKILL IDENTITY
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: send-media
|
|
3
|
+
description: Upload a local file to the osborn public upload endpoint (Supabase storage) to get a permanent public URL, then render it inline in your next reply as a markdown image or link. Use whenever you have a local screenshot, image, PDF, clip, or log the user should see rather than have described.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# send-media — deliver screenshots, images, and files to the user INLINE in chat
|
|
2
7
|
|
|
3
8
|
> 📅 Last updated: 2026-08-09. Use whenever you have a local file the user should SEE
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: shadcn
|
|
3
|
+
description: Add and configure shadcn/ui components — the copy-paste library built on Radix UI and Tailwind CSS — in a Next.js or React project via the shadcn CLI, including first-time init and adding single or multiple components. Use when the user wants to add UI components like buttons, dialogs, cards, forms, or tables.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Skill: shadcn/ui Components
|
|
2
7
|
|
|
3
8
|
Add and configure shadcn/ui components in a Next.js or React project.
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: slack-readonly
|
|
3
|
+
description: Search and read Slack messages, threads, and channels from the shell via read-only GET calls to the Slack Web API using a SLACK_TOKEN, with no posting, reactions, or edits by design. Use when asked to find, read, or summarize Slack content; refuse any request to send or write.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Slack (read-only) — search and read Slack from the shell
|
|
2
7
|
|
|
3
8
|
> 📅 **Last updated: 2026-08-09.** Recreated from scratch after the Mac data-loss events wiped the
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: voice-native-sync
|
|
3
|
+
description: Sync osborn sessions between the local Mac and cloud machines, starting with a mandatory served-version check that self-updates and aborts on a stale local copy to prevent unresumable-session corruption. Use when uploading or downloading sessions for the voice-native osborn setup.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Voice Native Sync Skill
|
|
2
7
|
|
|
3
8
|
## SKILL IDENTITY
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: youtube-transcript
|
|
3
|
+
description: Fetch a YouTube video's auto-generated English subtitles with yt-dlp, strip the SRT timing markers to clean transcript text, and save it to the session workspace. Use when the user asks to get a transcript, subtitles, captions, or summary from a YouTube video URL.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Skill: YouTube Transcript
|
|
2
7
|
|
|
3
8
|
Fetch and save transcripts from YouTube videos.
|
package/dist/claude-llm.js
CHANGED
|
@@ -199,6 +199,58 @@ function loadAllSkills(_workingDir) {
|
|
|
199
199
|
console.log(`📚 Loaded ${skillMap.size} skill(s) from ${homeSkillsDir}`);
|
|
200
200
|
return `<available-skills>\n${[...skillMap.values()].join('\n\n---\n\n')}\n</available-skills>`;
|
|
201
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Enumerate the agent's CURRENT skills (name + one-line description) from
|
|
204
|
+
* ~/.claude/skills, for injection into the PreCompact instruction. This is the
|
|
205
|
+
* list the compaction model dedupes/merges against so it stops re-emitting
|
|
206
|
+
* duplicate skills every session. Description is taken from YAML frontmatter
|
|
207
|
+
* (`description:`) when present, else the WHEN: line, else the first non-heading
|
|
208
|
+
* line. Returns one `- name: description` per line, or '' if none.
|
|
209
|
+
*/
|
|
210
|
+
function enumerateSkillsForCompaction() {
|
|
211
|
+
const dir = join(homedir(), '.claude', 'skills');
|
|
212
|
+
if (!existsSync(dir))
|
|
213
|
+
return '';
|
|
214
|
+
const lines = [];
|
|
215
|
+
try {
|
|
216
|
+
for (const name of readdirSync(dir).sort()) {
|
|
217
|
+
const file = join(dir, name, 'SKILL.md');
|
|
218
|
+
if (!existsSync(file))
|
|
219
|
+
continue;
|
|
220
|
+
let desc = '';
|
|
221
|
+
try {
|
|
222
|
+
const raw = readFileSync(file, 'utf-8');
|
|
223
|
+
const fm = raw.match(/^---\n([\s\S]*?)\n---/);
|
|
224
|
+
if (fm) {
|
|
225
|
+
const m = fm[1].match(/^description:\s*(.+)$/m);
|
|
226
|
+
if (m)
|
|
227
|
+
desc = m[1].trim();
|
|
228
|
+
}
|
|
229
|
+
if (!desc) {
|
|
230
|
+
const body = raw.replace(/^---\n[\s\S]*?\n---\n?/, '');
|
|
231
|
+
const when = body.match(/^\s*WHEN:\s*(.+)$/mi);
|
|
232
|
+
if (when)
|
|
233
|
+
desc = when[1].trim();
|
|
234
|
+
}
|
|
235
|
+
if (!desc) {
|
|
236
|
+
const body = raw.replace(/^---\n[\s\S]*?\n---\n?/, '');
|
|
237
|
+
const first = body.split('\n').map(l => l.trim()).find(l => l && !l.startsWith('#'));
|
|
238
|
+
desc = first || '(no description)';
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
desc = '(unreadable)';
|
|
243
|
+
}
|
|
244
|
+
if (desc.length > 180)
|
|
245
|
+
desc = desc.slice(0, 177) + '…';
|
|
246
|
+
lines.push(`- ${name}: ${desc}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
console.warn('⚠️ enumerateSkillsForCompaction failed:', err instanceof Error ? err.message : err);
|
|
251
|
+
}
|
|
252
|
+
return lines.join('\n');
|
|
253
|
+
}
|
|
202
254
|
// Compaction threshold: Fable 5 runs a 1M context window, so let sessions use
|
|
203
255
|
// all of it before auto-compacting. autoCompactWindow max is 1_000_000; the SDK
|
|
204
256
|
// reads it from settings.json (settingSources includes 'user'), so merge it into
|
|
@@ -2105,8 +2157,28 @@ class ClaudeLLMStream extends llm.LLMStream {
|
|
|
2105
2157
|
try {
|
|
2106
2158
|
this.#opts.onCompactionEvent?.({ type: 'compaction_started', trigger: input?.trigger });
|
|
2107
2159
|
const instructionPath = join(__claudeLlmDir, 'prompts', 'compact-learnings-instruction.md');
|
|
2108
|
-
const
|
|
2109
|
-
|
|
2160
|
+
const instructionRaw = existsSync(instructionPath) ? readFileSync(instructionPath, 'utf-8') : '';
|
|
2161
|
+
// Populate the EXISTING SKILLS section the instruction .md already refers to
|
|
2162
|
+
// (lines 42 & 55) but that nothing used to fill. Without this, the model is told
|
|
2163
|
+
// to "not re-emit skills already shown" against a list it never received — so it
|
|
2164
|
+
// proliferated duplicates. We hand it the current skill set + an adversarial,
|
|
2165
|
+
// self-critical directive to merge/refine rather than create anew.
|
|
2166
|
+
const existingSkills = enumerateSkillsForCompaction();
|
|
2167
|
+
const skillCount = existingSkills ? existingSkills.split('\n').length : 0;
|
|
2168
|
+
const criticBlock = existingSkills
|
|
2169
|
+
? `\n\n---\n\n=== EXISTING SKILLS (${skillCount}) ===\n`
|
|
2170
|
+
+ `These skills ALREADY EXIST for this user (name: description). Before you emit `
|
|
2171
|
+
+ `SKILL_CANDIDATES or BEHAVIORAL_LEARNINGS, act as an ADVERSARIAL reviewer of your own output:\n`
|
|
2172
|
+
+ `1. If a candidate duplicates or substantially overlaps one below, DO NOT create a new skill — `
|
|
2173
|
+
+ `re-emit it under the EXACT SAME kebab-case name, and only if it needs a substantive update; otherwise omit it.\n`
|
|
2174
|
+
+ `2. Propose a brand-new skill ONLY if nothing below covers it, it was CONFIRMED working this session, `
|
|
2175
|
+
+ `and it generalizes to future sessions on different tasks.\n`
|
|
2176
|
+
+ `3. Prefer merging/refining over proliferating. A small set of sharp, non-overlapping skills is the goal — `
|
|
2177
|
+
+ `reject your own low-signal or one-off candidates.\n\n`
|
|
2178
|
+
+ `${existingSkills}\n`
|
|
2179
|
+
: '';
|
|
2180
|
+
const instruction = instructionRaw + criticBlock;
|
|
2181
|
+
console.log(`🧠 PreCompact: injecting instruction (${instruction.length} chars, ${skillCount} existing skills, trigger=${input?.trigger || 'unknown'})`);
|
|
2110
2182
|
return { systemMessage: instruction };
|
|
2111
2183
|
}
|
|
2112
2184
|
catch (err) {
|
|
@@ -2166,7 +2238,7 @@ class ClaudeLLMStream extends llm.LLMStream {
|
|
|
2166
2238
|
const decPath = join(decFolder, 'SKILL.md');
|
|
2167
2239
|
mkdirSync(decFolder, { recursive: true });
|
|
2168
2240
|
const existing = existsSyncFs(decPath) ? readSyncFs(decPath, 'utf-8') : '';
|
|
2169
|
-
const header = existing ? '' :
|
|
2241
|
+
const header = existing ? '' : `---\nname: decisions\ndescription: "Project-scoped architectural and implementation decisions auto-extracted from compaction summaries; consult before revisiting settled choices."\nmetadata:\n type: learned\n source: postcompact\n---\n\n# Project Decisions\n\nAuto-extracted from compact summaries.\n\n`;
|
|
2170
2242
|
const entry = `\n## ${today} (session ${sessionId.substring(0, 8)})\n${projectLines.join('\n')}\n`;
|
|
2171
2243
|
writeSyncFs(decPath, header + existing + entry, 'utf-8');
|
|
2172
2244
|
console.log(`🧠 PostCompact: appended ${projectLines.length} decision(s) to ${decPath}`);
|
|
@@ -2196,8 +2268,14 @@ class ClaudeLLMStream extends llm.LLMStream {
|
|
|
2196
2268
|
const skillFolder = join(skillDir, '.claude', 'skills', name);
|
|
2197
2269
|
const skillPath = join(skillFolder, 'SKILL.md');
|
|
2198
2270
|
mkdirSync(skillFolder, { recursive: true });
|
|
2199
|
-
|
|
2200
|
-
|
|
2271
|
+
// Emit STANDARD skill format: YAML frontmatter (name + description) so
|
|
2272
|
+
// learned skills conform to the same shape the loader/other agents expect.
|
|
2273
|
+
// Description is derived from the candidate's WHEN: line; JSON.stringify
|
|
2274
|
+
// yields a safely-quoted YAML scalar even when it contains colons/quotes.
|
|
2275
|
+
const whenMatch = body.match(/^\s*WHEN:\s*(.+)$/mi);
|
|
2276
|
+
const desc = (whenMatch ? whenMatch[1].trim() : `Learned procedure: ${name}`).replace(/\s+/g, ' ').slice(0, 200);
|
|
2277
|
+
const frontmatter = `---\nname: ${name}\ndescription: ${JSON.stringify(desc)}\nmetadata:\n type: learned\n source: postcompact\n session: ${sessionId.substring(0, 8)}\n updated: ${today}\n---\n\n`;
|
|
2278
|
+
writeSyncFs(skillPath, frontmatter + `# ${name}\n\n` + body + '\n', 'utf-8');
|
|
2201
2279
|
console.log(`🧠 PostCompact: wrote skill '${name}' to ${skillPath}`);
|
|
2202
2280
|
skillsWritten++;
|
|
2203
2281
|
skillNames.push(name);
|
|
@@ -2216,7 +2294,7 @@ class ClaudeLLMStream extends llm.LLMStream {
|
|
|
2216
2294
|
const skillFolder = join(skillDir, '.claude', 'skills', 'learned-behaviors');
|
|
2217
2295
|
const skillPath = join(skillFolder, 'SKILL.md');
|
|
2218
2296
|
mkdirSync(skillFolder, { recursive: true });
|
|
2219
|
-
const header =
|
|
2297
|
+
const header = `---\nname: learned-behaviors\ndescription: "User corrections, preferences, domain knowledge, effective patterns, and anti-patterns learned across sessions; apply to align with how this user works."\nmetadata:\n type: learned\n source: postcompact\n updated: ${today}\n---\n\n# Learned Behaviors\n\nAuto-extracted from voice sessions via PostCompact.\nLast updated: ${today} | Session: ${sessionId.substring(0, 8)}...\n\n`;
|
|
2220
2298
|
writeSyncFs(skillPath, header + learnings + '\n', 'utf-8');
|
|
2221
2299
|
console.log(`🧠 PostCompact: wrote learned behaviors to ${skillPath} (${learnings.length} chars)`);
|
|
2222
2300
|
skillsWritten++;
|
package/package.json
CHANGED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
You are analyzing a voice AI assistant conversation to extract behavioral learnings that should persist across sessions.
|
|
2
|
-
|
|
3
|
-
The conversation is between a user and "Osborn" — a voice AI thinking partner. Your job is to identify:
|
|
4
|
-
|
|
5
|
-
1. USER CORRECTIONS — things the user explicitly told the agent to stop doing or start doing differently
|
|
6
|
-
2. USER PREFERENCES — recurring patterns in how the user wants to work (tools, approaches, communication style)
|
|
7
|
-
3. DOMAIN KNOWLEDGE — specific technical facts learned during the session (API behaviors, selectors, platform quirks, vendor-specific details)
|
|
8
|
-
4. EFFECTIVE PATTERNS — approaches that worked well and the user confirmed or accepted without pushback
|
|
9
|
-
5. ANTI-PATTERNS — approaches that failed, got the user frustrated, or had to be abandoned
|
|
10
|
-
|
|
11
|
-
For each item, include:
|
|
12
|
-
- The specific learning (concrete, actionable)
|
|
13
|
-
- Brief context for WHY (so future sessions can judge if it still applies)
|
|
14
|
-
- Confidence level: HIGH (user explicitly stated it), MEDIUM (inferred from user behavior), LOW (observed but not confirmed)
|
|
15
|
-
|
|
16
|
-
Output as markdown in this exact format:
|
|
17
|
-
|
|
18
|
-
```markdown
|
|
19
|
-
# Session Learnings — {date}
|
|
20
|
-
|
|
21
|
-
## User Corrections (HIGH confidence)
|
|
22
|
-
- {correction}: {context}
|
|
23
|
-
|
|
24
|
-
## User Preferences (MEDIUM-HIGH confidence)
|
|
25
|
-
- {preference}: {context}
|
|
26
|
-
|
|
27
|
-
## Domain Knowledge Learned (varies)
|
|
28
|
-
- [{confidence}] {fact}: {how it was verified}
|
|
29
|
-
|
|
30
|
-
## Effective Patterns (MEDIUM confidence)
|
|
31
|
-
- {pattern}: {when it worked}
|
|
32
|
-
|
|
33
|
-
## Anti-Patterns to Avoid (HIGH confidence)
|
|
34
|
-
- {anti-pattern}: {what went wrong}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Be SELECTIVE. Only include items that are:
|
|
38
|
-
- Generalizable to future sessions (not one-off task details)
|
|
39
|
-
- Actionable (the agent can actually change behavior based on this)
|
|
40
|
-
- Non-obvious (things the agent wouldn't know from its system prompt alone)
|
|
41
|
-
|
|
42
|
-
Do NOT include:
|
|
43
|
-
- Task-specific details (file paths, variable names, specific code changes)
|
|
44
|
-
- Things already in the system prompt
|
|
45
|
-
- Trivial confirmations or greetings
|
|
46
|
-
- Speculative patterns not grounded in the conversation
|