diff --git a/CHANGELOG.md b/CHANGELOG.md index 29ab13f..e0b86d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,9 +14,24 @@ packaged desktop and daemon. - Added native repository selection, agent settings, diagnostics, session recovery, bounded terminal replay, and safe worktree removal. - Rebranded the desktop experience as Jig and refreshed its app identity. +- Added a local prompts/context library, explicit rule and skill discovery, + and a composer that sends only to the selected live terminal. +- Added revision-checked local file IPC and organization metadata contracts; + file editor and organization canvas integration remain separate work. +- Made process snapshots monotonic to prevent older concurrent scans from + replacing newer session process observations. - Expanded Linux and macOS acceptance coverage and hardened process, path, confirmation, and error handling. +### Open-source project + +- Added the MIT license to the repository, package metadata, and application + bundle resources. +- Added a security policy with private vulnerability reporting, updated the + contribution guide, and clarified installation and development commands. +- Added the missing `pnpm package` command and documented distribution status + without implying unverified package-manager availability. + ### Distribution - Linux: unsigned AppImage. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d854d73..0a63b85 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,106 +1,164 @@ -# Contributing to CLI Master +# Contributing to Jig -CLI Master welcomes focused changes that move the Beta v0.1 acceptance flow -forward while preserving terminal correctness and Git safety. +Jig welcomes bug reports, documentation improvements, tests, and focused +changes that preserve terminal correctness and Git safety. You do not need to +be a Rust developer to contribute. ## Before you begin Read these files: -1. [README.md](README.md) for setup and validation commands. -2. [ARCHITECTURE.md](ARCHITECTURE.md) for accepted system boundaries. -3. [AGENTS.md](AGENTS.md) for crate ownership and the IPC catalog. -4. [design-system/cli-master/MASTER.md](design-system/cli-master/MASTER.md) for +1. [README.md](README.md) for what Jig does and how to run it. +2. [docs/install.md](docs/install.md) for native build prerequisites. +3. [ARCHITECTURE.md](ARCHITECTURE.md) for accepted system boundaries. +4. [AGENTS.md](AGENTS.md) for crate ownership and the IPC catalog. +5. [design-system/cli-master/MASTER.md](design-system/cli-master/MASTER.md) for interface and accessibility rules. -Windows support and the future features listed as out of scope in the -architecture are not accepted for Beta v0.1 unless the core acceptance flow is -already complete and stable. +Current development targets Beta v0.2 for Linux and macOS. Discuss substantial +features, new dependencies, or platform support in an issue before starting a +large change. Windows is outside the Beta scope. -## Development workflow +## Report a bug or suggest a feature -1. Create a focused branch from the current `main` branch. -2. Make one coherent change at a time. -3. Add or update tests for every public behavior. -4. Run the complete local gate. -5. Commit with a Conventional Commit title and an explanatory body. +Search [existing issues](https://github.com/guicybercode/Jig/issues) first. +For a bug, include: + +- Jig version or commit, operating system, and CPU architecture. +- Whether you used a release bundle or `pnpm tauri dev`. +- Small, reproducible steps and the expected versus actual result. +- Relevant sanitized diagnostics; never paste tokens, complete environments, + private repository contents, or confidential terminal output. + +For a feature, explain the workflow and the problem it solves. If it changes +process lifecycle, filesystem access, or Git behavior, describe the safety +implications too. + +**Do not report vulnerabilities in a public issue.** Follow +[SECURITY.md](SECURITY.md) instead. + +## Set up your development environment + +Use Node.js 24, the pinned pnpm 11.9.0, stable Rust, Git, and your platform's +Tauri dependencies as described in the [README](README.md#run-from-source). +Fork the repository if you do not have push access, then clone your fork and +create a focused branch from the current `main`. ```bash pnpm install --frozen-lockfile -pnpm check +pnpm tauri dev +``` + +`pnpm dev` is only the browser frontend; it is not a substitute for running +the native desktop app. Internal Cargo names, the daemon executable, and the +`@cli-master/desktop` workspace package still use the historical CLI Master +name. Use those exact identifiers in commands. + +## Validate your change + +From the repository root: + +```bash pnpm check:versions -cargo fmt --all -- --check -cargo clippy --workspace --all-targets -- -D warnings -cargo test --workspace +bash scripts/stage-sidecar.sh --debug +cargo build -p cli-master-fake-agent --locked +pnpm check +pnpm --filter @cli-master/desktop exec playwright install chromium +pnpm --filter @cli-master/desktop test:e2e ``` -Use commit titles such as: +On Linux, installing Chromium's system dependencies may require +`pnpm --filter @cli-master/desktop exec playwright install --with-deps chromium`. + +`pnpm check` runs frontend type checks, unit tests, and the Vite build, followed +by Rust formatting, Clippy, workspace tests, and documentation with warnings +treated as errors. Version checks and Playwright are separate. CI runs quality +and packaging jobs on both Linux and macOS. + +For a faster feedback loop while editing: -```text -feat(projects): validate repository roots -fix(worktrees): block dirty removal -test(session): cover PTY resize -docs: explain daemon recovery +```bash +pnpm test:frontend +cargo test -p cli-master-session --locked ``` -Keep commits reviewable. Do not combine formatting, dependency upgrades, and a -feature in one commit. +Run relevant targeted tests as you work, then the complete gate before +requesting review. For documentation-only changes, verify commands against +the scripts, check links, and run `git diff --check`; explain skipped runtime +checks in the pull request. Never claim to have run checks you skipped. + +## Open a pull request + +1. Keep one coherent change per pull request. Do not mix formatting, + dependency upgrades, and a feature. +2. Add or update tests for changed public behavior. Bug fixes need a + regression test that fails without the fix. +3. Update affected documentation and all IPC mirrors when relevant. +4. Use a descriptive Conventional Commit title, such as + `fix(worktrees): block dirty removal` or `docs: explain daemon recovery`. +5. Target `main`. Explain the problem, solution, tests run, and known limits. + Include screenshots for visible UI changes and link the related issue. +6. Wait for review and CI. Do not weaken assertions or bypass safety checks + to make a failing job pass. -## Code expectations +## Code and test expectations - Prefer small modules connected through explicit typed interfaces. - Keep public APIs documented and actionable errors specific. - Do not use TypeScript `any` or untyped Rust serialization boundaries. +- Keep `crates/core` free of I/O. The daemon, not React or Tauri, owns sessions. - Keep PTY output outside React state and SQLite write loops. - Pass executables and arguments separately; do not introduce a generic shell - execution IPC command. -- Do not add a dependency when the platform or standard library already solves - the problem clearly. -- Preserve Linux and macOS behavior in shared abstractions. + execution IPC command or interpolate commands into `sh -c`. +- Preserve Linux and macOS behavior in shared abstractions and tests. +- Update authoritative Rust wire types before the TypeScript and JSON + mirrors; do not add a domain-specific Tauri command. -## Tests +Backend tests use real temporary directories, real Git, real SQLite, and +short-lived child programs. Interactive runtime acceptance uses +`cli-master-fake-agent` through `CommandSpec`. Wait on observable readiness +or state, not arbitrary sleeps to hide a race. -Tests must be headless, deterministic, and independent. Use temporary -directories and databases for filesystem, Git, and SQLite integration tests. -Use short-lived real child programs for PTY lifecycle tests. Beta acceptance -that needs an interactive agent should launch `cli-master-fake-agent` through -`CommandSpec`, never `sh -c`. Wait on readiness lines, session status, Git -errors, or SQLite rows. Do not add `sleep(3)` calls to hide races. - -Frontend tests should query semantic roles and labels. Mock the project-owned -backend client rather than scattering Tauri mocks through components. Do not -unit-test xterm.js internals. - -Bug fixes require a regression test that fails without the fix. +Frontend tests query semantic roles and labels and mock the project-owned IPC +client rather than scattered Tauri APIs. Do not unit-test xterm.js internals. ## User interface changes - Preserve complete keyboard operation and visible focus. -- Include text or shape with status colors. +- Include text or shape with status colors and respect reduced motion. - Keep terminal control chords available while xterm has focus. -- Respect reduced-motion preferences. - Do not add remote fonts, decorative animation frameworks, or simulated terminal output. - -Verify responsive behavior at 375px, 768px, 1024px, and 1440px widths even -though the packaged desktop window has a larger minimum size. Narrow browser -views remain useful for accessibility and layout regression testing. +- Verify layouts at 375px, 768px, 1024px, and 1440px widths. ## Git and process safety -Changes that can stop processes or modify worktrees need tests for failure and +Changes that stop processes or modify worktrees need tests for failure and partial completion. Never introduce automatic force deletion, `git reset --hard`, PID-only reattachment, or recursive deletion of an unvalidated path. +Worktree removal requires preparation and a state-bound confirmation token. +Deleting session metadata must not delete a worktree; removing a project must +not delete its directory. Closing a window or removing a canvas card must not +stop daemon-owned sessions. + When an operation spans SQLite and Git, represent intermediate states and make -recovery visible. Do not claim atomic behavior that the system cannot provide. +recovery visible. Do not claim atomic behavior the system cannot provide. + +## Documentation and releases + +Write in clear, direct English and keep shell examples safe to paste. Update +setup commands when tooling changes. Architectural changes require an ADR; +do not silently rewrite accepted boundaries. -## Documentation +Packaging changes need matching updates to [docs/PACKAGING.md](docs/PACKAGING.md) +and [docs/RELEASE_CHECKLIST.md](docs/RELEASE_CHECKLIST.md). `pnpm package` produces +local unsigned bundles; it does not publish a GitHub Release. Release +publication is a separate maintainer action. Never commit signing secrets, +notarization credentials, or vendor API keys. -Write in clear, direct language. Update README setup commands when tooling -changes and update ARCHITECTURE.md only when an accepted boundary or tradeoff -changes. Keep examples safe to paste into a shell. +## License -Packaging changes need a matching note in [docs/PACKAGING.md](docs/PACKAGING.md) -and [docs/RELEASE_CHECKLIST.md](docs/RELEASE_CHECKLIST.md). Do not add signing -secrets, notarization credentials, or a CI job that publishes a GitHub Release. +Jig is licensed under [MIT](LICENSE). Submit only code and documentation you +have the right to contribute, under the project's license. Preserve required +notices for third-party material and identify it in your pull request. diff --git a/Cargo.toml b/Cargo.toml index 0ce1017..279e5d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,8 @@ resolver = "2" edition = "2024" rust-version = "1.85" version = "0.2.0" +license = "MIT" +repository = "https://github.com/guicybercode/Jig" [workspace.lints.rust] unsafe_code = "forbid" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3a0f29a --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 guicybercode and Jig contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 9bee3a4..f7a5391 100644 --- a/README.md +++ b/README.md @@ -1,109 +1,147 @@ # Jig -Terminals on a canvas. +Terminals on a canvas. A local-first desktop workspace for coding-agent CLIs. -![Jig](docs/brand/social-preview.png) +[Releases](https://github.com/guicybercode/Jig/releases) · +[Installation guide](docs/install.md) · [Contributing](CONTRIBUTING.md) · +[Security](SECURITY.md) · [MIT license](LICENSE) -## Install and run +![Jig — terminals on a canvas](docs/brand/social-preview.png) -Jig is a local-first desktop app for Linux and macOS. Windows is out of scope for Beta v0.2. +## What is Jig? -### Prerequisites +Jig brings real terminals, project folders, Git worktrees, notes, and browser +cards into one canvas. Run Codex, Claude Code, Gemini CLI, OpenCode, a shell, +or your own executable, and keep related work together. -- Node.js 22 or newer -- Corepack and pnpm 11 -- Rust 1.85 or newer -- Git on PATH -- Tauri 2 dependencies (WebKitGTK 4.1 on Linux, Xcode Command Line Tools on macOS) +Jig is not a coding agent or a vendor proxy. No Jig account is required. Agent +CLIs are installed separately and keep their own authentication and network +connections. Git worktrees separate working copies; they are not a security +sandbox for the programs you launch. -### Development +The source tree targets **Beta v0.2.0** for Linux and macOS. Read the +[known limitations](docs/KNOWN_ISSUES.md) before using it for important work. -```bash -# Enable package manager and install dependencies -corepack enable -pnpm install --frozen-lockfile +## Download and install -# Run the desktop app -pnpm tauri dev -``` +Use [GitHub Releases](https://github.com/guicybercode/Jig/releases) for published +builds. The [Packaging workflow](https://github.com/guicybercode/Jig/actions/workflows/packaging.yml) +provides temporary candidate artifacts; an Actions build is not a published +release. The version in this source tree may be newer than the latest release. -### Build from source +| Platform | Architecture | Package format | +| --- | --- | --- | +| Linux | x86_64 | AppImage | +| macOS 12+ | Apple Silicon (aarch64) | DMG or zipped `.app` | +| Windows | — | Not supported in this Beta | -```bash -# Stage daemon and build platform bundle (AppImage on Linux, .app and .dmg on macOS) -pnpm package -``` - -Builds are unsigned. macOS notarization is not configured. See [docs/install.md](docs/install.md) for platform-specific installation and verification steps. +See [package availability](docs/distribution.md) for distribution channels and +Linux repository status. Do not assume a similarly named package is this Jig. -## What it is +Download the artifact for your platform and its checksum file, verify it, +then follow the [installation guide](docs/install.md). Builds are **unsigned +and not notarized**; macOS may block the first launch. Git must be installed +and available on `PATH`. Node.js and Rust are needed only for source builds. -Jig hosts coding-agent CLIs in real terminals with projects and Git worktrees. It coordinates OpenAI Codex, Claude Code, Gemini CLI, OpenCode, and custom executables in isolated PTY sessions. +## Run from source -**Current status:** Beta v0.2 connects project management, isolated worktrees, agent discovery, live PTY sessions, and the terminal canvas through the packaged desktop and daemon. The stable IPC protocol is defined in `crates/core/src/wire`. See [docs/KNOWN_ISSUES.md](docs/KNOWN_ISSUES.md) for current limitations and [ARCHITECTURE.md](ARCHITECTURE.md) for accepted design decisions. +### Prerequisites -This is a local-first application. No cloud account, telemetry, or vendor proxy is required. Each agent CLI keeps its own authentication. +- **Node.js 24**, matching CI, and **pnpm 11.9.0**, pinned in `package.json`. +- **Rust stable** and Cargo. CI uses current stable Rust, not a separate + minimum-version job for the workspace's declared Rust 1.85 baseline. +- **Git** on `PATH`. +- **macOS:** Xcode Command Line Tools (`xcode-select --install`). +- **Linux:** Tauri native dependencies, including WebKitGTK 4.1. See the + [Ubuntu setup commands](docs/install.md#linux-build-dependencies) or the + [Tauri prerequisites](https://v2.tauri.app/start/prerequisites/) for your distribution. -### How it works +If pnpm is not installed, install the pinned version through your Node.js +installation: -```text -React + xterm.js - │ typed Tauri commands and events - ▼ -Tauri 2 desktop bridge - │ versioned local IPC - ▼ -jig daemon - ├── PTY session manager ── Codex / Claude / Gemini / OpenCode - ├── Git and worktree service - └── SQLite metadata storage +```bash +npm install --global pnpm@11.9.0 ``` -The separate daemon owns live PTYs and SQLite. Closing the desktop window does not stop active sessions. Read [ARCHITECTURE.md](ARCHITECTURE.md) for protocol, schema, lifecycle, and safety decisions. +If you already manage pnpm with Corepack, `corepack enable` lets it use the +repository's `packageManager` pin. See the +[pnpm installation guide](https://pnpm.io/installation) for alternatives. -## Supported platforms - -- **Linux:** First-class. AppImage is the initial package format. -- **macOS:** First-class on Apple Silicon and supported modern releases. `.app` and `.dmg` artifacts. -- **Windows:** Out of scope for Beta v0.2. - -## Validate changes - -Run the repository gate before committing: +### Start the desktop application ```bash -pnpm check -pnpm check:versions -cargo fmt --all -- --check -cargo clippy --workspace --all-targets -- -D warnings -cargo test --workspace -pnpm --filter @cli-master/desktop test:e2e +git clone https://github.com/guicybercode/Jig.git +cd Jig +pnpm install --frozen-lockfile +pnpm tauri dev ``` -`pnpm check` type-checks and builds the frontend, then checks every Rust crate. `pnpm check:versions` ensures Cargo, npm, Tauri, and the protocol catalog agree. +The first run compiles the Rust application and daemon, which can take several +minutes. A native **Jig** window should open and connect to the local daemon. +You do not need to start the daemon separately. -Runtime acceptance for sessions, worktree isolation, and daemon recovery lives in `crates/e2e`. Platform-specific PTY tests run in Linux and macOS CI jobs. +`pnpm dev` starts only the Vite frontend at `http://localhost:1420`. A normal +browser does not provide the native desktop bridge or live daemon sessions. +Use `pnpm tauri dev` to run the actual app. -## Repository layout +### Start your first terminal -```text -apps/desktop/ React, TypeScript, Vite, Tauri bridge, Playwright -crates/ Rust domain, storage, Git, PTY, daemon, e2e -crates/fake-agent Interactive coding-agent stand-in for Beta tests -crates/e2e Acceptance tests against production crates -docs/ Install, packaging, and recovery guides -docs/brand/ Jig brand assets -ARCHITECTURE.md Accepted architecture and protocol design -AGENTS.md Crate ownership and IPC rules -protocol/catalog.json Frozen v1 method names -``` +1. Click the sidebar **+** (**Add workspace project**), choose a local Git + repository with **Choose a project folder**, then click **Add Project**. +2. Select that project and click **Add terminal card** in the canvas toolbar. +3. Choose **Shell** to try Jig without an agent account, or choose an agent CLI + you have already installed and authenticated. Check the working directory. +4. Choose **Use project working copy**, or **Create an isolated Git worktree** + for a separate branch and checkout. The latter requires a repository with + at least one commit. +5. Click **Create terminal**. With the daemon connected, the terminal starts + on the canvas. If the card is still a draft, click **Start terminal**. -## Safety principles +Closing the window or removing a canvas card does **not** stop its session. +Use the terminal's session actions and **Stop process** to stop the running +program. If startup fails, check **Diagnostics** and the +[troubleshooting guide](docs/install.md#troubleshooting). -- Commands use an executable plus an argument array, not interpolated shell strings -- Removing a project never removes its repository directory -- Worktrees with uncommitted changes are never silently deleted -- Stopping a process and deleting session metadata are separate actions -- Full environments, tokens, and terminal contents are excluded from logs +### Build installable packages + +From the repository root, on the platform you want to package: + +```bash +pnpm package +``` -See [CONTRIBUTING.md](CONTRIBUTING.md) before opening a change. +This builds and stages `cli-masterd`, builds the desktop bundle, smoke-tests +the bundled daemon, and writes packages plus `SHA256SUMS` to `dist/artifacts/`. +It does not sign, notarize, or publish a release. `pnpm build` builds only the +frontend; it does not produce an installable desktop app. Python 3 is required +by the packaging scripts. See [packaging](docs/PACKAGING.md) for details. + +## Development and architecture + +The React + xterm.js interface talks through a Tauri 2 bridge to a per-user +Unix-socket daemon. The daemon owns PTYs, process lifecycle, Git operations, +and SQLite metadata. Closing the UI leaves the daemon running; restarting +the daemon cannot restore lost PTY handles. + +| Location | Responsibility | +| --- | --- | +| `apps/desktop/` | React interface, typed IPC client, Tauri bridge, frontend tests | +| `crates/` | Rust domain, storage, Git, PTY, daemon, and runtime acceptance tests | +| `crates/core/src/wire/` | Authoritative versioned IPC contract | +| `protocol/catalog.json` | IPC catalog mirror | +| `docs/` | Architecture decisions, installation, packaging, and recovery | + +Start with [CONTRIBUTING.md](CONTRIBUTING.md) for the complete development gate, +[ARCHITECTURE.md](ARCHITECTURE.md) for system boundaries, and +[AGENTS.md](AGENTS.md) for repository rules. + +## Community, security, and license + +Bug reports, documentation fixes, and focused pull requests are welcome. +Use [GitHub Issues](https://github.com/guicybercode/Jig/issues) for ordinary +bugs and feature proposals. Follow [SECURITY.md](SECURITY.md) to report a +vulnerability privately; do not include tokens or private terminal output +in public reports. + +Jig is open source under the [MIT License](LICENSE). Dependencies and agent +CLIs retain their own licenses. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..bb4ccf3 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,99 @@ +# Security policy + +Jig is a local-first desktop application for Linux and macOS. This policy +explains how to report a suspected vulnerability and the security boundaries +to consider before using it. + +## Supported versions + +Jig is beta software. Security maintenance targets the newest published +release, including a release marked as a pre-release, on a best-effort basis. +Older releases do not have a separate security-backport commitment. Check +the [release notes](https://github.com/guicybercode/Jig/releases) for the +current version, known limitations, and any available mitigations. + +Reports affecting `main` are also welcome, but development builds are not +stable releases. There is no guaranteed response time, fix deadline, or +security support SLA. + +## Report a vulnerability privately + +Use [Report a vulnerability](https://github.com/guicybercode/Jig/security/advisories/new) +while signed in to GitHub. This opens the repository's private reporting +channel; do not open a public issue or pull request with vulnerability details. +GitHub describes this workflow in its +[private reporting guide](https://docs.github.com/en/code-security/how-tos/report-and-fix-vulnerabilities/report-privately). + +If the private form is unavailable, open an issue asking only for a private +security contact. Do not include the affected component, exploit, logs, or +other sensitive details in that public request. + +Include, when available: + +- The Jig version or commit, operating system and architecture, and whether + you used a published package or a source build. +- A description of the impact and the trust boundary crossed. +- Minimal reproduction steps using a disposable repository and synthetic + data, plus the expected and observed behavior. +- Sanitized diagnostics or screenshots, relevant dependency versions, and + any mitigation you have verified. + +Never attach API tokens, passwords, private keys, authentication cookies, +full environment dumps, private repository contents, or unreviewed terminal +transcripts. Inspect diagnostic exports and screenshots before sharing them: +automatic redaction cannot recognize every secret. If a credential has +already been exposed, revoke or rotate it with its provider; do not send the +credential as proof. + +Maintainers may ask for additional reproduction details in the private +report. Please coordinate public disclosure there so affected versions, +mitigations, and any fix can be communicated together. Published security +notices are available in +[repository advisories](https://github.com/guicybercode/Jig/security/advisories). + +## Security boundaries + +- **Agent execution is not sandboxed by Jig.** A selected CLI runs with your + local account's filesystem and network access. Separate PTYs and Git + worktrees are coordination boundaries, not security isolation. Only start + executables and projects you trust; any vendor-specific sandbox or + approval mode must be configured in that CLI. +- **Jig is not a vendor proxy.** Agent CLIs manage their own authentication + and network traffic. Report vulnerabilities specific to an agent or its + remote service to that vendor; report unsafe Jig integration behavior here. +- **The daemon is a local control plane.** It owns sessions and communicates + through a per-user Unix socket, not an authenticated remote API. Private + directories use mode `0700` and the socket uses `0600`; Linux additionally + checks the peer UID. macOS relies on filesystem ownership and permissions. + Do not expose or forward the socket to other users or the network. Jig + does not defend against an already-compromised process under the same + operating-system account. +- **Remote browser pages are untrusted.** They must not gain application or + daemon IPC access. Native browser permissions and isolation have + platform-specific limitations; see [known issues](docs/KNOWN_ISSUES.md). + Automated tests are not a substitute for the packaged browser acceptance + checks in the [release checklist](docs/RELEASE_CHECKLIST.md). +- **Recovery must not act on stale process IDs.** Closing the desktop window + does not stop daemon-owned sessions. After a daemon crash, affected session + metadata becomes `unknown`; stored PIDs are not used to reattach or signal + a process. Follow the [recovery guide](docs/backup-and-recovery.md) and + verify process identity before taking manual action. + +Unexpected command execution, cross-user socket access, path-validation +bypasses, unsafe worktree deletion, secret leakage, and remote-page access +to native application privileges are examples of reports in scope. Test +only on systems, repositories, and data you own or have permission to test. + +## Release integrity + +Current builds are unsigned, and macOS notarization is not configured. +Download packages only from this repository's releases or packaging workflow +and follow the [installation and verification guide](docs/install.md). +Compare downloaded files against the accompanying `SHA256SUMS`; checksums +detect corruption or mismatches but do not replace code signing or establish +publisher identity. Do not disable system-wide security protections to run +Jig. + +For implementation details and residual risks, read the +[threat model](docs/THREAT_MODEL.md). This policy is not a certification or a +claim that every release has completed manual security acceptance. diff --git a/apps/desktop/package.json b/apps/desktop/package.json index ee8165b..e9219c4 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,6 +1,7 @@ { "name": "@cli-master/desktop", "private": true, + "license": "MIT", "version": "0.2.0", "type": "module", "scripts": { diff --git a/apps/desktop/src-tauri/Cargo.toml b/apps/desktop/src-tauri/Cargo.toml index 87362bf..382d94a 100644 --- a/apps/desktop/src-tauri/Cargo.toml +++ b/apps/desktop/src-tauri/Cargo.toml @@ -1,6 +1,8 @@ [package] name = "cli-master-desktop" version.workspace = true +license.workspace = true +repository.workspace = true description = "Local control center for CLI coding agents" authors = ["Jig contributors"] edition.workspace = true diff --git a/apps/desktop/src-tauri/tauri.conf.json b/apps/desktop/src-tauri/tauri.conf.json index e26be08..a3a026e 100644 --- a/apps/desktop/src-tauri/tauri.conf.json +++ b/apps/desktop/src-tauri/tauri.conf.json @@ -29,6 +29,11 @@ "active": true, "targets": ["app", "dmg", "appimage"], "category": "DeveloperTool", + "license": "MIT", + "licenseFile": "../../../LICENSE", + "resources": { + "../../../LICENSE": "licenses/Jig-LICENSE.txt" + }, "shortDescription": "Terminals on a canvas for coding agents", "longDescription": "Jig hosts coding-agent CLIs in real terminals with projects and Git worktrees. A local-first desktop app that coordinates Codex, Claude Code, Gemini CLI, OpenCode, and custom executables.", "icon": [ diff --git a/crates/agents/Cargo.toml b/crates/agents/Cargo.toml index 8a1cc56..c612cac 100644 --- a/crates/agents/Cargo.toml +++ b/crates/agents/Cargo.toml @@ -1,6 +1,8 @@ [package] name = "cli-master-agents" version.workspace = true +license.workspace = true +repository.workspace = true edition.workspace = true rust-version.workspace = true diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index cff9c6b..db29ca8 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -1,6 +1,8 @@ [package] name = "cli-master-core" version.workspace = true +license.workspace = true +repository.workspace = true edition.workspace = true rust-version.workspace = true diff --git a/crates/daemon/Cargo.toml b/crates/daemon/Cargo.toml index 13aa856..d2d1dc5 100644 --- a/crates/daemon/Cargo.toml +++ b/crates/daemon/Cargo.toml @@ -1,6 +1,8 @@ [package] name = "cli-master-daemon" version.workspace = true +license.workspace = true +repository.workspace = true edition.workspace = true rust-version.workspace = true diff --git a/crates/e2e/Cargo.toml b/crates/e2e/Cargo.toml index 7b434f7..0a0a585 100644 --- a/crates/e2e/Cargo.toml +++ b/crates/e2e/Cargo.toml @@ -1,6 +1,8 @@ [package] name = "cli-master-e2e" version.workspace = true +license.workspace = true +repository.workspace = true edition.workspace = true rust-version.workspace = true description = "Beta acceptance tests that drive production crates without weakening them" diff --git a/crates/fake-agent/Cargo.toml b/crates/fake-agent/Cargo.toml index 7f3b42f..9083421 100644 --- a/crates/fake-agent/Cargo.toml +++ b/crates/fake-agent/Cargo.toml @@ -1,6 +1,8 @@ [package] name = "cli-master-fake-agent" version.workspace = true +license.workspace = true +repository.workspace = true edition.workspace = true rust-version.workspace = true description = "Deterministic interactive coding-agent stand-in for Beta acceptance tests" diff --git a/crates/file-metadata/Cargo.toml b/crates/file-metadata/Cargo.toml index 93fcc57..0c4ae19 100644 --- a/crates/file-metadata/Cargo.toml +++ b/crates/file-metadata/Cargo.toml @@ -1,6 +1,8 @@ [package] name = "cli-master-file-metadata" version.workspace = true +license.workspace = true +repository.workspace = true edition.workspace = true rust-version.workspace = true diff --git a/crates/git/Cargo.toml b/crates/git/Cargo.toml index d5b544f..dea8c53 100644 --- a/crates/git/Cargo.toml +++ b/crates/git/Cargo.toml @@ -1,6 +1,8 @@ [package] name = "cli-master-git" version.workspace = true +license.workspace = true +repository.workspace = true edition.workspace = true rust-version.workspace = true diff --git a/crates/session/Cargo.toml b/crates/session/Cargo.toml index 3e42391..350d532 100644 --- a/crates/session/Cargo.toml +++ b/crates/session/Cargo.toml @@ -1,6 +1,8 @@ [package] name = "cli-master-session" version.workspace = true +license.workspace = true +repository.workspace = true edition.workspace = true rust-version.workspace = true publish = false diff --git a/crates/storage/Cargo.toml b/crates/storage/Cargo.toml index cce4f15..1316e82 100644 --- a/crates/storage/Cargo.toml +++ b/crates/storage/Cargo.toml @@ -1,6 +1,8 @@ [package] name = "cli-master-storage" version.workspace = true +license.workspace = true +repository.workspace = true edition.workspace = true rust-version.workspace = true diff --git a/docs/PACKAGING.md b/docs/PACKAGING.md index 69e4f4e..81a5424 100644 --- a/docs/PACKAGING.md +++ b/docs/PACKAGING.md @@ -18,6 +18,11 @@ pnpm package # build, smoke the bundle, checksums `pnpm package` writes `dist/artifacts/` plus `SHA256SUMS`. It does not create a GitHub Release. +Every application bundle includes the project's MIT license at +`licenses/Jig-LICENSE.txt` in its resources. The bundle smoke test compares +this file with the repository's `LICENSE`; it fails if the file is missing +or different. Third-party dependencies retain their own licenses. + `cargo clippy --workspace` and `cargo test --workspace` need `apps/desktop/src-tauri/binaries/cli-masterd-` to exist. Quality CI stages a real debug sidecar. A debug compile can also write a stub if the @@ -64,6 +69,13 @@ Retention is 14 days. The workflow has `contents: read` only. It cannot publish a Release and it does not receive signing secrets. +Download artifacts from the exact candidate commit, verify each platform's +`SHA256SUMS`, then combine the installable files and generate a single checksum +manifest for the release. Do not overwrite one platform's manifest with the +other before verifying it. A draft release is a staging area, not evidence of +manual acceptance; follow [RELEASE_CHECKLIST.md](RELEASE_CHECKLIST.md) before +publishing it. + ## Signing and notarization (not in this repository) Stop before any step that needs a secret or an Apple account: diff --git a/docs/RELEASE_CHECKLIST.md b/docs/RELEASE_CHECKLIST.md index beb439b..4cd0a6a 100644 --- a/docs/RELEASE_CHECKLIST.md +++ b/docs/RELEASE_CHECKLIST.md @@ -54,10 +54,14 @@ GUI acceptance below. ## Artifacts +- [ ] `LICENSE` declares MIT and Cargo, npm, and Tauri metadata agree. +- [ ] Bundle smoke tests verified `licenses/Jig-LICENSE.txt` matches `LICENSE`. - [ ] AppImage attached for Linux. - [ ] `.dmg` and/or `.app.zip` attached for macOS. - [ ] `SHA256SUMS` sits next to those files. - [ ] Checksums were regenerated after the last rebuild. +- [ ] The release tag points to the exact commit that produced both platform + artifacts; per-platform checksums were verified before combining them. ## Manual package acceptance @@ -99,6 +103,11 @@ hostile-page boundary during development before repeating it in each package. ## Documentation +- [ ] [SECURITY.md](../SECURITY.md) is current and private vulnerability + reporting is enabled in repository settings. +- [ ] [CONTRIBUTING.md](../CONTRIBUTING.md) and + [distribution.md](distribution.md) match the documented commands and + actual distribution channels. - [ ] [CHANGELOG.md](../CHANGELOG.md) matches what testers will see. - [ ] [install.md](install.md), [first-use.md](first-use.md), [backup-and-recovery.md](backup-and-recovery.md), diff --git a/docs/distribution.md b/docs/distribution.md new file mode 100644 index 0000000..26532a2 --- /dev/null +++ b/docs/distribution.md @@ -0,0 +1,67 @@ +# Jig distribution status + +This page distinguishes upstream release downloads, CI build coverage, and +native package-manager availability. A successful build on one Linux +distribution does not establish support for every distribution or desktop. + +## Upstream packages + +| Platform or channel | Format | Version source | Validation | +| --- | --- | --- | --- | +| Linux x86-64 | AppImage | [Published releases](https://github.com/guicybercode/Jig/releases) | Packaging CI uses Ubuntu 24.04 | +| macOS Apple Silicon | DMG and application ZIP | [Published releases](https://github.com/guicybercode/Jig/releases) | Packaging CI uses macOS 15 | +| Development candidates | The same unsigned formats | [Packaging artifacts](https://github.com/guicybercode/Jig/actions/workflows/packaging.yml) | Check the exact commit and both job results | +| macOS Intel / Linux ARM64 | No official prebuilt package | Not built by the current workflow | Do not infer support from another architecture | +| Windows | None | Outside this Beta's scope | Not tested | + +The source tree targets `0.2.0`. A candidate artifact or draft release is not +a published release. Use the release page for the actual public version and +the [release checklist](RELEASE_CHECKLIST.md) for remaining acceptance work. +All current packages are unsigned; macOS notarization is not configured. + +## Distribution repositories + +The project does not currently publish its own packages to the channels below. +This is a statement about this repository's distribution workflow, not a claim +that nobody has made an independent community package with a similar name. + +| Distribution or package manager | Official Jig package from this repository | +| --- | --- | +| Debian / Ubuntu APT | Not published; use the upstream AppImage | +| Fedora RPM / DNF | Not published | +| openSUSE RPM / Zypper | Not published | +| Arch Linux / AUR | Not published | +| Alpine APK | Not published; musl compatibility is not established | +| Nix / NixOS | Not published | +| Flatpak / Flathub | Not published | +| Snap | Not published | +| Homebrew Cask | Not published; use the upstream DMG or application ZIP | +| MacPorts | Not published | + +See [installation](install.md) for prerequisites and verification. Do not +assume that `apt install jig`, `brew install jig`, or a similarly named +package installs this application. + +## Repology version table + +[Repology](https://github.com/repology/repology-rs) tracks package versions +across repositories. Its distribution table, as used by +[kitty](https://github.com/kovidgoyal/kitty), describes packages actually +indexed for that project; it does not create or publish those packages. + +An indexed Repology identity for **guicybercode/Jig** has not been verified. +The README therefore uses the explicit availability table above instead of +embedding an unverified `jig` badge or copying another application's versions. + +Before enabling a live Repology table: + +1. Publish and maintain a real package in a repository indexed by Repology. +2. Confirm that the resulting project entry links back to + `https://github.com/guicybercode/Jig`, not a different project named Jig. +3. Copy that verified entry's badge from its **Badges** page and link it to + the corresponding **Versions** page. +4. Keep this page's package-manager commands and maintainer links current. + +Packaging contributions are welcome through +[CONTRIBUTING.md](../CONTRIBUTING.md). They need version-pinned sources, +checksums, the MIT license notice, and validation on the target platform. diff --git a/docs/first-use.md b/docs/first-use.md index 4dccc81..4ac492e 100644 --- a/docs/first-use.md +++ b/docs/first-use.md @@ -15,11 +15,12 @@ only in Homebrew (`/opt/homebrew/bin`), the daemon may miss it until that directory is on the desktop process `PATH`. `--preflight` reports the Git it actually found. -## 2. Run preflight +## 2. Optionally run preflight -```bash -cli-masterd --preflight -``` +The desktop locates its bundled daemon automatically. For command-line +diagnostics, use the full daemon path for your installation from +[install.md](install.md#the-daemon-does-not-connect); installing the application +does not put `cli-masterd` on your shell's `PATH`. You want `"ok": true` and `"git": { "available": true }`. Codex, Claude, Gemini, and OpenCode are listed as optional. Missing ones do not fail diff --git a/docs/install.md b/docs/install.md index a9baaa1..4e7aa8c 100644 --- a/docs/install.md +++ b/docs/install.md @@ -1,104 +1,240 @@ -# Install Jig Beta v0.2 +# Install and run Jig -Jig is a local-first desktop app for Linux and macOS. Windows is out -of scope for this Beta. +Jig runs locally on Linux and macOS. Choose a downloadable bundle to use the +app, or a source build to develop it. Windows is outside this Beta's scope. -Installable artifacts come from GitHub Actions on this repository, not from -an app store. Builds are **unsigned**. macOS notarization is not configured. +## Choose a download -## What you need +Use [GitHub Releases](https://github.com/guicybercode/Jig/releases) for published +versions. Download the asset for your operating system and its checksum file. +The source tree currently targets **0.2.0 Beta**, which may not yet be published. -- Git on `PATH`. The daemon refuses to start a useful preflight without it. -- A Linux distribution with WebKitGTK 4.1, or macOS 12 or newer. -- Optional: Codex, Claude Code, Gemini CLI, or OpenCode. The app starts - without them. Sessions that need a missing CLI fail later, with an - actionable error. +| System | Package | +| --- | --- | +| Linux x86_64 | `Jig__amd64.AppImage` | +| macOS 12+ on Apple Silicon | `Jig__aarch64.dmg` or `Jig.app.zip` | -Do not put vendor API tokens into Jig. Each agent CLI keeps its own -login. +The [Packaging workflow](https://github.com/guicybercode/Jig/actions/workflows/packaging.yml) +also produces temporary candidate artifacts for tested commits. Download and +extract the artifact for your platform to find its packages and `SHA256SUMS`. +These are development candidates, not automatically published releases. +See [distribution status](distribution.md) for available channels. -## Linux (AppImage) +Bundles are **unsigned and not notarized**. Checksums help detect a corrupt +or changed download; they do not replace a publisher's code signature. +Obtain both the package and checksum file from the official release or the +same official workflow run. -1. Download the `*.AppImage` and `SHA256SUMS` files from the packaging - workflow artifacts. -2. Verify the checksum: +## Runtime requirements + +- Git installed and available on `PATH`. +- Linux with the native libraries needed by the AppImage, including + WebKitGTK 4.1, or macOS 12 or newer on Apple Silicon. +- Optional agent CLIs installed and authenticated separately. You can use + Jig's **Shell** terminal without an agent account. + +Node.js, pnpm, Rust, and a Jig account are not required to run a bundle. +Jig does not install agent CLIs or proxy their authentication. Only run agents +and custom executables you trust: worktree isolation is not an OS sandbox. + +## Linux: install the AppImage + +These examples use a 0.2.0 candidate. Substitute your downloaded filename +when installing another version. + +1. In the download directory, calculate the checksum: ```bash - sha256sum -c SHA256SUMS + sha256sum Jig_0.2.0_amd64.AppImage ``` -3. Mark the AppImage executable and run it: + Compare the complete hash with the line for that filename in the downloaded + checksum file. If it differs, do not run the file; download it again from + the official source. + +2. Make the file executable and launch it: ```bash - chmod +x "Jig_0.2.0_amd64.AppImage" + chmod +x Jig_0.2.0_amd64.AppImage ./Jig_0.2.0_amd64.AppImage ``` -The AppImage includes `cli-masterd` next to the desktop binary. It does not -vendor your whole desktop stack. If the window fails to open, install the -WebKitGTK 4.1 packages for your distribution. See -[the Tauri Linux prerequisites](https://v2.tauri.app/start/prerequisites/). +3. The Jig window should open and connect to its bundled local daemon. -Debian packages are not a Beta v0.2 distribution format. AppImage is. +The AppImage includes `cli-masterd`. It does not bundle every Linux desktop +library. CI builds on Ubuntu 24.04; other distributions may need native +runtime packages or a source build. No `.deb` or `.rpm` is produced. -## macOS (application bundle and DMG) +## macOS: install the app -Apple Silicon is the CI target. Universal binaries are not produced. - -1. Download the `.dmg` or `Jig.app.zip` plus `SHA256SUMS`. -2. Verify the checksum: +1. Calculate the checksum of the file you downloaded, substituting its actual + filename if it is not a 0.2.0 candidate: ```bash - shasum -a 256 -c SHA256SUMS + shasum -a 256 Jig_0.2.0_aarch64.dmg + # If you downloaded the application ZIP instead: + shasum -a 256 Jig.app.zip ``` -3. Open the DMG and drag Jig to Applications, or unzip the `.app`. -4. Launch it from Applications. + Compare the complete hash with the matching filename in the checksum file. + If it differs, do not open the file. + +2. Open the DMG and drag **Jig** to **Applications**, or extract `Jig.app.zip` + and move `Jig.app` to Applications. +3. Launch Jig. If macOS blocks the unsigned application, review the warning + in **System Settings → Privacy & Security**. Only use **Open Anyway** if + you trust the official download and have verified its checksum. Do not + disable Gatekeeper globally. See Apple's guide to + [safely opening apps](https://support.apple.com/en-us/102445). +4. The Jig window should open and connect to its bundled daemon. -The first launch of an unsigned app is blocked by Gatekeeper. That is -expected. Open System Settings, Privacy & Security, and allow the app after -you have verified the checksum yourself. Notarization would remove this -step. It is not wired up, and this repository does not contain certificates. +The distributed macOS build targets Apple Silicon, not Intel or Universal. +The daemon lives inside `Jig.app/Contents/MacOS/cli-masterd`; it does not +need a separate installation. -`cli-masterd` lives in `Jig.app/Contents/MacOS/cli-masterd`. +## Run from source -## Confirm the daemon binary +Use **Node.js 24**, **pnpm 11.9.0**, **stable Rust with Cargo**, and **Git**, +matching CI. The workspace declares a Rust 1.85 baseline, but the current +dependency lockfile is validated with stable Rust, not a minimum-version job. -From a terminal, after install: +Install Node.js and Rust using their official +[Node.js](https://nodejs.org/en/download) and +[Rust](https://www.rust-lang.org/tools/install) instructions. With Node.js +available, install the pinned package manager if needed: ```bash -# Linux AppImage, after --appimage-extract, or from a source build: -cli-masterd --version -cli-masterd --preflight +npm install --global pnpm@11.9.0 ``` -`--version` must print `cli-masterd 0.2.0 (protocol 1)`. `--preflight` must -report Git as available. Missing Codex or Claude is fine. +An existing Corepack installation can use `corepack enable` and the repository's +`packageManager` pin instead. Avoid changing the lockfile to work around an +incompatible package-manager version. -## Build from source +### macOS build dependencies -Development setup is in the [README](../README.md). To produce the same -unsigned artifacts CI uploads: +Install the Xcode Command Line Tools and complete any installation prompt: ```bash +xcode-select --install +``` + +### Linux build dependencies + +On Ubuntu 24.04, install the native packages used by packaging CI, plus Git +and Python 3 for the repository's scripts: + +```bash +sudo apt-get update +sudo apt-get install --no-install-recommends \ + build-essential curl file git libayatana-appindicator3-dev \ + libgtk-3-dev librsvg2-dev libssl-dev libwebkit2gtk-4.1-dev \ + libxdo-dev patchelf pkg-config python3 wget +``` + +For other distributions, use the package names in the +[official Tauri prerequisites](https://v2.tauri.app/start/prerequisites/#linux). +The macOS tools requirement is also documented in +[Tauri's macOS prerequisites](https://v2.tauri.app/start/prerequisites/#macos). + +### Clone and start Jig + +```bash +git clone https://github.com/guicybercode/Jig.git +cd Jig pnpm install --frozen-lockfile +pnpm tauri dev +``` + +Keep that terminal open while developing. The first compilation takes longer +than subsequent starts. A native Jig window should open; the development +command builds the daemon automatically before starting the frontend. + +`pnpm dev` serves only the frontend at `http://localhost:1420`; live terminals +and native dialogs require Tauri. See +[your first terminal](../README.md#start-your-first-terminal) for adding a +project and starting a shell. + +### Build a distributable bundle + +From a prepared source checkout on Linux or macOS: + +```bash pnpm package ``` -`pnpm package` stages `cli-masterd`, runs `tauri build`, smoke-tests the -bundle, and writes `dist/artifacts/SHA256SUMS`. It never signs, notarizes, -or creates a GitHub Release. +The command stages `cli-masterd`, runs the Tauri build, smoke-tests the bundled +daemon, and writes packages and `SHA256SUMS` to `dist/artifacts/`. It packages +for the host platform and does not sign, notarize, or publish a release. +Python 3 is required by the packaging scripts. `pnpm build` alone only builds +the frontend. + +## Troubleshooting + +### pnpm is missing or reports an incompatible Node version + +Check `node --version` and `pnpm --version`. Use Node.js 24 and pnpm 11.9.0, +then rerun `pnpm install --frozen-lockfile` from the repository root. Do not +delete or regenerate `pnpm-lock.yaml` to bypass a version mismatch. + +### The browser opens, but native operations do not work + +You probably started `pnpm dev`. Run `pnpm tauri dev` and use its native window +for sessions, folder dialogs, and daemon operations. + +### Linux cannot find WebKitGTK or another shared library + +Install your distribution's Tauri native dependencies. Source builds need the +development packages listed above. A package built on a newer distribution +may not run on older system libraries; build from source on the target host +when necessary. + +### An agent is unavailable, or the daemon cannot find Git + +Check that Git and the agent executable run in your normal terminal and are +on the `PATH` available to Jig. Desktop-launcher environments can differ from +your interactive shell. For a custom executable, use its absolute path in the +terminal configuration. Open **Diagnostics** to inspect detection failures. +Never paste API keys or complete environment dumps into public issues. + +### The daemon does not connect + +Open **Diagnostics** first. To check a source-built daemon from the repository +root without starting a session: + +```bash +cargo run -p cli-master-daemon --locked -- --version +cargo run -p cli-master-daemon --locked -- --preflight +``` + +For a standard macOS installation: + +```bash +/Applications/Jig.app/Contents/MacOS/cli-masterd --version +/Applications/Jig.app/Contents/MacOS/cli-masterd --preflight +``` + +A 0.2.0 build prints `cli-masterd 0.2.0 (protocol 1)`. Preflight checks local +directories, Git, and optional agent CLIs. Missing optional agents do not mean +Jig itself failed to install. The sidecar is not automatically added to `PATH`. +See [daemon discovery](desktop/daemon-sidecar.md) for binary locations and the +explicit `CLI_MASTERD` override. + +### A terminal remains running after closing the window + +This is intentional. Reopen Jig and use the session's **Stop process** action +to stop it. Removing a canvas card also leaves the session running. If the +daemon crashes, lost terminal handles cannot be reattached and affected rows +become `unknown`. Do not try to recover by killing stored PIDs. See the +[known issues](KNOWN_ISSUES.md). -## Signing status +## Signing and support -| Step | Status | -|---|---| -| Application version `0.2.0` | Locked across Cargo, npm, Tauri, and the protocol catalog | -| Linux AppImage | Built unsigned | -| macOS `.app` / `.dmg` | Built unsigned, `signingIdentity` is `null` | -| Hardened Runtime | Off until a Developer ID exists | -| Notarization / stapling | Not configured. No Apple API key is stored in CI | -| GitHub Release publish | Not automated. Upload artifacts by hand after review | +The configuration enables Hardened Runtime, but no Developer ID signing +identity, notarization, or stapling is configured. Treat distributed macOS +bundles as unsigned. No Apple credentials are stored in the repository. -Do not add certificates, API keys, or `TAURI_*` signing secrets to this -repository to "finish" the Beta. +Report ordinary installation bugs through +[GitHub Issues](https://github.com/guicybercode/Jig/issues), including your +version, operating system, architecture, and sanitized error. Follow +[SECURITY.md](../SECURITY.md) for security reports. diff --git a/docs/releases/v0.2.0.md b/docs/releases/v0.2.0.md new file mode 100644 index 0000000..291b631 --- /dev/null +++ b/docs/releases/v0.2.0.md @@ -0,0 +1,84 @@ +# Jig v0.2.0 Beta + +Jig brings coding-agent terminals onto a persistent canvas, with local projects, +Git worktrees, and a separate session daemon for Linux and macOS. + +**Release candidate:** this document prepares the `v0.2.0` pre-release. Do not +interpret a draft release or green CI as completed manual package acceptance. +Publication requires the evidence in [RELEASE_CHECKLIST.md](../RELEASE_CHECKLIST.md). + +## Highlights + +- Persistent canvas with movable, resizable terminal cards, connections, + notes, browser cards, map controls, and terminal presets. +- Native repository selection, agent discovery, real PTY sessions, diagnostics, + bounded replay, daemon reconnect, and two-step worktree removal. +- Local prompts/context library, explicit rule and skill previews, and a + composer that targets only the selected live terminal. +- Revision-checked file IPC and persisted organization metadata contracts. + These backend capabilities do not imply a completed file editor or mounted + organization controls on the canvas. +- Monotonic process snapshots that reject older concurrent observations. +- MIT licensing in the source tree and packaged application resources, + private vulnerability reporting, and updated setup and contribution guides. + +## Downloads and verification + +| Platform | Artifact | +| --- | --- | +| Linux x86-64 | `Jig_0.2.0_amd64.AppImage` | +| macOS Apple Silicon | `Jig_0.2.0_aarch64.dmg` or `Jig.app.zip` | +| Both platforms | `SHA256SUMS` | + +Download a package and `SHA256SUMS` from the same release. Calculate the hash +of the file you downloaded and compare it with that file's line in the +manifest: + +```bash +# Linux +sha256sum Jig_0.2.0_amd64.AppImage + +# macOS +shasum -a 256 Jig_0.2.0_aarch64.dmg +``` + +After verification, Linux users can mark the AppImage executable and launch +it. macOS users can open the DMG and copy Jig to Applications. See +[install.md](../install.md) for complete instructions and prerequisites. + +## Requirements and limits + +- Git must be available on `PATH`. Agent CLIs are optional until selected; + each CLI manages its own login and network access. +- Linux builds require a compatible WebKitGTK 4.1 environment. Packaging CI + uses Ubuntu 24.04; this is not certification for every Linux distribution. +- macOS packages target Apple Silicon. No Intel, universal, Windows, or + Linux ARM64 binaries are produced by the current workflow. +- Packages are unsigned and macOS notarization is not configured. Verify + checksums and follow the OS's per-application security controls; do not + disable Gatekeeper system-wide. +- Closing the desktop does not stop active daemon-owned sessions. After a + daemon crash, lost PTYs cannot be reattached and persisted sessions recover + as `unknown` without signaling stale PIDs. +- Agent execution is not sandboxed by Jig. A worktree isolates Git work, not + filesystem or network privileges. +- Native browser permissions, isolation, focus and packaged PTY behavior need + manual validation on both platforms. Automated frontend and daemon tests do + not replace those checks. + +Read [known issues](../KNOWN_ISSUES.md), [security policy](../../SECURITY.md), +and [distribution status](../distribution.md) before testing this Beta. + +## Maintainer publication record + +Keep the GitHub Release in draft until this record is complete. Record the +candidate commit and CI/Packaging run URLs in the release body; attach only +artifacts built from that exact commit and verify their original checksums +before combining manifests. + +- [ ] Both platform quality jobs passed for the candidate commit. +- [ ] Both packaging jobs passed, including the bundled MIT license check. +- [ ] Downloaded package hashes match the workflow manifests. +- [ ] Linux packaged GUI, PTY and hostile-browser acceptance is recorded. +- [ ] macOS packaged GUI, PTY and hostile-browser acceptance is recorded. +- [ ] A maintainer reviewed the evidence and approved publication. diff --git a/package.json b/package.json index ab193dc..9631d12 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,11 @@ "name": "cli-master", "version": "0.2.0", "private": true, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/guicybercode/Jig.git" + }, "packageManager": "pnpm@11.9.0", "scripts": { "build": "pnpm --filter @cli-master/desktop build", @@ -19,6 +24,7 @@ "lint": "pnpm --filter @cli-master/desktop lint", "tauri": "pnpm --filter @cli-master/desktop tauri", "tauri:build": "bash scripts/stage-sidecar.sh && pnpm tauri build", + "package": "bash scripts/package.sh", "test": "pnpm test:frontend && cargo test --workspace --locked" } } diff --git a/scripts/smoke-bundle.sh b/scripts/smoke-bundle.sh index f2b336a..92a8a30 100755 --- a/scripts/smoke-bundle.sh +++ b/scripts/smoke-bundle.sh @@ -17,6 +17,7 @@ find_first() { } daemon="" +license="" work="$(mktemp -d "${TMPDIR:-/tmp}/cli-master-smoke.XXXXXX")" cleanup() { rm -rf "$work" @@ -38,6 +39,7 @@ case "$(uname -s)" in "$appimage" --appimage-extract >/dev/null ) daemon="$(find "$work/squashfs-root" -type f -name 'cli-masterd' -print | sort | head -n 1)" + license="$(find "$work/squashfs-root" -type f -name 'Jig-LICENSE.txt' -print | sort | head -n 1)" desktop="$(find "$work/squashfs-root" -type f \( -name 'cli-master-desktop' -o -name 'CLI Master' \) -print | sort | head -n 1)" if [[ -z "$desktop" ]]; then echo "desktop binary missing from AppImage" >&2 @@ -54,6 +56,7 @@ case "$(uname -s)" in fi echo "smoke app: $app" daemon="$app/Contents/MacOS/cli-masterd" + license="$app/Contents/Resources/licenses/Jig-LICENSE.txt" desktop="$(find "$app/Contents/MacOS" -maxdepth 1 -type f ! -name 'cli-masterd' -print | sort | head -n 1)" if [[ -z "$desktop" ]]; then echo "desktop binary missing from $app" >&2 @@ -72,6 +75,12 @@ case "$(uname -s)" in ;; esac +if [[ -z "$license" || ! -f "$license" ]] || ! cmp -s "$root/LICENSE" "$license"; then + echo "bundled Jig license is missing or differs from LICENSE" >&2 + exit 1 +fi +echo "bundled MIT license verified" + if [[ -z "$daemon" || ! -f "$daemon" ]]; then echo "cli-masterd missing from bundle" >&2 exit 1