Skip to content

feat: curl installer + uninstaller + CI smoke tests: https://github.com/riboseinc/claude-memory-files/issues/1 - #11

Merged
opoudjis merged 1 commit into
mainfrom
feat/install-uninstall-scripts
May 18, 2026
Merged

feat: curl installer + uninstaller + CI smoke tests: https://github.com/riboseinc/claude-memory-files/issues/1#11
opoudjis merged 1 commit into
mainfrom
feat/install-uninstall-scripts

Conversation

@opoudjis

Copy link
Copy Markdown
Member

Implements ticket #1; PR 7 of the delivery sequence.

Lands the v1 installer pair plus CI integration for it.

What this adds

  • tools/install.sh — POSIX-ish bash; deps curl + awk + jq + shasum. Per-type install behaviour for all 5 active types (rejects hook with a pointer to SAFETY.md). Settings-fragment deep-merge backs up settings.json first, dedupes permissions.{allow,deny,ask} arrays, and refuses extraneous top-level keys.
  • tools/uninstall.sh — reads the manifest, reverses each type. For settings-fragments, subtracts the recorded merged-fragment so hand-curated entries survive.
  • tools/test-install.sh — sandbox smoke test against --repo-root .. Asserts manifest schema, hand-curated-entry preservation, and clean-state after uninstall.
  • .github/workflows/validate.yml — adds shellcheck + smoke test. Runs on every PR.

Manifest schema

Every entry has all PR-9 fields written up front so PR 9's --update is read-only (no migration):

{
  "type": "instruction",
  "installed-at": "2026-...",
  "installed-hash": "sha256:...",
  "upstream-ref": "<commit-sha>",
  "source-path": "instructions/foo.md",
  "local-path": "/absolute/local/path.md",
  "forked": false,
  "merged-fragment": null,
  "history": [{ "event": "install", "ref": "...", "at": "..." }]
}

forked: true is set for scope: personal-share installs; merged-fragment is populated for settings-fragment installs (used by uninstall to subtract precisely).

CI integration (responding to your earlier concern)

Added to the existing validate.yml workflow:

  • shellcheck against install.sh, uninstall.sh, test-install.sh.
  • bash tools/test-install.sh runs end-to-end install/uninstall in a temp CLAUDE_DIR. Reads from --repo-root . so the test exercises the PR's exact content, not whatever's on main.

Locally verified the full smoke test passes (see commit message for details).

Curl one-liner UX

curl -fsSL https://raw.githubusercontent.com/riboseinc/claude-memory-files/main/tools/install.sh \
  | bash -s -- instructions/github-pr-title-issue-link.md

Project-CLAUDE.md needs --project:

curl -fsSL https://raw.githubusercontent.com/riboseinc/claude-memory-files/main/tools/install.sh \
  | bash -s -- --project ~/my-gem project-claude-md/ruby-gem.md

🤖 Generated with Claude Code

Implements ticket #1 (#1);
PR 7 of the delivery sequence.

Lands the v1 installer pair plus CI integration for it:

  - tools/install.sh: POSIX-ish bash, depends on curl + awk + jq + shasum.
    Fetches a file from raw.githubusercontent.com (or --repo-root <dir>
    for local checkouts and CI), parses YAML frontmatter, and applies
    per-type install behaviour:
      instruction       → ~/.claude/instructions/<name>.md + @-include in
                          CLAUDE.md under <!-- managed block --> markers
      memory-*          → ~/.claude/memory/<name>.md
      settings-fragment → deep-merge JSON block into ~/.claude/settings.json
                          (allowlisted top-level keys only; dedupes
                          permissions.{allow,deny,ask} arrays; backs up
                          before write)
      project-claude-md → <project>/CLAUDE.md (frontmatter stripped;
                          requires --project <dir>)
      path-rule         → ~/.claude/rules/<name>.md (or
                          <project>/.claude/rules/<name>.md with --project)
      hook              → rejected with pointer to SAFETY.md
    Records the install in ~/.claude/.memory-files-manifest.json with all
    fields PR 9's --update mode will need (installed-hash, upstream-ref,
    forked, merged-fragment for settings-fragments, history) written up
    front so PR 9 needs only read logic, not a manifest migration.

  - tools/uninstall.sh: reads the manifest entry by slug, reverses the
    install per type. For settings-fragments, subtracts the recorded
    merged-fragment from settings.json so hand-curated entries the user
    added themselves survive un-merge.

  - tools/test-install.sh: end-to-end smoke test exercising one file per
    type in a sandbox CLAUDE_DIR with --repo-root pointing at the local
    checkout. Validates the manifest schema (all PR-9 fields populated),
    the hand-curated-entry preservation case for settings-fragments, and
    the clean state after all uninstalls.

  - .github/workflows/validate.yml extension: shellcheck on the three
    shell scripts + runs tools/test-install.sh on every PR. Same workflow
    that already gates content; no new file. Bundled into PR 7 in response
    to the maintainer's concern that smoke tests should run in CI rather
    than depending on manual execution per PR.

Locally verified: install + uninstall round-trip works for all 5 types
against the current main; the hand-added Bash(rg:*) entry survives a
settings-fragment uninstall while the manifest-recorded entries are
removed cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@opoudjis opoudjis self-assigned this May 18, 2026
@opoudjis
opoudjis merged commit fce977e into main May 18, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant