Skip to content

feat(v1.1/W2): TanStack Query foundation + typed API client + Sanctum auth#6

Merged
lopadova merged 3 commits into
mainfrom
feature/v1.1/W2-foundation-api-client
May 18, 2026
Merged

feat(v1.1/W2): TanStack Query foundation + typed API client + Sanctum auth#6
lopadova merged 3 commits into
mainfrom
feature/v1.1/W2-foundation-api-client

Conversation

@lopadova
Copy link
Copy Markdown
Contributor

Summary

Wave W2 of the v1.1 cycle — the data-layer foundation that backs every read + mutation in v1.1. After this PR merges the SPA stays fully functional on fixture data; W3 swaps pages over to the live hooks page-by-page so the fixture-vs-real-data delta is reviewable in isolation.

What landed

Typed API surface mirroring OpenAPI 3.1 v1.5

  • resources/js/lib/api/types.ts — hand-written types for all 19 OpenAPI schemas (HostUser / HostTenant / HostApiKey / McpServer / Tool / AuditRow / AuditDetail / BreakerState / Resource / Prompt / AuditEvent / ConfirmTokenMint / ApiErrorPayload / ValidationErrorPayload + filters + envelopes). 1:1 with the wire.
  • resources/js/lib/api/errors.ts — typed error hierarchy: ApiError base + NetworkError / AuthExpiredError / FeatureDisabledError / ConfirmTokenError / ValidationError. TanStack Query's onError distinguishes by instanceof.
  • resources/js/lib/api/client.ts — singleton axios instance with:
    • baseURL resolved from import.meta.env.VITE_API_BASEwindow.__MCP_PACK_ADMIN__.api_base/api/admin/mcp-pack default.
    • withCredentials: true (Sanctum cookie auth).
    • Request interceptor: read XSRF-TOKEN cookie + echo as X-XSRF-TOKEN header on every non-GET (URL-decoded).
    • Response interceptor: 401 → AuthExpiredError + global auth:expired CustomEvent; 403 feature_disabledFeatureDisabledError; 422 confirmation codes → ConfirmTokenError; 422 with Laravel validation shape → ValidationError; no-response → NetworkError.
  • resources/js/lib/api/endpoints.ts — 22 typed endpoint helpers, every dynamic path segment via encodeURIComponent. invokeTool / replayAudit / resetBreaker implement the two-call confirm-token protocol — 202 throws ConfirmTokenError carrying the minted token.

TanStack Query hooks

  • resources/js/lib/queries/queryClient.ts — admin-tuned defaults (staleTime: 30s, no window-focus refetch, retry policy that short-circuits on auth / feature-disabled).
  • resources/js/lib/queries/keys.ts — centralised query-key factory.
  • resources/js/lib/queries/hooks.ts13 read hooks: useMe, useTenants, useApiKeys, useServers, useServer, useServerTools, useTools, useResources, useResource, usePrompts, usePrompt, useAudit, useAuditDetail, useBreakers.
  • resources/js/lib/mutations/hooks.ts10 mutation hooks: useUpdatePreferences, useCreateApiKey, useRevokeApiKey (optimistic), useCreateServer, useUpdateServer, useDeleteServer, useHandshake, useInvokeTool, useReplayAudit, useResetBreaker.

Shell wiring

  • resources/js/main.tsx<QueryClientProvider> wraps <App />; <ReactQueryDevtools /> gated on import.meta.env.DEV.
  • resources/js/App.tsx — listens for the auth:expired CustomEvent and surfaces a toast with data-testid="auth-expired-toast". NO read-path swap — every page still renders fixture data; W3 handles the swap.
  • resources/js/lib/ui.tsx — toast root now passes through data-testid (R11).
  • vite.config.tsaxios + @tanstack/react-query + @tanstack/react-query-devtools added to optimizeDeps.include.

