Skip to content

Latest commit

 

History

90 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Skillsync

Local-first Rust CLI for importing agent skill packages, preserving local edits during upstream updates, and publishing selected packages to Git repositories.

Commands

skillsync init [--library PATH]
skillsync config path
skillsync config edit   # external editor feature; VISUAL, then EDITOR (TTY only)
skillsync subscribe REPOSITORY [--skill NAME]
# Without --skill, a TTY offers a line-oriented single-select picker.
# With neither argument, the TTY asks for the repository first.
skillsync import --from PATH --skill NAME
skillsync update | sync | status | inventory | diff | doctor
skillsync recovery list
skillsync recovery inspect ID
skillsync state inspect --from PATH
skillsync state inspect-plan --plan PLAN [--from BUNDLE]
skillsync state package inspect --from PATH
skillsync state package stage --from PATH --out PATH  # non-activating staged artifact
skillsync state package install --from PATH --yes      # explicit package transfer install
skillsync state baseline export --relationship REL --out PATH  # read-only durable baseline transfer
skillsync state baseline inspect --from PATH  # read-only strict validation
skillsync state baseline install --from PATH --yes # explicit baseline transfer install
skillsync state relationship verify --relationship REL # read-only relationship validation
skillsync state relationship stage --package PATH --baseline PATH --out PLAN # non-activating evidence plan
skillsync state relationship apply --plan PLAN --package PATH --baseline PATH --yes # explicit apply
skillsync state export --out PATH   # deterministic metadata-only bundle
skillsync state stage --from BUNDLE --plan PLAN   # validate and write non-activating evidence plan
skillsync state apply-sets --from BUNDLE --yes # apply only validated portable set definitions
skillsync onboarding discover                 # read-only package/setup discovery report
skillsync onboarding plan --out PATH          # write a reviewable onboarding plan
skillsync onboarding apply --plan PATH --yes  # explicitly apply an onboarding plan
skillsync worker --once
skillsync worker --interval 300
skillsync worker retry                 # release pending publication backoff timers
skillsync worker enable [--interval 300]
skillsync worker disable | status | uninstall
skillsync publish NAME --repo REPOSITORY --yes   # --dry-run previews
skillsync unsubscribe NAME
skillsync unpublish NAME --repo REPOSITORY
skillsync delete NAME --yes
skillsync restore --from /ABSOLUTE/CONFIG/recovery/delete-NAME-STAMP [--skill NAME]
skillsync conflicts list
skillsync conflicts show RELATIONSHIP
skillsync conflicts export RELATIONSHIP --out WORKSPACE  # immutable evidence snapshot
skillsync conflicts inspect-workspace --workspace PATH  # read-only validation/report
skillsync conflicts resolve RELATIONSHIP --local|--incoming
skillsync conflicts resume RELATIONSHIP [--workspace WORKSPACE]
# --workspace applies a strict v2 resolved workspace; v1 remains inspect-only.
# Conflict export refuses non-portable local repository sources before staging or publishing a workspace.
# Explicit side selection, resolve, and resume are supported; semantic/workspace editing remains deferred.
skillsync set create NAME | list | show NAME | add NAME SKILL | remove NAME SKILL
skillsync harness link --root PATH --skill NAME
skillsync harness unlink --root PATH --skill NAME
skillsync harness enable --root PATH --set NAME
skillsync harness disable --root PATH --set NAME
skillsync harness list

With an initialized library, skillsync in a real terminal opens a read-only, library-first browser. It lists root and nested packages and provides a detail view with paths, provenance, relationships, harness health, status/attention, and explicitly unsupported capabilities. Use arrows or j/k to navigate, Enter to open/back, and q or Escape to quit. The TUI snapshots inventory while holding the shared read lock, then releases the lock before waiting for input; it never executes skill files or mutates the library/state. Redirected and --json invocations retain the noninteractive readiness JSON behavior.

Subscribe records a stable source-plus-relative-path relationship key, so same-named skills from different repositories do not overwrite state. import --from PATH --skill NAME explicitly adopts one package from an existing local directory (including a root package or nested package), stages and validates it, preserves modes/resources, and records local provenance without creating a subscription. state export --out PATH writes a deterministic, versioned metadata-only bundle containing portable relationship/provenance hashes, sets, publications, and pending intent; device-local library/baseline/recovery paths and operational files are omitted. Subscription metadata may additionally carry resolved_commit and resolved_tree, full 40-hex Git object IDs resolved from the exact checkout. These fields are optional for legacy state and bundles; present values are strictly validated and migration never contacts remotes or invents identities. state inspect --from PATH is read-only and validates the bundle strictly. State metadata has one explicit sets-only apply path; automatic import, package transfer, remote sync, worker restoration, harness recreation, credential copying, and baseline/recovery rehydration remain deferred. The picker is deliberately not a full TUI: it lists discovered packages and accepts one validated number. Multi-select, unattended onboarding, automatic registry discovery, and full TUI: unsupported remain explicit limitations.

