listAppFiles
List the source files of a Sasha App you manage
List every source file in the app package with its byte size and version, plus the package status. The result carries status: when status.ok is false the app is NOT usable until the listed diagnostics are fixed. Each names the package file, the line when known, the error code and a reason token. Fix the file and check again; the app is live as soon as it validates.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
app | string | required | The app id (lowercase kebab-case), as shown by open_app__<id> or listAppFiles. |
Scopes
apps:invoke, apps:write
Annotations
- Read only: yes
- Destructive: no
When to use
Call listAppFiles before you change a Sasha App. It shows the files in the app package and tells you whether the app validates now.
The six app source tools (listAppFiles, readAppFile, writeAppFile, editAppFile, deleteAppFile and checkApp) all need three things:
- The connection holds both
apps:invokeandapps:write. Only admin and staff can holdapps:write, so a member's connection never has these tools. - The person who connected is an admin or staff user.
- That person has
manageaccess on the app. When Sasha first finds an app, it givesmanageto each admin and staff user who exists at that moment. A user added later needs a grant. An admin can narrow a grant later.
The app argument is the app id in lowercase kebab-case, for example timesheet or expense-claims. The app's opener tool uses the same id with _ for -: the app expense-claims opens with open_app__expense_claims. The source tools take the id, not a tool name. An app that breaks after Sasha has seen it loses its opener tool, but the source tools still work on it, so you can use them to repair the app. A package that has never validated has no access grants yet, so it answers APP_ACCESS_DENIED.
The result has these fields:
fileslists each regular file in the package, sorted by path, withpath,bytes,versionandeditable. Files and folders whose name starts with.are not listed, and neither are symbolic links or paths with more than four segments.versionis a 64-character hex value for the exact bytes of the file. Pass it asexpectedVersiontowriteAppFile,editAppFileordeleteAppFile. It isnullonly for a file larger than 1 MiB.editableisfalsefor a file that the write tools refuse, for example a file type that is not allowed or a file larger than 1 MiB.status.okistruewhen the app validates. Thenstatus.revisionis the live revision.- When
status.okisfalse, the app cannot be used until you fix each entry instatus.diagnostics. Each entry hasfile,linewhen it is known,codeandreason.status.revisioncan benull.
The text part of the result lists the same files, one per line, and ends with a sentence that says whether the app validates.
Example
{ "app": "timesheet" }
The structured result (structuredContent):
{
"app": "timesheet",
"files": [
{ "path": "APP.md", "bytes": 912, "version": "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", "editable": true },
{ "path": "actions/log-hours.action.yaml", "bytes": 640, "version": "3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d", "editable": true },
{ "path": "app.js", "bytes": 4210, "version": "2e7d2c03a9507ae265ecf5b5356885a53393a2029d241394997265a1a25aefc6", "editable": true },
{ "path": "index.html", "bytes": 1388, "version": "18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", "editable": true },
{ "path": "migrations/001-create-entries.sql", "bytes": 199, "version": "3f79bb7b435b05321651daefd374cdc681dc06faa65e374e38337b88ca046dea", "editable": true },
{ "path": "schema.sql", "bytes": 199, "version": "3f79bb7b435b05321651daefd374cdc681dc06faa65e374e38337b88ca046dea", "editable": true }
],
"status": {
"ok": true,
"revision": "252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111",
"diagnostics": []
}
}
Refusals and what to do
An app source tool refuses with an error result. The text is the error message, and structuredContent.error holds code, message, retryable and a diagnosticId to quote when you report a problem.
APP_ACCESS_DENIED(app_access_denied): this person does not havemanageaccess on the app (useaccess is not enough), or is not an admin or staff user. An app id that does not exist gets the same answer. Check the id with the app'sopen_app__<app>tool name, or ask an admin formanageaccess.APP_INPUT_INVALID(app_input_invalid): the arguments do not match the schema, for example anappthat is not lowercase kebab-case or an extra argument. Send onlyapp.APP_NOT_READY(app_not_ready): the app source service is not available on this instance. Report it withsuggestImprovement.- If the connection does not hold both
apps:invokeandapps:write, the tool is not in your tool list, and a call to it returnsMCP error -32602: Tool listAppFiles not found. Read thepermissionssection ofgetDocs. A scope is never added to an existing connection: the person must reconnect, or mint a new token, withapps:write. Only admin and staff can hold it. - A
status.okoffalseis not a refusal. It describes the package. Read the diagnostics, fix the named file, then callcheckApp.
Related
readAppFilereads one file and returns itsversion.writeAppFile,editAppFileanddeleteAppFilechange files.checkAppvalidates the package again.- The
open-appfamily opens the app. getDocshas anapps-authoringsection with the full authoring loop.