{"id":15361966,"url":"https://github.com/tj/nshell","last_synced_at":"2026-03-08T23:02:05.721Z","repository":{"id":4102447,"uuid":"5211412","full_name":"tj/nshell","owner":"tj","description":"scriptable command-line shell written with node.js","archived":false,"fork":false,"pushed_at":"2014-07-06T00:39:38.000Z","size":237,"stargazers_count":110,"open_issues_count":13,"forks_count":13,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-10-14T17:43:28.789Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tj.png","metadata":{"files":{"readme":"Readme.md","changelog":"History.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-07-28T02:27:12.000Z","updated_at":"2024-10-19T14:09:46.000Z","dependencies_parsed_at":"2022-08-27T13:00:42.704Z","dependency_job_id":null,"html_url":"https://github.com/tj/nshell","commit_stats":null,"previous_names":["visionmedia/nshell"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tj/nshell","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tj%2Fnshell","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tj%2Fnshell/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tj%2Fnshell/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tj%2Fnshell/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tj","download_url":"https://codeload.github.com/tj/nshell/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tj%2Fnshell/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30276606,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-08T20:45:49.896Z","status":"ssl_error","status_checked_at":"2026-03-08T20:45:49.525Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2024-10-01T12:57:43.274Z","updated_at":"2026-03-08T23:02:05.677Z","avatar_url":"https://github.com/tj.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nshell\n\n  A work-in-progress scriptable shell written with node (replacing bash, ksh, etc).\n\n## Installation\n\n    $ npm install -g nshell\n\n For now clone and:\n \n    $ npm install\n    $ ./bin/shell\n\n## About\n\n  Just started this as a quick proof of concept,\n  but it's kinda fun! Keep in mind this is not an\n  attempt to become a POSIX shell.\n\n## Features\n\n  Small set of features so far:\n  \n  - PS1\n  - pipelining\n  - scriptability!\n  - aliases\n  - sources `~/.profile.js`\n  - saves history to `~/.nshell-history`\n  - brace expansion\n  - filename auto-completion\n  - some built-ins\n  - some magic variables\n\n### Built-ins\n\n  Currently the following built-ins are available:\n  \n  - `.` -- source a javascript file\n  - `cd` -- change directory\n  - `which` -- search __PATH__ for an executable\n  - `exit` -- exit nshell\n  - `history` -- view history\n\n### Variables\n\n  Currently the following magic vars are available:\n  \n  - `$?` the exit status of the previous command\n  - `!!` the string value of the previous command\n\n### Events\n\n Hook into events with `shell.on(event, callback)`:\n\n  - `cd` (dir) changing directories\n  - `exec` (line) is about to be executed\n  - `alias` (name, cmd) when an alias is defined\n  - `source` (file, mod) when a module is sourced\n  - `command` (e) when a command line is inputted, but not yet executed\n\n### ~/.profile.js\n\n  By default `nshell(1)` currently sources `~/.profile.js`,\n  this is where you can put config much like other shells.\n\n### PS1\n\n  Change your __PS1__ prompt by exporting a string:\n\n```js\nexports.PS1 = \"tj\u003e \";\n```\n\n  Or create something more dynamic and fancy\n  by exporting a function:\n\n```js\nvar colors = [31, 32, 33, 34, 35, 36];\n\nexports.PS1 = function(){\n  var color = colors[Math.random() * colors.length | 0];\n  return '\\033[' + color + 'm\u003e\\033[m ';\n};\n```\n\n### Brace expansion\n\n  Brace expansion works as you'd expect:\n\n```\n\u003e touch foobar\n\u003e touch foobaz\n\u003e rm foo{bar,baz}\n```\n\n### Sourcing\n\n  You may source files much like you do with `require()` in node,\n  support you have \"test.js\", you may load it with either of\n  the following:\n\n```\n▸ . test.js\n▸ . test\n```\n\n### Aliases\n\n```js\nshell.alias('GET', 'burl GET');\nshell.alias('HEAD', 'burl -I');\nshell.alias('POST', 'burl POST');\nshell.alias('PUT', 'burl PUT');\nshell.alias('PATCH', 'burl PATCH');\nshell.alias('DELETE', 'burl DELETE');\nshell.alias('DEL', 'burl DELETE');\nshell.alias('OPTIONS', 'burl OPTIONS');\n```\n\n## Debugging\n\n```js\n$ DEBUG=nshell ./bin/shell\n▸ cat Readme.md\n  nshell cmd [{\"name\":\"cat\",\"argv\":[\"Readme.md\"]}] +1.1m\n  nshell env {} +0ms\n  nshell which cat +0ms\n  nshell found /bin/cat +2ms\n  nshell spawn /bin/cat [\"Readme.md\"] +0ms\n  nshell exit 0 +5ms\n  nshell prompt +0ms\n```\n\n## Examples\n\n  Some cool examples showing off the power\n  of scripting your shell!\n\n### Auto-cd\n\n  By default `nshell(1)` does not auto-chdir when\n  the given line is a directory, however you can\n  easily script this in:\n\n```js\nvar fs = require('fs')\n  , exists = fs.existsSync\n  , stat = fs.statSync;\n\n// auto-cd\n\nshell.on('command', function(e){\n  var path = e.line.trim();\n  if (exists(path) \u0026\u0026 stat(path).isDirectory) {\n    e.preventDefault();\n    shell.exec('cd \"' + path + '\"');\n  }\n});\n```\n\nUsage:\n\n```js\n▸ pwd\n/Users/tj/projects/nshell\n▸ node_modules/commander\n▸ pwd\n/Users/tj/projects/nshell/node_modules/commander\n▸ ../..\n▸ pwd\n/Users/tj/projects/nshell\n```\n\n### Auto-edit\n\n  By default `nshell(1)` will simply give you\n  a \"command not found\" error if you try to\n  type a filename, however you can script\n  in the ability to edit that file depending\n  on its mime type:\n\n```js\n// $ npm install mime\n\nvar path = require('path');\nvar mime = require('mime');\n\n// auto-editor (silly implementation)\n\nshell.on('command', function(e){\n  var line = e.line.trim();\n  var type = mime.lookup(line);\n  switch (type) {\n    case 'text/plain':\n    case 'text/css':\n    case 'application/javascript':\n      e.preventDefault();\n      shell.exec('mate \"' + line + '\"');\n      break;\n  }\n});\n```\n\n### Command replay\n\n  To replay the previous command on a blank line\n  you can also listen on the \"command\" event and\n  use the `shell.lastCommand` property, which is\n  populated by the last successfully executed \n  command line.\n\n```js\nshell.on('command', function(e){\n  if ('' == e.line.trim()) {\n    e.preventDefault();\n    shell.exec(shell.lastCommand);\n  }\n});\n```\n\n### JavaScript expansion\n\n  Modifications to `e.line` are accepted by nshell,\n  this means you can progressively layer on plugins,\n  in this case a naive implementation of \"js expansion\":\n\n```js\nshell.on('command', function(e){\n  e.line = expansion(e.line);\n});\n\nfunction expansion(line) {\n  return line.replace(/`(.*?)`/, function(_, js){\n    return eval('(' + js + ')');\n  });\n}\n```\n\nUsage:\n\n```\n▸ echo `Math.pow(2, 32)`\n▸ 4294967296\n▸ cat `\"Make\" + \"file\"`\n\ntest:\n\t@./node_modules/.bin/mocha \\\n\t\t--require should \\\n\t\t--reporter spec\n...\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 TJ Holowaychuk \u0026lt;tj@vision-media.ca\u0026gt;\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftj%2Fnshell","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftj%2Fnshell","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftj%2Fnshell/lists"}