Safety and storage

recovery list inventories durable recovery artifacts and recovery inspect ID validates and reports one artifact read-only. restore --from PATH is an explicit, noninteractive recovery operation. PATH must be one durable deletion recovery directory beneath the configured recovery/ root and contain a strict package/ snapshot; the manifest supplies the skill name unless matching --skill NAME is provided. It stages and validates the complete no-follow snapshot, preserves operational-looking files and Unix modes, and installs only when the canonical destination is absent. Existing differing content, malformed or linked content, path escapes, and source/destination overlap fail without overwrite. An identical validated destination returns already_present. Restore rehydrates canonical package content only: it never recreates subscriptions, publications, harness links, sets, or remote effects; use their explicit commands separately.

state stage requires an initialized receiving target, takes the exclusive state lock for validation/snapshot/plan write, derives only receiving-library paths, and never activates or mutates canonical state/library/remote relationships. It writes a versioned deny-unknown-fields evidence plan; later apply is intentionally unsupported.

onboarding discover is a read-only, deterministic report for the effective library and persisted harness roots. Repeatable --root PATH adds only caller-supplied explicit occurrence roots; each must be an absolute, existing, canonical regular directory with no symlink/reparse or unsafe ancestors. Missing, relative, file, symlink/reparse, and special roots fail closed without creating anything. Explicit roots are deduplicated by canonical identity and never produce adoption proposals. It classifies packages and recorded ownership without adopting, linking, repairing, scanning arbitrary home directories, executing bundled files, or claiming automatic harness discovery. Unmanaged canonical-library packages produce explicit adopt proposals that are review-only, require approval, and are never applied by discovery; persisted harness-root and explicit-root occurrences do not produce adoption proposals. Initialized targets use the shared read lock; uninitialized targets do not create configuration, state, locks, or missing roots.

State loads strictly validate every local adoption record (identity, absolute no-follow source, canonical library destination, hash, and status); tampered records are rejected before status, doctor, or mutation. SKILL.md must begin with exactly one unquoted name: <safe-component> line; prose or duplicate/conflicting names are rejected. Imports stage content and roll back the newly installed package if provenance state cannot be persisted. Skill names and source-relative package paths reject absolute paths, parent traversal, separators where a package key is required, and control characters. Symlinks and Windows reparse points are rejected; regular-file scans use no-follow opens on Unix and handle-bound reparse checks on Windows, and live package/publication replacements are staged through identity-checked native directory moves. Managed snapshots are rechecked before commit or replacement and abort when a concurrent change is detected; import installation uses an anchored no-replace primitive (Linux renameat2, Windows native no-overwrite move) and fails closed where unavailable. External writers are not fully serialized. Bundled files are never executed. SKILLSYNC_TEST_FAIL_STATE_SAVE=1 is a test-only failure-injection hook for exercising rollback; it is not a configuration or recovery bypass.

Package copies exclude operational files such as .env, logs, credential directories, and private keys. Publication updates managed files in skills/<name> without deleting the destination package wholesale, preserving unrelated operational files. Destination changes that cannot be attributed to the recorded publication are rejected. Publication records are written only after a meaningful commit and successful push; a durable pending-publication intent is written before each push so a failed push or post-push state write can be retried without losing the relationship. Mutating commands share a persistent advisory lock in the config directory; the lock is held for a whole operation or worker run, and status probes the lock rather than trusting a stale PID.

Updates compare the durable baseline, live package, and fetched upstream package. conflicts list inventories paused conflicts, conflicts show RELATIONSHIP is inspection-only: it validates and displays an immutable manifest with base/local/incoming hashes and evidence paths. Its bounded source_observation reports only vocabulary: local package observations use recorded_package_missing, recorded_repository_missing, recorded_package_unsafe, recorded_repository_unsafe, recorded_package_manifest_mismatch, or recorded_package_manifest_valid; remote sources use not_checked_remote. It emits no raw paths, URLs, or errors. conflicts inspect-workspace --workspace PATH is also inspection-only: it validates a moved immutable conflict-resolution workspace and emits deterministic structured status without selecting or applying a tree. Explicit side selection, resolve, and resume are supported; semantic/workspace editing remains deferred; no semantic or automatic conflict resolution is performed; inspect-workspace never executes bundled files or mutates state, library, baselines, recovery, or the workspace. Deletion recovery remains separate via restore.