Tests (Vitest 7 → 64, +57)

  • tests/js/lib/api/client.test.ts — 11 specs covering XSRF echo + every error-mapping branch.
  • tests/js/lib/api/endpoints.test.ts — 24 specs covering one happy-path per endpoint + confirm-token round-trips.
  • tests/js/lib/queries/hooks.test.tsx — 9 specs exercising loading/success/cache.
  • tests/js/lib/mutations/hooks.test.tsx — 9 specs covering create / update / handshake + the destructive flow.
  • tests/js/setup.ts — wires MSW v2 setupServer lifecycle.
  • tests/js/lib/queries/wrapper.tsx — shared <QueryClientProvider> test factory.

Dependencies

Package Range Type
@tanstack/react-query ^5 runtime
axios ^1 runtime
@tanstack/react-query-devtools ^5 dev
msw ^2 dev

Bundle size

Before After Delta
main-*.js ~290 KB / ~85 KB gz 346 KB / 99 KB gz +56 KB / +14 KB gz
main-*.css 46 KB / 8.7 KB gz 46 KB / 8.7 KB gz unchanged

Delta is within the projected envelope for TanStack Query + axios.

R-rules honoured

  • R11 — toast root passes through data-testid; new auth-expired-toast testid.
  • R14 — typed errors thrown, never silent success. Every error branch in the interceptor produces an instanceof ApiError.
  • R19 — every dynamic path segment via encodeURIComponent.
  • R21 — two-call confirm-token protocol on invokeTool / replayAudit / resetBreaker. 202 throws ConfirmTokenError carrying the minted token; UI re-calls with confirmToken in the body.
  • R30 — client never sets X-Tenant-Id from JS state; host middleware owns tenant resolution.
  • Standalone-agnostic invariant preserved: zero references to AskMyDocs host code under resources/js/.

Verification

  • npm run typecheck — clean
  • npm test — 64/64 passing
  • npm run build — succeeds (346 KB / 99 KB gz bundle)
  • php vendor/phpunit/phpunit/phpunit — 8/8 passing (no PHP touched)

Test plan

  • CI matrix green (Vitest + Playwright + PHPUnit across PHP/Laravel cells).
  • Manual smoke: npm run dev boots, every fixture-backed page renders identically to v1.0.1.
  • Manual: open DevTools, force a /api/admin/mcp-pack/me 401 response, observe the auth-expired-toast flash.
  • Copilot review pass — wave-foundation PR, expect coverage hits on edge cases (empty cookies, malformed JSON SSE frames, optimistic-update rollback paths).

Next

W3 wires read-paths page-by-page (Dashboard → Servers → Tools → Audit → Resources/Prompts → Breakers → Settings). The fixture imports stay in place until each page is migrated and its E2E spec is updated to assert against live shape.

🤖 Generated with Claude Code

… auth

Wave W2 of the v1.1 cycle establishes the data layer that backs every
read + mutation in v1.1. The SPA stays fully functional on fixture data
after this PR merges; W3 swaps pages page-by-page.

Files added
- resources/js/lib/api/types.ts — 19 hand-written types mirroring OpenAPI 3.1 v1.5
- resources/js/lib/api/errors.ts — typed error hierarchy (ApiError + 5 subclasses)
- resources/js/lib/api/client.ts — axios singleton + Sanctum XSRF interceptor + response error mapper
- resources/js/lib/api/endpoints.ts — 22 typed endpoint helpers
- resources/js/lib/queries/queryClient.ts — admin-tuned shared QueryClient
- resources/js/lib/queries/keys.ts — centralised query-key factory
- resources/js/lib/queries/hooks.ts — 13 read hooks
- resources/js/lib/mutations/hooks.ts — 10 mutation hooks (incl. R21 confirm-token protocol)
- resources/js/env.d.ts — VITE_API_BASE type declaration
- tests/js/lib/api/{client,endpoints}.test.ts — 35 specs
- tests/js/lib/queries/hooks.test.tsx — 9 specs
- tests/js/lib/mutations/hooks.test.tsx — 9 specs
- tests/js/lib/queries/wrapper.tsx — shared <QueryClientProvider> test factory
- tests/js/lib/api/server.ts — shared MSW v2 setupServer

