create-egregore 0.19.8 → 0.19.12
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 +266 -4
- package/lib/local.js +11 -1
- package/lib/setup.js +33 -0
- package/package.json +2 -2
- package/runtime/codex/.codex/hooks/branch-guard.js +242 -34
- package/runtime/codex/.codex/skills/activity/SKILL.md +18 -6
- package/runtime/codex/.codex/skills/deep-reflect/SKILL.md +90 -55
- package/runtime/codex/.codex/skills/deploy-bridge/SKILL.md +25 -0
- package/runtime/codex/.codex/skills/handoff/SKILL.md +6 -2
- package/runtime/codex/.codex/skills/save/SKILL.md +29 -5
- package/runtime/codex/.codex/skills/scroll/SKILL.md +54 -3
- package/runtime/codex/.codex/skills/task/SKILL.md +25 -0
- package/runtime/codex/.codex/skills/tui-design/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/wrap/SKILL.md +4 -1
- package/runtime/codex/.codex/spec-manifest.json +19 -7
- package/runtime/codex/AGENTS.md +63 -19
- package/runtime/codex/bin/activity-data.sh +1 -1
- package/runtime/codex/bin/agent.sh +88 -25
- package/runtime/codex/bin/attendant.sh +525 -0
- package/runtime/codex/bin/capture-reconcile.sh +67 -0
- package/runtime/codex/bin/capture-run.sh +341 -0
- package/runtime/codex/bin/codex-render-spec.mjs +29 -14
- package/runtime/codex/bin/codex-session-start.sh +49 -4
- package/runtime/codex/bin/codex-skill-render.mjs +23 -4
- package/runtime/codex/bin/graph-op.sh +719 -49
- package/runtime/codex/bin/graph-wal.sh +3 -2
- package/runtime/codex/bin/handoff-run.sh +72 -0
- package/runtime/codex/bin/handoff-save-egregore.sh +51 -11
- package/runtime/codex/bin/index-handoff.sh +26 -17
- package/runtime/codex/bin/ingest-graph.sh +80 -0
- package/runtime/codex/bin/ingest-surface.html +429 -0
- package/runtime/codex/bin/ingest.py +614 -0
- package/runtime/codex/bin/ingest.sh +231 -0
- package/runtime/codex/bin/ingest_graph.py +776 -0
- package/runtime/codex/bin/ingest_surface.py +464 -0
- package/runtime/codex/bin/lib/git-sync.sh +2 -6
- package/runtime/codex/bin/lib/greeting.sh +157 -22
- package/runtime/codex/bin/lib/identity.sh +50 -29
- package/runtime/codex/bin/lib/noncode.sh +31 -0
- package/runtime/codex/bin/person.py +610 -0
- package/runtime/codex/bin/person.sh +448 -0
- package/runtime/codex/bin/session-autosave.sh +184 -0
- package/runtime/codex/bin/session-log.sh +199 -0
- package/runtime/codex/bin/settings.sh +1 -1
- package/runtime/codex/manifest.json +19 -1
- package/runtime/pi/.codex/hooks/branch-guard.js +242 -34
- package/runtime/pi/.codex/skills/activity/SKILL.md +18 -6
- package/runtime/pi/.codex/skills/deep-reflect/SKILL.md +90 -55
- package/runtime/pi/.codex/skills/deploy-bridge/SKILL.md +25 -0
- package/runtime/pi/.codex/skills/handoff/SKILL.md +6 -2
- package/runtime/pi/.codex/skills/save/SKILL.md +29 -5
- package/runtime/pi/.codex/skills/scroll/SKILL.md +54 -3
- package/runtime/pi/.codex/skills/task/SKILL.md +25 -0
- package/runtime/pi/.codex/skills/tui-design/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/wrap/SKILL.md +4 -1
- package/runtime/pi/.codex/spec-manifest.json +19 -7
- package/runtime/pi/.pi/APPEND_SYSTEM.md +57 -14
- package/runtime/pi/.pi/extensions/egregore.ts +98 -8
- package/runtime/pi/.pi/spec-manifest.json +2 -2
- package/runtime/pi/AGENTS.md +63 -19
- package/runtime/pi/bin/activity-data.sh +1 -1
- package/runtime/pi/bin/agent.sh +88 -25
- package/runtime/pi/bin/attendant.sh +525 -0
- package/runtime/pi/bin/capture-reconcile.sh +67 -0
- package/runtime/pi/bin/capture-run.sh +341 -0
- package/runtime/pi/bin/codex-render-spec.mjs +29 -14
- package/runtime/pi/bin/codex-session-start.sh +49 -4
- package/runtime/pi/bin/codex-skill-render.mjs +23 -4
- package/runtime/pi/bin/graph-op.sh +719 -49
- package/runtime/pi/bin/graph-wal.sh +3 -2
- package/runtime/pi/bin/handoff-run.sh +72 -0
- package/runtime/pi/bin/handoff-save-egregore.sh +51 -11
- package/runtime/pi/bin/index-handoff.sh +26 -17
- package/runtime/pi/bin/ingest-graph.sh +80 -0
- package/runtime/pi/bin/ingest-surface.html +429 -0
- package/runtime/pi/bin/ingest.py +614 -0
- package/runtime/pi/bin/ingest.sh +231 -0
- package/runtime/pi/bin/ingest_graph.py +776 -0
- package/runtime/pi/bin/ingest_surface.py +464 -0
- package/runtime/pi/bin/lib/git-sync.sh +2 -6
- package/runtime/pi/bin/lib/greeting.sh +157 -22
- package/runtime/pi/bin/lib/identity.sh +50 -29
- package/runtime/pi/bin/lib/noncode.sh +31 -0
- package/runtime/pi/bin/person.py +610 -0
- package/runtime/pi/bin/person.sh +448 -0
- package/runtime/pi/bin/pi-branch-policy.mjs +164 -4
- package/runtime/pi/bin/pi-product-workflows.mjs +31 -2
- package/runtime/pi/bin/publish-artifact.sh +14 -0
- package/runtime/pi/bin/session-autosave.sh +184 -0
- package/runtime/pi/bin/session-log.sh +199 -0
- package/runtime/pi/bin/settings.sh +274 -0
- package/runtime/pi/manifest.json +20 -1
|
@@ -17,15 +17,37 @@ which branch, commit, push, pull request, or memory sync steps are required.
|
|
|
17
17
|
```bash
|
|
18
18
|
git status --short
|
|
19
19
|
git status --short memory 2>/dev/null || true
|
|
20
|
-
git branch --show-current
|
|
20
|
+
BRANCH=$(git branch --show-current)
|
|
21
|
+
AHEAD=0
|
|
22
|
+
OPEN_PR=""
|
|
23
|
+
case "$BRANCH" in
|
|
24
|
+
dev/*|feature/*|bugfix/*)
|
|
25
|
+
git fetch origin develop --quiet 2>/dev/null || true
|
|
26
|
+
AHEAD=$(git rev-list --count "origin/develop..HEAD" 2>/dev/null || echo 0)
|
|
27
|
+
if command -v gh >/dev/null 2>&1; then
|
|
28
|
+
OPEN_PR=$(gh pr list --head "$BRANCH" --base develop --state open \
|
|
29
|
+
--json url --jq '.[0].url // empty' 2>/dev/null || true)
|
|
30
|
+
fi
|
|
31
|
+
;;
|
|
32
|
+
esac
|
|
21
33
|
```
|
|
22
34
|
|
|
23
|
-
3.
|
|
24
|
-
|
|
35
|
+
3. A clean working tree alone does **not** mean the work is fully saved:
|
|
36
|
+
- If there are repo or memory changes, continue.
|
|
37
|
+
- If the task branch is ahead of `origin/develop` and `OPEN_PR` is empty,
|
|
38
|
+
continue even when the tree is clean. The bridge must push any committed
|
|
39
|
+
work and create the missing PR.
|
|
40
|
+
- Stop with "everything is already saved" only when there are no repo or
|
|
41
|
+
memory changes and either the branch has no commits to integrate
|
|
42
|
+
(`AHEAD=0`) or an open integration PR already exists.
|
|
25
43
|
4. Synthesize:
|
|
26
44
|
- a short topic from the work,
|
|
27
45
|
- a clear commit message,
|
|
28
|
-
- a one-line user-facing scope summary
|
|
46
|
+
- a one-line user-facing scope summary,
|
|
47
|
+
- a PR description following `.claude/context/pr-format.md`:
|
|
48
|
+
`## What` (1–4 bullets), `## Why` (1–3 sentences), and
|
|
49
|
+
`## Verification` (how the change was checked — required when the
|
|
50
|
+
diff touches non-markdown files; be honest if unverified).
|
|
29
51
|
5. If the scope is ambiguous or includes unrelated changes, ask for one compact
|
|
30
52
|
confirmation. Use structured Codex question tooling when available;
|
|
31
53
|
otherwise render:
|
|
@@ -40,11 +62,13 @@ Other:
|
|
|
40
62
|
6. Run the bridge command:
|
|
41
63
|
|
|
42
64
|
```bash
|
|
43
|
-
bin/agent.sh save --message "$MESSAGE" --topic "$TOPIC"
|
|
65
|
+
bin/agent.sh save --message "$MESSAGE" --topic "$TOPIC" --pr-body "$PR_BODY"
|
|
44
66
|
```
|
|
45
67
|
|
|
46
68
|
The bridge owns the mechanical workflow: sync memory, ensure a task branch,
|
|
47
69
|
commit repo changes, push, and create or reuse a pull request when available.
|
|
70
|
+
Always pass the synthesized `--pr-body` — the bridge only auto-generates a
|
|
71
|
+
skeleton body as a last resort, and the CI `pr-format` check gates every PR.
|
|
48
72
|
|
|
49
73
|
7. Parse the output and report only useful user information:
|
|
50
74
|
- branch name,
|
|
@@ -18,7 +18,7 @@ small fork. A scroll requires all three legs: face, harvest, and update loop.
|
|
|
18
18
|
## Structured UX parity
|
|
19
19
|
|
|
20
20
|
The browser artifact is the primary output. Preserve both tabs, deep links from
|
|
21
|
-
honest costs into decisions, the versioned copydock
|
|
21
|
+
honest costs into decisions, the versioned copydock return block, stable URL, and local
|
|
22
22
|
source path. Do not substitute a prose-only summary or expose raw publish output.
|
|
23
23
|
|
|
24
24
|
## Route the invocation
|
|
@@ -121,13 +121,64 @@ the same `--id`; never mint a new URL for an update. In local mode, publishing
|
|
|
121
121
|
is unavailable: open the file locally and report the source path without
|
|
122
122
|
suggesting configuration changes.
|
|
123
123
|
|
|
124
|
-
Add the URL or local path, source location, version, and
|
|
124
|
+
Add the URL or local path, source location, version, and return-block tag to the
|
|
125
125
|
relevant quest's log/artifacts tables. If no quest is relevant, keep the source
|
|
126
126
|
path as the durable record and state it.
|
|
127
127
|
|
|
128
|
+
## Creator gate — before any absorb
|
|
129
|
+
|
|
130
|
+
The scroll record `memory/scrolls/<slug>.md` names `creator: <person-slug>` and
|
|
131
|
+
optionally `trusted: [<person-slug>, …]`. A record missing `creator:` is
|
|
132
|
+
backfilled from unambiguous existing attribution, otherwise ask the user once
|
|
133
|
+
and write it — never silently default the gate open.
|
|
134
|
+
|
|
135
|
+
Derive the paster from the session person (`.egregore-state.json`, then git
|
|
136
|
+
config) — never from the return block's self-declared `respondent:` line, which
|
|
137
|
+
is attribution metadata, not an authorization credential.
|
|
138
|
+
|
|
139
|
+
If the paster is not the creator and not in `trusted:`, the return is **gated**:
|
|
140
|
+
|
|
141
|
+
1. Append a `turn-received` event to `memory/scrolls/.events/<slug>.jsonl`
|
|
142
|
+
(create the file if absent). Event ids are append-if-absent and MUST match
|
|
143
|
+
the Claude corpus exactly — both runtimes share one event log:
|
|
144
|
+
`turn.id = respondent + '|' + base_version + '|' + date + '|' + digest`;
|
|
145
|
+
digest = FNV-1a 32-bit hex over the UTF-8 bytes of
|
|
146
|
+
`JSON.stringify([respondent, String(base_version), date, sortedAnswers,
|
|
147
|
+
sortedOpens])` where `sortedAnswers` = answers sorted by fork id, each
|
|
148
|
+
mapped to the tuple `[fork, pick-or-UNDECIDED, note-or-empty]` (labels are
|
|
149
|
+
excluded), and `sortedOpens` = opens sorted by prompt id, each mapped to
|
|
150
|
+
`[prompt, text-or-UNDECIDED]`; every string is NFC-normalized and
|
|
151
|
+
CRLF→LF-normalized before hashing. Record `submitted_by: <paster>` on the
|
|
152
|
+
event (event-log metadata only — never projected into a published ledger)
|
|
153
|
+
and `merged_into: "pending"`.
|
|
154
|
+
2. Do NOT absorb: no `memory/knowledge/decisions/` writes, no spec/plan edits,
|
|
155
|
+
no face rewrite, no version bump, no republish of new content. Republishing
|
|
156
|
+
the unchanged current version to acknowledge the turn is allowed and appends
|
|
157
|
+
no version event.
|
|
158
|
+
3. Notify the creator — connected: `bash bin/notify.sh send <creator>
|
|
159
|
+
"<paster> answered your scroll <slug> (vN): <digest> — pending your review"`;
|
|
160
|
+
local: write an addressed handoff in `memory/handoffs/` naming the scroll,
|
|
161
|
+
paster, base version, digest, and the dispositions below. The contributor
|
|
162
|
+
may also send the artifact link directly.
|
|
163
|
+
4. Report the gated state and stop.
|
|
164
|
+
|
|
165
|
+
**Creator review.** The creator disposes in chat: **accept** (absorb into the
|
|
166
|
+
next version), **decline — <reason>** (mandatory nonblank note; refuse a
|
|
167
|
+
decline without one), per-answer overrides (top-level disposition is the
|
|
168
|
+
default, listed answers override; a turn with zero effectively accepted answers
|
|
169
|
+
is a plain decline; a zero-answer turn takes the top-level disposition), or
|
|
170
|
+
**synthesize** (compose one proposal from all pending turns — consensus
|
|
171
|
+
decides, conflicts become new explicit forks — and publish only on creator
|
|
172
|
+
approval). Every disposition appends `turn-reviewed`
|
|
173
|
+
`{type, turn, disposition: accepted|declined, by, date, note?, answers?}` with
|
|
174
|
+
id `review|<turn.id>` before any composition. An accepted turn stays pending
|
|
175
|
+
until a version actually absorbs it. Declined turns are never absorbed, stay
|
|
176
|
+
attributed in the log, and their reason travels with them. The creator's own
|
|
177
|
+
returns and trusted respondents keep the immediate loop below.
|
|
178
|
+
|
|
128
179
|
## Update loop
|
|
129
180
|
|
|
130
|
-
On a returned
|
|
181
|
+
On a returned block (creator or trusted paster — gated returns stop above):
|
|
131
182
|
|
|
132
183
|
1. **Absorb.** Parse Q/O lines and notes. Write durable decisions with their
|
|
133
184
|
reasoning to `memory/knowledge/decisions/`, update the underlying spec or
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: task
|
|
3
|
+
description: 'Create, import, inspect, approve, answer, or cancel work in the hosted Egregore Agent Desk. Use for `/task`, `$task`, “send this work to the agents,” “start these tasks,” Markdown development batches, or checking hosted task progress. This skill submits work to the hosted pipeline; it does not implement the task in the current local session.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- generated-by: bin/codex-sync-skills.sh -->
|
|
7
|
+
|
|
8
|
+
# Egregore task Adapter
|
|
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.
|
|
17
|
+
|
|
18
|
+
1. Read `.claude/skills/task/SKILL.md` for the workflow details.
|
|
19
|
+
2. Run the referenced `bin/` scripts directly from Codex.
|
|
20
|
+
3. Treat graph, publish, and notify steps as best-effort unless that workflow
|
|
21
|
+
explicitly says they are required.
|
|
22
|
+
4. Keep local-mode behavior filesystem-first and avoid graph or notification
|
|
23
|
+
calls when `egregore.json` declares `"mode": "local"`.
|
|
24
|
+
5. Never call the deprecated `egregore-handoff` CLI for Egregore project
|
|
25
|
+
handoffs.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tui-design
|
|
3
|
-
description: '
|
|
3
|
+
description: 'TUI Design System for Egregore slash commands. Use when designing or modifying any command''s terminal output to ensure visual consistency. Triggers on: TUI, terminal output, box drawing, command output formatting, sigils, section markers. Do NOT use for browser rendering (use dark-mode) or external prose (use egregore-voice).'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<!-- generated-by: bin/codex-sync-skills.sh -->
|
|
@@ -6,7 +6,10 @@ description: Wrap an Egregore session when the user invokes /wrap or $wrap, or s
|
|
|
6
6
|
# Egregore Wrap
|
|
7
7
|
|
|
8
8
|
Native Codex Egregore skill. Use this inside an Egregore checkout with
|
|
9
|
-
`bin/agent.sh`.
|
|
9
|
+
`bin/agent.sh`. The command routes through `bin/capture-run.sh --mode personal`.
|
|
10
|
+
It writes the personal record first, appends graph and handoff-completion events
|
|
11
|
+
to the local WAL, and reconciles them detached; do not wait for or repeat that
|
|
12
|
+
background work.
|
|
10
13
|
|
|
11
14
|
## Flow
|
|
12
15
|
|
|
@@ -14,6 +14,18 @@
|
|
|
14
14
|
"sourceHash": "ddcbc0083aff",
|
|
15
15
|
"note": "Kept; /update, /contribute, /save tokens rendered as $skill tokens."
|
|
16
16
|
},
|
|
17
|
+
{
|
|
18
|
+
"section": "Cross-Runtime Compatibility",
|
|
19
|
+
"action": "keep",
|
|
20
|
+
"sourceHash": "75d02e2603f5",
|
|
21
|
+
"note": "Kept verbatim — framework parity applies equally to Claude Code, Codex, and Pi."
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"section": "Voice",
|
|
25
|
+
"action": "keep",
|
|
26
|
+
"sourceHash": "af73d4eaa7cd",
|
|
27
|
+
"note": "Kept — all runtimes can consult the shared voice rules and register-specific skills."
|
|
28
|
+
},
|
|
17
29
|
{
|
|
18
30
|
"section": "On Launch — MANDATORY FIRST ACTION",
|
|
19
31
|
"action": "replace",
|
|
@@ -23,19 +35,19 @@
|
|
|
23
35
|
{
|
|
24
36
|
"section": "After Greeting — BRANCH ON FIRST RESPONSE",
|
|
25
37
|
"action": "replace",
|
|
26
|
-
"sourceHash": "
|
|
38
|
+
"sourceHash": "bce266fb848b",
|
|
27
39
|
"note": "EnterWorktree -> bin/agent.sh branch with git checkout fallback; AskUserQuestion -> numbered options in plain text; branch-guard mapped to .codex/hooks/branch-guard.js with instruction fallback; plan-mode note dropped (no plan mode on Codex); /branch + /onboarding -> skill tokens. Handoff claiming and repoState auto-checkout kept verbatim (pure git)."
|
|
28
40
|
},
|
|
29
41
|
{
|
|
30
42
|
"section": "Config Files",
|
|
31
43
|
"action": "keep",
|
|
32
|
-
"sourceHash": "
|
|
44
|
+
"sourceHash": "8d7f1bd0f2d9",
|
|
33
45
|
"note": "Kept verbatim — shell facts, runtime-neutral."
|
|
34
46
|
},
|
|
35
47
|
{
|
|
36
48
|
"section": "Knowledge Graph",
|
|
37
49
|
"action": "keep",
|
|
38
|
-
"sourceHash": "
|
|
50
|
+
"sourceHash": "b5d9a149f1a6",
|
|
39
51
|
"note": "Kept verbatim — bin/graph.sh is runtime-neutral."
|
|
40
52
|
},
|
|
41
53
|
{
|
|
@@ -71,7 +83,7 @@
|
|
|
71
83
|
{
|
|
72
84
|
"section": "Git Workflow",
|
|
73
85
|
"action": "keep",
|
|
74
|
-
"sourceHash": "
|
|
86
|
+
"sourceHash": "49fd4625fa1e",
|
|
75
87
|
"note": "Kept; slash tokens rendered as $skill tokens. Branch diagram unchanged (code fence)."
|
|
76
88
|
},
|
|
77
89
|
{
|
|
@@ -83,7 +95,7 @@
|
|
|
83
95
|
{
|
|
84
96
|
"section": "Command Awareness",
|
|
85
97
|
"action": "keep",
|
|
86
|
-
"sourceHash": "
|
|
98
|
+
"sourceHash": "ce5eb3015427",
|
|
87
99
|
"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
100
|
},
|
|
89
101
|
{
|
|
@@ -107,8 +119,8 @@
|
|
|
107
119
|
{
|
|
108
120
|
"section": "Environment Isolation",
|
|
109
121
|
"action": "replace",
|
|
110
|
-
"sourceHash": "
|
|
111
|
-
"note": "boundary-check is a Claude PreToolUse hook with no .codex equivalent —
|
|
122
|
+
"sourceHash": "086e2c1d9019",
|
|
123
|
+
"note": "boundary-check is a Claude PreToolUse hook with no .codex equivalent — two-tier model stated as a standing instruction; AskUserQuestion remediation -> numbered options, now including the two consent-grant options (session grant -> .egregore-boundary-consent, instance grant -> .egregore-boundary.local.json read[])."
|
|
112
124
|
}
|
|
113
125
|
]
|
|
114
126
|
}
|
package/runtime/codex/AGENTS.md
CHANGED
|
@@ -35,7 +35,8 @@ Use the runtime-neutral bridge instead of Claude Code slash commands:
|
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
37
|
bin/agent.sh branch --topic "auth review"
|
|
38
|
-
bin/agent.sh save --message "Save: auth review" --topic "auth review"
|
|
38
|
+
bin/agent.sh save --message "Save: auth review" --topic "auth review" \
|
|
39
|
+
--pr-body "$PR_BODY" # body per .claude/context/pr-format.md (auto-skeleton if omitted)
|
|
39
40
|
bin/agent.sh wrap --from alice --topic "auth review" \
|
|
40
41
|
--summary "Implemented the OAuth callback parser and documented follow-ups." \
|
|
41
42
|
--body "Open threads: review error cases and browser redirects."
|
|
@@ -96,6 +97,24 @@ When a user reports broken or missing framework behavior, the first question is
|
|
|
96
97
|
|
|
97
98
|
---
|
|
98
99
|
|
|
100
|
+
## Cross-Runtime Compatibility
|
|
101
|
+
|
|
102
|
+
Framework behavior must work across Claude Code, Codex, and Pi Egregores. Put
|
|
103
|
+
shared mechanics in runtime-neutral `bin/` scripts; keep `.claude/`, `.codex/`,
|
|
104
|
+
and `.pi/` as thin adapters to those mechanics. When changing startup, session
|
|
105
|
+
lifecycle, capture, skills, or commands, trace all three runtime entry points
|
|
106
|
+
and add or update a parity test. Do not call a framework change complete based
|
|
107
|
+
on one runtime alone. Regenerate derived Codex and Pi specifications or runtime
|
|
108
|
+
bundles whenever their sources change.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Voice
|
|
113
|
+
|
|
114
|
+
Egregore's voice is governed by `.claude/rules/voice-bedrock.md` (always loaded). Register-specific skills: `egregore-voice` (external), `product-voice` (internal UX), `character-v4` (encounters), `alpha-openers` (outreach). See voice-bedrock for the full register map.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
99
118
|
## On Launch — MANDATORY FIRST ACTION
|
|
100
119
|
|
|
101
120
|
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`.
|
|
@@ -146,19 +165,22 @@ If on develop after two messages, create a branch immediately from whatever cont
|
|
|
146
165
|
|
|
147
166
|
### Branch-guard protocol
|
|
148
167
|
|
|
149
|
-
The `.codex/hooks/branch-guard.js` PreToolUse hook (enabled by the launcher via `--enable hooks`)
|
|
168
|
+
The `.codex/hooks/branch-guard.js` PreToolUse hook (enabled by the launcher via `--enable hooks`) protects project writes on `develop`/`main`/`master`. Its block message is operational guidance, not a reason to interrupt the user with routine Git choices:
|
|
150
169
|
|
|
151
|
-
- **Topic is
|
|
152
|
-
- **Topic is ambiguous**
|
|
170
|
+
- **Topic is clear** (the user said "fix X", "add Y feature") → run `bin/agent.sh branch --topic "<topic>"` automatically, continue in the printed worktree, and say one short sentence so the branch change is visible. Do not ask the user to approve routine branching.
|
|
171
|
+
- **Topic is genuinely ambiguous** → ask only for the topic, using compact numbered options:
|
|
153
172
|
|
|
154
173
|
```text
|
|
155
|
-
|
|
174
|
+
What should I call this work?
|
|
156
175
|
1. <suggested slug from context>
|
|
157
176
|
2. <alternative slug>
|
|
158
177
|
3. Other: (name it)
|
|
159
178
|
```
|
|
160
179
|
|
|
161
180
|
Wait for the reply, then branch.
|
|
181
|
+
- **The user explicitly requested the protected branch** → that request is consent. Record it with `echo '{branch}' > .egregore-branch-consent`, then retry. Never create the marker merely to silence the hook.
|
|
182
|
+
|
|
183
|
+
Memory, managed-repo, and runtime-state writes should bypass the project guard. If one triggers it, correct the operation target/context instead of asking for protected-branch consent.
|
|
162
184
|
|
|
163
185
|
If this Codex build does not support hooks, follow the same discipline as a standing instruction: never write or commit on develop/main/master.
|
|
164
186
|
|
|
@@ -170,7 +192,7 @@ If the startup card output contains `onboarding_needed`, invoke the `$onboarding
|
|
|
170
192
|
|
|
171
193
|
## Config Files
|
|
172
194
|
|
|
173
|
-
- **`egregore.json`** — committed. Non-secret org config: `org_name`, `github_org`, `memory_repo`, `slug`, `mode`. `api_url` is connected-mode only. **Never put secrets here.**
|
|
195
|
+
- **`egregore.json`** — committed. Non-secret org config: `org_name`, `github_org`, `memory_repo`, `slug`, `mode`. `api_url` is connected-mode only. Optional `boundary { posture, read[], locked }` sets the org's isolation posture (see Environment Isolation). **Never put secrets here.**
|
|
174
196
|
- **`.env`** — gitignored. Personal secrets. Local mode: `GITHUB_TOKEN` only. Connected mode: `GITHUB_TOKEN` + `EGREGORE_API_KEY`. **Never use `source .env`** — use `grep '^KEY=' .env | cut -d'=' -f2-`.
|
|
175
197
|
|
|
176
198
|
In connected mode, infrastructure credentials (Neo4j, Telegram) live on the API server only — `bin/graph.sh` and `bin/notify.sh` route through the API gateway.
|
|
@@ -179,7 +201,22 @@ In connected mode, infrastructure credentials (Neo4j, Telegram) live on the API
|
|
|
179
201
|
|
|
180
202
|
## Knowledge Graph
|
|
181
203
|
|
|
182
|
-
**Connected mode only.**
|
|
204
|
+
**Connected mode only.** For the following intents, the named read must be the
|
|
205
|
+
first retrieval action. Run the exact command with its safe default limit before
|
|
206
|
+
opening files, running broad grep, inspecting `graph-op.sh`, or writing Cypher:
|
|
207
|
+
|
|
208
|
+
- current work addressed to someone → `bash bin/graph-op.sh open-handoffs "<user>"`
|
|
209
|
+
- unanswered questions for someone → `bash bin/graph-op.sh pending-questions "<user>"`
|
|
210
|
+
- handoff → implementation → branch/PR/direction → `bash bin/graph-op.sh lineage "<topic>"`
|
|
211
|
+
- company/person/topic across meetings → `bash bin/graph-op.sh meeting-history "<entity-or-topic>"`
|
|
212
|
+
|
|
213
|
+
A question about calls, meetings, transcripts, demos, or how a conversation
|
|
214
|
+
evolved is always `meeting-history` intent when it names a company, person, or
|
|
215
|
+
topic—even when it does not ask for "current" or "live" state. Pass the shortest
|
|
216
|
+
discriminative entity or topic (for example, `meeting-history "42CAP"`), not the
|
|
217
|
+
whole question.
|
|
218
|
+
|
|
219
|
+
Run `catalog` only when the route is unclear. Named reads return bounded stable fields and exact canonical `evidencePath` pointers; open only the returned files needed to answer. When a read reports partial coverage, use `unprojectedPaths` rather than claiming those files are represented in the graph. Use `bin/graph.sh` for unsupported Neo4j queries and never construct curl calls directly. See DEVELOPMENT.md §1 for the schema. In local mode there is no graph; read `memory/` directly.
|
|
183
220
|
|
|
184
221
|
---
|
|
185
222
|
|
|
@@ -244,6 +281,10 @@ main ← stable (/release)
|
|
|
244
281
|
- **Memory repo**: stays on main (separate repo, auto-merge).
|
|
245
282
|
- **Never push directly to main or develop.** All changes flow through PRs.
|
|
246
283
|
|
|
284
|
+
### Pull request format (all harnesses)
|
|
285
|
+
|
|
286
|
+
Every PR body follows `.claude/context/pr-format.md`, enforced by the `pr-format` CI check regardless of which harness opened it: `## What` (1–4 bullets) + `## Why` (1–3 sentences) always; `## Verification` when the diff touches non-markdown files (how it was checked, or an honest `Not verified — <reason>`); `## Risk`/`## Links` when real; title `type(scope): imperative summary` (advisory). **Never create a PR with an empty body or `--fill`** — write the body and pass it explicitly (`gh pr create --body`, or `bin/agent.sh save --pr-body` for shell agents; the bridge auto-generates a compliant skeleton only as a last resort).
|
|
287
|
+
|
|
247
288
|
### Managed Repos
|
|
248
289
|
|
|
249
290
|
Repos in `egregore.json` → `repos[]` are cloned as siblings (`../{repo}/`). Each entry can be a string or `{"name": "...", "description": "..."}`. Match user intent to the right repo using `description`. Same branching strategy. Use `git -C` with absolute paths — never `cd` into repos. `$save` scans all managed repos for uncommitted changes.
|
|
@@ -268,13 +309,13 @@ Invoke commands from user intent — don't wait for the slash. Each command file
|
|
|
268
309
|
**Knowledge** — `$search` `$deep-reflect` `$archive` `$note` `$add` `$meeting` `$ingest` `$scroll`
|
|
269
310
|
**Identity** — `$me` (view profile or set display name)
|
|
270
311
|
**Coordination** — `$ask` `$quest` `$issue` `$invite` `$delete-user` `$announce`
|
|
271
|
-
**Connectors** — `$telegram-connect` (Telegram group setup)
|
|
312
|
+
**Connectors** — `$telegram-connect` (Telegram group setup) `$teams-connect` (Microsoft Teams channel setup)
|
|
272
313
|
**Git** — `$branch` `$commit` `$push` `$pr` `$save` `$review-pr` `$contribute`
|
|
273
314
|
**Spirits** — `$summon` (persistent agent processes)
|
|
274
315
|
**Infra** — `$setup` `$update` `$pull` `$env` `$infra` `$sync-repos` `$release` `$checkup`
|
|
275
316
|
|
|
276
317
|
**Disambiguation:**
|
|
277
|
-
- Knowledge: `$reflect` (share-ready) · `$note` (half-baked) · `$deep-reflect` (cross-
|
|
318
|
+
- Knowledge: `$reflect` (share-ready) · `$note` (half-baked) · `$deep-reflect` (deep research over memory — questions AND cross-referencing) · `$archive` (AI patterns)
|
|
278
319
|
- 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
320
|
- 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
321
|
- Artifacts with questions: `$scroll` (living paper + embedded harvest, updates in place) · `$view` (static render) · `$harvest` (elicitation, no published face)
|
|
@@ -282,8 +323,8 @@ Invoke commands from user intent — don't wait for the slash. Each command file
|
|
|
282
323
|
- Ending: `$wrap` (personal closure) · `$handoff` (notes for others) · `$save` (still working)
|
|
283
324
|
- Tasks: `$todo` (personal) · `$quest` (team exploration) · `$issue` (something broken)
|
|
284
325
|
- Questions: `$ask [person]` (async) · just ask (agent answers from context)
|
|
285
|
-
- Ingestion: `$ingest meeting` · `$ingest user-interview` · `$ingest google` · ambiguous → ask which type
|
|
286
|
-
- Connectors: `$telegram-connect` (Telegram group) · `$ingest` (bring content in)
|
|
326
|
+
- Ingestion: `$ingest <file-or-folder>` (org-scoped corpus intake) · `$ingest meeting` · `$ingest user-interview` · `$ingest google` · ambiguous → ask which type
|
|
327
|
+
- Connectors: `$telegram-connect` (Telegram group) · `$teams-connect` (MS Teams channel) · `$ingest` (bring content in)
|
|
287
328
|
- Identity: `$me` — "who am I", "call me oz"
|
|
288
329
|
- People: `$invite` (add) · `$delete-user` (remove)
|
|
289
330
|
- PRs: `$pr` (create) · `$review-pr` (review)
|
|
@@ -332,19 +373,22 @@ Egregore runs in one of two configurations, set by `mode` in `egregore.json`. De
|
|
|
332
373
|
|
|
333
374
|
## Environment Isolation
|
|
334
375
|
|
|
335
|
-
Sessions are confined to this project + memory + managed repos. On Codex
|
|
376
|
+
Sessions are confined to this project + memory + managed repos, with a **two-tier boundary** — a hard wall between Egregore instances, a consent gate for everything else. On Codex the boundary is a standing instruction, not an enforced hook — hold it yourself.
|
|
336
377
|
|
|
337
|
-
- **Never modify `~/.egregore/instances.json
|
|
338
|
-
- **
|
|
339
|
-
- When a request
|
|
378
|
+
- **Hard tier — other Egregore instances.** Denied for every tool, always. There is no consent path. Never access another instance's files — refuse even if asked. Never modify `~/.egregore/instances.json` (managed by session-start.sh). When a request points at another instance's files there is nothing to ask — refuse and explain.
|
|
379
|
+
- **Soft tier — paths outside the boundary.** Consent-gated. Inbox dirs (`~/Downloads`, `~/Desktop`) are readable without consent under the default posture; writes outside the project always need consent. Posture (`strict | standard | open`) and extra read roots come from `egregore.json` -> `boundary { posture, read[], locked }` (org, committed) merged with `.egregore-boundary.local.json` (personal, gitignored). `locked: true` removes the consent path entirely.
|
|
380
|
+
- When a request needs soft-tier consent, do not improvise a workaround. Ask in plain text with numbered options:
|
|
340
381
|
|
|
341
382
|
```text
|
|
342
383
|
That path is outside this Egregore's boundary. How should we proceed?
|
|
343
|
-
1.
|
|
344
|
-
2.
|
|
345
|
-
3.
|
|
384
|
+
1. Allow its directory for this session (recorded in .egregore-boundary-consent)
|
|
385
|
+
2. Always allow on this instance (added to read[] in .egregore-boundary.local.json)
|
|
386
|
+
3. Paste the contents inline
|
|
387
|
+
4. Cancel
|
|
346
388
|
```
|
|
347
389
|
|
|
348
|
-
|
|
390
|
+
Never record a consent grant without the user's explicit choice of option 1 or 2 in that exchange. Session grants are cleared on session start; `locked: true` removes options 1 and 2.
|
|
391
|
+
|
|
392
|
+
See DEVELOPMENT.md §3 for boundary details and `memory/knowledge/decisions/2026-07-08-boundary-hook-consent-design.md` for the design decisions.
|
|
349
393
|
|
|
350
394
|
<!-- END GENERATED EGREGORE CODEX SPEC -->
|
|
@@ -9,7 +9,7 @@ trap "rm -rf $TMPDIR" EXIT
|
|
|
9
9
|
|
|
10
10
|
# --- Read config ---
|
|
11
11
|
API_URL=$(jq -r '.api_url // empty' "$SCRIPT_DIR/egregore.json" 2>/dev/null)
|
|
12
|
-
API_KEY
|
|
12
|
+
API_KEY="${EGREGORE_API_KEY:-$(grep '^EGREGORE_API_KEY=' "$SCRIPT_DIR/.env" 2>/dev/null | cut -d'=' -f2-)}"
|
|
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
|
|
|
@@ -32,9 +32,13 @@ Runtime-neutral commands:
|
|
|
32
32
|
Hybrid recall over shared memory (qmd)
|
|
33
33
|
people List known people from memory/people
|
|
34
34
|
branch --topic TEXT Create or reuse a task branch/worktree
|
|
35
|
-
save [--message TEXT]
|
|
35
|
+
save [--message TEXT] [--pr-body TEXT|--pr-body-file PATH]
|
|
36
|
+
Commit and push current repo + memory changes;
|
|
37
|
+
PR body follows .claude/context/pr-format.md
|
|
38
|
+
(auto-generated skeleton if not provided)
|
|
36
39
|
wrap --topic T --summary TEXT Write a session wrap to memory/wraps
|
|
37
|
-
handoff --from A --to B --topic T [--
|
|
40
|
+
handoff --from A --to B --topic T [--intent action|feedback|fyi]
|
|
41
|
+
[--body TEXT|--body-file PATH] [--no-push] [--no-publish] [--no-notify] [--json]
|
|
38
42
|
ask --from A --to B --topic T --question TEXT [--no-push]
|
|
39
43
|
[--harvest-id ID --harvest-session-id ID --turn N
|
|
40
44
|
--question-intent TEXT --context-mode blind|disclosed|comparative]
|
|
@@ -331,13 +335,26 @@ ensure_working_branch() {
|
|
|
331
335
|
echo "$branch"
|
|
332
336
|
}
|
|
333
337
|
|
|
338
|
+
build_pr_body() {
|
|
339
|
+
# Compliant fallback PR body (spec: .claude/context/pr-format.md) built
|
|
340
|
+
# from the commit log + diff when the calling agent supplies none.
|
|
341
|
+
local topic="${1:-portable save}" commits stat
|
|
342
|
+
commits="$(git -C "$SCRIPT_DIR" log --pretty='- %s' "origin/develop..HEAD" 2>/dev/null | head -8)"
|
|
343
|
+
[ -n "$commits" ] || commits="- (commit list unavailable — see the Files tab)"
|
|
344
|
+
stat="$(git -C "$SCRIPT_DIR" diff --shortstat "origin/develop...HEAD" 2>/dev/null | sed 's/^ *//')"
|
|
345
|
+
printf '## What\n%s\n\n## Why\nShell-agent session save — topic: %s. Body auto-generated by bin/agent.sh; pass --pr-body for a hand-written description.\n\n## Verification\nNot verified — auto-generated skeleton; review the diff before merging.%s\n\n🤖 Saved via bin/agent.sh\n' \
|
|
346
|
+
"$commits" "$topic" "${stat:+ ($stat)}"
|
|
347
|
+
}
|
|
348
|
+
|
|
334
349
|
cmd_save() {
|
|
335
|
-
local message="" topic="" no_pr=0 branch pushed="false" committed="false" pr_url="" existing_pr=""
|
|
350
|
+
local message="" topic="" no_pr=0 branch pushed="false" committed="false" pr_url="" existing_pr="" pr_number="" non_md="" merged="false" pr_body="" pr_body_file=""
|
|
336
351
|
|
|
337
352
|
while [ $# -gt 0 ]; do
|
|
338
353
|
case "$1" in
|
|
339
354
|
--message|-m) message="${2:-}"; shift 2 ;;
|
|
340
355
|
--topic) topic="${2:-}"; shift 2 ;;
|
|
356
|
+
--pr-body) pr_body="${2:-}"; shift 2 ;;
|
|
357
|
+
--pr-body-file) pr_body_file="${2:-}"; shift 2 ;;
|
|
341
358
|
--no-pr) no_pr=1; shift ;;
|
|
342
359
|
*) die "unknown save option: $1" ;;
|
|
343
360
|
esac
|
|
@@ -375,7 +392,31 @@ cmd_save() {
|
|
|
375
392
|
if [ -n "$existing_pr" ]; then
|
|
376
393
|
pr_url="$existing_pr"
|
|
377
394
|
else
|
|
378
|
-
|
|
395
|
+
if [ -z "$pr_body" ] && [ -n "$pr_body_file" ] && [ -f "$pr_body_file" ]; then
|
|
396
|
+
pr_body="$(cat "$pr_body_file")"
|
|
397
|
+
fi
|
|
398
|
+
[ -n "$pr_body" ] || pr_body="$(build_pr_body "$topic")"
|
|
399
|
+
pr_url="$(gh pr create --base develop --head "$branch" --title "$message" --body "$pr_body" 2>/dev/null || true)"
|
|
400
|
+
fi
|
|
401
|
+
fi
|
|
402
|
+
|
|
403
|
+
# Non-coding saves auto-merge to develop (same rule as /save and the
|
|
404
|
+
# handoff helper; policy in bin/lib/noncode.sh). `--auto` needs repo
|
|
405
|
+
# auto-merge + pending required checks; without branch protection it always
|
|
406
|
+
# errors, so fall back to a direct merge.
|
|
407
|
+
if [ -n "$pr_url" ]; then
|
|
408
|
+
# shellcheck source=bin/lib/noncode.sh
|
|
409
|
+
. "$SCRIPT_DIR/bin/lib/noncode.sh" 2>/dev/null || true
|
|
410
|
+
type noncode_blockers >/dev/null 2>&1 || noncode_blockers() {
|
|
411
|
+
git -C "${2:-.}" diff "${1:-origin/develop}...HEAD" --name-only 2>/dev/null | grep -v '\.md$' | head -1 || true
|
|
412
|
+
}
|
|
413
|
+
pr_number="${pr_url##*/}"
|
|
414
|
+
non_code="$(noncode_blockers origin/develop "$SCRIPT_DIR")"
|
|
415
|
+
if [ -z "$non_code" ] && [ -n "$pr_number" ]; then
|
|
416
|
+
if gh pr merge "$pr_number" --auto --merge >/dev/null 2>&1 \
|
|
417
|
+
|| gh pr merge "$pr_number" --merge >/dev/null 2>&1; then
|
|
418
|
+
merged="true"
|
|
419
|
+
fi
|
|
379
420
|
fi
|
|
380
421
|
fi
|
|
381
422
|
|
|
@@ -383,6 +424,7 @@ cmd_save() {
|
|
|
383
424
|
echo "commit: $committed"
|
|
384
425
|
echo "push: $pushed"
|
|
385
426
|
[ -n "$pr_url" ] && echo "pr: $pr_url"
|
|
427
|
+
[ "$merged" = "true" ] && echo "merge: non-coding, merged to develop"
|
|
386
428
|
return 0
|
|
387
429
|
}
|
|
388
430
|
|
|
@@ -413,31 +455,38 @@ cmd_wrap() {
|
|
|
413
455
|
fi
|
|
414
456
|
[ -n "$body" ] || body="$summary"
|
|
415
457
|
|
|
416
|
-
local
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
458
|
+
local tmpd result rel session_id branch
|
|
459
|
+
local capture_args=(--mode personal)
|
|
460
|
+
tmpd="$(mktemp -d -t egregore-agent-wrap-XXXXXX)"
|
|
461
|
+
trap 'rm -rf "$tmpd"' RETURN
|
|
462
|
+
session_id="$(cat "$SCRIPT_DIR/.egregore-session-id" 2>/dev/null || true)"
|
|
463
|
+
branch="$(git -C "$SCRIPT_DIR" branch --show-current 2>/dev/null || true)"
|
|
464
|
+
[ "$no_push" = "1" ] && capture_args+=(--no-push)
|
|
465
|
+
|
|
466
|
+
printf '%s\n' "$body" |
|
|
467
|
+
TMPDIR="$tmpd" bash "$SCRIPT_DIR/bin/capture-run.sh" \
|
|
468
|
+
"${capture_args[@]}" \
|
|
469
|
+
--author "$from" \
|
|
470
|
+
--topic "$topic" \
|
|
471
|
+
--summary "$summary" \
|
|
472
|
+
--session-id "$session_id" \
|
|
473
|
+
--branch "$branch" >/dev/null
|
|
474
|
+
|
|
475
|
+
result="$tmpd/capture-run-result.json"
|
|
476
|
+
rel="$(jq -r '.file // empty' "$result" 2>/dev/null || true)"
|
|
477
|
+
[ -n "$rel" ] || die "wrap was not created"
|
|
435
478
|
echo "wrap: memory/$rel"
|
|
479
|
+
|
|
480
|
+
# Session close: non-coding core-repo changes save + merge themselves
|
|
481
|
+
# (gated inside session-autosave.sh — code is never auto-committed).
|
|
482
|
+
if [ "$no_push" = "0" ]; then
|
|
483
|
+
( bash "$SCRIPT_DIR/bin/session-autosave.sh" --dir "$SCRIPT_DIR" >/dev/null 2>&1 & ) >/dev/null 2>&1
|
|
484
|
+
fi
|
|
436
485
|
}
|
|
437
486
|
|
|
438
487
|
cmd_handoff() {
|
|
439
488
|
ensure_memory
|
|
440
|
-
local from="" to="" topic="" body="" body_file="" project=""
|
|
489
|
+
local from="" to="" topic="" body="" body_file="" project="" intent="action"
|
|
441
490
|
local no_publish=0 no_notify=0 json=0
|
|
442
491
|
NO_PUSH=0
|
|
443
492
|
|
|
@@ -449,6 +498,7 @@ cmd_handoff() {
|
|
|
449
498
|
--body) body="${2:-}"; shift 2 ;;
|
|
450
499
|
--body-file) body_file="${2:-}"; shift 2 ;;
|
|
451
500
|
--project) project="${2:-}"; shift 2 ;;
|
|
501
|
+
--intent) intent="${2:-}"; shift 2 ;;
|
|
452
502
|
--no-push) NO_PUSH=1; shift ;;
|
|
453
503
|
--no-publish) no_publish=1; shift ;;
|
|
454
504
|
--no-notify) no_notify=1; shift ;;
|
|
@@ -460,6 +510,10 @@ cmd_handoff() {
|
|
|
460
510
|
[ -z "$from" ] && from="$(person_from_state)"
|
|
461
511
|
[ -n "$from" ] || die "handoff requires --from"
|
|
462
512
|
[ -n "$topic" ] || die "handoff requires --topic"
|
|
513
|
+
case "$intent" in
|
|
514
|
+
action|feedback|fyi) ;;
|
|
515
|
+
*) die "invalid --intent: $intent (action|feedback|fyi)" ;;
|
|
516
|
+
esac
|
|
463
517
|
if [ -n "$body_file" ]; then
|
|
464
518
|
[ -f "$body_file" ] || die "body file not found: $body_file"
|
|
465
519
|
body="$(cat "$body_file")"
|
|
@@ -480,6 +534,7 @@ cmd_handoff() {
|
|
|
480
534
|
[ -n "$project" ] && project_line="**Project**: $project"
|
|
481
535
|
[ -n "$to" ] && handoff_args+=(--recipient "$to")
|
|
482
536
|
[ -n "$project" ] && handoff_args+=(--project "$project")
|
|
537
|
+
handoff_args+=(--intent "$intent")
|
|
483
538
|
[ "$NO_PUSH" = "1" ] && handoff_args+=(--no-push)
|
|
484
539
|
[ "$no_publish" = "1" ] && handoff_args+=(--no-publish)
|
|
485
540
|
[ "$no_notify" = "1" ] && handoff_args+=(--no-notify)
|
|
@@ -489,10 +544,12 @@ cmd_handoff() {
|
|
|
489
544
|
printf '**Date**: %s\n' "$today"
|
|
490
545
|
printf '**Author**: %s\n' "$from"
|
|
491
546
|
[ -n "$to" ] && printf '**To**: %s\n' "$to"
|
|
547
|
+
printf '**Intent**: %s\n' "$intent"
|
|
492
548
|
[ -n "$project_line" ] && printf '%s\n' "$project_line"
|
|
493
549
|
printf '\n## Briefing\n\n%s\n\n' "$body"
|
|
494
550
|
printf '## Next Steps\n\n- Continue from this handoff using the shared Egregore memory protocol.\n'
|
|
495
|
-
} | TMPDIR="$tmpd" bash "$SCRIPT_DIR/bin/
|
|
551
|
+
} | TMPDIR="$tmpd" bash "$SCRIPT_DIR/bin/capture-run.sh" \
|
|
552
|
+
--mode addressed \
|
|
496
553
|
--author "$from" \
|
|
497
554
|
--topic "$topic" \
|
|
498
555
|
"${handoff_args[@]}" \
|
|
@@ -509,6 +566,12 @@ cmd_handoff() {
|
|
|
509
566
|
[ -s "$stdout_file" ] && sed 's/^/status: /' "$stdout_file"
|
|
510
567
|
echo "handoff: memory/$rel"
|
|
511
568
|
echo "result: $result_out"
|
|
569
|
+
|
|
570
|
+
# Parity with the Claude /handoff skill: save core-repo session work in the
|
|
571
|
+
# background (non-coding diffs auto-merge to develop, code stays in a PR).
|
|
572
|
+
if [ "$NO_PUSH" = "0" ]; then
|
|
573
|
+
( bash "$SCRIPT_DIR/bin/handoff-save-egregore.sh" "$from" "$topic" --repo-dir "$SCRIPT_DIR" >/dev/null 2>&1 & ) >/dev/null 2>&1
|
|
574
|
+
fi
|
|
512
575
|
}
|
|
513
576
|
|
|
514
577
|
cmd_ask() {
|