- .claude-plugin/plugin.json v0.1.0 (auto_discover, MIT) - SessionStart hook: thin zero-dep .mjs wrapper (marketplace convention) around scripts/coord-inbox.sh, emitting the additionalContext envelope; always exits 0. Smoke-tested: empty mailbox -> bare continue, pending message -> injected with UNTRUSTED framing. - coord-send skill bundled; examples and description use generic repo names only (coordination metadata never reaches a public surface). - README (English; documents the deliver-until-done lifecycle correctly, review §7), CHANGELOG, LICENSE (MIT), CLAUDE.md, package.json + node --test wrapper around the bash selftest. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HBbjgS5A55RVavoyjJC4FX
42 lines
1.5 KiB
JavaScript
42 lines
1.5 KiB
JavaScript
#!/usr/bin/env node
|
|
// coord - SessionStart hook: inject this repo's pending coordination inbox
|
|
// (directed messages + unseen broadcasts) as additionalContext.
|
|
//
|
|
// Thin Node wrapper (marketplace convention: hooks are .mjs) around the bash
|
|
// engine scripts/coord-inbox.sh, which owns the mailbox semantics and is
|
|
// covered by scripts/coord-selftest.sh. Zero dependencies. Always exits 0 -
|
|
// a broken mailbox must never block a session.
|
|
|
|
import { execFileSync } from 'node:child_process';
|
|
import { basename, dirname, join } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
function emit(context) {
|
|
const out = { continue: true };
|
|
if (context) {
|
|
out.hookSpecificOutput = { hookEventName: 'SessionStart', additionalContext: context };
|
|
}
|
|
process.stdout.write(JSON.stringify(out) + '\n');
|
|
}
|
|
|
|
try {
|
|
const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT
|
|
|| join(dirname(fileURLToPath(import.meta.url)), '..', '..');
|
|
|
|
let repoRoot = '';
|
|
try {
|
|
repoRoot = execFileSync('git', ['rev-parse', '--show-toplevel'],
|
|
{ stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf8' }).trim();
|
|
} catch {
|
|
// not a git repo: fall back to the working directory below
|
|
}
|
|
if (!repoRoot) repoRoot = process.cwd();
|
|
|
|
const inbox = execFileSync('bash',
|
|
[join(pluginRoot, 'scripts', 'coord-inbox.sh'), '--repo', basename(repoRoot)],
|
|
{ stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf8' });
|
|
|
|
emit(inbox.trim() ? '== Repo coordination (unread messages) ==\n' + inbox : '');
|
|
} catch {
|
|
emit('');
|
|
}
|