{
 "components": {
  "schemas": {
   "Body_drop_api_fs_drop_post": {
    "properties": {
     "files": {
      "items": {
       "contentMediaType": "application/octet-stream",
       "type": "string"
      },
      "title": "Files",
      "type": "array"
     },
     "sequence": {
      "default": "",
      "title": "Sequence",
      "type": "string"
     }
    },
    "required": [
     "files"
    ],
    "title": "Body_drop_api_fs_drop_post",
    "type": "object"
   },
   "Body_upload_api_fs_upload_post": {
    "properties": {
     "files": {
      "items": {
       "contentMediaType": "application/octet-stream",
       "type": "string"
      },
      "title": "Files",
      "type": "array"
     },
     "path": {
      "title": "Path",
      "type": "string"
     },
     "sequence": {
      "default": "",
      "title": "Sequence",
      "type": "string"
     }
    },
    "required": [
     "path",
     "files"
    ],
    "title": "Body_upload_api_fs_upload_post",
    "type": "object"
   },
   "DeleteBody": {
    "properties": {
     "path": {
      "title": "Path",
      "type": "string"
     },
     "recursive": {
      "default": false,
      "title": "Recursive",
      "type": "boolean"
     }
    },
    "required": [
     "path"
    ],
    "title": "DeleteBody",
    "type": "object"
   },
   "DestBody": {
    "properties": {
     "dest": {
      "title": "Dest",
      "type": "string"
     },
     "path": {
      "title": "Path",
      "type": "string"
     }
    },
    "required": [
     "path",
     "dest"
    ],
    "title": "DestBody",
    "type": "object"
   },
   "HTTPValidationError": {
    "properties": {
     "detail": {
      "items": {
       "$ref": "#/components/schemas/ValidationError"
      },
      "title": "Detail",
      "type": "array"
     }
    },
    "title": "HTTPValidationError",
    "type": "object"
   },
   "LocateBody": {
    "properties": {
     "base": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Base"
     },
     "paths": {
      "items": {
       "type": "string"
      },
      "title": "Paths",
      "type": "array"
     },
     "session": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Session"
     }
    },
    "required": [
     "paths"
    ],
    "title": "LocateBody",
    "type": "object"
   },
   "NameBody": {
    "properties": {
     "name": {
      "title": "Name",
      "type": "string"
     },
     "path": {
      "title": "Path",
      "type": "string"
     }
    },
    "required": [
     "path",
     "name"
    ],
    "title": "NameBody",
    "type": "object"
   },
   "ValidationError": {
    "properties": {
     "ctx": {
      "title": "Context",
      "type": "object"
     },
     "input": {
      "title": "Input"
     },
     "loc": {
      "items": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "integer"
        }
       ]
      },
      "title": "Location",
      "type": "array"
     },
     "msg": {
      "title": "Message",
      "type": "string"
     },
     "type": {
      "title": "Error Type",
      "type": "string"
     }
    },
    "required": [
     "loc",
     "msg",
     "type"
    ],
    "title": "ValidationError",
    "type": "object"
   },
   "WriteBody": {
    "properties": {
     "append": {
      "default": false,
      "title": "Append",
      "type": "boolean"
     },
     "content": {
      "title": "Content",
      "type": "string"
     },
     "mtime": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Mtime"
     },
     "path": {
      "title": "Path",
      "type": "string"
     }
    },
    "required": [
     "path",
     "content"
    ],
    "title": "WriteBody",
    "type": "object"
   }
  }
 },
 "info": {
  "contact": {
   "name": "Argus",
   "url": "https://github.com/andreaderuvo/argus"
  },
  "description": "\nEverything Argus does, it does through this API \u2014 the browser is one client of it, not a\nprivileged one. That is the whole extension story: a script, a cron job, an agent hook or\nanother machine can do anything the app can, with no plugin to install and nothing running\ninside the page.\n\n**Every route is behind the same token**, in an `Authorization: Bearer \u2026` header or a\n`?token=` query for the places a header cannot go \u2014 a WebSocket, an `<img>`, a page opened\ndirectly. Anyone holding it can run anything you can: treat it like an SSH key.\n\n**Everything lives under `/api`.** Nothing outside it answers with data, this document\nincluded, so a single rule guards the lot.\n\nThe most useful thing to build against first is `POST /api/bell` \u2014 that is how an agent\ntells you it has finished or wants you, and it needs nothing but curl.\n",
  "license": {
   "name": "MIT",
   "url": "https://github.com/andreaderuvo/argus/blob/master/LICENSE"
  },
  "summary": "Watch your agents run in tmux, and read what they produced.",
  "title": "Argus",
  "version": "0.1.0"
 },
 "openapi": "3.1.0",
 "paths": {
  "/api/ask": {
   "post": {
    "description": "Put a question in front of whoever is holding the phone, and wait.\n\n`options` turns the answer into taps: two or three words, and answering costs no typing at\nall. Without them there is a box, which is right for \"what should I call it\" and wrong for\n\"shall I overwrite it\" \u2014 and the difference between those two is most of why this exists.\n\nThe wait is bounded and the question is not: when `wait` runs out the answer is simply not\nthere yet, and the same id can be waited on again. An agent that would rather not sit\nthere can pass `wait=0`, ask, get on with something else and come back.",
    "operationId": "postApiAsk",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Ask Api Ask Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Ask the person a question, and wait for the answer",
    "tags": [
     "Notifications"
    ]
   }
  },
  "/api/ask/{ident}": {
   "get": {
    "description": "Come back for an answer that was not there yet. Same question, same id.",
    "operationId": "getApiAskIdent",
    "parameters": [
     {
      "in": "path",
      "name": "ident",
      "required": true,
      "schema": {
       "title": "Ident",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "wait",
      "required": false,
      "schema": {
       "default": 0,
       "title": "Wait",
       "type": "number"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response One Api Ask  Ident  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Wait for an answer, or read one",
    "tags": [
     "Notifications"
    ]
   }
  },
  "/api/ask/{ident}/answer": {
   "post": {
    "description": "The tap, or the sentence.\n\nDeliberately not something an agent key can reach. The whole value of a question is that a\nperson answered it; an agent that could answer its own \u2014 or another's \u2014 would turn this\ninto a slower way of deciding by itself.",
    "operationId": "postApiAskIdentAnswer",
    "parameters": [
     {
      "in": "path",
      "name": "ident",
      "required": true,
      "schema": {
       "title": "Ident",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Answer Api Ask  Ident  Answer Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Answer one",
    "tags": [
     "Notifications"
    ]
   }
  },
  "/api/asks": {
   "get": {
    "description": "What is waiting on a person, oldest first \u2014 the order they should be answered in.",
    "operationId": "getApiAsks",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Listing Api Asks Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Questions waiting for an answer",
    "tags": [
     "Notifications"
    ]
   }
  },
  "/api/bell": {
   "post": {
    "description": "Called by an agent hook, or by anything else that knows it has finished.",
    "operationId": "postApiBell",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Ring Api Bell Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Ring: something finished, or wants you",
    "tags": [
     "Notifications"
    ]
   }
  },
  "/api/bell/wiring": {
   "get": {
    "description": "Which agents on this machine are set up to ring, and which are not.",
    "operationId": "getApiBellWiring",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Wired Api Bell Wiring Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Which agents on this machine are set up to ring",
    "tags": [
     "Notifications"
    ]
   },
   "post": {
    "description": "Do the setting up, or take it back out.\n\nThis writes into the agents' own configuration files, which is exactly the work the\nperson would otherwise be doing by hand \u2014 and it is additive: an event they have\nalready claimed is reported, never overwritten, and a copy of each file as it was\nbefore Argus first touched it is kept beside it.",
    "operationId": "postApiBellWiring",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Rewire Api Bell Wiring Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set the agents up to ring, or undo it",
    "tags": [
     "Notifications"
    ]
   }
  },
  "/api/bells": {
   "get": {
    "description": "Everything rung after `since`.\n\nThe answer always carries the current sequence, so a browser that has just started \u2014\nor one that was away long enough for the list to roll over \u2014 can mark where \"now\" is\nand catch up from there rather than replaying a morning's worth of notifications.\n\nDeciding *that* is the browser's job, not this one's. An earlier version tried to help\nby treating `since=0` as \"you have just arrived, here is nothing\", and it meant a\nserver that had not rung yet handed out `seq: 0`, took `since=0` back for ever after,\nand stayed silent for the life of the page.",
    "operationId": "getApiBells",
    "parameters": [
     {
      "in": "query",
      "name": "since",
      "required": false,
      "schema": {
       "default": 0,
       "title": "Since",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Since Api Bells Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "What has rung since a given point",
    "tags": [
     "Notifications"
    ]
   }
  },
  "/api/bells/stream": {
   "get": {
    "description": "Bells as they happen, over one connection that stays open.\n\nThis is what makes a background tab work. It also needs no HTTPS, unlike the\nbrowser's own notifications \u2014 the sound and the tab title are what is left over\nplain http, and both want to happen the moment it rings rather than a minute later.",
    "operationId": "getApiBellsStream",
    "parameters": [
     {
      "in": "query",
      "name": "since",
      "required": false,
      "schema": {
       "default": 0,
       "title": "Since",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Bells as they happen, over one open connection",
    "tags": [
     "Notifications"
    ]
   }
  },
  "/api/config": {
   "get": {
    "operationId": "getApiConfig",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Server Info Api Config Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "What this server allows",
    "tags": [
     "Setup"
    ]
   }
  },
  "/api/devices": {
   "get": {
    "description": "Names, when each was added and when each was last used. Never the tokens: only a\nhash of those is kept, and the plain form existed once, when it was created.",
    "operationId": "getApiDevices",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "additionalProperties": true,
          "type": "object"
         },
         "title": "Response List Devices Api Devices Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "The devices that may get in",
    "tags": [
     "Setup"
    ]
   },
   "post": {
    "description": "Mints one and returns it **once**. There is no way to see it again \u2014 the file holds\nonly a hash \u2014 which is the same bargain GitHub makes for a personal access token, and\nfor the same reason.\n\nOnly the token in the config may do this. A device cannot mint another, so a phone\nthat is lost cannot be used to grow its own foothold.",
    "operationId": "postApiDevices",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Add Device Api Devices Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Give a device its own token",
    "tags": [
     "Setup"
    ]
   }
  },
  "/api/devices/{device_id}": {
   "delete": {
    "description": "Takes effect on the next request that device makes: the file is re-read every time\na token is presented, precisely so that revoking is not something you have to restart\nfor.",
    "operationId": "deleteApiDevicesDeviceId",
    "parameters": [
     {
      "in": "path",
      "name": "device_id",
      "required": true,
      "schema": {
       "title": "Device Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Drop Device Api Devices  Device Id  Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Take a device's token back",
    "tags": [
     "Setup"
    ]
   },
   "post": {
    "description": "The token is untouched: this is the label, not the key. Renaming does not sign\nanything out, which is the whole reason it is a separate action from revoking.",
    "operationId": "postApiDevicesDeviceId",
    "parameters": [
     {
      "in": "path",
      "name": "device_id",
      "required": true,
      "schema": {
       "title": "Device Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Rename Device Api Devices  Device Id  Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Rename a device",
    "tags": [
     "Setup"
    ]
   }
  },
  "/api/download": {
   "get": {
    "operationId": "getApiDownload",
    "parameters": [
     {
      "in": "query",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Download a file under its own name",
    "tags": [
     "Files"
    ]
   }
  },
  "/api/drops/keep": {
   "post": {
    "description": "Set `drop_keep_days`, write it to the config, and sweep straight away.\n\nA setting rather than a button, and one of the very few the browser may change: it\ndecides that files get deleted, so it belongs in the file everybody reads to find out\nwhat this server does, next to `drop_dir` \u2014 not in the preferences, which are the\nbrowser's own memory and are not where anybody would look for \"why did my file go\".\n\nOnly one key is written, and only this one. The config is a document people edit by\nhand and comment; re-dumping it to change a number would quietly erase what they\nwrote, so the line is replaced in place.",
    "operationId": "postApiDropsKeep",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Set Drops Keep Api Drops Keep Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "How long a dropped file is kept",
    "tags": [
     "Writing"
    ]
   }
  },
  "/api/favourites": {
   "get": {
    "operationId": "getApiFavourites",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Favourites Api Favourites Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Pinned folders, kept on the server",
    "tags": [
     "Files"
    ]
   },
   "post": {
    "description": "Pinning is jailed; unpinning is not, and the difference is the whole of this.\n\nA favourite is a folder somebody kept. Folders get renamed, moved and deleted, and the\npin outlives them \u2014 which is fine, it goes grey and says so. What was not fine is that\nremoving it went through the jail too, and the jail refuses a path that is not there.\nSo the one favourite you certainly want gone was the one that could not be removed.\nReported exactly that way.\n\nTaking something *off* a list needs no path on disk: the entry was jailed on the way\nin, so matching the stored string is enough and nothing can be smuggled by it. Putting\none *on* still resolves strictly \u2014 you cannot bookmark your way out, and a typo should\nnot become a favourite.",
    "operationId": "postApiFavourites",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Toggle Favourite Api Favourites Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Pin or unpin a folder",
    "tags": [
     "Files"
    ]
   }
  },
  "/api/file": {
   "get": {
    "operationId": "getApiFile",
    "parameters": [
     {
      "in": "query",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "raw",
      "required": false,
      "schema": {
       "default": false,
       "title": "Raw",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read a file, or its tail if it is large",
    "tags": [
     "Files"
    ]
   }
  },
  "/api/files": {
   "get": {
    "operationId": "getApiFiles",
    "parameters": [
     {
      "in": "query",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "additionalProperties": true,
          "type": "object"
         },
         "title": "Response List Dir Api Files Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List a folder",
    "tags": [
     "Files"
    ]
   }
  },
  "/api/fs/copy": {
   "post": {
    "operationId": "postApiFsCopy",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DestBody"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Copy Api Fs Copy Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Copy",
    "tags": [
     "Writing"
    ]
   }
  },
  "/api/fs/delete": {
   "post": {
    "operationId": "postApiFsDelete",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DeleteBody"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Delete Api Fs Delete Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete",
    "tags": [
     "Writing"
    ]
   }
  },
  "/api/fs/drop": {
   "post": {
    "description": "Receive files dropped onto a session.\n\nA terminal is not a folder, so a file dropped on one has to land somewhere the sender\ndid not choose \u2014 and the same somewhere every time, or the absolute path it is handed\nback means nothing the next day. That place is `drop_dir` in the config, and it is\nnamed here rather than by the client precisely because nobody was looking at a folder\nwhen they let go of the file.\n\nCreated the first time something is dropped and never before: a machine where this is\nnot used does not grow a directory for it.",
    "operationId": "postApiFsDrop",
    "requestBody": {
     "content": {
      "multipart/form-data": {
       "schema": {
        "$ref": "#/components/schemas/Body_drop_api_fs_drop_post"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Drop Api Fs Drop Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Put a file where drops land, and say where that is",
    "tags": [
     "Writing"
    ]
   }
  },
  "/api/fs/fetch": {
   "post": {
    "description": "Download a URL straight into a directory.\n\nThe upload you would otherwise do in three moves \u2014 open a terminal, `wget`, come back \u2014 or\nin four, if the file is on the far side of the machine you are holding: download it to a\nphone and upload it again. A link is the whole instruction.\n\nThe same care as an upload, because it is one: streamed to a dotted part-file and renamed\ninto place only when it is complete, so an interrupted download never leaves a truncated\nfile wearing the real name. Nothing is ever overwritten; a name already taken gets a number.\n\n**On the obvious objection.** Yes, this makes the server fetch a URL somebody else chose,\nand yes, that URL could be `169.254.169.254` or a service on loopback. It grants nothing:\nwhoever can call this can already open a terminal here and run `curl`, because that is what\nArgus *is*. It is behind `--allow-write` like every other route that puts something on the\ndisk, and it is worth knowing rather than worth hiding.",
    "operationId": "postApiFsFetch",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Fetch Link Api Fs Fetch Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Put a link's file into a folder, without a round trip",
    "tags": [
     "Writing"
    ]
   }
  },
  "/api/fs/locate": {
   "post": {
    "description": "Which of these words are files? Read-only, and jailed like everything else.",
    "operationId": "postApiFsLocate",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LocateBody"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Locate Api Fs Locate Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Locate",
    "tags": [
     "Prompts"
    ]
   }
  },
  "/api/fs/mkdir": {
   "post": {
    "operationId": "postApiFsMkdir",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/NameBody"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Mkdir Api Fs Mkdir Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Mkdir",
    "tags": [
     "Writing"
    ]
   }
  },
  "/api/fs/move": {
   "post": {
    "operationId": "postApiFsMove",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DestBody"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Move Api Fs Move Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Move",
    "tags": [
     "Writing"
    ]
   }
  },
  "/api/fs/rename": {
   "post": {
    "operationId": "postApiFsRename",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/NameBody"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Rename Api Fs Rename Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Rename",
    "tags": [
     "Writing"
    ]
   }
  },
  "/api/fs/upload": {
   "post": {
    "description": "Receive files into a directory.\n\nEach one is streamed to a dotted part-file and renamed into place only once it is\ncomplete, so an interrupted upload never leaves a truncated file wearing the real\nname \u2014 which for a 40 GB fastq is the difference between \"retry\" and \"silent\ncorruption three steps down the pipeline\".",
    "operationId": "postApiFsUpload",
    "requestBody": {
     "content": {
      "multipart/form-data": {
       "schema": {
        "$ref": "#/components/schemas/Body_upload_api_fs_upload_post"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Upload Api Fs Upload Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Upload",
    "tags": [
     "Writing"
    ]
   }
  },
  "/api/fs/usage": {
   "get": {
    "description": "What a folder actually weighs, added up by hand.\n\nApparent size, the sum of the file sizes \u2014 the number that matches what you see in a\nlisting, rather than the blocks on disk, which sparse files and compression make a\ndifferent question.",
    "operationId": "getApiFsUsage",
    "parameters": [
     {
      "in": "query",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Usage Api Fs Usage Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "What a folder weighs, walked on request",
    "tags": [
     "Files"
    ]
   }
  },
  "/api/fs/write": {
   "post": {
    "description": "Save an edited text file.\n\nTwo things must hold. The file cannot have moved on since it was read \u2014 otherwise a\nphone would quietly undo whatever the running job just wrote \u2014 and a file too large\nto have been previewed whole must never be saved from a preview, because that\npreview was only its tail.",
    "operationId": "postApiFsWrite",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/WriteBody"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Write Api Fs Write Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Write",
    "tags": [
     "Writing"
    ]
   }
  },
  "/api/git/worktree": {
   "delete": {
    "operationId": "deleteApiGitWorktree",
    "parameters": [
     {
      "in": "query",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "force",
      "required": false,
      "schema": {
       "default": false,
       "title": "Force",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Drop Worktree Api Git Worktree Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Remove a working directory",
    "tags": [
     "Sessions"
    ]
   },
   "post": {
    "description": "A second checkout of the same repository, on its own branch.\n\nWriting, so it needs `--allow-write`: it makes a directory, and one that git will go\non believing in until somebody removes it properly.",
    "operationId": "postApiGitWorktree",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Add Worktree Api Git Worktree Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Add a working directory on its own branch",
    "tags": [
     "Sessions"
    ]
   }
  },
  "/api/git/worktrees": {
   "get": {
    "operationId": "getApiGitWorktrees",
    "parameters": [
     {
      "in": "query",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Worktrees Api Git Worktrees Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "The working directories of a repository",
    "tags": [
     "Sessions"
    ]
   }
  },
  "/api/journal": {
   "delete": {
    "description": "Everything, or everything before a cutoff given in seconds.\n\nThe deletion is recorded like any other change \u2014 the middleware sees this request and\nwrites it down \u2014 so the journal always says that it was emptied, when, and from where.",
    "operationId": "deleteApiJournal",
    "parameters": [
     {
      "in": "query",
      "name": "older_than",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Older Than"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Clear Journal Api Journal Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Empty the journal, or the old part of it",
    "tags": [
     "Setup"
    ]
   },
   "get": {
    "description": "Most recent first. Only the token from the config may read it: a record that a\npossibly-stolen device can read is a record that tells whoever took it what you can see.",
    "operationId": "getApiJournal",
    "parameters": [
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 200,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Read Journal Api Journal Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "What has been done here, and what was refused",
    "tags": [
     "Setup"
    ]
   }
  },
  "/api/language": {
   "post": {
    "description": "Anyone can translate the catalogue and add it here; it is a flat JSON object\nkeyed by the English strings, so it needs no tooling to produce.",
    "operationId": "postApiLanguage",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Import Language Api Language Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Add or replace a language catalogue",
    "tags": [
     "Setup"
    ]
   }
  },
  "/api/language/{code}": {
   "get": {
    "operationId": "getApiLanguageCode",
    "parameters": [
     {
      "in": "path",
      "name": "code",
      "required": true,
      "schema": {
       "title": "Code",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response One Language Api Language  Code  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "One language catalogue",
    "tags": [
     "Setup"
    ]
   }
  },
  "/api/languages": {
   "get": {
    "operationId": "getApiLanguages",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "additionalProperties": true,
          "type": "object"
         },
         "title": "Response List Languages Api Languages Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "The interface languages available",
    "tags": [
     "Setup"
    ]
   }
  },
  "/api/launchers": {
   "get": {
    "description": "The list a browser is allowed to pick from, and whether each one is really here.\n\n`available` is `null` when the answer is not knowable: a command with a pipe or a\n`&&` in it is a shell line rather than a program, and checking the PATH for it would\nbe a guess dressed as a fact.\n\n`?versions=1` also runs each of them with `--version`, which is a second question and\ndeliberately a second request: finding out a word is on the PATH is free, and starting\nthree node programs to ask their version costs about two seconds. The box appears with\nits choices; the versions arrive after and fill themselves in.",
    "operationId": "getApiLaunchers",
    "parameters": [
     {
      "in": "query",
      "name": "versions",
      "required": false,
      "schema": {
       "default": false,
       "title": "Versions",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Launchers Api Launchers Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "What this machine can start",
    "tags": [
     "Sessions"
    ]
   }
  },
  "/api/network": {
   "get": {
    "description": "Read entirely from this machine and this request \u2014 no network call, ever.\n\nThe machine's own address comes from asking the kernel which source it would use for\nthe default route, which sends nothing. Yours comes from the socket the request arrived\non, which the server was holding anyway. The public address is deliberately *not* here:\nit needs a stranger, so it needs a press \u2014 see `/api/network/outside`.",
    "operationId": "getApiNetwork",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Where We Are Api Network Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Where this machine is, where you are, and the ssh line between them",
    "tags": [
     "The machine"
    ]
   }
  },
  "/api/network/outside": {
   "post": {
    "description": "The only thing in Argus that tells somebody else anything, and it is a POST for that\nreason: it is an action with a consequence, not a reading.\n\nAsking a service \"what is my address\" *is* telling that service your address, which is\nwhy nothing here does it on a timer, on load, or on anybody's behalf. The answer is\nreturned and not written down: no cache, no config, no journal entry beyond the fact\nthat the route was called, which the journal records for every route anyway.",
    "operationId": "postApiNetworkOutside",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response From Outside Api Network Outside Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Ask a stranger what this machine's public address is",
    "tags": [
     "The machine"
    ]
   }
  },
  "/api/overview": {
   "get": {
    "description": "Everything a board watching several machines needs, and nothing it does not.\n\nThis is the one door a watcher token opens, and the same answer a machine\nannounces to a board that cannot reach it.",
    "operationId": "getApiOverview",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Overview Api Overview Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "What is happening on this machine, in one cheap call",
    "tags": [
     "The machine"
    ]
   }
  },
  "/api/pdf/search": {
   "get": {
    "description": "Find a string in a PDF and say which pages it is on.\n\nThe browser's own viewer has a search box on a desktop and nothing at all on a phone,\nand inside an iframe Ctrl+F searches the page around it rather than the document. So\nthe text is extracted here and the viewer is sent to the page.",
    "operationId": "getApiPdfSearch",
    "parameters": [
     {
      "in": "query",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "q",
      "required": true,
      "schema": {
       "title": "Q",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Pdf Search Api Pdf Search Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Find text in a PDF, page by page",
    "tags": [
     "Files"
    ]
   }
  },
  "/api/ports": {
   "get": {
    "operationId": "getApiPorts",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Ports Api Ports Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "What is listening, and what is holding it",
    "tags": [
     "Ports"
    ]
   },
   "post": {
    "description": "Opening a port also hands back the cookie the proxied page needs: its own\nstylesheets and scripts cannot carry an Authorization header.",
    "operationId": "postApiPorts",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Open or close a port for proxying",
    "tags": [
     "Ports"
    ]
   }
  },
  "/api/prefs": {
   "get": {
    "description": "The desks, the windows and where they sit, the prompt library, the placeholder sets,\nthe shortcuts, the theme \u2014 the sixty keys that used to live only in one browser's\nstorage.\n\nTwo things become possible by moving them here, and they are the two people ask for: a\ndesk made at the desk exists on the phone, and something that is not a browser can read\nthe workspace \u2014 a script that wants the prompt library, an agent that has just started\nthree jobs and could lay out a desk to watch them in.\n\nThe version comes with the document and is what a full replacement has to present.",
    "operationId": "getApiPrefs",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Read Prefs Api Prefs Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Everything the browser remembers, from here",
    "tags": [
     "Setup"
    ]
   },
   "patch": {
    "description": "Merge the keys you send into whatever is there now, and nothing else.\n\nThis is how the browser saves, and the reason it is a merge rather than a replacement:\nlast-write-wins on the whole document loses a desk made on the phone the moment a laptop\nsaves an older copy of everything. Two devices changing different keys both keep their\nchange; two devices changing the same key still resolve to the last one, and there is no\nhonest way around that without asking somebody which they meant.\n\nA key sent as `null` is removed, which is how a browser says it has stopped keeping\nsomething.",
    "operationId": "patchApiPrefs",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Patch Prefs Api Prefs Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change some of them, leaving the rest alone",
    "tags": [
     "Setup"
    ]
   },
   "put": {
    "description": "The whole thing at once \u2014 an import, a restore, a browser adopting a machine that has\nnothing yet.\n\nIt must present the version it believes it is replacing. A mismatch is a 409 carrying the\ncurrent document, so the caller can look at what changed underneath rather than\ndiscovering later that an afternoon of window-moving went away. `version: 0` is \"there\nshould be nothing here\", which is exactly what a first upload means.",
    "operationId": "putApiPrefs",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Prefs Api Prefs Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Replace the whole document",
    "tags": [
     "Setup"
    ]
   }
  },
  "/api/relay": {
   "post": {
    "description": "Type text into another session, and press return if asked.\n\nThis is what the browser does when you drop a prompt onto a terminal, offered to the\nthing already sitting in a session: *I have finished, go and look*. It carries text and\nnot a prompt from the library, because the library lives in the browser \u2014 an agent that\nwants a template can read it out of the desk it belongs to, or simply write the\nsentence, which is what it is good at.\n\nThe same care as everywhere else: bracketed paste, and the return as a separate write a\nmoment later, or an input box that reads writes rather than lines swallows it.",
    "operationId": "postApiRelay",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Relay Api Relay Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Hand a sentence to another session, the way a person would",
    "tags": [
     "Sessions"
    ]
   }
  },
  "/api/runnable": {
   "get": {
    "description": "The names, and whether each is up right now. Not the commands.\n\nA board needs to know what it may ask for and what is already happening; it has no\nuse for the shell line, and every extra thing on the wire is one more thing a leaked\nboard leaks.",
    "operationId": "getApiRunnable",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "additionalProperties": true,
          "type": "object"
         },
         "title": "Response Runnable Api Runnable Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "What this machine offers to start and stop",
    "tags": [
     "The machine"
    ]
   }
  },
  "/api/runnable/{name}/{action}": {
   "post": {
    "description": "`action` is start or stop, and `name` must be something this machine published.\n\nNo command arrives in this request and none ever will. That is what keeps a watcher\ntoken nearly worthless: the worst anything holding it can do is start or stop what is\nwritten in this machine's own config.",
    "operationId": "postApiRunnableNameAction",
    "parameters": [
     {
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     },
     {
      "in": "path",
      "name": "action",
      "required": true,
      "schema": {
       "title": "Action",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Run One Api Runnable  Name   Action  Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Start or stop one of them",
    "tags": [
     "The machine"
    ]
   }
  },
  "/api/runs": {
   "get": {
    "description": "What is running, newest first. A page that arrives in the middle of a run draws it from\nhere; after that it is told about every change on the bell stream.",
    "operationId": "getApiRuns",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Listing Api Runs Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Orchestrations happening now",
    "tags": [
     "Sessions"
    ]
   },
   "post": {
    "description": "Called by the framework, every time something about a run changes.\n\nThe whole document each time rather than a patch: a run is a dozen lines of JSON, the\nsender always knows the truth, and a diff protocol between a script and a noticeboard is\nmachinery in exchange for nothing.",
    "operationId": "postApiRuns",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Post Api Runs Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Post the shape and state of an orchestration",
    "tags": [
     "Sessions"
    ]
   }
  },
  "/api/search": {
   "get": {
    "operationId": "getApiSearch",
    "parameters": [
     {
      "in": "query",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "q",
      "required": true,
      "schema": {
       "title": "Q",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "additionalProperties": true,
          "type": "object"
         },
         "title": "Response Search Api Search Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Find files by name under a folder",
    "tags": [
     "Files"
    ]
   }
  },
  "/api/shutdown": {
   "post": {
    "description": "Stops the server. Nothing here can start it again.\n\nThat asymmetry is the whole character of this endpoint: every tmux session carries on\nuntouched \u2014 Argus is a client, not their parent \u2014 but the only way back to this page\nis a shell on this machine, or a supervisor that restarts it. Which is why it takes\n`may_stop_argus` on top of `may_run`, and why the answer says so.",
    "operationId": "postApiShutdown",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Shutdown Api Shutdown Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Stop this Argus",
    "tags": [
     "The machine"
    ]
   }
  },
  "/api/since": {
   "get": {
    "description": "Everything that changed since a moment, in one answer.\n\nThe question this app exists for is not \"what is happening\" \u2014 a screen full of\nterminals already says that, and says it whether or not any of it is new. It is \"did\nanything happen while I was away, and does it need me\". That question can only be\nanswered by the machine: the browser was closed.\n\nFour sources, because four different things count as news. An agent that rang. A\nsession that appeared. An orchestration that ended or is stuck on a question. And\nfiles that were written \u2014 which is the only evidence there is that a job produced\nsomething, and the one thing none of the others can tell you.\n\nThe folders are the caller's business: the desks are the browser's idea, not this\nserver's, so it says which ones it cares about rather than being second-guessed. One\nthat has gone, or that points outside the roots, is skipped rather than refused \u2014\nthis is a summary, and a summary that 404s because one desk moved is no summary.",
    "operationId": "getApiSince",
    "parameters": [
     {
      "in": "query",
      "name": "at",
      "required": true,
      "schema": {
       "title": "At",
       "type": "number"
      }
     },
     {
      "in": "query",
      "name": "folder",
      "required": false,
      "schema": {
       "default": [],
       "items": {
        "type": "string"
       },
       "title": "Folder",
       "type": "array"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response What Happened Api Since Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "What happened while you were not looking",
    "tags": [
     "Setup"
    ]
   }
  },
  "/api/stat": {
   "get": {
    "description": "Just enough to notice a file has changed: a window watching a report being\nregenerated polls this rather than re-downloading the whole thing.",
    "operationId": "getApiStat",
    "parameters": [
     {
      "in": "query",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Stat Path Api Stat Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Size and modification time, for watching a file",
    "tags": [
     "Files"
    ]
   }
  },
  "/api/system": {
   "get": {
    "operationId": "getApiSystem",
    "parameters": [
     {
      "in": "query",
      "name": "brief",
      "required": false,
      "schema": {
       "default": false,
       "title": "Brief",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Vitals Api System Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "CPU, memory, swap, GPUs, disks, uptime",
    "tags": [
     "The machine"
    ]
   }
  },
  "/api/tmux/buffer": {
   "get": {
    "description": "The last thing copied inside tmux, so it can reach the device's clipboard.",
    "operationId": "getApiTmuxBuffer",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Tmux Buffer Api Tmux Buffer Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "The last thing copied inside tmux",
    "tags": [
     "Sessions"
    ]
   }
  },
  "/api/tmux/copymode": {
   "get": {
    "description": "Is this session showing history rather than the live end?",
    "operationId": "getApiTmuxCopymode",
    "parameters": [
     {
      "in": "query",
      "name": "session",
      "required": true,
      "schema": {
       "title": "Session",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Read Copy Mode Api Tmux Copymode Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Is this session showing history rather than the live end",
    "tags": [
     "Sessions"
    ]
   },
   "post": {
    "description": "Leave history and return to the live end.",
    "operationId": "postApiTmuxCopymode",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Exit Copy Mode Api Tmux Copymode Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Back to the live end",
    "tags": [
     "Sessions"
    ]
   }
  },
  "/api/tmux/cwd": {
   "get": {
    "description": "Where this session actually is, and how well that is known.\n\nNot the same thing as the folder a desk was given: that one decides where a file\nbrowser lands and what a hand-over sentence says, while this is the directory the\nwork is really happening in. Telling the other agent to look somewhere its\ncounterpart never was is a whole round wasted.\n\n`cwd_source` says where the answer came from, best first \u2014 `agent` (the program said\nso, in the pane option `@argus_cwd`), `process` (read from the process that holds the\nterminal), `tmux` (tmux's own observation), `start` (the directory the pane was made\nin). `cwd_live` is false only for the last, which is history rather than news.",
    "operationId": "getApiTmuxCwd",
    "parameters": [
     {
      "in": "query",
      "name": "session",
      "required": true,
      "schema": {
       "title": "Session",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Pane Directory Api Tmux Cwd Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "The directory a session is really in",
    "tags": [
     "Sessions"
    ]
   }
  },
  "/api/tmux/kill": {
   "post": {
    "description": "Killing a session ends everything running in it. The UI asks first.",
    "operationId": "postApiTmuxKill",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Kill Session Api Tmux Kill Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "End a session",
    "tags": [
     "Sessions"
    ]
   }
  },
  "/api/tmux/launch": {
   "post": {
    "description": "Create a session, start a launcher in it, wait for it to settle, type the prompt.\n\nOnly a launcher **named in the config** can be started, which is what keeps this from\nbeing \"run anything\" \u2014 the terminal next to it always was, but an endpoint that takes\na command line is a different thing to leave on a network.\n\nThe return says what actually happened rather than only that it worked: whether the\nthing settled before the wait ran out, and whether the return was pressed. A prompt\ntyped into an agent that was still drawing its banner is the failure this is designed\naround, so when `ready` is false the text is left sitting there unsent, for you.",
    "operationId": "postApiTmuxLaunch",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Launch Agent Api Tmux Launch Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Start an agent, with its first instruction",
    "tags": [
     "Sessions"
    ]
   }
  },
  "/api/tmux/new": {
   "post": {
    "operationId": "postApiTmuxNew",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response New Session Api Tmux New Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Start a session",
    "tags": [
     "Sessions"
    ]
   }
  },
  "/api/tmux/rename": {
   "post": {
    "operationId": "postApiTmuxRename",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Rename Session Api Tmux Rename Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Rename a session",
    "tags": [
     "Sessions"
    ]
   }
  },
  "/api/tmux/sessions": {
   "get": {
    "operationId": "getApiTmuxSessions",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "additionalProperties": true,
          "type": "object"
         },
         "title": "Response Sessions Api Tmux Sessions Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Every tmux session on this server",
    "tags": [
     "Sessions"
    ]
   }
  },
  "/api/tmux/source": {
   "post": {
    "description": "Make every session pick up the configuration file.\n\ntmux options are per-server, so one source-file reaches every session on it \u2014\nthere is nothing to do per session. The file is tried on a throwaway server first,\nbecause sourcing runs it and a bad line can end the server everything is in.",
    "operationId": "postApiTmuxSource",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Source Conf Api Tmux Source Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Hand the tmux config to every session, after trying it safely",
    "tags": [
     "Setup"
    ]
   }
  },
  "/api/tmux/style": {
   "post": {
    "description": "Put a look on one session, live.\n\nA look in the config file belongs to the server and dresses everything; this\ndresses the session named and leaves the rest alone. Only style options are\naccepted, from a fixed list \u2014 see tmux.STYLE_OPTIONS.",
    "operationId": "postApiTmuxStyle",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Dress Api Tmux Style Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Dress one session, without touching the config",
    "tags": [
     "Sessions"
    ]
   }
  },
  "/api/todo": {
   "get": {
    "description": "Kept on the server rather than in the browser, so the note you wrote at the desk is\non the phone as well. That is the whole reason it is here and not in the preferences.",
    "operationId": "getApiTodo",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Todo Api Todo Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "The list of things to do",
    "tags": [
     "Setup"
    ]
   },
   "post": {
    "operationId": "postApiTodo",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Add Todo Api Todo Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Add something to do",
    "tags": [
     "Setup"
    ]
   }
  },
  "/api/todo/{ident}": {
   "delete": {
    "operationId": "deleteApiTodoIdent",
    "parameters": [
     {
      "in": "path",
      "name": "ident",
      "required": true,
      "schema": {
       "title": "Ident",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Drop Todo Api Todo  Ident  Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Take one off the list",
    "tags": [
     "Setup"
    ]
   },
   "patch": {
    "operationId": "patchApiTodoIdent",
    "parameters": [
     {
      "in": "path",
      "name": "ident",
      "required": true,
      "schema": {
       "title": "Ident",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Edit Todo Api Todo  Ident  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change one: its words or its state",
    "tags": [
     "Setup"
    ]
   }
  },
  "/api/version": {
   "get": {
    "description": "Answers immediately from a day-old cache; the question is only asked of GitHub\nwhen that cache is stale. Switched off, it answers about this machine and stops\nthere, which is also what it does when there is no way out to the network.",
    "operationId": "getApiVersion",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Version Api Version Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "What is running here, and whether anything newer exists",
    "tags": [
     "Setup"
    ]
   }
  },
  "/api/where/wiring": {
   "get": {
    "description": "Which agents here can tell Argus the folder they consider current.\n\nOnly Claude Code can: it hands its status line hook `workspace.current_dir`. Nothing\noutside an agent can work that out \u2014 an agent never moves its own process \u2014 so this is\nthe difference between a mark that follows the work and one that names where the\nsession started.",
    "operationId": "getApiWhereWiring",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Where Wired Api Where Wiring Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Which agents are set up to say which folder they are in",
    "tags": [
     "Sessions"
    ]
   },
   "post": {
    "description": "Do the setting up, or take it back out.\n\nThe same bargain as the bell: it writes into the agent's own configuration, keeps a copy\nof the file as it was before Argus first touched it, reports a status line you wrote\nyourself rather than replacing it, and removes only what carries our own marker.",
    "operationId": "postApiWhereWiring",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Where Rewire Api Where Wiring Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set the agents up to say where they are, or undo it",
    "tags": [
     "Sessions"
    ]
   }
  },
  "/api/who": {
   "get": {
    "description": "The one call an agent makes first.\n\nThe same facts the browser assembles from four requests, put together on this side: the\nsessions, who is in each one and in which folder, which of them are asking for a person,\nand where the machine is. An agent that has to make four calls to find out who else is\nworking will make none.",
    "operationId": "getApiWho",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Who Api Who Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "What is on this machine, in one answer, for an agent",
    "tags": [
     "Sessions"
    ]
   }
  },
  "/proxy/{port}/{path}": {
   "delete": {
    "operationId": "deleteProxyPortPath",
    "parameters": [
     {
      "in": "path",
      "name": "port",
      "required": true,
      "schema": {
       "title": "Port",
       "type": "integer"
      }
     },
     {
      "in": "path",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Reach a service that only listens on loopback",
    "tags": [
     "Ports"
    ]
   },
   "get": {
    "operationId": "getProxyPortPath",
    "parameters": [
     {
      "in": "path",
      "name": "port",
      "required": true,
      "schema": {
       "title": "Port",
       "type": "integer"
      }
     },
     {
      "in": "path",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Reach a service that only listens on loopback",
    "tags": [
     "Ports"
    ]
   },
   "head": {
    "operationId": "headProxyPortPath",
    "parameters": [
     {
      "in": "path",
      "name": "port",
      "required": true,
      "schema": {
       "title": "Port",
       "type": "integer"
      }
     },
     {
      "in": "path",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Reach a service that only listens on loopback",
    "tags": [
     "Ports"
    ]
   },
   "options": {
    "operationId": "optionsProxyPortPath",
    "parameters": [
     {
      "in": "path",
      "name": "port",
      "required": true,
      "schema": {
       "title": "Port",
       "type": "integer"
      }
     },
     {
      "in": "path",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Reach a service that only listens on loopback",
    "tags": [
     "Ports"
    ]
   },
   "patch": {
    "operationId": "patchProxyPortPath",
    "parameters": [
     {
      "in": "path",
      "name": "port",
      "required": true,
      "schema": {
       "title": "Port",
       "type": "integer"
      }
     },
     {
      "in": "path",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Reach a service that only listens on loopback",
    "tags": [
     "Ports"
    ]
   },
   "post": {
    "operationId": "postProxyPortPath",
    "parameters": [
     {
      "in": "path",
      "name": "port",
      "required": true,
      "schema": {
       "title": "Port",
       "type": "integer"
      }
     },
     {
      "in": "path",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Reach a service that only listens on loopback",
    "tags": [
     "Ports"
    ]
   },
   "put": {
    "operationId": "putProxyPortPath",
    "parameters": [
     {
      "in": "path",
      "name": "port",
      "required": true,
      "schema": {
       "title": "Port",
       "type": "integer"
      }
     },
     {
      "in": "path",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Reach a service that only listens on loopback",
    "tags": [
     "Ports"
    ]
   }
  }
 },
 "tags": [
  {
   "description": "Reading the filesystem, previewing and searching it. Confined to the configured roots, canonicalised before the check, symlinks out of them refused.",
   "name": "Files"
  },
  {
   "description": "Making, moving, deleting, uploading. Every route here is off unless the server was started with `--allow-write`.",
   "name": "Writing"
  },
  {
   "description": "tmux: what exists, where it is, what it is showing, and how it looks. The terminal itself is a WebSocket.",
   "name": "Sessions"
  },
  {
   "description": "Something has finished, or wants you. Post to it from an agent hook; read the stream to be told as it happens.",
   "name": "Notifications"
  },
  {
   "description": "Working out what a path in a session refers to, so it can be opened.",
   "name": "Prompts"
  },
  {
   "description": "CPU, memory, disks, GPUs, and the ports that are listening.",
   "name": "The machine"
  },
  {
   "description": "Standing in front of a service that only listens on loopback, one port at a time.",
   "name": "Ports"
  },
  {
   "description": "What this server allows, which languages it has, and the tmux configuration it reads.",
   "name": "Setup"
  }
 ]
}
