From anchor
Initializes Context Companion session: suggests modules from recent git changes, prompts to load project specs or start fresh, checks and optionally reconciles prior unreconciled sessions.
npx claudepluginhub nraychaudhuri/anchor --plugin anchorThis skill is limited to using the following tools:
Do these things in order. No greeting. No preamble.
Initializes Claude Code sessions by migrating legacy harness files to .claude-harness/, creating missing state files like memory rules and config, and preparing GitHub sync.
Recalls project context via ctx CLI: loads context packet, reads TASKS.md/DECISIONS.md, lists recent sessions, presents structured readback of last session, active tasks, recent decisions, next steps. For memory questions or session starts.
Loads user preferences, session history from today's file, and inbox tasks at session start, after /clear, or on triggers like 'start session'. Activates session documenter and confirms readiness.
Share bugs, ideas, or general feedback.
Do these things in order. No greeting. No preamble.
First, gather module suggestions:
cat .companion/modules.json 2>/dev/null || echo "[]"
git diff --name-only HEAD~5 2>/dev/null
Match changed files to module paths from modules.json to determine suggestions (modules whose paths appear in recent git changes get the ← suggested label).
Use AskUserQuestion:
question: "What are we working on today?"
options: [
"<module> ← suggested", (modules matching recent git files, up to 4)
"<module>", (remaining modules alphabetically)
"Nothing — start fresh"
]
multiSelect: true
uv run python -c "
import json
from pathlib import Path
p = Path('.companion/product.json')
if not p.exists():
print('0')
else:
ref = json.loads(p.read_text())
config = json.loads(Path(ref['config']).read_text())
spec_loc = Path(config['spec_location'])
cp_path = Path(ref['config']).parent / 'reconciled_sessions.json'
checkpoint = json.loads(cp_path.read_text()) if cp_path.exists() else {}
changes_dir = spec_loc / 'openspec' / 'changes'
unreconciled = []
if changes_dir.exists():
for d in changes_dir.iterdir():
if d.is_dir() and d.name not in checkpoint:
if (d / 'incremental.json').exists():
unreconciled.append(d.name)
print(len(unreconciled))
"
If count > 0, use AskUserQuestion:
question: "Found N unreconciled sessions from previous runs. Reconcile now? (merges captured decisions into your canonical spec)"
options: ["Yes, reconcile now", "Skip — I'll do it later"]
If yes, run reconcile:
uv run python ${CLAUDE_SKILL_DIR}/../seed/scripts/reconcile.py \
"$(uv run python -c "import json; print(json.loads(open('.companion/product.json').read())['config'])")" \
.companion/modules.json
If 0 or skip → continue to Step 2.
If "Nothing — start fresh" selected → skip to Step 3.
If modules selected:
uv run python -c "
import json
from pathlib import Path
ref = json.loads(Path('.companion/product.json').read_text())
config = json.loads(Path(ref['config']).read_text())
modules = json.loads(Path('.companion/modules.json').read_text())
module_names = [m['name'] for m in modules]
print(config['spec_location'])
print(','.join(module_names))
"
question: "<module> doesn't exist yet. Create it as a new module?"
options: ["Yes — create it", "Skip — don't load it"]
If yes, ask the user for a one-line description, then create it:
uv run python -c "
import json
from pathlib import Path
modules = json.loads(Path('.companion/modules.json').read_text())
modules.append({'name': '<module>', 'description': '<user description>', 'paths': []})
Path('.companion/modules.json').write_text(json.dumps(modules, indent=2))
# Create skeleton spec
import sys
ref = json.loads(Path('.companion/product.json').read_text())
config = json.loads(Path(ref['config']).read_text())
spec_dir = Path(config['spec_location']) / 'openspec' / 'specs' / '<module>'
spec_dir.mkdir(parents=True, exist_ok=True)
(spec_dir / 'spec.json').write_text(json.dumps({
'module': '<module>',
'summary': '<user description>',
'business_rules': [],
'non_negotiables': [],
'tradeoffs': [],
'conflicts': [],
'lineage': []
}, indent=2))
print('created')
"
For each selected module read:
<spec_location>/openspec/specs/<module-name>/spec.json
Save selected modules to state:
uv run python -c "
import json, sys
from pathlib import Path
state_path = Path('.companion/state.json')
state = json.loads(state_path.read_text()) if state_path.exists() else {}
state['last_loaded_modules'] = sys.argv[1:]
state_path.write_text(json.dumps(state, indent=2))
print('saved')
" <module1> <module2> ...
Loaded: <module names>Now that state.json has the loaded modules, start the sidebar:
bash ${CLAUDE_SKILL_DIR}/scripts/start_sidebar.sh
The sidebar will start with full context already available.
Report what it prints (started / already running).
Done. The spec is loaded in your context and the sidebar is watching.