Repository navigation
Commit 99ed5fb
feat(project-files): let Chat read and write Project files (#9034)
* feat(files): restore Project file browser and Mothership integration
* fix(files): resolve CI audits and test types after restacking on staging
- Keep prepareProjectsForAccountDeletion returning the Project IDs to delete.
The object return added an unused storageCleanupEventIds field; the
durable cleanup outbox already processes those events, so restore the
staging contract and its stronger integration assertions.
- Exempt lib/mothership/generated from the relative-import convention.
contracts:sync copies those wire contracts verbatim and byte-checks them,
so their sibling imports must stay relative; drop their baseline rows.
- Re-record the files page module-count baseline for the Project browser.
- Type the test fixtures that regressed, including a queue-recovery
fixture that persisted the invalid completion status 'success'.
* fix(files): gate Project sandbox callbacks like workspace callbacks
Staging now holds resource-delegated Chat principals to content
admission, so a Project callback read with no gate was refused and the
sandbox got a 503. Run Project callbacks under the same workbench
session gate as workspace callbacks (the gate's workspace is optional,
since Projects have none) and share the withheld-result handling.
The Project CLI read suite now runs reads under the tool executor's
registry gate, as Chat does.
* fix(projects): keep Project chat tabs behind the rollout flag
The chat resources API stored a Project-owned tab without checking the
projects flag. Refuse new Project tabs while Projects are off; removing
or reordering stored tabs stays possible so they can be cleaned up.
Also drop the projects flag check in list_user_projects that could never
run (listProjects already refuses while the flag is off) and the content
delivery barrel export left unused by the shared sandbox delivery helper.
* refactor(files): drop the Project files UI from the Chat transport PR
The Project files UI will be built for the project-first redesign, so
this PR keeps only the backend and Chat transport behind the projects
flag. Restore the workspace Files page, file viewer, Chat resource
panel, add-resource and mention entries, and their client query hooks
and owner adapters to staging. The previous tip is tagged
project-files-ui-seed for that UI work.
Kept: the shared ChatContext wire type (Project contexts and file owners
reach the Chat server) and its exhaustive kind registry entry.
Also drop the UI-only browser constants and response types nothing uses
now, restore the files page module-count baseline, and type the
use-chat fixtures that returned with the staging test.
* fix(files): redact Project file text like workspace file text
Project grep and text reads admitted every Project artifact as opaque
bytes, so any file carrying a secret was refused to Chat instead of
having the secret masked, unlike the same file in a workspace.
Share one text extraction core between workspace text reads and private
file observation: parse, redact before a line window can cut a secret,
then slice. Project text reads now go through readProjectFileText, which
admits the source and every rendered input as complete text and returns
text only. The complete artifact read stays private to that use case, so
bytes never leave under a complete label; readProjectFileArtifact keeps
admitting opaque bytes, and visual reads of a secret still refuse.
* fix(sim-cli): keep unpublished groups in the Mothership command inventory
#9057 hid the projects group from --help and `sim cli` search until
launch, and the inventory printer dropped every hidden command, so the
Mothership worker lost the Project file commands it routes --project to.
List a hidden top-level group that is only unpublished, marked
`unpublished`, so the worker can route to it once Sim enables Projects
for a turn; other hidden commands stay out, and --help is unchanged.
* fix(files): address Cubic and Greptile review findings
Workspace regressions while Projects are off:
- Sandbox file copies between workspaces keep the workspace route when
the lease has not negotiated the file-owner protocol; only pairs that
name a Project owner need it.
- Chat upload contexts keep their uploads/ path in the workspace owner
adapter.
Project transport:
- Project CLI requests refuse mutations during benchmark reference
generation, as workspace requests do.
- Project grep defaults an omitted scope to files.
- Project files with unrecorded or empty exact provenance are readable
when the caller holds a registry; a missing registry is still refused.
Mothership inventory:
- Unpublished Project commands carry response shapes from the
launch-ready Project OpenAPI definitions.
- An operation whose delegated services exclude Chat no longer mints a
Chat principal, so the refused-route list now matches runtime for
Project file version history.
* fix(files): address the second review round
- Project `files read` returns binary metadata for undecodable files:
the text route checked `workspaceFileTextFormat` against null, but it
returns undefined.
- Workspace file resources keep `workspaceId` beside their new workspace
owner, so current browsers can open and close those tabs in
organization chats; the resource key is unchanged.
- The Project tab flag gate is covered against the database instead of
through mocked collaborators.
* fix(files): choose a generated Project document's read by its rendered type
A generated PDF is stored under its source type (text/x-python-pdf), so
the Project text route treated `files read report.pdf` as text instead
of the default visual representation. Share the workspace reader's type
selection as observedMediaType: a generated document is read as the
type its name promises, otherwise as its effective stored type.
* fix(mothership): close review gaps in Project file transport
- Dispatch CLI services before file-owner adapters, so a service that
carries a file owner gets the services validation instead of a bridge
error. The unreachable Project-side service check is removed.
- Check caller-chosen names on Project file renames and folder create
and update with the same secret-provenance gate as create and upload,
including workbench history for sandbox callbacks.
- Move first-message file panel resolution into resolveFileAttachment
and replace the mock-only post test with a database-backed check of
the saved tab.
* fix(mothership): match chat tabs within the chat's workspace
- The chat resource store now keys tabs with the chat's workspace as the
fallback scope, so an unscoped tab and the same tab addressed by that
workspace merge instead of duplicating. Upsert, remove and reorder all
use the same identity.
- Project file renames and folder writes recheck cancellation after the
name check and never forward a cancelled write.
- Leave the .claude and .cursor import rules to staging, whose source
conventions check now exempts generated contract copies itself.
* fix(mothership): bound Project name checks and keep equal owners
- Parse Project file renames and folder writes with their route contracts
under the inline body limit before the name check, so an oversized body
is refused instead of buffered. Only those routes copy the request.
- Treat an equal file owner as unchanged when merging chat tabs, so a
repeated upsert stays a no-op.
* fix(project-files): harden owner hints, grep provenance, and tab identity
- Restore info/warn levels for stale or forbidden tab attachments and skip an unresolvable target instead of throwing
- Make Project owner hints best-effort so a failed lookup never fails the turn; document that a worker rollback needs projects off first
- Cache the worker file-owner protocol probe per base URL (lru-cache, 30s, success only)
- Answer an invalid copy body on an unnegotiated lease from the workspace route (v2 400) instead of a 403
- One tab-key function on server and client, keyed with the chat workspace on both sides
- Project grep withholds a file without provenance instead of failing the search or latching the registry, and stops listing once the file budget is full
- Bound copy effects: one copied file opens a tab, bulk and folder copies refresh the destination owner; org copies carry the destination workspace
- Bound list_user_projects capability fan-out
- Refuse unextractable or oversized Project text reads before download, with the text-extraction size message
- Share the create-file input mapper, the resource authoring version, and isProjectsEnabled
* fix(project-files): refuse secret-bearing raw Project downloads without a workbench tracker
* test(project-files): pin refusals and cover live owner-hint, tab-key and log-level paths
* refactor(project-files): move owner routing and admission behind the file-owner adapter
- copilot-request carries one opaque resource grant per request; the Project file
and file-copy grants are minted next to their adapters, so the shared route layer
no longer imports Project or copy policy
- One projectFileDelegationScope for the verifier, the Copilot adapter and the
request grant; admitsCopilotResourceDelegation shared by the adapter and the grant
- Private v2 transports derive route patterns from their contracts
(v2RoutePattern / isV2ContractRoute / tryMatchV2Route), including the name-write
lookup, so a renamed route can no longer skip interception silently
- Project upload and write transports share their route prologue, cancellation
check and failure envelope
- One forwarded-header strip list and one callback context for sandbox callbacks;
SandboxResourceScope is exported instead of re-derived
- isOwnerScopedFile replaces adapter field comparisons; the adapter field is
renamed invocationScope so it no longer reads like Principal.resourceScope
- authoringInvocation picks a turn's chat-or-workspace invocation in one place
* refactor(mothership): share chat tab keys, CLI session setup, and file read helpers
- chatResourceKeyFor binds the tab key to one chat's workspace for the store,
reorder, stream handler and use-chat; resource removal looks keys up in a Set
- isFileResourceType names the file/filefolder check; shared owner refinement in
the resource contracts
- prepareCliSession gives every CLI invocation its endpoint, workbench session,
file provenance and effect sink
- Text-extraction refusals, the default-visual media check and MIME
normalization are shared rather than copied
- Grep page cap and listing note are shared; a corpus states its own scope
refusal instead of the engine naming Projects
- resource-effects builds an owned file path once and shares the owner refresh
* perf(project-files): skip the folder tree for grep reads and check hint gates before the flag
- Project grep reads ask the artifact read not to load the owner's whole folder
tree per file; grep never reads file.folderPath
- File-owner hints run the route, mode and admission checks before awaiting the
projects flag
- Project text reads reuse the workspace text-extraction refusals; Project grep
uses the shared page cap and states its own scope refusal
* test(mothership): drive stale-tab and owner-hint failures through the real boundary
* test(project-files): pin upload cancellation during provenance and new-chat tab order
* fix(project-files): recheck cancellation before completing a workbench upload
Provenance resolution can outlast the invocation; completion now rechecks both
signals before it registers the file, as the create path does.
* fix(mothership): persist new-chat tabs in attachment order
Attachments resolve concurrently, so tabs were persisted in completion order.
Each authorized tab now keeps its attachment index.
* fix(mothership): store the recovery authoring marker only while Projects are on
Earlier builds parse recovery config strictly and skip recovery on an unknown
key. Only Project authoring reads the marker, so flag-off turns no longer
write it and stay recoverable across a rollback.
* fix(mothership): tag an unlabeled file selection as a bare mention
* test(project-files): give new suites their own reports and drop an unreachable adapter case
* refactor(files): return readSourceBuffer's TSDoc to its function
---------
Co-authored-by: Waleed Latif <waleed@sim.ai>
Co-authored-by: Waleed Latif <walif6@gmail.com>1 parent 84f41ea commit 99ed5fb
144 files changed
Lines changed: 9895 additions & 1121 deletions
File tree
- apps/sim
- app
- api
- copilot/chat/resources
- mothership/chats/[chatId]
- v2
- files/[fileId]/metadata
- projects/[projectId]/files
- workspace/[workspaceId]/home
- components/chat-context-kind-registry
- hooks
- stream
- executor/utils
- lib
- api
- contracts
- server/routes
- mothership
- agent-cli
- engines
- application
- auth
- chat
- application
- content-delivery
- file-owners
- generated
- request
- application
- lifecycle
- session
- tools
- resources
- tool-executor
- tools
- handlers
- registry
- server
- files
- projects
- __integration__
- application
- files
- __integration__
- api
- application
- uploads
- documents
- utils
- workspace-files
- application
- stores/panel
- packages
- sim-cli
- scripts
- src
- contract
- testing/src/mocks
- scripts
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
9 | 8 | | |
10 | 9 | | |
11 | 10 | | |
12 | 11 | | |
13 | 12 | | |
| 13 | + | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
23 | | - | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
24 | 28 | | |
25 | 29 | | |
26 | 30 | | |
| |||
53 | 57 | | |
54 | 58 | | |
55 | 59 | | |
56 | | - | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
57 | 68 | | |
58 | 69 | | |
59 | 70 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| 33 | + | |
33 | 34 | | |
34 | 35 | | |
35 | 36 | | |
| |||
107 | 108 | | |
108 | 109 | | |
109 | 110 | | |
110 | | - | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
111 | 114 | | |
112 | 115 | | |
113 | 116 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
8 | 12 | | |
9 | 13 | | |
10 | 14 | | |
11 | 15 | | |
12 | | - | |
13 | | - | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
22 | 20 | | |
23 | 21 | | |
24 | 22 | | |
| |||
30 | 28 | | |
31 | 29 | | |
32 | 30 | | |
| 31 | + | |
33 | 32 | | |
34 | 33 | | |
35 | 34 | | |
| |||
89 | 88 | | |
90 | 89 | | |
91 | 90 | | |
92 | | - | |
| 91 | + | |
93 | 92 | | |
94 | 93 | | |
95 | 94 | | |
96 | 95 | | |
97 | 96 | | |
98 | 97 | | |
99 | 98 | | |
100 | | - | |
| 99 | + | |
101 | 100 | | |
102 | 101 | | |
103 | 102 | | |
| |||
106 | 105 | | |
107 | 106 | | |
108 | 107 | | |
109 | | - | |
| 108 | + | |
110 | 109 | | |
111 | 110 | | |
112 | 111 | | |
113 | 112 | | |
114 | 113 | | |
115 | | - | |
| 114 | + | |
116 | 115 | | |
117 | 116 | | |
118 | 117 | | |
119 | 118 | | |
120 | 119 | | |
121 | 120 | | |
122 | 121 | | |
123 | | - | |
| 122 | + | |
124 | 123 | | |
125 | 124 | | |
126 | 125 | | |
127 | 126 | | |
128 | 127 | | |
129 | | - | |
| 128 | + | |
130 | 129 | | |
131 | 130 | | |
132 | 131 | | |
133 | 132 | | |
134 | 133 | | |
135 | 134 | | |
136 | 135 | | |
137 | | - | |
| 136 | + | |
138 | 137 | | |
139 | 138 | | |
140 | 139 | | |
| |||
157 | 156 | | |
158 | 157 | | |
159 | 158 | | |
160 | | - | |
| 159 | + | |
161 | 160 | | |
162 | 161 | | |
163 | 162 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
17 | | - | |
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
| |||
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
| 71 | + | |
80 | 72 | | |
81 | 73 | | |
82 | 74 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
108 | 108 | | |
109 | 109 | | |
110 | 110 | | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
111 | 115 | | |
112 | 116 | | |
113 | 117 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
467 | 467 | | |
468 | 468 | | |
469 | 469 | | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
470 | 498 | | |
471 | 499 | | |
472 | 500 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| |||
102 | 102 | | |
103 | 103 | | |
104 | 104 | | |
| 105 | + | |
105 | 106 | | |
106 | 107 | | |
107 | 108 | | |
| |||
135 | 136 | | |
136 | 137 | | |
137 | 138 | | |
138 | | - | |
139 | | - | |
140 | | - | |
| 139 | + | |
141 | 140 | | |
142 | 141 | | |
143 | 142 | | |
| |||
181 | 180 | | |
182 | 181 | | |
183 | 182 | | |
184 | | - | |
185 | | - | |
186 | | - | |
| 183 | + | |
187 | 184 | | |
188 | 185 | | |
189 | 186 | | |
| |||
257 | 254 | | |
258 | 255 | | |
259 | 256 | | |
260 | | - | |
| 257 | + | |
261 | 258 | | |
262 | 259 | | |
263 | 260 | | |
| |||
308 | 305 | | |
309 | 306 | | |
310 | 307 | | |
311 | | - | |
| 308 | + | |
312 | 309 | | |
313 | 310 | | |
314 | 311 | | |
315 | | - | |
316 | | - | |
317 | | - | |
| 312 | + | |
318 | 313 | | |
319 | 314 | | |
320 | 315 | | |
| |||
326 | 321 | | |
327 | 322 | | |
328 | 323 | | |
329 | | - | |
330 | | - | |
331 | | - | |
| 324 | + | |
332 | 325 | | |
333 | 326 | | |
334 | 327 | | |
| |||
341 | 334 | | |
342 | 335 | | |
343 | 336 | | |
344 | | - | |
345 | | - | |
346 | | - | |
347 | | - | |
348 | | - | |
349 | | - | |
350 | | - | |
351 | | - | |
| 337 | + | |
| 338 | + | |
352 | 339 | | |
353 | 340 | | |
354 | 341 | | |
| |||
0 commit comments