rollout-cli 0.6.0__tar.gz → 0.7.0__tar.gz
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.
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/recall/SKILL.md +13 -9
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/recall/scripts/recall.sh +45 -22
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/remember/SKILL.md +8 -5
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/remember/scripts/remember.sh +50 -22
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/CHANGELOG.md +18 -1
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/CLAUDE.md +28 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/PKG-INFO +1 -1
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/docs/skill-sources.md +6 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/pyproject.toml +1 -1
- rollout_cli-0.7.0/recipes/eidetic-memory/README.md +161 -0
- rollout_cli-0.7.0/recipes/eidetic-memory/apply.sh +118 -0
- rollout_cli-0.7.0/recipes/eidetic-memory/check.sh +46 -0
- rollout_cli-0.7.0/recipes/eidetic-memory/files/CLAUDE.snippet.tmpl +25 -0
- rollout_cli-0.7.0/recipes/eidetic-memory/files/SKILL.md.recall.tmpl +185 -0
- rollout_cli-0.7.0/recipes/eidetic-memory/files/SKILL.md.remember.tmpl +121 -0
- rollout_cli-0.7.0/recipes/eidetic-memory/files/scripts/recall.sh +164 -0
- rollout_cli-0.7.0/recipes/eidetic-memory/files/scripts/remember.sh +166 -0
- rollout_cli-0.7.0/recipes/eidetic-memory/manifest.toml +51 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/core/devex_pr.py +18 -8
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_devex_pr.py +23 -5
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/uv.lock +1 -1
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/agent-config/SKILL.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/agent-config/data/backend-fingerprints.yaml +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/agent-config/scripts/show.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/ask-colleague/SKILL.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/ask-colleague/prompts/explore.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/ask-colleague/prompts/review.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/ask-colleague/prompts/write.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/ask-colleague/scripts/ask-colleague.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/assign-to-workforce/SKILL.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/cicd/SKILL.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/cicd/scripts/_resolve-nick.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/cicd/scripts/portability-lint.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/cicd/scripts/pr-reply.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/cicd/scripts/pr-status.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/cicd/scripts/workflow.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/communicate/SKILL.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/communicate/scripts/templates/skill-new-brief.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/communicate/scripts/templates/skill-update-brief.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/mass-update/SKILL.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/mass-update/scripts/mass-update.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/pypi-maintainer/SKILL.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/pypi-maintainer/scripts/switch-source.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/run-tests/SKILL.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/run-tests/scripts/test.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/sonarclaude/SKILL.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/sonarclaude/scripts/sonar.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/spec-to-plan/SKILL.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/think/SKILL.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/think/scripts/think.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/version-bump/SKILL.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills/version-bump/scripts/bump.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.claude/skills.local.yaml.example +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.devague/frames/mass-update-now-clones-each-target-repo-into-a-git.json +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.devague/frames/rollout-cli-ships-rollout-define-an-org-wide-chang.json +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.devague/plans/mass-update-now-clones-each-target-repo-into-a-git.json +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.devague/plans/rollout-cli-ships-rollout-define-an-org-wide-chang.json +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.flake8 +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.github/workflows/publish.yml +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.github/workflows/tests.yml +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.gitignore +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/.markdownlint-cli2.yaml +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/AGENTS.colleague.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/LICENSE +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/README.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/culture.yaml +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/docs/plans/2026-06-06-rollout-cli-ships-rollout-define-an-org-wide-chang.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/docs/plans/2026-06-12-mass-update-now-clones-each-target-repo-into-a-git.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/docs/specs/2026-06-06-rollout-cli-ships-rollout-define-an-org-wide-chang.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/docs/specs/2026-06-12-mass-update-now-clones-each-target-repo-into-a-git.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/recipes/apache-relicense/apply.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/recipes/apache-relicense/check.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/recipes/apache-relicense/files/LICENSE +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/recipes/apache-relicense/manifest.toml +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/recipes/ask-colleague-revendor/README.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/recipes/ask-colleague-revendor/apply.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/recipes/ask-colleague-revendor/check.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/recipes/ask-colleague-revendor/files/SKILL.md.tmpl +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/recipes/ask-colleague-revendor/files/prompts/explore.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/recipes/ask-colleague-revendor/files/prompts/review.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/recipes/ask-colleague-revendor/files/prompts/write.md +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/recipes/ask-colleague-revendor/files/scripts/ask-colleague.sh +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/recipes/ask-colleague-revendor/manifest.toml +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/__init__.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/__main__.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/cli/__init__.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/cli/_commands/__init__.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/cli/_commands/apply.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/cli/_commands/cli.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/cli/_commands/doctor.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/cli/_commands/explain.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/cli/_commands/learn.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/cli/_commands/overview.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/cli/_commands/plan.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/cli/_commands/whoami.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/cli/_errors.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/cli/_output.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/core/__init__.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/core/bump.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/core/gitops.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/core/orchestrate.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/core/preflight.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/core/recipe.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/core/report.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/core/targets.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/explain/__init__.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/rollout/explain/catalog.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/sonar-project.properties +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/__init__.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_apache_relicense.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_apply_cmd.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_bump.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_cli.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_cli_introspection.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_cli_wiring.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_e2e_apache_relicense.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_explain_catalog.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_gitops.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_mass_update.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_orchestrate.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_plan_cmd.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_preflight.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_recipe.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_report.py +0 -0
- {rollout_cli-0.6.0 → rollout_cli-0.7.0}/tests/test_targets.py +0 -0
|
@@ -9,13 +9,17 @@ description: >
|
|
|
9
9
|
text, full metadata, a relevance `score`, and a freshness `signal`. Recall
|
|
10
10
|
passively reinforces matched records (bumps last_recall + recall_count).
|
|
11
11
|
Shadowed and archived records are excluded by default; use
|
|
12
|
-
--include-shadowed / --include-archived to retrieve them. The store
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
--include-shadowed / --include-archived to retrieve them. The store uses
|
|
13
|
+
visibility-aware routing: PUBLIC records inside a git repo go to
|
|
14
|
+
<repo-root>/.eidetic/memory (committed, team-shared); PRIVATE records, or any
|
|
15
|
+
record outside a git repo, go to $HOME/.eidetic/memory (never committed). An
|
|
16
|
+
explicit EIDETIC_DATA_DIR wins and short-circuits to that single dir. Recall
|
|
17
|
+
reads both stores and merges. The wrapper defaults queries to this agent's
|
|
18
|
+
PERSONAL, PRIVATE scope (`--scope rollout-cli --visibility private`, suffix
|
|
19
|
+
read from culture.yaml) — matching where /remember writes — so a no-flag
|
|
20
|
+
recall returns this agent's own private records plus the shared public pool,
|
|
21
|
+
and Claude and the colleague backend recall each other's memories because both
|
|
22
|
+
resolve the same suffix via this skill. Use
|
|
19
23
|
when the user says "recall", "what do we know about X", "search memory",
|
|
20
24
|
"have we seen X before", "look it up in memory", "eidetic recall", or before
|
|
21
25
|
answering from scratch when prior context may already be stored. Pairs with
|
|
@@ -31,7 +35,7 @@ surface; the write half is the sibling **/remember** skill.
|
|
|
31
35
|
|
|
32
36
|
The point of a *shared* store is that memory is a **team faculty**, not a
|
|
33
37
|
per-agent silo: a record Claude wrote is recallable by the colleague backend
|
|
34
|
-
(and vice versa), because both resolve the same
|
|
38
|
+
(and vice versa), because both resolve the same `$HOME/.eidetic/memory` path.
|
|
35
39
|
|
|
36
40
|
## How to run
|
|
37
41
|
|
|
@@ -168,7 +172,7 @@ bash .claude/skills/recall/scripts/recall.sh "power" --include-archived --includ
|
|
|
168
172
|
matches. `approximate` keeps every candidate ranked by raw cosine, so it can
|
|
169
173
|
return low/near-zero scores when the store is small — lower `--top-k` to trim.
|
|
170
174
|
A `--min-score` threshold is a tracked follow-up.
|
|
171
|
-
- **Sharing scope = one OS user.** The default store is
|
|
175
|
+
- **Sharing scope = one OS user.** The default store is `$HOME/.eidetic/memory`, so
|
|
172
176
|
every agent/process running as the *same* OS user shares it (that is the point —
|
|
173
177
|
Claude + colleague). It is not isolated between OS users by anything but file
|
|
174
178
|
permissions; keep genuinely private data in a `--visibility private` scope and
|
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
# forwards every flag verbatim — so `recall.sh "<query>" --mode hybrid --json`
|
|
7
7
|
# is exactly `eidetic recall "<query>" --mode hybrid --json`.
|
|
8
8
|
#
|
|
9
|
-
# The store is the files backend
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
9
|
+
# The store is the files backend. Default location resolves per-operation:
|
|
10
|
+
# PUBLIC records inside a git repo → <repo-root>/.eidetic/memory (committed,
|
|
11
|
+
# team-shared); PRIVATE records, or any record outside a git repo →
|
|
12
|
+
# $HOME/.eidetic/memory (never committed). Recall reads both stores and merges.
|
|
13
|
+
# An explicit EIDETIC_DATA_DIR wins and short-circuits to that single dir.
|
|
13
14
|
|
|
14
15
|
set -euo pipefail
|
|
15
16
|
|
|
@@ -34,12 +35,10 @@ resolve_eidetic() {
|
|
|
34
35
|
fi
|
|
35
36
|
dir=$(dirname "$dir")
|
|
36
37
|
done
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
The console script is `eidetic` (dist name: eidetic-cli).
|
|
42
|
-
EOF
|
|
38
|
+
# In a vendored copy there is no eidetic-cli checkout to fall back to, so the
|
|
39
|
+
# only honest remedy is to install the CLI. One `error:` + one `hint:` line.
|
|
40
|
+
printf 'error: eidetic CLI not found.\n' >&2
|
|
41
|
+
printf 'hint: install it with: uv tool install eidetic-cli (or pipx install eidetic-cli); the console script is eidetic.\n' >&2
|
|
43
42
|
return 1
|
|
44
43
|
}
|
|
45
44
|
|
|
@@ -65,15 +64,22 @@ EOF
|
|
|
65
64
|
}
|
|
66
65
|
|
|
67
66
|
case "${1:-}" in
|
|
68
|
-
-h | --help
|
|
67
|
+
-h | --help)
|
|
69
68
|
usage
|
|
70
69
|
exit 0
|
|
71
70
|
;;
|
|
71
|
+
"")
|
|
72
|
+
# A missing query is a usage error, not success. The bareword `help` is
|
|
73
|
+
# a legitimate search term, so it is intentionally NOT a usage alias.
|
|
74
|
+
printf 'error: no query given.\n' >&2
|
|
75
|
+
printf 'hint: recall.sh "<query>" [--mode ...] [--json]; run recall.sh --help for usage.\n' >&2
|
|
76
|
+
exit 1
|
|
77
|
+
;;
|
|
72
78
|
esac
|
|
73
79
|
|
|
74
80
|
resolve_eidetic || exit 2
|
|
75
81
|
|
|
76
|
-
# ── default to this agent's PERSONAL,
|
|
82
|
+
# ── default to this agent's PERSONAL scope, PUBLIC visibility (culture.yaml `suffix`) ──
|
|
77
83
|
# Query this agent's OWN personal scope by default, matching where /remember
|
|
78
84
|
# writes, instead of the global `default` scope shared by every project on this
|
|
79
85
|
# host. We read the `suffix` from the nearest culture.yaml (walking up from this
|
|
@@ -82,15 +88,16 @@ resolve_eidetic || exit 2
|
|
|
82
88
|
# backend (running in a worktree of this same repo) resolves the same suffix,
|
|
83
89
|
# keeping the Claude↔colleague shared-memory story intact.
|
|
84
90
|
#
|
|
85
|
-
#
|
|
86
|
-
#
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
#
|
|
91
|
+
# Visibility defaults to PUBLIC (a recipe-level policy override of eidetic's
|
|
92
|
+
# upstream private default — see the POLICY OVERRIDE comment below) to match
|
|
93
|
+
# /remember, so a plain recall queries the in-repo public pool at
|
|
94
|
+
# <repo>/.eidetic/memory that /remember writes to. Scope and visibility are
|
|
95
|
+
# paired — the public default applies only when we inject the resolved scope,
|
|
90
96
|
# and only if the caller didn't pass --visibility (so an explicit
|
|
91
|
-
# `--visibility
|
|
92
|
-
#
|
|
93
|
-
# plain CLI default
|
|
97
|
+
# `--visibility private` still wins, also surfacing this agent's private $HOME
|
|
98
|
+
# notes). An explicit --scope on the command line takes over steering entirely; a
|
|
99
|
+
# wheel install with no culture.yaml falls back to the plain CLI default
|
|
100
|
+
# (`default`/`public`).
|
|
94
101
|
resolve_scope() {
|
|
95
102
|
local dir suffix=""
|
|
96
103
|
dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|
@@ -100,9 +107,12 @@ resolve_scope() {
|
|
|
100
107
|
# inline `# comment` or trailing space can't bleed into the scope),
|
|
101
108
|
# then strip surrounding quotes only — matching the canonical parser
|
|
102
109
|
# in .claude/skills/cicd/scripts/_resolve-nick.sh.
|
|
110
|
+
# `|| true`: under `set -o pipefail`, `head -n1` closing the pipe
|
|
111
|
+
# early can SIGPIPE `sed`, making the substitution non-zero and
|
|
112
|
+
# aborting the script. An empty parse must yield "" here, not exit.
|
|
103
113
|
suffix=$(sed -n \
|
|
104
114
|
's/^[[:space:]]*-\{0,1\}[[:space:]]*suffix:[[:space:]]*\([^[:space:]]*\).*/\1/p' \
|
|
105
|
-
"$dir/culture.yaml" | head -n1 | tr -d "\"'")
|
|
115
|
+
"$dir/culture.yaml" | head -n1 | tr -d "\"'" || true)
|
|
106
116
|
break
|
|
107
117
|
fi
|
|
108
118
|
dir=$(dirname "$dir")
|
|
@@ -127,7 +137,20 @@ if ! has_flag --scope "$@"; then
|
|
|
127
137
|
EIDETIC_SCOPE=$(resolve_scope)
|
|
128
138
|
if [ -n "$EIDETIC_SCOPE" ]; then
|
|
129
139
|
SCOPE_ARGS+=(--scope "$EIDETIC_SCOPE")
|
|
130
|
-
|
|
140
|
+
# rollout-cli eidetic-memory recipe POLICY OVERRIDE (not eidetic's
|
|
141
|
+
# upstream private default): default to PUBLIC, so a plain recall queries
|
|
142
|
+
# the in-repo public pool (<repo>/.eidetic/memory) this repo writes to.
|
|
143
|
+
# Pass --visibility private to also surface this agent's private ($HOME)
|
|
144
|
+
# notes. The two-store read model reads both dirs regardless.
|
|
145
|
+
has_flag --visibility "$@" || SCOPE_ARGS+=(--visibility public)
|
|
146
|
+
elif ! has_flag --visibility "$@"; then
|
|
147
|
+
# No suffix AND no explicit --visibility: the query runs against
|
|
148
|
+
# eidetic's own default (scope=default, visibility=public), not this
|
|
149
|
+
# agent's private personal scope — so an empty result isn't silently
|
|
150
|
+
# misread. Warn on stderr (stdout stays clean for --json). Warn ONLY
|
|
151
|
+
# here: an explicit --scope (outer guard) or --visibility (this guard) is
|
|
152
|
+
# a deliberate choice, honored verbatim, so either flag silences this.
|
|
153
|
+
printf 'warning: no culture.yaml suffix resolved; querying the public default scope rather than a private personal scope. Pass --scope or --visibility to target deliberately.\n' >&2
|
|
131
154
|
fi
|
|
132
155
|
fi
|
|
133
156
|
|
|
@@ -8,10 +8,13 @@ description: >
|
|
|
8
8
|
dedups by content hash) — re-remembering updates in place, never duplicates.
|
|
9
9
|
Stamps a `created` date on every record at ingest time. Accepts `supersedes`
|
|
10
10
|
(id of the record this one replaces, for within-scope shadowing via `sweep`)
|
|
11
|
-
and `links` (list of related-memory ids). The store
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
and `links` (list of related-memory ids). The store uses visibility-aware
|
|
12
|
+
routing: PUBLIC records inside a git repo go to <repo-root>/.eidetic/memory
|
|
13
|
+
(committed, team-shared); PRIVATE records, or any record outside a git repo,
|
|
14
|
+
go to $HOME/.eidetic/memory (never committed). An explicit EIDETIC_DATA_DIR
|
|
15
|
+
wins and short-circuits to that single dir. The wrapper defaults records to
|
|
16
|
+
this agent's PERSONAL, PRIVATE scope (`--scope rollout-cli --visibility
|
|
17
|
+
private`, suffix read from culture.yaml) so they don't leak to a
|
|
15
18
|
default/other-scope recall — Claude and the colleague backend still share them
|
|
16
19
|
because both resolve the same suffix via this skill. Pass `--visibility public`
|
|
17
20
|
to contribute to the shared public pool instead. Use when the user says
|
|
@@ -25,7 +28,7 @@ description: >
|
|
|
25
28
|
`remember` drives **`eidetic remember`**, the write half of the memory surface
|
|
26
29
|
(the read half is the sibling **/recall** skill). Records you store here are
|
|
27
30
|
recallable later by *any* agent on this machine — Claude or the colleague
|
|
28
|
-
backend — because the default store is one shared
|
|
31
|
+
backend — because the default store is one shared `$HOME/.eidetic/memory` path.
|
|
29
32
|
|
|
30
33
|
## How to run
|
|
31
34
|
|
|
@@ -12,10 +12,11 @@
|
|
|
12
12
|
# Upsert is idempotent by id (and dedups by content hash): re-remembering the
|
|
13
13
|
# same record updates it in place, never duplicates.
|
|
14
14
|
#
|
|
15
|
-
# The store is the files backend
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
15
|
+
# The store is the files backend. Default location resolves per-operation:
|
|
16
|
+
# PUBLIC records inside a git repo → <repo-root>/.eidetic/memory (committed,
|
|
17
|
+
# team-shared); PRIVATE records, or any record outside a git repo →
|
|
18
|
+
# $HOME/.eidetic/memory (never committed). An explicit EIDETIC_DATA_DIR still
|
|
19
|
+
# wins and short-circuits to that single dir. Use --backend mongo|neo4j (with
|
|
19
20
|
# EIDETIC_MONGO_URI / NEO4J_URI) for a server-backed shared store.
|
|
20
21
|
|
|
21
22
|
set -euo pipefail
|
|
@@ -40,12 +41,10 @@ resolve_eidetic() {
|
|
|
40
41
|
fi
|
|
41
42
|
dir=$(dirname "$dir")
|
|
42
43
|
done
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
The console script is `eidetic` (dist name: eidetic-cli).
|
|
48
|
-
EOF
|
|
44
|
+
# In a vendored copy there is no eidetic-cli checkout to fall back to, so the
|
|
45
|
+
# only honest remedy is to install the CLI. One `error:` + one `hint:` line.
|
|
46
|
+
printf 'error: eidetic CLI not found.\n' >&2
|
|
47
|
+
printf 'hint: install it with: uv tool install eidetic-cli (or pipx install eidetic-cli); the console script is eidetic.\n' >&2
|
|
49
48
|
return 1
|
|
50
49
|
}
|
|
51
50
|
|
|
@@ -60,7 +59,10 @@ Usage:
|
|
|
60
59
|
|
|
61
60
|
A record needs `id`, `text`, and `type`; `hash` and `metadata` are recommended
|
|
62
61
|
(hash is derived from text when omitted). Upsert is idempotent by id.
|
|
63
|
-
|
|
62
|
+
Records default to this agent's PUBLIC personal scope (--scope from the
|
|
63
|
+
culture.yaml suffix), committed in-repo at <repo>/.eidetic/memory; pass
|
|
64
|
+
--visibility private to keep a record in $HOME (uncommitted). Every flag is
|
|
65
|
+
forwarded verbatim to `eidetic remember`.
|
|
64
66
|
See `eidetic explain remember`.
|
|
65
67
|
EOF
|
|
66
68
|
}
|
|
@@ -72,9 +74,19 @@ case "${1:-}" in
|
|
|
72
74
|
;;
|
|
73
75
|
esac
|
|
74
76
|
|
|
77
|
+
# No record argument AND stdin is an interactive terminal → `eidetic remember`
|
|
78
|
+
# would block forever waiting for NDJSON. Show usage instead of hanging. A piped
|
|
79
|
+
# or redirected stdin (`cat records.ndjson | remember.sh`) is not a TTY and
|
|
80
|
+
# proceeds to the batch path normally.
|
|
81
|
+
if [ "$#" -eq 0 ] && [ -t 0 ]; then
|
|
82
|
+
usage >&2
|
|
83
|
+
printf 'hint: pass a JSON record as an argument, or pipe NDJSON on stdin.\n' >&2
|
|
84
|
+
exit 1
|
|
85
|
+
fi
|
|
86
|
+
|
|
75
87
|
resolve_eidetic || exit 2
|
|
76
88
|
|
|
77
|
-
# ── default to this agent's PERSONAL,
|
|
89
|
+
# ── default to this agent's PERSONAL scope, PUBLIC visibility (culture.yaml `suffix`) ──
|
|
78
90
|
# A record this agent remembers should land in its OWN personal scope, not the
|
|
79
91
|
# global `default` scope shared by every project on this host. We read the
|
|
80
92
|
# `suffix` from the nearest culture.yaml (walking up from this script), so the
|
|
@@ -83,14 +95,15 @@ resolve_eidetic || exit 2
|
|
|
83
95
|
# (running in a worktree of this same repo) resolves the same suffix, keeping
|
|
84
96
|
# the Claude↔colleague shared-memory story intact.
|
|
85
97
|
#
|
|
86
|
-
#
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
# visibility are paired — the
|
|
90
|
-
# resolved scope, and only if the caller didn't
|
|
91
|
-
# explicit `--visibility
|
|
92
|
-
#
|
|
93
|
-
#
|
|
98
|
+
# Visibility defaults to PUBLIC (a recipe-level policy override of eidetic's
|
|
99
|
+
# upstream private default — see the POLICY OVERRIDE comment below), so a plain
|
|
100
|
+
# remember lands in the in-repo, committed, team- and mesh-shared pool at
|
|
101
|
+
# <repo>/.eidetic/memory. Scope and visibility are paired — the public default
|
|
102
|
+
# applies only when we inject the resolved scope, and only if the caller didn't
|
|
103
|
+
# pass --visibility (so an explicit `--visibility private` still wins, keeping
|
|
104
|
+
# the record in $HOME / uncommitted). An explicit --scope on the command line
|
|
105
|
+
# takes over steering entirely; a wheel install with no culture.yaml falls back
|
|
106
|
+
# to the plain CLI default (`default`/`public`).
|
|
94
107
|
resolve_scope() {
|
|
95
108
|
local dir suffix=""
|
|
96
109
|
dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|
@@ -100,9 +113,12 @@ resolve_scope() {
|
|
|
100
113
|
# inline `# comment` or trailing space can't bleed into the scope),
|
|
101
114
|
# then strip surrounding quotes only — matching the canonical parser
|
|
102
115
|
# in .claude/skills/cicd/scripts/_resolve-nick.sh.
|
|
116
|
+
# `|| true`: under `set -o pipefail`, `head -n1` closing the pipe
|
|
117
|
+
# early can SIGPIPE `sed`, making the substitution non-zero and
|
|
118
|
+
# aborting the script. An empty parse must yield "" here, not exit.
|
|
103
119
|
suffix=$(sed -n \
|
|
104
120
|
's/^[[:space:]]*-\{0,1\}[[:space:]]*suffix:[[:space:]]*\([^[:space:]]*\).*/\1/p' \
|
|
105
|
-
"$dir/culture.yaml" | head -n1 | tr -d "\"'")
|
|
121
|
+
"$dir/culture.yaml" | head -n1 | tr -d "\"'" || true)
|
|
106
122
|
break
|
|
107
123
|
fi
|
|
108
124
|
dir=$(dirname "$dir")
|
|
@@ -127,7 +143,19 @@ if ! has_flag --scope "$@"; then
|
|
|
127
143
|
EIDETIC_SCOPE=$(resolve_scope)
|
|
128
144
|
if [ -n "$EIDETIC_SCOPE" ]; then
|
|
129
145
|
SCOPE_ARGS+=(--scope "$EIDETIC_SCOPE")
|
|
130
|
-
|
|
146
|
+
# rollout-cli eidetic-memory recipe POLICY OVERRIDE (not eidetic's
|
|
147
|
+
# upstream private default): default to PUBLIC so a plain remember lands
|
|
148
|
+
# in <repo>/.eidetic/memory — committed, team- and mesh-shared. Pass
|
|
149
|
+
# --visibility private to keep a record in $HOME (uncommitted).
|
|
150
|
+
has_flag --visibility "$@" || SCOPE_ARGS+=(--visibility public)
|
|
151
|
+
elif ! has_flag --visibility "$@"; then
|
|
152
|
+
# No suffix AND no explicit --visibility: the record falls back to
|
|
153
|
+
# eidetic's own default (scope=default, visibility=public). Don't let an
|
|
154
|
+
# expected-private record go public silently — warn on stderr (stdout
|
|
155
|
+
# stays clean for --json). Warn ONLY here: an explicit --scope (outer
|
|
156
|
+
# guard) or --visibility (this guard) means the caller chose deliberately
|
|
157
|
+
# and is honored verbatim, so either flag silences this.
|
|
158
|
+
printf 'warning: no culture.yaml suffix resolved; this record falls back to the public default scope. Pass --scope or --visibility to place it deliberately.\n' >&2
|
|
131
159
|
fi
|
|
132
160
|
fi
|
|
133
161
|
|
|
@@ -5,11 +5,28 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
Format follows [Keep a Changelog](https://keepachangelog.com/). This project
|
|
6
6
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.7.0] - 2026-06-23
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `eidetic-memory` rollout recipe (`recipes/eidetic-memory/`) — propagates the eidetic-origin `remember` + `recall` skills to every AgentCulture repo with a `.claude/skills/` kit, and adds them fresh where absent. `apply.sh` drops both wrappers verbatim and, on a fresh add, localizes each SKILL.md’s illustrative `--scope <nick>` example to the target’s `culture.yaml` suffix (else repo basename); `check.sh` skips repos lacking a quoted-semver `pyproject.toml`, a `CHANGELOG.md`, or a skills kit. The engine bumps the target version + prepends a CHANGELOG entry (so the org-wide version-check passes) and opens one PR per repo. README carries the 57-repo downstream-consumer ledger + reconciliation procedure.
|
|
13
|
+
- `eidetic-memory` now also wires a memory-discipline **"Conventions and workflow"** section into each target’s `CLAUDE.md` (`files/CLAUDE.snippet.tmpl`) — a per-task *recall-before / remember-after* convention with the scope reference localized to the target’s nick (`__REPO_NICK__`), so the vendored skills are actually used, not just present. The section frames each repo’s memory as **in-repo and public** (records resolve to `<repo-root>/.eidetic/memory`, committed and team/mesh-shared), matching the wrappers’ public default. Inserted idempotently on a marker phrase: slotted under an existing `## Conventions and workflow` heading when one exists, else appended (the file is created if the repo has none). `check.sh` now requires the section present (alongside byte-matching wrappers) before classifying a repo `done`; `manifest.toml` declares `CLAUDE.md` in `touched_files`.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Refreshed the `eidetic-memory` recipe’s bundled `remember` / `recall` wrappers — and rollout-cli’s own vendored copies — from **eidetic-cli 0.10.0** (cite-don’t-import), picking up eidetic’s **project-local store default**: PUBLIC records inside a git repo resolve to `<repo-root>/.eidetic/memory` (committed, team-shared), PRIVATE records (or any record outside a repo) go to `$HOME/.eidetic/memory` (uncommitted), `EIDETIC_DATA_DIR` still wins, and recall reads both stores and merges. Also carries the 0.9.3 hardening (interactive-stdin guard, `help` as a search term, SIGPIPE-safe suffix parsing). **Recipe-level policy override** (the wrappers are no longer byte-verbatim): the injected default visibility is flipped from eidetic’s `private` to **`public`** (one line + a `POLICY OVERRIDE` comment in each wrapper), so a plain `/remember` keeps memory in-repo at `./.eidetic/memory`; the reconciliation procedure re-applies this `sed` after each `cp` from origin. rollout-cli’s own `CLAUDE.md` + skill copies dogfood the change.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- `rollout/core/devex_pr.py` `open_pr` now **requires** `gh`. The engine opens a PR for a freshly-cloned sibling (an arbitrary repo + branch) from rollout-cli’s own cwd, which only `gh pr create --repo --head --base` can target; `devex pr open` operates on the current checkout and rejects those flags, so it silently failed to open PRs whenever it was on PATH. The earlier "prefer gh, fall back to devex" selection was internally inconsistent — the devex fallback built a command devex would reject (Qodo review). `open_pr` now selects `gh` unconditionally and raises a clear `PrError` (pointing at `https://cli.github.com`) when `gh` is absent, instead of falling through to a broken devex invocation. `build_pr_command`’s pure `tool="devex"` branch is retained (still unit-tested); only the runtime selection is gh-only.
|
|
22
|
+
- `recipes/eidetic-memory/check.sh` version preflight is now end-anchored (`…"$`), matching `rollout/core/bump.py`’s `_LINE_RE` exactly (Qodo review). The old grep accepted `version = "1.2.3" # comment` (or trailing whitespace), so `plan` could classify a repo `ok`/`done` and then `apply` would fail at the version-bump step; preflight is now a strict subset of what the bumper accepts.
|
|
23
|
+
- `eidetic-memory` wrappers (`remember.sh` / `recall.sh`, bundled + rollout-cli’s own copies): corrected stale header/usage comments that still described a **private** default after the policy flip to public (Qodo review) — the code already injected `--visibility public` and warned on a suffixless fallback, but the prose said "PRIVATE by default", contradicting the behavior. Comment-only; no behavior change.
|
|
24
|
+
|
|
8
25
|
## [0.6.0] - 2026-06-23
|
|
9
26
|
|
|
10
27
|
### Added
|
|
11
28
|
|
|
12
|
-
- remember / recall skills — vendored directly from eidetic-cli (cite-don't-import), the write/read halves of eidetic's shared
|
|
29
|
+
- remember / recall skills — vendored directly from eidetic-cli (cite-don't-import), the write/read halves of eidetic's shared `$HOME/.eidetic/memory` surface. `remember` wraps `eidetic remember` (idempotent JSON object or NDJSON-batch upsert by id); `recall` wraps `eidetic recall` with four search modes (exact / approximate / keyword / hybrid). The `.sh` wrappers are byte-verbatim; each SKILL.md is localized only in the illustrative `--scope rollout-cli` scope examples (Provenance keeps "First-party to eidetic-cli"). docs/skill-sources.md gains the two provenance rows (origin = eidetic-cli, vendored direct, not via guildmaster). Runtime dep: the `eidetic` CLI on PATH (else a local eidetic-cli checkout + uv).
|
|
13
30
|
|
|
14
31
|
## [0.5.1] - 2026-06-18
|
|
15
32
|
|
|
@@ -81,3 +81,31 @@ check whether the *target file path* is already ignored —
|
|
|
81
81
|
Note: `devex`'s own self-heal (`devex overview`/`devex init`) bootstraps `.devex/`
|
|
82
82
|
only — it will **not** restore an `.agex/.gitignore`, so for `.agex` repos the
|
|
83
83
|
file must be supplied verbatim.
|
|
84
|
+
|
|
85
|
+
## Conventions and workflow
|
|
86
|
+
|
|
87
|
+
**Memory discipline — recall before, remember after.** This repo keeps its
|
|
88
|
+
eidetic memory **in-repo and public**: records resolve to
|
|
89
|
+
`<repo-root>/.eidetic/memory` — committed, and shared with the team and mesh
|
|
90
|
+
peers (the `claude` and `colleague` backends both read the same `rollout-cli`
|
|
91
|
+
scope), so memory travels with the repo, not a private home-dir store. Make it
|
|
92
|
+
a per-task habit:
|
|
93
|
+
|
|
94
|
+
- **`/recall` before you start.** Search the store for the area you're about
|
|
95
|
+
to touch — prior decisions, gotchas, "have we done this before?" — so you
|
|
96
|
+
build on what's already known instead of re-deriving it. Do this before
|
|
97
|
+
non-trivial tasks, not just when asked.
|
|
98
|
+
- **`/remember` when something worth keeping surfaces.** A non-obvious
|
|
99
|
+
decision and its rationale, a constraint, a fix and *why* it was needed, a
|
|
100
|
+
gotcha that cost time, a fact the next session would otherwise re-learn.
|
|
101
|
+
Capture it as it happens, not at the end when it's faded.
|
|
102
|
+
|
|
103
|
+
A plain `/remember` lands the note in `./.eidetic/memory` in this repo — no
|
|
104
|
+
flag needed (the wrappers here default to `--visibility public`; in-repo
|
|
105
|
+
routing needs `eidetic >= 0.10.0`, older CLIs keep records in `$HOME`). Keep
|
|
106
|
+
something out of the committed store only by passing `--visibility private`
|
|
107
|
+
(routes to `$HOME/.eidetic/memory`, never committed); `/recall` reads both
|
|
108
|
+
stores and merges. Don't store what the repo already records (code structure,
|
|
109
|
+
git history, what's already in this file or `CHANGELOG.md`) — store what you'd
|
|
110
|
+
have to re-derive. These are the `recall`/`remember` skills (`.claude/skills/`),
|
|
111
|
+
backed by the `eidetic` store.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rollout-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Cross-repo propagation workflow built on refactor-cli — apply a transformation across many repos at once.
|
|
5
5
|
Project-URL: Homepage, https://github.com/agentculture/rollout-cli
|
|
6
6
|
Project-URL: Issues, https://github.com/agentculture/rollout-cli/issues
|
|
@@ -115,6 +115,12 @@ ledger of who those consumers are — is owned by the
|
|
|
115
115
|
[`ask-colleague-revendor`](../recipes/ask-colleague-revendor/README.md) rollout
|
|
116
116
|
recipe (rollout-cli#3).
|
|
117
117
|
|
|
118
|
+
Likewise, broadcasting the eidetic-origin `remember` / `recall` skills **out to
|
|
119
|
+
the AgentCulture mesh** — and the ledger of which repos consume them — is owned
|
|
120
|
+
by the [`eidetic-memory`](../recipes/eidetic-memory/README.md) rollout recipe.
|
|
121
|
+
Re-vendor *this* repo's own copy from `../eidetic-cli` directly (the `.sh`
|
|
122
|
+
wrappers verbatim; localize only the illustrative `--scope rollout-cli` examples).
|
|
123
|
+
|
|
118
124
|
## Tooling prerequisites
|
|
119
125
|
|
|
120
126
|
- **`devex`** (>=0.21) on PATH — `cicd` delegates the PR lifecycle to `devex pr`.
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# eidetic-memory
|
|
2
|
+
|
|
3
|
+
Propagate eidetic-cli's first-party **`remember`** + **`recall`** memory skills
|
|
4
|
+
to every AgentCulture repo that vendors a `.claude/skills/` kit — add them fresh
|
|
5
|
+
wherever they are absent, refresh the wrappers wherever they are stale — and wire
|
|
6
|
+
a per-task **memory-discipline convention** into each repo's `CLAUDE.md` so the
|
|
7
|
+
skills are actually used, not just present.
|
|
8
|
+
|
|
9
|
+
`remember` / `recall` are first-party to **eidetic-cli** (it owns its memory
|
|
10
|
+
surface); downstream repos vendor them **cite-don't-import**. eidetic-cli's own
|
|
11
|
+
skill ledger anticipated this broadcast: *"Broadcast to the mesh via
|
|
12
|
+
steward/guildmaster is for later, if other agents want it."* This recipe is that
|
|
13
|
+
broadcast, driven through rollout-cli (the propagation tool) rather than forced
|
|
14
|
+
into the origin repo.
|
|
15
|
+
|
|
16
|
+
## What it does
|
|
17
|
+
|
|
18
|
+
For each target repo, `apply.sh` lays down both skills:
|
|
19
|
+
|
|
20
|
+
- **`scripts/<skill>.sh`** — always overwritten from the bundled snapshot. The
|
|
21
|
+
wrapper resolves the `eidetic` CLI (`PATH` first, else `uv run` from a
|
|
22
|
+
checkout) and reads the `suffix` from `culture.yaml` at runtime, so the same
|
|
23
|
+
bytes are correct in every consumer. The snapshot is eidetic-cli **0.10.0**
|
|
24
|
+
verbatim **except one documented recipe-level policy override**: the injected
|
|
25
|
+
default visibility is flipped from eidetic's `private` to **`public`** (a
|
|
26
|
+
single line in each wrapper, plus a `POLICY OVERRIDE` comment). With
|
|
27
|
+
eidetic 0.10.0's project-local store, a PUBLIC record inside a git repo
|
|
28
|
+
resolves to `<repo-root>/.eidetic/memory` (committed, team-shared) while a
|
|
29
|
+
PRIVATE one goes to `$HOME/.eidetic/memory` (uncommitted) — so defaulting to
|
|
30
|
+
public means a plain `/remember` keeps memory **in the repo**. Pass
|
|
31
|
+
`--visibility private` to opt a record back out to `$HOME`.
|
|
32
|
+
- **`SKILL.md`** — written **only when absent** (fresh add), substituting the
|
|
33
|
+
target's nick (`culture.yaml` `suffix`, else repo basename) into the
|
|
34
|
+
illustrative `--scope <nick>` examples via the `__REPO_NICK__` token in
|
|
35
|
+
`files/SKILL.md.<skill>.tmpl`. An existing `SKILL.md` is never clobbered (a
|
|
36
|
+
downstream may have localized or diverged it). The Provenance line always
|
|
37
|
+
cites **"First-party to eidetic-cli"**.
|
|
38
|
+
|
|
39
|
+
Then, once, into `CLAUDE.md`:
|
|
40
|
+
|
|
41
|
+
- **Memory-discipline section** — a "Conventions and workflow" block
|
|
42
|
+
(*recall-before / remember-after*) rendered from `files/CLAUDE.snippet.tmpl`
|
|
43
|
+
with the same `__REPO_NICK__` nick substituted into the scope reference.
|
|
44
|
+
Inserted **only when its marker is absent** (idempotent): slotted under an
|
|
45
|
+
existing `## Conventions and workflow` heading when the repo already has one,
|
|
46
|
+
otherwise appended as a fresh section (and `CLAUDE.md` is created if the repo
|
|
47
|
+
has none). This makes the skills load-bearing — the agent is told to `/recall`
|
|
48
|
+
before non-trivial work and `/remember` what it would otherwise re-derive.
|
|
49
|
+
|
|
50
|
+
`apply` also bumps the target's version (`minor`) and prepends a CHANGELOG entry
|
|
51
|
+
— required because AgentCulture's org-wide CI rule fails any PR that does not
|
|
52
|
+
bump the version. `check.sh` classifies a repo `done` (both wrappers byte-match
|
|
53
|
+
the snapshot **and** `CLAUDE.md` already carries the section), `ok`
|
|
54
|
+
(wrapper missing/stale or section absent → apply), or `needs-attention` (no
|
|
55
|
+
quoted-semver `pyproject.toml`, no `CHANGELOG.md`, or no `.claude/skills/` kit).
|
|
56
|
+
|
|
57
|
+
## Run it
|
|
58
|
+
|
|
59
|
+
Operate on **fresh clones** in a scratch base dir (never live agent checkouts):
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Dry-run classification across consumers (zero outward effect):
|
|
63
|
+
uv run rollout plan eidetic-memory --repos <slugs> --base <clones-dir>
|
|
64
|
+
|
|
65
|
+
# Apply — branch, lay down skills, bump version, open one PR per repo
|
|
66
|
+
# (the operator squash-merges; rollout never merges):
|
|
67
|
+
uv run rollout apply eidetic-memory --repos <slugs> --base <clones-dir> --yes
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Downstream-consumer ledger
|
|
71
|
+
|
|
72
|
+
Origin: **eidetic-cli** (`agentculture/eidetic-cli`,
|
|
73
|
+
`.claude/skills/{remember,recall}/`). Consumers = every non-archived
|
|
74
|
+
AgentCulture repo with a `.claude/skills/` kit + a version-bumpable
|
|
75
|
+
`pyproject.toml`, discovered 2026-06-23 (57 repos):
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
agenda agentculture-cli agentfront agentirc agent-lifecycle agtag
|
|
79
|
+
amazing-hand-cli antoine appsec arm101-cli arxivist auntiepypi climate-cli
|
|
80
|
+
cloudai-cli code-lens-cli coherence-cli colleague culture cultureagent
|
|
81
|
+
culture-agent-template culture-core cultureflare culture-tools data-refinery-cli
|
|
82
|
+
devague devex dgx-spark-cli discord-bot-cli dominion-breaker ec2bedrock-cli
|
|
83
|
+
ec2-cli ghafi grant guildmaster identity-cli irc-lens jetson jetson-ai-lab-cli
|
|
84
|
+
katvan knowledgebase-cli lecodeur lobes-cli office-agent operator-cli prove-cli
|
|
85
|
+
qodo-cli reachy-mini-cli reachy-mini-mcp reduce-cli refactor-cli reterminal-cli
|
|
86
|
+
rtx-spark-cli steward telek tensor-cli tipalti unsloth-cli
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Excluded as non-targets (no `.claude/skills/` kit): `antigravityd`, `codexd`,
|
|
90
|
+
`kirod`, `landing-page`. `eidetic-cli` is the origin (already has them);
|
|
91
|
+
`rollout-cli` is self (carries its own localized copy + this recipe).
|
|
92
|
+
|
|
93
|
+
Eight consumers have **no `culture.yaml` suffix** (`agentirc`, `cultureagent`,
|
|
94
|
+
`cultureflare`, `ghafi`, `grant`, `irc-lens`, `office-agent`, `tipalti`) — their
|
|
95
|
+
fresh-add `SKILL.md` falls back to the repo basename in the scope example; the
|
|
96
|
+
wrapper itself falls back to the CLI default scope at runtime, so they still
|
|
97
|
+
work. Keep this table current when a consumer is added or dropped.
|
|
98
|
+
|
|
99
|
+
## Reconciliation procedure (when eidetic-cli changes a wrapper)
|
|
100
|
+
|
|
101
|
+
1. Refresh the snapshot from the origin checkout, then **re-apply the
|
|
102
|
+
public-default policy override** (the wrappers are origin-verbatim *except*
|
|
103
|
+
that one line — `cp` re-introduces eidetic's `private`, so the `sed` must
|
|
104
|
+
flip it back to `public`):
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
O=../eidetic-cli/.claude/skills
|
|
108
|
+
D=recipes/eidetic-memory/files/scripts
|
|
109
|
+
cp "$O/remember/scripts/remember.sh" "$D/"
|
|
110
|
+
cp "$O/recall/scripts/recall.sh" "$D/"
|
|
111
|
+
# POLICY OVERRIDE: default visibility private -> public (keeps memory in-repo).
|
|
112
|
+
# Re-add the POLICY OVERRIDE comment by hand if a future eidetic release moves
|
|
113
|
+
# the line; the marker to find is `SCOPE_ARGS+=(--visibility private)`.
|
|
114
|
+
sed -i 's/SCOPE_ARGS+=(--visibility private)/SCOPE_ARGS+=(--visibility public)/' \
|
|
115
|
+
"$D/remember.sh" "$D/recall.sh"
|
|
116
|
+
# SKILL.md templates — re-tokenize the illustrative scope examples:
|
|
117
|
+
sed -e 's/--scope eidetic-cli/--scope __REPO_NICK__/g' \
|
|
118
|
+
-e 's/(here, `eidetic-cli`)/(here, `__REPO_NICK__`)/g' \
|
|
119
|
+
"$O/remember/SKILL.md" > recipes/eidetic-memory/files/SKILL.md.remember.tmpl
|
|
120
|
+
sed -e 's/--scope eidetic-cli/--scope __REPO_NICK__/g' \
|
|
121
|
+
"$O/recall/SKILL.md" > recipes/eidetic-memory/files/SKILL.md.recall.tmpl
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Note: the vendored `SKILL.md` text still describes eidetic's upstream
|
|
125
|
+
`private` default (it is documentation from the origin). The operative
|
|
126
|
+
override to `public` lives in the wrapper + the `CLAUDE.md` convention this
|
|
127
|
+
recipe writes; keep those two authoritative.
|
|
128
|
+
|
|
129
|
+
2. Dry-run, then apply (see "Run it"). The wrapper is always re-vendored; an
|
|
130
|
+
existing downstream `SKILL.md` is left untouched, so a doc-only upstream
|
|
131
|
+
change must be re-broadcast deliberately (delete the downstream `SKILL.md`
|
|
132
|
+
first, or extend `apply.sh`).
|
|
133
|
+
|
|
134
|
+
The `CLAUDE.md` memory-discipline section (`files/CLAUDE.snippet.tmpl`) is
|
|
135
|
+
rollout-cli-authored, **not** vendored from eidetic-cli, so a wrapper refresh
|
|
136
|
+
does not touch it. It is gated on its marker phrase the same way: once a target
|
|
137
|
+
carries the section, a re-apply leaves it alone; to re-broadcast an edited
|
|
138
|
+
snippet, remove the marker line downstream first.
|
|
139
|
+
|
|
140
|
+
## Re-broadcasting: the work-branch collision
|
|
141
|
+
|
|
142
|
+
The engine names the work branch `rollout/<recipe-name>` — for this recipe,
|
|
143
|
+
`rollout/eidetic-memory` — and the `apply` CLI has **no `--branch` flag**. So a
|
|
144
|
+
*second* broadcast collides with the first round's branch wherever it still
|
|
145
|
+
exists (merged-but-not-deleted, or an open round-1 PR): the push is rejected and
|
|
146
|
+
that repo lands a `needs-attention` row. Deleting sibling branches in bulk is
|
|
147
|
+
also (rightly) refused by the agent's safety classifier. The clean fix is a
|
|
148
|
+
**fresh, unique branch name** per round — drive the engine directly:
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
# round-2 used branch="rollout/eidetic-memory-0.10" over fresh clones:
|
|
152
|
+
orchestrate.apply_one(clone_path, rec, branch="rollout/eidetic-memory-0.10",
|
|
153
|
+
repo_slug=slug, date=today, pr_opener=opener)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
A unique branch never collides and deletes nothing. (Round-2, 2026-06-24, opened
|
|
157
|
+
57/57 this way; `colleague`'s still-open round-1 PR became a harmless duplicate
|
|
158
|
+
to close.)
|
|
159
|
+
|
|
160
|
+
Refs: eidetic-cli skill ledger (`docs/skill-sources.md`), rollout-cli
|
|
161
|
+
`docs/skill-sources.md` (provenance rows for `remember` / `recall`).
|