From a3e4bca7f424dc7a62416352343498532dfc0279 Mon Sep 17 00:00:00 2001 From: "developerz-ai[bot]" <286432749+developerz-ai[bot]@users.noreply.github.com> Date: Fri, 18 Sep 2026 14:56:46 +0000 Subject: [PATCH] chore: establish the AI-first base for tesote/seven_zip_ruby Dz-Task-Id: tsk_70b5f5f18bc9150c721795cb6d2479c5 --- .claude/agents/archive-api.md | 27 +++++++ .claude/agents/native-glue.md | 27 +++++++ .claude/commands/feature.md | 47 +++++++++++ .claude/commands/planx.md | 40 ++++++++++ .../skills/build-native-extension/SKILL.md | 14 ++++ .claude/skills/verify-change/SKILL.md | 41 ++++++++++ .codegraph/.gitignore | 5 ++ .dz/maintainer/maintainer.yml | 62 +++++++++++++++ .dz/maintainer/reviewer.md | 28 +++++++ .dz/onboarding/scorecard.md | 78 +++++++++++++++++++ .githooks/pre-commit | 7 ++ .mcp.json | 35 +++++++++ AGENTS.md | 8 ++ CLAUDE.md | 41 ++++++++++ bin/check | 5 ++ bin/dev | 5 ++ bin/setup | 6 ++ docs/README.md | 11 +++ 18 files changed, 487 insertions(+) create mode 100644 .claude/agents/archive-api.md create mode 100644 .claude/agents/native-glue.md create mode 100644 .claude/commands/feature.md create mode 100644 .claude/commands/planx.md create mode 100644 .claude/skills/build-native-extension/SKILL.md create mode 100644 .claude/skills/verify-change/SKILL.md create mode 100644 .codegraph/.gitignore create mode 100644 .dz/maintainer/maintainer.yml create mode 100644 .dz/maintainer/reviewer.md create mode 100644 .dz/onboarding/scorecard.md create mode 100755 .githooks/pre-commit create mode 100644 .mcp.json create mode 100644 AGENTS.md create mode 100644 CLAUDE.md create mode 100755 bin/check create mode 100755 bin/dev create mode 100755 bin/setup create mode 100644 docs/README.md diff --git a/.claude/agents/archive-api.md b/.claude/agents/archive-api.md new file mode 100644 index 0000000..c4e194e --- /dev/null +++ b/.claude/agents/archive-api.md @@ -0,0 +1,27 @@ +--- +name: archive-api +description: Owns the public Ruby API in lib/seven_zip_ruby (Reader, Writer, EntryInfo, ArchiveInfo). Use for extract_all, add_data, password, entries, verify, sfx. Do NOT use for C++ extension internals or vendored p7zip code. +--- + +> Specialist definition — drafted by dz-runner setup mode from this repo, then owned by its maintainers. Correct it in place; setup never overwrites a definition that exists. + +## Identity + +You are an elite software engineer and the pilot of this task: own the outcome, decide inside your authority, optimise for the codebase's next year. Your duty: make the change in your brief and prove it with the repo's own checks. + +- Weigh long-term cost: maintainability, the next person debugging it, one-way doors (stored shapes, public contracts). +- Say "I don't know — checking", then check; never guess. +- Escalate only a true blocker: a destructive or irreversible action, auth, data integrity, a principle. +- Autonomy runs inside the leashes: always disclose you are a bot; everything is audited; policy and merge gates are machines, never you; never reply to another bot. +- You may be any model on any provider key: never name a model or assume vendor behaviour. +- Typed tools first: prefer the audited tools you were given over a raw command; batch independent calls, serialize only one that needs a prior result. +- Scale effort to the task: a one-line fix is not a research project; a migration is not one shot. +- Read the code before changing it. Reproduce a bug with a failing test first, then fix the cause. +- Make the smallest correct change. Done means a tool result in this run proves it, not a diff written. + +Public classes: SevenZipRuby::SevenZipReader, SevenZipWriter, EntryInfo, ArchiveInfo, UpdateInfo in lib/seven_zip_ruby/*.rb; the gem is loaded via lib/seven_zip_ruby.rb. +Both block and non-block forms are public API (Reader.open(file){|szr|...} and Reader.extract_all(file, dir)) — preserve both. +Passwords go through the password: option; a wrong password must raise, never yield corrupt data (fixed in 1.1.0). +Writer supports method= (LZMA, LZMA2, PPMD, BZIP2, DEFLATE, COPY), multi_thread=, sfx: :gui/:console, add_data/add_file/mkdir. +Every API change needs a matching example in README.md — it is the only documentation. +Specs cover this API in spec/seven_zip_ruby_spec.rb using fixture archives spec/seven_zip.7z and spec/seven_zip_password.7z; run `bundle exec rake build_local` before rspec after ext/ changes. diff --git a/.claude/agents/native-glue.md b/.claude/agents/native-glue.md new file mode 100644 index 0000000..55ddc11 --- /dev/null +++ b/.claude/agents/native-glue.md @@ -0,0 +1,27 @@ +--- +name: native-glue +description: Owns the C++ Ruby-extension glue in ext/seven_zip_ruby that wraps the vendored 7-zip library. Use for seven_zip_archive.cpp, extconf, Data_Get_Struct, mutex.h, native extension, segfault. Do NOT use for ext/p7zip internals or pure-Ruby API changes. +--- + +> Specialist definition — drafted by dz-runner setup mode from this repo, then owned by its maintainers. Correct it in place; setup never overwrites a definition that exists. + +## Identity + +You are an elite software engineer and the pilot of this task: own the outcome, decide inside your authority, optimise for the codebase's next year. Your duty: make the change in your brief and prove it with the repo's own checks. + +- Weigh long-term cost: maintainability, the next person debugging it, one-way doors (stored shapes, public contracts). +- Say "I don't know — checking", then check; never guess. +- Escalate only a true blocker: a destructive or irreversible action, auth, data integrity, a principle. +- Autonomy runs inside the leashes: always disclose you are a bot; everything is audited; policy and merge gates are machines, never you; never reply to another bot. +- You may be any model on any provider key: never name a model or assume vendor behaviour. +- Typed tools first: prefer the audited tools you were given over a raw command; batch independent calls, serialize only one that needs a prior result. +- Scale effort to the task: a one-line fix is not a research project; a migration is not one shot. +- Read the code before changing it. Reproduce a bug with a failing test first, then fix the cause. +- Make the smallest correct change. Done means a tool result in this run proves it, not a diff written. + +The Ruby API lives in ext/seven_zip_ruby/seven_zip_archive.cpp and util_common.h/utils.cpp; ext/p7zip is vendored 7-zip — never edit it. +Rebuild and test with `bundle exec rake build_local && bundle exec rspec spec/seven_zip_ruby_spec.rb` after any ext/ change. +Data_Get_Struct is deprecated on modern MRI; warnings are known, migrations to TypedData must keep Ruby >= 2.0 compat. +Platform forks exist: ext/seven_zip_ruby/win32/mutex.h vs posix/mutex.h — changes must build on Windows (nmake) and Linux/macOS. +The built artifact is copied to lib/seven_zip_ruby/seven_zip_archive.so (or .bundle); never commit it. +Free/allocate and exception safety in RubyCppUtil::wrapInitialize paths matter — GC bugs surface as flaky segfaults in the spec suite. diff --git a/.claude/commands/feature.md b/.claude/commands/feature.md new file mode 100644 index 0000000..1e39a54 --- /dev/null +++ b/.claude/commands/feature.md @@ -0,0 +1,47 @@ +--- +description: Take one change in tesote/seven_zip_ruby from idea to merged — explore, build, prove it with bin/check, open one pull request, watch it land. Use for feature, implement, build it, ship this, fix and merge. +argument-hint: +allowed-tools: Read, Write, Edit, Glob, Grep, Bash, Task +--- + +# /feature — idea to merged in tesote/seven_zip_ruby + +> Workflow command — established by dz-runner setup mode. Correct it in place; +> setup never overwrites a command that exists. + +**Done means MERGED.** A green local gate is not done, and an open pull request is not +done. Report what you verified, never what you assume happened. + +## Goal + +$ARGUMENTS + +## Steps + +1. Restate the goal in one line. If it names a URL or an issue, read it first. +2. **Distrust the paperwork.** Check any plan, status file or design doc against the code + and `git log` before working from it — trackers rot in both directions. Say plainly + which claims you falsified, and fix the doc in the same change. +3. Explore read-only, in parallel, into a ranked worklist of PR-sized batches. +4. Build primitive-first: one reusable primitive with its first real caller. No + abstraction before a consumer. +5. **Prove it.** `bin/setup` after any dependency change, then `bin/check`, which here is + `bundle exec rake build_local && bundle exec rspec spec/seven_zip_ruby_spec.rb`. + Red is not a pull request: fix the cause, never silence the gate. Add the failing test + first — a green run that never went red proves nothing. +6. **One pull request in flight, start to finish.** Open it, watch it to merged, run + `git fetch`, and only then start the next. Each merge rebases the base under the + other, and green-when-opened is not green-to-merge. +7. Re-check the original symptom after the merge, and leave the issues and docs true. + +## Fan-out rules — restate these to every agent you spawn + +- **One checkout. No git worktrees.** Work would land in a directory nobody is looking at, + and each tree costs its own install and its own test database. Disjoint file sets are a + scheduling problem you can see; isolation is one you cannot. +- **Exclusive file sets.** Two agents never write one file, and a rename or a signature + change pulls every caller into the same set. +- **No git in a spawned agent** — no add, commit, branch, stash or push. You own git, and + you touch it only once every agent has returned. +- **Scope each agent to the files it edited.** The repo-wide gate is yours, run once, at + the end. diff --git a/.claude/commands/planx.md b/.claude/commands/planx.md new file mode 100644 index 0000000..aecd303 --- /dev/null +++ b/.claude/commands/planx.md @@ -0,0 +1,40 @@ +--- +description: Write a self-contained implementation plan under docs/plans/ for another agent to execute. Use for plan, planx, design the work, break this down. +argument-hint: +allowed-tools: Read, Glob, Grep, Bash, Write +--- + +# /planx — plan a piece of work in tesote/seven_zip_ruby + +> Workflow command — established by dz-runner setup mode. Correct it in place; +> setup never overwrites a command that exists. + +**Plan only.** No implementation, no edits outside the plan directory. A plan that lives +only in a session's context dies with the session; on disk it is reviewable, correctable, +and restartable by whoever picks it up. + +## Goal + +$ARGUMENTS + +## Steps + +1. Resolve the directory: `date +%Y %m %d`, then the highest existing `1NN-*` under + `docs/plans///
/` plus 1, else `101`. Slug kebab-case, 5 words max. +2. Explore read-only first — find the patterns to follow and the files to change. +3. Write `overview.md`: goal (1-2 sentences), context (only the facts the executor needs, + as `path:line`), the slice files in execution order, done-when, risks. +4. Write one `-.md` per separable AREA OF WORK — `01-data-model.md`, + `02-api.md`, `03-frontend.md`. Each carries: what it depends on, files to change + (`path:line` — what, why), ordered steps, the tests to add, done-when. +5. Write `status.yml`: `plan`, `title`, `status`, `owner`, `percent`, `current_focus`, + `slices`, `evidence` (commits/PRs), `last_updated`. + +## Rules + +- **Reference, never restate.** Cite `path:line`; pasted code is stale the day it is pasted. +- **Self-contained.** The executor reads `overview.md`, its own slice, and what those cite. +- **Split by area of work, never by chapter.** A slice boundary is the file-set boundary the + build fans out on, and that file set is one pull request. +- **`status.yml` is the only tracker.** No checkboxes in a `.md` — two trackers disagree. +- **Skip the plan for a one-file fix.** Writing it costs more than the change. diff --git a/.claude/skills/build-native-extension/SKILL.md b/.claude/skills/build-native-extension/SKILL.md new file mode 100644 index 0000000..4e05ed5 --- /dev/null +++ b/.claude/skills/build-native-extension/SKILL.md @@ -0,0 +1,14 @@ +--- +description: Rebuilding the C++ native extension via rake build_local after touching lib/ or ext/. Use for build_local, extconf, seven_zip_archive.so, compile error, native extension. +--- + +> House skill — established by dz-runner setup mode from this repo's own evidence, then owned by its maintainers. Correct it in place; setup never overwrites a skill that exists. + +1. Run `bundle install` if not already done. +2. Build and copy the native binary: `bundle exec rake build_local`. + - It runs extconf.rb inside `ext/seven_zip_ruby`, invokes make (override with `MAKE=...` env; nmake on mswin), and copies `seven_zip_archive.so|bundle` into `lib/seven_zip_ruby/`. + - Compile errors in `ext/p7zip/**` -> stop; that is vendored source, do not patch it. +3. Clean rebuild when stale: `bundle exec rake build_local_clean && bundle exec rake build_local` (or `rake build_local_all`). +4. Prove the build: `bundle exec rspec spec/seven_zip_ruby_spec.rb`. +5. Only the `set multi_thread` example may legitimately fail from machine timing -> re-run before investigating. +6. Never commit the copied `lib/seven_zip_ruby/seven_zip_archive.so|bundle`; they are build output. diff --git a/.claude/skills/verify-change/SKILL.md b/.claude/skills/verify-change/SKILL.md new file mode 100644 index 0000000..edf6847 --- /dev/null +++ b/.claude/skills/verify-change/SKILL.md @@ -0,0 +1,41 @@ +--- +description: Prove a change in tesote/seven_zip_ruby before committing or opening a pull request — the repo's own install, run and check commands. Use before every commit. +--- + +# Verify a change in tesote/seven_zip_ruby + +> House skill — established by dz-runner setup mode from this repo’s own +> detected commands. Correct it in place; setup never overwrites a skill that exists. + +## The one gate + +`bin/check` is the gate. CI runs it and the pre-commit hook runs it, so a change that +passes it locally passes everywhere. + +| Step | Command | What it is | +|------|---------|------------| +| install | `bin/setup` | bundle install | +| run | `bin/dev` | bundle exec rake build_local | +| prove | `bin/check` | bundle exec rake build_local && bundle exec rspec spec/seven_zip_ruby_spec.rb | + +## Rules + +- Run every command from the repo root — the scripts `cd` there themselves. +- `bin/check` red is not a pull request. Fix the cause, never silence the gate. + +## Exit codes `bin/check` must use + +A coding box runs this gate before it commits, and it has to tell a FAILING change +from a gate it could not run — otherwise correct work is thrown away as if it were +red. Exit 1 cannot carry that difference, so one code is reserved: + +| Exit | Means | What the platform does | +|------|-------|------------------------| +| 0 | the change passes | commit it | +| 75 | a resource the gate NEEDS is unreachable (a database, a service, a credential) — it refused to grade | refuse the commit, and blame the environment, never the change | +| any other non-zero | the gate ran and the change is red | refuse the commit, and blame the change | + +- Guard preconditions FIRST and `exit 75` when one is unmet. `exit 1` there tells the + platform your change is broken when it is your environment that is. +- Changed a dependency? Re-run `bin/setup` before `bin/check`, or you are proving a stale tree. +- Add the test that fails first, then the fix — a green run that never went red proves nothing. diff --git a/.codegraph/.gitignore b/.codegraph/.gitignore new file mode 100644 index 0000000..d20c0fe --- /dev/null +++ b/.codegraph/.gitignore @@ -0,0 +1,5 @@ +# CodeGraph data files — local to each machine, not for committing. +# Ignore everything in .codegraph/ except this file itself, so transient +# files (the database, daemon.pid, sockets, logs) never show up in git. +* +!.gitignore diff --git a/.dz/maintainer/maintainer.yml b/.dz/maintainer/maintainer.yml new file mode 100644 index 0000000..c99fb09 --- /dev/null +++ b/.dz/maintainer/maintainer.yml @@ -0,0 +1,62 @@ +# .dz/maintainer/maintainer.yml — how the developerz.ai maintainer agent may act on tesote/seven_zip_ruby. +# Proposed by dz-runner setup mode; MERGING this pull request is the opt-in. +# +# This is the AUTONOMOUS posture: PRs merge when the machine gates pass, and the bot +# qualifies issues and dispatches coding. Releases follow the `release:` block below. +# The keys below are the ones you tune by hand — every other knob falls back to the +# schema defaults. Full reference: https://developerz.ai/docs/maintainer-yml +version: 1 + +# Services this repo's own verify gate needs running before it can grade a diff. +# None detected — leave the array empty or declare the service this gate needs. +services: [] + +# handoff: coding dispatches to the developerz fleet (BYOVM). `fleet` needs no +# `webhook_ref`: the fleet claims each task directly, and no external webhook fires. +handoff: + mode: fleet + # autonomous posture: go straight to coding rather than asking the reporter first. + ask_reporter_first: false + +# pr: +# - `auto_merge: true` must be written out: the schema default does not count as +# opting in, and without this line the free and open-source tiers keep +# auto-merge off. +# - `wait_for_other_bots` lists the review bots the agent defers to; it never +# argues with another bot. +# - `require_review: true` — CI green alone is not enough; a PR nobody reviewed +# does not merge. +pr: + auto_merge: true + wait_for_other_bots: [coderabbit, copilot] + require_review: true + large_threshold_lines: 500 + +# release: derived from the detected mechanism. The comment below names which +# one was observed for this repo; the rendered line is the safe default either way. +release: + # No release mechanism was observed in the entries supplied; the agent is not cutting releases on this repo. + manager: none + channels: [] + +# review: the developerz.ai reviewer, alongside any review bot already installed. +# `force: true` runs it beside CodeRabbit rather than standing down; remove it once +# you have moved off the other bot. `request_changes: false` and `approval: false`: +# the first pass comments only — it never blocks a merge and never approves. +review: + enabled: true + force: true + depth: inline + request_changes: false + approval: false + +# triage: ask reporters for repro before dispatching coding — keeps the coding +# queue honest about which issues are dispatch-ready. +triage: + ask_for_repro: true + +# escalate: the schema defaults already cover these; stated so you can see what +# stays with a human. +escalate: + always: [hostile_tone, direct_mention] + ask_before_acting: [breaking_change, major_dep_bump, first_time_contributor, large_pr] diff --git a/.dz/maintainer/reviewer.md b/.dz/maintainer/reviewer.md new file mode 100644 index 0000000..41b2eb0 --- /dev/null +++ b/.dz/maintainer/reviewer.md @@ -0,0 +1,28 @@ +# Reviewer instructions — tesote/seven_zip_ruby + +> Read by the developerz.ai reviewer at EVERY review of this repository, at the reviewed +> commit, as this repo's own layer of the reviewer's prompt — established by dz-runner setup mode. +> It refines the platform rules (a finding is cited or withheld; the bot always discloses) +> and never overrides them. Edit freely; keep it under 12,000 characters — past that it is cut. + +## Stack + +Ruby + Bundler (C++ native extension). The gate is `bin/check` (`bundle exec rake build_local && bundle exec rspec spec/seven_zip_ruby_spec.rb`): a change that does not pass it is not proven, whatever its description says. + +## Review conventions +- Require a fresh `bundle exec rake build_local` before rspec after any change under `lib/` or `ext/` — the Ruby tests load the copied native binary `lib/seven_zip_ruby/seven_zip_archive.so`. +- Treat `ext/p7zip/**` and the prebuilt `lib/seven_zip_ruby/7z*.dll|sfx` blobs as vendored; flag edits to them as suspect. +- Real API changes must be reflected in README.md examples (the README is the only user doc). +- Keep gemspec dev-dependency discipline: no new runtime gem dependencies for this gem. +- Password handling: wrong password must raise an exception (established 1.1.0 behavior), not silently corrupt output. + +## Gates that matter +- The whole gate is `bundle exec rake build_local && bundle exec rspec spec/seven_zip_ruby_spec.rb` — identical to `.github/workflows/ci.yml` (the "Rspec" badge) and `.travis.yml`. +- "Proven" means all 44 examples pass. The `set multi_thread` spec (`spec/seven_zip_ruby_spec.rb:601`) is a wall-clock timing comparison of single- vs multi-threaded BZIP2 and is flaky on loaded or single-core machines; if only that example fails, re-run before rejecting the change. +- CI matrix runs Ubuntu/macOS/Windows across Ruby 2.1–2.7/head — a change to the C++ glue should consider Windows (`win32/mutex.h` vs `posix/mutex.h`). + +## Never flag +- Vendored p7zip/7-zip C/C++ source under `ext/p7zip/`, including its many platform makefiles and `Alloc.c.back*` files. +- Deprecated-Ruby-C-API warnings (e.g. `Data_Get_Struct`) from the extension build — pre-existing, informational only. +- Absence of RuboCop: the repo has no lint config; do not demand lint compliance. +- Old-style Ruby (no frozen_string_literal comments, `attr_accessor` patterns) — the gem targets Ruby >= 2.0 by design. diff --git a/.dz/onboarding/scorecard.md b/.dz/onboarding/scorecard.md new file mode 100644 index 0000000..caece78 --- /dev/null +++ b/.dz/onboarding/scorecard.md @@ -0,0 +1,78 @@ +# AI-first scorecard + +> Written by the developerz.ai maintainer agent — established by dz-runner setup mode. Each onboarding run rewrites this file whole; the latest run wins, and the same card is stored on the platform. + +- Run: `run_553e9c7027ea4d05a8054f6811d82a39` +- Computed: 2026-09-18T14:56:46.060Z +- Proof: **unprovable** — `bin/check` did not run green at head on this box. Nothing in the repository’s own code was changed to force it; the excerpt below is the record. +- Score: 10 of 15 items ok + +## `policy` — ok + +- .dz/maintainer/maintainer.yml established +- .dz/maintainer/reviewer.md established + +## `brain` — ok + +- CLAUDE.md established + +## `roster` — ok + +- .claude/agents/native-glue.md established +- .claude/agents/archive-api.md established + +## `skills` — ok + +- .claude/skills/verify-change/SKILL.md established +- .claude/skills/build-native-extension/SKILL.md established + +## `scripts` — ok + +- bin/setup established +- bin/dev established +- bin/check established +- ./bin/setup exited 0 at head (0.3s) + +## `wiring` — ok + +- .mcp.json established + +## `commands` — ok + +- .claude/commands/planx.md established +- .claude/commands/feature.md established + +## `access` — gap + +- asked for 0 credentials + +## `layout` — gap + +- migration to the house layout filed as tasks +- apps/seven-zip-ruby: 8 move(s) planned as one task + +## `smoke_test` — unprovable + +- spec/seven_zip_ruby_spec.rb in the repository +- ./bin/check at head: red, exit 1 (70.6s) + +## `env_example` — gap + +- nothing recorded + +## `agents_md` — ok + +- AGENTS.md established + +## `per_workspace_brains` — ok + +- single-package repository: 0 workspaces +- CLAUDE.md established + +## `docs_readme` — ok + +- docs/README.md established + +## `gate_proved` — unprovable + +- ./bin/check at head: red, exit 1 (70.6s) diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000..c3b9929 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +# pre-commit gate — established by dz-runner setup mode. Runs the SAME +# `bin/check` CI runs, so a commit that would fail CI fails here first. +# ACTIVATE IT (once, per clone): git config core.hooksPath .githooks +set -euo pipefail +cd "$(dirname "$0")/.." +exec bin/check diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..4bd7cb6 --- /dev/null +++ b/.mcp.json @@ -0,0 +1,35 @@ +{ + "mcpServers": { + "sentry-mcp": { + "type": "stdio", + "command": "bunx", + "args": [ + "@sentry/mcp-server" + ], + "env": { + "SENTRY_ACCESS_TOKEN": "${SENTRY_ACCESS_TOKEN}", + "SENTRY_HOST": "${SENTRY_HOST}" + } + }, + "codegraph": { + "type": "stdio", + "command": "codegraph", + "args": [ + "serve", + "--mcp" + ], + "env": { + "DO_NOT_TRACK": "1", + "CODEGRAPH_TELEMETRY": "0", + "CODEGRAPH_NO_UPDATE_CHECK": "1" + } + }, + "developerz": { + "type": "http", + "url": "https://mcp.developerz.ai/v1/mcp", + "headers": { + "Authorization": "Bearer ${DEVELOPERZ_API_KEY}" + } + } + } +} diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..36b340c --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,8 @@ +# tesote/seven_zip_ruby + +> Pointer — established by dz-runner setup mode. Two names, ONE brain. + +This repository's brain is [`CLAUDE.md`](CLAUDE.md) — read it before +you touch anything here. `AGENTS.md` exists because some agents look for this name +first; it is a pointer, never a second copy, because two brains drift and the reader +cannot tell which one is current. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..04e22ab --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,41 @@ +# tesote/seven_zip_ruby + +> Project brain — established by dz-runner setup mode from this repo, then owned by +> its maintainers. Correct it in place; setup never overwrites a brain that exists. + +SevenZipRuby — a Ruby gem (native C++ extension wrapping the official 7-Zip/p7zip sources) for reading, extracting and writing 7-Zip archives; maintained as an open-source library by masamitsu-murase (upstream) with CI on GitHub Actions. + +## Stack + +Ruby + Bundler (C++ native extension) + +Toolchain: `mise.toml` — `bin/setup` runs `mise install`; the box carries only bun. + +## Commands + +| Task | Command | +|------|---------| +| setup | `bin/setup` — bundle install | +| dev | `bin/dev` — bundle exec rake build_local | +| check | `bin/check` — bundle exec rake build_local && bundle exec rspec spec/seven_zip_ruby_spec.rb | + +## Structure + +- `lib/seven_zip_ruby.rb` + `lib/seven_zip_ruby/*.rb` — the public Ruby API (SevenZipReader, SevenZipWriter, EntryInfo, ArchiveInfo, UpdateInfo, Exception). Loads the compiled binary `seven_zip_archive.so` from `lib/seven_zip_ruby/`. +- `lib/seven_zip_ruby/7z.dll`, `7z64.dll`, `7z.sfx`, `7zCon.sfx` — prebuilt official 7-Zip binaries shipped in the gem (Windows DLL + SFX stubs). +- `ext/seven_zip_ruby/` — the Ruby C++ extension glue (seven_zip_archive.cpp, utils.cpp, extconf.rb; per-platform `win32/mutex.h` / `posix/mutex.h`). Built by `rake build_local` via extconf + make; the `.so`/`.bundle` is copied into `lib/seven_zip_ruby/`. +- `ext/p7zip/` + `ext/CPP/` + `ext/C/` — vendored p7zip / 7-Zip C and C++ sources compiled into the extension. Never hand-edit. +- `spec/` — RSpec suite (`seven_zip_ruby_spec.rb` + helper) with fixture archives (`seven_zip.7z`, `seven_zip_password.7z`). +- `resources/` — logo and platform-gemspec template used by `rake build_platform`; excluded from the gem files. +- `Rakefile` — native build tasks: `build_local` (`build_binary` + `copy_binary`), `build_local_clean`, `build_platform`. +- Dependency rule: `spec/` → `lib/` (Ruby API) → compiled `seven_zip_archive.so` (from `ext/seven_zip_ruby/` + `ext/p7zip`). Changing `lib/` or `ext/` requires `rake build_local` before running specs. + +## Conventions + +- Ruby >= 2.0; gemspec declares dev deps only: bundler, rake, rspec (plus rubysl-* under rbx). No runtime gems. +- Tests are RSpec in `spec/`; the suite entry is `spec/seven_zip_ruby_spec.rb`, helper `spec/seven_zip_ruby_spec_helper.rb`; fixtures are real archives in `spec/*.7z` (incl. an encrypted one). +- Any change to `lib/` or `ext/seven_zip_ruby/` requires a rebuild before testing: `bundle exec rake build_local` (CI runs it as its install step). +- No RuboCop/lint config exists; style follows the existing code (`{ |i| ... }` braces, 2-space indent, snake_case). +- `ext/p7zip/**` is vendored 7-zip/p7zip source — never hand-edit it; changes belong in the glue code `ext/seven_zip_ruby/*.{cpp,h}`. +- Binary blobs in `lib/seven_zip_ruby/` (7z.dll, 7z64.dll, 7z.sfx, 7zCon.sfx, *.so, *.bundle) are build output/vendor, not source. +- Passwords are passed via the `password:` option to `Reader.open`/`extract_all`; wrong password must raise, not return bad data. diff --git a/bin/check b/bin/check new file mode 100755 index 0000000..11b6923 --- /dev/null +++ b/bin/check @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# one-command check (typecheck + lint + test) — established by dz-runner setup mode. One command; adjust as the repo grows. +set -euo pipefail +cd "$(dirname "$0")/.." +bundle exec rake build_local && bundle exec rspec spec/seven_zip_ruby_spec.rb diff --git a/bin/dev b/bin/dev new file mode 100755 index 0000000..12ff8b6 --- /dev/null +++ b/bin/dev @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# one-command dev — established by dz-runner setup mode. One command; adjust as the repo grows. +set -euo pipefail +cd "$(dirname "$0")/.." +bundle exec rake build_local diff --git a/bin/setup b/bin/setup new file mode 100755 index 0000000..bb62b81 --- /dev/null +++ b/bin/setup @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +# one-command setup — established by dz-runner setup mode. One command; adjust as the repo grows. +set -euo pipefail +cd "$(dirname "$0")/.." +command -v mise >/dev/null && mise install +bundle install diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..247aefd --- /dev/null +++ b/docs/README.md @@ -0,0 +1,11 @@ +# tesote/seven_zip_ruby — docs + +> Index — established by dz-runner setup mode. Add a line when you add a page. + +| Where | What lives there | +|---|---| +| [`idea/`](idea/) | Why this repository is shaped the way it is: the product idea, the architecture, the principles a change is weighed against. *(not created yet)* | +| [`standards/`](standards/) | How work is done here: the rules a change follows, and for each rule the check that enforces it. *(not created yet)* | + +The brain itself is the repo root's [`CLAUDE.md`](../CLAUDE.md); the +commands are `bin/{setup,dev,check}`.