Compare commits

..

No commits in common. "main" and "codex/alpha-product-ux" have entirely different histories.

16 changed files with 14 additions and 196 deletions

View File

@ -25,18 +25,6 @@ The build emits `dist/`. A packed npm artifact can be made locally with:
It validates the requested version against `package.json`, then writes an npm
tarball and `SHA256SUMS` to `release/`.
## Publish a GitHub Release
```bash
./scripts/publish-github-release.sh v0.1.0
```
This runs the same local packaging command, then requires a clean, up-to-date
`main` and an authenticated [`gh`](https://cli.github.com/) CLI. It creates and
pushes the annotated version tag when needed and uploads the npm tarball and
`SHA256SUMS` to GitHub Releases. The requested version must match
`package.json`.
## Contracts relevant to the alpha
- Workspaces have durable UUID identities; paths are addresses, not identity.

2
dist/types.d.ts vendored
View File

@ -50,7 +50,7 @@ export interface CapabilityEntry {
pluginId: string;
status: 'stable' | 'draft' | 'deprecated';
}
export type Permission = 'vault.read' | 'vault.write' | 'vault.watch' | 'files.read' | 'files.write' | 'files.delete' | 'files.openExternal' | 'workbench.open' | 'storage.namespace' | 'storage.migrations' | 'events.publish' | 'events.subscribe' | 'ui.register' | 'commands.register' | 'network.local' | 'network.remote' | 'process.spawn' | 'secrets.read' | 'secrets.write' | 'sync.participate' | 'browser.receiver.manage' | 'notifications.schedule';
export type Permission = 'vault.read' | 'vault.write' | 'vault.watch' | 'files.read' | 'files.write' | 'files.delete' | 'files.openExternal' | 'workbench.open' | 'storage.namespace' | 'storage.migrations' | 'events.publish' | 'events.subscribe' | 'ui.register' | 'commands.register' | 'network.local' | 'network.remote' | 'process.spawn' | 'secrets.read' | 'secrets.write' | 'sync.participate' | 'browser.receiver.manage';
export interface PermissionEntry {
name: Permission;
description: string;

2
dist/types.d.ts.map vendored

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/mirivlad/verstak-sdk/main/schemas/capabilities.json",
"$id": "https://git.mirv.top/verstak/verstak-sdk/schemas/capabilities.json",
"title": "Verstak Capability Registry",
"description": "Known capability names and their descriptions for the Verstak platform",
"type": "object",

View File

@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/mirivlad/verstak-sdk/main/schemas/contributions.json",
"$id": "https://git.mirv.top/verstak/verstak-sdk/schemas/contributions.json",
"title": "Verstak Contribution Points Registry",
"description": "Known contribution points that plugins can register",
"type": "object",

View File

@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/mirivlad/verstak-sdk/main/schemas/events/browser.json",
"$id": "https://git.mirv.top/verstak/verstak-sdk/schemas/events/browser.json",
"title": "Verstak Browser Events",
"description": "Event schemas for browser extension and browser-inbox plugin communication",
"type": "object",

View File

@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/mirivlad/verstak-sdk/main/schemas/events/lifecycle.json",
"$id": "https://git.mirv.top/verstak/verstak-sdk/schemas/events/lifecycle.json",
"title": "Verstak Lifecycle Events",
"description": "Event schemas for plugin and application lifecycle events",
"type": "object",

View File

@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/mirivlad/verstak-sdk/main/schemas/events/vault.json",
"$id": "https://git.mirv.top/verstak/verstak-sdk/schemas/events/vault.json",
"title": "Verstak Vault Events",
"description": "Event schemas for vault and case lifecycle events",
"type": "object",

View File

@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/mirivlad/verstak-sdk/main/schemas/hostname-normalization-v1.json",
"$id": "https://git.mirv.top/verstak/verstak-sdk/schemas/hostname-normalization-v1.json",
"title": "Verstak canonical hostname normalization v1 test vectors",
"description": "Canonical hostnames are lowercase ASCII A-labels without a port or trailing DNS dot. Bare hostnames accept DNS names, IPv4, bracketed IPv6, localhost, and internal single-label names. URL inputs accept only HTTP(S). Invalid or excessively long input normalizes to an empty string.",
"version": 1,

View File

@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/mirivlad/verstak-sdk/main/schemas/manifest.json",
"$id": "https://git.mirv.top/verstak/verstak-sdk/schemas/manifest.json",
"title": "Verstak Plugin Manifest",
"description": "Schema for Verstak plugin.json manifest files",
"type": "object",
@ -126,8 +126,7 @@
"secrets.read",
"secrets.write",
"sync.participate",
"browser.receiver.manage",
"notifications.schedule"
"browser.receiver.manage"
]
},
"minItems": 1