Files modified
- resources/js/main.tsx — QueryClientProvider + ReactQueryDevtools wrapping
- resources/js/App.tsx — auth:expired event listener + dedicated toast (R11)
- resources/js/lib/ui.tsx — toast root now passes through data-testid (R11)
- tests/js/setup.ts — MSW lifecycle wiring
- vite.config.ts — axios + TanStack Query in optimizeDeps.include
- CHANGELOG.md — [Unreleased] → v1.1.0 entry
- package.json + package-lock.json — added @tanstack/react-query, axios, devtools, msw

Test delta
- Vitest 7 → 64 (+57)
- PHPUnit 8 → 8 (unchanged — no PHP touched)
- Build: 346 KB / 99 KB gzipped (~+56 KB raw / ~+14 KB gzipped)

R-rules honoured
- R11 toast testid passthrough + auth-expired-toast testid
- R14 typed errors thrown, never silent success
- R19 every dynamic path segment via encodeURIComponent
- R21 two-call confirm-token protocol on invokeTool / replayAudit / resetBreaker
- R30 client never sets X-Tenant-Id; host middleware owns tenant resolution
- Standalone-agnostic invariant preserved (zero AskMyDocs host refs)
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2ab36cfcaa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +123 to +124
qc.invalidateQueries({ queryKey: keys.servers.detail(id) });
qc.invalidateQueries({ queryKey: keys.servers.tools(id) });
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Invalidate the flat tools cache after handshake

When a server handshake refreshes the server's advertised tools, this only invalidates the detail and per-server tools queries. The global useTools() hook is cached under keys.tools.all() with a 30s staleTime, so if the operator has visited the Tools page and then runs a handshake, returning to the global tools view can continue showing the pre-handshake tool set until the cache ages out. Please invalidate keys.tools.all() here as well.

Useful? React with 👍 / 👎.

CI's `npm ci` rejected the previous lockfile with:

```
npm error Missing: @emnapi/core@1.10.0 from lock file
npm error Missing: @emnapi/runtime@1.10.0 from lock file
```

These are platform-specific optional transitive deps (from `node-fetch`
ecosystem on Linux) that the local Windows `npm install` did not
materialise into `package-lock.json`. Result: `package.json` ↔
`package-lock.json` were out-of-sync from CI's perspective.

Fix: regenerated the lockfile via `rm -rf node_modules package-lock.json
&& npm install` so the platform-specific optional deps are properly
recorded.

Local verification after regen:
- `npm test` — 64/64 green (unchanged)
- `npm run typecheck` — clean
- `npm run build` — 346.13 KB / 98.53 KB gzipped (unchanged)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces the v1.1/W2 data-layer foundation for the admin SPA: a typed axios API client (Sanctum/XSRF + error normalization), typed endpoint helpers, and TanStack Query query/mutation hooks, plus MSW-backed Vitest coverage and minimal shell wiring (QueryClientProvider + auth-expired toast).

Changes:

  • Added typed API surface (types.ts, errors.ts, client.ts, endpoints.ts) including confirm-token protocol handling and auth-expired signaling.
  • Added TanStack Query client defaults, query-key factory, and a set of read/mutation hooks.
  • Added MSW server + Vitest setup + new unit tests for client/endpoints/hooks; wired QueryClientProvider + devtools in the app shell.

Reviewed changes

