Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions .claude/skills/weave-issue/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,30 +76,30 @@ Do not create duplicate issues — check the open issues list above first. No "B

### Step 6 — Set issue type

Get the new issue's node ID and set the type:
Get the new issue's node ID and set the type **in a single Bash call** (variables don't persist across calls):

```sh
# Get the issue node ID
NODE_ID=$(gh api graphql -f query='{ repository(owner: "PackWeave", name: "weave") { issue(number: <NUMBER>) { id } } }' --jq '.data.repository.issue.id')

# Set the type (use the type ID from context above)
NODE_ID=$(gh api graphql -f query='{ repository(owner: "PackWeave", name: "weave") { issue(number: <NUMBER>) { id } } }' --jq '.data.repository.issue.id') && \
gh api graphql -f query='mutation { updateIssue(input: {id: "'$NODE_ID'", issueTypeId: "<TYPE_ID>"}) { issue { number } } }'
```

### Step 7 — Set blocked-by relationships

If blocking issues were identified in Step 4, for each blocker:
If blocking issues were identified in Step 4, for each blocker run **in a single Bash call** (NODE_ID from Step 6 won't persist — re-fetch it, or chain all steps together):

```sh
# Get the blocker's node ID
BLOCKER_ID=$(gh api graphql -f query='{ repository(owner: "PackWeave", name: "weave") { issue(number: <BLOCKER_NUMBER>) { id } } }' --jq '.data.repository.issue.id')

# Set the relationship
gh api graphql -f query='mutation { addBlockedBy(input: {issueId: "'$NODE_ID'", blockingIssueId: "'$BLOCKER_ID'"}) { issue { number } blockingIssue { number } } }'
NODE_ID=$(gh api graphql -f query='{ repository(owner: "PackWeave", name: "weave") { issue(number: <NUMBER>) { id } } }' --jq '.data.repository.issue.id') && \
BLOCKER_ID=$(gh api graphql -f query='{ repository(owner: "PackWeave", name: "weave") { issue(number: <BLOCKER_NUMBER>) { id } } }' --jq '.data.repository.issue.id') && \
gh api graphql -f query='mutation { addBlockedBy(input: {issueId: "'$NODE_ID'", blockingIssueId: "'$BLOCKER_ID'"}) { issue { number } blockingIssue { number } } }' && \
gh issue edit <NUMBER> --add-label "blocked"
```

Also add the `blocked` label if any blockers were set:
Repeat for each additional blocker, or loop:
```sh
for BLOCKER_NUM in <NUM1> <NUM2>; do
BLOCKER_ID=$(gh api graphql -f query='{ repository(owner: "PackWeave", name: "weave") { issue(number: '$BLOCKER_NUM') { id } } }' --jq '.data.repository.issue.id') && \
gh api graphql -f query='mutation { addBlockedBy(input: {issueId: "'$NODE_ID'", blockingIssueId: "'$BLOCKER_ID'"}) { issue { number } blockingIssue { number } } }'
done
gh issue edit <NUMBER> --add-label "blocked"
```

Expand Down
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ src/core/ Business logic — no I/O to CLI config files here
core/store.rs Local pack cache (~/.packweave/packs/)
core/registry.rs Registry trait + GitHubRegistry + CompositeRegistry
core/mcp_registry.rs MCP Registry client (weave search --mcp)
core/checksum.rs SHA-256 pack content integrity verification
core/conflict.rs Tool-level conflict detection
core/install.rs Install orchestration (registry + local)
core/update.rs Update orchestration (version comparison + apply)
Expand Down
72 changes: 72 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1"
tempfile = "3"
thiserror = "2"
sha2 = "0.10"
toml = "0.8"
toml_edit = "0.22"

Expand Down
13 changes: 9 additions & 4 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ weave install @webdev
Resolver ← resolves semver, checks conflicts, builds install plan
Checksum ← verifies SHA-256 content integrity before storing
Store ← writes inline files to ~/.packweave/packs/
Expand Down Expand Up @@ -93,6 +96,7 @@ src/
mod.rs Module re-exports.
config.rs Global weave config (~/.packweave/config.toml).
credentials.rs Token storage, retrieval, and validation.
checksum.rs SHA-256 pack content integrity verification.
conflict.rs Tool-level conflict detection across installed packs.
install.rs Install orchestration (registry + local).
lockfile.rs Lock file: read/write, version pinning.
Expand Down Expand Up @@ -525,14 +529,15 @@ Each version entry contains a `files` map of relative path → file content:
},
"dependencies": {
"other-pack": "^1.0.0"
}
},
"checksum": "sha256:a1b2c3..."
}
```

The store writes each entry directly to `~/.packweave/packs/{name}/{version}/` after
path-validating the key (rejects absolute paths, `..` components, Windows drive prefixes).
Trust is provided by TLS and GitHub as the content host. No tarballs, no release artifacts,
no SHA256 ceremony.
path-validating the key (rejects absolute paths, `..` components, Windows drive prefixes)
and verifying the SHA-256 checksum embedded in the release metadata. No tarballs, no release
artifacts — integrity is verified via content-addressable checksums.

-----

Expand Down
14 changes: 9 additions & 5 deletions docs/REGISTRY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This document is the authoritative specification for the PackWeave registry prot

The pack registry is a GitHub-hosted repository (`PackWeave/registry`) that serves pack metadata and file content. It is separate from MCP server registries (like the official MCP Registry or Smithery) — weave packs are composable bundles of MCP server configuration, system prompts, slash commands, and settings, not individual MCP server listings.

The registry uses a two-tier sparse index so clients never download more than they need. Pack content is embedded directly in `packs/{name}.json` as a flat map of relative path → file content — no tarballs, no release artifacts, no SHA256 ceremony.
The registry uses a two-tier sparse index so clients never download more than they need. Pack content is embedded directly in `packs/{name}.json` as a flat map of relative path → file content — no tarballs, no release artifacts. Integrity is verified via SHA-256 checksums embedded in each release entry.

---

Expand Down Expand Up @@ -89,13 +89,14 @@ Fetched on demand when installing or resolving a specific pack. Contains all ver
"pack.toml": "[pack]\nname = \"filesystem\"\n...",
"prompts/system.md": "# System prompt content...",
"commands/review.md": "# Review command..."
}
},
"checksum": "sha256:a1b2c3..."
}
]
}
```

`files` is a flat map of relative path → file content. The store writes each entry directly to `~/.packweave/packs/{name}/{version}/` — no tarball download, no SHA256 verification step. Trust is provided by TLS and GitHub as the content host.
`files` is a flat map of relative path → file content. The store writes each entry directly to `~/.packweave/packs/{name}/{version}/` after verifying the SHA-256 checksum. No tarball download — integrity is ensured by content-addressable checksums.

The client caches this per-pack after the first fetch for the lifetime of the command.

Expand All @@ -108,10 +109,12 @@ weave install filesystem
├─ GET {base}/packs/filesystem.json
│ ├─ Authorization: Bearer <token> (if authenticated)
│ └─ {versions: [{version, files, dependencies}]}
│ └─ {versions: [{version, files, dependencies, checksum}]}
├─ resolve: pick version satisfying constraints
├─ verify SHA-256 checksum of pack content
├─ write files from release.files to ~/.packweave/packs/filesystem/0.1.0/
│ (path-validated: no .., no absolute paths)
Expand Down Expand Up @@ -400,7 +403,8 @@ WEAVE_REGISTRY_URL=https://your-registry.example.com weave search mypack
},
"files": {
"<relative-path>": "file content string"
}
},
"checksum": "sha256:<hex-digest>"
}
]
}
Expand Down
Loading
Loading