Download the PHP package hop-top/kit without Composer

On this page you can find all versions of the php package hop-top/kit. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package kit

php

experimental PHP client SDK.

Modules

URI facade

The experimental SDK exposes a thin facade over hop-top/cite so kit callers can use the shared URI contract without depending on kit-specific parsing code.

This facade intentionally delegates to hop-top/cite (^0.2.0); it does not reimplement URI parsing, vanity handling, action routing, or handler identity.

Output formatting

HopTop\Kit\Output ships the table, json and yaml built-in formatters. csv and text are not implemented in PHP — see Conformance status below.

Column ordering

Go, the reference runtime, reads column order off table:"" struct tags in field declaration order. PHP rows are associative arrays, so an explicit ColumnSpec list carries that order instead. Five rules bind every runtime.

1. Default order. With a ColumnSpec list passed to Dispatcher::dispatch() / KitCommand::render() / KitOutput::columns() and no --cols, the list's order and names drive every formatter. Payload key order is the fallback used only when no list is supplied.

The payload's own key order is count, status, name; the spec wins:

2. --cols reorders as well as selects. The user's sequence beats the ColumnSpec order — --cols status,name renders status then name — and the same rule holds on the no-schema fallback path:

--format json follows the identical order, since PHP arrays are insertion-ordered end to end:

3. header === key. The two name the same column: the label, the value matched against --cols, and the key read off the row. The ColumnSpec constructor throws InvalidArgumentException on a mismatch:

Go cannot express the split through a table:"" tag, so no SDK offers one.

4. Zero rows emits nothing — not even a bare header row. Emptiness is decided by row count, never column count, so a ColumnSpec list never resurrects a header for an empty payload.

5. priority is accepted, stored and ignored. The hide-on-overflow behavior it drives is implemented in Go only; the field is kept so specs stay portable until that feature is ported.

Dispatcher collapses --cols and the ColumnSpec list into one ordered list before calling a formatter (Projection::resolveEffectiveCols()), so the $cols argument a formatter receives is already final. Formatter::render() is unchanged: third-party formatters pick up correct ordering with no code change. That collapse is sound only because header === key.

--template

The minimal renderer substitutes {key} per field and additionally supports a {*} placeholder that expands to every resolved column's value, tab-separated, in schema order:

--template and --cols are mutually exclusive, so on this path the ColumnSpec list is the sole ordering signal. {*} is PHP-specific for now: Go exposes .Cols and Python and TS expose cols, all iterable column names, whereas {*} yields pre-joined row values. The two are not the same affordance, and the house spelling for the minimal-renderer tier is still an open decision.

Go-vs-payload capability gaps

Capability Go (reference) php py / ts rs
Column order source table:"" tags, declaration order ColumnSpec list order ColumnSpec list order ColumnSpec list order
priority hide-on-overflow implemented accepted, stored, ignored accepted, stored, ignored accepted, stored, ignored
header != key inexpressible via table:"" InvalidArgumentException rejected at construction panics in ColumnSpec::new
json/yaml key order follows resolved order follows resolved order follows resolved order follows resolved order
--cols reorders yes yes yes yes
Built-in formats table, json, yaml, csv, text (+ human) table, json, yaml all five table, json, yaml
Ordered columns on the template path .Cols {*} cols none

Go's inability to express header != key is the reason rule 3 is universal: no SDK may carry a capability the reference cannot mirror.

Conformance status

PHP satisfies all five ordering rules on both the formatter and template paths, as does Go across all five formats. The cross-runtime fixtures under sdk/tests/cross-lang/ execute the contract against every runtime. Two gaps are open:

The fixtures compare the column order re-parsed from each runtime's own output, never raw bytes — PHP's YAML emits the dash on its own line and Rust's table renderer pads cells, so byte comparison was never viable. Byte-level formatting parity is pinned by each SDK's own unit tests instead.

MCP surface

Serves the Model Context Protocol over a bridged command tree, exposing one MCP tool per runnable leaf. One mount answers both protocol revisions — 2024-11-05 (handshake) and 2026-07-28 (stateless per-request envelope) — choosing per request, because the newer revision has no handshake to negotiate with.

Wire behaviour is pinned by the shared cross-language fixtures in sdk/tests/cross-lang/fixtures/mcp-wire.json, compared as raw bytes.

Hosting: PSR-15

The surface is exported as a PSR-15 RequestHandlerInterface, not a server. Kit does not own your HTTP stack, so binding the handler is your decision; being a plain request-to-response function also means the wire behaviour is testable without opening a socket.

Mount it wherever your stack routes requests. With a PSR-15 middleware pipeline (Slim, Mezzio, Laminas):