Copilot reviewed 21 out of 23 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
vite.config.ts Pre-bundles axios/TanStack deps for faster Vite dev cold start.
tests/js/setup.ts Adds Vitest lifecycle hooks to start/reset/stop MSW server; adjusts test runtime API base.
tests/js/lib/queries/wrapper.tsx Test helper to create an isolated QueryClientProvider per spec.
tests/js/lib/queries/hooks.test.tsx Happy/failure-path coverage for read hooks using MSW.
tests/js/lib/mutations/hooks.test.tsx Mutation hook coverage including confirm-token destructive flows.
tests/js/lib/api/server.ts Shared MSW node server instance.
tests/js/lib/api/endpoints.test.ts Endpoint helper coverage including confirm-token round trips and path encoding.
tests/js/lib/api/client.test.ts Axios client interceptor/error-mapping coverage + auth:expired event spec.
resources/js/main.tsx Wraps app in QueryClientProvider and mounts React Query devtools in DEV.
resources/js/lib/ui.tsx Toast DOM now passes through data-testid from toast payload.
resources/js/lib/queries/queryClient.ts Creates the shared QueryClient with admin-tuned defaults and retry policy.
resources/js/lib/queries/keys.ts Centralized query-key factory used by hooks/mutations.
resources/js/lib/queries/hooks.ts Introduces the GET/read hooks backed by endpoint helpers.
resources/js/lib/mutations/hooks.ts Introduces mutation hooks with invalidation + optimistic revoke flow.
resources/js/lib/api/types.ts Adds hand-written OpenAPI-mirroring TypeScript types/envelopes/filters.
resources/js/lib/api/errors.ts Adds typed ApiError hierarchy used by axios client + TanStack Query.
resources/js/lib/api/endpoints.ts Adds typed endpoint functions + confirm-token protocol + SSE subscription helper.
resources/js/lib/api/client.ts Adds axios singleton/factory with Sanctum XSRF echoing + response error normalization.
resources/js/env.d.ts Declares Vite env typings for VITE_API_BASE and mode flags.
resources/js/App.tsx Listens for auth:expired and pushes a dedicated toast.
package.json Adds axios/TanStack Query/MSW deps and updates Node engine constraints.
package-lock.json Locks new dependencies and reflects updated engines metadata.
CHANGELOG.md Documents the W2 foundation, API surface, hooks, and test additions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread resources/js/App.tsx
Comment on lines +165 to 188
const onAuthExpired = () => {
toast.push({
kind: 'err',
title: 'Session expired',
body: 'Please reload the page to sign in again.',
testId: 'auth-expired-toast',
});
};
document.addEventListener('app:toggle-theme', onToggleTheme as any);
document.addEventListener('app:toggle-paused', onTogglePaused as any);
document.addEventListener('app:start-tour', onStartTour as any);
document.addEventListener('app:nav', onNavEvt as any);
document.addEventListener('app:open-audit', onOpenAudit as any);
document.addEventListener('auth:expired', onAuthExpired as any);
return () => {
document.removeEventListener('app:toggle-theme', onToggleTheme as any);
document.removeEventListener('app:toggle-paused', onTogglePaused as any);
document.removeEventListener('app:start-tour', onStartTour as any);
document.removeEventListener('app:nav', onNavEvt as any);
document.removeEventListener('app:open-audit', onOpenAudit as any);
document.removeEventListener('auth:expired', onAuthExpired as any);
};
}, [nav]);
}, [nav, toast]);

