feat: add okr plugin v1.0.0 — OKR guidance for Norwegian public sector

Expert OKR guidance based on Google/Doerr methodology, adapted for
4-month tertial cycles and Norwegian government accountability.

Components:
- 8 commands (skriv, kvalitet, kaskade, sporing, møter, innføring, governance, oppsett)
- 5 agents (kvalitetssjekker, kaskadebygger, fremdriftssporer, møtefasilitator, styringsrådgiver)
- 3 hooks (UserPromptSubmit context injection, PreCompact state preservation, Stop reminder)
- 15 reference files covering methodology, governance, meetings, antipatterns
- Linear MCP integration for OKR tracking

Previously in ktg-privat, now open-sourced.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-04-08 13:32:45 +02:00
commit 5078712f0e
42 changed files with 7341 additions and 0 deletions

View file

@ -0,0 +1,45 @@
#!/usr/bin/env node
// inject-okr-context.mjs
// Event: UserPromptSubmit
// Purpose: Inject OKR organization context from .claude/okr.local.md when configured.
// Zero npm dependencies. Target execution: <20ms.
import { readFileSync, existsSync } from 'node:fs';
import { join } from 'node:path';
const configPath = join(process.cwd(), '.claude', 'okr.local.md');
if (!existsSync(configPath)) {
process.exit(0);
}
try {
const content = readFileSync(configPath, 'utf8');
const match = content.match(/^---\n([\s\S]*?)\n---/);
if (!match) process.exit(0);
const fm = match[1];
const get = (key) => {
const m = fm.match(new RegExp(`${key}:\\s*["']?([^"'\\n]+)["']?`));
return m ? m[1].trim() : null;
};
const org = get('navn') || get('name');
const syklus = get('gjeldende') || get('current_cycle');
const sektor = get('sektor') || get('sector');
const linear = fm.includes('aktivert: true') || fm.includes('enabled: true');
if (!org) process.exit(0);
const parts = [`Organisasjon: ${org}`];
if (syklus) parts.push(`Gjeldende syklus: ${syklus}`);
if (sektor) parts.push(`Sektor: ${sektor}`);
if (linear) parts.push('Linear: aktivert');
const systemMessage = `OKR-kontekst (fra .claude/okr.local.md): ${parts.join(', ')}.`;
process.stdout.write(JSON.stringify({ systemMessage }));
} catch {
// Graceful exit on any error — never block the user
process.exit(0);
}