api.json 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464
  1. {
  2. "_note": "This file is the source for the Terminal in-app documentation panel. It is derived from mod/agi/README.md. Whenever README.md is updated, this file MUST also be updated to keep the in-app help in sync.",
  3. "_version": "3.0",
  4. "sections": [
  5. {
  6. "id": "core",
  7. "name": "Core",
  8. "desc": "Built-in functions always available without requirelib()",
  9. "functions": [
  10. {
  11. "name": "sendResp",
  12. "sig": "sendResp(content)",
  13. "desc": "Set the HTTP response body.",
  14. "ret": "void",
  15. "example": "sendResp(\"Hello from AGI\");"
  16. },
  17. {
  18. "name": "sendJSONResp",
  19. "sig": "sendJSONResp(objectOrJsonString)",
  20. "desc": "Set Content-Type to application/json and write a JSON response.",
  21. "ret": "void",
  22. "example": "sendJSONResp({ ok: true, items: [1, 2, 3] });"
  23. },
  24. {
  25. "name": "echo",
  26. "sig": "echo(content)",
  27. "desc": "Append text to the current HTTP_RESP.",
  28. "ret": "void",
  29. "example": "echo(\"Hello \");\necho(\"World\");"
  30. },
  31. {
  32. "name": "sendOK",
  33. "sig": "sendOK()",
  34. "desc": "Set response to the string \"ok\".",
  35. "ret": "void",
  36. "example": "sendOK();"
  37. },
  38. {
  39. "name": "requirelib",
  40. "sig": "requirelib(libname)",
  41. "desc": "Load an AGI library into the current VM. Returns true on success.",
  42. "ret": "bool",
  43. "example": "if (!requirelib(\"filelib\")) {\n sendResp(\"filelib not available\");\n}"
  44. },
  45. {
  46. "name": "includes",
  47. "sig": "includes(scriptName)",
  48. "desc": "Load and execute another script relative to the current script's directory.",
  49. "ret": "void",
  50. "example": "includes(\"helpers.js\");"
  51. },
  52. {
  53. "name": "delay",
  54. "sig": "delay(ms)",
  55. "desc": "Sleep for the given number of milliseconds. After websocket.upgrade(), also pumps incoming WebSocket messages.",
  56. "ret": "void",
  57. "example": "delay(500);"
  58. },
  59. {
  60. "name": "exit",
  61. "sig": "exit()",
  62. "desc": "Stop script execution immediately.",
  63. "ret": "void",
  64. "example": "if (!userIsAdmin()) exit();"
  65. },
  66. {
  67. "name": "execd",
  68. "sig": "execd(scriptName, payload)",
  69. "desc": "Execute another AGI script asynchronously as a detached process.",
  70. "ret": "void",
  71. "example": "execd(\"worker.agi\", JSON.stringify({ job: \"thumbs\" }));"
  72. },
  73. {
  74. "name": "console.log",
  75. "sig": "console.log(...args)",
  76. "desc": "Write a line to the server log. In Terminal sessions, output is captured and shown in yellow.",
  77. "ret": "void",
  78. "example": "console.log(\"Debug:\", someVariable);"
  79. }
  80. ]
  81. },
  82. {
  83. "id": "db",
  84. "name": "DB",
  85. "desc": "Key-value database functions, always available.",
  86. "functions": [
  87. {
  88. "name": "newDBTableIfNotExists",
  89. "sig": "newDBTableIfNotExists(tableName)",
  90. "desc": "Create a database table if it does not already exist.",
  91. "ret": "bool",
  92. "example": "newDBTableIfNotExists(\"my_table\");"
  93. },
  94. {
  95. "name": "DBTableExists",
  96. "sig": "DBTableExists(tableName)",
  97. "desc": "Return true if the table exists.",
  98. "ret": "bool",
  99. "example": "if (DBTableExists(\"my_table\")) sendOK();"
  100. },
  101. {
  102. "name": "writeDBItem",
  103. "sig": "writeDBItem(tableName, key, value)",
  104. "desc": "Write a string value to the given key.",
  105. "ret": "bool",
  106. "example": "writeDBItem(\"my_table\", \"theme\", \"dark\");"
  107. },
  108. {
  109. "name": "readDBItem",
  110. "sig": "readDBItem(tableName, key)",
  111. "desc": "Read a string value from the given key.",
  112. "ret": "string",
  113. "example": "var theme = readDBItem(\"my_table\", \"theme\");"
  114. },
  115. {
  116. "name": "listDBTable",
  117. "sig": "listDBTable(tableName)",
  118. "desc": "Return all key-value pairs in the table as an object.",
  119. "ret": "object",
  120. "example": "var kv = listDBTable(\"my_table\");\nsendJSONResp(kv);"
  121. },
  122. {
  123. "name": "deleteDBItem",
  124. "sig": "deleteDBItem(tableName, key)",
  125. "desc": "Delete a single key from the table.",
  126. "ret": "bool",
  127. "example": "deleteDBItem(\"my_table\", \"theme\");"
  128. },
  129. {
  130. "name": "dropDBTable",
  131. "sig": "dropDBTable(tableName)",
  132. "desc": "Delete the entire table.",
  133. "ret": "bool",
  134. "example": "dropDBTable(\"my_table\");"
  135. }
  136. ]
  137. },
  138. {
  139. "id": "user",
  140. "name": "User",
  141. "desc": "User management and permission functions.",
  142. "functions": [
  143. {
  144. "name": "pathCanWrite",
  145. "sig": "pathCanWrite(vpath)",
  146. "desc": "Return true if the current user can write to the virtual path.",
  147. "ret": "bool",
  148. "example": "if (pathCanWrite(\"user:/Documents\")) sendOK();"
  149. },
  150. {
  151. "name": "getUserPermissionGroup",
  152. "sig": "getUserPermissionGroup()",
  153. "desc": "Return a JSON string describing the current user's permission group.",
  154. "ret": "string (JSON)",
  155. "example": "var group = JSON.parse(getUserPermissionGroup());"
  156. },
  157. {
  158. "name": "userIsAdmin",
  159. "sig": "userIsAdmin()",
  160. "desc": "Return true if the current user is an administrator.",
  161. "ret": "bool",
  162. "example": "if (!userIsAdmin()) {\n sendResp(\"Admin only\");\n exit();\n}"
  163. },
  164. {
  165. "name": "userExists",
  166. "sig": "userExists(username)",
  167. "desc": "(Admin only) Return true if the username exists.",
  168. "ret": "bool",
  169. "example": "if (userExists(\"alice\")) echo(\"exists\");"
  170. },
  171. {
  172. "name": "createUser",
  173. "sig": "createUser(username, password, defaultGroup)",
  174. "desc": "(Admin only) Create a new user account.",
  175. "ret": "bool",
  176. "example": "createUser(\"alice\", \"StrongPass\", \"default\");"
  177. },
  178. {
  179. "name": "removeUser",
  180. "sig": "removeUser(username)",
  181. "desc": "(Admin only) Delete a user account.",
  182. "ret": "bool",
  183. "example": "removeUser(\"alice\");"
  184. }
  185. ]
  186. },
  187. {
  188. "id": "filelib",
  189. "name": "filelib",
  190. "desc": "Virtual filesystem read, write, and metadata operations.",
  191. "load": "requirelib(\"filelib\");",
  192. "functions": [
  193. {
  194. "name": "filelib.writeFile",
  195. "sig": "filelib.writeFile(vpath, content)",
  196. "desc": "Write text content to a virtual path. Creates the file if it does not exist.",
  197. "ret": "bool",
  198. "example": "requirelib(\"filelib\");\nfilelib.writeFile(\"user:/notes.txt\", \"Hello World\");"
  199. },
  200. {
  201. "name": "filelib.readFile",
  202. "sig": "filelib.readFile(vpath)",
  203. "desc": "Read text content from a virtual path.",
  204. "ret": "string | false",
  205. "example": "requirelib(\"filelib\");\nvar text = filelib.readFile(\"user:/notes.txt\");"
  206. },
  207. {
  208. "name": "filelib.deleteFile",
  209. "sig": "filelib.deleteFile(vpath)",
  210. "desc": "Delete a file at the virtual path.",
  211. "ret": "bool",
  212. "example": "requirelib(\"filelib\");\nfilelib.deleteFile(\"user:/notes.txt\");"
  213. },
  214. {
  215. "name": "filelib.walk",
  216. "sig": "filelib.walk(vpath, mode)",
  217. "desc": "Recursively list entries. mode: \"all\", \"file\", or \"folder\".",
  218. "ret": "string[]",
  219. "example": "requirelib(\"filelib\");\nvar files = filelib.walk(\"user:/\", \"file\");"
  220. },
  221. {
  222. "name": "filelib.glob",
  223. "sig": "filelib.glob(pattern, sortMode)",
  224. "desc": "Glob match files. sortMode: \"default\" or user-defined sort. Does not support ** patterns.",
  225. "ret": "string[]",
  226. "example": "requirelib(\"filelib\");\nvar jpgs = filelib.glob(\"user:/Desktop/*.jpg\", \"default\");"
  227. },
  228. {
  229. "name": "filelib.aglob",
  230. "sig": "filelib.aglob(pattern, sortMode)",
  231. "desc": "Advanced glob supporting ** recursive patterns. Cannot scan bare root dirs.",
  232. "ret": "string[]",
  233. "example": "requirelib(\"filelib\");\nvar pngs = filelib.aglob(\"user:/Desktop/**/*.png\", \"default\");"
  234. },
  235. {
  236. "name": "filelib.readdir",
  237. "sig": "filelib.readdir(vpath, sortMode)",
  238. "desc": "List directory entries. Returns array of {Filename, Filepath, Ext, Filesize, Modtime, IsDir}.",
  239. "ret": "object[]",
  240. "example": "requirelib(\"filelib\");\nvar entries = filelib.readdir(\"user:/Desktop\", \"default\");\nsendJSONResp(entries);"
  241. },
  242. {
  243. "name": "filelib.filesize",
  244. "sig": "filelib.filesize(vpath)",
  245. "desc": "Return file size in bytes.",
  246. "ret": "number",
  247. "example": "requirelib(\"filelib\");\nvar sz = filelib.filesize(\"user:/movie.mp4\");"
  248. },
  249. {
  250. "name": "filelib.fileExists",
  251. "sig": "filelib.fileExists(vpath)",
  252. "desc": "Return true if the path exists as a file.",
  253. "ret": "bool",
  254. "example": "requirelib(\"filelib\");\nif (filelib.fileExists(\"user:/a.txt\")) sendOK();"
  255. },
  256. {
  257. "name": "filelib.isDir",
  258. "sig": "filelib.isDir(vpath)",
  259. "desc": "Return true if the path is a directory.",
  260. "ret": "bool",
  261. "example": "requirelib(\"filelib\");\nif (filelib.isDir(\"user:/Desktop\")) sendOK();"
  262. },
  263. {
  264. "name": "filelib.mkdir",
  265. "sig": "filelib.mkdir(vpath)",
  266. "desc": "Create a directory (and parents) at the virtual path.",
  267. "ret": "bool",
  268. "example": "requirelib(\"filelib\");\nfilelib.mkdir(\"user:/newfolder\");"
  269. },
  270. {
  271. "name": "filelib.md5",
  272. "sig": "filelib.md5(vpath)",
  273. "desc": "Return the MD5 hash string of a file.",
  274. "ret": "string",
  275. "example": "requirelib(\"filelib\");\nvar hash = filelib.md5(\"user:/a.txt\");"
  276. },
  277. {
  278. "name": "filelib.mtime",
  279. "sig": "filelib.mtime(vpath, parseToUnix)",
  280. "desc": "Return file modification time. parseToUnix=true returns a Unix timestamp; otherwise a formatted string.",
  281. "ret": "number | string",
  282. "example": "requirelib(\"filelib\");\nvar ts = filelib.mtime(\"user:/a.txt\", true);"
  283. },
  284. {
  285. "name": "filelib.rootName",
  286. "sig": "filelib.rootName(vpath)",
  287. "desc": "Return the display name of the storage root that owns this path.",
  288. "ret": "string",
  289. "example": "requirelib(\"filelib\");\nvar root = filelib.rootName(\"user:/Desktop/a.txt\");"
  290. }
  291. ]
  292. },
  293. {
  294. "id": "imagelib",
  295. "name": "imagelib",
  296. "desc": "Image dimension, resize, crop, and EXIF operations.",
  297. "load": "requirelib(\"imagelib\");",
  298. "functions": [
  299. {
  300. "name": "imagelib.getImageDimension",
  301. "sig": "imagelib.getImageDimension(vpath)",
  302. "desc": "Return [width, height] of the image.",
  303. "ret": "[number, number]",
  304. "example": "requirelib(\"imagelib\");\nvar dim = imagelib.getImageDimension(\"user:/img.jpg\");"
  305. },
  306. {
  307. "name": "imagelib.resizeImage",
  308. "sig": "imagelib.resizeImage(src, dest, width, height)",
  309. "desc": "Resize an image and save to dest.",
  310. "ret": "bool",
  311. "example": "requirelib(\"imagelib\");\nimagelib.resizeImage(\"user:/img.jpg\", \"user:/img_small.jpg\", 800, 600);"
  312. },
  313. {
  314. "name": "imagelib.resizeImageBase64",
  315. "sig": "imagelib.resizeImageBase64(src, width, height, format)",
  316. "desc": "Resize an image and return it as a base64 data URL. format: \"jpeg\", \"png\".",
  317. "ret": "string (data URL)",
  318. "example": "requirelib(\"imagelib\");\nvar b64 = imagelib.resizeImageBase64(\"user:/img.jpg\", 320, 240, \"jpeg\");"
  319. },
  320. {
  321. "name": "imagelib.cropImage",
  322. "sig": "imagelib.cropImage(src, dest, x, y, width, height)",
  323. "desc": "Crop a region from an image and save to dest.",
  324. "ret": "bool",
  325. "example": "requirelib(\"imagelib\");\nimagelib.cropImage(\"user:/img.jpg\", \"user:/crop.jpg\", 10, 10, 200, 200);"
  326. },
  327. {
  328. "name": "imagelib.loadThumbString",
  329. "sig": "imagelib.loadThumbString(vpath)",
  330. "desc": "Return the cached thumbnail as a base64 string.",
  331. "ret": "string",
  332. "example": "requirelib(\"imagelib\");\nvar thumb = imagelib.loadThumbString(\"user:/img.jpg\");"
  333. },
  334. {
  335. "name": "imagelib.hasExif",
  336. "sig": "imagelib.hasExif(vpath)",
  337. "desc": "Return true if the image has EXIF metadata.",
  338. "ret": "bool",
  339. "example": "requirelib(\"imagelib\");\nif (imagelib.hasExif(\"user:/img.jpg\")) echo(\"has exif\");"
  340. },
  341. {
  342. "name": "imagelib.getExif",
  343. "sig": "imagelib.getExif(vpath)",
  344. "desc": "Return EXIF data as a JSON string.",
  345. "ret": "string (JSON)",
  346. "example": "requirelib(\"imagelib\");\nvar exif = JSON.parse(imagelib.getExif(\"user:/img.jpg\"));"
  347. }
  348. ]
  349. },
  350. {
  351. "id": "http",
  352. "name": "http",
  353. "desc": "Outbound HTTP request helpers.",
  354. "load": "requirelib(\"http\");",
  355. "functions": [
  356. {
  357. "name": "http.request",
  358. "sig": "http.request(options)",
  359. "desc": "Curl-like request. options: {url, method, headers, body, json, form, bodyBase64, contentType, username, password, timeout, followRedirect, responseType}. Returns a response object {ok, status, statusText, headers, body, error}. Body precedence: bodyBase64 > form > json > body; responseType 'base64' returns a binary body base64 encoded.",
  360. "ret": "object",
  361. "example": "requirelib(\"http\");\nvar resp = http.request({url:\"https://example.com/api\", method:\"POST\", headers:{\"Authorization\":\"Bearer x\"}, json:{a:1}});\nif (resp.ok){ console.log(resp.status, resp.body); }"
  362. },
  363. {
  364. "name": "http.get",
  365. "sig": "http.get(url, headers)",
  366. "desc": "Perform an HTTP GET and return the response body as a string. headers is optional.",
  367. "ret": "string",
  368. "example": "requirelib(\"http\");\nvar body = http.get(\"https://example.com/api\");"
  369. },
  370. {
  371. "name": "http.post",
  372. "sig": "http.post(url, body, headers, contentType)",
  373. "desc": "Perform an HTTP POST and return the response body. Without headers/contentType the body is sent as JSON (backward compatible).",
  374. "ret": "string",
  375. "example": "requirelib(\"http\");\nvar resp = http.post(\"https://example.com/api\", JSON.stringify({a:1}));"
  376. },
  377. {
  378. "name": "http.put / http.patch / http.delete",
  379. "sig": "http.put(url, body, headers, contentType)",
  380. "desc": "Method helpers built on http.request; each returns the response object. http.delete(url, headers) sends no body.",
  381. "ret": "object",
  382. "example": "requirelib(\"http\");\nvar resp = http.put(\"https://example.com/api/1\", JSON.stringify({a:1}), {\"Content-Type\":\"application/json\"});"
  383. },
  384. {
  385. "name": "http.postForm / http.postJSON",
  386. "sig": "http.postForm(url, formObject, headers)",
  387. "desc": "POST helpers built on http.request. postForm sends application/x-www-form-urlencoded; postJSON sends a JSON body. Both return the response object.",
  388. "ret": "object",
  389. "example": "requirelib(\"http\");\nvar resp = http.postForm(\"https://example.com/api\", {a:1, b:2});"
  390. },
  391. {
  392. "name": "http.head",
  393. "sig": "http.head(url, headerKey)",
  394. "desc": "Fetch response headers. Without headerKey returns all headers as JSON; with headerKey returns just that header.",
  395. "ret": "string (JSON)",
  396. "example": "requirelib(\"http\");\nvar headers = JSON.parse(http.head(\"https://example.com\"));"
  397. },
  398. {
  399. "name": "http.getCode",
  400. "sig": "http.getCode(url)",
  401. "desc": "Return the HTTP status code for the URL.",
  402. "ret": "number",
  403. "example": "requirelib(\"http\");\nvar code = http.getCode(\"https://example.com\");"
  404. },
  405. {
  406. "name": "http.download",
  407. "sig": "http.download(url, destDirVpath, filenameOptional)",
  408. "desc": "Download a URL into the destination virtual directory.",
  409. "ret": "bool",
  410. "example": "requirelib(\"http\");\nhttp.download(\"https://example.com/a.zip\", \"user:/Downloads\", \"a.zip\");"
  411. },
  412. {
  413. "name": "http.getb64",
  414. "sig": "http.getb64(url)",
  415. "desc": "Fetch a URL and return the raw bytes as a base64 string.",
  416. "ret": "string",
  417. "example": "requirelib(\"http\");\nvar raw = http.getb64(\"https://example.com/logo.png\");"
  418. },
  419. {
  420. "name": "http.redirect",
  421. "sig": "http.redirect(targetUrl, statusCode)",
  422. "desc": "Redirect the client. Default statusCode is 307.",
  423. "ret": "void",
  424. "example": "requirelib(\"http\");\nhttp.redirect(\"https://example.com/new\", 302);"
  425. }
  426. ]
  427. },
  428. {
  429. "id": "share",
  430. "name": "share",
  431. "desc": "Create and manage public file share links.",
  432. "load": "requirelib(\"share\");",
  433. "functions": [
  434. {
  435. "name": "share.shareFile",
  436. "sig": "share.shareFile(vpath, timeoutSec)",
  437. "desc": "Create a public share link. timeoutSec=0 means no expiry. Returns the share UUID.",
  438. "ret": "string (uuid)",
  439. "example": "requirelib(\"share\");\nvar uuid = share.shareFile(\"user:/report.pdf\", 3600);"
  440. },
  441. {
  442. "name": "share.removeShare",
  443. "sig": "share.removeShare(shareUUID)",
  444. "desc": "Remove an existing share link.",
  445. "ret": "bool",
  446. "example": "requirelib(\"share\");\nshare.removeShare(uuid);"
  447. },
  448. {
  449. "name": "share.checkShareExists",
  450. "sig": "share.checkShareExists(shareUUID)",
  451. "desc": "Return true if the share UUID is still valid.",
  452. "ret": "bool",
  453. "example": "requirelib(\"share\");\nif (share.checkShareExists(uuid)) sendOK();"
  454. },
  455. {
  456. "name": "share.fileIsShared",
  457. "sig": "share.fileIsShared(vpath)",
  458. "desc": "Return true if the file already has an active share link.",
  459. "ret": "bool",
  460. "example": "requirelib(\"share\");\nif (share.fileIsShared(\"user:/report.pdf\")) sendOK();"
  461. },
  462. {
  463. "name": "share.getFileShareUUID",
  464. "sig": "share.getFileShareUUID(vpath)",
  465. "desc": "Return the share UUID for the given file, or false if not shared.",
  466. "ret": "string | false",
  467. "example": "requirelib(\"share\");\nvar sid = share.getFileShareUUID(\"user:/report.pdf\");"
  468. }
  469. ]
  470. },
  471. {
  472. "id": "appdata",
  473. "name": "appdata",
  474. "desc": "Read-only access to web-root application data files.",
  475. "load": "requirelib(\"appdata\");",
  476. "functions": [
  477. {
  478. "name": "appdata.readFile",
  479. "sig": "appdata.readFile(relativePathFromWebRoot)",
  480. "desc": "Read a file relative to ./web/. Returns false on error.",
  481. "ret": "string | false",
  482. "example": "requirelib(\"appdata\");\nvar conf = appdata.readFile(\"MyApp/config.json\");"
  483. },
  484. {
  485. "name": "appdata.listDir",
  486. "sig": "appdata.listDir(relativeDirFromWebRoot)",
  487. "desc": "List files in a directory relative to ./web/. Returns an array of relative paths.",
  488. "ret": "string[]",
  489. "example": "requirelib(\"appdata\");\nvar files = appdata.listDir(\"MyApp\");\nsendJSONResp(files);"
  490. },
  491. {
  492. "name": "appdata.getModuleList",
  493. "sig": "appdata.getModuleList()",
  494. "desc": "Return an array of registered module objects.",
  495. "ret": "object[]",
  496. "example": "requirelib(\"appdata\");\nvar mods = appdata.getModuleList();"
  497. }
  498. ]
  499. },
  500. {
  501. "id": "sysinfo",
  502. "name": "sysinfo",
  503. "desc": "Real-time system resource information.",
  504. "load": "requirelib(\"sysinfo\");",
  505. "functions": [
  506. {
  507. "name": "sysinfo.getCPUUsage",
  508. "sig": "sysinfo.getCPUUsage()",
  509. "desc": "Return CPU usage as a percentage (0–100).",
  510. "ret": "number",
  511. "example": "requirelib(\"sysinfo\");\nvar cpu = sysinfo.getCPUUsage();"
  512. },
  513. {
  514. "name": "sysinfo.getRAMUsage",
  515. "sig": "sysinfo.getRAMUsage()",
  516. "desc": "Return {used, total, percent} memory statistics.",
  517. "ret": "object",
  518. "example": "requirelib(\"sysinfo\");\nvar ram = sysinfo.getRAMUsage();\nsendJSONResp(ram);"
  519. },
  520. {
  521. "name": "sysinfo.getNetworkUsage",
  522. "sig": "sysinfo.getNetworkUsage()",
  523. "desc": "Return {rxRate, txRate, rxTotal, txTotal} in bytes/bytes-per-second.",
  524. "ret": "object",
  525. "example": "requirelib(\"sysinfo\");\nvar net = sysinfo.getNetworkUsage();"
  526. },
  527. {
  528. "name": "sysinfo.getDiskInfo",
  529. "sig": "sysinfo.getDiskInfo()",
  530. "desc": "Return an array of logical disk info objects.",
  531. "ret": "object[]",
  532. "example": "requirelib(\"sysinfo\");\nvar disks = sysinfo.getDiskInfo();\nsendJSONResp(disks);"
  533. }
  534. ]
  535. },
  536. {
  537. "id": "ziplib",
  538. "name": "ziplib",
  539. "desc": "Archive creation and extraction (zip, tar, tar.gz, gz).",
  540. "load": "requirelib(\"ziplib\");",
  541. "functions": [
  542. {
  543. "name": "ziplib.extractZipFile",
  544. "sig": "ziplib.extractZipFile(src, destDir)",
  545. "desc": "Extract a ZIP archive into destDir.",
  546. "ret": "bool",
  547. "example": "requirelib(\"ziplib\");\nziplib.extractZipFile(\"user:/a.zip\", \"user:/out/\");"
  548. },
  549. {
  550. "name": "ziplib.createZipFile",
  551. "sig": "ziplib.createZipFile(sourcesArrayOrString, outputZip)",
  552. "desc": "Create a ZIP archive from one or more source paths.",
  553. "ret": "bool",
  554. "example": "requirelib(\"ziplib\");\nziplib.createZipFile([\"user:/a.txt\", \"user:/b.txt\"], \"user:/bundle.zip\");"
  555. },
  556. {
  557. "name": "ziplib.extractAnyFile",
  558. "sig": "ziplib.extractAnyFile(srcArchive, destDir)",
  559. "desc": "Auto-detect archive format and extract into destDir.",
  560. "ret": "bool",
  561. "example": "requirelib(\"ziplib\");\nziplib.extractAnyFile(\"user:/archive.tar.gz\", \"user:/out/\");"
  562. },
  563. {
  564. "name": "ziplib.createAnyZipFile",
  565. "sig": "ziplib.createAnyZipFile(sourcesArrayOrString, outputPath, format)",
  566. "desc": "Create an archive in any supported format. format: \"zip\", \"tar\", \"tar.gz\", \"gz\".",
  567. "ret": "bool",
  568. "example": "requirelib(\"ziplib\");\nziplib.createAnyZipFile([\"user:/folder\"], \"user:/bundle.tar.gz\", \"tar.gz\");"
  569. },
  570. {
  571. "name": "ziplib.isValidZipFile",
  572. "sig": "ziplib.isValidZipFile(vpath)",
  573. "desc": "Return true if the file is a recognisable archive.",
  574. "ret": "bool",
  575. "example": "requirelib(\"ziplib\");\nvar ok = ziplib.isValidZipFile(\"user:/a.zip\");"
  576. },
  577. {
  578. "name": "ziplib.listZipFileContents",
  579. "sig": "ziplib.listZipFileContents(zipPath)",
  580. "desc": "Return a JSON tree string of the archive's contents.",
  581. "ret": "string (JSON)",
  582. "example": "requirelib(\"ziplib\");\nvar tree = JSON.parse(ziplib.listZipFileContents(\"user:/a.zip\"));"
  583. },
  584. {
  585. "name": "ziplib.getFileFromZip",
  586. "sig": "ziplib.getFileFromZip(zipPath, filePathInZip)",
  587. "desc": "Extract one file to tmp:/ and return its virtual path.",
  588. "ret": "string (vpath)",
  589. "example": "requirelib(\"ziplib\");\nvar tmp = ziplib.getFileFromZip(\"user:/a.zip\", \"docs/readme.txt\");"
  590. },
  591. {
  592. "name": "ziplib.extract7zFile",
  593. "sig": "ziplib.extract7zFile(src, destDir)",
  594. "desc": "Extract all files from a 7z archive into destDir.",
  595. "ret": "bool",
  596. "example": "requirelib(\"ziplib\");\nziplib.extract7zFile(\"user:/archive.7z\", \"user:/out/\");"
  597. },
  598. {
  599. "name": "ziplib.list7zFileDir",
  600. "sig": "ziplib.list7zFileDir(src, dirPathIn7z)",
  601. "desc": "List immediate children of a directory inside a 7z archive. Directories are returned with a trailing /.",
  602. "ret": "string[]",
  603. "example": "requirelib(\"ziplib\");\nvar items = ziplib.list7zFileDir(\"user:/archive.7z\", \"docs\");"
  604. },
  605. {
  606. "name": "ziplib.list7zFileContents",
  607. "sig": "ziplib.list7zFileContents(src)",
  608. "desc": "Return the full contents of a 7z archive as a JSON tree string (same schema as listZipFileContents).",
  609. "ret": "string (JSON)",
  610. "example": "requirelib(\"ziplib\");\nvar tree = JSON.parse(ziplib.list7zFileContents(\"user:/archive.7z\"));"
  611. },
  612. {
  613. "name": "ziplib.getFileFrom7z",
  614. "sig": "ziplib.getFileFrom7z(src, filePathIn7z)",
  615. "desc": "Extract a single file from a 7z archive to tmp:/ and return its virtual path.",
  616. "ret": "string (vpath)",
  617. "example": "requirelib(\"ziplib\");\nvar tmp = ziplib.getFileFrom7z(\"user:/archive.7z\", \"docs/readme.txt\");"
  618. },
  619. {
  620. "name": "ziplib.extractPartial7z",
  621. "sig": "ziplib.extractPartial7z(src, paths, destDir)",
  622. "desc": "Extract selected files/folders from a 7z archive. paths is a JS array or JSON array string. Folder paths strip their parent prefix; file paths are placed flat in destDir.",
  623. "ret": "bool",
  624. "example": "requirelib(\"ziplib\");\nziplib.extractPartial7z(\"user:/archive.7z\", [\"docs/\", \"README.md\"], \"user:/out/\");"
  625. },
  626. {
  627. "name": "ziplib.get7zFileInfo",
  628. "sig": "ziplib.get7zFileInfo(src)",
  629. "desc": "Return metadata about a 7z archive: { fileCount, dirCount, totalUncompressedSize, totalCompressedSize }. totalCompressedSize is always 0 (solid compression).",
  630. "ret": "string (JSON)",
  631. "example": "requirelib(\"ziplib\");\nvar info = JSON.parse(ziplib.get7zFileInfo(\"user:/archive.7z\"));\nconsole.log(info.fileCount + \" files\");"
  632. }
  633. ]
  634. },
  635. {
  636. "id": "sqlite",
  637. "name": "sqlite",
  638. "desc": "SQLite database access for scripts. Not available on linux/mipsle or windows/arm/386.",
  639. "load": "requirelib(\"sqlite\");",
  640. "functions": [
  641. {
  642. "name": "sqlite.open",
  643. "sig": "sqlite.open(vpath)",
  644. "desc": "Open or create a SQLite database at the virtual path. Returns a connection object with exec, query, queryRow, tables, schema, transaction, and close methods. Throws SQLiteError on failure. Databases open in WAL mode with a 5s busy timeout, so concurrent requests queue for the write lock instead of failing. Any handle still open when the script ends (including on error or exit) is closed automatically.",
  645. "ret": "object (db)",
  646. "example": "requirelib(\"sqlite\");\nvar db = sqlite.open(\"user:/.appdata/myapp/data.sqlite\");\ndb.exec(\"CREATE TABLE IF NOT EXISTS t (id INTEGER PRIMARY KEY, name TEXT)\");\ndb.close();"
  647. },
  648. {
  649. "name": "db.exec",
  650. "sig": "db.exec(sql, params)",
  651. "desc": "Execute a non-SELECT statement. params is an optional JS array of bound values. Returns { lastInsertId, rowsAffected }.",
  652. "ret": "object",
  653. "example": "db.exec(\"INSERT INTO t (name) VALUES (?)\", [\"Alice\"]);"
  654. },
  655. {
  656. "name": "db.query",
  657. "sig": "db.query(sql, params)",
  658. "desc": "Execute a SELECT and return all matching rows as an array of plain objects.",
  659. "ret": "object[]",
  660. "example": "var rows = db.query(\"SELECT * FROM t WHERE id > ?\", [0]);\nrows.forEach(function(r) { console.log(r.id, r.name); });"
  661. },
  662. {
  663. "name": "db.queryRow",
  664. "sig": "db.queryRow(sql, params)",
  665. "desc": "Like db.query() but returns only the first row object, or null if no rows matched.",
  666. "ret": "object | null",
  667. "example": "var row = db.queryRow(\"SELECT * FROM t WHERE id = ?\", [1]);\nif (row) sendJSONResp(row);"
  668. },
  669. {
  670. "name": "db.tables",
  671. "sig": "db.tables()",
  672. "desc": "Return the names of all user-created tables in the database.",
  673. "ret": "string[]",
  674. "example": "var tables = db.tables();\nsendJSONResp(tables);"
  675. },
  676. {
  677. "name": "db.schema",
  678. "sig": "db.schema(tableName)",
  679. "desc": "Return column metadata for a table as an array of { cid, name, type, notnull, dflt_value, pk } objects (from PRAGMA table_info).",
  680. "ret": "object[]",
  681. "example": "var cols = db.schema(\"t\");\nsendJSONResp(cols);"
  682. },
  683. {
  684. "name": "db.transaction",
  685. "sig": "db.transaction(fn)",
  686. "desc": "Run fn inside a single write transaction, committing when it returns and rolling back if it throws. fn receives the connection object and its return value is passed through. Use this for bulk writes: it collapses N lock cycles and N fsyncs into one. Opens with BEGIN IMMEDIATE so the busy timeout applies to acquiring the lock. Cannot be nested.",
  687. "ret": "any",
  688. "example": "db.transaction(function(tx) {\n for (var i = 0; i < items.length; i++) {\n tx.exec(\"INSERT INTO t (name) VALUES (?)\", [items[i]]);\n }\n});"
  689. },
  690. {
  691. "name": "db.close",
  692. "sig": "db.close()",
  693. "desc": "Close the database connection and release the handle. Optional - handles are also closed automatically when the script ends.",
  694. "ret": "bool",
  695. "example": "db.close();"
  696. }
  697. ]
  698. },
  699. {
  700. "id": "llm",
  701. "name": "llm",
  702. "desc": "Call any OpenAI-compatible or Anthropic LLM endpoint. Endpoint, API key, default model, pricing, and usage quota are configured in System Settings > AI Integration > AI Model.",
  703. "load": "requirelib(\"llm\");",
  704. "functions": [
  705. {
  706. "name": "llm.chat",
  707. "sig": "llm.chat(prompt, options)",
  708. "desc": "Send a single-turn text prompt and return the assistant reply string. options is optional (see llm options).",
  709. "ret": "string",
  710. "example": "requirelib(\"llm\");\nvar reply = llm.chat(\"What is 2 + 2?\");\nsendResp(reply);"
  711. },
  712. {
  713. "name": "llm.chatWithFile",
  714. "sig": "llm.chatWithFile(prompt, files, options)",
  715. "desc": "Like llm.chat() but attaches virtual-path files. Images become vision parts; text files are inlined. files may be a single vpath string or an array.",
  716. "ret": "string",
  717. "example": "requirelib(\"llm\");\nvar reply = llm.chatWithFile(\n \"Describe this image.\",\n \"user:/Photos/holiday.jpg\"\n);\nsendResp(reply);"
  718. },
  719. {
  720. "name": "llm.request",
  721. "sig": "llm.request(messages, options)",
  722. "desc": "Low-level call with a full OpenAI-style messages array. Returns the raw response object including choices and usage. When the model exposes chain-of-thought, choices[0].message.reasoning_content holds its thinking text (DeepSeek reasoning_content, OpenRouter reasoning, or Anthropic thinking blocks).",
  723. "ret": "object",
  724. "example": "requirelib(\"llm\");\nvar resp = llm.request([\n { role: \"system\", content: \"You are helpful.\" },\n { role: \"user\", content: \"Hi!\" }\n]);\nsendResp(resp.choices[0].message.content);"
  725. },
  726. {
  727. "name": "llm.streamRequest",
  728. "sig": "llm.streamRequest(messages, options, onDelta)",
  729. "desc": "Streaming version of llm.request(). onDelta({content, reasoning}) fires for each incremental chunk as the model generates it (content = new answer text, reasoning = new thinking text); the assembled response with usage is returned when the stream ends. Safe to relay chunks straight to a browser via websocket.send().",
  730. "ret": "object",
  731. "example": "requirelib(\"llm\");\nrequirelib(\"websocket\");\nwebsocket.upgrade(300);\nvar resp = llm.streamRequest([{ role: \"user\", content: \"Explain gravity\" }], {}, function(d){\n if (d.reasoning != \"\") websocket.send(JSON.stringify({ type: \"reasoning\", content: d.reasoning }));\n if (d.content != \"\") websocket.send(JSON.stringify({ type: \"delta\", content: d.content }));\n});\nwebsocket.send(JSON.stringify({ type: \"done\", usage: resp.usage }));"
  732. },
  733. {
  734. "name": "llm.usage",
  735. "sig": "llm.usage()",
  736. "desc": "Return accumulated token/cost metrics: { totalTokens, totalCost, totalRequests, perModel, currency, ... }.",
  737. "ret": "object",
  738. "example": "requirelib(\"llm\");\nvar u = llm.usage();\nsendJSONResp(u);"
  739. },
  740. {
  741. "name": "llm.models",
  742. "sig": "llm.models()",
  743. "desc": "Return the configured default model and list of models with pricing entries: { default, models }.",
  744. "ret": "object",
  745. "example": "requirelib(\"llm\");\nvar m = llm.models();\nsendJSONResp(m);"
  746. },
  747. {
  748. "name": "llm.listModels",
  749. "sig": "llm.listModels()",
  750. "desc": "Query the live endpoint for available models (no tokens consumed). Returns { models: [...] }.",
  751. "ret": "object",
  752. "example": "requirelib(\"llm\");\nvar m = llm.listModels();\nsendJSONResp(m.models);"
  753. },
  754. {
  755. "name": "llm.fileParts",
  756. "sig": "llm.fileParts(files)",
  757. "desc": "Convert virtual-path file(s) into OpenAI-style content parts for use in llm.request(). Images → image_url data URIs; text files → text parts.",
  758. "ret": "object[]",
  759. "example": "requirelib(\"llm\");\nvar parts = llm.fileParts([\"user:/report.txt\"]);\nvar resp = llm.request([{ role: \"user\", content: parts }]);\nsendResp(resp.choices[0].message.content);"
  760. }
  761. ]
  762. },
  763. {
  764. "id": "cnn",
  765. "name": "cnn",
  766. "desc": "Run image/face vision inference (classification, detection, segmentation, pose, oriented detection, face analysis) against an external CXNNAIO server. Endpoint, token and timeout are configured in System Settings > AI Integration > CNN Inference.",
  767. "load": "requirelib(\"cnn\");",
  768. "functions": [
  769. {
  770. "name": "cnn.classify",
  771. "sig": "cnn.classify(file, options)",
  772. "desc": "Classify an image (default model mobilenet-v2). file is a virtual path. Returns the server's image.classification envelope.",
  773. "ret": "object",
  774. "example": "requirelib(\"cnn\");\nvar r = cnn.classify(\"user:/cat.jpg\", { top_k: 3 });\nsendJSONResp(r.data);"
  775. },
  776. {
  777. "name": "cnn.detect",
  778. "sig": "cnn.detect(file, options)",
  779. "desc": "Run object detection (default model yolo11n). Returns the server's image.detection envelope; set options.render to also get an annotated PNG in rendered_image.",
  780. "ret": "object",
  781. "example": "requirelib(\"cnn\");\nvar r = cnn.detect(\"user:/street.jpg\", { score_threshold: 0.3 });\nsendJSONResp(r.data);"
  782. },
  783. {
  784. "name": "cnn.segment",
  785. "sig": "cnn.segment(file, options)",
  786. "desc": "Run instance segmentation (yolo11n-seg). Each item carries a per-instance, box-cropped base64 PNG mask.",
  787. "ret": "object",
  788. "example": "requirelib(\"cnn\");\nvar r = cnn.segment(\"user:/photo.jpg\", {});\nsendJSONResp(r.data);"
  789. },
  790. {
  791. "name": "cnn.pose",
  792. "sig": "cnn.pose(file, options)",
  793. "desc": "Run pose estimation (yolo11n-pose), 17 COCO keypoints per detected person.",
  794. "ret": "object",
  795. "example": "requirelib(\"cnn\");\nvar r = cnn.pose(\"user:/photo.jpg\", {});\nsendJSONResp(r.data);"
  796. },
  797. {
  798. "name": "cnn.oriented",
  799. "sig": "cnn.oriented(file, options)",
  800. "desc": "Run oriented/rotated-box detection (yolo11n-obb), intended for aerial/top-down imagery.",
  801. "ret": "object",
  802. "example": "requirelib(\"cnn\");\nvar r = cnn.oriented(\"user:/aerial.jpg\", {});\nsendJSONResp(r.data);"
  803. },
  804. {
  805. "name": "cnn.faceDetect",
  806. "sig": "cnn.faceDetect(file, options)",
  807. "desc": "Detect faces (default model ultraface-rfb-320). Returns the server's face.detection envelope.",
  808. "ret": "object",
  809. "example": "requirelib(\"cnn\");\nvar r = cnn.faceDetect(\"user:/group.jpg\", {});\nsendJSONResp(r.data);"
  810. },
  811. {
  812. "name": "cnn.faceLandmarks",
  813. "sig": "cnn.faceLandmarks(file, options)",
  814. "desc": "Detect 98-point facial landmarks (pfld). Set options.cropped to treat the whole input as one face crop instead of detecting faces first.",
  815. "ret": "object",
  816. "example": "requirelib(\"cnn\");\nvar r = cnn.faceLandmarks(\"user:/face.jpg\", { cropped: true });\nsendJSONResp(r.data);"
  817. },
  818. {
  819. "name": "cnn.faceEmbedding",
  820. "sig": "cnn.faceEmbedding(file, options)",
  821. "desc": "Return an L2-normalized 128-d embedding vector per face (mbv2facenet).",
  822. "ret": "object",
  823. "example": "requirelib(\"cnn\");\nvar r = cnn.faceEmbedding(\"user:/face.jpg\", {});\nsendJSONResp(r.data);"
  824. },
  825. {
  826. "name": "cnn.faceAttributes",
  827. "sig": "cnn.faceAttributes(file, options)",
  828. "desc": "Return gender attributes per face (gender-mbv2-0.35). Calls the server's /v1/faces/gender route; response object is face.gender.",
  829. "ret": "object",
  830. "example": "requirelib(\"cnn\");\nvar r = cnn.faceAttributes(\"user:/face.jpg\", {});\nsendJSONResp(r.data);"
  831. },
  832. {
  833. "name": "cnn.faceCompare",
  834. "sig": "cnn.faceCompare(fileA, fileB, options)",
  835. "desc": "Compare two face photos/crops and return their cosine similarity. options: { model, threshold, a_cropped, b_cropped }. No async variant.",
  836. "ret": "object",
  837. "example": "requirelib(\"cnn\");\nvar r = cnn.faceCompare(\"user:/a.jpg\", \"user:/b.jpg\", { threshold: 0.5 });\nsendResp(r.same ? \"same\" : \"different\");"
  838. },
  839. {
  840. "name": "cnn.analyze",
  841. "sig": "cnn.analyze(file, tasks, options)",
  842. "desc": "Run several tasks over one image in a single round trip. tasks is an array (classify/detect/segment/pose/oriented/faces/landmarks/attributes); options carries top-level render/async plus per-task blocks keyed by task name.",
  843. "ret": "object",
  844. "example": "requirelib(\"cnn\");\nvar r = cnn.analyze(\"user:/group.jpg\", [\"detect\", \"faces\"], { render: true });\nsendJSONResp(r.results);"
  845. },
  846. {
  847. "name": "cnn.job",
  848. "sig": "cnn.job(id)",
  849. "desc": "Poll an async job submitted with options.async = true. Returns { id, object, status, created, result, error }; status is queued, running, succeeded or failed.",
  850. "ret": "object",
  851. "example": "requirelib(\"cnn\");\nvar job = cnn.detect(\"user:/big.jpg\", { async: true });\nwhile (job.status === \"queued\" || job.status === \"running\") {\n delay(500);\n job = cnn.job(job.id);\n}\nsendJSONResp(job.result);"
  852. },
  853. {
  854. "name": "cnn.models",
  855. "sig": "cnn.models()",
  856. "desc": "Return the live model registry from the configured server: { object, data: [{ id, object, task, classes, input }, ...] }.",
  857. "ret": "object",
  858. "example": "requirelib(\"cnn\");\nsendJSONResp(cnn.models());"
  859. },
  860. {
  861. "name": "cnn.health",
  862. "sig": "cnn.health()",
  863. "desc": "Return live server health: { status, version, models_loaded, sessions, uptime_s }.",
  864. "ret": "object",
  865. "example": "requirelib(\"cnn\");\nsendJSONResp(cnn.health());"
  866. }
  867. ]
  868. },
  869. {
  870. "id": "office",
  871. "name": "office",
  872. "desc": "ArozOS Office suite document converters (.pptx, .xlsx and .docx import/export). Backed by mod/office.",
  873. "load": "requirelib(\"office\");",
  874. "functions": [
  875. {
  876. "name": "office.pptxToPresentation",
  877. "sig": "office.pptxToPresentation(srcVpath)",
  878. "desc": "Parse a .pptx file into the Slides document body schema (see Office/common/CONTRACT.md). Returns the body as a JSON string; embedded pictures are inlined as data: URLs. Throws on failure.",
  879. "ret": "string (JSON)",
  880. "example": "requirelib(\"office\");\nvar bodyJson = office.pptxToPresentation(\"user:/Desktop/deck.pptx\");\nsendJSONResp('{\"body\":' + bodyJson + '}');"
  881. },
  882. {
  883. "name": "office.presentationToPptx",
  884. "sig": "office.presentationToPptx(bodyJson, destVpath)",
  885. "desc": "Build a .pptx from a serialized Slides body JSON string and write it to destVpath. Image objects must be data: URLs; chart objects should carry a client-rendered PNG in props.png. Video/audio are not embedded: each renders as its poster frame and the media files are packed into a sidecar zip next to the pptx. Returns true, or the sidecar zip vpath (string) when one was written.",
  886. "ret": "bool | string",
  887. "example": "requirelib(\"office\");\nvar r = office.presentationToPptx(data, \"user:/Desktop/out.pptx\");\nif (r){ sendResp(\"OK\"); }"
  888. },
  889. {
  890. "name": "office.xlsxToWorkbook",
  891. "sig": "office.xlsxToWorkbook(srcVpath)",
  892. "desc": "Parse a .xlsx file into the Sheets document body schema. Returns the body as a JSON string. Values, formulas, styles, number formats, merges and frozen panes are converted; charts are skipped. Legacy binary .xls is rejected.",
  893. "ret": "string (JSON)",
  894. "example": "requirelib(\"office\");\nvar bodyJson = office.xlsxToWorkbook(\"user:/Desktop/report.xlsx\");\nsendJSONResp('{\"body\":' + bodyJson + '}');"
  895. },
  896. {
  897. "name": "office.workbookToXlsx",
  898. "sig": "office.workbookToXlsx(bodyJson, destVpath)",
  899. "desc": "Build a .xlsx from a serialized Sheets body JSON string and write it to destVpath. Formulas are written natively so Excel recalculates them. Returns true on success.",
  900. "ret": "bool",
  901. "example": "requirelib(\"office\");\nif (office.workbookToXlsx(data, \"user:/Desktop/out.xlsx\")){\n sendResp(\"OK\");\n}"
  902. },
  903. {
  904. "name": "office.docxToDocument",
  905. "sig": "office.docxToDocument(srcVpath)",
  906. "desc": "Parse a .docx file into the Docs document body schema. Returns the body as a JSON string. Paragraphs, headings, inline formatting, links, lists, tables, images, header/footer and page setup are converted. Legacy binary .doc is rejected.",
  907. "ret": "string (JSON)",
  908. "example": "requirelib(\"office\");\nvar bodyJson = office.docxToDocument(\"user:/Desktop/report.docx\");\nsendJSONResp('{\"body\":' + bodyJson + '}');"
  909. },
  910. {
  911. "name": "office.documentToDocx",
  912. "sig": "office.documentToDocx(bodyJson, destVpath)",
  913. "desc": "Build a .docx from a serialized Docs body JSON string and write it to destVpath. Images must be data: URLs. Returns true on success.",
  914. "ret": "bool",
  915. "example": "requirelib(\"office\");\nif (office.documentToDocx(data, \"user:/Desktop/out.docx\")){\n sendResp(\"OK\");\n}"
  916. },
  917. {
  918. "name": "office.packToFile",
  919. "sig": "office.packToFile(envelopeJson, destVpath)",
  920. "desc": "Write an Office suite native file (.doca/.xlsa/.ppta) as a zip container: document.json plus deduplicated binary assets. Media data URLs and legacy media?file= links inside the envelope become embedded assets, making the file portable. Returns true on success.",
  921. "ret": "bool",
  922. "example": "requirelib(\"office\");\nif (office.packToFile(content, \"user:/Documents/report.doca\")){\n sendResp(\"OK\");\n}"
  923. },
  924. {
  925. "name": "office.unpackFromFile",
  926. "sig": "office.unpackFromFile(srcVpath)",
  927. "desc": "Read a native Office suite file and return its envelope JSON string with embedded assets re-inlined as data URLs. Legacy plain-JSON documents pass through unchanged.",
  928. "ret": "string (JSON)",
  929. "example": "requirelib(\"office\");\nvar envelope = office.unpackFromFile(\"user:/Documents/report.doca\");\nsendJSONResp('{\"envelope\":' + envelope + '}');"
  930. },
  931. {
  932. "name": "office.unpackToWorkdir",
  933. "sig": "office.unpackToWorkdir(srcVpath, workdirBase)",
  934. "desc": "Read a native Office suite container and return its envelope JSON with binary assets extracted into <workdirBase>/<doc-hash>/ and referenced by media?file= links (keeps the JSON small even for video-heavy documents). Legacy plain-JSON files pass through unchanged.",
  935. "ret": "string (JSON)",
  936. "example": "requirelib(\"office\");\nvar envelope = office.unpackToWorkdir(\"user:/Documents/deck.ppta\", \"user:/.appdata/Office/cache\");\nsendJSONResp('{\"envelope\":' + envelope + '}');"
  937. },
  938. {
  939. "name": "office.odtToDocument",
  940. "sig": "office.odtToDocument(srcVpath)",
  941. "desc": "Read an OpenDocument Text (.odt) file and return the Docs body schema as a JSON string (formatting, links, lists, tables, pictures as data URLs, page geometry, header/footer, page breaks).",
  942. "ret": "string (JSON)",
  943. "example": "requirelib(\"office\");\nvar bodyJson = office.odtToDocument(\"user:/Documents/notes.odt\");\nsendJSONResp('{\"body\":' + bodyJson + '}');"
  944. },
  945. {
  946. "name": "office.documentToOdt",
  947. "sig": "office.documentToOdt(jsonStr, destVpath)",
  948. "desc": "Build an OpenDocument Text (.odt) file from a serialized Docs body JSON and write it to destVpath. Same subset as the docx exporter.",
  949. "ret": "boolean",
  950. "example": "requirelib(\"office\");\nvar ok = office.documentToOdt(data, \"user:/Documents/notes.odt\");\nsendResp(ok ? \"OK\" : \"failed\");"
  951. },
  952. {
  953. "name": "office.odsToWorkbook",
  954. "sig": "office.odsToWorkbook(srcVpath)",
  955. "desc": "Read an OpenDocument Spreadsheet (.ods) and return the Sheets body schema as a JSON string. ODF of:= formulas are translated back to plain A1 references; styles, widths, merges and cell notes are kept.",
  956. "ret": "string (JSON)",
  957. "example": "requirelib(\"office\");\nvar bodyJson = office.odsToWorkbook(\"user:/Documents/report.ods\");\nsendJSONResp('{\"body\":' + bodyJson + '}');"
  958. },
  959. {
  960. "name": "office.workbookToOds",
  961. "sig": "office.workbookToOds(jsonStr, destVpath)",
  962. "desc": "Build an OpenDocument Spreadsheet (.ods) from a serialized Sheets body JSON and write it to destVpath (formulas rewritten to ODF of:= syntax).",
  963. "ret": "boolean",
  964. "example": "requirelib(\"office\");\nvar ok = office.workbookToOds(data, \"user:/Documents/report.ods\");\nsendResp(ok ? \"OK\" : \"failed\");"
  965. },
  966. {
  967. "name": "office.odpToPresentation",
  968. "sig": "office.odpToPresentation(srcVpath)",
  969. "desc": "Read an OpenDocument Presentation (.odp) and return the Slides body schema as a JSON string, scaled into the 960x540 editor space (text, images, shapes, lines, tables, backgrounds, notes).",
  970. "ret": "string (JSON)",
  971. "example": "requirelib(\"office\");\nvar bodyJson = office.odpToPresentation(\"user:/Documents/deck.odp\");\nsendJSONResp('{\"body\":' + bodyJson + '}');"
  972. },
  973. {
  974. "name": "office.presentationToOdp",
  975. "sig": "office.presentationToOdp(jsonStr, destVpath)",
  976. "desc": "Build an OpenDocument Presentation (.odp) from a serialized Slides body JSON and write it to destVpath. Charts use their client-side PNG raster; video/audio objects are skipped.",
  977. "ret": "boolean",
  978. "example": "requirelib(\"office\");\nvar ok = office.presentationToOdp(data, \"user:/Documents/deck.odp\");\nsendResp(ok ? \"OK\" : \"failed\");"
  979. },
  980. {
  981. "name": "office.documentToPdf",
  982. "sig": "office.documentToPdf(jsonStr, destVpath)",
  983. "desc": "Build a PDF with real selectable text from a serialized Docs body JSON and write it to destVpath. Renders headings, inline styles, links, lists, tables, inline images, page breaks, page geometry and header/footer with page numbers. Latin-1 core fonts; other characters are transliterated.",
  984. "ret": "boolean",
  985. "example": "requirelib(\"office\");\nvar ok = office.documentToPdf(data, \"user:/Desktop/report.pdf\");\nsendResp(ok ? \"OK\" : \"failed\");"
  986. },
  987. {
  988. "name": "office.workbookPrintToPdf",
  989. "sig": "office.workbookPrintToPdf(printJson, destVpath)",
  990. "desc": "Build a real-text PDF from a Sheets print model ({sheets:[{name,colW,rowH,rows:[[{t,b,i,u,fc,bg,al}]]}]}) - formatted display strings plus styles computed by the web client. One A4-landscape section per sheet, columns scaled to fit the page.",
  991. "ret": "boolean",
  992. "example": "requirelib(\"office\");\nvar ok = office.workbookPrintToPdf(printModelJson, \"user:/Desktop/sheet.pdf\");\nsendResp(ok ? \"OK\" : \"failed\");"
  993. },
  994. {
  995. "name": "office.presentationToPdf",
  996. "sig": "office.presentationToPdf(jsonStr, destVpath)",
  997. "desc": "Build a real-text PDF from a serialized Slides body JSON: one page per slide at the deck canvas size. Text and tables stay selectable; images/charts embed from data URLs; video/audio render their captured poster frame (props.png) or a generic placeholder.",
  998. "ret": "boolean",
  999. "example": "requirelib(\"office\");\nvar ok = office.presentationToPdf(data, \"user:/Desktop/deck.pdf\");\nsendResp(ok ? \"OK\" : \"failed\");"
  1000. }
  1001. ]
  1002. },
  1003. {
  1004. "id": "websocket",
  1005. "name": "websocket",
  1006. "desc": "Upgrade the HTTP connection to a persistent WebSocket session.",
  1007. "load": "requirelib(\"websocket\");",
  1008. "functions": [
  1009. {
  1010. "name": "websocket.upgrade",
  1011. "sig": "websocket.upgrade(timeoutSec)",
  1012. "desc": "Upgrade to WebSocket. Also overrides delay() with a message-pumping version. Returns false on failure.",
  1013. "ret": "bool",
  1014. "example": "requirelib(\"websocket\");\nif (!websocket.upgrade(120)) exit();\nwebsocket.send(\"Connected!\");"
  1015. },
  1016. {
  1017. "name": "websocket.send",
  1018. "sig": "websocket.send(text)",
  1019. "desc": "Send a text frame to the client. Returns false if the connection is closed.",
  1020. "ret": "bool",
  1021. "example": "websocket.send(\"Hello client\");"
  1022. },
  1023. {
  1024. "name": "websocket.read",
  1025. "sig": "websocket.read(timeoutMs)",
  1026. "desc": "Read next message. Returns string on message, null on timeout (still open), false if closed. Omit timeoutMs to block.",
  1027. "ret": "string | null | false",
  1028. "example": "var msg = websocket.read(5000);\nif (msg === false) { /* closed */ }\nif (msg === null) { /* timeout */ }"
  1029. },
  1030. {
  1031. "name": "websocket.available",
  1032. "sig": "websocket.available()",
  1033. "desc": "Return count of buffered unread messages. Non-blocking.",
  1034. "ret": "number",
  1035. "example": "if (websocket.available() > 0) {\n var msg = websocket.read();\n}"
  1036. },
  1037. {
  1038. "name": "websocket.isClosed",
  1039. "sig": "websocket.isClosed()",
  1040. "desc": "Return true when the connection is no longer active.",
  1041. "ret": "bool",
  1042. "example": "while (!websocket.isClosed()) {\n websocket.send(\"tick\");\n delay(1000);\n}"
  1043. },
  1044. {
  1045. "name": "websocket.onMessage",
  1046. "sig": "websocket.onMessage = function(msg) { ... }",
  1047. "desc": "Assign a callback fired inside delay(). msg = { data, timestamp, type }. Set to null to stop and leave messages in buffer.",
  1048. "ret": "void",
  1049. "example": "var last = \"\";\nwebsocket.onMessage = function(msg) {\n last = msg.data;\n};\nwhile (!websocket.isClosed()) {\n if (last !== \"\") {\n websocket.send(\"Echo: \" + last);\n last = \"\";\n }\n delay(100);\n}"
  1050. },
  1051. {
  1052. "name": "websocket.close",
  1053. "sig": "websocket.close()",
  1054. "desc": "Send a normal-closure frame and close the connection.",
  1055. "ret": "bool",
  1056. "example": "websocket.close();"
  1057. }
  1058. ]
  1059. },
  1060. {
  1061. "id": "scheduler",
  1062. "name": "scheduler",
  1063. "desc": "Register and manage recurring background tasks for a webapp.",
  1064. "load": "requirelib(\"scheduler\");",
  1065. "functions": [
  1066. {
  1067. "name": "scheduler.hasPermission",
  1068. "sig": "scheduler.hasPermission()",
  1069. "desc": "Return true if the current user is allowed to create scheduled tasks.",
  1070. "ret": "bool",
  1071. "example": "requirelib(\"scheduler\");\nif (!scheduler.hasPermission()) sendResp(\"no_permission\");"
  1072. },
  1073. {
  1074. "name": "scheduler.registered",
  1075. "sig": "scheduler.registered(taskName, appName)",
  1076. "desc": "Return true if the task is already registered for this user+app.",
  1077. "ret": "bool",
  1078. "example": "requirelib(\"scheduler\");\nif (scheduler.registered(\"MyApp_Sync\", \"MyApp\")) sendResp(\"already_registered\");"
  1079. },
  1080. {
  1081. "name": "scheduler.register",
  1082. "sig": "scheduler.register(taskName, appName, intervalSecs, description, scriptName)",
  1083. "desc": "Register a new background task. scriptName defaults to \"cron.agi\".",
  1084. "ret": "bool",
  1085. "example": "requirelib(\"scheduler\");\nvar ok = scheduler.register(\"MyApp_Sync\", \"MyApp\", 3600, \"Hourly sync\", \"cron.agi\");"
  1086. },
  1087. {
  1088. "name": "scheduler.unregister",
  1089. "sig": "scheduler.unregister(taskName)",
  1090. "desc": "Remove a registered task.",
  1091. "ret": "bool",
  1092. "example": "requirelib(\"scheduler\");\nscheduler.unregister(\"MyApp_Sync\");"
  1093. }
  1094. ]
  1095. },
  1096. {
  1097. "id": "ffmpeg",
  1098. "name": "ffmpeg",
  1099. "desc": "Media conversion via ffmpeg. Only available when ffmpeg is installed on the host.",
  1100. "load": "requirelib(\"ffmpeg\");",
  1101. "functions": [
  1102. {
  1103. "name": "ffmpeg.convert",
  1104. "sig": "ffmpeg.convert(input, output, compression)",
  1105. "desc": "Generic media conversion.",
  1106. "ret": "bool",
  1107. "example": "requirelib(\"ffmpeg\");\nffmpeg.convert(\"user:/in.mov\", \"user:/out.mp4\", 0);"
  1108. },
  1109. {
  1110. "name": "ffmpeg.videoConvert",
  1111. "sig": "ffmpeg.videoConvert(input, output, resolution, compressionRate, progressFile)",
  1112. "desc": "Convert video to the given resolution. progressFile is a virtual path for JSON progress updates.",
  1113. "ret": "bool",
  1114. "example": "requirelib(\"ffmpeg\");\nffmpeg.videoConvert(\"user:/in.mp4\", \"user:/out.mp4\", \"720p\", 55, \"tmp:/progress.json\");"
  1115. },
  1116. {
  1117. "name": "ffmpeg.audioConvert",
  1118. "sig": "ffmpeg.audioConvert(input, output, sampleRate, progressFile)",
  1119. "desc": "Convert audio to the given sample rate.",
  1120. "ret": "bool",
  1121. "example": "requirelib(\"ffmpeg\");\nffmpeg.audioConvert(\"user:/in.wav\", \"user:/out.mp3\", 44100, \"tmp:/audio_progress.json\");"
  1122. },
  1123. {
  1124. "name": "ffmpeg.imageConvert",
  1125. "sig": "ffmpeg.imageConvert(input, output, scaleFactor, compressionRate, progressFile)",
  1126. "desc": "Convert/resize an image. scaleFactor 0.5 = 50% size. progressFile is optional; it only reports 0% and 100% but makes the job cancellable.",
  1127. "ret": "bool",
  1128. "example": "requirelib(\"ffmpeg\");\nffmpeg.imageConvert(\"user:/in.png\", \"user:/out.jpg\", 0.5, 80, \"tmp:/image_progress.json\");"
  1129. },
  1130. {
  1131. "name": "ffmpeg.convertWithProgress",
  1132. "sig": "ffmpeg.convertWithProgress(input, output, progressFile)",
  1133. "desc": "Convert between media types without format detection (e.g. mp4 to gif), writing JSON progress updates to progressFile.",
  1134. "ret": "bool",
  1135. "example": "requirelib(\"ffmpeg\");\nffmpeg.convertWithProgress(\"user:/in.mp4\", \"user:/out.gif\", \"tmp:/conv_progress.json\");"
  1136. },
  1137. {
  1138. "name": "ffmpeg.cancel",
  1139. "sig": "ffmpeg.cancel(progressFile)",
  1140. "desc": "Stop a running conversion, identified by the progress file it was started with. Returns true if a running conversion was terminated, false if it already finished. Call it from a separate request while the conversion request is still open.",
  1141. "ret": "bool",
  1142. "example": "requirelib(\"ffmpeg\");\nvar stopped = ffmpeg.cancel(\"tmp:/job42.progress.json\");"
  1143. }
  1144. ]
  1145. },
  1146. {
  1147. "id": "notification",
  1148. "name": "notification",
  1149. "desc": "Raise notifications to ArozOS users through the core notification system. The delivery channel (Telegram, desktop, email, custom webhook) is chosen by each receiving user's own notification preferences; the script only sets the priority (low / medium / high). Available when the host wired the notification system in.",
  1150. "load": "requirelib(\"notification\");",
  1151. "functions": [
  1152. {
  1153. "name": "notification.send",
  1154. "sig": "notification.send(title, message, priority)",
  1155. "desc": "Send a notification to the current user. priority is optional and one of \"low\", \"medium\" (default) or \"high\". Returns true on success.",
  1156. "ret": "bool",
  1157. "example": "requirelib(\"notification\");\nnotification.send(\"Backup done\", \"Your nightly backup finished\");\nnotification.send(\"Disk failing\", \"SMART error on /dev/sda\", notification.PRIORITY_HIGH);"
  1158. },
  1159. {
  1160. "name": "notification.sendToUser",
  1161. "sig": "notification.sendToUser(username, title, message, priority)",
  1162. "desc": "Send a notification to another user. Requires admin permission. priority is optional (low / medium / high). Returns true on success.",
  1163. "ret": "bool",
  1164. "example": "requirelib(\"notification\");\nnotification.sendToUser(\"bob\", \"Hi Bob\", \"A message for you\", \"low\");"
  1165. },
  1166. {
  1167. "name": "notification.PRIORITY_LOW / PRIORITY_MEDIUM / PRIORITY_HIGH",
  1168. "sig": "notification.PRIORITY_HIGH",
  1169. "desc": "Convenience string constants (\"low\", \"medium\", \"high\") for the priority argument.",
  1170. "ret": "string",
  1171. "example": "requirelib(\"notification\");\nnotification.send(\"Urgent\", \"Something needs attention\", notification.PRIORITY_HIGH);"
  1172. }
  1173. ]
  1174. },
  1175. {
  1176. "id": "git",
  1177. "name": "git",
  1178. "desc": "Version control for folders in the user's virtual file system, backed by go-git (no git binary needed on the host). Query calls return their payload directly or an object with an error field; mutating calls return {success, error, message}, plus authRequired:true when a remote rejects the credentials. HTTPS credentials are stored per user, encrypted, and keyed by remote host. Repositories must live on a local storage pool. Available when the host wired the git manager in.",
  1179. "load": "requirelib(\"git\");",
  1180. "functions": [
  1181. {
  1182. "name": "git.isRepo",
  1183. "sig": "git.isRepo(vpath)",
  1184. "desc": "Check whether vpath is inside a git working tree.",
  1185. "ret": "bool",
  1186. "example": "requirelib(\"git\");\nif (git.isRepo(\"user:/Desktop/myproject\")) {\n console.log(\"tracked by git\");\n}"
  1187. },
  1188. {
  1189. "name": "git.repoRoot",
  1190. "sig": "git.repoRoot(vpath)",
  1191. "desc": "Virtual path of the working tree root containing vpath. Returns false when vpath is not in a repository.",
  1192. "ret": "string | false",
  1193. "example": "var root = git.repoRoot(\"user:/Desktop/myproject/src\");"
  1194. },
  1195. {
  1196. "name": "git.init",
  1197. "sig": "git.init(vpath)",
  1198. "desc": "Create an empty repository at vpath, creating the folder when it does not exist.",
  1199. "ret": "object",
  1200. "example": "var result = git.init(\"user:/Desktop/newproject\");"
  1201. },
  1202. {
  1203. "name": "git.clone",
  1204. "sig": "git.clone(url, vpath, options)",
  1205. "desc": "Clone a remote into vpath, which must be empty or absent. Options: username, token, remember, branch, depth.",
  1206. "ret": "object",
  1207. "example": "var result = git.clone(\"https://github.com/tobychui/arozos.git\", \"user:/Desktop/arozos\", {\n username: \"tobychui\",\n token: \"ghp_...\",\n remember: true,\n depth: 1\n});\nif (!result.success && result.authRequired) {\n //ask the user for credentials and retry\n}"
  1208. },
  1209. {
  1210. "name": "git.status",
  1211. "sig": "git.status(vpath)",
  1212. "desc": "Full repository snapshot: branch, detached, head, upstream, ahead, behind, clean, changes[], remotes[], conflicted. Each change carries path, status, staging, worktree, staged, binary, size and preview (image/pdf/video/audio, absent when the browser cannot render it).",
  1213. "ret": "object",
  1214. "example": "var status = git.status(\"user:/Desktop/myproject\");\nconsole.log(status.branch + \": \" + status.changes.length + \" changed files\");"
  1215. },
  1216. {
  1217. "name": "git.log",
  1218. "sig": "git.log(vpath, limit)",
  1219. "desc": "Commits reachable from HEAD, newest first (default limit 50). Each has hash, shortHash, subject, message, authorName, authorEmail, timestamp and parents. Each commit also carries a tags array of tag names pointing at it.",
  1220. "ret": "array",
  1221. "example": "var commits = git.log(\"user:/Desktop/myproject\", 10);\ncommits.forEach(function(c) {\n console.log(c.shortHash + \" \" + c.subject);\n});"
  1222. },
  1223. {
  1224. "name": "git.checkoutCommit",
  1225. "sig": "git.checkoutCommit(vpath, hash)",
  1226. "desc": "Check a commit out in detached HEAD state. Refuses when the working tree has uncommitted changes.",
  1227. "ret": "object",
  1228. "example": "requirelib(\"git\");\ngit.checkoutCommit(\"user:/Desktop/myproject\", commitHash);"
  1229. },
  1230. {
  1231. "name": "git.resetToCommit",
  1232. "sig": "git.resetToCommit(vpath, hash, mode)",
  1233. "desc": "Move the current branch to a commit. mode is \"soft\" (HEAD only), \"mixed\" (also the index, the default) or \"hard\" (also the working tree). A hard reset refuses when there are uncommitted changes.",
  1234. "ret": "object",
  1235. "example": "requirelib(\"git\");\ngit.resetToCommit(\"user:/Desktop/myproject\", commitHash, \"soft\");"
  1236. },
  1237. {
  1238. "name": "git.createBranchAt",
  1239. "sig": "git.createBranchAt(vpath, branch, hash)",
  1240. "desc": "Create a branch pointing at a commit and check it out.",
  1241. "ret": "object",
  1242. "example": "requirelib(\"git\");\ngit.createBranchAt(\"user:/Desktop/myproject\", \"hotfix\", commitHash);"
  1243. },
  1244. {
  1245. "name": "git.createTag",
  1246. "sig": "git.createTag(vpath, tag, hash, message)",
  1247. "desc": "Tag a commit. A non-empty message produces an annotated tag, otherwise a lightweight one.",
  1248. "ret": "object",
  1249. "example": "requirelib(\"git\");\ngit.createTag(\"user:/Desktop/myproject\", \"v1.0\", commitHash, \"First release\");"
  1250. },
  1251. {
  1252. "name": "git.revertCommit",
  1253. "sig": "git.revertCommit(vpath, hash, options)",
  1254. "desc": "Create a new commit undoing a commit's changes. Uses a clean-or-refuse strategy: since go-git has no merge engine, the revert is applied only when the affected files still match the reverted commit, otherwise it is refused rather than producing a wrong result. options may carry name and email.",
  1255. "ret": "object",
  1256. "example": "requirelib(\"git\");\nvar result = git.revertCommit(\"user:/Desktop/myproject\", commitHash, {});\nif (!result.success) { console.log(result.error); }"
  1257. },
  1258. {
  1259. "name": "git.cherryPickCommit",
  1260. "sig": "git.cherryPickCommit(vpath, hash, options)",
  1261. "desc": "Apply a commit's changes onto the current HEAD, preserving the original author. Uses the same clean-or-refuse strategy as revert. options may carry name and email for the committer.",
  1262. "ret": "object",
  1263. "example": "requirelib(\"git\");\ngit.cherryPickCommit(\"user:/Desktop/myproject\", commitHash, {});"
  1264. },
  1265. {
  1266. "name": "git.amendMessage",
  1267. "sig": "git.amendMessage(vpath, message, options)",
  1268. "desc": "Rewrite the message of the HEAD commit, keeping its tree, parents and author. Only a branch tip can be amended.",
  1269. "ret": "object",
  1270. "example": "requirelib(\"git\");\ngit.amendMessage(\"user:/Desktop/myproject\", \"Corrected commit message\", {});"
  1271. },
  1272. {
  1273. "name": "git.branches",
  1274. "sig": "git.branches(vpath)",
  1275. "desc": "Local and remote-tracking branches: name, fullRef, hash, isRemote, isCurrent, plus remote and short — for origin/feature/login those are \"origin\" and \"feature/login\", which is what the branch management calls expect. For a local branch short equals name and remote is empty.",
  1276. "ret": "array",
  1277. "example": "var branches = git.branches(\"user:/Desktop/myproject\");"
  1278. },
  1279. {
  1280. "name": "git.checkout",
  1281. "sig": "git.checkout(vpath, branch, create)",
  1282. "desc": "Switch to a branch, creating it from HEAD when create is true. Checking out a remote name such as \"origin/feature\" creates the matching local branch.",
  1283. "ret": "object",
  1284. "example": "git.checkout(\"user:/Desktop/myproject\", \"feature/login\", true);"
  1285. },
  1286. {
  1287. "name": "git.deleteBranch",
  1288. "sig": "git.deleteBranch(vpath, branch, force)",
  1289. "desc": "Delete a local branch. The checked-out branch is never deleted. A branch holding commits unreachable from HEAD is refused with unmerged:true unless force is set, mirroring git branch -d versus -D.",
  1290. "ret": "object",
  1291. "example": "requirelib(\"git\");\nvar result = git.deleteBranch(\"user:/Desktop/myproject\", \"old-feature\", false);\nif (result.unmerged) {\n //confirm with the user, then force\n git.deleteBranch(\"user:/Desktop/myproject\", \"old-feature\", true);\n}"
  1292. },
  1293. {
  1294. "name": "git.renameBranch",
  1295. "sig": "git.renameBranch(vpath, oldName, newName)",
  1296. "desc": "Rename a local branch. Its upstream configuration moves with it, and HEAD follows when the renamed branch is the checked-out one.",
  1297. "ret": "object",
  1298. "example": "requirelib(\"git\");\ngit.renameBranch(\"user:/Desktop/myproject\", \"feature\", \"feature-v2\");"
  1299. },
  1300. {
  1301. "name": "git.deleteRemoteBranch",
  1302. "sig": "git.deleteRemoteBranch(vpath, remote, branch, options)",
  1303. "desc": "Delete a branch on the remote — a network push with an empty source refspec. The local remote-tracking ref is pruned too, so the branch stops appearing in git.branches(); any local branch of the same name is left alone. Options: username, token, remember.",
  1304. "ret": "object",
  1305. "example": "requirelib(\"git\");\nvar result = git.deleteRemoteBranch(\"user:/Desktop/myproject\", \"origin\", \"stale\", {});\nif (!result.success && result.authRequired) { /* prompt and retry */ }"
  1306. },
  1307. {
  1308. "name": "git.renameRemoteBranch",
  1309. "sig": "git.renameRemoteBranch(vpath, remote, oldName, newName, options)",
  1310. "desc": "Rename a branch on the remote. Git cannot rename a remote ref, so this pushes the new name then deletes the old one — in that order, so an interrupted rename leaves the branch under both names rather than losing it. Options: username, token, remember.",
  1311. "ret": "object",
  1312. "example": "requirelib(\"git\");\ngit.renameRemoteBranch(\"user:/Desktop/myproject\", \"origin\", \"feature\", \"feature-v2\", {});"
  1313. },
  1314. {
  1315. "name": "git.remotes",
  1316. "sig": "git.remotes(vpath)",
  1317. "desc": "Configured remotes, each with name and urls.",
  1318. "ret": "array",
  1319. "example": "var remotes = git.remotes(\"user:/Desktop/myproject\");"
  1320. },
  1321. {
  1322. "name": "git.addRemote",
  1323. "sig": "git.addRemote(vpath, name, url)",
  1324. "desc": "Add a remote. Passing an existing name replaces its URL.",
  1325. "ret": "object",
  1326. "example": "git.addRemote(\"user:/Desktop/myproject\", \"origin\", \"https://github.com/owner/repo.git\");"
  1327. },
  1328. {
  1329. "name": "git.removeRemote",
  1330. "sig": "git.removeRemote(vpath, name)",
  1331. "desc": "Delete a remote by name.",
  1332. "ret": "object",
  1333. "example": "git.removeRemote(\"user:/Desktop/myproject\", \"upstream\");"
  1334. },
  1335. {
  1336. "name": "git.add",
  1337. "sig": "git.add(vpath, files)",
  1338. "desc": "Stage the given repository-relative paths. A deleted path is removed from the index.",
  1339. "ret": "object",
  1340. "example": "git.add(\"user:/Desktop/myproject\", [\"src/main.go\", \"README.md\"]);"
  1341. },
  1342. {
  1343. "name": "git.addAll",
  1344. "sig": "git.addAll(vpath)",
  1345. "desc": "Stage every change in the working tree, like git add -A.",
  1346. "ret": "object",
  1347. "example": "git.addAll(\"user:/Desktop/myproject\");"
  1348. },
  1349. {
  1350. "name": "git.unstage",
  1351. "sig": "git.unstage(vpath, files)",
  1352. "desc": "Remove paths from the index while leaving the working tree untouched.",
  1353. "ret": "object",
  1354. "example": "git.unstage(\"user:/Desktop/myproject\", [\"src/main.go\"]);"
  1355. },
  1356. {
  1357. "name": "git.discard",
  1358. "sig": "git.discard(vpath, files)",
  1359. "desc": "Throw away working tree changes. Untracked files are deleted, since there is nothing to restore them from.",
  1360. "ret": "object",
  1361. "example": "git.discard(\"user:/Desktop/myproject\", [\"src/broken.go\"]);"
  1362. },
  1363. {
  1364. "name": "git.commit",
  1365. "sig": "git.commit(vpath, message, files, options)",
  1366. "desc": "Stage files and commit them in one step. Options: name, email, all. The author defaults to the calling user, then to the repository git config. Returns {success, hash, message}.",
  1367. "ret": "object",
  1368. "example": "var result = git.commit(\"user:/Desktop/myproject\", \"Fix the parser\", [\"src/parser.go\"], {\n name: \"Toby Chui\",\n email: \"toby@example.com\"\n});\nconsole.log(result.hash);"
  1369. },
  1370. {
  1371. "name": "git.ignore",
  1372. "sig": "git.ignore(vpath, patterns)",
  1373. "desc": "Append rules to the repository's .gitignore, creating the file when absent. Rules that are already present are skipped and the existing content is never rewritten, so repeating the call is harmless. The returned message names the rules actually added.",
  1374. "ret": "object",
  1375. "example": "requirelib(\"git\");\ngit.ignore(\"user:/Desktop/myproject\", [\"/build\", \"*.log\"]);"
  1376. },
  1377. {
  1378. "name": "git.diff",
  1379. "sig": "git.diff(vpath, file)",
  1380. "desc": "Diff of one path between HEAD and the working tree: additions, deletions, binary, tooLarge, isNew, isDeleted and hunks[]. Each hunk has header, oldStart/oldLines, newStart/newLines and lines[], where each line is {type, oldLine, newLine, content} and type is \"context\", \"add\" or \"del\".",
  1381. "ret": "object",
  1382. "example": "var diff = git.diff(\"user:/Desktop/myproject\", \"src/main.go\");\nconsole.log(\"+\" + diff.additions + \" -\" + diff.deletions);"
  1383. },
  1384. {
  1385. "name": "git.diffCommit",
  1386. "sig": "git.diffCommit(vpath, hash, file)",
  1387. "desc": "Same shape as git.diff, comparing a commit against its first parent.",
  1388. "ret": "object",
  1389. "example": "var diff = git.diffCommit(\"user:/Desktop/myproject\", commitHash, \"src/main.go\");"
  1390. },
  1391. {
  1392. "name": "git.commitFiles",
  1393. "sig": "git.commitFiles(vpath, hash)",
  1394. "desc": "The paths a commit touched, each with a status of added, modified or deleted, and a preview kind.",
  1395. "ret": "array",
  1396. "example": "var files = git.commitFiles(\"user:/Desktop/myproject\", commitHash);"
  1397. },
  1398. {
  1399. "name": "git.fileBlob",
  1400. "sig": "git.fileBlob(vpath, file, revision)",
  1401. "desc": "Read a file's content at a revision, returning {success, exists, base64, mime, kind, size}. revision is \"HEAD\" (the default) or a full 40 character commit hash; branch names and short hashes are rejected. This is the only way to obtain a committed binary file, which lives in the object database rather than on disk. exists is false without an error when the path was not part of that revision. Files above 8 MB are refused.",
  1402. "ret": "object",
  1403. "example": "requirelib(\"git\");\nvar blob = git.fileBlob(\"user:/Desktop/myproject\", \"img/logo.png\", \"HEAD\");\nif (blob.exists) {\n //blob.base64 holds the committed image, blob.mime is \"image/png\"\n}"
  1404. },
  1405. {
  1406. "name": "git.fetch",
  1407. "sig": "git.fetch(vpath, options)",
  1408. "desc": "Update remote-tracking refs without touching the working tree. Options: remote, username, token, remember.",
  1409. "ret": "object",
  1410. "example": "git.fetch(\"user:/Desktop/myproject\", { remote: \"origin\" });"
  1411. },
  1412. {
  1413. "name": "git.pull",
  1414. "sig": "git.pull(vpath, options)",
  1415. "desc": "Fetch and fast-forward the current branch. A diverged branch is reported as an error rather than merged. Options: remote, branch, username, token, remember.",
  1416. "ret": "object",
  1417. "example": "var result = git.pull(\"user:/Desktop/myproject\", {});\nif (!result.success && result.authRequired) {\n //ask the user for credentials and retry\n}"
  1418. },
  1419. {
  1420. "name": "git.push",
  1421. "sig": "git.push(vpath, options)",
  1422. "desc": "Push a branch to a remote. Options: remote, branch, username, token, remember, force, setUpstream.",
  1423. "ret": "object",
  1424. "example": "var result = git.push(\"user:/Desktop/myproject\", { setUpstream: true });\nconsole.log(result.message);"
  1425. },
  1426. {
  1427. "name": "git.saveCredential",
  1428. "sig": "git.saveCredential(host, username, token)",
  1429. "desc": "Store an HTTPS credential for a host, encrypted, for the calling user only. host may be a bare host name or a full remote URL.",
  1430. "ret": "object",
  1431. "example": "git.saveCredential(\"github.com\", \"tobychui\", \"ghp_...\");"
  1432. },
  1433. {
  1434. "name": "git.listCredentials",
  1435. "sig": "git.listCredentials()",
  1436. "desc": "Stored credentials as {host, username}. Tokens are never returned.",
  1437. "ret": "array",
  1438. "example": "var saved = git.listCredentials();"
  1439. },
  1440. {
  1441. "name": "git.hasCredential",
  1442. "sig": "git.hasCredential(host)",
  1443. "desc": "Check whether a credential is stored for a host.",
  1444. "ret": "bool",
  1445. "example": "if (!git.hasCredential(\"github.com\")) {\n //prompt the user\n}"
  1446. },
  1447. {
  1448. "name": "git.removeCredential",
  1449. "sig": "git.removeCredential(host)",
  1450. "desc": "Delete the stored credential for a host.",
  1451. "ret": "object",
  1452. "example": "git.removeCredential(\"github.com\");"
  1453. },
  1454. {
  1455. "name": "git.remoteHost",
  1456. "sig": "git.remoteHost(url)",
  1457. "desc": "The host a remote URL maps to, i.e. the key credentials are stored under. Both https://github.com/a/b.git and git@github.com:a/b.git yield github.com.",
  1458. "ret": "string",
  1459. "example": "var host = git.remoteHost(\"https://github.com/owner/repo.git\");"
  1460. }
  1461. ]
  1462. }
  1463. ]
  1464. }