create-egregore 0.19.2 → 0.19.5
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 +3 -1
- package/bin/cli.js +4 -1
- package/lib/local.js +78 -12
- package/lib/setup.js +15 -0
- package/package.json +2 -2
- package/runtime/codex/.codex/hooks/search-hint.js +65 -0
- package/runtime/codex/.codex/hooks.json +13 -0
- package/runtime/codex/.codex/skills/deep-reflect/SKILL.md +14 -10
- package/runtime/codex/.codex/skills/minion/SKILL.md +25 -0
- package/runtime/codex/.codex/skills/scroll/SKILL.md +168 -0
- package/runtime/codex/.codex/skills/scroll/agents/openai.yaml +4 -0
- package/runtime/codex/.codex/skills/scroll/assets/shell.html +542 -0
- package/runtime/codex/.codex/skills/search/SKILL.md +56 -0
- package/runtime/codex/.codex/skills/session-view/SKILL.md +25 -0
- package/runtime/codex/.codex/skills/thread/SKILL.md +25 -0
- package/runtime/codex/.codex/skills/view/SKILL.md +147 -32
- package/runtime/codex/.codex/skills/view/agents/openai.yaml +4 -0
- package/runtime/codex/.codex/skills/view/assets/compose-scaffold.html +221 -0
- package/runtime/codex/.codex/spec-manifest.json +3 -3
- package/runtime/codex/AGENTS.md +24 -3
- package/runtime/codex/bin/activity-data.sh +46 -4
- package/runtime/codex/bin/agent.sh +10 -2
- package/runtime/codex/bin/codex-install-skills.sh +1 -1
- package/runtime/codex/bin/codex-render-spec.mjs +18 -1
- package/runtime/codex/bin/codex-session-start.sh +1 -1
- package/runtime/codex/bin/codex-skill-render.mjs +13 -7
- package/runtime/codex/bin/codex-sync-skills.sh +4 -0
- package/runtime/codex/bin/graph-op.sh +56 -5
- package/runtime/codex/bin/graph.sh +36 -0
- package/runtime/codex/bin/handoff-run.sh +157 -7
- package/runtime/codex/bin/handoff-save-egregore.sh +6 -1
- package/runtime/codex/bin/index-handoff.sh +9 -3
- package/runtime/codex/bin/lib/context.sh +89 -17
- package/runtime/codex/bin/lib/dashboard-artifact.sh +1 -1
- package/runtime/codex/bin/lib/git-sync.sh +35 -9
- package/runtime/codex/bin/lib/greeting.sh +25 -3
- package/runtime/codex/bin/publish-artifact.sh +29 -1
- package/runtime/codex/manifest.json +16 -1
|
@@ -1,41 +1,156 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: view
|
|
3
|
-
description: '
|
|
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
|
-
|
|
6
|
+
# Egregore View
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Native Codex Egregore skill. Use only inside an Egregore checkout.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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,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>
|
|
@@ -77,13 +77,13 @@
|
|
|
77
77
|
{
|
|
78
78
|
"section": "Working Conventions",
|
|
79
79
|
"action": "keep",
|
|
80
|
-
"sourceHash": "
|
|
80
|
+
"sourceHash": "2e4ec18b72a6",
|
|
81
81
|
"note": "Kept verbatim."
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
84
|
"section": "Command Awareness",
|
|
85
85
|
"action": "keep",
|
|
86
|
-
"sourceHash": "
|
|
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": "
|
|
98
|
+
"sourceHash": "f45afa2da8ac",
|
|
99
99
|
"note": "Kept verbatim — bin/telemetry.sh is runtime-neutral."
|
|
100
100
|
},
|
|
101
101
|
{
|
package/runtime/codex/AGENTS.md
CHANGED
|
@@ -29,6 +29,12 @@ portable memory protocol below.
|
|
|
29
29
|
Use the runtime-neutral bridge instead of Claude Code slash commands:
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
+
bin/agent.sh branch --topic "auth review"
|
|
33
|
+
bin/agent.sh save --message "Save: auth review" --topic "auth review"
|
|
34
|
+
bin/agent.sh wrap --from alice --topic "auth review" \
|
|
35
|
+
--summary "Implemented the OAuth callback parser and documented follow-ups." \
|
|
36
|
+
--body "Open threads: review error cases and browser redirects."
|
|
37
|
+
|
|
32
38
|
bin/agent.sh handoff --from alice --to bob --topic "auth review" \
|
|
33
39
|
--body "Implemented the OAuth callback parser. Bob should review error cases."
|
|
34
40
|
|
|
@@ -44,6 +50,17 @@ Each command writes to the existing Git-backed `memory/` repository and pushes
|
|
|
44
50
|
when the memory repo has an `origin` remote. Agents that cannot run shell may
|
|
45
51
|
write the same markdown files directly, following `docs/AGENT-PROTOCOL.md`.
|
|
46
52
|
|
|
53
|
+
## Handoffs vs Emissaries
|
|
54
|
+
|
|
55
|
+
`bin/agent.sh handoff` is the runtime-neutral path for internal team
|
|
56
|
+
session-handoffs: it writes to `memory/handoffs/`, updates the index, and uses
|
|
57
|
+
the same `bin/handoff-run.sh` machinery as Claude Code's `/handoff`.
|
|
58
|
+
|
|
59
|
+
Portable external capsules are **emissaries**, not team handoffs. Claude Code
|
|
60
|
+
routes those through `/emissary`; non-Claude agents should use the
|
|
61
|
+
`egregore-emissary` CLI/skill when it is installed. Do not use the deprecated
|
|
62
|
+
`egregore-handoff` CLI for Egregore project `/handoff` work.
|
|
63
|
+
|
|
47
64
|
## Compatibility
|
|
48
65
|
|
|
49
66
|
Claude Code users continue using `/handoff`, `/activity`, `/ask`, `/save`, and
|
|
@@ -230,7 +247,7 @@ Repos in `egregore.json` → `repos[]` are cloned as siblings (`../{repo}/`). Ea
|
|
|
230
247
|
|
|
231
248
|
## Working Conventions
|
|
232
249
|
|
|
233
|
-
- Check
|
|
250
|
+
- Check memory before starting unfamiliar work — `bash bin/search.sh query "topic"` (hybrid search over all of `memory/`)
|
|
234
251
|
- Document significant decisions in `memory/knowledge/decisions/`
|
|
235
252
|
- After substantial sessions, log to `memory/handoffs/` and update `index.md`
|
|
236
253
|
|
|
@@ -238,12 +255,12 @@ Repos in `egregore.json` → `repos[]` are cloned as siblings (`../{repo}/`). Ea
|
|
|
238
255
|
|
|
239
256
|
## Command Awareness
|
|
240
257
|
|
|
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.
|
|
258
|
+
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
259
|
|
|
243
260
|
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
261
|
|
|
245
262
|
**Core loop** — `$activity` `$dashboard` `$handoff` `$wrap` `$save` `$reflect` `$todo`
|
|
246
|
-
**Knowledge** — `$deep-reflect` `$archive` `$note` `$add` `$meeting` `$ingest`
|
|
263
|
+
**Knowledge** — `$search` `$deep-reflect` `$archive` `$note` `$add` `$meeting` `$ingest` `$scroll`
|
|
247
264
|
**Identity** — `$me` (view profile or set display name)
|
|
248
265
|
**Coordination** — `$ask` `$quest` `$issue` `$invite` `$delete-user` `$announce`
|
|
249
266
|
**Connectors** — `$telegram-connect` (Telegram group setup)
|
|
@@ -253,6 +270,9 @@ Invoke commands from user intent — don't wait for the slash. Each command file
|
|
|
253
270
|
|
|
254
271
|
**Disambiguation:**
|
|
255
272
|
- Knowledge: `$reflect` (share-ready) · `$note` (half-baked) · `$deep-reflect` (cross-reference) · `$archive` (AI patterns)
|
|
273
|
+
- 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.)
|
|
274
|
+
- 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.
|
|
275
|
+
- Artifacts with questions: `$scroll` (living paper + embedded harvest, updates in place) · `$view` (static render) · `$harvest` (elicitation, no published face)
|
|
256
276
|
- Status: `$dashboard` (personal) · `$activity` (org-wide)
|
|
257
277
|
- Ending: `$wrap` (personal closure) · `$handoff` (notes for others) · `$save` (still working)
|
|
258
278
|
- Tasks: `$todo` (personal) · `$quest` (team exploration) · `$issue` (something broken)
|
|
@@ -284,6 +304,7 @@ Privacy-respecting, opt-out telemetry. After every slash command, emit fire-and-
|
|
|
284
304
|
`bash bin/telemetry.sh emit "command" '{"command":"save"}' 2>/dev/null &`
|
|
285
305
|
|
|
286
306
|
Never collected: file contents, code, env var values, conversation content.
|
|
307
|
+
Command events may carry optional model/tier/routing/duration fields per `.claude/context/telemetry.md`.
|
|
287
308
|
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
309
|
|
|
289
310
|
---
|
|
@@ -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. "
|
|
163
|
-
# instead of the person's display name ("
|
|
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
|
+
'
|
|
@@ -28,6 +28,8 @@ Runtime-neutral commands:
|
|
|
28
28
|
protocol Print the portable agent protocol
|
|
29
29
|
sync Pull latest shared memory
|
|
30
30
|
activity [--for <person>] Show recent handoffs and questions
|
|
31
|
+
search "query" [-n N] [--fast|--semantic]
|
|
32
|
+
Hybrid recall over shared memory (qmd)
|
|
31
33
|
people List known people from memory/people
|
|
32
34
|
branch --topic TEXT Create or reuse a task branch/worktree
|
|
33
35
|
save [--message TEXT] Commit and push current repo + memory changes
|
|
@@ -165,8 +167,9 @@ Egregore portable agent protocol
|
|
|
165
167
|
4. Use `bin/agent.sh handoff` to leave structured context for another agent.
|
|
166
168
|
5. Use `bin/agent.sh ask` and `bin/agent.sh answer` for asynchronous questions.
|
|
167
169
|
6. Run `bin/agent.sh activity --for <person>` to see pending work.
|
|
168
|
-
7. Run `bin/agent.sh
|
|
169
|
-
8. Run `bin/agent.sh
|
|
170
|
+
7. Run `bin/agent.sh search "<query>"` to recall shared memory (decisions, handoffs, knowledge) before answering questions about past work.
|
|
171
|
+
8. Run `bin/agent.sh branch --topic "<what you are working on>"` before code changes when you need a task branch/worktree.
|
|
172
|
+
9. Run `bin/agent.sh save` and `bin/agent.sh wrap` for portable save/wrap flows.
|
|
170
173
|
|
|
171
174
|
This protocol is runtime-neutral. Claude Code may still use .claude hooks and
|
|
172
175
|
skills, while Codex or another agent can call this script directly.
|
|
@@ -653,11 +656,16 @@ cmd_answer() {
|
|
|
653
656
|
echo "answered: memory/$rel"
|
|
654
657
|
}
|
|
655
658
|
|
|
659
|
+
cmd_search() {
|
|
660
|
+
bash "$SCRIPT_DIR/bin/search.sh" query "$@"
|
|
661
|
+
}
|
|
662
|
+
|
|
656
663
|
case "${1:-}" in
|
|
657
664
|
--help|-h|help|"") usage ;;
|
|
658
665
|
protocol) shift; cmd_protocol "$@" ;;
|
|
659
666
|
sync) shift; cmd_sync "$@" ;;
|
|
660
667
|
activity) shift; cmd_activity "$@" ;;
|
|
668
|
+
search) shift; cmd_search "$@" ;;
|
|
661
669
|
people) shift; cmd_people "$@" ;;
|
|
662
670
|
branch) shift; cmd_branch "$@" ;;
|
|
663
671
|
save) shift; cmd_save "$@" ;;
|