config edit is supported only in builds with the optional external-editor feature and from an interactive terminal. It creates a uniquely named no-follow temporary file inside the config directory, invokes VISUAL before EDITOR as an executable with that temporary path as its sole argument, then validates and publishes the result without replacing a config created concurrently. Existing configs are published only when their identity and bytes remain unchanged; symlink/reparse substitutions and editor-replaced temporary files fail closed. It inherits terminal streams and reports editor failures. Unix publishes through directory handles; Windows publishes through reparse-protected file handles and verifies the directory/file identity before and after publication. It never parses editor command strings or runs through a shell; --json and redirected stdin/stdout fail instead of launching an editor. Set VISUAL or EDITOR to an executable path: nvim is suitable, while VS Code must be invoked through an explicit wait-capable wrapper/command because the launcher passes exactly one temporary-file argument and does not use a shell.

Testing the native binary, then run the TypeScript integration suite with Bun:

cargo build
bun install
bun test
bun x tsc --noEmit

The Bun suite uses isolated temporary Git repositories and configuration roots. It covers nested selection, default-branch checkout, local/upstream merge preservation, conflict recovery, scoped publication, operational-file retention, multiple publication destinations, unsubscribe/unpublish retention, foreground worker locking, JSON failures, and tampered state paths.

Honest limits

The explicit harness integration is deliberately narrow: harness link creates one native directory symlink from a caller-supplied existing harness skill root to one canonical library skill, and edits through that link write back to the canonical package. harness unlink removes only a recorded link whose target still resolves to the expected canonical skill; canonical content is retained. Existing unrelated harness files are preserved and collisions, symlink/reparse roots, and unsafe names are rejected. harness list, status, and doctor report these relationships; inventory performs bounded read-only existence, symlink, and target health checks on recorded links only. It does not scan arbitrary harness roots or mutate links. Skillsync does not currently discover harnesses automatically, filter harness skills, reload running harnesses, curate Hermes autonomous learning, or promise universal harness compatibility; there is no silent copy fallback. Windows uses native directory symlinks and reports privilege/API failures. Windows build, CLI integration, import, replacement, recovery, publication, locking, and launcher paths run in the hosted windows-latest workflow; interactive editor behavior still requires a real terminal session.

The foreground worker is supported for worker --once and worker --interval SECONDS; it owns the same advisory state lock as mutating CLI commands. Explicit worker enable installs the currently running native executable into a per-user stable application directory and registers a per-user sign-in startup definition; it never uses npm/npx cache, PATH, shell commands, admin elevation, or system-wide services. worker disable retains the installed executable, while worker uninstall removes only validated Skillsync-owned registration artifacts. Registration is currently runtime-exercised only on Linux; macOS and Windows providers are compile-checked but unavailable for native runtime verification here. Startup provider failures are reported without success metadata. worker status is read-only. Named local sets are supported for organizing canonical library skills (set create/list/show/add/remove); membership is portable state only. Set publication, set subscription metadata, personal-library sync, and membership-change propagation remain unsupported. The TUI is intentionally read-only: it has no onboarding, mutation actions, worker registration, or semantic conflict resolution, and its capability display is not a claim that those operations are available. Registry integration, Hermes autonomous curation, and automatic harness discovery/filtering/reload remain unsupported. Semantic conflict resolution, source-specific authentication, and cross-device worker coordination remain unsupported. unsubscribe and unpublish remove only the relationship and retain installed/published content. delete NAME --yes is the only canonical-library deletion surface: it fails closed for active subscriptions, publications, harness links, or set membership, stages a complete recoverable package snapshot under recovery/, then removes only that package. Safe no-replace directory quarantine is verified on Linux (renameat2) and Windows (native no-overwrite move); on other Unix platforms deletion fails closed because this runtime has no portable atomic no-replace directory primitive. Set membership is intentionally not auto-removed; remove the skill from every set first. Harness set enablement is an explicit one-time expansion: it records the set name, root, and member identities, creates only native per-skill directory links, and later set membership changes are not propagated. harness disable removes only those recorded links after target validation and retains canonical content. Empty named sets are valid no-op enablements: they persist and reload as healthy relationships, repeated enablement is already_enabled, and disable removes only the relationship without filesystem mutation. Automatic harness discovery/filtering/reload remains unsupported. Repeated or missing deletion is reported as already_absent and never affects unrelated paths.

Private npm launcher plumbing

npm/ contains a private, development-only npm launcher package. Its skillsync bin forwards arguments and standard streams to a bundled platform/architecture native binary, or to the explicit SKILLSYNC_NATIVE_BIN override used by tests and deployments. It never searches PATH or an npx cache, downloads artifacts, installs a worker, or registers startup. Missing artifacts fail clearly.

This is launcher plumbing only, not a published skillsync npm distribution. Package ownership, release publication, and the precompiled native artifact matrix remain unresolved; no native artifacts are bundled in this repository. Durable installation and sign-in startup registration remain unsupported.

About

Share and manage agent skills with your entire team.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages