{"id":13582870,"url":"https://github.com/stephancasas/jxa-toolkit","last_synced_at":"2026-01-23T06:08:46.530Z","repository":{"id":42499004,"uuid":"456329579","full_name":"stephancasas/jxa-toolkit","owner":"stephancasas","description":"A boilerplate / utility wrapper for JXA (AppleScript JavaScript) scripts — providing common automation functions.","archived":false,"fork":false,"pushed_at":"2022-08-31T18:23:37.000Z","size":8,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-11-05T23:41:22.511Z","etag":null,"topics":["applescript","javascript","jxa","osascript"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stephancasas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-07T02:14:38.000Z","updated_at":"2024-09-17T07:28:56.000Z","dependencies_parsed_at":"2023-01-16T18:45:48.923Z","dependency_job_id":null,"html_url":"https://github.com/stephancasas/jxa-toolkit","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephancasas%2Fjxa-toolkit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephancasas%2Fjxa-toolkit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephancasas%2Fjxa-toolkit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephancasas%2Fjxa-toolkit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stephancasas","download_url":"https://codeload.github.com/stephancasas/jxa-toolkit/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247522737,"owners_count":20952615,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["applescript","javascript","jxa","osascript"],"created_at":"2024-08-01T15:03:05.391Z","updated_at":"2026-01-23T06:08:46.504Z","avatar_url":"https://github.com/stephancasas.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# jxa-toolkit\n\nA boilerplate / utility wrapper for JXA (AppleScript JavaScript) scripts — providing common automation functions.\n\n## Usage\n\njxa-toolkit is intended to aid in the creation of JXA scripts which will be run from the command line/shell. The entrypoint is the top-level `run()` function, which accepts a single argument, `argv` — rendered as the array of args which are passed via the shell.\n\nWrite your automation script's entry code inside of the `run()` function of `src/app.js`. You can declare additional functions or variables outside of this function signature, but such declarations will remain dormant unless by a called inside of `run().`\n\nWhen ready, use `npm run test` to compile your script inside of the utility wrapper and execute the outcome (`dist/app.jxa`). The execution permission will be automatically applied by the compiler script.\n\n\u003e :memo: **NOTE**\n\u003e\n\u003e If you have not previously granted permissions to _System Events_ or _Visual Studio Code_, macOS may prompt you for additional permissions. You should grant/apply these permissions in _System Preferences_ when prompted.\n\n# Functions Reference\n\n## Globals\n\n### `ctx()` | _Current Application_\n\n**Description**\nGet the current application context with standard additions included.\n\n**Example**\n\n```js\n// request input from the user\nconst response = ctx().displayDialog('Do you want to continue?');\n```\n\n---\n\n### `process(processName)` | _Application Process by Name_\n\n**Description**\nGet the application process (of _System Events_) by its name.\n\n**Arguments**\n\n| Argument      | Description                  |\n| :------------ | :--------------------------- |\n| `processName` | The process name to resolve. |\n\n**Example**\n\n```js\n// get the position of a Finder window\nconst windowPos = process('Finder').windows.at(0).position();\n```\n\n---\n\n### `exec(...cmd)` | _Execute Shell Command_\n\n**Description**\nExecute a shell function — including the current user's environment variables and shell config.\n\n**Arguments**\n\n| Argument | Description                                       |\n| :------- | :------------------------------------------------ |\n| `cmd`    | The command to execute, and any of its arguments. |\n\n**Example**\n\n```js\n// execute a nodejs script named \"script.js\" from the user's Downloads directory\nexec('node', Path.resolve(Path.User.DOWNLOADS, 'script.js'));\n```\n\n---\n\n### `fetchSync(url)` | _HTTP GET Request_\n\n**Description**\nPerform a `curl` `GET` request against the given url.\n\n**Arguments**\n\n| Argument | Description               |\n| :------- | :------------------------ |\n| `url`    | The request's target url. |\n\n**Example**\n\n```js\n// verify whether or not the system is presently connected to the internet by\n//   making a request to Apple's captive validation service\nconst hasInternet = fetchSync('https://captive.apple.com/')\n  .toLowerCase()\n  .includes('success');\n```\n\n## Cursor\n\n### `Cursor.getPosition(actual)` | _Current Cursor Position_\n\n**Description**\nGet the cursor's current coordinates.\n\n**Arguments**\n\n| Argument | Description                                                                                     |\n| :------- | :---------------------------------------------------------------------------------------------- |\n| `actual` | Get the cursor's actual position without consideration for display offset (very rare use case). |\n\n**Example**\n\n```js\n// get the cursor's current position\nconst { x, y } = Cursor.getPosition();\n```\n\n---\n\n### `Cursor.setPosition(x, y, offset)` | _Set Cursor Position_\n\n**Description**\nSet the cursor's position using (x, y) coordinates. A default offset of 8x8 is applied. This is done to ensure correct targeting of coordinates provided by querying UI elements directly, but can be overriden by passing `null` as the third argument.\n\n**Arguments**\n\n| Argument | Description                                                    |\n| :------- | :------------------------------------------------------------- |\n| `x`      | The cursor's target `X` position.                              |\n| `y`      | The cursor's target `Y` position.                              |\n| `offset` | The offset, as `{x,y}`, to apply to the final cursor position. |\n\n**Example**\n\n```js\n// move the cursor to the exact position of the first Finder window\nconst [x, y] = process('Finder')\n  .windows.at(0)\n  .attributes.byName('AXPosition')\n  .value();\n\nCursor.setPosition(x, y, null);\n```\n\n---\n\n### `Cursor.click(button)` | _Click the Cursor_\n\n**Description**\nClick the cursor at its current position.\n\n**Arguments**\n\n| Argument | Description                                                                  |\n| :------- | :--------------------------------------------------------------------------- |\n| `button` | As `'left'` or `'right'`, the cursor button to click (defaults to `'left'`). |\n\n**Example**\n\n```js\n// move the cursor to the exact position of the first Finder window and click\nconst [x, y] = process('Finder')\n  .windows.at(0)\n  .attributes.byName('AXPosition')\n  .value();\n\nCursor.setPosition(x, y, null);\nCursor.click('left');\n```\n\n---\n\n### `Cursor.setRestore()` / `Cursor.restore()` | _Store/Restore the Cursor Position_\n\n**Description**\nStore the current cursor position for restore later.\n\n**Example**\n\n```js\n// move the cursor to the exact position of the first Finder window and click,\n//   then return to the original position\nconst [x, y] = process('Finder')\n  .windows.at(0)\n  .attributes.byName('AXPosition')\n  .value();\n\nCursor.setRestore();\nCursor.setPosition(x, y, null);\nCursor.click('left');\nCursor.restore();\n```\n\n## File\n\n### `File.read(path)` | _Read File Content_\n\n**Description**\nRead the content of file by its path.\n\n**Arguments**\n\n| Argument | Description                        |\n| :------- | :--------------------------------- |\n| `path`   | The POSIX path to the target file. |\n\n**Example**\n\n```js\n// read the contents of a file on the desktop\nconst data = File.read('~/Desktop/my_file.txt');\n```\n\n---\n\n### `File.write(path, data)` | _Write File Content_\n\n**Description**\nWrite data to a file at the given path.\n\n**Arguments**\n\n| Argument | Description                        |\n| :------- | :--------------------------------- |\n| `path`   | The POSIX path to the target file. |\n| `data`   | As a string, the data to write.    |\n\n**Example**\n\n```js\n// write content to a file on the desktop\nconst data = 'Stephan hates osascript.';\nFile.write('~/Desktop/my_file.txt', data);\n```\n\n---\n\n### `File.delete(path)` | _Delete a File_\n\n**Description**\nDelete a file or directory by its path.\n\n**Arguments**\n\n| Argument | Description                                     |\n| :------- | :---------------------------------------------- |\n| `path`   | The POSIX path to the target file or directory. |\n\n**Example**\n\n```js\n// delete a file named \"my_file.txt\" from the desktop\nFile.delete('~/Desktop/my_file.txt');\n\n// delete a directory named \"AppleScript\" from the desktop\nFile.delete('~/Desktop/AppleScript');\n```\n\n---\n\n### `File.exists(path)` | _Check File Existence_\n\n**Description**\nDetermine whether or not a file exists at the given path.\n\n**Arguments**\n\n| Argument | Description                        |\n| :------- | :--------------------------------- |\n| `path`   | The POSIX path to the target file. |\n\n**Example**\n\n```js\n// perform an operation dependingon whether or not a file named\n//  \"my_file.txt\" exists on the desktop\nif (File.exists('~/Desktop/my_file.txt')) {\n  // ...\n}\n```\n\n## Dir\n\n### `Dir.read(path)` | _List a Directory's Content_\n\n**Description**\nRead the content of a directory by its path. An array is returned, with each filename as an element.\n\n**Arguments**\n\n| Argument | Description                             |\n| :------- | :-------------------------------------- |\n| `path`   | The POSIX path to the target directory. |\n\n**Example**\n\n```js\n// get the name of every file on the desktop\nconst files = Dir.read('~/Desktop');\n```\n\n---\n\n### `Dir.make(path)` | _Make a Directory_\n\n**Description**\nMake a directory at the given path.\n\n**Arguments**\n\n| Argument | Description                                      |\n| :------- | :----------------------------------------------- |\n| `path`   | The POSIX path to the target creation directory. |\n\n**Example**\n\n```js\n// create a directory named \"AppleScript\" on the desktop\nDir.make('~/Desktop/AppleScript');\n```\n\n## Path\n\n### `Path.resolve(...path)` | _Resolve an Absolute Path_\n\n**Description**\nResolve the absolute location of a given path.\n\n**Note**\nThis is automatically applied to any `File` or `Dir` operations.\n\n**Arguments**\n\n| Argument | Description                                                                         |\n| :------- | :---------------------------------------------------------------------------------- |\n| `path`   | A single POSIX path to resolve, or its constituents separated into individual args. |\n\n**Example**\n\n```js\n// get the path to a directory named \"AppleScript\" in the\n//   current user's pictures directory\nconst applescript = Path.resolve('~/Pictures', 'AppleScript');\n//   → \"/Users/johnnyappleseed/Pictures/AppleScript\"\n```\n\n---\n\n### `Path.User.{{...}}` | _Resolve an Absolute User Path_\n\n**Description**\nResolve the absolute location of the current user's home, `Desktop`, `Documents`, `Downloads`, or `Library` directory.\n\n**Variations**\n`Path.User.HOME` / `Path.User.DESKTOP` / `Path.User.DOCUMENTS` / `Path.User.DOWNLOADS` / `Path.User.LIBRARY`\n\n**Example**\n\n```js\n// get the path to a file named \"script.txt\" in the current\n//   user's Downloads directory\nconst applescript = Path.resolve(Path.User.DOWNLOADS, 'script.txt');\n//   → \"/Users/johnnyappleseed/Downloads/script.txt\"\n```\n\n---\n\n### `Path.System.{{...}}` | _Resolve an Absolute System Path_\n\n**Description**\nResolve the absolute location of the system's `Library` or `tmp` (temporary) directory.\n\n**Variations**\n\n`Path.System.LIBRARY` / `Path.System.TMP`\n\n**Example**\n\n```js\n// get the path to a file named \"script.txt\" in the temporary directory\nconst applescript = Path.resolve(Path.System.TMP, 'script.txt');\n//   → \"/tmp/script.txt\"\n```\n\n# License\n\nMIT -- _\"Hell, yeah! Free software!\"_\n\n# Contact\n\n| :man_technologist: | **Stephan Casas**                                       |\n| :----------------: | :------------------------------------------------------ |\n|      :email:       | stephancasas[at]icloud[dot]com                          |\n|       :bird:       | [@stephancasas](https://www.twitter.com/stephancasas)   |\n|      :camera:      | [@stephancasas](https://www.instagram.com/stephancasas) |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstephancasas%2Fjxa-toolkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstephancasas%2Fjxa-toolkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstephancasas%2Fjxa-toolkit/lists"}