Under plain php-fpm, bridge the superglobals with any PSR-7 implementation and emit the result:

Two details matter when choosing a PSR-7 bridge:

Safety

Exposure is gated by Policy::allowed(). The default is deliberately closed: no remote surface may invoke a destructive leaf, and a blocked call comes back as an isError result at HTTP 200 rather than a transport error — the call was understood and declined, not malformed.

Leaves are classified from kit/* annotations: kit/side-effect (destructive, destructive-local, destructive-shared), kit/auth-required, and kit/requires-confirmation.

Confirmation

A kit/requires-confirmation leaf requires an X-Confirm-Token header by default. Supplying a confirmationKey instead opts into the 2026-07-28 MRTR flow: the first call answers resultType: "input_required" with an elicitation form and a signed requestState, and the client retries with the user's decision. The token is bound to the tool, its arguments and the caller, so the surface stays stateless and a token minted for one call cannot be replayed against another.

Clients that do not advertise form elicitation keep the header gate — the spec forbids sending input requests to a client that cannot answer them.

Protocol layer

The surface implements the JSON-RPC framing and era detection directly rather than delegating to mcp/sdk. The published SDK (v0.7.1, the latest release) carries revisions 2024-11-05 through 2025-11-25 only — 2026-07-28, server/discover, resultType and cacheScope exist on its main branch but in no tagged release. Its supporting types also disagree with this surface where the fixtures are explicit: Mcp\Schema\JsonRpc\Error rejects a null id, which the 2024-11-05 era must round-trip verbatim, and ProtocolVersionMiddleware answers an unknown version with its own wording and a 2025-03-26 fallback rather than the -32022 payload the fixtures pin.

Revisit once a release carries the modern era: ProtocolVersion's handshake/modern split is the right vocabulary to adopt, and the middleware already reads the reserved _meta protocol-version key.

Scope

Deprecated upstream features (Roots, Sampling, Logging, HTTP+SSE) are unimplemented, matching the Go reference. Pagination, tasks/* and subscriptions/listen are likewise not served here.

Cross-references

Offline enforcement

The family-wide --offline global disables network access. It is the highest-precedence override: per-command network opt-ins behave as if their opt-out flag had been passed. It only forces opt-outs on — it never un-sets an explicitly passed --no-* flag.

Loopback is exempt. --offline means "do not talk to the network", not "do not talk to myself", so 127.0.0.1, localhost, [::1] and unix sockets stay reachable. Hostnames are remote even when they would resolve to loopback, because performing that resolution is itself network access.

Setting the marker

Go threads this through context.Context; PHP has no ambient context, so the marker is process state. A CLI invocation is exactly one process, which is the scope --offline describes.

Enforcement

The marker alone is advisory — a caller who forgets to consult it still reaches the wire. Enforcement therefore sits beneath the caller, and a blocked request throws OfflineException rather than skipping silently.

For Guzzle, guard the handler stack:

The stack is the right seam because Guzzle's request(), send(), requestAsync() and sendAsync() are siblings — none delegates to another — but all four run the stack. A decorator wrapping only PSR-18's sendRequest() would leave request() and send() unguarded.

For a non-Guzzle PSR-18 client, where sendRequest() is the only seam, wrap the client:

OfflineException implements PSR-18's ClientExceptionInterface, so conforming callers catch it normally.

ApiClient installs the guard on the client it builds when you inject none, so the default path is enforced without opting in. An injected client is left alone — its owner chose its stack — so guard it yourself.

Scope

Enforcement covers HTTP(S) through Guzzle and PSR-18, which is every network client in this port today. It does not cover code that opens a socket directly: fsockopen, stream_socket_client, PDO and other database drivers, or file_get_contents() on an http:// URL. For those --offline stays advisory and the call site must consult NetPolicy::isOffline() itself.

Telemetry\Sink\HttpsSink is deliberately not guarded. Telemetry is logging-class egress: --offline stops traffic the user asked for, it is not a second consent gate on diagnostics — the same way a remote syslog target is not muted by an offline flag. Consent and telemetry mode already govern whether anything is emitted at all. Do not pass it a guarded client; that would suppress diagnostics --offline is not meant to touch.

CLI flag

Not yet wired. This port has no global-flag layer — src/Cli/Cli.php is a stub — so the marker is set programmatically today. Registering --offline as a Symfony Console global belongs with the CLI-layer work, which will call NetPolicy::setOffline() from the resolved flag.

Telemetry

The PHP SDK ships a publish-only telemetry client under the HopTop\Kit\Telemetry namespace. It mirrors the Go ground truth at go/runtime/telemetry/.

Default-denied posture

Telemetry is off by default. The PHP SDK never prompts the user; the canonical consent prompt lives in the Go CLI. Adopters drive the lifecycle with:

The PHP SDK only reads the persisted decision from $XDG_CONFIG_HOME/kit/config.yaml (default ~/.config/kit/config.yaml) at the kit.telemetry.consent partition. A pre-refactor $XDG_CONFIG_HOME/kit/telemetry.yaml (bare telemetry.consent) is honored as a read-only fallback.

What is collected

Mode Fields recorded
off nothing (no envelope created)
anon event, ts, install_id, mode, sdk
full anon fields + attrs (redacted PII / token shapes)

install_id is a SHA-256 hex digest of 32 random bytes stored at $XDG_STATE_HOME/kit/telemetry/installation_id. Rotate via kit telemetry reset or InstallId::rotate().

Disabling

Any of these turns telemetry off:

Signal Effect
DO_NOT_TRACK=1 (or any truthy) Honored before mode resolution
KIT_TELEMETRY_MODE=off Mode resolves to Off, all events drop
KIT_TELEMETRY_CONSENT=denied Reserved override (Go CLI authoritative)
kit telemetry disable Persists state: denied in YAML

If the persisted YAML reports state: denied, Telemetry::record() short- circuits regardless of mode.

Sink selection

The transport is chosen via KIT_TELEMETRY_SINK:

Value Sink
(unset) / jsonl JsonlSink — append JSONL to a per-PID file under XDG_STATE (default; FPM-safe)
none NullSink — drop every envelope (CI / staging)

https is not an accepted value of this variable. The facade never constructs an HTTP client, so KIT_TELEMETRY_SINK=https reports a diagnostic and falls back to JsonlSink. Adopters who need HTTPS construct HttpsSink themselves and call Telemetry::setSink() (see the FPM caveat below). Note this differs from the Python, TypeScript, and Rust SDKs, where https is env-selectable.

Any other explicitly-set value (a typo such as htpps, or an unimplemented transport) is likewise reported and falls back to JsonlSink — an operator's choice is never discarded in silence.

Diagnostics go to a reporter that defaults to a no-op, so the SDK stays quiet on import and never writes to a php-fpm response body. Wire it to your logger to see them:

JsonlSink registers a register_shutdown_function callback so envelopes are flushed even when the caller never calls Telemetry::flush(). The on- disk layout is $XDG_STATE_HOME/kit/telemetry/inbox/php-<pid>.jsonl with LOCK_EX serialization and a 10 MiB size-rotation trigger. A separate Go drain (future kit telemetry daemon) sweeps these files.

HttpsSink posts batched NDJSON to a remote ingestor. It is opt-in.

FPM caveat (HTTPS sink)

HttpsSink::flush() makes synchronous HTTPS calls. Under php-fpm a flush during a request adds the round-trip to that request's wall-clock time. The class deliberately does not auto-register a shutdown flush. In FPM the recommended pattern is:

CLI processes can safely register the shutdown flush themselves:

Client hardening (HTTPS sink)

HttpsSink does not construct its own Guzzle client — the adopter injects one, so the adopter owns its security options. Kit sets only connect_timeout, timeout, and http_errors; every other Guzzle default applies as-is. Two defaults matter:

Kit performs no host allowlisting on the configured $endpoint. If the endpoint comes from untrusted configuration, validate it before constructing the sink. A hardened client:

The same applies to HopTop\Kit\Api\ApiClient, which falls back to a default-constructed GuzzleHttp\Client when no client is injected. Pass a configured client when the baseURL is not a trusted constant.

Redaction

Redactor applies best-effort PII / token-prefix replacement to all attributes in Full mode:

Adopters can supply a custom callback for project-specific patterns:

The custom callback's output is re-run through the default pass as defense in depth.

Bus transport

The PHP SDK is publish-only. It does not consume from any event bus. Envelopes flow PHP → JSONL/HTTPS → Go drain → bus. Adopters who need bus consumption should call the Go runtime.

Cross-references


All versions of kit with dependencies

PHP Build Version
Package Version
Requires php Version ^8.4
guzzlehttp/guzzle Version ^7.9
hop-top/cite Version ^0.2.0
jewei/typeid-php Version ^1.1
laravel/prompts Version ^0.3
symfony/console Version ^7.0
symfony/event-dispatcher Version ^7.0
symfony/yaml Version ^7.0
psr/http-server-handler Version ^1.0
psr/http-message Version ^2.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package hop-top/kit contains the following files

Loading the files please wait ...