Skip to main content

Local-first package hub for PSI packages.

Project description

PsiHub

PsiHub

PsiHub is the local-first package hub for PSI packages.

It owns the package protocol: psi.toml, validation, local publish/download, package cards, and local config templates. It does not launch services. psi.toml must be a regular package file rather than a symlink.

Install

python -m pip install psihub

For a reproducible install:

python -m pip install psihub==0.0.2

Package Shape

[package]
psi_version = "0.1"
org = "demo"
name = "echo"
version = "0.1.0"
kind = "tactic"
primary = "tactics.echo"

[schemas.echo_input]
entry = "demo.schemas:EchoInput"

[schemas.echo_output]
entry = "demo.schemas:EchoOutput"

[tactics.echo]
entry = "demo.tactics:EchoTactic"
input = "echo_input"
output = "echo_output"

[services.api]
tactic = "echo"
tactics = ["echo"]
transport = "fastapi"

[requirements.api_keys]
OPENAI_API_KEY = "OpenAI-compatible model access."

[snapshots.latest]
schema = "echo_output"
description = "Latest echo result."

[runs.local]
services = ["api"]
snapshots = ["latest"]

[card]
summary = "Echo tactic package."
tags = ["demo"]
suggested_commands = ["uvicorn demo.app:create_app --reload"]

[docs.readme]
path = "README.md"
title = "README"

[config.defaults]
policy_url = "http://127.0.0.1:8000"

Focused package kinds should declare a matching package.primary: tactic packages point at tactics.*, channel packages at channels.*, service packages at services.*, and app packages at services.* or runs.*.

Local Lifecycle

psihub init . --org demo --name echo --kind tactic
psihub validate .
psihub publish . --local
psihub list
psihub get demo/echo --dest ./downloaded
psihub card demo/echo
psihub agent-card demo/echo
psihub config-template demo/echo

For a step-by-step local package walkthrough, see docs/tutorials/local-package-lifecycle.md.

Local publish validates by default and rejects packages with validation errors. Use psihub publish --local --no-validate only when intentionally indexing an incomplete local package.

Package and agent cards render declared endpoint and tactic example metadata so custom service routes and concrete calls are visible without opening source files. Generated cards, config templates, local hub index records, and local hub JSON metadata responses filter raw secret-shaped metadata keys such as api_key/apiKey/apikey, tokens, accessToken/accesstoken, passwords, cookies, authorization, and credentials while preserving local refs such as api_key_ref, apiKeyRef, and apikeyref.

Validation accepts well-formed external psi://.../schemas/name refs, rejects malformed schema refs, and catches same-package schema refs that point at missing declared schemas. Ref, package, and resource-name segments must be plain path segments without whitespace, percent escapes, path separators, or semicolon params. Doc, example, and asset package-file paths must stay portable and must not use symlinks, because local publish and download copies skip symlinks. Tactic examples should include an input, output, or command; empty examples produce a validation warning so cards stay useful. Packages that need provider credentials should declare public requirements in [requirements.api_keys], mapping conventional environment names such as OPENAI_API_KEY, ANTHROPIC_API_KEY, or TOGETHER_API_KEY to short descriptions. Package manifests describe required names only; raw secret values stay in the user's environment, OS keyring, or local env file managed by psi init. Packages should declare [card] metadata and [docs.readme] when a README.md exists; missing card/readme metadata produces validation warnings so generated human and agent cards stay discoverable. Endpoint metadata must declare one of GET, POST, PUT, PATCH, or DELETE, use a /-prefixed path without empty or dot segments, backslashes, colons, semicolon path params, queries, fragments, URLs, network-path prefixes, or percent escapes, and use known SSSN scopes when a scope is provided. Service resources must declare either an importable entry or a declared tactic, so package cards and config templates do not advertise unbound services. Local .psi/config.toml binding keys are also validated as strict psi://org/package/resources/name refs with known PSI resource sections. Each binding must declare exactly one serializable concrete target: url, store, or path; other keys are kept as metadata. URL targets must be absolute HTTP(S) URLs without URL params, query strings, fragments, or embedded credentials. In-process object bindings are registered with LocalConfigResolver.bind(..., object=...) and are not serialized into .psi/config.toml. Use [refs."psi://...".metadata] for structured binding metadata. Legacy top-level extra keys still work, but the explicit metadata table wins on duplicate keys. Ref, service, and store metadata must not include raw secret-shaped keys such as api_key/apiKey/apikey, tokens, accessToken/accesstoken, passwords, cookies, authorization, or credentials; use local credential refs such as api_key_ref, apiKeyRef, or apikeyref instead. Metadata maps must use string keys; direct Python metadata with non-string keys is rejected before Pydantic can coerce keys into text.

Local hub storage defaults to:

.psihub/
  packages/
  index/

When a local hub is reopened, index records must still point at the deterministic .psihub/packages/org/name/version/psi.toml package location.

Local publish copies package source into the hub while excluding local-only secret/config/cache material such as .env, .env.local, .envrc, .envrc.local, .netrc, .pypirc, .npmrc, .ssh/, .aws/, .azure/, .gcloud/, root-level private key files such as id_ed25519 and id_rsa, .direnv/, .psi/, .psihub/, virtualenvs, build output, and Python caches. Template files such as .env.example, .env.sample, .env.template, .envrc.example, .envrc.sample, and .envrc.template are preserved. Symlinks are skipped rather than followed during publish and download copies.

Generated config templates assign multiple service refs distinct default local ports in manifest order. A service can declare port in its metadata to prefer a local config-template port; PsiHub still only writes passive config and does not launch that service. Tactic refs point at the local port for the service that declares the tactic, falling back to port 8000 when no service declares it. Templates also include passive [services.*] port tables and [stores.*] path tables for humans or future runners to inspect without asking PsiHub to launch anything; store table paths must be non-empty strings without whitespace and must stay portable relative local paths, without absolute paths, traversal, home expansion, percent escapes, URL syntax, or Windows/UNC path syntax. Snapshot resources render as psi://.../snapshots/name refs and bind to the same local store path convention as channels. Config defaults render under [settings]; LocalConfigResolver.settings() and setting(name, default) expose those local values alongside ref bindings, services()/service(name), and stores()/store(name).

Use --hub to point commands at another local hub directory.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

psihub-0.0.2.tar.gz (1.1 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

psihub-0.0.2-py3-none-any.whl (39.8 kB view details)

Uploaded Python 3

File details

Details for the file psihub-0.0.2.tar.gz.

File metadata

  • Download URL: psihub-0.0.2.tar.gz
  • Upload date:
  • Size: 1.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for psihub-0.0.2.tar.gz
Algorithm Hash digest
SHA256 e0df2e63ff328a6584a8f9b532c11b1305414cdfe74ab1ca2ab58faab3d44644
MD5 b41f509f89b2d207423232ee7a722d02
BLAKE2b-256 f041bc4d7c07741a385a221ea1d0d169e8063e3b4d6571b90497cffe3779119f

See more details on using hashes here.

File details

Details for the file psihub-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: psihub-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 39.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for psihub-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7a8ea24540d506550ff91871e8a4b33d414f3c864291a609852e49c2044ce22a
MD5 5c32f08a4e8579e791c4000b9ad1783e
BLAKE2b-256 e78d57bd7435bcbc4b8eb45ee429d194cb606623c7785e50c72301aa3713c06a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page