create-egregore 0.19.3 → 0.19.6

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.
Files changed (154) hide show
  1. package/assets/egregore-launcher.js +410 -26
  2. package/bin/cli.js +34 -20
  3. package/lib/local.js +84 -11
  4. package/lib/pi-runtime.js +186 -0
  5. package/lib/setup.js +56 -11
  6. package/lib/ui.js +1 -1
  7. package/package.json +8 -6
  8. package/runtime/codex/.codex/hooks/search-hint.js +65 -0
  9. package/runtime/codex/.codex/hooks.json +13 -0
  10. package/runtime/codex/.codex/skills/deep-reflect/SKILL.md +14 -10
  11. package/runtime/codex/.codex/skills/minion/SKILL.md +25 -0
  12. package/runtime/codex/.codex/skills/scroll/SKILL.md +168 -0
  13. package/runtime/codex/.codex/skills/scroll/agents/openai.yaml +4 -0
  14. package/runtime/codex/.codex/skills/scroll/assets/shell.html +542 -0
  15. package/runtime/codex/.codex/skills/search/SKILL.md +56 -0
  16. package/runtime/codex/.codex/skills/session-view/SKILL.md +25 -0
  17. package/runtime/codex/.codex/skills/thread/SKILL.md +25 -0
  18. package/runtime/codex/.codex/skills/view/SKILL.md +147 -32
  19. package/runtime/codex/.codex/skills/view/agents/openai.yaml +4 -0
  20. package/runtime/codex/.codex/skills/view/assets/compose-scaffold.html +221 -0
  21. package/runtime/codex/.codex/spec-manifest.json +4 -4
  22. package/runtime/codex/AGENTS.md +31 -5
  23. package/runtime/codex/bin/activity-data.sh +46 -4
  24. package/runtime/codex/bin/agent.sh +10 -2
  25. package/runtime/codex/bin/codex-install-skills.sh +1 -1
  26. package/runtime/codex/bin/codex-render-spec.mjs +24 -2
  27. package/runtime/codex/bin/codex-session-start.sh +6 -60
  28. package/runtime/codex/bin/codex-skill-render.mjs +20 -12
  29. package/runtime/codex/bin/codex-sync-skills.sh +4 -0
  30. package/runtime/codex/bin/graph-op.sh +56 -5
  31. package/runtime/codex/bin/graph.sh +36 -0
  32. package/runtime/codex/bin/handoff-run.sh +157 -7
  33. package/runtime/codex/bin/handoff-save-egregore.sh +6 -1
  34. package/runtime/codex/bin/index-handoff.sh +9 -3
  35. package/runtime/codex/bin/lib/context.sh +97 -18
  36. package/runtime/codex/bin/lib/dashboard-artifact.sh +1 -1
  37. package/runtime/codex/bin/lib/git-sync.sh +35 -9
  38. package/runtime/codex/bin/lib/greeting.sh +30 -104
  39. package/runtime/codex/bin/lib/metrics.sh +374 -0
  40. package/runtime/codex/bin/publish-artifact.sh +43 -1
  41. package/runtime/codex/bin/settings.sh +274 -0
  42. package/runtime/codex/manifest.json +18 -1
  43. package/runtime/pi/.codex/config.toml +15 -0
  44. package/runtime/pi/.codex/hooks/branch-guard.js +242 -0
  45. package/runtime/pi/.codex/hooks/search-hint.js +65 -0
  46. package/runtime/pi/.codex/hooks.json +30 -0
  47. package/runtime/pi/.codex/skills/activity/SKILL.md +70 -0
  48. package/runtime/pi/.codex/skills/add/SKILL.md +25 -0
  49. package/runtime/pi/.codex/skills/announce/SKILL.md +54 -0
  50. package/runtime/pi/.codex/skills/answer/SKILL.md +25 -0
  51. package/runtime/pi/.codex/skills/archive/SKILL.md +41 -0
  52. package/runtime/pi/.codex/skills/ask/SKILL.md +59 -0
  53. package/runtime/pi/.codex/skills/branch/SKILL.md +25 -0
  54. package/runtime/pi/.codex/skills/checkup/SKILL.md +41 -0
  55. package/runtime/pi/.codex/skills/commit/SKILL.md +25 -0
  56. package/runtime/pi/.codex/skills/contribute/SKILL.md +25 -0
  57. package/runtime/pi/.codex/skills/dark-mode/SKILL.md +25 -0
  58. package/runtime/pi/.codex/skills/dashboard/SKILL.md +59 -0
  59. package/runtime/pi/.codex/skills/deep-reflect/SKILL.md +74 -0
  60. package/runtime/pi/.codex/skills/delete-user/SKILL.md +25 -0
  61. package/runtime/pi/.codex/skills/egregore-voice/SKILL.md +25 -0
  62. package/runtime/pi/.codex/skills/emissary/SKILL.md +41 -0
  63. package/runtime/pi/.codex/skills/env/SKILL.md +25 -0
  64. package/runtime/pi/.codex/skills/handoff/SKILL.md +67 -0
  65. package/runtime/pi/.codex/skills/harvest/SKILL.md +107 -0
  66. package/runtime/pi/.codex/skills/ingest/SKILL.md +25 -0
  67. package/runtime/pi/.codex/skills/ingest-google/SKILL.md +25 -0
  68. package/runtime/pi/.codex/skills/ingest-user-interview/SKILL.md +41 -0
  69. package/runtime/pi/.codex/skills/invite/SKILL.md +40 -0
  70. package/runtime/pi/.codex/skills/issue/SKILL.md +41 -0
  71. package/runtime/pi/.codex/skills/me/SKILL.md +25 -0
  72. package/runtime/pi/.codex/skills/meeting/SKILL.md +41 -0
  73. package/runtime/pi/.codex/skills/minion/SKILL.md +25 -0
  74. package/runtime/pi/.codex/skills/note/SKILL.md +25 -0
  75. package/runtime/pi/.codex/skills/onboarding/SKILL.md +41 -0
  76. package/runtime/pi/.codex/skills/pr/SKILL.md +25 -0
  77. package/runtime/pi/.codex/skills/project/SKILL.md +41 -0
  78. package/runtime/pi/.codex/skills/pull/SKILL.md +25 -0
  79. package/runtime/pi/.codex/skills/push/SKILL.md +25 -0
  80. package/runtime/pi/.codex/skills/quest/SKILL.md +77 -0
  81. package/runtime/pi/.codex/skills/quest-suggest/SKILL.md +25 -0
  82. package/runtime/pi/.codex/skills/reflect/SKILL.md +41 -0
  83. package/runtime/pi/.codex/skills/review-pr/SKILL.md +41 -0
  84. package/runtime/pi/.codex/skills/save/SKILL.md +62 -0
  85. package/runtime/pi/.codex/skills/scroll/SKILL.md +168 -0
  86. package/runtime/pi/.codex/skills/scroll/agents/openai.yaml +4 -0
  87. package/runtime/pi/.codex/skills/scroll/assets/shell.html +542 -0
  88. package/runtime/pi/.codex/skills/search/SKILL.md +56 -0
  89. package/runtime/pi/.codex/skills/session-view/SKILL.md +25 -0
  90. package/runtime/pi/.codex/skills/setup/SKILL.md +25 -0
  91. package/runtime/pi/.codex/skills/summon/SKILL.md +41 -0
  92. package/runtime/pi/.codex/skills/sync-repos/SKILL.md +25 -0
  93. package/runtime/pi/.codex/skills/telegram-connect/SKILL.md +25 -0
  94. package/runtime/pi/.codex/skills/telemetry/SKILL.md +25 -0
  95. package/runtime/pi/.codex/skills/test/SKILL.md +41 -0
  96. package/runtime/pi/.codex/skills/the-spiral/SKILL.md +84 -0
  97. package/runtime/pi/.codex/skills/thread/SKILL.md +25 -0
  98. package/runtime/pi/.codex/skills/todo/SKILL.md +41 -0
  99. package/runtime/pi/.codex/skills/tui-design/SKILL.md +41 -0
  100. package/runtime/pi/.codex/skills/tutorial/SKILL.md +41 -0
  101. package/runtime/pi/.codex/skills/update/SKILL.md +25 -0
  102. package/runtime/pi/.codex/skills/view/SKILL.md +156 -0
  103. package/runtime/pi/.codex/skills/view/agents/openai.yaml +4 -0
  104. package/runtime/pi/.codex/skills/view/assets/compose-scaffold.html +221 -0
  105. package/runtime/pi/.codex/skills/visual-explain/SKILL.md +41 -0
  106. package/runtime/pi/.codex/skills/wrap/SKILL.md +55 -0
  107. package/runtime/pi/.codex/spec-manifest.json +114 -0
  108. package/runtime/pi/.pi/APPEND_SYSTEM.md +255 -0
  109. package/runtime/pi/.pi/extensions/egregore.ts +324 -0
  110. package/runtime/pi/.pi/settings.json +6 -0
  111. package/runtime/pi/.pi/spec-manifest.json +12 -0
  112. package/runtime/pi/AGENTS.md +350 -0
  113. package/runtime/pi/bin/activity-data.sh +242 -0
  114. package/runtime/pi/bin/agent.sh +677 -0
  115. package/runtime/pi/bin/codex-install-skills.sh +78 -0
  116. package/runtime/pi/bin/codex-render-spec.mjs +394 -0
  117. package/runtime/pi/bin/codex-session-start.sh +188 -0
  118. package/runtime/pi/bin/codex-skill-render.mjs +323 -0
  119. package/runtime/pi/bin/codex-sync-skills.sh +227 -0
  120. package/runtime/pi/bin/dashboard-data.sh +178 -0
  121. package/runtime/pi/bin/graph-batch.sh +60 -0
  122. package/runtime/pi/bin/graph-op.sh +431 -0
  123. package/runtime/pi/bin/graph-wal.sh +228 -0
  124. package/runtime/pi/bin/graph.sh +177 -0
  125. package/runtime/pi/bin/handoff-pr-backfill.sh +86 -0
  126. package/runtime/pi/bin/handoff-run.sh +581 -0
  127. package/runtime/pi/bin/handoff-save-egregore.sh +136 -0
  128. package/runtime/pi/bin/index-handoff.sh +312 -0
  129. package/runtime/pi/bin/lib/artifact-id.sh +46 -0
  130. package/runtime/pi/bin/lib/config.sh +71 -0
  131. package/runtime/pi/bin/lib/context.sh +542 -0
  132. package/runtime/pi/bin/lib/dashboard-artifact.sh +142 -0
  133. package/runtime/pi/bin/lib/ensure-develop.sh +183 -0
  134. package/runtime/pi/bin/lib/git-sync.sh +288 -0
  135. package/runtime/pi/bin/lib/greeting.sh +340 -0
  136. package/runtime/pi/bin/lib/hash.sh +13 -0
  137. package/runtime/pi/bin/lib/identity.sh +174 -0
  138. package/runtime/pi/bin/lib/metrics.sh +374 -0
  139. package/runtime/pi/bin/lib/permissions.sh +106 -0
  140. package/runtime/pi/bin/lib/time.sh +56 -0
  141. package/runtime/pi/bin/lib/worktree-links.sh +54 -0
  142. package/runtime/pi/bin/notify.sh +207 -0
  143. package/runtime/pi/bin/pi-branch-policy.mjs +15 -0
  144. package/runtime/pi/bin/pi-product-workflows.mjs +324 -0
  145. package/runtime/pi/bin/pi-render-spec.mjs +114 -0
  146. package/runtime/pi/bin/pi-session-start.sh +24 -0
  147. package/runtime/pi/bin/publish-artifact.sh +201 -0
  148. package/runtime/pi/bin/publish-references.sh +144 -0
  149. package/runtime/pi/bin/repo-state.sh +99 -0
  150. package/runtime/pi/bin/telemetry.sh +391 -0
  151. package/runtime/pi/bin/worktree-create.sh +118 -0
  152. package/runtime/pi/bin/worktree-remove.sh +50 -0
  153. package/runtime/pi/bin/worktree.sh +198 -0
  154. package/runtime/pi/manifest.json +176 -0
@@ -1,41 +1,156 @@
1
1
  ---
2
2
  name: view
3
- description: 'Fallback Codex adapter for the Egregore view workflow.'
3
+ description: 'Render Egregore data and documents as branded browser artifacts. Use when the user invokes /view or $view, asks to show something visually, open it in a browser, make a document readable or presentable, render a quest/handoff/activity/board/network, or synthesize a visual artifact from a topic.'
4
4
  ---
5
5
 
6
- <!-- generated-by: bin/codex-sync-skills.sh -->
6
+ # Egregore View
7
7
 
8
- # Egregore view Adapter
8
+ Native Codex Egregore skill. Use only inside an Egregore checkout.
9
9
 
10
- This is fallback coverage for a long-tail Egregore workflow that has not been
11
- ported to a hand-written Codex-native skill yet.
12
-
13
- Use the project shell and filesystem directly. Do not invoke Claude Code
14
- commands. Translate interactive choices to structured Codex question tooling
15
- when it is available; otherwise render compact numbered choices with an
16
- `Other:` option and wait for the user.
10
+ Resolve a file or live Egregore surface, render it with the in-repo artifact
11
+ tooling, open it, and report the concrete output path. Run the workflow inline;
12
+ do not invoke Claude Code commands or delegate through Loom.
17
13
 
18
14
  ## Structured UX parity
19
15
 