Comment thread resources/js/App.tsx Outdated
Comment on lines +162 to +171
// The API client interceptor fires this event on every 401 so the SPA
// can surface a single, deduplicated session-expired toast (W2 wiring;
// actual sign-out / refresh flow lives further upstream).
const onAuthExpired = () => {
toast.push({
kind: 'err',
title: 'Session expired',
body: 'Please reload the page to sign in again.',
testId: 'auth-expired-toast',
});
Comment thread resources/js/lib/queries/queryClient.ts Outdated
Comment on lines +8 to +9
// Tests build their own client via `queries/testWrapper.tsx` with retries
// disabled and `gcTime: 0` so cache state doesn't leak between specs.
Comment thread resources/js/lib/api/endpoints.ts Outdated
HostApiKey,
HostApiKeyCreateEnvelope,
HostTenant,
HostUser,
Comment on lines +285 to +299
/**
* Subscribe to the audit-invocation event stream. Returns a cleanup function
* that closes the underlying `EventSource`. Errors are surfaced via the
* `onError` callback; the EventSource auto-reconnects per spec until closed.
*/
export function subscribeEvents(
onMessage: (event: AuditEvent) => void,
onError?: (err: Event) => void,
): () => void {
if (typeof EventSource === 'undefined') {
// jsdom + node — no-op subscription useful for tests.
return () => undefined;
}

// SSE doesn't carry the XSRF cookie reliably through cross-origin EventSource;
Comment on lines +21 to +26
beforeEach(() => {
// Reset the singleton client between tests so interceptor mutations don't
// leak across files. Re-create against the canonical test base URL.
setApiClient(createApiClient(BASE));
document.cookie = '';
});
…nvalidation + dedupe + DX polish

## Findings & fixes

### P2 — useHandshake() did not invalidate flat tools cache (Codex)

After a successful handshake the per-server tools cache was
invalidated but `keys.tools.all()` (the flat `useTools()` cache)
was not. Operators visiting the Tools page after a handshake would
see pre-handshake data for up to 30s `staleTime`.

**Fix**: `useHandshake.onSuccess` now also invalidates
`keys.tools.all()`.

### P2 — useEffect re-registered listeners on every render (Copilot)

The effect depended on the whole `toast` object, which the provider
returns fresh on every render. Result: every parent re-render
re-registered all 6 document listeners (including `auth:expired`),
risking listener-storm + duplicate fires during the cleanup race.

**Fix**: destructure the stable `push` callback inside `Shell()`
and depend on `[nav, push]` only.

### P2 — auth:expired toast was not actually deduplicated (Copilot)

The comment claimed dedupe but every 401 pushed a fresh toast. A
stale Sanctum cookie can fire dozens of 401s as TanStack Query
retries queued requests in parallel.

**Fix**: module-scoped `authExpiredToastShown` flag. First 401
shows the toast, subsequent ones are silently swallowed until the
user reloads.

### P2 — queryClient.ts docblock pointed at a non-existent file (Copilot)

Comment referenced `queries/testWrapper.tsx`; the actual test
wrapper is at `tests/js/lib/queries/wrapper.tsx`.

**Fix**: docblock path corrected.

### P2 — unused HostUser import in endpoints.ts (Copilot)

**Fix**: removed.

### P2 — subscribeEvents() lacked test coverage (Copilot)

The new EventSource wiring (with JSON parsing + fallback for
environments where `EventSource === undefined`) had no test pinning
the no-op contract.

**Fix**: 2 new tests — verify (a) `subscribeEvents()` returns a
function in jsdom (where EventSource is undefined); (b) the
function doesn't throw on invocation. Pin the contract against
future regressions that might throw instead of returning a no-op.

### P2 — document.cookie='' unreliable in jsdom (Copilot)

`document.cookie = ''` is silently ignored by jsdom (it attempts to
set a cookie with empty name + empty value). The previously-set
XSRF-TOKEN cookie persisted into subsequent tests, making the
suite order-dependent.

**Fix**: `document.cookie = 'XSRF-TOKEN=; Max-Age=0; path=/'` — the
explicit expiry actually clears the cookie.

## Test impact

- Vitest: 64 → 66 tests (+2 new for subscribeEvents EventSource-
  missing path).
- Typecheck: clean.
- npm run build: unchanged bundle size (no source code growth on
  the bundle path).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lopadova
Copy link
Copy Markdown
Contributor Author

@copilot review

Copy link
Copy Markdown

Copilot AI commented May 18, 2026

@copilot review

Reviewed. The review findings are already addressed in commit ce78934 (listener deps/dedupe fixes in App, queryClient comment path, unused import cleanup, SSE no-EventSource tests, and cookie cleanup update), and I re-ran targeted + project checks successfully.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/CarbonPHP/carbon/zipball/e890471a3494740f7d9326d72ce6a8c559ffee60
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/FakerPHP/Faker/zipball/e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/e01f4a821471308ba86aa202fed6698b6b695e3b
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/Seldaek/monolog/zipball/b321dd6749f0bf7189444158a3ce785cc16d69b0
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/bobthecow/psysh/zipball/3be75d5b9244936dd4ac62ade2bfb004d13acf0f
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/brick/math/zipball/63422359a44b7f06cae63c3b429b59e8efcc0629
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/a23a2bf4f31d3518f3ecb38660c95715dfead60f
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/doctrine/inflector/zipball/6d6c96277ea252fc1304627204c3d5e6e15faa3b
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/psu5RQ /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/psu5RQ /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/dragonmantank/cron-expression/zipball/d61a8a9604ec1f8c3d150d09db6ce98b32675013
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/psu5RQ /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/filp/whoops/zipball/d2102955e48b9fd9ab24280a7ad12ed552752c4d
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/psu5RQ /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/fruitcake/php-cors/zipball/38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/guzzle/psr7/zipball/7d0ed42f28e42d61352a7a79de682e5e67fec884
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/guzzle/uri-template/zipball/4f4bbd4e7172148801e76e3decc1e559bdee34e1
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/hamcrest/hamcrest-php/zipball/f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/laravel/framework/zipball/a0c6ad03b380287015287d8d5a0fa2459e2332fd
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/laravel/pail/zipball/aa71a01c309e7f66bc2ec4fb1a59291b82eb4abf
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/laravel/pint/zipball/0770e9b7fafd50d4586881d456d6eb41c9247a80
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/laravel/prompts/zipball/6a82ac19a28b916ae0885828795dbd4c59d9a818
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/laravel/serializable-closure/zipball/b566ee0dd251f3c4078bed003a7ce015f5ea6dce
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/laravel/tinker/zipball/4faba77764bd33411735936acdf30446d058c78b
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/mockery/mockery/zipball/1f4efdd7d3beafe9807b08156dfcb176d18f1699
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/nette/schema/zipball/f0ab1a3cda782dbc5da270d28545236aa80c4002
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/nette/utils/zipball/7da6c396d7ebe142bc857c20479d5e70a5e1aac7
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/nunomaduro/collision/zipball/716af8f95a470e9094cfca09ed897b023be191a5
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/nunomaduro/termwind/zipball/712a31b768f5daea284c2169a7d227031001b9a8
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/orchestral/canvas-core/zipball/88d091ff989748e2ca447bca0cd06ab14671ba82
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/orchestral/canvas/zipball/d240410f4cd89b380d7d89b5bbaf60c32f4fb691
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/orchestral/sidekick/zipball/267a71b56cb2fe1a634d69fc99889c671b77ff43
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/orchestral/testbench-core/zipball/8b85d7754a08b4ff88fc65ab86edf81d70fd1e26
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/orchestral/testbench/zipball/997f33e5200c7e8db4756b35a9deb3f5f3086759
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/orchestral/workbench/zipball/e750c7bcae4405e054ff286475502e23274de04b
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/psu5RQ /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/ramsey/collection/zipball/344572933ad0181accbf4ba763e85a0306a8c5e2
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/ramsey/uuid/zipball/8429c78ca35a09f27565311b98101e2826affde0
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/schmittjoh/php-option/zipball/75365b91986c2405cf5e1e012c5595cd487a98be
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/7d05781b13f7dec9043a629a21d086ed74582a15
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/comparator/zipball/c769009dee98f494e0edc3fd4f4087501688f11e
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/complexity/zipball/bad4316aba5303d0221f43f8cee37eb58d384bbb
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/environment/zipball/b121608b28a13f721e76ffbbd386d08eff58f3f6
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/exporter/zipball/016951ae10980765e4e7aee491eb288c64e505b7
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/global-state/zipball/ef1377171613d09edd25b7816f05be8313f9115d
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/97ffee3bcfb5805568d6af7f0f893678fc076d2f
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1effe8e9b8e068e9ae228e542d5d11b5d16db894
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/4bfa827c969c98be1e527abd576533293c634f6a
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/876099a072646c7745f673d7aeab5382c4439691
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/12b54e689b07a25a9b41e57736dfab6ec9ae5406
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/e1367a453f0eda562eedb4f659e13aa900d66c53
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/php-timer/zipball/f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/phpunit/zipball/792c2980442dfce319226b88fa845b8b6de3b333
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/0b01998a7d5b1f122911a66bebcb8d46f0c82d8c
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/type/zipball/e549163b9760b8f71f191651d22acf32d56d6d4d
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/version/zipball/3e6ccf7657d4f0a59200564b08cead899313b53c
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/clock/zipball/674fa3b98e21531dd040e613479f5f6fa8f32111
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/console/zipball/ed0107e43ab452aa77ae99e005b95e56b556e075
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/css-selector/zipball/b75663ed96cf4756e28e3105476f220f92886cc4
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/deprecation-contracts/zipball/50f59d1f3ca46d41ac911f97a78626b6756af35b
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/psu5RQ /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/error-handler/zipball/8dd79d8af777ee6cba2fd4d98da6ffb839f3c0fa
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/ccba7060602b7fed0b03c85bf025257f76d9ef32
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/event-dispatcher/zipball/e4a2e29753c7801f7a8340e066cfa788f3bc8101
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/finder/zipball/e0be088d22278583a82da281886e8c3592fbf149
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/http-foundation/zipball/9381209597ec66c25be154cbf2289076e64d1eab
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/psu5RQ /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/http-kernel/zipball/eb9d68199af3fcfb3fb4d2e227367b68f8c1bb88
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/mailer/zipball/f6ea532250b476bfc1b56699b388a1bdbf168f62
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/mime/zipball/2d550c4758ba4c47519a6667c36553d535705b0c
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/4864388bfbd3001ce88e234fab652acd91fdc57e
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/psu5RQ /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/polyfill-php83/zipball/3600c2cb22399e25bb226e4a135ce91eeb2a6149
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/polyfill-php84/zipball/88486db2c389b290bf87ff1de7ebc1e13e42bb06
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/polyfill-php85/zipball/fcfa4973a9917cef23f2e38774da74a2b7d115ee
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/polyfill-php86/zipball/33d8fc5a705481e21fe3a81212b26f9b1f61749c
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/polyfill-uuid/zipball/26dfec253c4cf3e51b541b52ddf7e42cb0908e94
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/process/zipball/d9593c9efa40499eb078b81144de42cbc28a31f0
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/routing/zipball/287771d8bc86eacb30678dd10eda6c64a859951f
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/service-contracts/zipball/d25d82433a80eba6aa0e6c24b61d7370d99e444a
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/string/zipball/965f7306a43383d02c6aca1e3f3bd2f0ea5dee15
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/translation-contracts/zipball/0ab302977a952b42fd51475c4ebac81f8da0a95d
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/translation/zipball/ada7578c30dd5feaa8259cff3e885069ea81ddde
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/uid/zipball/2676b524340abcfe4d6151ec698463cebafee439
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/var-dumper/zipball/9510c3966f749a1d1ff0059e1eabef6cc621e7fd
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/symfony/yaml/zipball/e2eb64a57763815ccae07ac1c7653d6cc1c326fd
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/thephpleague/commonmark/zipball/59fb075d2101740c337c7216e3f32b36c204218b
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/thephpleague/flysystem-local/zipball/2f669db18a4c20c755c2bb7d3a7b0b2340488079
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/thephpleague/flysystem/zipball/2daaac3b0d4c83ea7ed5d8586e786f5d00f3540e
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/thephpleague/mime-type-detection/zipball/2d6702ff215bf922936ccc1ad31007edc76451b9
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/thephpleague/uri-interfaces/zipball/85d5c77c5d6d3af6c54db4a78246364908f3c928
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/thephpleague/uri/zipball/08cf38e3924d4f56238125547b5720496fac8fd4
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/theseer/tokenizer/zipball/7989e43bf381af0eac72e4f0ca5bcbfa81658be4
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/f0292ccf0ec75843d65027214426b6b163b48b41
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/vlucas/phpdotenv/zipball/955e7815d677a3eaa7075231212f2110983adecc
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/voku/portable-ascii/zipball/8e1051fe39379367aecf014f41744ce7539a856f
    • Triggering command: REDACTED, pid is -1 (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@lopadova lopadova merged commit 3345e43 into main May 18, 2026
10 checks passed
@lopadova lopadova deleted the feature/v1.1/W2-foundation-api-client branch May 18, 2026 03:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants