create-egregore 0.19.32 → 0.20.0
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/assets/egregore-launcher.js +118 -13
- package/bin/cli.js +48 -3
- package/lib/connect-runtime.js +4 -2
- package/lib/local.js +15 -1
- package/lib/prime-runtime.js +208 -0
- package/lib/setup.js +45 -3
- package/package.json +5 -4
- package/runtime/codex/.codex/skills/ingest-notion/SKILL.md +29 -0
- package/runtime/codex/.codex/skills/notion-connect/SKILL.md +29 -0
- package/runtime/codex/.codex/skills/teams-connect/SKILL.md +29 -0
- package/runtime/codex/.codex/spec-manifest.json +3 -3
- package/runtime/codex/AGENTS.md +11 -4
- package/runtime/codex/bin/activity-data.sh +4 -8
- package/runtime/codex/bin/attendant.sh +13 -0
- package/runtime/codex/bin/autosave.sh +27 -1
- package/runtime/codex/bin/codex-render-spec.mjs +6 -0
- package/runtime/codex/bin/codex-session-start.sh +8 -1
- package/runtime/codex/bin/connect-refresh.sh +33 -0
- package/runtime/codex/bin/graph-batch.sh +25 -6
- package/runtime/codex/bin/graph-op.sh +5 -4
- package/runtime/codex/bin/graph.sh +31 -5
- package/runtime/codex/bin/ingest.py +81 -5
- package/runtime/codex/bin/lib/context.sh +26 -1
- package/runtime/codex/bin/lib/greeting.sh +4 -1
- package/runtime/codex/bin/lib/worktree-links.sh +25 -0
- package/runtime/codex/manifest.json +8 -1
- package/runtime/pi/.codex/skills/ingest-notion/SKILL.md +29 -0
- package/runtime/pi/.codex/skills/notion-connect/SKILL.md +29 -0
- package/runtime/pi/.codex/skills/teams-connect/SKILL.md +29 -0
- package/runtime/pi/.codex/spec-manifest.json +3 -3
- package/runtime/pi/.pi/APPEND_SYSTEM.md +3 -2
- package/runtime/pi/.pi/extensions/egregore.ts +17 -6
- package/runtime/pi/.pi/spec-manifest.json +2 -2
- package/runtime/pi/AGENTS.md +11 -4
- package/runtime/pi/bin/activity-data.sh +4 -8
- package/runtime/pi/bin/attendant.sh +13 -0
- package/runtime/pi/bin/autosave.sh +27 -1
- package/runtime/pi/bin/codex-render-spec.mjs +6 -0
- package/runtime/pi/bin/codex-session-start.sh +8 -1
- package/runtime/pi/bin/connect-refresh.sh +33 -0
- package/runtime/pi/bin/graph-batch.sh +25 -6
- package/runtime/pi/bin/graph-op.sh +5 -4
- package/runtime/pi/bin/graph.sh +31 -5
- package/runtime/pi/bin/ingest.py +81 -5
- package/runtime/pi/bin/lib/context.sh +26 -1
- package/runtime/pi/bin/lib/greeting.sh +4 -1
- package/runtime/pi/bin/lib/worktree-links.sh +25 -0
- package/runtime/pi/bin/pi-branch-policy.mjs +138 -1
- package/runtime/pi/bin/pi-product-workflows.mjs +35 -7
- package/runtime/pi/manifest.json +8 -1
- package/runtime/prime/.claude/context/notification-consent.md +66 -0
- package/runtime/prime/.codex/config.toml +17 -0
- package/runtime/prime/.codex/hooks/branch-guard.js +461 -0
- package/runtime/prime/.codex/hooks/search-hint.js +67 -0
- package/runtime/prime/.codex/hooks.json +30 -0
- package/runtime/prime/.codex/skills/activity/SKILL.md +82 -0
- package/runtime/prime/.codex/skills/announce/SKILL.md +67 -0
- package/runtime/prime/.codex/skills/archive/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/branch/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/checkup/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/commit/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/contribute/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/create-skill/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/dark-mode/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/dashboard/SKILL.md +59 -0
- package/runtime/prime/.codex/skills/deep-reflect/SKILL.md +109 -0
- package/runtime/prime/.codex/skills/delete-user/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/emissary/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/handoff/SKILL.md +166 -0
- package/runtime/prime/.codex/skills/harvest/QUESTION_PALETTE.md +76 -0
- package/runtime/prime/.codex/skills/harvest/SKILL.md +131 -0
- package/runtime/prime/.codex/skills/ingest/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/ingest-notion/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/ingest-user-interview/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/invite/SKILL.md +44 -0
- package/runtime/prime/.codex/skills/issue/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/me/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/meeting/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/note/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/notion-connect/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/onboarding/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/pr/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/pull/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/push/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/quest/SKILL.md +80 -0
- package/runtime/prime/.codex/skills/reflect/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/review-pr/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/save/SKILL.md +125 -0
- package/runtime/prime/.codex/skills/slack-connect/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/summon/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/sync-repos/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/teams-connect/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/telegram-connect/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/telemetry/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/test/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/the-spiral/SKILL.md +84 -0
- package/runtime/prime/.codex/skills/tui-design/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/tutorial/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/update/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/view/SKILL.md +156 -0
- package/runtime/prime/.codex/skills/view/agents/openai.yaml +4 -0
- package/runtime/prime/.codex/skills/view/assets/compose-scaffold.html +221 -0
- package/runtime/prime/.codex/skills/visual-explain/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/wrap/SKILL.md +58 -0
- package/runtime/prime/.codex/spec-manifest.json +132 -0
- package/runtime/prime/.prime/agent/APPEND_SYSTEM.md +393 -0
- package/runtime/prime/.prime/agent/extensions/egregore.ts +460 -0
- package/runtime/prime/.prime/agent/settings.json +4 -0
- package/runtime/prime/.prime/agent/skills/egregore/SKILL.md +34 -0
- package/runtime/prime/.prime/agent/skills/egregore/pyproject.toml +13 -0
- package/runtime/prime/.prime/agent/skills/egregore/src/egregore/__init__.py +156 -0
- package/runtime/prime/.prime/agent/spec-manifest.json +12 -0
- package/runtime/prime/AGENTS.md +489 -0
- package/runtime/prime/bin/activity-data.sh +238 -0
- package/runtime/prime/bin/agent.sh +775 -0
- package/runtime/prime/bin/attendant.sh +707 -0
- package/runtime/prime/bin/autosave.sh +112 -0
- package/runtime/prime/bin/capture-reconcile.sh +69 -0
- package/runtime/prime/bin/capture-run.sh +341 -0
- package/runtime/prime/bin/codex-install-skills.sh +78 -0
- package/runtime/prime/bin/codex-render-spec.mjs +440 -0
- package/runtime/prime/bin/codex-session-start.sh +265 -0
- package/runtime/prime/bin/codex-skill-render.mjs +347 -0
- package/runtime/prime/bin/codex-sync-skills.sh +232 -0
- package/runtime/prime/bin/connect-refresh.sh +33 -0
- package/runtime/prime/bin/dashboard-data.sh +178 -0
- package/runtime/prime/bin/graph-batch.sh +79 -0
- package/runtime/prime/bin/graph-op.sh +1102 -0
- package/runtime/prime/bin/graph-wal.sh +229 -0
- package/runtime/prime/bin/graph.sh +223 -0
- package/runtime/prime/bin/handoff-pr-backfill.sh +86 -0
- package/runtime/prime/bin/handoff-run.sh +671 -0
- package/runtime/prime/bin/handoff-save-egregore.sh +212 -0
- package/runtime/prime/bin/index-handoff.sh +322 -0
- package/runtime/prime/bin/ingest-graph.sh +80 -0
- package/runtime/prime/bin/ingest-surface.html +495 -0
- package/runtime/prime/bin/ingest.py +756 -0
- package/runtime/prime/bin/ingest.sh +279 -0
- package/runtime/prime/bin/ingest_graph.py +856 -0
- package/runtime/prime/bin/ingest_surface.py +544 -0
- package/runtime/prime/bin/lib/artifact-id.sh +46 -0
- package/runtime/prime/bin/lib/config.sh +116 -0
- package/runtime/prime/bin/lib/context.sh +621 -0
- package/runtime/prime/bin/lib/dashboard-artifact.sh +242 -0
- package/runtime/prime/bin/lib/ensure-develop.sh +183 -0
- package/runtime/prime/bin/lib/git-sync.sh +406 -0
- package/runtime/prime/bin/lib/greeting.sh +519 -0
- package/runtime/prime/bin/lib/hash.sh +13 -0
- package/runtime/prime/bin/lib/identity.sh +213 -0
- package/runtime/prime/bin/lib/metrics.sh +374 -0
- package/runtime/prime/bin/lib/noncode.sh +31 -0
- package/runtime/prime/bin/lib/permissions.sh +106 -0
- package/runtime/prime/bin/lib/time.sh +56 -0
- package/runtime/prime/bin/lib/worktree-links.sh +79 -0
- package/runtime/prime/bin/notify.sh +636 -0
- package/runtime/prime/bin/person.py +630 -0
- package/runtime/prime/bin/person.sh +448 -0
- package/runtime/prime/bin/pi-branch-policy.mjs +312 -0
- package/runtime/prime/bin/pi-product-workflows.mjs +394 -0
- package/runtime/prime/bin/prime-render-spec.mjs +123 -0
- package/runtime/prime/bin/prime-session-start.sh +24 -0
- package/runtime/prime/bin/publish-artifact.sh +271 -0
- package/runtime/prime/bin/publish-references.sh +144 -0
- package/runtime/prime/bin/repo-state.sh +96 -0
- package/runtime/prime/bin/search.sh +240 -0
- package/runtime/prime/bin/session-autosave.sh +209 -0
- package/runtime/prime/bin/session-log.sh +199 -0
- package/runtime/prime/bin/settings.sh +304 -0
- package/runtime/prime/bin/telemetry.sh +391 -0
- package/runtime/prime/bin/worktree-create.sh +128 -0
- package/runtime/prime/bin/worktree-remove.sh +50 -0
- package/runtime/prime/bin/worktree.sh +198 -0
- package/runtime/prime/manifest.json +178 -0
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Derive the Codex-native Egregore behavioral spec from CLAUDE.md.
|
|
3
|
+
//
|
|
4
|
+
// CLAUDE.md is the single source of truth for egregore behavior. Codex does
|
|
5
|
+
// not read CLAUDE.md — it reads AGENTS.md (root, concatenated, 32 KiB cap).
|
|
6
|
+
// This script renders CLAUDE.md into a generated block inside AGENTS.md the
|
|
7
|
+
// same way bin/codex-sync-skills.sh derives skills: deterministic transform,
|
|
8
|
+
// explicit per-section adaptation, manifest of what was adapted or dropped.
|
|
9
|
+
//
|
|
10
|
+
// node bin/codex-render-spec.mjs # render AGENTS.md + manifest
|
|
11
|
+
// node bin/codex-render-spec.mjs --check # exit 1 if rendered output is stale
|
|
12
|
+
//
|
|
13
|
+
// Adaptation rules (the DECIDED option-b translations):
|
|
14
|
+
// EnterWorktree -> bin/agent.sh branch / git checkout fallback
|
|
15
|
+
// AskUserQuestion -> numbered options in plain text
|
|
16
|
+
// hook-dependent behavior -> .codex/hooks equivalent where it exists,
|
|
17
|
+
// stated as an instruction where it doesn't
|
|
18
|
+
// Claude-only mechanics -> dropped explicitly (recorded in the manifest)
|
|
19
|
+
// /command tokens -> $skill tokens when a Codex skill of that name exists
|
|
20
|
+
//
|
|
21
|
+
// Manifest: .codex/spec-manifest.json — one entry per CLAUDE.md section with
|
|
22
|
+
// action (keep|replace), the source section hash, and a note explaining the
|
|
23
|
+
// translation. `replace` sections embed hand-authored Codex-native bodies;
|
|
24
|
+
// when the source section changes, the recorded hash goes stale and --check
|
|
25
|
+
// fails, forcing a review of the translation.
|
|
26
|
+
|
|
27
|
+
import fs from 'node:fs';
|
|
28
|
+
import path from 'node:path';
|
|
29
|
+
import crypto from 'node:crypto';
|
|
30
|
+
import { fileURLToPath } from 'node:url';
|
|
31
|
+
|
|
32
|
+
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
33
|
+
const CLAUDE_MD = path.join(ROOT, 'CLAUDE.md');
|
|
34
|
+
const AGENTS_MD = path.join(ROOT, 'AGENTS.md');
|
|
35
|
+
const MANIFEST = path.join(ROOT, '.codex', 'spec-manifest.json');
|
|
36
|
+
|
|
37
|
+
const BEGIN = '<!-- BEGIN GENERATED EGREGORE CODEX SPEC — derived from CLAUDE.md by bin/codex-render-spec.mjs; do not edit by hand -->';
|
|
38
|
+
const END = '<!-- END GENERATED EGREGORE CODEX SPEC -->';
|
|
39
|
+
|
|
40
|
+
// Hand-authored top of AGENTS.md, owned by this script so it can never be lost
|
|
41
|
+
// on regeneration. Opens with the runtime-precedence guard: Claude Code reads
|
|
42
|
+
// CLAUDE.md (and now loads root AGENTS.md automatically), so the first thing it
|
|
43
|
+
// must see here is an instruction to defer. Codex / shell-only agents read past
|
|
44
|
+
// the guard into the thin protocol and the generated spec below.
|
|
45
|
+
const AGENTS_PREAMBLE = `# Egregore Agent Protocol
|
|
46
|
+
|
|
47
|
+
> **Runtime precedence — read this first.**
|
|
48
|
+
>
|
|
49
|
+
> **If you are Claude Code** (or any agent that loads \`.claude/\`): **stop here.**
|
|
50
|
+
> Your authoritative instructions are \`CLAUDE.md\` and \`.claude/\`. Follow the
|
|
51
|
+
> SessionStart greeting and the branch-on-first-message rule there. Do **not**
|
|
52
|
+
> follow the startup steps below and do **not** use \`bin/agent.sh\` for work an
|
|
53
|
+
> Egregore skill already covers. This file exists only for runtimes that cannot
|
|
54
|
+
> read \`CLAUDE.md\`.
|
|
55
|
+
>
|
|
56
|
+
> **If you are Pi** (the \`pi\` coding-agent harness): **stop here.** Your
|
|
57
|
+
> authoritative Egregore instructions are loaded from
|
|
58
|
+
> \`.pi/APPEND_SYSTEM.md\`, and your workflows are exposed through the
|
|
59
|
+
> project-local \`.pi/\` runtime. Do not follow the Codex-specific block below.
|
|
60
|
+
>
|
|
61
|
+
> **If you are Prime Agent** (the \`prime-agent\` harness): **stop here.** Your
|
|
62
|
+
> authoritative Egregore instructions are loaded from
|
|
63
|
+
> \`.prime/agent/APPEND_SYSTEM.md\`, and your workflows are exposed through the
|
|
64
|
+
> project-local \`.prime/agent/\` runtime. Do not follow the Codex-specific
|
|
65
|
+
> block below.
|
|
66
|
+
>
|
|
67
|
+
> **If you are Codex or another shell-only agent:** this file is yours — continue.
|
|
68
|
+
|
|
69
|
+
Egregore is no longer only a Claude Code workspace. Claude Code remains the
|
|
70
|
+
first-class integrated runtime through \`.claude/\` and \`CLAUDE.md\`; any other
|
|
71
|
+
agent that can run shell commands in this checkout participates through the
|
|
72
|
+
portable memory protocol below.
|
|
73
|
+
|
|
74
|
+
## Startup
|
|
75
|
+
|
|
76
|
+
1. Read \`egregore.json\` for the instance name, GitHub owner, and managed repos.
|
|
77
|
+
2. Run \`bin/agent.sh sync\` to pull the latest shared memory.
|
|
78
|
+
3. Read \`memory/people/\` to learn collaborator handles.
|
|
79
|
+
4. Run \`bin/agent.sh activity --for <your-handle>\` to inspect handoffs and
|
|
80
|
+
pending questions addressed to you.
|
|
81
|
+
|
|
82
|
+
## Communication
|
|
83
|
+
|
|
84
|
+
Use the runtime-neutral bridge instead of Claude Code slash commands:
|
|
85
|
+
|
|
86
|
+
\`\`\`bash
|
|
87
|
+
bin/agent.sh branch --topic "auth review"
|
|
88
|
+
bin/agent.sh save --message "Save: auth review" --topic "auth review" \\
|
|
89
|
+
--pr-body "$PR_BODY" # body per .claude/context/pr-format.md (auto-skeleton if omitted)
|
|
90
|
+
bin/agent.sh wrap --from alice --topic "auth review" \\
|
|
91
|
+
--summary "Implemented the OAuth callback parser and documented follow-ups." \\
|
|
92
|
+
--body "Open threads: review error cases and browser redirects."
|
|
93
|
+
|
|
94
|
+
bin/agent.sh handoff --from alice --to bob --topic "auth review" \\
|
|
95
|
+
--body "Implemented the OAuth callback parser. Bob should review error cases."
|
|
96
|
+
|
|
97
|
+
bin/agent.sh ask --from bob --to alice --topic "auth review" \\
|
|
98
|
+
--question "Should invalid state redirect to login or return 400?"
|
|
99
|
+
|
|
100
|
+
bin/agent.sh answer --from alice \\
|
|
101
|
+
--question memory/knowledge/questions/2026-04-26-bob-to-alice-auth-review.md \\
|
|
102
|
+
--body "Return 400 in the API path; redirect only in browser routes."
|
|
103
|
+
\`\`\`
|
|
104
|
+
|
|
105
|
+
Each command writes to the existing Git-backed \`memory/\` repository and pushes
|
|
106
|
+
when the memory repo has an \`origin\` remote. Agents that cannot run shell may
|
|
107
|
+
write the same markdown files directly, following \`docs/AGENT-PROTOCOL.md\`.
|
|
108
|
+
|
|
109
|
+
## Handoffs vs Emissaries
|
|
110
|
+
|
|
111
|
+
\`bin/agent.sh handoff\` is the runtime-neutral path for internal team
|
|
112
|
+
session-handoffs: it writes to \`memory/handoffs/\`, updates the index, and uses
|
|
113
|
+
the same \`bin/handoff-run.sh\` machinery as Claude Code's \`/handoff\`.
|
|
114
|
+
|
|
115
|
+
Portable external capsules are **emissaries**, not team handoffs. Claude Code
|
|
116
|
+
routes those through \`/emissary\`; non-Claude agents should use the
|
|
117
|
+
\`egregore-emissary\` CLI/skill when it is installed. Do not use the deprecated
|
|
118
|
+
\`egregore-handoff\` CLI for Egregore project \`/handoff\` work.
|
|
119
|
+
|
|
120
|
+
## Compatibility
|
|
121
|
+
|
|
122
|
+
Claude Code users continue using \`/handoff\`, \`/activity\`, \`/ask\`, \`/save\`, and
|
|
123
|
+
other skills — driven by \`CLAUDE.md\`, not this file. Non-Claude agents use
|
|
124
|
+
\`bin/agent.sh\` and the file protocol, with the full Codex behavioral spec in the
|
|
125
|
+
generated block below. Both paths converge on the same \`memory/\` files.`;
|
|
126
|
+
|
|
127
|
+
function sha(text) {
|
|
128
|
+
return crypto.createHash('sha256').update(text).digest('hex').slice(0, 12);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ── fence-aware section splitter ────────────────────────────────────────
|
|
132
|
+
// Splits markdown into the intro (before the first H2) and one chunk per H2.
|
|
133
|
+
// `## ` lines inside ``` fences do not start sections.
|
|
134
|
+
function splitSections(markdown) {
|
|
135
|
+
const lines = markdown.split('\n');
|
|
136
|
+
const sections = [];
|
|
137
|
+
let current = { heading: '(intro)', body: [] };
|
|
138
|
+
let inFence = false;
|
|
139
|
+
for (const line of lines) {
|
|
140
|
+
if (/^```/.test(line.trim())) inFence = !inFence;
|
|
141
|
+
if (!inFence && /^## /.test(line)) {
|
|
142
|
+
sections.push(current);
|
|
143
|
+
current = { heading: line.replace(/^## /, '').trim(), body: [] };
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
current.body.push(line);
|
|
147
|
+
}
|
|
148
|
+
sections.push(current);
|
|
149
|
+
return sections.map((s) => ({ heading: s.heading, body: s.body.join('\n').replace(/^\n+/, '').replace(/\n+$/, '') }));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ── /command -> $skill token transform (outside code fences) ────────────
|
|
153
|
+
// Deterministic: every backticked /token becomes a $skill token except a
|
|
154
|
+
// static denylist of Claude Code harness features that are not Egregore
|
|
155
|
+
// skills on any runtime. Consulting the local .codex/skills directory here
|
|
156
|
+
// would make the rendered output depend on which instance ran the render
|
|
157
|
+
// (public checkouts carry fewer skills than the source repo).
|
|
158
|
+
const NON_SKILL_TOKENS = new Set(['loop', 'fast', 'config', 'clear', 'help']);
|
|
159
|
+
|
|
160
|
+
function transformTokens(body) {
|
|
161
|
+
const lines = body.split('\n');
|
|
162
|
+
let inFence = false;
|
|
163
|
+
const out = lines.map((line) => {
|
|
164
|
+
if (/^```/.test(line.trim())) {
|
|
165
|
+
inFence = !inFence;
|
|
166
|
+
return line;
|
|
167
|
+
}
|
|
168
|
+
if (inFence) return line;
|
|
169
|
+
return line.replace(/`\/([a-z][a-z0-9-]*)((?: [^`]*)?)`/g, (match, name, args) =>
|
|
170
|
+
NON_SKILL_TOKENS.has(name) ? match : `\`$${name}${args}\``
|
|
171
|
+
);
|
|
172
|
+
});
|
|
173
|
+
return out.join('\n');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ── hand-authored Codex-native section bodies ────────────────────────────
|
|
177
|
+
// Each is the option-b translation of the matching CLAUDE.md section. The
|
|
178
|
+
// manifest records the source hash so drift is caught by --check.
|
|
179
|
+
|
|
180
|
+
const INTRO_BODY = `You are a collaborator inside Egregore — a shared intelligence layer for organizations using AI coding agents. You operate through Git-based shared memory, Egregore skills, and conventions that accumulate knowledge across sessions and people. You are not a tool. You are a participant.
|
|
181
|
+
|
|
182
|
+
This block is the Codex-native Egregore behavioral spec, rendered from CLAUDE.md (the source of truth for egregore behavior) by \`bin/codex-render-spec.mjs\`. The per-section adaptation manifest is \`.codex/spec-manifest.json\`. The thin agent protocol above this block applies to every shell-capable agent; this block is the full behavioral contract for Codex sessions.`;
|
|
183
|
+
|
|
184
|
+
const ON_LAUNCH_BODY = `The \`egregore\` launcher renders the Egregore startup card (identity, team momentum, and pending work) via \`bin/codex-session-start.sh\` before Codex starts, and installs project skills. Do not rerun startup checks and do not narrate startup. The card ends with **"What are you working on?"** — that question is already on screen; treat the user's first message as the answer to it. To re-show the card, run \`bash bin/codex-session-start.sh --card\`.`;
|
|
185
|
+
|
|
186
|
+
const AFTER_GREETING_BODY = `**Mandatory behavioral rule.** When the user describes work, your **first action** — before reading files, exploring code, or anything else — is to get onto a working branch:
|
|
187
|
+
|
|
188
|
+
The integration branch is \`develop\` by default. When top-level
|
|
189
|
+
\`egregore.json.base_branch\` is set, that configured branch replaces
|
|
190
|
+
\`develop\` as the branch point, rebase target, PR base, and protected
|
|
191
|
+
integration branch.
|
|
192
|
+
|
|
193
|
+
1. Derive a topic slug from what the user said (kebab-case, 2–4 words)
|
|
194
|
+
2. Run \`bin/agent.sh branch --topic "<topic>"\` — it resolves the configured base and creates a work branch from \`origin/{base}\` in a task worktree (\`dev/{author}/{slug}\`, or \`feature/{slug}\` / \`bugfix/{slug}\` when the topic reads as a feature or fix). Continue all file work from the printed path.
|
|
195
|
+
3. Give a value-first workspace receipt. Do not lead with Git terminology:
|
|
196
|
+
|
|
197
|
+
\`Your stable project is protected. I’m working in a separate workspace for **{topic}**, where changes stay isolated, reviewable, and reversible.\`
|
|
198
|
+
|
|
199
|
+
Then expose the implementation as secondary detail:
|
|
200
|
+
|
|
201
|
+
\`Workspace: {branch} (worktree).\`
|
|
202
|
+
|
|
203
|
+
**Fallback:** If \`bin/agent.sh branch\` fails, resolve \`{base}\` with
|
|
204
|
+
\`_get_base_branch\`, then use
|
|
205
|
+
\`git checkout -b dev/{author}/{slug} origin/{base}\`.
|
|
206
|
+
|
|
207
|
+
4. Update graph (fire-and-forget): \`bash bin/graph-op.sh set-topic "$(cat .egregore-session-id 2>/dev/null)" "topic from slug" "dev/author/slug" 2>/dev/null &\`
|
|
208
|
+
|
|
209
|
+
### Starting-work UX contract
|
|
210
|
+
|
|
211
|
+
Before execution begins, make Egregore's useful structure legible without turning every task start into a tutorial:
|
|
212
|
+
|
|
213
|
+
- **Workspace** — use the value-first receipt above for a newly created workspace or topic pivot. If already on the appropriate working branch, do not repeat it.
|
|
214
|
+
- **Context** — when organizational retrieval materially informs the work, keep the required Egregore Retrieval Beat and then add one compact result receipt: \`↳ Context restored: {decision, handoff, or prior work} · {source/date}\`. Never claim context was restored when retrieval found nothing useful.
|
|
215
|
+
- **Assumptions** — surface only consequential assumptions that could change the implementation. Use \`Assumption: {assumption} — based on {evidence}.\` Add a correction path when cheap; do not narrate obvious operational choices.
|
|
216
|
+
- **Transition** — once workspace, context, and assumptions are settled, state the outcome you are starting toward in one short sentence and begin.
|
|
217
|
+
|
|
218
|
+
The intended sequence is: **intent → safe workspace → relevant context → consequential assumptions → execution**. Keep technical identifiers available but subordinate them to user value.
|
|
219
|
+
|
|
220
|
+
### Handoff claiming
|
|
221
|
+
|
|
222
|
+
If \`addressed_to_user\` handoffs exist and the user is picking one up, create the IMPLEMENTS link after branch creation:
|
|
223
|
+
\`\`\`bash
|
|
224
|
+
bash bin/graph-op.sh claim-handoff "$SESSION_ID" "$HANDOFF_SESSION_ID" 2>/dev/null &
|
|
225
|
+
\`\`\`
|
|
226
|
+
|
|
227
|
+
**Auto-checkout repos from handoff**: After claiming, check the \`addressed_rich\` context for \`repoState\`. If the handoff includes repo state (non-empty \`repoState\` array), check out the handoff's branches in each managed repo:
|
|
228
|
+
|
|
229
|
+
\`\`\`bash
|
|
230
|
+
PARENT_DIR="$(cd .. && pwd)"
|
|
231
|
+
# For each entry in repoState:
|
|
232
|
+
REPO_DIR="$PARENT_DIR/$REPO_NAME"
|
|
233
|
+
if [ -d "$REPO_DIR/.git" ] || [ -f "$REPO_DIR/.git" ]; then
|
|
234
|
+
git -C "$REPO_DIR" fetch origin "$BRANCH" --quiet 2>/dev/null
|
|
235
|
+
git -C "$REPO_DIR" checkout "$BRANCH" 2>/dev/null || \\
|
|
236
|
+
git -C "$REPO_DIR" checkout -b "$BRANCH" "origin/$BRANCH" 2>/dev/null
|
|
237
|
+
fi
|
|
238
|
+
\`\`\`
|
|
239
|
+
|
|
240
|
+
Report results: \`✓ Checked out {branch} in {repo1}, {repo2}\`. If a branch no longer exists (PR was merged): \`◐ {repo}: PR #{N} merged — on {base}\`. If \`repoState\` is absent or empty, skip auto-checkout silently.
|
|
241
|
+
|
|
242
|
+
**Exceptions** — skip branching when:
|
|
243
|
+
- The user explicitly created or named a branch themselves
|
|
244
|
+
- Already on a working branch AND the user's intent continues the current branch's topic
|
|
245
|
+
|
|
246
|
+
**Topic pivot while on a working branch:** If the user describes work **unrelated** to the current branch's topic, treat it as a new topic and create a new branch (\`bin/agent.sh branch --topic "<new topic>"\`). Do NOT mix unrelated work on one branch.
|
|
247
|
+
|
|
248
|
+
If still on the configured base branch after two messages, create a branch immediately from whatever context you have.
|
|
249
|
+
|
|
250
|
+
### Branch-guard protocol
|
|
251
|
+
|
|
252
|
+
The \`.codex/hooks/branch-guard.js\` PreToolUse hook (enabled by the launcher via \`--enable hooks\`) protects project writes on the configured base branch as well as \`develop\`/\`main\`/\`master\`. Its block message is operational guidance, not a reason to interrupt the user with routine Git choices:
|
|
253
|
+
|
|
254
|
+
- **Topic is clear** (the user said "fix X", "add Y feature") → run \`bin/agent.sh branch --topic "<topic>"\` automatically, continue in the printed worktree, and say one short sentence so the branch change is visible. Do not ask the user to approve routine branching.
|
|
255
|
+
- **Topic is genuinely ambiguous** → ask only for the topic, using compact numbered options:
|
|
256
|
+
|
|
257
|
+
\`\`\`text
|
|
258
|
+
What should I call this work?
|
|
259
|
+
1. <suggested slug from context>
|
|
260
|
+
2. <alternative slug>
|
|
261
|
+
3. Other: (name it)
|
|
262
|
+
\`\`\`
|
|
263
|
+
|
|
264
|
+
Wait for the reply, then branch.
|
|
265
|
+
- **The user explicitly requested the protected branch** → that request is consent. Record it with \`echo '{branch}' > .egregore-branch-consent\`, then retry. Never create the marker merely to silence the hook.
|
|
266
|
+
|
|
267
|
+
Memory, managed-repo, and runtime-state writes should bypass the project guard. If one triggers it, correct the operation target/context instead of asking for protected-branch consent.
|
|
268
|
+
|
|
269
|
+
If this Codex build does not support hooks, follow the same discipline as a standing instruction: never write or commit on the configured base, develop, main, or master.
|
|
270
|
+
|
|
271
|
+
### Onboarding exception
|
|
272
|
+
|
|
273
|
+
If the startup card output contains \`onboarding_needed\`, invoke the \`$onboarding\` skill instead of greeting.`;
|
|
274
|
+
|
|
275
|
+
const COMMAND_AWARENESS_PREPEND = `Codex reserves leading \`/\` for built-ins, so Egregore workflows are **skills**, not slash commands. Invoke them with the matching \`$name\` skill token or from natural language intent ("show activity", "make a handoff"). Hand-written native Codex skills: \`$activity\`, \`$handoff\`, \`$wrap\`, \`$announce\`, \`$harvest\`, \`$the-spiral\`, \`$dashboard\`, \`$deep-reflect\`, \`$quest\`, \`$invite\`, \`$ask\`, \`$save\`, \`$view\`, and \`$scroll\`. Every other workflow has a generated adapter skill of the same name. \`$save\` is the user-facing abstraction for committing, pushing, opening or reusing pull requests, and syncing memory — never make users manage the git workflow by hand.`;
|
|
276
|
+
|
|
277
|
+
const SOCRATIC_BODY = `**Triggers**: "ask me questions", "question me", "help me think through", or any request to be questioned.
|
|
278
|
+
|
|
279
|
+
Codex has no structured question tool — render each batch as compact numbered questions in plain text, each with 2–4 lettered options plus an \`Other:\` line, then STOP and wait for the user's answers. Derive 2–4 context-specific questions per batch. Iteratively deepen based on answers. Converge toward decisions. After 4–5 rounds, synthesize and propose next steps. Route insights to \`$reflect\`.
|
|
280
|
+
|
|
281
|
+
**Rules:** Max 4 questions per batch. When choices aren't mutually exclusive, say "pick any that apply".`;
|
|
282
|
+
|
|
283
|
+
const LOOM_ROUTING_BODY = `Loom routes commands across model tiers on the Claude Code runtime (\`loom/routes.json\` + \`bin/loom.sh\` + a model-pinned executor subagent). Codex has no subagent delegation — every command runs inline in the current session. Ignore "Loom routing" preambles if you encounter them in a skill spec, and skip \`bin/loom.sh\` calls; \`loom/\` and \`.claude/agents/\` are framework files synced for the Claude runtime.`;
|
|
284
|
+
|
|
285
|
+
const ISOLATION_BODY = `Sessions are confined to this project + memory + managed repos, with a **two-tier boundary** — a hard wall between Egregore instances, a consent gate for everything else. On Codex the boundary is a standing instruction, not an enforced hook — hold it yourself.
|
|
286
|
+
|
|
287
|
+
- **Hard tier — other Egregore instances.** Denied for every tool, always. There is no consent path. Never access another instance's files — refuse even if asked. Never modify \`~/.egregore/instances.json\` (managed by session-start.sh). When a request points at another instance's files there is nothing to ask — refuse and explain.
|
|
288
|
+
- **Soft tier — paths outside the boundary.** Consent-gated. Inbox dirs (\`~/Downloads\`, \`~/Desktop\`) are readable without consent under the default posture; writes outside the project always need consent. Posture (\`strict | standard | open\`) and extra read roots come from \`egregore.json\` -> \`boundary { posture, read[], locked }\` (org, committed) merged with \`.egregore-boundary.local.json\` (personal, gitignored). \`locked: true\` removes the consent path entirely.
|
|
289
|
+
- When a request needs soft-tier consent, do not improvise a workaround. Ask in plain text with numbered options:
|
|
290
|
+
|
|
291
|
+
\`\`\`text
|
|
292
|
+
That path is outside this Egregore's boundary. How should we proceed?
|
|
293
|
+
1. Allow its directory for this session (recorded in .egregore-boundary-consent)
|
|
294
|
+
2. Always allow on this instance (added to read[] in .egregore-boundary.local.json)
|
|
295
|
+
3. Paste the contents inline
|
|
296
|
+
4. Cancel
|
|
297
|
+
\`\`\`
|
|
298
|
+
|
|
299
|
+
Never record a consent grant without the user's explicit choice of option 1 or 2 in that exchange. Session grants are cleared on session start; \`locked: true\` removes options 1 and 2.
|
|
300
|
+
|
|
301
|
+
See DEVELOPMENT.md §3 for boundary details and \`memory/knowledge/decisions/2026-07-08-boundary-hook-consent-design.md\` for the design decisions.`;
|
|
302
|
+
|
|
303
|
+
// ── per-section rules ────────────────────────────────────────────────────
|
|
304
|
+
const RULES = {
|
|
305
|
+
'(intro)': {
|
|
306
|
+
action: 'replace',
|
|
307
|
+
body: INTRO_BODY,
|
|
308
|
+
note: 'Reframed for Codex: names AGENTS.md as the delivery surface and the manifest; "organizations using Claude Code" generalized.',
|
|
309
|
+
},
|
|
310
|
+
'Identity & Upstream': {
|
|
311
|
+
action: 'keep',
|
|
312
|
+
note: 'Kept; /update, /contribute, /save tokens rendered as $skill tokens.',
|
|
313
|
+
},
|
|
314
|
+
'Cross-Runtime Compatibility': {
|
|
315
|
+
action: 'keep',
|
|
316
|
+
note: 'Kept verbatim — framework parity applies equally to Claude Code, Codex, and Pi.',
|
|
317
|
+
},
|
|
318
|
+
'Voice': {
|
|
319
|
+
action: 'keep',
|
|
320
|
+
note: 'Kept — all runtimes can consult the shared voice rules and register-specific skills.',
|
|
321
|
+
},
|
|
322
|
+
'On Launch — MANDATORY FIRST ACTION': {
|
|
323
|
+
action: 'replace',
|
|
324
|
+
body: ON_LAUNCH_BODY,
|
|
325
|
+
note: 'Claude SessionStart hook does not run on Codex; the egregore launcher renders the card via bin/codex-session-start.sh before the session. Greeting-replay instruction dropped (card is already on screen).',
|
|
326
|
+
},
|
|
327
|
+
'After Greeting — BRANCH ON FIRST RESPONSE': {
|
|
328
|
+
action: 'replace',
|
|
329
|
+
body: AFTER_GREETING_BODY,
|
|
330
|
+
note: 'EnterWorktree -> bin/agent.sh branch with git checkout fallback; AskUserQuestion -> numbered options in plain text; branch-guard mapped to .codex/hooks/branch-guard.js with instruction fallback; plan-mode note dropped (no plan mode on Codex); /branch + /onboarding -> skill tokens. Handoff claiming and repoState auto-checkout kept verbatim (pure git).',
|
|
331
|
+
},
|
|
332
|
+
'Config Files': { action: 'keep', note: 'Kept verbatim — shell facts, runtime-neutral.' },
|
|
333
|
+
'Knowledge Graph': { action: 'keep', note: 'Kept verbatim — bin/graph.sh is runtime-neutral.' },
|
|
334
|
+
'Egregore Retrieval Beat': { action: 'keep', note: 'Kept verbatim — product attribution applies across runtimes.' },
|
|
335
|
+
'Notifications': { action: 'keep', note: 'Kept verbatim — bin/notify.sh is runtime-neutral.' },
|
|
336
|
+
'Onboarding': { action: 'keep', note: 'Kept; /onboarding rendered as $onboarding.' },
|
|
337
|
+
'Transparency Beat': { action: 'keep', note: 'Kept verbatim.' },
|
|
338
|
+
'Memory': { action: 'keep', note: 'Kept verbatim.' },
|
|
339
|
+
'Loom Routing': {
|
|
340
|
+
action: 'replace',
|
|
341
|
+
body: LOOM_ROUTING_BODY,
|
|
342
|
+
note: 'Loom delegation rides the Claude Code Agent tool; Codex has no subagent delegation — commands run inline. Preambles and bin/loom.sh calls marked skippable.',
|
|
343
|
+
},
|
|
344
|
+
'Git Workflow': {
|
|
345
|
+
action: 'keep',
|
|
346
|
+
note: 'Kept; slash tokens rendered as $skill tokens. Branch diagram unchanged (code fence).',
|
|
347
|
+
},
|
|
348
|
+
'Working Conventions': { action: 'keep', note: 'Kept verbatim.' },
|
|
349
|
+
'Command Awareness': {
|
|
350
|
+
action: 'keep',
|
|
351
|
+
prepend: COMMAND_AWARENESS_PREPEND,
|
|
352
|
+
note: 'Prepended the Codex command surface (skill tokens, native vs adapter split, $save abstraction); disambiguation map kept with /x -> $x token rendering. Tokens with no Codex skill (e.g. /loop, a Claude Code harness feature) are left as-is.',
|
|
353
|
+
},
|
|
354
|
+
'Socratic Questioning (MANDATORY)': {
|
|
355
|
+
action: 'replace',
|
|
356
|
+
body: SOCRATIC_BODY,
|
|
357
|
+
note: 'AskUserQuestion -> numbered plain-text question batches with explicit stop-and-wait; multiSelect -> "pick any that apply".',
|
|
358
|
+
},
|
|
359
|
+
'Telemetry': { action: 'keep', note: 'Kept verbatim — bin/telemetry.sh is runtime-neutral.' },
|
|
360
|
+
'Mode': { action: 'keep', note: 'Kept; /env and /checkup rendered as $skill tokens.' },
|
|
361
|
+
'Environment Isolation': {
|
|
362
|
+
action: 'replace',
|
|
363
|
+
body: ISOLATION_BODY,
|
|
364
|
+
note: 'boundary-check is a Claude PreToolUse hook with no .codex equivalent — two-tier model stated as a standing instruction; AskUserQuestion remediation -> numbered options, now including the two consent-grant options (session grant -> .egregore-boundary-consent, instance grant -> .egregore-boundary.local.json read[]).',
|
|
365
|
+
},
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
// ── render ───────────────────────────────────────────────────────────────
|
|
369
|
+
function render() {
|
|
370
|
+
const claudeMd = fs.readFileSync(CLAUDE_MD, 'utf-8');
|
|
371
|
+
const sections = splitSections(claudeMd);
|
|
372
|
+
|
|
373
|
+
const manifest = [];
|
|
374
|
+
const parts = [];
|
|
375
|
+
|
|
376
|
+
for (const section of sections) {
|
|
377
|
+
const rule = RULES[section.heading];
|
|
378
|
+
if (!rule) {
|
|
379
|
+
console.error(`codex-render-spec: no rule for CLAUDE.md section "${section.heading}" — add one to RULES in bin/codex-render-spec.mjs`);
|
|
380
|
+
process.exit(1);
|
|
381
|
+
}
|
|
382
|
+
const sourceHash = sha(section.body);
|
|
383
|
+
manifest.push({ section: section.heading, action: rule.action, sourceHash, note: rule.note });
|
|
384
|
+
|
|
385
|
+
const heading = section.heading === '(intro)' ? '## Egregore on Codex' : `## ${section.heading}`;
|
|
386
|
+
let body;
|
|
387
|
+
if (rule.action === 'replace') {
|
|
388
|
+
body = rule.body;
|
|
389
|
+
} else {
|
|
390
|
+
body = transformTokens(section.body);
|
|
391
|
+
if (rule.prepend) body = `${rule.prepend}\n\n${body}`;
|
|
392
|
+
}
|
|
393
|
+
parts.push(`${heading}\n\n${body}`);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
for (const heading of Object.keys(RULES)) {
|
|
397
|
+
if (!sections.some((s) => s.heading === heading)) {
|
|
398
|
+
console.error(`codex-render-spec: RULES contains "${heading}" but CLAUDE.md has no such section — remove or update the rule`);
|
|
399
|
+
process.exit(1);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
const block = `${BEGIN}\n\n${parts.join('\n\n---\n\n')}\n\n${END}`;
|
|
404
|
+
return { block, manifest };
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// AGENTS.md is fully owned by this script: the guard preamble plus the generated
|
|
408
|
+
// spec block. Reconstructing it deterministically (rather than splicing into the
|
|
409
|
+
// existing file) guarantees the runtime-precedence guard is always present and
|
|
410
|
+
// correct — it cannot be stripped by an upstream sync or a hand edit.
|
|
411
|
+
function assembleAgentsMd(block) {
|
|
412
|
+
return `${AGENTS_PREAMBLE.trim()}\n\n${block}\n`;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const check = process.argv.includes('--check');
|
|
416
|
+
const { block, manifest } = render();
|
|
417
|
+
const manifestJson = `${JSON.stringify({ generatedBy: 'bin/codex-render-spec.mjs', source: 'CLAUDE.md', sections: manifest }, null, 2)}\n`;
|
|
418
|
+
|
|
419
|
+
const currentAgents = fs.existsSync(AGENTS_MD) ? fs.readFileSync(AGENTS_MD, 'utf-8') : '';
|
|
420
|
+
const nextAgents = assembleAgentsMd(block);
|
|
421
|
+
|
|
422
|
+
const CODEX_DOC_BUDGET = 32 * 1024;
|
|
423
|
+
if (Buffer.byteLength(nextAgents, 'utf-8') > CODEX_DOC_BUDGET) {
|
|
424
|
+
console.error(`codex-render-spec: AGENTS.md would be ${Buffer.byteLength(nextAgents, 'utf-8')} bytes — over Codex's ${CODEX_DOC_BUDGET}-byte project-doc budget. Trim CLAUDE.md or tighten translations.`);
|
|
425
|
+
process.exit(1);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (check) {
|
|
429
|
+
const currentManifest = fs.existsSync(MANIFEST) ? fs.readFileSync(MANIFEST, 'utf-8') : '';
|
|
430
|
+
const stale = nextAgents !== currentAgents || manifestJson !== currentManifest;
|
|
431
|
+
if (stale) {
|
|
432
|
+
console.error('codex spec out of date — run: node bin/codex-render-spec.mjs');
|
|
433
|
+
process.exit(1);
|
|
434
|
+
}
|
|
435
|
+
console.log('codex spec up to date');
|
|
436
|
+
} else {
|
|
437
|
+
fs.writeFileSync(AGENTS_MD, nextAgents);
|
|
438
|
+
fs.writeFileSync(MANIFEST, manifestJson);
|
|
439
|
+
console.log(`codex spec rendered: AGENTS.md (${Buffer.byteLength(nextAgents, 'utf-8')} bytes), .codex/spec-manifest.json (${manifest.length} sections)`);
|
|
440
|
+
}
|