deploy_files #
Generated automatically from the published contract sources.
Build metadata: Registered in this build. Registration describes the default dispatcher in this build. It does not guarantee that a caller has the required credential or grant, that a tool is listed for that connection, or that the required service is configured.
A script calls this action over HTTPS at POST https://turnzero.ai/api/v1/actions/deploy_files, with a bearer credential and the action's payload as the JSON body.
Contract description #
Deploy an application's files from a tool whose shell cannot reach this platform, such as claude.ai's chat or ChatGPT and Codex in the cloud. Wherever your shell reaches the platform, call `deploy` and run its line instead; use this only where that line fails to fetch the command or to connect: a 403, `ENOTFOUND`, `ECONNREFUSED`, or a timeout.
Name the application, and the environment or none, as `deploy` takes them. First send `files`: every file of the application's folder with its `path` and `sha256`, the SHA-256 of its UTF-8 bytes, `package.json` at the root among them. The answer names under `missing` each file the platform does not hold, under `left_out` the files a deploy never carries (`node_modules`, `.git`, `.env`, and every `.env.*`), and under `warnings` the files whose names look like keys or credentials. Send each missing file in a call of its own as `file`: its `path`, its text as `content`, and its `sha256`. The call naming `files` with the last one, or after it, starts the deploy once nothing is missing and answers as `deploy` does, with `next` the `read_status` call. Send no file holding a secret value; store secrets on the signed-in site's secrets page.
Text files alone: at most 512 KiB each, 200 files, and 4 MiB in all, and a JSON, JavaScript, or TypeScript file that does not parse is refused by name. A larger application deploys with `deploy`'s line from a tool whose shell reaches the platform: Claude Code, the Codex CLI, or the desktop app's Code tab.
An answer that is not this platform's own says nothing about whether the deploy started. Read `read_status` with `wait_seconds` first, and call again only where it shows no start. The rest is on the page /cloud/reference/actions/deploy-files/, which `read_documentation` reads as `page` and the platform's origin serves.
More about this action #
The calls are stateless: each list call is whole, and no state but the kept files spans calls. A file call checks its file and keeps it under its SHA-256 in the application's deploy area, in the partition of the environment the deploy targets; where it names `sha256`, a content whose hash differs is refused `deploy_files_hash_mismatch` and nothing is kept. Where it names none, the answer's `kept` names the hash the platform computed. A path holding a segment a deploy leaves out is refused before anything is kept.
The syntax check reads a `.json` file by a JSON parse, and a `tsconfig` or `jsconfig` file with comments and trailing commas allowed, as TypeScript reads it. It reads a JavaScript or TypeScript file by a parser chosen by its extension, so it refuses no file Node or TypeScript reads. A failure is refused `deploy_files_syntax_error`, naming the path, the line, and the column. Every other text file is kept unchecked.
A list call refuses a path that is absolute or holds a backslash, an empty, `.`, or `..` segment, a path named twice, and a list with no `package.json` at the root. Where a file is missing, it first answers the refusals a deploy's start would make before it reads any zip, `deploys_per_day_exceeded` among them, so you hear them before you send a file. Where none is missing, the platform builds the turnzero command's own zip from the kept files, checks each entry again by its listed path, and starts the deploy: every refusal after that is the deploy's own, and the answer is the deploy's.
Kept files wait at least a day and at most two from when they were sent. A deploy made with the line clears them, and so does a change of the application's environment count; the next list call answers them as missing, and you send them again. The call mints no grant and answers none.
Access and action metadata #
{
"name": "deploy_files",
"resource": "environment",
"tier": "reversible",
"product": "cloud",
"summary": "Deploy an application's files from a tool whose shell cannot reach this platform, such as claude.ai's chat or ChatGPT and Codex in the cloud. Wherever your shell reaches the platform, call `deploy` and run its line instead; use this only where that line fails to fetch the command or to connect: a 403, `ENOTFOUND`, `ECONNREFUSED`, or a timeout.\n\nName the application, and the environment or none, as `deploy` takes them. First send `files`: every file of the application's folder with its `path` and `sha256`, the SHA-256 of its UTF-8 bytes, `package.json` at the root among them. The answer names under `missing` each file the platform does not hold, under `left_out` the files a deploy never carries (`node_modules`, `.git`, `.env`, and every `.env.*`), and under `warnings` the files whose names look like keys or credentials. Send each missing file in a call of its own as `file`: its `path`, its text as `content`, and its `sha256`. The call naming `files` with the last one, or after it, starts the deploy once nothing is missing and answers as `deploy` does, with `next` the `read_status` call. Send no file holding a secret value; store secrets on the signed-in site's secrets page.\n\nText files alone: at most 512 KiB each, 200 files, and 4 MiB in all, and a JSON, JavaScript, or TypeScript file that does not parse is refused by name. A larger application deploys with `deploy`'s line from a tool whose shell reaches the platform: Claude Code, the Codex CLI, or the desktop app's Code tab.\n\nAn answer that is not this platform's own says nothing about whether the deploy started. Read `read_status` with `wait_seconds` first, and call again only where it shows no start.",
"annotations": {
"readOnlyHint": false,
"destructiveHint": true,
"openWorldHint": true
}
}
MCP catalog entry #
{
"name": "deploy_files",
"title": "Deploy files",
"tier": "reversible",
"scenario": "CHI-L0-07",
"summary": "Deploy an application's files from a tool whose shell cannot reach this platform, such as claude.ai's chat or ChatGPT and Codex in the cloud. Wherever your shell reaches the platform, call `deploy` and run its line instead; use this only where that line fails to fetch the command or to connect: a 403, `ENOTFOUND`, `ECONNREFUSED`, or a timeout.\n\nName the application, and the environment or none, as `deploy` takes them. First send `files`: every file of the application's folder with its `path` and `sha256`, the SHA-256 of its UTF-8 bytes, `package.json` at the root among them. The answer names under `missing` each file the platform does not hold, under `left_out` the files a deploy never carries (`node_modules`, `.git`, `.env`, and every `.env.*`), and under `warnings` the files whose names look like keys or credentials. Send each missing file in a call of its own as `file`: its `path`, its text as `content`, and its `sha256`. The call naming `files` with the last one, or after it, starts the deploy once nothing is missing and answers as `deploy` does, with `next` the `read_status` call. Send no file holding a secret value; store secrets on the signed-in site's secrets page.\n\nText files alone: at most 512 KiB each, 200 files, and 4 MiB in all, and a JSON, JavaScript, or TypeScript file that does not parse is refused by name. A larger application deploys with `deploy`'s line from a tool whose shell reaches the platform: Claude Code, the Codex CLI, or the desktop app's Code tab.\n\nAn answer that is not this platform's own says nothing about whether the deploy started. Read `read_status` with `wait_seconds` first, and call again only where it shows no start. The rest is on the page /cloud/reference/actions/deploy-files/, which `read_documentation` reads as `page` and the platform's origin serves.",
"owners": [
"API-L0-25",
"MAPI-04",
"MAPI-26",
"OST-L0-01",
"OST-L0-03",
"OST-L0-05",
"PLD-L0-63",
"PLD-L0-86",
"PLD-L0-94",
"PLD-L0-96"
]
}
request #
| JSON pointer | Description and constraints |
|---|---|
| "" (root) | Type: object Required fields: ["application"] |
| / |
The application id, from `list_applications`. Type: string |
| / |
As `deploy` reads it: absent, the application's deploy target, production with one environment and development with two. Type: string Allowed values: ["development","production"] |
| / |
Every file of the application's folder, `package.json` at the root among them. The answer names what is `missing`; where nothing is, the call starts the deploy. Type: array Maximum items: 200 |
| / |
Type: object Required fields: ["path","sha256"] Additional properties: false |
| / |
The file's path relative to the application's folder, `/` between segments. Type: string Minimum length: 1 Maximum length: 1024 |
| / |
The SHA-256 of the file's UTF-8 bytes, 64 lower-case hexadecimal characters. Type: string Pattern: ^[0-9a-f]{64}$ |
| / |
One missing file, kept before `files` is read. Type: object Required fields: ["path","content"] Additional properties: false |
| / |
The file's path relative to the application's folder, `/` between segments. Type: string Minimum length: 1 Maximum length: 1024 |
| / |
The file's text, at most 512 KiB as UTF-8. Type: string |
| / |
Optional: the SHA-256 of `content`'s UTF-8 bytes; a mismatch keeps nothing. Type: string Pattern: ^[0-9a-f]{64}$ |
| / |
On the call that starts the deploy: the seconds, 1 to 45, the answer is held until the version-history row it starts ends, counted from the call's arrival. A value outside that range is refused `invalid_request`, its detail naming 45 as the bound. The bound keeps the answer inside the sixty seconds many tools give one call; where yours gives less, name fewer seconds, there and on the `next` call the answer names. Type: integer Minimum: 1 Maximum: 45 |
response #
| JSON pointer | Description and constraints |
|---|---|
| "" (root) | 200 with `file_kept` or `awaiting_files` where the call started nothing; where a list call leaves nothing missing, the deploy's own answer, 202 at once with `deploying`, or 200 where `wait_seconds` saw it end. No call mints or answers a grant. Type: object Required fields: ["contract_version","application","environment","state"] |
| / |
Required value: 1 |
| / |
The short reference the platform recorded this call under, ten lowercase hexadecimal characters, the value the call’s record row carries; quote it when reporting the call. Type: string Pattern: ^[0-9a-f]{10}$ |
| / |
On a call that started the deploy, the deploy's own summary. Type: string |
| / |
Type: string |
| / |
Type: string |
| / |
The version number the deploy started: answered with `deploying`, `deployed`, and `failed`. Type: integer |
| / |
`file_kept` on a call carrying `file` alone, `awaiting_files` on a list call while a file is missing, each 200; otherwise the deploy's own state, `deploying` on the 202 answer and `deployed` or `failed` where `wait_seconds` saw the deploy end. Type: string Pattern: ^(file_kept|awaiting_files|deploying|deployed|failed)$ |
| / |
The hostname of the environment the deploy goes to, where the call started it. Type: string |
| / |
The recorded manifest's health path the deploy's gate will probe, cut at 256 characters, where the call started it. Type: string |
| / |
Present where the call started the deploy and carried `wait_seconds`, as `deploy` answers it. Type: boolean |
| / |
Present where the call started the deploy and carried `wait_seconds`. Type: integer Minimum: 0 |
| / |
Present where the wait settled: the row's `outcome` as `list_versions` answers it. Type: object |
| / |
The file this call kept, its path and the SHA-256 the platform computed of its content. Type: object Required fields: ["path","sha256"] Additional properties: false |
| / |
Type: string |
| / |
Type: string Pattern: ^[0-9a-f]{64}$ |
| / |
With `awaiting_files`: each listed file the platform does not hold, to send as `file`. Type: array |
| / |
Type: object Required fields: ["path","sha256"] Additional properties: false |
| / |
Type: string |
| / |
Type: string Pattern: ^[0-9a-f]{64}$ |
| / |
On a list call: the listed paths a deploy never carries (`node_modules`, `.git`, `.env`, and every `.env.*`), never asked for. Type: array |
| / |
Type: string |
| / |
On a list call: the listed paths whose names look like keys or credentials; send one only where it holds no secret value. Type: array |
| / |
Type: string |
| / |
Where the call started the deploy: the exact `read_status` call that reads it to its end. Type: object Required fields: ["action","arguments"] Additional properties: false |
| / |
Required value: read_status |
| / |
Type: object Required fields: ["application","environment","wait_seconds"] Additional properties: false |
| / |
Type: string |
| / |
Type: string Pattern: ^(development|production)$ |
| / |
Type: integer Minimum: 1 Maximum: 45 |
| / |
With `file_kept` and `awaiting_files`, what to send next; where the call started the deploy, the deploy's own detail. Type: string |
| / |
present where the zip's manifest.json, less its application member, differs or does not parse, or a lib/ copy is unread, uncompared, or unpaired. Type: string |
| / |
present where the build will not run an install script or rebuild a binding.gyp of the root or a workspace member, naming each and each member package.json left unread. Type: string |
| / |
present while the application's usage state is over, absent otherwise, as `deploy` answers it. Type: string |
Complete payload contract #
{
"request": {
"type": "object",
"required": [
"application"
],
"properties": {
"application": {
"type": "string",
"description": "The application id, from `list_applications`."
},
"environment": {
"type": "string",
"enum": [
"development",
"production"
],
"description": "As `deploy` reads it: absent, the application's deploy target, production with one environment and development with two."
},
"files": {
"type": "array",
"maxItems": 200,
"items": {
"type": "object",
"required": [
"path",
"sha256"
],
"properties": {
"path": {
"type": "string",
"minLength": 1,
"maxLength": 1024,
"description": "The file's path relative to the application's folder, `/` between segments."
},
"sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$",
"description": "The SHA-256 of the file's UTF-8 bytes, 64 lower-case hexadecimal characters."
}
},
"additionalProperties": false
},
"description": "Every file of the application's folder, `package.json` at the root among them. The answer names what is `missing`; where nothing is, the call starts the deploy."
},
"file": {
"type": "object",
"required": [
"path",
"content"
],
"properties": {
"path": {
"type": "string",
"minLength": 1,
"maxLength": 1024,
"description": "The file's path relative to the application's folder, `/` between segments."
},
"content": {
"type": "string",
"description": "The file's text, at most 512 KiB as UTF-8."
},
"sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$",
"description": "Optional: the SHA-256 of `content`'s UTF-8 bytes; a mismatch keeps nothing."
}
},
"additionalProperties": false,
"description": "One missing file, kept before `files` is read."
},
"wait_seconds": {
"type": "integer",
"minimum": 1,
"maximum": 45,
"description": "On the call that starts the deploy: the seconds, 1 to 45, the answer is held until the version-history row it starts ends, counted from the call's arrival. A value outside that range is refused `invalid_request`, its detail naming 45 as the bound. The bound keeps the answer inside the sixty seconds many tools give one call; where yours gives less, name fewer seconds, there and on the `next` call the answer names."
}
}
},
"response": {
"type": "object",
"required": [
"contract_version",
"application",
"environment",
"state"
],
"properties": {
"contract_version": {
"const": 1
},
"reference": {
"type": "string",
"pattern": "^[0-9a-f]{10}$",
"description": "The short reference the platform recorded this call under, ten lowercase hexadecimal characters, the value the call’s record row carries; quote it when reporting the call."
},
"summary": {
"type": "string",
"description": "On a call that started the deploy, the deploy's own summary (PLD-L0-63)."
},
"application": {
"type": "string"
},
"environment": {
"type": "string"
},
"version": {
"type": "integer",
"description": "The version number the deploy started: answered with `deploying`, `deployed`, and `failed`."
},
"state": {
"type": "string",
"pattern": "^(file_kept|awaiting_files|deploying|deployed|failed)$",
"description": "`file_kept` on a call carrying `file` alone, `awaiting_files` on a list call while a file is missing, each 200; otherwise the deploy's own state, `deploying` on the 202 answer and `deployed` or `failed` where `wait_seconds` saw the deploy end."
},
"hostname": {
"type": "string",
"description": "The hostname of the environment the deploy goes to, where the call started it."
},
"health_path": {
"type": "string",
"description": "The recorded manifest's health path the deploy's gate will probe, cut at 256 characters, where the call started it."
},
"settled": {
"type": "boolean",
"description": "Present where the call started the deploy and carried `wait_seconds`, as `deploy` answers it."
},
"waited_ms": {
"type": "integer",
"minimum": 0,
"description": "Present where the call started the deploy and carried `wait_seconds`."
},
"outcome": {
"type": "object",
"description": "Present where the wait settled: the row's `outcome` as `list_versions` answers it."
},
"kept": {
"type": "object",
"required": [
"path",
"sha256"
],
"properties": {
"path": {
"type": "string"
},
"sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
},
"additionalProperties": false,
"description": "The file this call kept, its path and the SHA-256 the platform computed of its content."
},
"missing": {
"type": "array",
"items": {
"type": "object",
"required": [
"path",
"sha256"
],
"properties": {
"path": {
"type": "string"
},
"sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
},
"additionalProperties": false
},
"description": "With `awaiting_files`: each listed file the platform does not hold, to send as `file`."
},
"left_out": {
"type": "array",
"items": {
"type": "string"
},
"description": "On a list call: the listed paths a deploy never carries (`node_modules`, `.git`, `.env`, and every `.env.*`), never asked for."
},
"warnings": {
"type": "array",
"items": {
"type": "string"
},
"description": "On a list call: the listed paths whose names look like keys or credentials; send one only where it holds no secret value."
},
"next": {
"type": "object",
"required": [
"action",
"arguments"
],
"properties": {
"action": {
"const": "read_status"
},
"arguments": {
"type": "object",
"required": [
"application",
"environment",
"wait_seconds"
],
"properties": {
"application": {
"type": "string"
},
"environment": {
"type": "string",
"pattern": "^(development|production)$"
},
"wait_seconds": {
"type": "integer",
"minimum": 1,
"maximum": 45
}
},
"additionalProperties": false
}
},
"additionalProperties": false,
"description": "Where the call started the deploy: the exact `read_status` call that reads it to its end."
},
"detail": {
"type": "string",
"description": "With `file_kept` and `awaiting_files`, what to send next; where the call started the deploy, the deploy's own detail."
},
"manifest_notice": {
"type": "string",
"description": "present where the zip's manifest.json, less its application member, differs or does not parse, or a lib/ copy is unread, uncompared, or unpaired (PLD-L0-63)."
},
"artifact_notice": {
"type": "string",
"description": "present where the build will not run an install script or rebuild a binding.gyp of the root or a workspace member, naming each and each member package.json left unread (PLD-L0-60)."
},
"usage_notice": {
"type": "string",
"description": "present while the application's usage state is over, absent otherwise, as `deploy` answers it (ACB-L0-26)."
}
},
"description": "200 with `file_kept` or `awaiting_files` where the call started nothing; where a list call leaves nothing missing, the deploy's own answer, 202 at once with `deploying`, or 200 where `wait_seconds` saw it end. No call mints or answers a grant."
}
}
Shared contracts #
- Refusals: every refusal, by surface, with its cause and its remedy
- schemas/wire_error.schema.json
- schemas/wire_errors.json
- schemas/action_payloads.json (includes shared shapes)
- management_api_contract.md