View File

@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/mirivlad/verstak-sdk/main/schemas/permissions.json",
"$id": "https://git.mirv.top/verstak/verstak-sdk/schemas/permissions.json",
"title": "Verstak Permissions Registry",
"description": "Known runtime permissions and their safety levels",
"type": "object",
@ -47,7 +47,6 @@
{ "name": "secrets.read", "description": "Read secrets from the secret store", "dangerous": true },
{ "name": "secrets.write", "description": "Write secrets to the secret store", "dangerous": true },
{ "name": "sync.participate", "description": "Participate in vault sync", "dangerous": true },
{ "name": "browser.receiver.manage", "description": "View and rotate the local browser receiver pairing token", "dangerous": true },
{ "name": "notifications.schedule", "description": "Replace the plugin's scheduled native notifications", "dangerous": false }
{ "name": "browser.receiver.manage", "description": "View and rotate the local browser receiver pairing token", "dangerous": true }
]
}

View File

@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/mirivlad/verstak-sdk/main/schemas/sync.json",
"$id": "https://git.mirv.top/verstak/verstak-sdk/schemas/sync.json",
"title": "Verstak Sync Operations",
"description": "Sync operation schemas for vault synchronization between devices",
"type": "object",

View File

@ -1,74 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
VERSION="${1:-}"
REPOSITORY="mirivlad/verstak-sdk"
RELEASE_SCRIPT="${VERSTAK_RELEASE_SCRIPT:-$ROOT/scripts/release.sh}"
RELEASE_DIR="${VERSTAK_RELEASE_DIR:-$ROOT/release}"
GIT_BIN="${GIT_BIN:-git}"
GH_BIN="${GH_BIN:-gh}"
cd "$ROOT"
if [[ -z "$VERSION" || ! "$VERSION" =~ ^[A-Za-z0-9][A-Za-z0-9._-]*$ ]]; then
echo "usage: $0 <version>" >&2
echo "example: $0 v0.1.0" >&2
exit 2
fi
if ! command -v "$GH_BIN" >/dev/null; then
echo "gh CLI is required to publish a GitHub Release" >&2
exit 1
fi
if [[ "$("$GIT_BIN" branch --show-current)" != "main" ]]; then
echo "GitHub releases must be published from main" >&2
exit 1
fi
if [[ -n "$("$GIT_BIN" status --porcelain)" ]]; then
echo "working tree must be clean before publishing a release" >&2
exit 1
fi
"$GH_BIN" auth status
"$GIT_BIN" fetch origin main --tags
HEAD="$("$GIT_BIN" rev-parse HEAD)"
if [[ "$HEAD" != "$("$GIT_BIN" rev-parse origin/main)" ]]; then
echo "local main must match origin/main before publishing a release" >&2
exit 1
fi
"$RELEASE_SCRIPT" "$VERSION"
shopt -s nullglob
ASSETS=("$RELEASE_DIR"/*.tar.gz "$RELEASE_DIR"/*.tgz)
if [[ -f "$RELEASE_DIR/SHA256SUMS" ]]; then
ASSETS+=("$RELEASE_DIR/SHA256SUMS")
fi
if [[ ${#ASSETS[@]} -eq 0 ]]; then
echo "no release assets found in $RELEASE_DIR" >&2
exit 1
fi
if "$GIT_BIN" rev-parse -q --verify "refs/tags/$VERSION" >/dev/null; then
if [[ "$("$GIT_BIN" rev-parse "${VERSION}^{commit}")" != "$HEAD" ]]; then
echo "existing tag $VERSION does not point at HEAD" >&2
exit 1
fi
else
"$GIT_BIN" tag -a "$VERSION" -m "Release $VERSION"
"$GIT_BIN" push origin "refs/tags/$VERSION"
fi
if "$GH_BIN" release view "$VERSION" --repo "$REPOSITORY" >/dev/null 2>&1; then
"$GH_BIN" release upload "$VERSION" "${ASSETS[@]}" --repo "$REPOSITORY" --clobber
else
"$GH_BIN" release create "$VERSION" "${ASSETS[@]}" \
--repo "$REPOSITORY" \
--title "Verstak Plugin SDK $VERSION" \
--generate-notes \
--latest \
--verify-tag
fi
echo "GitHub release:"
"$GH_BIN" release view "$VERSION" --repo "$REPOSITORY" --json url --jq .url

View File

@ -1,91 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
PUBLISHER="$ROOT/scripts/publish-github-release.sh"
VERSION="v0.0.0-test"
REPOSITORY="mirivlad/verstak-sdk"
ASSET_NAME="verstak-plugin-sdk-0.0.0-test.tgz"
WORK="$(mktemp -d)"
trap 'rm -rf "$WORK"' EXIT
if [[ ! -x "$PUBLISHER" ]]; then
echo "publisher is missing or not executable: $PUBLISHER" >&2
exit 1
fi
mkdir -p "$WORK/bin" "$WORK/release" "$WORK/state"
LOG="$WORK/log"
export LOG
cat > "$WORK/release.sh" <<'SCRIPT'
#!/usr/bin/env bash
set -euo pipefail
printf 'release:%s\n' "$1" >> "$LOG"
printf 'package\n' > "$VERSTAK_RELEASE_DIR/verstak-plugin-sdk-${1#v}.tgz"
printf 'checksum\n' > "$VERSTAK_RELEASE_DIR/SHA256SUMS"
SCRIPT
chmod +x "$WORK/release.sh"
cat > "$WORK/bin/git" <<'SCRIPT'
#!/usr/bin/env bash
set -euo pipefail
if [[ "$PWD" != "${EXPECTED_ROOT:?}" ]]; then
echo "publisher did not enter repository root: $PWD" >&2
exit 1
fi
case "${1:-}" in
status) exit 0 ;;
branch) echo main ;;
fetch) printf 'fetch\n' >> "$LOG" ;;
rev-parse)
if [[ "${2:-}" == "-q" ]]; then
if [[ -f "$TEST_STATE/tag" ]]; then echo test-commit; exit 0; fi
exit 1
fi
echo test-commit
;;
tag) touch "$TEST_STATE/tag"; printf 'tag:%s\n' "${3:-}" >> "$LOG" ;;
push) printf 'push:%s:%s\n' "${2:-}" "${3:-}" >> "$LOG" ;;
*) echo "unexpected git invocation: $*" >&2; exit 1 ;;
esac
SCRIPT
chmod +x "$WORK/bin/git"
cat > "$WORK/bin/gh" <<'SCRIPT'
#!/usr/bin/env bash
set -euo pipefail
case "${1:-}:${2:-}" in
auth:status) printf 'auth\n' >> "$LOG" ;;
release:view)
if [[ -f "$TEST_STATE/release" ]]; then echo https://github.example/release; else exit 1; fi
;;
release:create) touch "$TEST_STATE/release"; printf 'create:%s\n' "$*" >> "$LOG" ;;
release:upload) printf 'upload:%s\n' "$*" >> "$LOG" ;;
*) echo "unexpected gh invocation: $*" >&2; exit 1 ;;
esac
SCRIPT
chmod +x "$WORK/bin/gh"
run_publisher() {
VERSTAK_RELEASE_SCRIPT="$WORK/release.sh" \
VERSTAK_RELEASE_DIR="$WORK/release" \
GIT_BIN="$WORK/bin/git" \
GH_BIN="$WORK/bin/gh" \
EXPECTED_ROOT="$ROOT" \
TEST_STATE="$WORK/state" \
"$PUBLISHER" "$VERSION"
}
run_publisher
grep -Fqx "release:$VERSION" "$LOG"
grep -Fqx "tag:$VERSION" "$LOG"
grep -Fqx "push:origin:refs/tags/$VERSION" "$LOG"
grep -F "release create $VERSION" "$LOG" >/dev/null
grep -F "$ASSET_NAME" "$LOG" >/dev/null
grep -F "SHA256SUMS" "$LOG" >/dev/null
run_publisher
grep -F "release upload $VERSION" "$LOG" >/dev/null
echo "GitHub release publisher test passed"

View File

@ -135,9 +135,7 @@ describe('VerstakPluginAPI contract', () => {
const permissionEnum = ((manifestSchema as any).properties.permissions.items.enum || []) as string[];
expect(permissions).toContainEqual(expect.objectContaining({ name: 'browser.receiver.manage', dangerous: true }));
expect(permissions).toContainEqual(expect.objectContaining({ name: 'notifications.schedule', dangerous: false }));
expect(permissionEnum).toContain('browser.receiver.manage');
expect(permissionEnum).toContain('notifications.schedule');
});
test('file.changed schema documents watcher refresh payload', () => {

View File

@ -89,8 +89,7 @@ export type Permission =
| 'secrets.read'
| 'secrets.write'
| 'sync.participate'
| 'browser.receiver.manage'
| 'notifications.schedule';
| 'browser.receiver.manage';
export interface PermissionEntry {
name: Permission;