20
- This workflow has a Claude skill with user-visible structured output. After
21
- reading `.claude/skills/view/SKILL.md`, reproduce the same visible UX in Codex:
22
-
23
- - Preserve TUI boxes, markdown tables, rich cards, browser artifact rendering,
24
- exact confirmation blocks, and "no preamble" rules from the source skill.
25
- - Use the source skill's frame width, section order, labels, status footer,
26
- and examples as the contract for the final response.
27
- - Never replace a required box/table/card/artifact view with a prose summary
28
- unless the user explicitly asks for a summary.
29
- - When the source says to output a TUI box directly, paste that box as the
30
- visible response, preferably in a `text` fenced block.
31
- - Never show raw JSON, raw command output, or unformatted script output when
32
- the source skill requires formatted status or rendered output.
33
-
34
- 1. Read `.claude/skills/view/SKILL.md` for the workflow details.
35
- 2. Run the referenced `bin/` scripts directly from Codex.
36
- 3. Treat graph, publish, and notify steps as best-effort unless that workflow
37
- explicitly says they are required.
38
- 4. Keep local-mode behavior filesystem-first and avoid graph or notification
39
- calls when `egregore.json` declares `"mode": "local"`.
40
- 5. Never call the deprecated `egregore-handoff` CLI for Egregore project
41
- handoffs.
16
+ The visible result is the browser artifact and a compact receipt. Preserve the
17
+ typed artifact templates, designed document composition, exact file path, and
18
+ stable board URL when available. Do not replace the artifact with a prose
19
+ summary or expose raw renderer output.
20
+
21
+ ## Resolve the request
22
+
23
+ 1. Verify `bin/agent.sh` exists. If not, say this is not an Egregore checkout.
24
+ 2. Parse an optional type followed by a name:
25
+ - `quest` from `memory/quests/`
26
+ - `handoff` from `memory/handoffs/` recursively
27
+ - `activity`, `board`, or `network` with no source file
28
+ - `document` for any markdown file
29
+ 3. Treat an argument containing `/` or ending in `.md` as a direct path. Use it
30
+ if it exists and infer the type from its directory.
31
+ 4. With no explicit type, search in this order: quests, handoffs, knowledge.
32
+ Prefer exact basename matches, then case-insensitive partial matches. For
33
+ handoffs, prefer the newest matching dated path.
34
+ 5. If several files match, use structured Codex question tooling when
35
+ available; otherwise ask one concise plain-text question listing the paths.
36
+ 6. If no file matches and the input is a topic or question, synthesize a
37
+ temporary markdown document from relevant memory, repository files, and
38
+ conversation context at
39
+ `/tmp/egregore-artifacts/synthesized-<slug>.md`. If the input clearly names
40
+ a missing file, report it as missing instead of inventing a document.
41
+
42
+ ## Select the renderer
43
+
44
+ Prefer the checked-out package so local changes are exercised and no package
45
+ download is needed:
46
+
47
+ ```bash
48
+ RENDER="npx egregore-artifacts@latest"
49
+ if [ -f packages/egregore-artifacts/bin/cli.js ] && \
50
+ [ -d packages/egregore-artifacts/node_modules/react ]; then
51
+ RENDER="node packages/egregore-artifacts/bin/cli.js"
52
+ fi
53
+ ```
54
+
55
+ If the local package exists without dependencies, install its dependencies or
56
+ use the `npx` fallback. Do not block a render on optional connected services.
57
+
58
+ ## Render typed artifacts
59
+
60
+ Run the matching command:
61
+
62
+ ```bash
63
+ $RENDER quest <quest-file>
64
+ $RENDER handoff <handoff-file>
65
+ $RENDER activity
66
+ $RENDER board
67
+ $RENDER network
68
+ $RENDER document <markdown-file>
69
+ ```
70
+
71
+ Use the renderer's reported HTML path rather than guessing it.
72
+
73
+ For documents, walk the generative-UI synthesis graph in
74
+ `packages/design-system/generative-ui/skill/SKILL.md`: select one id each for
75
+ objective, audience, register, palette, and grammar from the document's
76
+ substance, record one line of judgment for each, resolve the brief, and pass it
77
+ with `--brief`. If that layer is unavailable, render without the brief.
78
+
79
+ ## Compose flagship documents
80
+
81
+ Composition is the default for a multi-section strategy, briefing, explainer,
82
+ analysis, decision document, or anything explicitly requested as composed,
83
+ presentable, client-facing, designed, or `--compose`. Use the fast renderer for
84
+ typed artifacts, short utility documents, `--fast`, or `--floor`.
85
+
86
+ For composition:
87
+
88
+ 1. Read the source document in full.
89
+ 2. Copy `.codex/skills/view/assets/compose-scaffold.html` to
90
+ `/tmp/egregore-artifacts/composed-<slug>.html`.
91
+ 3. Fill every placeholder and walk the generative-UI graph for the manifest's
92
+ register, palette, grammar, and trail.
93
+ 4. Transform rather than mirror the markdown:
94
+ - write a two-tone claim-led hero and italic standfirst;
95
+ - make section headings state findings, not repeat source headings;
96
+ - choose components by meaning: ledger for Q/A, claims for numbers, panels
97
+ for options, steps for sequences, feature rows for capability/status,
98
+ threads for decisions, gap cards for negatives, and a readout for the
99
+ honest bottom line;
100
+ - create one anchored navigation item per composed section.
101
+ 5. Keep every theme-sensitive color as `var(--token)`. Never emit inline hex
102
+ colors in composed content. Preserve the scaffold's no-flash theme restore,
103
+ `<html data-theme>`, and light/auto/dark behavior.
104
+ 6. Verify no placeholders remain, open the HTML with the platform browser
105
+ opener, and report `Renderer: composed (band 5, inline)`.
106
+
107
+ ## Publish the stable board
108
+
109
+ After `$RENDER board`, publish best-effort only when `egregore.json` declares a
110
+ connected configuration:
111
+
112
+ ```bash
113
+ _API_URL=$(jq -r '.api_url // empty' egregore.json 2>/dev/null)
114
+ _MODE=$(jq -r '.mode // empty' egregore.json 2>/dev/null)
115
+ if [ -n "$_API_URL" ] && [ "$_MODE" != "local" ]; then
116
+ ORG_NAME=$(jq -r '.org_name // .slug' egregore.json)
117
+ bash bin/publish-artifact.sh board memory/board/board.json \
118
+ --id board \
119
+ --title "Project Board — $ORG_NAME" \
120
+ --author "$ORG_NAME" \
121
+ --description "Latest board for $ORG_NAME" 2>/dev/null &
122
+ fi
123
+ ```
124
+
125
+ The local artifact remains the successful result if publishing fails. In local
126
+ mode, do not call graph or notification services.
127
+
128
+ ## Report
129
+
130
+ Return only the useful receipt after the browser opens:
131
+
132
+ ```text
133
+ ✓ Artifact opened in browser
134
+ File: /tmp/egregore-artifacts/<rendered-file>.html
135
+ ```
136
+
137
+ For a connected board, append:
138
+
139
+ ```text
140
+ ◆ https://egregore.xyz/view/<org-slug>/board (stable — refresh for latest)
141
+ ```
142
+
143
+ Emit telemetry best-effort after completion:
144
+
145
+ ```bash
146
+ bash bin/telemetry.sh emit "command" '{"command":"view"}' 2>/dev/null &
147
+ ```
148
+
149
+ ## Rules
150
+
151
+ - Keep filesystem resolution sufficient in local mode; the graph is optional.
152
+ - Preserve auto-linked backtick references handled by
153
+ `bin/publish-references.sh` when publishing markdown.
154
+ - Never install a global renderer package as the first choice.
155
+ - Never call the deprecated `egregore-handoff` CLI.
156
+ - Never claim publishing succeeded unless a URL was actually returned.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Egregore View"
3
+ short_description: "Render Egregore artifacts in the browser"
4
+ default_prompt: "Use $view to render this as a branded browser artifact."
@@ -0,0 +1,221 @@
1
+ <!DOCTYPE html>
2
+ <!--
3
+ EGREGORE COMPOSITION SCAFFOLD — the reusable chrome + component kit for
4
+ band-5 composed artifacts (`$view <doc> --compose`).
5
+
6
+ How to use: copy this file, then
7
+ 1. fill <title>, the manifest `register`/`grammar`, nav brand + links,
8
+ the hero (series / h1 / standfirst / chips), and the footer.
9
+ 2. replace the <!-- COMPONENTS: … --> region with composed sections built
10
+ from the component kit below — do NOT mirror the markdown; transform
11
+ the substance into the grammar (statement titles, panels, cards, …).
12
+ 3. every theme-sensitive color MUST be a var(--token). Never inline hex
13
+ in content — dark mode breaks. The kit already does this.
14
+ The token blocks (vellum/nocturne) + toggle JS are complete — leave them.
15
+ -->
16
+ <html lang="en" data-theme="vellum" data-theme-pair="meridian" data-theme-mode="auto">
17
+ <head>
18
+ <meta charset="utf-8">
19
+ <meta name="viewport" content="width=device-width, initial-scale=1">
20
+ <title>__TITLE__ — Egregore</title>
21
+ <link rel="preconnect" href="https://fonts.googleapis.com">
22
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
23
+ <link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,300..900;1,9..144,400..700&family=Hanken+Grotesk:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
24
+ <script type="application/json" id="egregore-design-manifest">{"system":"egregore-design-convention","version":"0.3.0","lineage":"meridian","pair":"meridian","mode":"auto","resolvedTheme":"vellum","target":"browser","register":"__REGISTER__","grammar":"__GRAMMAR__","composed":true}</script>
25
+ <style>
26
+ :root{--serif:"Fraunces",Georgia,serif;--sans:"Hanken Grotesk",system-ui,sans-serif;--mono:"IBM Plex Mono",ui-monospace,monospace;--ease:cubic-bezier(.22,.61,.36,1)}
27
+ [data-theme="vellum"]{--paper:#eceef2;--paper-2:#e2e6ec;--card:#f8fafc;--ink:#15212e;--ink-soft:#4d5a68;--ink-faint:#8492a0;--line:#cbd4de;--line-soft:#dde3ea;--prussian:#2c4a6b;--prussian-bright:#3f74ad;--brass:#9a7521;--brass-bright:#c0962f;--teal:#1d7a6e;--rose:#a8493e;--t1:#9a7521;--t1-bg:#f3ead0;--t2:#1d7a6e;--t2-bg:#ddefea;--t3:#a8493e;--t3-bg:#f4ddd7;--contour:#bcc6d2;--shadow:0 1px 2px rgba(21,33,46,.06),0 12px 34px -18px rgba(21,33,46,.34)}
28
+ [data-theme="nocturne"]{--paper:#0e151d;--paper-2:#131c26;--card:#18222e;--ink:#e7ecf2;--ink-soft:#aab6c2;--ink-faint:#76838f;--line:#2a3744;--line-soft:#202b36;--prussian:#5b8cc0;--prussian-bright:#7aa9d8;--brass:#d8b25a;--brass-bright:#e7c878;--teal:#3fb0a0;--rose:#d2796b;--t1:#d8b25a;--t1-bg:#2c2616;--t2:#3fb0a0;--t2-bg:#152b29;--t3:#d2796b;--t3-bg:#2c1c18;--contour:#283543;--shadow:0 1px 2px rgba(0,0,0,.4),0 18px 40px -20px rgba(0,0,0,.7)}
29
+ [data-theme="loam"]{--paper:#f0ece2;--paper-2:#e7e1d3;--card:#faf7f0;--ink:#241d12;--ink-soft:#5c4f3a;--ink-faint:#8f8168;--line:#d3c9b4;--line-soft:#e2dac8;--prussian:#5a6b3a;--brass:#9a6b21;--teal:#3a7a5c;--rose:#a85a3e;--t1:#9a6b21;--t1-bg:#efe2c8;--t2:#3a7a5c;--t2-bg:#dcebe0;--t3:#a85a3e;--t3-bg:#f2ded4;--contour:#c8bca0;--shadow:0 1px 2px rgba(36,29,18,.06),0 12px 34px -18px rgba(36,29,18,.3)}
30
+
31
+ /* ── base ── */
32
+ *{box-sizing:border-box;margin:0;padding:0}
33
+ html{scroll-behavior:smooth}
34
+ body{background:var(--paper);color:var(--ink);font-family:var(--sans);font-size:16.5px;line-height:1.62;-webkit-font-smoothing:antialiased;transition:background .3s var(--ease),color .3s var(--ease)}
35
+ a{color:var(--prussian-bright);text-decoration:none}
36
+ .wrap{max-width:1080px;margin:0 auto;padding:0 32px}
37
+ .col{max-width:860px}
38
+ .contours{position:fixed;inset:0;z-index:0;pointer-events:none;opacity:.5}
39
+ .contours path{fill:none;stroke:var(--contour);stroke-width:1}
40
+ main{position:relative;z-index:1}
41
+ .rule{border:none;border-top:1px solid var(--line-soft);margin:60px 0 0}
42
+ code{font-family:var(--mono);font-size:.82em;background:var(--paper-2);border:1px solid var(--line-soft);border-radius:5px;padding:1px 6px;color:var(--prussian-bright)}
43
+ p{color:var(--ink-soft)} p b,li b,.lede b{color:var(--ink);font-weight:600}
44
+
45
+ /* ── nav (sticky section rail) ── */
46
+ nav{position:sticky;top:0;z-index:50;display:flex;align-items:center;gap:28px;padding:13px 32px;background:color-mix(in srgb,var(--paper) 86%,transparent);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-bottom:1px solid var(--line-soft)}
47
+ nav .brand{font:500 .68rem/1 var(--mono);letter-spacing:2px;text-transform:uppercase;color:var(--ink-soft);white-space:nowrap}
48
+ nav .brand b{color:var(--prussian-bright);font-weight:600}
49
+ nav .links{display:flex;gap:20px;margin-left:auto;overflow-x:auto;scrollbar-width:none}
50
+ nav .links::-webkit-scrollbar{display:none}
51
+ nav .links a{font:400 .7rem/1 var(--mono);color:var(--ink-soft);white-space:nowrap;padding:4px 0;border-bottom:1px solid transparent}
52
+ nav .links a:hover{color:var(--ink);border-bottom-color:var(--t1)}
53
+ .toggle{flex:0 0 auto;font:500 .66rem/1 var(--mono);letter-spacing:.5px;color:var(--ink-soft);background:var(--card);border:1px solid var(--line);border-radius:20px;padding:6px 12px;cursor:pointer}
54
+ .toggle:hover{color:var(--ink);border-color:var(--ink-faint)}
55
+
56
+ /* ── hero ── */
57
+ header.hero{padding:92px 0 60px}
58
+ .series{display:flex;align-items:center;gap:14px;font:500 .7rem/1 var(--mono);letter-spacing:2.5px;text-transform:uppercase;color:var(--t1);margin-bottom:32px}
59
+ .series::before{content:"";width:44px;height:1px;background:var(--t1)}
60
+ h1{font-family:var(--serif);font-weight:420;font-size:clamp(2.6rem,5.4vw,4rem);line-height:1.06;letter-spacing:-.02em;max-width:19ch}
61
+ h1 em{font-style:italic;font-weight:430;color:var(--prussian-bright)}
62
+ .standfirst{font-family:var(--serif);font-style:italic;font-size:1.3rem;line-height:1.44;color:var(--ink-soft);max-width:56ch;margin:26px 0 28px}
63
+
64
+ /* ── section frame ── */
65
+ section{padding:72px 0 6px}
66
+ .seclabel{display:flex;align-items:center;gap:10px;font:500 .72rem/1 var(--mono);letter-spacing:2.5px;text-transform:uppercase;color:var(--t1);margin-bottom:16px}
67
+ .seclabel .n{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border:1px solid var(--t1);border-radius:50%;font-size:.62rem}
68
+ h2{font-family:var(--serif);font-weight:430;font-size:clamp(1.9rem,3.4vw,2.6rem);line-height:1.12;letter-spacing:-.015em;max-width:24ch;margin-bottom:12px}
69
+ .lede{font-size:1.05rem;color:var(--ink-soft);max-width:62ch;margin-bottom:24px}
70
+
71
+ /* ── chips / pills / badges ── */
72
+ .chips{display:flex;flex-wrap:wrap;gap:9px}
73
+ .chip{font:500 .68rem/1 var(--mono);letter-spacing:.4px;padding:7px 13px;border-radius:20px;border:1px solid var(--line);background:var(--card);color:var(--ink-soft);white-space:nowrap}
74
+ .chip.ok{border-color:var(--t2);color:var(--t2)} .chip.ok::before{content:"● ";font-size:.6rem}
75
+ .chip.brass{border-color:var(--t1);color:var(--t1)} .chip.brass::before{content:"◇ ";font-size:.66rem}
76
+ .chip.warn{border-color:var(--t3);color:var(--t3)}
77
+ .bd{display:inline-flex;align-items:center;gap:5px;font:600 .64rem/1 var(--mono);letter-spacing:.4px;text-transform:uppercase;padding:3px 8px;border-radius:5px;white-space:nowrap}
78
+ .bd.ok{background:var(--t2-bg);color:var(--t2)} .bd.half{background:var(--t1-bg);color:var(--t1)} .bd.no{background:var(--t3-bg);color:var(--t3)} .bd.neu{background:var(--paper-2);color:var(--ink-faint)}
79
+
80
+ /* ── claim / stat cards ── */
81
+ .claims{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin:26px 0 8px}
82
+ .claims.four{grid-template-columns:repeat(4,1fr)} .claims.two{grid-template-columns:1fr 1fr}
83
+ @media(max-width:760px){.claims,.claims.four,.claims.two{grid-template-columns:1fr 1fr}}
84
+ .claim{background:var(--card);border:1px solid var(--line-soft);border-radius:12px;padding:20px 22px;box-shadow:var(--shadow)}
85
+ .claim .v{font-family:var(--serif);font-size:1.55rem;line-height:1.1;color:var(--t1)}
86
+ .claim.teal .v{color:var(--t2)} .claim.rose .v{color:var(--t3)}
87
+ .claim .l{font-size:.84rem;color:var(--ink-soft);margin-top:8px;line-height:1.5}
88
+
89
+ /* ── labeled tag card ── */
90
+ .tagcard{background:var(--card);border:1px solid var(--line-soft);border-radius:14px;padding:22px 26px;margin:14px 0;box-shadow:var(--shadow)}
91
+ .tagcard .tag{display:inline-block;font:600 .62rem/1 var(--mono);letter-spacing:1.5px;text-transform:uppercase;color:#fff;border-radius:6px;padding:5px 9px;margin-right:12px;vertical-align:2px;background:var(--prussian)}
92
+ .tagcard .tag.teal{background:var(--teal)} .tagcard .tag.rose{background:var(--rose)} .tagcard .tag.brass{background:var(--brass)}
93
+ .tagcard h3{display:inline;font-family:var(--serif);font-weight:500;font-size:1.16rem}
94
+ .tagcard p{margin-top:12px;font-size:.95rem}
95
+ .tagcard .verdict{margin-top:12px;font:600 .74rem/1.5 var(--mono);letter-spacing:.3px}
96
+ .tagcard .verdict.ok{color:var(--t2)} .tagcard .verdict.no{color:var(--t3)}
97
+
98
+ /* ── comparison panels (2–3 up) ── */
99
+ .panels{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin:26px 0 10px}
100
+ .panels.three{grid-template-columns:repeat(3,1fr)}
101
+ @media(max-width:760px){.panels,.panels.three{grid-template-columns:1fr}}
102
+ .panel{border:1px solid var(--line);border-radius:14px;overflow:hidden;background:var(--card);box-shadow:var(--shadow);display:flex;flex-direction:column}
103
+ .panel .ph{font:600 .7rem/1 var(--mono);letter-spacing:1.5px;text-transform:uppercase;color:#fff;padding:13px 18px;background:var(--prussian)}
104
+ .panel.b .ph{background:var(--teal)} .panel.c .ph{background:var(--ink-faint)} .panel.warn .ph{background:var(--rose)}
105
+ .panel .pb{padding:16px 20px;font-size:.9rem;color:var(--ink-soft);flex:1}
106
+ .panel .pb b{color:var(--ink)}
107
+ .panel .price{font-family:var(--serif);font-size:1.3rem;color:var(--t1);margin:2px 0 10px}
108
+ .panel ul{list-style:none;margin-top:8px} .panel li{padding:5px 0 5px 18px;position:relative;line-height:1.5}
109
+ .panel li::before{content:"";position:absolute;left:2px;top:12px;width:5px;height:5px;border-radius:50%;background:var(--t1)}
110
+ .panel .pr{display:grid;grid-template-columns:110px 1fr;gap:12px;padding:11px 0;border-bottom:1px solid var(--line-soft)}
111
+ .panel .pr:last-child{border-bottom:none} .panel .pr .k{font:500 .68rem/1.4 var(--mono);color:var(--ink-faint);text-transform:uppercase;letter-spacing:.4px}
112
+ .panel .pf{padding:12px 20px;border-top:1px solid var(--line-soft);font:500 .68rem/1.5 var(--mono);color:var(--ink-faint)}
113
+ .verdict-band{background:var(--t2-bg);border:1px solid var(--t2);border-radius:12px;padding:16px 22px;font:500 .82rem/1.7 var(--mono);color:var(--ink)}
114
+ .verdict-band b{color:var(--t2)}
115
+
116
+ /* ── highlight callout ── */
117
+ .hl{background:var(--t2-bg);border:1px solid var(--t2);border-radius:14px;padding:22px 26px;margin:18px 0}
118
+ .hl.brass{background:var(--t1-bg);border-color:var(--t1)} .hl.rose{background:var(--t3-bg);border-color:var(--t3)}
119
+ .hl .k{font:600 .66rem/1 var(--mono);letter-spacing:1.5px;text-transform:uppercase;color:var(--t2)}
120
+ .hl.brass .k{color:var(--t1)} .hl.rose .k{color:var(--t3)}
121
+ .hl h3{font-family:var(--serif);font-weight:500;font-size:1.3rem;margin:8px 0 10px}
122
+ .hl p{font-size:.96rem} .hl .num{font-family:var(--serif);font-style:italic;color:var(--ink)}
123
+
124
+ /* ── Q/A ledger ── */
125
+ .ledger{margin:24px 0;border-top:1px solid var(--line)}
126
+ .ledger .row{display:grid;grid-template-columns:230px 1fr;gap:24px;padding:16px 4px;border-bottom:1px solid var(--line-soft)}
127
+ @media(max-width:680px){.ledger .row{grid-template-columns:1fr}}
128
+ .ledger .q{font:500 .78rem/1.5 var(--mono);color:var(--ink-faint);padding-top:3px}
129
+ .ledger .a{font-size:.95rem;color:var(--ink-soft)} .ledger .a b{color:var(--ink)}
130
+
131
+ /* ── numbered steps ── */
132
+ .steps{margin:24px 0;counter-reset:st}
133
+ .step{display:grid;grid-template-columns:40px 1fr;gap:16px;padding:14px 0;border-bottom:1px solid var(--line-soft)}
134
+ .step:last-child{border-bottom:none}
135
+ .step .b{counter-increment:st;font-family:var(--serif);font-size:1.25rem;color:var(--t1)} .step .b::before{content:counter(st,decimal-leading-zero)}
136
+ .step h4{font-family:var(--serif);font-weight:500;font-size:1.05rem;margin-bottom:3px} .step h4 .min{font:500 .64rem/1 var(--mono);color:var(--ink-faint);letter-spacing:.5px;margin-left:8px}
137
+ .step p{font-size:.9rem}
138
+
139
+ /* ── feature rows w/ trailing badges ── */
140
+ .feat{display:grid;grid-template-columns:1fr auto;gap:14px 20px;align-items:baseline;padding:14px 0;border-bottom:1px solid var(--line-soft)}
141
+ .feat:last-child{border-bottom:none} .feat .fx{font-size:.98rem;color:var(--ink-soft)} .feat .fx b{color:var(--ink);font-weight:600}
142
+ .feat .fb{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}
143
+
144
+ /* ── checkbox thread list (decisions) ── */
145
+ .threads{list-style:none;margin:24px 0}
146
+ .threads li{display:flex;gap:14px;padding:12px 0;border-bottom:1px solid var(--line-soft);font-size:.98rem;color:var(--ink-soft);align-items:baseline}
147
+ .threads li::before{content:"";flex:0 0 auto;width:12px;height:12px;border:1.5px solid var(--t1);border-radius:3px;transform:translateY(1px)}
148
+ .threads b{color:var(--ink)}
149
+
150
+ /* ── gap / negative callout ── */
151
+ .gap{background:var(--t3-bg);border:1px solid var(--t3);border-radius:14px;padding:22px 26px;margin:22px 0}
152
+ .gap h3{font-family:var(--serif);font-weight:500;font-size:1.15rem;color:var(--t3);margin-bottom:12px}
153
+ .gap ul{list-style:none} .gap li{padding:5px 0 5px 20px;position:relative;font-size:.94rem;color:var(--ink-soft)}
154
+ .gap li::before{content:"×";position:absolute;left:2px;color:var(--t3);font-weight:600} .gap li b{color:var(--ink)}
155
+
156
+ /* ── status / summary table ── */
157
+ .sumtable{width:100%;border-collapse:collapse;margin:24px 0;font-size:.9rem}
158
+ .sumtable th{text-align:left;font:600 .64rem/1 var(--mono);letter-spacing:.8px;text-transform:uppercase;color:var(--ink-faint);padding:0 12px 12px;border-bottom:1px solid var(--line)}
159
+ .sumtable th.c,.sumtable td.c{text-align:center}
160
+ .sumtable td{padding:11px 12px;border-bottom:1px solid var(--line-soft);color:var(--ink-soft);vertical-align:middle}
161
+ .sumtable tr td:first-child{color:var(--ink);font-weight:500}
162
+ .sumtable .tier{font:500 .64rem/1 var(--mono);text-transform:uppercase;letter-spacing:.4px;color:var(--ink-faint)}
163
+ .dot{display:inline-block;width:18px;height:18px;line-height:18px;border-radius:50%;font-size:.72rem;font-weight:700}
164
+ .dot.ok{background:var(--t2-bg);color:var(--t2)} .dot.half{background:var(--t1-bg);color:var(--t1)} .dot.no{background:var(--t3-bg);color:var(--t3)} .dot.neu{background:var(--paper-2);color:var(--ink-faint)}
165
+
166
+ /* ── accent-left readout ── */
167
+ .readout{background:var(--card);border:1px solid var(--line);border-left:3px solid var(--t1);border-radius:4px;padding:20px 24px;margin:28px 0;font-size:1rem;color:var(--ink-soft)}
168
+ .readout b{color:var(--ink)}
169
+
170
+ /* ── footer ── */
171
+ footer{padding:64px 0 90px;font:400 .74rem/1.8 var(--mono);color:var(--ink-faint)}
172
+ footer .tags{display:flex;gap:10px;flex-wrap:wrap;margin-top:12px}
173
+ footer .tg{border:1px solid var(--line-soft);border-radius:6px;padding:3px 10px;background:var(--card)}
174
+ </style>
175
+ </head>
176
+ <body>
177
+ <svg class="contours" width="100%" height="100%" preserveAspectRatio="none" viewBox="0 0 1400 900"><path d="M-50,160 C300,90 700,240 1450,130"/><path d="M-50,440 C400,360 900,540 1450,420"/><path d="M-50,720 C350,660 800,820 1450,710"/></svg>
178
+ <main>
179
+ <nav>
180
+ <span class="brand">EGREGORE · <b>__BRAND__</b></span>
181
+ <div class="links"><!-- NAV: one <a href="#anchor">Short label</a> per section --></div>
182
+ <button class="toggle" onclick="__t()">◐ <span id="tl">nocturne</span></button>
183
+ </nav>
184
+
185
+ <div class="wrap col">
186
+
187
+ <header class="hero">
188
+ <div class="series">__SERIES_KICKER__</div>
189
+ <h1>__LEAD__. <em>__ACCENT_PHRASE__</em></h1>
190
+ <p class="standfirst">__STANDFIRST__</p>
191
+ <div class="chips"><!-- CHIPS: from status/meta --></div>
192
+ </header>
193
+
194
+ <!-- COMPONENTS: compose sections here. Each section:
195
+ <hr class="rule"><section id="anchor">
196
+ <div class="seclabel"><span class="n">01</span> LABEL</div>
197
+ <h2>Statement title — the finding, not the raw heading.</h2>
198
+ … pick from the kit: .ledger .tagcard .claims .panels+.verdict-band
199
+ .hl .steps .feat .threads .gap .sumtable .readout …
200
+ </section>
201
+ -->
202
+
203
+ <footer>
204
+ __FOOTER_LINE__
205
+ <div class="tags"><span class="tg">__KIND__</span><span class="tg">__AUTHOR__</span><span class="tg">ugi · __TRAIL__</span><span class="tg">composed</span></div>
206
+ </footer>
207
+
208
+ </div>
209
+ </main>
210
+ <script>
211
+ (function(){
212
+ var saved=localStorage.getItem('eg-theme-mode');
213
+ var prefersDark=window.matchMedia('(prefers-color-scheme: dark)').matches;
214
+ var t=saved==='dark'||(saved!=='light'&&prefersDark)?'nocturne':'vellum';
215
+ apply(t);
216
+ window.__t=function(){apply(document.documentElement.dataset.theme==='vellum'?'nocturne':'vellum',true)};
217
+ function apply(theme,persist){document.documentElement.dataset.theme=theme;var el=document.getElementById('tl');if(el)el.textContent=theme==='vellum'?'nocturne':'vellum';if(persist)localStorage.setItem('eg-theme-mode',theme==='nocturne'?'dark':'light')}
218
+ })();
219
+ </script>
220
+ </body>
221
+ </html>
@@ -11,7 +11,7 @@
11
11
  {
12
12
  "section": "Identity & Upstream",
13
13
  "action": "keep",
14
- "sourceHash": "11d07e3fcb58",
14
+ "sourceHash": "ddcbc0083aff",
15
15
  "note": "Kept; /update, /contribute, /save tokens rendered as $skill tokens."
16
16
  },
17
17
  {
@@ -77,13 +77,13 @@
77
77
  {
78
78
  "section": "Working Conventions",
79
79
  "action": "keep",
80
- "sourceHash": "37a5318e9ee0",
80
+ "sourceHash": "2e4ec18b72a6",
81
81
  "note": "Kept verbatim."
82
82
  },
83
83
  {
84
84
  "section": "Command Awareness",
85
85
  "action": "keep",
86
- "sourceHash": "d3ea48ebf938",
86
+ "sourceHash": "e1db878ccaee",
87
87
  "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."
88
88
  },
89
89
  {
@@ -95,7 +95,7 @@
95
95
  {
96
96
  "section": "Telemetry",
97
97
  "action": "keep",
98
- "sourceHash": "f8b242d0fd64",
98
+ "sourceHash": "f45afa2da8ac",
99
99
  "note": "Kept verbatim — bin/telemetry.sh is runtime-neutral."
100
100
  },
101
101
  {
@@ -9,6 +9,11 @@
9
9
  > Egregore skill already covers. This file exists only for runtimes that cannot
10
10
  > read `CLAUDE.md`.
11
11
  >
12
+ > **If you are Pi** (the `pi` coding-agent harness): **stop here.** Your
13
+ > authoritative Egregore instructions are loaded from
14
+ > `.pi/APPEND_SYSTEM.md`, and your workflows are exposed through the
15
+ > project-local `.pi/` runtime. Do not follow the Codex-specific block below.
16
+ >
12
17
  > **If you are Codex or another shell-only agent:** this file is yours — continue.
13
18
 
14
19
  Egregore is no longer only a Claude Code workspace. Claude Code remains the
@@ -29,6 +34,12 @@ portable memory protocol below.
29
34
  Use the runtime-neutral bridge instead of Claude Code slash commands:
30
35
 
31
36
  ```bash
37
+ bin/agent.sh branch --topic "auth review"
38
+ bin/agent.sh save --message "Save: auth review" --topic "auth review"
39
+ bin/agent.sh wrap --from alice --topic "auth review" \
40
+ --summary "Implemented the OAuth callback parser and documented follow-ups." \
41
+ --body "Open threads: review error cases and browser redirects."
42
+
32
43
  bin/agent.sh handoff --from alice --to bob --topic "auth review" \
33
44
  --body "Implemented the OAuth callback parser. Bob should review error cases."
34
45
 
@@ -44,6 +55,17 @@ Each command writes to the existing Git-backed `memory/` repository and pushes
44
55
  when the memory repo has an `origin` remote. Agents that cannot run shell may
45
56
  write the same markdown files directly, following `docs/AGENT-PROTOCOL.md`.
46
57
 
58
+ ## Handoffs vs Emissaries
59
+
60
+ `bin/agent.sh handoff` is the runtime-neutral path for internal team
61
+ session-handoffs: it writes to `memory/handoffs/`, updates the index, and uses
62
+ the same `bin/handoff-run.sh` machinery as Claude Code's `/handoff`.
63
+
64
+ Portable external capsules are **emissaries**, not team handoffs. Claude Code
65
+ routes those through `/emissary`; non-Claude agents should use the
66
+ `egregore-emissary` CLI/skill when it is installed. Do not use the deprecated
67
+ `egregore-handoff` CLI for Egregore project `/handoff` work.
68
+
47
69
  ## Compatibility
48
70
 
49
71
  Claude Code users continue using `/handoff`, `/activity`, `/ask`, `/save`, and
@@ -63,7 +85,7 @@ This block is the Codex-native Egregore behavioral spec, rendered from CLAUDE.md
63
85
 
64
86
  ## Identity & Upstream
65
87
 
66
- This is an Egregore instance — a downstream fork of the upstream framework at `egregore-labs/egregore`. The framework (`bin/`, `.claude/skills/`, `.claude/hooks/`, `.claude/context/`, `.claude/agents/`, `loom/`, `CLAUDE.md`, `skills/`) is synced from upstream on every session start and via `$update`. It is not authored in this repo.
88
+ This is an Egregore instance — a downstream fork of the upstream framework at `egregore-labs/egregore`. The framework (`bin/`, `.claude/skills/`, `.claude/hooks/`, `.claude/context/`, `.claude/agents/`, `.pi/`, `loom/`, `CLAUDE.md`, `skills/`) is synced from upstream on every session start and via `$update`. It is not authored in this repo.
67
89
 
68
90
  **Where changes belong:**
69
91
  - **Framework is outdated or a skill is missing:** run `$update` first. It pulls the latest from upstream.
@@ -76,7 +98,7 @@ When a user reports broken or missing framework behavior, the first question is
76
98
 
77
99
  ## On Launch — MANDATORY FIRST ACTION
78
100
 
79
- The `egregore` launcher renders the Egregore startup card (identity, handoffs, team activity) 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`.
101
+ 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`.
80
102
 
81
103
  ---
82
104
 
@@ -230,7 +252,7 @@ Repos in `egregore.json` → `repos[]` are cloned as siblings (`../{repo}/`). Ea
230
252
 
231
253
  ## Working Conventions
232
254
 
233
- - Check `memory/knowledge/` before starting unfamiliar work
255
+ - Check memory before starting unfamiliar work — `bash bin/search.sh query "topic"` (hybrid search over all of `memory/`)
234
256
  - Document significant decisions in `memory/knowledge/decisions/`
235
257
  - After substantial sessions, log to `memory/handoffs/` and update `index.md`
236
258
 
@@ -238,12 +260,12 @@ Repos in `egregore.json` → `repos[]` are cloned as siblings (`../{repo}/`). Ea
238
260
 
239
261
  ## Command Awareness
240
262
 
241
- 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`. 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.
263
+ 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.
242
264
 
243
265
  Invoke commands from user intent — don't wait for the slash. Each command file has a `## When to invoke` section. Load it for the full spec.
244
266
 
245
267
  **Core loop** — `$activity` `$dashboard` `$handoff` `$wrap` `$save` `$reflect` `$todo`
246
- **Knowledge** — `$deep-reflect` `$archive` `$note` `$add` `$meeting` `$ingest`
268
+ **Knowledge** — `$search` `$deep-reflect` `$archive` `$note` `$add` `$meeting` `$ingest` `$scroll`
247
269
  **Identity** — `$me` (view profile or set display name)
248
270
  **Coordination** — `$ask` `$quest` `$issue` `$invite` `$delete-user` `$announce`
249
271
  **Connectors** — `$telegram-connect` (Telegram group setup)
@@ -253,6 +275,9 @@ Invoke commands from user intent — don't wait for the slash. Each command file
253
275
 
254
276
  **Disambiguation:**
255
277
  - Knowledge: `$reflect` (share-ready) · `$note` (half-baked) · `$deep-reflect` (cross-reference) · `$archive` (AI patterns)
278
+ - Finding things — the retrieval layers: **Grep/ls** (Claude Code / Codex file ops — always available, OSS) · **`bin/graph.sh`** (indexed relevance + relationships/status — paid). Use grep proactively; the graph deepens it when connected. (Semantic `$search` is dormant — evals showed it only pays off on massive unstructured data.)
279
+ - Finding **something you generated** (a scroll, handoff, emissary, decision, any hosted egregore.xyz link): `bash bin/artifacts.sh find <query>`. Every generative surface already records into memory — hosted artifacts self-register into `memory/artifacts/` at publish (and the record is committed+pushed, so it's findable from *any* session, not just the one that made it); handoffs land in `memory/handoffs/`, emissaries in `memory/handoffs/outbound/`, decisions/findings/patterns in `memory/knowledge/`. The finder searches **all** of them, ranks title/topic matches above passing body mentions, tags each hit by type (`[document]`/`[handoff]`/`[emissary]`/`[decision]`), and surfaces the shareable URL. Findable by **content, not just name**, across all three layers — grep-first for OSS, folding in search + graph when available. *"bring me the artifact where I laid out our GTM plan"* → this.
280
+ - Artifacts with questions: `$scroll` (living paper + embedded harvest, updates in place) · `$view` (static render) · `$harvest` (elicitation, no published face)
256
281
  - Status: `$dashboard` (personal) · `$activity` (org-wide)
257
282
  - Ending: `$wrap` (personal closure) · `$handoff` (notes for others) · `$save` (still working)
258
283
  - Tasks: `$todo` (personal) · `$quest` (team exploration) · `$issue` (something broken)
@@ -284,6 +309,7 @@ Privacy-respecting, opt-out telemetry. After every slash command, emit fire-and-
284
309
  `bash bin/telemetry.sh emit "command" '{"command":"save"}' 2>/dev/null &`
285
310
 
286
311
  Never collected: file contents, code, env var values, conversation content.
312
+ Command events may carry optional model/tier/routing/duration fields per `.claude/context/telemetry.md`.
287
313
  On first session (if `telemetry_noticed` not set in state file), mention the notice once, then set `telemetry_noticed: true`. Full spec: `.claude/context/telemetry.md`.
288
314
 
289
315
  ---
@@ -13,6 +13,8 @@ API_KEY=$(grep '^EGREGORE_API_KEY=' "$SCRIPT_DIR/.env" 2>/dev/null | cut -d'=' -
13
13
  ORG=$(jq -r '.org_name // "Egregore"' "$SCRIPT_DIR/egregore.json" 2>/dev/null || echo "Egregore")
14
14
  DATE=$(date '+%b %d')
15
15
 
16
+ source "$SCRIPT_DIR/bin/lib/handoff-meta.sh" >/dev/null 2>/dev/null || true
17
+
16
18
  # --- Detect user ---
17
19
  GH_USER="${1:-}"
18
20
  if [ -z "$GH_USER" ]; then
@@ -159,8 +161,8 @@ PRS=$(cat "$TMPDIR/prs.json" 2>/dev/null || echo "[]")
159
161
  echo "$PRS" | jq . >/dev/null 2>&1 || PRS="[]"
160
162
 
161
163
  # Resolve PR author GitHub logins -> egregore display names. `gh pr list` returns
162
- # the raw github login (e.g. "fcdagdelen"); without this it leaks into activity
163
- # instead of the person's display name ("cem"). Map via the graph when connected;
164
+ # the raw github login (e.g. "alice-gh"); without this it leaks into activity
165
+ # instead of the person's display name ("Alice"). Map via the graph when connected;
164
166
  # fall back to the github profile name, then the login. Author becomes a string.
165
167
  if [ -n "$PRS" ] && [ "$PRS" != "[]" ]; then
166
168
  AUTHOR_MAP='{}'
@@ -182,8 +184,28 @@ DISK_DECISIONS=$(cat "$TMPDIR/disk_decisions.txt" 2>/dev/null || echo "")
182
184
  LOCAL_SESSIONS=$(cat "$TMPDIR/local_sessions.json" 2>/dev/null || echo '{"my_sessions":[],"team_sessions":[]}')
183
185
  echo "$LOCAL_SESSIONS" | jq . >/dev/null 2>&1 || LOCAL_SESSIONS='{"my_sessions":[],"team_sessions":[]}'
184
186
 
187
+ handoff_metadata_map() {
188
+ local json="$1"
189
+
190
+ if ! declare -F eg_handoff_metadata_json >/dev/null 2>&1; then
191
+ echo "{}"
192
+ return
193
+ fi
194
+
195
+ printf '%s\n' "$json" | jq -r '
196
+ [(.handoffs_to_me[]?.filePath // empty), (.all_handoffs[]?.filePath // empty)]
197
+ | map(select(. != ""))
198
+ | unique[]
199
+ ' 2>/dev/null | while IFS= read -r rel; do
200
+ [ -z "$rel" ] && continue
201
+ file="$SCRIPT_DIR/memory/$rel"
202
+ [ -f "$file" ] || continue
203
+ eg_handoff_metadata_json "$file" | jq -c --arg rel "$rel" '{key:$rel, value:{author:.author, topic:.topic, date:.date}}'
204
+ done | jq -sc 'map({(.key): .value}) | add // {}' 2>/dev/null || echo "{}"
205
+ }
206
+
185
207
  # --- Merge server response + local git/disk data ---
186
- jq -n \
208
+ FINAL_JSON=$(jq -n \
187
209
  --arg org "$ORG" \
188
210
  --arg date "$DATE" \
189
211
  --slurpfile activity "$TMPDIR/activity.json" \
@@ -197,4 +219,24 @@ jq -n \
197
219
  prs: $prs,
198
220
  disk: {handoffs: $disk_handoffs, decisions: $disk_decisions},
199
221
  local_sessions: $local_sessions
200
- }'
222
+ }')
223
+
224
+ HANDOFF_META="$(handoff_metadata_map "$FINAL_JSON")"
225
+ [ -z "$HANDOFF_META" ] && HANDOFF_META="{}"
226
+
227
+ printf '%s\n' "$FINAL_JSON" | jq --argjson handoff_meta "$HANDOFF_META" '
228
+ def enrich_handoff_sender:
229
+ (.filePath // "") as $file
230
+ | if $file != "" and ($handoff_meta[$file] // null) != null then
231
+ ($handoff_meta[$file] // {}) as $meta
232
+ | .author = ($meta.author // .author)
233
+ | .from = ($meta.author // .from)
234
+ | .topic = (.topic // $meta.topic)
235
+ | .date = (.date // $meta.date)
236
+ else
237
+ .
238
+ end;
239
+
240
+ .handoffs_to_me = ((.handoffs_to_me // []) | map(enrich_handoff_sender))
241
+ | .all_handoffs = ((.all_handoffs // []) | map(enrich_handoff_sender))
242
+ '