@kortix/sdk 0.12.4 → 0.12.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -15
- package/dist/browser/session-sync/session-transcript-cache.d.ts +17 -0
- package/dist/browser/session-sync/session-transcript-cache.d.ts.map +1 -1
- package/dist/browser/session-sync/session-transcript-cache.js +14 -2
- package/dist/browser/session-sync/session-transcript-cache.js.map +1 -1
- package/dist/browser/stores/sync-store.d.ts +86 -2
- package/dist/browser/stores/sync-store.d.ts.map +1 -1
- package/dist/browser/stores/sync-store.js +386 -33
- package/dist/browser/stores/sync-store.js.map +1 -1
- package/dist/core/client/kortix.d.ts +87 -54
- package/dist/core/client/kortix.d.ts.map +1 -1
- package/dist/core/client/kortix.js +67 -21
- package/dist/core/client/kortix.js.map +1 -1
- package/dist/core/http/api-client.d.ts +19 -1
- package/dist/core/http/api-client.d.ts.map +1 -1
- package/dist/core/http/api-client.js +79 -21
- package/dist/core/http/api-client.js.map +1 -1
- package/dist/core/http/auth.d.ts.map +1 -1
- package/dist/core/http/auth.js +6 -4
- package/dist/core/http/auth.js.map +1 -1
- package/dist/core/http/config.d.ts +4 -0
- package/dist/core/http/config.d.ts.map +1 -1
- package/dist/core/http/config.js.map +1 -1
- package/dist/core/rest/platform-client/host-boundary.js +2 -2
- package/dist/core/rest/platform-client/host-boundary.js.map +1 -1
- package/dist/core/rest/projects-client/access.d.ts +1 -1
- package/dist/core/rest/projects-client/agent-config.d.ts +1 -1
- package/dist/core/rest/projects-client/agent-config.d.ts.map +1 -1
- package/dist/core/rest/projects-client/apps.d.ts +216 -0
- package/dist/core/rest/projects-client/apps.d.ts.map +1 -0
- package/dist/core/rest/projects-client/apps.js +105 -0
- package/dist/core/rest/projects-client/apps.js.map +1 -0
- package/dist/core/rest/projects-client/audit.js +1 -1
- package/dist/core/rest/projects-client/audit.js.map +1 -1
- package/dist/core/rest/projects-client/billing.d.ts +7 -0
- package/dist/core/rest/projects-client/billing.d.ts.map +1 -1
- package/dist/core/rest/projects-client/billing.js.map +1 -1
- package/dist/core/rest/projects-client/channels.d.ts +7 -6
- package/dist/core/rest/projects-client/channels.d.ts.map +1 -1
- package/dist/core/rest/projects-client/channels.js +12 -2
- package/dist/core/rest/projects-client/channels.js.map +1 -1
- package/dist/core/rest/projects-client/connectors.d.ts +133 -98
- package/dist/core/rest/projects-client/connectors.d.ts.map +1 -1
- package/dist/core/rest/projects-client/connectors.js +199 -119
- package/dist/core/rest/projects-client/connectors.js.map +1 -1
- package/dist/core/rest/projects-client/files.d.ts.map +1 -1
- package/dist/core/rest/projects-client/files.js +7 -1
- package/dist/core/rest/projects-client/files.js.map +1 -1
- package/dist/core/rest/projects-client/index.d.ts +1 -0
- package/dist/core/rest/projects-client/index.d.ts.map +1 -1
- package/dist/core/rest/projects-client/index.js +1 -0
- package/dist/core/rest/projects-client/index.js.map +1 -1
- package/dist/core/rest/projects-client/policies.js +3 -3
- package/dist/core/rest/projects-client/policies.js.map +1 -1
- package/dist/core/rest/projects-client/projects.d.ts +47 -1
- package/dist/core/rest/projects-client/projects.d.ts.map +1 -1
- package/dist/core/rest/projects-client/projects.js +12 -0
- package/dist/core/rest/projects-client/projects.js.map +1 -1
- package/dist/core/rest/projects-client/secrets.d.ts +55 -3
- package/dist/core/rest/projects-client/secrets.d.ts.map +1 -1
- package/dist/core/rest/projects-client/secrets.js +14 -4
- package/dist/core/rest/projects-client/secrets.js.map +1 -1
- package/dist/core/rest/projects-client/sessions.d.ts +8 -16
- package/dist/core/rest/projects-client/sessions.d.ts.map +1 -1
- package/dist/core/rest/projects-client/sessions.js +1 -1
- package/dist/core/rest/projects-client/sessions.js.map +1 -1
- package/dist/core/session/index.d.ts +1 -0
- package/dist/core/session/index.d.ts.map +1 -1
- package/dist/core/session/index.js +1 -0
- package/dist/core/session/index.js.map +1 -1
- package/dist/core/session/preview-probe.d.ts +76 -0
- package/dist/core/session/preview-probe.d.ts.map +1 -0
- package/dist/core/session/preview-probe.js +97 -0
- package/dist/core/session/preview-probe.js.map +1 -0
- package/dist/core/turns/classify.js +1 -1
- package/dist/core/turns/errors.js +1 -1
- package/dist/core/turns/errors.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/kortix.esm.min.js +19 -19
- package/dist/kortix.global.js +19 -19
- package/dist/platform/auth-core.d.ts +2 -1
- package/dist/platform/auth-core.d.ts.map +1 -1
- package/dist/platform/auth-core.js +10 -1
- package/dist/platform/auth-core.js.map +1 -1
- package/dist/react/index.d.ts +8 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +13 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/invalidate-project.d.ts +76 -0
- package/dist/react/invalidate-project.d.ts.map +1 -0
- package/dist/react/invalidate-project.js +72 -0
- package/dist/react/invalidate-project.js.map +1 -0
- package/dist/react/provider-refresh.d.ts.map +1 -1
- package/dist/react/provider-refresh.js +12 -3
- package/dist/react/provider-refresh.js.map +1 -1
- package/dist/react/query-contracts.d.ts +112 -0
- package/dist/react/query-contracts.d.ts.map +1 -0
- package/dist/react/query-contracts.js +100 -0
- package/dist/react/query-contracts.js.map +1 -0
- package/dist/react/query-keys.d.ts +251 -0
- package/dist/react/query-keys.d.ts.map +1 -0
- package/dist/react/query-keys.js +249 -0
- package/dist/react/query-keys.js.map +1 -0
- package/dist/react/session-title-sync.d.ts.map +1 -1
- package/dist/react/session-title-sync.js +14 -4
- package/dist/react/session-title-sync.js.map +1 -1
- package/dist/react/use-admin-accounts.d.ts +85 -0
- package/dist/react/use-admin-accounts.d.ts.map +1 -1
- package/dist/react/use-admin-accounts.js +100 -0
- package/dist/react/use-admin-accounts.js.map +1 -1
- package/dist/react/use-admin-activity-analytics.d.ts +91 -0
- package/dist/react/use-admin-activity-analytics.d.ts.map +1 -0
- package/dist/react/use-admin-activity-analytics.js +83 -0
- package/dist/react/use-admin-activity-analytics.js.map +1 -0
- package/dist/react/use-admin-projects.d.ts +50 -0
- package/dist/react/use-admin-projects.d.ts.map +1 -0
- package/dist/react/use-admin-projects.js +28 -0
- package/dist/react/use-admin-projects.js.map +1 -0
- package/dist/react/use-canonical-opencode-session.d.ts.map +1 -1
- package/dist/react/use-canonical-opencode-session.js +12 -7
- package/dist/react/use-canonical-opencode-session.js.map +1 -1
- package/dist/react/use-gateway-catalog-sync.d.ts.map +1 -1
- package/dist/react/use-gateway-catalog-sync.js +5 -2
- package/dist/react/use-gateway-catalog-sync.js.map +1 -1
- package/dist/react/use-model-defaults.d.ts.map +1 -1
- package/dist/react/use-model-defaults.js +3 -1
- package/dist/react/use-model-defaults.js.map +1 -1
- package/dist/react/use-model-enablement.d.ts.map +1 -1
- package/dist/react/use-model-enablement.js +6 -2
- package/dist/react/use-model-enablement.js.map +1 -1
- package/dist/react/use-opencode-events/handle-event.d.ts +6 -0
- package/dist/react/use-opencode-events/handle-event.d.ts.map +1 -1
- package/dist/react/use-opencode-events/handle-event.js +3 -3
- package/dist/react/use-opencode-events/handle-event.js.map +1 -1
- package/dist/react/use-opencode-events/helpers.d.ts +27 -1
- package/dist/react/use-opencode-events/helpers.d.ts.map +1 -1
- package/dist/react/use-opencode-events/helpers.js +31 -6
- package/dist/react/use-opencode-events/helpers.js.map +1 -1
- package/dist/react/use-opencode-events/index.d.ts.map +1 -1
- package/dist/react/use-opencode-events/index.js +8 -0
- package/dist/react/use-opencode-events/index.js.map +1 -1
- package/dist/react/use-opencode-sessions/agents.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/agents.js +10 -1
- package/dist/react/use-opencode-sessions/agents.js.map +1 -1
- package/dist/react/use-opencode-sessions/messages.d.ts +19 -3
- package/dist/react/use-opencode-sessions/messages.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/messages.js +28 -55
- package/dist/react/use-opencode-sessions/messages.js.map +1 -1
- package/dist/react/use-opencode-sessions/providers.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/providers.js +9 -2
- package/dist/react/use-opencode-sessions/providers.js.map +1 -1
- package/dist/react/use-project-apps.d.ts +410 -0
- package/dist/react/use-project-apps.d.ts.map +1 -0
- package/dist/react/use-project-apps.js +98 -0
- package/dist/react/use-project-apps.js.map +1 -0
- package/dist/react/use-project-config.d.ts +7 -0
- package/dist/react/use-project-config.d.ts.map +1 -1
- package/dist/react/use-project-config.js +14 -4
- package/dist/react/use-project-config.js.map +1 -1
- package/dist/react/use-project-models.d.ts.map +1 -1
- package/dist/react/use-project-models.js +8 -2
- package/dist/react/use-project-models.js.map +1 -1
- package/dist/react/use-project-name.d.ts +23 -0
- package/dist/react/use-project-name.d.ts.map +1 -0
- package/dist/react/use-project-name.js +44 -0
- package/dist/react/use-project-name.js.map +1 -0
- package/dist/react/use-project-secrets.d.ts +29 -2
- package/dist/react/use-project-secrets.d.ts.map +1 -1
- package/dist/react/use-project-secrets.js +8 -2
- package/dist/react/use-project-secrets.js.map +1 -1
- package/dist/react/use-project-session.d.ts +40 -0
- package/dist/react/use-project-session.d.ts.map +1 -0
- package/dist/react/use-project-session.js +49 -0
- package/dist/react/use-project-session.js.map +1 -0
- package/dist/react/use-project-triggers.d.ts +4 -2
- package/dist/react/use-project-triggers.d.ts.map +1 -1
- package/dist/react/use-project-triggers.js +7 -2
- package/dist/react/use-project-triggers.js.map +1 -1
- package/dist/react/use-session-sync.d.ts +1 -2
- package/dist/react/use-session-sync.d.ts.map +1 -1
- package/dist/react/use-session-sync.js +17 -40
- package/dist/react/use-session-sync.js.map +1 -1
- package/dist/react/use-session.d.ts.map +1 -1
- package/dist/react/use-session.js +18 -16
- package/dist/react/use-session.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place a Kortix query key is constructed.
|
|
3
|
+
*
|
|
4
|
+
* Before this existed, `apps/web` hand-typed roughly 176 key literals across
|
|
5
|
+
* 30 `project*` families. One entity therefore had several cache entries (the
|
|
6
|
+
* flat `project-sessions` key and the flat `project-session-inventory` key
|
|
7
|
+
* held the same server data), and one key had several freshness contracts, because
|
|
8
|
+
* `staleTime` is per-observer and seven call sites disagreed about it.
|
|
9
|
+
*
|
|
10
|
+
* The first version of `sessions(id)` repeated that exact mistake one level
|
|
11
|
+
* down: it dropped `listProjectSessions`'s `scope` argument, so a
|
|
12
|
+
* `scope: 'visible'` reader and a `scope: 'project'` reader (a DIFFERENT
|
|
13
|
+
* server request — see `sessions` below) shared one cache slot, and
|
|
14
|
+
* whichever fetch resolved last silently overwrote what the other scope's
|
|
15
|
+
* readers saw. Anything that changes the response MUST be part of the key —
|
|
16
|
+
* that is the rule this file exists to enforce, and it is not optional just
|
|
17
|
+
* because the argument is easy to forget.
|
|
18
|
+
*
|
|
19
|
+
* The SECOND version of `sessions(id, scope)` fixed that, then introduced a
|
|
20
|
+
* narrower version of the same class of bug: `sessions(id, scope)` and
|
|
21
|
+
* `session(id, sessionId)` were both `sessionsScope(id)` plus exactly one
|
|
22
|
+
* segment, so a session id equal to a scope literal (`'visible'`,
|
|
23
|
+
* `'project'`) would collide byte-for-byte with a scoped list. Nothing in
|
|
24
|
+
* THIS file prevented that — the only thing standing in the way was a UUID
|
|
25
|
+
* regex enforced server-side, in `apps/api`, a different package, with no
|
|
26
|
+
* link back here. `sessions` now inserts a literal `'list'` segment so it is
|
|
27
|
+
* structurally longer than `session(...)` for every possible session id —
|
|
28
|
+
* the collision is unrepresentable, not merely unlikely.
|
|
29
|
+
*
|
|
30
|
+
* Two rules make this work:
|
|
31
|
+
*
|
|
32
|
+
* 1. `scope(id)` is a PREFIX, never a query key. Everything belonging to one
|
|
33
|
+
* project sits under it, so `invalidateQueries({ queryKey: scope(id) })`
|
|
34
|
+
* provably reaches all of it.
|
|
35
|
+
* 2. Nothing derived from another query gets its own key. Skills, commands
|
|
36
|
+
* and agents are `config.*` fields of the project detail response, not
|
|
37
|
+
* separate fetches — they are `select` projections over `detail(id)`.
|
|
38
|
+
*
|
|
39
|
+
* Not to be confused with `kortixKeys` in `use-kortix-master.ts`, which
|
|
40
|
+
* addresses the multi-server Kortix Master surface and means something else.
|
|
41
|
+
*
|
|
42
|
+
* The root segment below is `'kx'`, not `'kortix'`. `'kortix'` is already
|
|
43
|
+
* `kortixKeys`'s root (`use-kortix-master.ts:276-279`):
|
|
44
|
+
* `kortixKeys.projects() = ['kortix', 'projects']` and
|
|
45
|
+
* `kortixKeys.project(id) = ['kortix', 'projects', id]`. If this factory also
|
|
46
|
+
* rooted at `'kortix'`, `kortixKeys.project(id)` and `qk.projects.list(id)`
|
|
47
|
+
* would be the identical array for a matching id — one cache entry standing
|
|
48
|
+
* in for two unrelated concepts — and `kortixKeys.projects()` (used as an
|
|
49
|
+
* `invalidateQueries` prefix at `use-kortix-master.ts:371,384`) would also
|
|
50
|
+
* match every key this factory produces, since TanStack matches query keys by
|
|
51
|
+
* prefix. `'kx'` makes the two factories disjoint at segment 0, so neither
|
|
52
|
+
* can ever prefix-match the other. Do not "tidy" this back to `'kortix'`.
|
|
53
|
+
*/
|
|
54
|
+
export declare const qk: {
|
|
55
|
+
readonly projects: {
|
|
56
|
+
/** Invalidation prefix covering every account's list AND the accountless
|
|
57
|
+
* slot. Never pass this as a `queryKey` — `list(accountId)` and
|
|
58
|
+
* `list()` are SIBLINGS (`'<id>'` vs `'all'`), not a parent/child pair,
|
|
59
|
+
* so `list()` alone does not prefix-match `list(accountId)`. Use this
|
|
60
|
+
* when a mutation needs to reach every form at once. */
|
|
61
|
+
readonly scope: () => readonly ["kx", "projects"];
|
|
62
|
+
/** Every project the account can see. `undefined` means the active account. */
|
|
63
|
+
readonly list: (accountId?: string) => readonly ["kx", "projects", string];
|
|
64
|
+
};
|
|
65
|
+
readonly project: {
|
|
66
|
+
/** Invalidation prefix. Never pass this as a `queryKey`. */
|
|
67
|
+
readonly scope: (id: string) => readonly ["kx", "project", string];
|
|
68
|
+
/**
|
|
69
|
+
* The bare project row — `getProject`, `GET /projects/:id`, a
|
|
70
|
+
* `KortixProject`. NOT `detail(id)` below: `getProjectDetail` hits
|
|
71
|
+
* `GET /projects/:id/detail` and returns a completely different shape,
|
|
72
|
+
* `{ project, config, file_count, files, git_connection }`. An earlier
|
|
73
|
+
* draft of this migration folded the two onto one key because both
|
|
74
|
+
* requests are "about a project" — but they are different requests with
|
|
75
|
+
* different responses, so sharing a key means whichever one resolves
|
|
76
|
+
* last silently overwrites the other's shape: a `data.account_id` reader
|
|
77
|
+
* (this one) would intermittently receive the detail wrapper instead,
|
|
78
|
+
* where the same field lives at `data.project.account_id`. Keep them
|
|
79
|
+
* apart, the same way `sessions`/`session` and `policies`/
|
|
80
|
+
* `executorPolicies` below are kept apart for the identical reason.
|
|
81
|
+
*/
|
|
82
|
+
readonly summary: (id: string) => readonly ["kx", "project", string, "summary"];
|
|
83
|
+
readonly detail: (id: string) => readonly ["kx", "project", string, "detail"];
|
|
84
|
+
/**
|
|
85
|
+
* Prefix reserved for config-adjacent sub-resources that do NOT share
|
|
86
|
+
* `getProjectDetail`'s response shape (currently only `modelPicker`
|
|
87
|
+
* below). The project config DATA ITSELF — `ProjectConfigSummary`,
|
|
88
|
+
* i.e. `getProjectDetail(id).config` — is not keyed here: it rides the
|
|
89
|
+
* shared `detail(id)` entry via a `select` projection (see
|
|
90
|
+
* `use-project-config.ts`), because it IS that same response every
|
|
91
|
+
* other detail reader already caches. Keying it separately here would
|
|
92
|
+
* bring back the exact double-fetch this factory exists to remove —
|
|
93
|
+
* `useProjectConfig` used to do exactly that under a standalone
|
|
94
|
+
* `['project-config', id]` key.
|
|
95
|
+
*/
|
|
96
|
+
readonly config: (id: string) => readonly ["kx", "project", string, "config"];
|
|
97
|
+
/**
|
|
98
|
+
* `getProjectModelPicker`, `GET /projects/:id/model-picker` — the compact,
|
|
99
|
+
* connection-aware model catalog. LIVE: `useProjectModels` (`use-project-
|
|
100
|
+
* models.ts`) `useQuery`s it directly, rendered at `gateway-view.tsx`,
|
|
101
|
+
* `gateway-routing.tsx`, `gateway-playground.tsx`, `models-tab.tsx`, and
|
|
102
|
+
* `use-session.ts`. `useModelEnablement` (`use-model-enablement.ts`) reads
|
|
103
|
+
* and optimistically writes the SAME entry so a toggle and the picker never
|
|
104
|
+
* disagree. A routing-policy save's `invalidateQueries` targets this key
|
|
105
|
+
* too (`gateway-routing.tsx`) — before the `packages/sdk/src/react`
|
|
106
|
+
* migration that call and every reader above hand-typed the same flat
|
|
107
|
+
* `project-model-picker` array literal independently; an earlier
|
|
108
|
+
* version of this comment called the key "dead" because that literal
|
|
109
|
+
* search only ever turned up the invalidation site, never the readers —
|
|
110
|
+
* they lived one file away, under `packages/sdk/src/react`, which this
|
|
111
|
+
* factory did not yet reach.
|
|
112
|
+
*/
|
|
113
|
+
readonly modelPicker: (id: string) => readonly ["kx", "project", string, "config", "models"];
|
|
114
|
+
/**
|
|
115
|
+
* Invalidation prefix for the WHOLE sessions family: the list, in every
|
|
116
|
+
* scope, and every individual session/message beneath it. Never pass
|
|
117
|
+
* this as a `queryKey` — pass it to `invalidateQueries` at every site
|
|
118
|
+
* that means "the sessions list changed" (create/rename/delete/restart/
|
|
119
|
+
* stop/share). `sessions(id)` and `sessions(id, 'project')` are SIBLINGS,
|
|
120
|
+
* not parent and child (see `sessions` below) — invalidating one alone
|
|
121
|
+
* would leave the other silently stale, and this prefix is the only form
|
|
122
|
+
* that reaches both in one call.
|
|
123
|
+
*/
|
|
124
|
+
readonly sessionsScope: (id: string) => readonly ["kx", "project", string, "sessions"];
|
|
125
|
+
/**
|
|
126
|
+
* The sessions list. `scope` is part of the key ON PURPOSE:
|
|
127
|
+
* `listProjectSessions(id, { scope })`
|
|
128
|
+
* (`core/rest/projects-client/sessions.ts`) is a DIFFERENT server
|
|
129
|
+
* request per scope, not a client-side filter of one response —
|
|
130
|
+
* `'visible'` (the default; matches passing no `options` at all) returns
|
|
131
|
+
* what the caller can see, `'project'` is the manager-only unfiltered
|
|
132
|
+
* full inventory (`apps/api/src/projects/lib/session-inventory.ts`).
|
|
133
|
+
* Before this, both scopes shared one scope-less key, so whichever fetch
|
|
134
|
+
* resolved last silently overwrote what the OTHER scope's readers saw —
|
|
135
|
+
* the sidebar could render the unfiltered manager inventory, or the
|
|
136
|
+
* inventory page could render the sidebar's filtered list. Use
|
|
137
|
+
* `sessionsScope(id)`, not this, for invalidation.
|
|
138
|
+
*
|
|
139
|
+
* The literal `'list'` segment exists so this can NEVER collide with
|
|
140
|
+
* `session(id, sessionId)` below. Without it, both were
|
|
141
|
+
* `sessionsScope(id)` plus exactly one segment — a session whose id
|
|
142
|
+
* happened to equal the string `'visible'` or `'project'` would produce
|
|
143
|
+
* the identical array a scoped list produces, and the two would silently
|
|
144
|
+
* overwrite each other. Session ids are `crypto.randomUUID()`
|
|
145
|
+
* client-side and rejected server-side otherwise
|
|
146
|
+
* (`apps/api/src/projects/lib/sessions.ts`), so that made the collision
|
|
147
|
+
* unreachable, not impossible — safety by an invariant enforced in a
|
|
148
|
+
* DIFFERENT package, with no link back to this file. `'list'` makes
|
|
149
|
+
* `sessions(...)` structurally longer than `session(...)` for every
|
|
150
|
+
* possible session id, which is the same standard this file already
|
|
151
|
+
* applies to the `'kx'` root (see the top doc comment): make the
|
|
152
|
+
* collision unrepresentable, don't rely on another package's validation
|
|
153
|
+
* staying strict.
|
|
154
|
+
*/
|
|
155
|
+
readonly sessions: (id: string, scope?: "visible" | "project") => readonly ["kx", "project", string, "sessions", "list", "project" | "visible"];
|
|
156
|
+
/**
|
|
157
|
+
* One session, by id. Nests directly under the scope-LESS
|
|
158
|
+
* `sessionsScope` prefix, not under a specific `sessions(id, scope)`
|
|
159
|
+
* slot: a session is not "owned" by whichever list scope happened to
|
|
160
|
+
* discover it (the same session id is reachable via either scope), so
|
|
161
|
+
* its own cache entry does not carry a scope segment either.
|
|
162
|
+
*/
|
|
163
|
+
readonly session: (id: string, sessionId: string) => readonly ["kx", "project", string, "sessions", string];
|
|
164
|
+
readonly messages: (id: string, sessionId: string) => readonly ["kx", "project", string, "sessions", string, "messages"];
|
|
165
|
+
/**
|
|
166
|
+
* Orphaned pre-existing behavior, migrated verbatim rather than "fixed":
|
|
167
|
+
* three `apps/web` call sites invalidate this slot after a session
|
|
168
|
+
* restart / config reload, and one reads it with `getQueryData`, but no
|
|
169
|
+
* site anywhere `useQuery`s or `setQueryData`s it — so the read always
|
|
170
|
+
* resolves `undefined` and the three invalidations are no-ops today.
|
|
171
|
+
* Nests under `session(id, sessionId)` rather than folding onto it
|
|
172
|
+
* because `session(...)` became a REAL, live query in this same
|
|
173
|
+
* migration (`getProjectSession`); sharing that slot would make these
|
|
174
|
+
* dead invalidations start firing against real session data instead of
|
|
175
|
+
* continuing to hit nothing.
|
|
176
|
+
*/
|
|
177
|
+
readonly sessionSandbox: (id: string, sessionId: string) => readonly ["kx", "project", string, "sessions", string, "sandbox"];
|
|
178
|
+
readonly connectors: (id: string) => readonly ["kx", "project", string, "connectors"];
|
|
179
|
+
/** One connector's config — `getConnectorConfig(id, slug)`. */
|
|
180
|
+
readonly connectorConfig: (id: string, slug: string) => readonly ["kx", "project", string, "connectors", string];
|
|
181
|
+
readonly access: (id: string) => readonly ["kx", "project", string, "access"];
|
|
182
|
+
readonly accessRequests: (id: string) => readonly ["kx", "project", string, "access", "requests"];
|
|
183
|
+
readonly pendingInvites: (id: string) => readonly ["kx", "project", string, "access", "invites"];
|
|
184
|
+
/** `listProjectGroupGrants` — `GET /group-grants`, `{ grants: ProjectGroupGrant[] }`. */
|
|
185
|
+
readonly groupGrants: (id: string) => readonly ["kx", "project", string, "access", "group-grants"];
|
|
186
|
+
/** `listProjectResourceGrants` — `GET /resource-grants`, a DIFFERENT
|
|
187
|
+
* endpoint and shape from `groupGrants` above; do not fold together. */
|
|
188
|
+
readonly resourceGrants: (id: string) => readonly ["kx", "project", string, "access", "grants"];
|
|
189
|
+
readonly secrets: (id: string) => readonly ["kx", "project", string, "secrets"];
|
|
190
|
+
/** Stable App inventory for `GET /projects/:id/apps`. */
|
|
191
|
+
readonly apps: (id: string) => readonly ["kx", "project", string, "apps"];
|
|
192
|
+
/** Access policy and short-lived browser session for one App. */
|
|
193
|
+
readonly appAccess: (id: string, appId: string) => readonly ["kx", "project", string, "apps", string, "access"];
|
|
194
|
+
/** Short-lived browser exchange URL for one App. */
|
|
195
|
+
readonly appAccessSession: (id: string, appId: string) => readonly ["kx", "project", string, "apps", string, "access", "session"];
|
|
196
|
+
/** Immutable deployment history for one App. */
|
|
197
|
+
readonly appDeployments: (id: string, appId: string) => readonly ["kx", "project", string, "apps", string, "deployments"];
|
|
198
|
+
/** `listProjectTriggers` — `GET /projects/:id/triggers`, the cron/webhook
|
|
199
|
+
* listing (file-defined in the repo manifest). Shared by
|
|
200
|
+
* `useProjectTriggers` (`use-project-triggers.ts`), the Customize
|
|
201
|
+
* settings pause switch, and the schedule/triggers view — all three read
|
|
202
|
+
* and write the identical entity through `listProjectTriggers(id)`, so
|
|
203
|
+
* they must share this one key. */
|
|
204
|
+
readonly triggers: (id: string) => readonly ["kx", "project", string, "triggers"];
|
|
205
|
+
/**
|
|
206
|
+
* `readProjectFile(id, path)` — a single-file source read, used by the
|
|
207
|
+
* Customize config-entity viewer. Unrelated to the much larger Git file
|
|
208
|
+
* browser under `features/project-files/` (its own local key factories,
|
|
209
|
+
* `commitKeys`/`branchKeys`/`changeRequestKeys`, rooted at the literal
|
|
210
|
+
* string `'project-files'` — never migrated onto `qk`, and never sharing
|
|
211
|
+
* this prefix).
|
|
212
|
+
*/
|
|
213
|
+
readonly files: (id: string) => readonly ["kx", "project", string, "files"];
|
|
214
|
+
readonly fileSource: (id: string, path: string) => readonly ["kx", "project", string, "files", string];
|
|
215
|
+
readonly branches: (id: string) => readonly ["kx", "project", string, "branches"];
|
|
216
|
+
/** IAM role policies — `listPolicies(accountId, { scopeId: id })`,
|
|
217
|
+
* `{ policies: IamPolicy[] }`. NOT the same entity as
|
|
218
|
+
* `executorPolicies` below — see that member's doc comment. */
|
|
219
|
+
readonly policies: (id: string) => readonly ["kx", "project", string, "policies"];
|
|
220
|
+
/**
|
|
221
|
+
* Executor sandbox tool-execution allow/deny rules —
|
|
222
|
+
* `listProjectPolicies(id)`, `GET /executor/projects/:id/policies`,
|
|
223
|
+
* `ProjectPoliciesResponse`. A DIFFERENT endpoint and a DIFFERENT shape
|
|
224
|
+
* from `policies` above (account IAM role policies) — both used to read
|
|
225
|
+
* the identical literal `['project-policies', id]`, so whichever one's
|
|
226
|
+
* fetch resolved last silently overwrote the other's cache entry with an
|
|
227
|
+
* incompatible shape. Sibling of `policies`, not nested under it: they
|
|
228
|
+
* are unrelated domains that happen to share a name, not a parent/child
|
|
229
|
+
* pair, so invalidating one must never reach the other.
|
|
230
|
+
*/
|
|
231
|
+
readonly executorPolicies: (id: string) => readonly ["kx", "project", string, "executor-policies"];
|
|
232
|
+
readonly sandboxes: (id: string) => readonly ["kx", "project", string, "sandboxes"];
|
|
233
|
+
readonly sandboxTemplates: (id: string) => readonly ["kx", "project", string, "sandboxes", "templates"];
|
|
234
|
+
readonly snapshots: (id: string) => readonly ["kx", "project", string, "snapshots"];
|
|
235
|
+
/** Prefix for the gateway family — keys, budgets, series, logs, overview. */
|
|
236
|
+
readonly gateway: (id: string) => readonly ["kx", "project", string, "gateway"];
|
|
237
|
+
readonly gatewayOverview: (id: string, days: number) => readonly ["kx", "project", string, "gateway", "overview", number];
|
|
238
|
+
readonly gatewaySeries: (id: string, days: number) => readonly ["kx", "project", string, "gateway", "series", number];
|
|
239
|
+
readonly gatewayBreakdown: (id: string, days: number) => readonly ["kx", "project", string, "gateway", "breakdown", number];
|
|
240
|
+
readonly gatewaySessions: (id: string, days: number) => readonly ["kx", "project", string, "gateway", "sessions", number];
|
|
241
|
+
readonly gatewayErrors: (id: string, days: number) => readonly ["kx", "project", string, "gateway", "errors", number];
|
|
242
|
+
/** `ok` mirrors `listGatewayLogs`'s optional pass/fail filter — `null` = unfiltered. */
|
|
243
|
+
readonly gatewayLogs: (id: string, ok: boolean | null) => readonly ["kx", "project", string, "gateway", "logs", boolean | null];
|
|
244
|
+
readonly gatewayLog: (id: string, logId: string | null) => readonly ["kx", "project", string, "gateway", "log", string | null];
|
|
245
|
+
readonly gatewayBudgets: (id: string) => readonly ["kx", "project", string, "gateway", "budgets"];
|
|
246
|
+
readonly gatewayKeys: (id: string) => readonly ["kx", "project", string, "gateway", "keys"];
|
|
247
|
+
};
|
|
248
|
+
};
|
|
249
|
+
export type ProjectScopeKey = ReturnType<typeof qk.project.scope>;
|
|
250
|
+
export type ProjectsListKey = ReturnType<typeof qk.projects.list>;
|
|
251
|
+
//# sourceMappingURL=query-keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-keys.d.ts","sourceRoot":"","sources":["../../src/react/query-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,eAAO,MAAM,EAAE;;QAEX;;;;iEAIyD;;QAGzD,+EAA+E;oCAC5D,MAAM;;;QAIzB,4DAA4D;6BAChD,MAAM;QAElB;;;;;;;;;;;;;WAaG;+BACW,MAAM;8BAEP,MAAM;QACnB;;;;;;;;;;;WAWG;8BACU,MAAM;QACnB;;;;;;;;;;;;;;;WAeG;mCACe,MAAM;QAExB;;;;;;;;;WASG;qCACiB,MAAM;QAE1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA6BG;gCACY,MAAM,UAAS,SAAS,GAAG,SAAS;QAGnD;;;;;;WAMG;+BACW,MAAM,aAAa,MAAM;gCAExB,MAAM,aAAa,MAAM;QAExC;;;;;;;;;;;WAWG;sCACkB,MAAM,aAAa,MAAM;kCAG7B,MAAM;QACvB,+DAA+D;uCACzC,MAAM,QAAQ,MAAM;8BAG7B,MAAM;sCACE,MAAM;sCACN,MAAM;QAC3B,yFAAyF;mCACvE,MAAM;QACxB;iFACyE;sCACpD,MAAM;+BAEb,MAAM;QAEpB,yDAAyD;4BAC9C,MAAM;QACjB,iEAAiE;iCACjD,MAAM,SAAS,MAAM;QACrC,oDAAoD;wCAC7B,MAAM,SAAS,MAAM;QAE5C,gDAAgD;sCAC3B,MAAM,SAAS,MAAM;QAG1C;;;;;4CAKoC;gCACrB,MAAM;QAErB;;;;;;;WAOG;6BACS,MAAM;kCACD,MAAM,QAAQ,MAAM;gCAEtB,MAAM;QAErB;;wEAEgE;gCACjD,MAAM;QACrB;;;;;;;;;;WAUG;wCACoB,MAAM;iCAEb,MAAM;wCACC,MAAM;iCACb,MAAM;QAEtB,6EAA6E;+BAC/D,MAAM;uCACE,MAAM,QAAQ,MAAM;qCAEtB,MAAM,QAAQ,MAAM;wCAEjB,MAAM,QAAQ,MAAM;uCAErB,MAAM,QAAQ,MAAM;qCAEtB,MAAM,QAAQ,MAAM;QAExC,wFAAwF;mCACtE,MAAM,MAAM,OAAO,GAAG,IAAI;kCAE3B,MAAM,SAAS,MAAM,GAAG,IAAI;sCAExB,MAAM;mCACT,MAAM;;CAElB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAClE,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place a Kortix query key is constructed.
|
|
3
|
+
*
|
|
4
|
+
* Before this existed, `apps/web` hand-typed roughly 176 key literals across
|
|
5
|
+
* 30 `project*` families. One entity therefore had several cache entries (the
|
|
6
|
+
* flat `project-sessions` key and the flat `project-session-inventory` key
|
|
7
|
+
* held the same server data), and one key had several freshness contracts, because
|
|
8
|
+
* `staleTime` is per-observer and seven call sites disagreed about it.
|
|
9
|
+
*
|
|
10
|
+
* The first version of `sessions(id)` repeated that exact mistake one level
|
|
11
|
+
* down: it dropped `listProjectSessions`'s `scope` argument, so a
|
|
12
|
+
* `scope: 'visible'` reader and a `scope: 'project'` reader (a DIFFERENT
|
|
13
|
+
* server request — see `sessions` below) shared one cache slot, and
|
|
14
|
+
* whichever fetch resolved last silently overwrote what the other scope's
|
|
15
|
+
* readers saw. Anything that changes the response MUST be part of the key —
|
|
16
|
+
* that is the rule this file exists to enforce, and it is not optional just
|
|
17
|
+
* because the argument is easy to forget.
|
|
18
|
+
*
|
|
19
|
+
* The SECOND version of `sessions(id, scope)` fixed that, then introduced a
|
|
20
|
+
* narrower version of the same class of bug: `sessions(id, scope)` and
|
|
21
|
+
* `session(id, sessionId)` were both `sessionsScope(id)` plus exactly one
|
|
22
|
+
* segment, so a session id equal to a scope literal (`'visible'`,
|
|
23
|
+
* `'project'`) would collide byte-for-byte with a scoped list. Nothing in
|
|
24
|
+
* THIS file prevented that — the only thing standing in the way was a UUID
|
|
25
|
+
* regex enforced server-side, in `apps/api`, a different package, with no
|
|
26
|
+
* link back here. `sessions` now inserts a literal `'list'` segment so it is
|
|
27
|
+
* structurally longer than `session(...)` for every possible session id —
|
|
28
|
+
* the collision is unrepresentable, not merely unlikely.
|
|
29
|
+
*
|
|
30
|
+
* Two rules make this work:
|
|
31
|
+
*
|
|
32
|
+
* 1. `scope(id)` is a PREFIX, never a query key. Everything belonging to one
|
|
33
|
+
* project sits under it, so `invalidateQueries({ queryKey: scope(id) })`
|
|
34
|
+
* provably reaches all of it.
|
|
35
|
+
* 2. Nothing derived from another query gets its own key. Skills, commands
|
|
36
|
+
* and agents are `config.*` fields of the project detail response, not
|
|
37
|
+
* separate fetches — they are `select` projections over `detail(id)`.
|
|
38
|
+
*
|
|
39
|
+
* Not to be confused with `kortixKeys` in `use-kortix-master.ts`, which
|
|
40
|
+
* addresses the multi-server Kortix Master surface and means something else.
|
|
41
|
+
*
|
|
42
|
+
* The root segment below is `'kx'`, not `'kortix'`. `'kortix'` is already
|
|
43
|
+
* `kortixKeys`'s root (`use-kortix-master.ts:276-279`):
|
|
44
|
+
* `kortixKeys.projects() = ['kortix', 'projects']` and
|
|
45
|
+
* `kortixKeys.project(id) = ['kortix', 'projects', id]`. If this factory also
|
|
46
|
+
* rooted at `'kortix'`, `kortixKeys.project(id)` and `qk.projects.list(id)`
|
|
47
|
+
* would be the identical array for a matching id — one cache entry standing
|
|
48
|
+
* in for two unrelated concepts — and `kortixKeys.projects()` (used as an
|
|
49
|
+
* `invalidateQueries` prefix at `use-kortix-master.ts:371,384`) would also
|
|
50
|
+
* match every key this factory produces, since TanStack matches query keys by
|
|
51
|
+
* prefix. `'kx'` makes the two factories disjoint at segment 0, so neither
|
|
52
|
+
* can ever prefix-match the other. Do not "tidy" this back to `'kortix'`.
|
|
53
|
+
*/
|
|
54
|
+
export const qk = {
|
|
55
|
+
projects: {
|
|
56
|
+
/** Invalidation prefix covering every account's list AND the accountless
|
|
57
|
+
* slot. Never pass this as a `queryKey` — `list(accountId)` and
|
|
58
|
+
* `list()` are SIBLINGS (`'<id>'` vs `'all'`), not a parent/child pair,
|
|
59
|
+
* so `list()` alone does not prefix-match `list(accountId)`. Use this
|
|
60
|
+
* when a mutation needs to reach every form at once. */
|
|
61
|
+
scope: () => ['kx', 'projects'],
|
|
62
|
+
/** Every project the account can see. `undefined` means the active account. */
|
|
63
|
+
list: (accountId) => [...qk.projects.scope(), accountId ?? 'all'],
|
|
64
|
+
},
|
|
65
|
+
project: {
|
|
66
|
+
/** Invalidation prefix. Never pass this as a `queryKey`. */
|
|
67
|
+
scope: (id) => ['kx', 'project', id],
|
|
68
|
+
/**
|
|
69
|
+
* The bare project row — `getProject`, `GET /projects/:id`, a
|
|
70
|
+
* `KortixProject`. NOT `detail(id)` below: `getProjectDetail` hits
|
|
71
|
+
* `GET /projects/:id/detail` and returns a completely different shape,
|
|
72
|
+
* `{ project, config, file_count, files, git_connection }`. An earlier
|
|
73
|
+
* draft of this migration folded the two onto one key because both
|
|
74
|
+
* requests are "about a project" — but they are different requests with
|
|
75
|
+
* different responses, so sharing a key means whichever one resolves
|
|
76
|
+
* last silently overwrites the other's shape: a `data.account_id` reader
|
|
77
|
+
* (this one) would intermittently receive the detail wrapper instead,
|
|
78
|
+
* where the same field lives at `data.project.account_id`. Keep them
|
|
79
|
+
* apart, the same way `sessions`/`session` and `policies`/
|
|
80
|
+
* `executorPolicies` below are kept apart for the identical reason.
|
|
81
|
+
*/
|
|
82
|
+
summary: (id) => [...qk.project.scope(id), 'summary'],
|
|
83
|
+
detail: (id) => [...qk.project.scope(id), 'detail'],
|
|
84
|
+
/**
|
|
85
|
+
* Prefix reserved for config-adjacent sub-resources that do NOT share
|
|
86
|
+
* `getProjectDetail`'s response shape (currently only `modelPicker`
|
|
87
|
+
* below). The project config DATA ITSELF — `ProjectConfigSummary`,
|
|
88
|
+
* i.e. `getProjectDetail(id).config` — is not keyed here: it rides the
|
|
89
|
+
* shared `detail(id)` entry via a `select` projection (see
|
|
90
|
+
* `use-project-config.ts`), because it IS that same response every
|
|
91
|
+
* other detail reader already caches. Keying it separately here would
|
|
92
|
+
* bring back the exact double-fetch this factory exists to remove —
|
|
93
|
+
* `useProjectConfig` used to do exactly that under a standalone
|
|
94
|
+
* `['project-config', id]` key.
|
|
95
|
+
*/
|
|
96
|
+
config: (id) => [...qk.project.scope(id), 'config'],
|
|
97
|
+
/**
|
|
98
|
+
* `getProjectModelPicker`, `GET /projects/:id/model-picker` — the compact,
|
|
99
|
+
* connection-aware model catalog. LIVE: `useProjectModels` (`use-project-
|
|
100
|
+
* models.ts`) `useQuery`s it directly, rendered at `gateway-view.tsx`,
|
|
101
|
+
* `gateway-routing.tsx`, `gateway-playground.tsx`, `models-tab.tsx`, and
|
|
102
|
+
* `use-session.ts`. `useModelEnablement` (`use-model-enablement.ts`) reads
|
|
103
|
+
* and optimistically writes the SAME entry so a toggle and the picker never
|
|
104
|
+
* disagree. A routing-policy save's `invalidateQueries` targets this key
|
|
105
|
+
* too (`gateway-routing.tsx`) — before the `packages/sdk/src/react`
|
|
106
|
+
* migration that call and every reader above hand-typed the same flat
|
|
107
|
+
* `project-model-picker` array literal independently; an earlier
|
|
108
|
+
* version of this comment called the key "dead" because that literal
|
|
109
|
+
* search only ever turned up the invalidation site, never the readers —
|
|
110
|
+
* they lived one file away, under `packages/sdk/src/react`, which this
|
|
111
|
+
* factory did not yet reach.
|
|
112
|
+
*/
|
|
113
|
+
modelPicker: (id) => [...qk.project.config(id), 'models'],
|
|
114
|
+
/**
|
|
115
|
+
* Invalidation prefix for the WHOLE sessions family: the list, in every
|
|
116
|
+
* scope, and every individual session/message beneath it. Never pass
|
|
117
|
+
* this as a `queryKey` — pass it to `invalidateQueries` at every site
|
|
118
|
+
* that means "the sessions list changed" (create/rename/delete/restart/
|
|
119
|
+
* stop/share). `sessions(id)` and `sessions(id, 'project')` are SIBLINGS,
|
|
120
|
+
* not parent and child (see `sessions` below) — invalidating one alone
|
|
121
|
+
* would leave the other silently stale, and this prefix is the only form
|
|
122
|
+
* that reaches both in one call.
|
|
123
|
+
*/
|
|
124
|
+
sessionsScope: (id) => [...qk.project.scope(id), 'sessions'],
|
|
125
|
+
/**
|
|
126
|
+
* The sessions list. `scope` is part of the key ON PURPOSE:
|
|
127
|
+
* `listProjectSessions(id, { scope })`
|
|
128
|
+
* (`core/rest/projects-client/sessions.ts`) is a DIFFERENT server
|
|
129
|
+
* request per scope, not a client-side filter of one response —
|
|
130
|
+
* `'visible'` (the default; matches passing no `options` at all) returns
|
|
131
|
+
* what the caller can see, `'project'` is the manager-only unfiltered
|
|
132
|
+
* full inventory (`apps/api/src/projects/lib/session-inventory.ts`).
|
|
133
|
+
* Before this, both scopes shared one scope-less key, so whichever fetch
|
|
134
|
+
* resolved last silently overwrote what the OTHER scope's readers saw —
|
|
135
|
+
* the sidebar could render the unfiltered manager inventory, or the
|
|
136
|
+
* inventory page could render the sidebar's filtered list. Use
|
|
137
|
+
* `sessionsScope(id)`, not this, for invalidation.
|
|
138
|
+
*
|
|
139
|
+
* The literal `'list'` segment exists so this can NEVER collide with
|
|
140
|
+
* `session(id, sessionId)` below. Without it, both were
|
|
141
|
+
* `sessionsScope(id)` plus exactly one segment — a session whose id
|
|
142
|
+
* happened to equal the string `'visible'` or `'project'` would produce
|
|
143
|
+
* the identical array a scoped list produces, and the two would silently
|
|
144
|
+
* overwrite each other. Session ids are `crypto.randomUUID()`
|
|
145
|
+
* client-side and rejected server-side otherwise
|
|
146
|
+
* (`apps/api/src/projects/lib/sessions.ts`), so that made the collision
|
|
147
|
+
* unreachable, not impossible — safety by an invariant enforced in a
|
|
148
|
+
* DIFFERENT package, with no link back to this file. `'list'` makes
|
|
149
|
+
* `sessions(...)` structurally longer than `session(...)` for every
|
|
150
|
+
* possible session id, which is the same standard this file already
|
|
151
|
+
* applies to the `'kx'` root (see the top doc comment): make the
|
|
152
|
+
* collision unrepresentable, don't rely on another package's validation
|
|
153
|
+
* staying strict.
|
|
154
|
+
*/
|
|
155
|
+
sessions: (id, scope = 'visible') => [...qk.project.sessionsScope(id), 'list', scope],
|
|
156
|
+
/**
|
|
157
|
+
* One session, by id. Nests directly under the scope-LESS
|
|
158
|
+
* `sessionsScope` prefix, not under a specific `sessions(id, scope)`
|
|
159
|
+
* slot: a session is not "owned" by whichever list scope happened to
|
|
160
|
+
* discover it (the same session id is reachable via either scope), so
|
|
161
|
+
* its own cache entry does not carry a scope segment either.
|
|
162
|
+
*/
|
|
163
|
+
session: (id, sessionId) => [...qk.project.sessionsScope(id), sessionId],
|
|
164
|
+
messages: (id, sessionId) => [...qk.project.session(id, sessionId), 'messages'],
|
|
165
|
+
/**
|
|
166
|
+
* Orphaned pre-existing behavior, migrated verbatim rather than "fixed":
|
|
167
|
+
* three `apps/web` call sites invalidate this slot after a session
|
|
168
|
+
* restart / config reload, and one reads it with `getQueryData`, but no
|
|
169
|
+
* site anywhere `useQuery`s or `setQueryData`s it — so the read always
|
|
170
|
+
* resolves `undefined` and the three invalidations are no-ops today.
|
|
171
|
+
* Nests under `session(id, sessionId)` rather than folding onto it
|
|
172
|
+
* because `session(...)` became a REAL, live query in this same
|
|
173
|
+
* migration (`getProjectSession`); sharing that slot would make these
|
|
174
|
+
* dead invalidations start firing against real session data instead of
|
|
175
|
+
* continuing to hit nothing.
|
|
176
|
+
*/
|
|
177
|
+
sessionSandbox: (id, sessionId) => [...qk.project.session(id, sessionId), 'sandbox'],
|
|
178
|
+
connectors: (id) => [...qk.project.scope(id), 'connectors'],
|
|
179
|
+
/** One connector's config — `getConnectorConfig(id, slug)`. */
|
|
180
|
+
connectorConfig: (id, slug) => [...qk.project.connectors(id), slug],
|
|
181
|
+
access: (id) => [...qk.project.scope(id), 'access'],
|
|
182
|
+
accessRequests: (id) => [...qk.project.access(id), 'requests'],
|
|
183
|
+
pendingInvites: (id) => [...qk.project.access(id), 'invites'],
|
|
184
|
+
/** `listProjectGroupGrants` — `GET /group-grants`, `{ grants: ProjectGroupGrant[] }`. */
|
|
185
|
+
groupGrants: (id) => [...qk.project.access(id), 'group-grants'],
|
|
186
|
+
/** `listProjectResourceGrants` — `GET /resource-grants`, a DIFFERENT
|
|
187
|
+
* endpoint and shape from `groupGrants` above; do not fold together. */
|
|
188
|
+
resourceGrants: (id) => [...qk.project.access(id), 'grants'],
|
|
189
|
+
secrets: (id) => [...qk.project.scope(id), 'secrets'],
|
|
190
|
+
/** Stable App inventory for `GET /projects/:id/apps`. */
|
|
191
|
+
apps: (id) => [...qk.project.scope(id), 'apps'],
|
|
192
|
+
/** Access policy and short-lived browser session for one App. */
|
|
193
|
+
appAccess: (id, appId) => [...qk.project.apps(id), appId, 'access'],
|
|
194
|
+
/** Short-lived browser exchange URL for one App. */
|
|
195
|
+
appAccessSession: (id, appId) => [...qk.project.appAccess(id, appId), 'session'],
|
|
196
|
+
/** Immutable deployment history for one App. */
|
|
197
|
+
appDeployments: (id, appId) => [...qk.project.apps(id), appId, 'deployments'],
|
|
198
|
+
/** `listProjectTriggers` — `GET /projects/:id/triggers`, the cron/webhook
|
|
199
|
+
* listing (file-defined in the repo manifest). Shared by
|
|
200
|
+
* `useProjectTriggers` (`use-project-triggers.ts`), the Customize
|
|
201
|
+
* settings pause switch, and the schedule/triggers view — all three read
|
|
202
|
+
* and write the identical entity through `listProjectTriggers(id)`, so
|
|
203
|
+
* they must share this one key. */
|
|
204
|
+
triggers: (id) => [...qk.project.scope(id), 'triggers'],
|
|
205
|
+
/**
|
|
206
|
+
* `readProjectFile(id, path)` — a single-file source read, used by the
|
|
207
|
+
* Customize config-entity viewer. Unrelated to the much larger Git file
|
|
208
|
+
* browser under `features/project-files/` (its own local key factories,
|
|
209
|
+
* `commitKeys`/`branchKeys`/`changeRequestKeys`, rooted at the literal
|
|
210
|
+
* string `'project-files'` — never migrated onto `qk`, and never sharing
|
|
211
|
+
* this prefix).
|
|
212
|
+
*/
|
|
213
|
+
files: (id) => [...qk.project.scope(id), 'files'],
|
|
214
|
+
fileSource: (id, path) => [...qk.project.files(id), path],
|
|
215
|
+
branches: (id) => [...qk.project.scope(id), 'branches'],
|
|
216
|
+
/** IAM role policies — `listPolicies(accountId, { scopeId: id })`,
|
|
217
|
+
* `{ policies: IamPolicy[] }`. NOT the same entity as
|
|
218
|
+
* `executorPolicies` below — see that member's doc comment. */
|
|
219
|
+
policies: (id) => [...qk.project.scope(id), 'policies'],
|
|
220
|
+
/**
|
|
221
|
+
* Executor sandbox tool-execution allow/deny rules —
|
|
222
|
+
* `listProjectPolicies(id)`, `GET /executor/projects/:id/policies`,
|
|
223
|
+
* `ProjectPoliciesResponse`. A DIFFERENT endpoint and a DIFFERENT shape
|
|
224
|
+
* from `policies` above (account IAM role policies) — both used to read
|
|
225
|
+
* the identical literal `['project-policies', id]`, so whichever one's
|
|
226
|
+
* fetch resolved last silently overwrote the other's cache entry with an
|
|
227
|
+
* incompatible shape. Sibling of `policies`, not nested under it: they
|
|
228
|
+
* are unrelated domains that happen to share a name, not a parent/child
|
|
229
|
+
* pair, so invalidating one must never reach the other.
|
|
230
|
+
*/
|
|
231
|
+
executorPolicies: (id) => [...qk.project.scope(id), 'executor-policies'],
|
|
232
|
+
sandboxes: (id) => [...qk.project.scope(id), 'sandboxes'],
|
|
233
|
+
sandboxTemplates: (id) => [...qk.project.sandboxes(id), 'templates'],
|
|
234
|
+
snapshots: (id) => [...qk.project.scope(id), 'snapshots'],
|
|
235
|
+
/** Prefix for the gateway family — keys, budgets, series, logs, overview. */
|
|
236
|
+
gateway: (id) => [...qk.project.scope(id), 'gateway'],
|
|
237
|
+
gatewayOverview: (id, days) => [...qk.project.gateway(id), 'overview', days],
|
|
238
|
+
gatewaySeries: (id, days) => [...qk.project.gateway(id), 'series', days],
|
|
239
|
+
gatewayBreakdown: (id, days) => [...qk.project.gateway(id), 'breakdown', days],
|
|
240
|
+
gatewaySessions: (id, days) => [...qk.project.gateway(id), 'sessions', days],
|
|
241
|
+
gatewayErrors: (id, days) => [...qk.project.gateway(id), 'errors', days],
|
|
242
|
+
/** `ok` mirrors `listGatewayLogs`'s optional pass/fail filter — `null` = unfiltered. */
|
|
243
|
+
gatewayLogs: (id, ok) => [...qk.project.gateway(id), 'logs', ok],
|
|
244
|
+
gatewayLog: (id, logId) => [...qk.project.gateway(id), 'log', logId],
|
|
245
|
+
gatewayBudgets: (id) => [...qk.project.gateway(id), 'budgets'],
|
|
246
|
+
gatewayKeys: (id) => [...qk.project.gateway(id), 'keys'],
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
//# sourceMappingURL=query-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-keys.js","sourceRoot":"","sources":["../../src/react/query-keys.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-title-sync.d.ts","sourceRoot":"","sources":["../../src/react/session-title-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"session-title-sync.d.ts","sourceRoot":"","sources":["../../src/react/session-title-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIzD,KAAK,uBAAuB,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,GAAG,gBAAgB,CAAC,CAAC;AAEpF,UAAU,0BAA0B;IAClC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAuED;;;;;GAKG;AACH,wBAAsB,qCAAqC,CACzD,WAAW,EAAE,uBAAuB,EACpC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,OAAO,CAAC,CAYlB;AAED;;;;;GAKG;AACH,wBAAsB,6BAA6B,CACjD,WAAW,EAAE,uBAAuB,EACpC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EACxB,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,OAAO,CAAC,CAIlB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { qk } from './query-keys.js';
|
|
1
2
|
const DEFAULT_TITLE_REFRESH_DELAYS_MS = [0, 5_000, 5_000, 10_000, 10_000, 15_000, 20_000];
|
|
2
3
|
function readRealTitle(value) {
|
|
3
4
|
const title = typeof value === 'string' ? value.trim() : '';
|
|
@@ -6,8 +7,13 @@ function readRealTitle(value) {
|
|
|
6
7
|
return title;
|
|
7
8
|
}
|
|
8
9
|
function cachedSessionHasTitle(queryClient, projectId, sessionId) {
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
// Exact-match reads (`getQueryData`), so these have to be the REAL cache
|
|
11
|
+
// entries the list/detail queries populate, not the broad `sessionsScope`
|
|
12
|
+
// invalidation prefix used below — `getQueryData` never does prefix
|
|
13
|
+
// matching. Default scope ('visible') matches `listProjectSessions`' own
|
|
14
|
+
// default and what the sidebar/list surfaces actually read.
|
|
15
|
+
const list = queryClient.getQueryData(qk.project.sessions(projectId));
|
|
16
|
+
const detail = queryClient.getQueryData(qk.project.session(projectId, sessionId));
|
|
11
17
|
const candidates = [...(Array.isArray(list) ? list : []), detail];
|
|
12
18
|
return candidates.some((candidate) => {
|
|
13
19
|
if (!candidate || typeof candidate !== 'object')
|
|
@@ -25,12 +31,16 @@ function cachedSessionHasTitle(queryClient, projectId, sessionId) {
|
|
|
25
31
|
}
|
|
26
32
|
function refetchSessionTitleQueries(queryClient, projectId, sessionId) {
|
|
27
33
|
return Promise.all([
|
|
34
|
+
// The broad sessions-family prefix, not just the default-scope list: it
|
|
35
|
+
// reaches the list in EVERY scope plus every session/messages entry
|
|
36
|
+
// beneath it, so a manager-only 'project'-scope reader picks up the
|
|
37
|
+
// resolved title too, not only the default 'visible' one.
|
|
28
38
|
queryClient.refetchQueries({
|
|
29
|
-
queryKey:
|
|
39
|
+
queryKey: qk.project.sessionsScope(projectId),
|
|
30
40
|
type: 'active',
|
|
31
41
|
}),
|
|
32
42
|
queryClient.refetchQueries({
|
|
33
|
-
queryKey:
|
|
43
|
+
queryKey: qk.project.session(projectId, sessionId),
|
|
34
44
|
type: 'active',
|
|
35
45
|
}),
|
|
36
46
|
]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-title-sync.js","sourceRoot":"","sources":["../../src/react/session-title-sync.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"session-title-sync.js","sourceRoot":"","sources":["../../src/react/session-title-sync.ts"],"names":[],"mappings":"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"}
|