{"id":13769250,"url":"https://github.com/rhysd/tweet-app","last_synced_at":"2025-08-29T05:06:21.688Z","repository":{"id":34239499,"uuid":"169722025","full_name":"rhysd/tweet-app","owner":"rhysd","description":"Desktop Twitter client only for tweeting. Timeline never shows up.","archived":false,"fork":false,"pushed_at":"2023-10-17T10:10:47.000Z","size":2560,"stargazers_count":76,"open_issues_count":6,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-09T17:56:23.366Z","etag":null,"topics":["desktop-application","tweet","twitter"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/tweet-app","language":"TypeScript","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/rhysd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-02-08T11:01:05.000Z","updated_at":"2025-07-25T21:44:51.000Z","dependencies_parsed_at":"2024-01-12T09:46:03.952Z","dependency_job_id":null,"html_url":"https://github.com/rhysd/tweet-app","commit_stats":{"total_commits":340,"total_committers":2,"mean_commits":170.0,"dds":0.04117647058823526,"last_synced_commit":"62e9f5fe53626fe58c7e7fea33f785a10f9bec2c"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/rhysd/tweet-app","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhysd%2Ftweet-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhysd%2Ftweet-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhysd%2Ftweet-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhysd%2Ftweet-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rhysd","download_url":"https://codeload.github.com/rhysd/tweet-app/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhysd%2Ftweet-app/sbom","scorecard":{"id":774614,"data":{"date":"2025-08-11","repo":{"name":"github.com/rhysd/tweet-app","commit":"f1ef6b4c321f127e562c22490c35671c790e9283"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.9,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/24 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:21","Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:20","Warn: no topLevel permission defined: .github/workflows/ci.yaml:1","Warn: no topLevel permission defined: .github/workflows/codeql.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":4,"reason":"dependency not pinned by hash detected -- score normalized to 4","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yaml:9: update your workflow using https://app.stepsecurity.io/secureworkflow/rhysd/tweet-app/ci.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yaml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/rhysd/tweet-app/ci.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yaml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/rhysd/tweet-app/ci.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yaml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/rhysd/tweet-app/ci.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yaml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/rhysd/tweet-app/ci.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/rhysd/tweet-app/codeql.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/rhysd/tweet-app/codeql.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/rhysd/tweet-app/codeql.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:55: update your workflow using https://app.stepsecurity.io/secureworkflow/rhysd/tweet-app/codeql.yml/master?enable=pin","Info:   0 out of   8 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   2 out of   2 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: MIT License: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.4.2 not signed: https://api.github.com/repos/rhysd/tweet-app/releases/98561882","Warn: release artifact v0.4.1 not signed: https://api.github.com/repos/rhysd/tweet-app/releases/93023190","Warn: release artifact v0.4.0 not signed: https://api.github.com/repos/rhysd/tweet-app/releases/92946313","Warn: release artifact v0.3.4 not signed: https://api.github.com/repos/rhysd/tweet-app/releases/59120580","Warn: release artifact v0.3.3 not signed: https://api.github.com/repos/rhysd/tweet-app/releases/49519176","Warn: release artifact v0.4.2 does not have provenance: https://api.github.com/repos/rhysd/tweet-app/releases/98561882","Warn: release artifact v0.4.1 does not have provenance: https://api.github.com/repos/rhysd/tweet-app/releases/93023190","Warn: release artifact v0.4.0 does not have provenance: https://api.github.com/repos/rhysd/tweet-app/releases/92946313","Warn: release artifact v0.3.4 does not have provenance: https://api.github.com/repos/rhysd/tweet-app/releases/59120580","Warn: release artifact v0.3.3 does not have provenance: https://api.github.com/repos/rhysd/tweet-app/releases/49519176"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"SAST","score":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 0 commits out of 6 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"24 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-r4pf-3v7r-hh55","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-ghr5-ch3p-vcr6","Warn: Project is vulnerable to: GHSA-7x97-j373-85x5","Warn: Project is vulnerable to: GHSA-7m48-wc93-9g85","Warn: Project is vulnerable to: GHSA-j7hp-h8jx-5ppr","Warn: Project is vulnerable to: GHSA-qqvq-6xgj-jw8g","Warn: Project is vulnerable to: GHSA-6r2x-8pq8-9489","Warn: Project is vulnerable to: GHSA-67mh-4wv8-2f99","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-78xj-cgh5-2h22","Warn: Project is vulnerable to: GHSA-2p57-rm9w-gvfp","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-76p7-773f-r4q5","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T03:12:17.983Z","repository_id":34239499,"created_at":"2025-08-23T03:12:17.983Z","updated_at":"2025-08-23T03:12:17.983Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272631634,"owners_count":24967104,"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","status":"online","status_checked_at":"2025-08-29T02:00:10.610Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["desktop-application","tweet","twitter"],"created_at":"2024-08-03T17:00:20.279Z","updated_at":"2025-08-29T05:06:21.656Z","avatar_url":"https://github.com/rhysd.png","language":"TypeScript","funding_links":[],"categories":["Overview"],"sub_categories":["Twitter"],"readme":"\u003cimg src=\"assets/images/icon128x128.png\" width=\"64\" height=\"64\" alt=\"icon\"/\u003e Tweet.app\n======================================================================================\n[![npm version][]][npm]\n[![CI][ci badge]][ci]\n[![codecov badge][]][codecov]\n\n[Tweet app][repo] is a small Twitter client only for tweeting on [Twitter][twitter], but never shows\na tweets timeline. It's built on [mobile Twitter website][mobile-twitter] and [Electron][electron].\n\n- Tweet form is the same as mobile official client (accurate characters count, emoji picker,\n  pictures/movies upload, save draft tweets, poll, ...)\n- After posting a tweet, it goes back to the tweet form again. Timeline never shows up in this app\n- Replying to a previously posted tweet (making tweets thread) is supported\n- Multi-account support\n- Terminal is first class. A `tweet` command is provided to access to the app from command line\n- Customizable. Keyboard shortcuts and lifecycle of the application can be configured\n- macOS, Linux and Windows are supported (confirmed with macOS 10.15, Ubuntu 18.04, Windows 10)\n\n\n\n## Screenshot\n\n- New tweet\n\n\u003cimg src=\"https://github.com/rhysd/ss/blob/master/tweet-app/new-tweet.png?raw=true\" width=\"712\" height=\"712\"/\u003e\n\n- Reply to previously posted tweet\n\n\u003cimg src=\"https://github.com/rhysd/ss/blob/master/tweet-app/reply.png?raw=true\" width=\"712\" height=\"712\"/\u003e\n\n\n\n## The Problem\n\nWhile using Twitter, it promotes seeing a tweets timeline. Twitter shows timeline after posting a\ntweet. But I want to control the timing to see timeline since it's time consuming especially when\nI'm working on something (e.g. coding, debugging, ...).\n\nBy separating posting a tweet from seeing timeline, it stops you 'escaping' into a timeline (and\nconsuming time to see it) and makes you back to your work when posting a tweet. I'm also thinking\nthat reducing times to see a timeline and actively determining the timing to see it are effective to\navoid SNS addiction.\n\nTo achieve the separation, this app only provides the functionality to post tweets.\n\n\n\n## Installation\n\n### Install App\n\n#### From [release page][release]\n\nInstallers for each platforms are ready at [releases page][release].\nPlease download it for your platform and double click it to install.\n\n- **macOS**: `Tweet-x.y.z.dmg` or `Tweet-x.y.z-mac.zip`\n- **Linux**: `Tweet x.y.z.AppImage` (in [AppImage][appimage] format) or `tweet-app_x.y.z_amd64.deb` or `tweet-app_x.y.z.zip`\n- **Windows**: `Tweet Setup.x.y.z.exe` (as [NSIS][nsis] installer)\n\nNote: On macOS, trying to install app may be rejected by OS at first time since this app is not\nsigned with code signing. In the case, please allow to run it from\n`System Preferences -\u003e Security and Privacy`.\n\n#### With [homebrew-cask][]\n\nIf you're macOS user and using [homebrew-cask][], this app can be installed via it.\nPlease tap the repository URL and install this app via `brew cask` as follows.\n\n```\nbrew tap rhysd/tweet-app https://github.com/rhysd/tweet-app\nbrew cask install tweet\n```\n\nIt's easiest way to install and manage this app on macOS.\n\n#### With `npm` package manager\n\n```sh\nnpm install -g tweet-app\n```\n\n`electron` package is a peer-dependency so it is not installed automatically. If you have not\ninstalled the package yet. Please install it additionally.\n\n```sh\nnpm install -g electron\n```\n\n### CLI Setup\n\nThis app can be accessed from command line. As optional, this section describes how to setup it.\n\n#### Using installed app\n\nWhen you have installed this app via [homebrew-cask][], you need to do nothing here. `tweet` command\nwas already setup at `/usr/local/bin` (it requires `node`).\n\nIf you have installed the app from [release page][release], `tweet` command can be setup as a symbolic\nlink. Please make a symbolic link to `app/bin/cli.js` in resources directory.\n\nFor example, on macOS:\n\n```sh\nln -s /path/to/Tweet.app/Contents/Resources/app/bin/cli.js /usr/local/bin/tweet\n```\n\nIt requires `node` executable to run the `cli.js` script with this configuration.\n\nNote: Please do not move `cli.js` to other directory since it locates Electron binary depending on\nits file path. Otherwise, you need to pass `--electron-path` option.\n\nEven if you don't want to install `node` executable, it's ok since Electron app executable can run\nas `node` executable as well. Please set [`$ELECTRON_RUN_AS_NODE`][ELECTRON_RUN_AS_NODE]\nenvironment variable.\n\n`tweet` command can be setup as an alias of shell or small ShellScript (on Linux or macOS) or batch\n(on Windows) which sets the environment variable and run the script by forwarding all commandline\noptions.\n\nFor example, on macOS:\n\n```sh\nalias tweet='ELECTRON_RUN_AS_NODE=true /Applications/Tweet.app/Contents/MacOS/Tweet /Applications/Tweet.app/Contents/Resources/app/bin/cli.js'\n```\n\n#### With `npm`\n\nIf you installed this app via `npm` by installing `tweet-app` and `electron` package, everything\nhas been done. `npm` should put `tweet` command in `$PATH` directory.\n\nIf you have installed the app from [release page][release], installing only `tweet-app`\npackage should work as follows.\n\nInstall it via `npm`.\n\n```sh\nnpm install -g tweet-app\n```\n\nAnd set the installed app's executable path to `$TWEET_APP_ELECTRON_EXECUTABLE` environment variable\nor pass it to `--electron-path` option.\n\nFor example (on macOS):\n\n```sh\nexport TWEET_APP_ELECTRON_EXECUTABLE=/Applications/Tweet.app/Contents/MacOS/Tweet\n\n# or\n\nalias tweet='tweet --electron-path=/Applications/Tweet.app/Contents/MacOS/Tweet'\n```\n\n\n\n## Usage\n\n### Basic Usage\n\nWhen starting app at first, You'll see login page. It's actually https://mobile.twitter.com/login\nso please enter your login information.  Then the page will be redirected to tweet form.\n\nNote: Please consider to create a configuration file `config.json` to enable some functionality.\nSince Twitter Lite does not expose a screen name in DOM, setting it to `default_account` is\nnecessary to notify this app your screen name. Please see 'Customization' section for the detail.\n\nThe tweet form is exactly the same as the input form of https://mobile.twitter.com/compose/tweet.\nAll functionalities like accurate characters count, picture/movie upload, emoji picker, save draft\ntweets, poll,... are available. Clicking '+' chains additional tweets.\n\nMenu items are in menu bar on macOS, and in a window tool bar on Windows and Linux. By default,\nthe window hides a tool bar on Windows and Linux. To reveal it, please type \u003ckbd\u003eAlt\u003c/kbd\u003e.\n\nBy clicking 'Tweet' (or 'Tweet All') button, it sends your tweet(s) to Twitter. And it returns to\n'New Tweet' input form again instead of showing a timeline.\n\nThis app uses accessibility label in some features. For example it finds out an element for 'Tweet'\nbutton based on the label and only English and Japanese are supported for now. If you find your\nlanguage is not supported, please create an issue to request a support.\n\n### Reply to Previous Tweet\n\nAfter posting a tweet, you may want to chain a new tweet by replying to the previous tweet. This app\nremembers the previous tweet on memory. Selecting 'Reply to Previous Tweet' in 'Edit' menu shows an\ninput form to reply to your previous tweet.\n\n### Command Usage in Terminal\n\n```\nUsage: tweet [options] [text]\n\nDesktop application for tweeting. Timeline never shows up.\n\nOptions:\n  -V, --version              output the version number\n  -t --hashtags \u003clist\u003e       comma-separated list of hashtags (e.g. \"js,react,node\")\n  -a --after-tweet \u003caction\u003e  what to do after posting tweet. One of 'new tweet', 'reply previous', 'close', 'quit'\n  --no-detach                do not detach process from shell\n  -r --reply                 reply to tweet sent previously. This option is only effective when app is already running\n  --electron-path \u003cpath\u003e     file path to Electron executable to run app\n  -h, --help                 output usage information\n```\n\nThe command `tweet` opens GUI window and a tweet form. When running the command, \n\n- if this app is not running yet, it starts GUI app\n- if this app is running in background, it reopens a window\n- if this app is running, it gives focus on application's window\n\nIn any case of above, the command line options passed to `tweet` are reflected.\n\n### Run This App as Background App\n\nBy setting `quit_on_close` to `false` in configuration, app does not quit even if you close the\nwindow. It remains as 'background app' in system. When app is started again next time by clicking\napplication icon in launcher or dock, the background app is activated and it shows a window again.\n\nTo stop the application, please choose 'Quit' from menu item or context menu at dock.\n\nFor configuration, please see 'Customization' section for more detail. For performance of the\nbackground app, please see 'Performance' section as well.\n\n### Multi-account\n\nThis app supports configuring multiple accounts. By setting additional accounts to `other_accounts`\nin configuration, you can switch accounts from 'Accounts' menu. When switching accounts, the window\nis created again to switch login session. For configuration, please read following 'Customization'\nsection.\n\n### Context Menu\n\nThanks to [electron-context-menu][], it supports basic context menu on right click.\n\nIn addition, 'Unlink auto links' item appears when showing context menu after selecting text in tweet form.\nIt removes auto links in selected text by inserting zero-width space.\n\n\u003c!-- Add short screenshot --\u003e\n\n### Touch Bar Support\n\nFor recent MacBook Pro, this app supports a touch bar.\n\n\n\n## Customization\n\nBehavior of this app can be configured with JSON configuration file.\nThe configuration file and all values in it are optional.\n`default_account` is recommended to be set since some features of this app is depending on it.\n\n### Configuration File\n\nPlease put a JSON file named `config.json` at application's data directory.\n\n- `~/Library/Application Support/Tweet/config.json` on macOS\n- `$XDG_CONFIG_HOME/Tweet/config.json` or `~/.config/Tweet/config.json` on Linux\n- `%APPDATA%\\Tweet\\config.json` on Windows\n\n### `default_account` (`String`)\n\nScreen name (`@name`) used by default. `@` can be omitted. If this value is not set, some features\nof this app are unavailable. Especially 'Reply to Previous Tweet' feature is not available. This\napp extracts your last tweet from timeline drawn after posting a new tweet, but it requires your\nscreen name. Twitter Lite does not expose a screen name in DOM, so this app needs to know it from\nconfiguration.\n\nI recommend to set this value.\n\n### `other_accounts` (`Array\u003cString\u003e`)\n\nAn array of screen names. These accounts can be switched from 'Accounts' menu.\n\n### `keymaps` (`Object\u003cString | Null\u003e`)\n\nObject of key shortcut mappings. Key string is a label of menu item. Value is string representing\nkey combination as [Electron's accelerator][accelerator] or `null`. For example,\n`\"Click Tweet Button\": \"CmdOrCtrl+Shift+Enter\"` changes keyboard shortcut for clicking tweet button\nfrom keyboard to \u003ckbd\u003eCmd\u003c/kbd\u003e + \u003ckbd\u003eShift\u003c/kbd\u003e + \u003ckbd\u003eEnter\u003c/kbd\u003e. When `null` is set, key\nshortcut is cleared for the menu item.\n\n### `after_tweet` (`String`)\n\nWhat this app should do after posting a tweet as string value. Possible values are as follows:\n\n- `\"new tweet\"`: Back to 'New Tweet' page.\n- `\"reply previous\"`: Back to 'Reply to Previous Tweet' page. It's useful when you often chain your\n  tweets.\n- `\"close\"`: Close and unfocus the app but not quit. This is the same as `\"quit\"` when\n  `quit_on_close` is set to `true`. It's useful when you want to back to your work after posting a\n  new tweet.\n- `\"quit\"`: Quit the app.\n\nDefault behavior is `\"new tweet\"`.\n\n### `hotkey` (`String`)\n\nHot key shortcut as string. Format is the same as `keymaps` values ([Electron's accelerator][accelerator]).\n\nThe key shortcut is global to toggle window of this app. It enables to access to this app from\nanywhere with one key shortcut. Please be careful to define this key shortcut since it overwrites\nexisting key shortcut.\n\nBy default no hot key is defined.\n\n### `quit_on_close` (`Boolean`)\n\nWhen `true`, this app quits after closing a window. This is a default behavior\non Linux and Windows.\n\nWhen `false`, this app does not quit. It means that main process does not die, but renderer process\nends when closing the window. It means that this app goes to background apps after closing a window.\nPlease read 'Performance' about background app performance. This is a default behavior on macOS.\n\n### `window` (`Object\u003cAny\u003e`)\n\n`window` is an object containing configuration for window properties. Each properties are described\nas follows.\n\n- `window.width` (`Number`): Width of window in pixels. Default value is `600`.\n- `window.height` (`Number`): Height of window in pixels. Default value is `600`.\n- `window.zoom` (`Number`): Zoom factor of font size in float number. `1.0` means `100%`.\n- `window.auto_hide_menu_bar` (`Boolean`): This config value is effective only on Linux or Windows.\n  Default value is `true`. When this value is set to `true`, a tool bar menu in window is hidden\n  automatically. Typing \u003ckbd\u003eAlt\u003c/kbd\u003e reveals the menu temporarily. When this value is set to\n  `false`, a tool bar menu is always shown in window.\n- `window.visible_on_all_workspaces` (`Boolean`): If this value is set to `true`, the application\n  window appears in every workspace rather than sticking the workspace the window was opened at\n  first. Default value is `false`.\n\n### Configuration Example\n\nHere is my own configuration:\n\n```json\n{\n  \"default_account\": \"@Linda_pp\",\n  \"keymaps\": {\n    \"Click Tweet Button\": \"CmdOrCtrl+Shift+Enter\"\n  },\n  \"after_tweet\": \"close\",\n  \"window\": {\n    \"width\": 450,\n    \"height\": 420,\n    \"zoom\": 0.8\n  }\n}\n```\n\n\n\n## FAQ\n\n### How can I enable dark mode?\n\n1. Choose 'Toggle Developer Tools' from 'View' menu\n2. Move to 'console' tab in DevTools\n3. Enter JavaScript `location.href = 'https://mobile.twitter.com'`\n4. Click your icon at top left of the window to open account menu\n5. Click toggle switch of dark mode\n6. Close DevTools and click 'New Tweet' from 'Edit' menu to back\n\n### How can I delete a tweet previously posted?\n\n1. Click 'Open Previous Tweet' item in 'Edit' menu\n2. Find a dropdown menu at top right\n3. Click 'Delete' item in the dropdown menu\n4. After deleting the tweet, automatically redirect to 'New Tweet' page\n\n### How can I save current text as draft?\n\n1. Click 'Cancel Tweet' item in 'Edit' menu\n2. When some text is in textarea, a dialog shows up with 'Discard' or 'Save' buttons\n3. Click 'Save' button\n4. Click 'Unsent Tweets' link in tweet page to restore the text later\n\n\n\n## Performance\n\nWhile a window is closed, renderer process is shutdown and there are only main process and GPU process.\nTotal memory footprint is around 70MB and CPU usage is 0.0%.\nWhen opening a window, a renderer process is created. Memory usage and CPU usage of the renderer\nprocess are depending on rendered contents https://mobile.twitter.com .\n\n\n\n## Security\n\nThis app conforms [the official guideline](https://www.electronjs.org/docs/tutorial/security).\n\nRegarding to permissions, only `media` and `geolocation` permissions are allowed in the browser\nwindow. When mobile.twitter.com requests these permissions, the main process will open a confirmation\ndialog to ask user if it is allowed. Other permission requests are always rejected.\n\n\n\n## Feedback\n\nIf you're facing some bug or having any feature request, please report it from\n[Issues page](https://github.com/rhysd/tweet-app/issues). Pull requests are more than welcome.\n\n\n\n## License\n\nDistributed under [the MIT License](./LICENSE.txt).\n\nSome icon was provided by [feather icons][feathericons] (`Copyright (c) 2013-2017 Cole Bemis`).\n\n[npm version]: https://badge.fury.io/js/tweet-app.svg\n[npm]: https://www.npmjs.com/package/tweet-app\n[ci badge]: https://github.com/rhysd/tweet-app/workflows/CI/badge.svg?branch=master\u0026event=push\n[ci]: https://github.com/rhysd/tweet-app/actions?query=workflow%3ACI\n[codecov badge]: https://codecov.io/gh/rhysd/tweet-app/branch/master/graph/badge.svg\n[codecov]: https://codecov.io/gh/rhysd/tweet-app\n[repo]: https://github.com/rhysd/tweet-app\n[twitter]: https://twitter.com\n[mobile-twitter]: https://play.google.com/store/apps/details?id=com.twitter.android.lite\n[electron]: https://electronjs.org\n[release]: https://github.com/rhysd/tweet-app/releases\n[accelerator]: https://electronjs.org/docs/api/accelerator\n[feathericons]: https://feathericons.com/\n[appimage]: https://appimage.org/\n[nsis]: https://sourceforge.net/projects/nsis/\n[ELECTRON_RUN_AS_NODE]: https://electronjs.org/docs/api/environment-variables#electron_run_as_node\n[homebrew-cask]: https://github.com/Homebrew/homebrew-cask\n[electron-context-menu]: https://github.com/sindresorhus/electron-context-menu\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhysd%2Ftweet-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frhysd%2Ftweet-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhysd%2Ftweet-app/lists"}