{"_id":"@ascdong/nexus","_rev":"7-84f814181c0d162695d5dd20f1a14df8","name":"@ascdong/nexus","dist-tags":{"latest":"0.1.6"},"versions":{"0.1.0":{"name":"@ascdong/nexus","version":"0.1.0","_id":"@ascdong/nexus@0.1.0","maintainers":[{"name":"ascdong","email":"rongyu.dong@outlook.com"}],"bin":{"nexus":"dist/cli.js"},"dist":{"shasum":"3a3adc40ef641638c61db7e40340a4b5d7ab3122","tarball":"https://registry.npmjs.org/@ascdong/nexus/-/nexus-0.1.0.tgz","fileCount":24,"integrity":"sha512-DZ8m1/QHO5wEtUpyiRNY82lDxQ1gfzDvxx4klgRwJ2dBZpwYuHxjbG/Sld8IouqtTuOuEskHDJyzPuBRe13hLQ==","signatures":[{"sig":"MEUCIEX0lfogRMw8TqEyofXHSF04GCMVaebiZJNJBeKP78OoAiEAiSR/W2YVIG5zkuxQROOg5bVt5XJ2ZT27lIujuyPFV+g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":49921},"type":"module","shasum":"3a3adc40ef641638c61db7e40340a4b5d7ab3122","engines":{"node":">=20"},"scripts":{"dev":"bun run src/cli.ts","test":"bun test","build":"tsc","typecheck":"tsc --noEmit","test:watch":"bun test --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"ascdong","email":"rongyu.dong@outlook.com"},"_integrity":"sha512-DZ8m1/QHO5wEtUpyiRNY82lDxQ1gfzDvxx4klgRwJ2dBZpwYuHxjbG/Sld8IouqtTuOuEskHDJyzPuBRe13hLQ==","_npmVersion":"10.8.3","description":"Unified Azure data access CLI for Log Analytics, Kusto, Azure SQL, and Storage Account","directories":{},"_nodeVersion":"24.3.0","dependencies":{"mssql":"^11.0.1","commander":"^12.1.0","@azure/identity":"^4.5.0","azure-kusto-data":"^6.0.0","@azure/data-tables":"^13.3.2","@azure/storage-blob":"^12.32.0","@azure/monitor-query":"^1.3.0","@azure/storage-queue":"^12.30.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"^1.1.0","typescript":"^5.6.0","@types/node":"^22.0.0","@types/mssql":"^9.1.5"},"_npmOperationalInternal":{"tmp":"tmp/nexus_0.1.0_1781016134191_0.7196333954971188","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@ascdong/nexus","version":"0.1.1","_id":"@ascdong/nexus@0.1.1","maintainers":[{"name":"ascdong","email":"rongyu.dong@outlook.com"}],"bin":{"nexus":"dist/cli.js"},"dist":{"shasum":"9094d3e269e493c0dbd802319088ef8dd91174de","tarball":"https://registry.npmjs.org/@ascdong/nexus/-/nexus-0.1.1.tgz","fileCount":24,"integrity":"sha512-4CXnAbHTrrMNlPBRvuxY7I8JRZInB02vCoNNlMknCttGnd8c22GTM5+qWl81id3qPrISPFMByjuw1pgDDpQrbA==","signatures":[{"sig":"MEYCIQDU3Jli5ayReqTfN7IO6JjN2gZQHC/JGinH1/QJuvNdigIhAPVaBt8cWrLBhqpmz0p9QYHibOCb4pUleyipkLlpJN6o","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50204},"type":"module","engines":{"node":">=20"},"gitHead":"52b0e01d5221c3fb27c4dc19289a08e67d75d111","scripts":{"dev":"bun run src/cli.ts","test":"bun test","build":"tsc","typecheck":"tsc --noEmit","test:watch":"bun test --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"ascdong","email":"rongyu.dong@outlook.com"},"_npmVersion":"11.7.0","description":"Unified Azure data access CLI for Log Analytics, Kusto, Azure SQL, and Storage Account","directories":{},"_nodeVersion":"25.4.0","dependencies":{"mssql":"^11.0.1","commander":"^12.1.0","@azure/identity":"^4.5.0","azure-kusto-data":"^6.0.0","@azure/data-tables":"^13.3.2","@azure/storage-blob":"^12.32.0","@azure/monitor-query":"^1.3.0","@azure/storage-queue":"^12.30.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"^1.1.0","typescript":"^5.6.0","@types/node":"^22.0.0","@types/mssql":"^9.1.5"},"_npmOperationalInternal":{"tmp":"tmp/nexus_0.1.1_1781019299227_0.8551476668599605","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@ascdong/nexus","version":"0.1.2","_id":"@ascdong/nexus@0.1.2","maintainers":[{"name":"ascdong","email":"rongyu.dong@outlook.com"}],"bin":{"nexus":"dist/cli.js"},"dist":{"shasum":"cb567e1e0b7e460c664bfbeb9cd7b4989f17356b","tarball":"https://registry.npmjs.org/@ascdong/nexus/-/nexus-0.1.2.tgz","fileCount":24,"integrity":"sha512-ds+QW4kIfFuCIpzFocYG1RBMiYDCO6vNm+Q0ldkUgsS2YAyNsNkl6iJ0lj7iaUQBytKlHqNFrmmJOH19P1yBkg==","signatures":[{"sig":"MEUCIBKiwWorocH7LeC77xneTBx7dPKlESFZ5dz7R6aG4T1xAiEA00wuf6GQm/4Ly9O2Bb4UChQmFPsRd2Y2ZPoiO4ONpMM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50208},"type":"module","engines":{"node":">=20"},"gitHead":"7fffa5f4eba67000a5fd5dc5619df82d0e2d47c3","scripts":{"dev":"bun run src/cli.ts","test":"bun test","build":"tsc","typecheck":"tsc --noEmit","test:watch":"bun test --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"ascdong","email":"rongyu.dong@outlook.com"},"_npmVersion":"11.7.0","description":"Unified Azure data access CLI for Log Analytics, Kusto, Azure SQL, and Storage Account","directories":{},"_nodeVersion":"25.4.0","dependencies":{"mssql":"^11.0.1","commander":"^12.1.0","@azure/identity":"^4.5.0","azure-kusto-data":"^6.0.0","@azure/data-tables":"^13.3.2","@azure/storage-blob":"^12.32.0","@azure/monitor-query":"^1.3.0","@azure/storage-queue":"^12.30.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"^1.1.0","typescript":"^5.6.0","@types/node":"^22.0.0","@types/mssql":"^9.1.5"},"_npmOperationalInternal":{"tmp":"tmp/nexus_0.1.2_1781021320353_0.5478466601134275","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@ascdong/nexus","version":"0.1.3","_id":"@ascdong/nexus@0.1.3","maintainers":[{"name":"ascdong","email":"rongyu.dong@outlook.com"}],"bin":{"nexus":"dist/cli.js"},"dist":{"shasum":"e00a82ea9c1e46eb4b56b0c2c3787d59777458f6","tarball":"https://registry.npmjs.org/@ascdong/nexus/-/nexus-0.1.3.tgz","fileCount":24,"integrity":"sha512-qQb77pINfWYBM7CU/HVbVsTGGoAuZuVGFdDOnjw1Gq3EyvlrgNgLrWP+ocJNfdlVTeBK6RIwx1J+UcJ6qYICRA==","signatures":[{"sig":"MEQCIHh0ckY9QIWTgdI6+0LT03kh+cI5OD2MfXnnngmaq83FAiBWLaPyJLYZflY7LpuvLMdGXcwRSqCAjzSqOgS9yvwWkQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":51073},"type":"module","engines":{"node":">=20"},"gitHead":"622f326f8d139f9bde7cb8cc24408109cd67776d","scripts":{"dev":"bun run src/cli.ts","test":"bun test","build":"tsc","typecheck":"tsc --noEmit","test:watch":"bun test --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"ascdong","email":"rongyu.dong@outlook.com"},"_npmVersion":"11.7.0","description":"Unified Azure data access CLI for Log Analytics, Kusto, Azure SQL, and Storage Account","directories":{},"_nodeVersion":"25.4.0","dependencies":{"mssql":"^11.0.1","commander":"^12.1.0","@azure/identity":"^4.5.0","azure-kusto-data":"^6.0.0","@azure/data-tables":"^13.3.2","@azure/storage-blob":"^12.32.0","@azure/monitor-query":"^1.3.0","@azure/storage-queue":"^12.30.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"^1.1.0","typescript":"^5.6.0","@types/node":"^22.0.0","@types/mssql":"^9.1.5"},"_npmOperationalInternal":{"tmp":"tmp/nexus_0.1.3_1781072164310_0.9974193229457273","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@ascdong/nexus","version":"0.1.4","_id":"@ascdong/nexus@0.1.4","maintainers":[{"name":"ascdong","email":"rongyu.dong@outlook.com"}],"bin":{"nexus":"dist/cli.js"},"dist":{"shasum":"5747becb4ab0d4368e8d6538b92829952950cb8c","tarball":"https://registry.npmjs.org/@ascdong/nexus/-/nexus-0.1.4.tgz","fileCount":26,"integrity":"sha512-WHPe4dhi+sKsPqN9VbZvjjiPqxaMnkMmMoURIwPFn3jqieaP8EWycrAlsqsxO26V6E3ocspvp+ydgoTrNR+Wvw==","signatures":[{"sig":"MEUCIH5eJdgfXQbD6ok4qPGVAKOaNvZ66flbmdXon7jha+mZAiEAjE7taO5vtrFjSybhRLwsYiEyyg3deRopR+46XDgu3bs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":70921},"type":"module","engines":{"node":">=20"},"gitHead":"b31ea2ea85d954264e7aa9676669d3a8d37fce39","scripts":{"dev":"bun run src/cli.ts","test":"bun test","build":"tsc","typecheck":"tsc --noEmit","test:watch":"bun test --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"ascdong","email":"rongyu.dong@outlook.com"},"_npmVersion":"11.7.0","description":"Unified Azure data access CLI for Log Analytics, Kusto, Azure SQL, PostgreSQL, and Storage Account","directories":{},"_nodeVersion":"25.4.0","dependencies":{"pg":"^8.21.0","mssql":"^11.0.1","commander":"^12.1.0","@azure/identity":"^4.5.0","azure-kusto-data":"^6.0.0","@azure/data-tables":"^13.3.2","@azure/storage-blob":"^12.32.0","@azure/monitor-query":"^1.3.0","@azure/storage-queue":"^12.30.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/pg":"^8.20.0","@types/bun":"^1.1.0","typescript":"^5.6.0","@types/node":"^22.0.0","@types/mssql":"^9.1.5"},"_npmOperationalInternal":{"tmp":"tmp/nexus_0.1.4_1781094805425_0.1254678706040704","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@ascdong/nexus","version":"0.1.5","_id":"@ascdong/nexus@0.1.5","maintainers":[{"name":"ascdong","email":"rongyu.dong@outlook.com"}],"bin":{"nexus":"dist/cli.js"},"dist":{"shasum":"8d078abcf7b273c26dae6aee8c1fc4d231ccbd8c","tarball":"https://registry.npmjs.org/@ascdong/nexus/-/nexus-0.1.5.tgz","fileCount":27,"integrity":"sha512-RCvoDar6/V8NGEvetK7HJH9riY0QOAf9GNTkU1XwFiYyt4/J5c5FiKJuXCFOnV2ZzeJE3otjjVEezk2JhP0S6w==","signatures":[{"sig":"MEQCIElkYqTt/sYeOngypPsS0g6LJAg6zxj1f0sxsq88RU5dAiBHYxd48A3qFp2EqT3yXHP2+cwAVWKiWhgEYFXJfPlOdA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":74701},"type":"module","engines":{"node":">=20"},"gitHead":"b31ea2ea85d954264e7aa9676669d3a8d37fce39","scripts":{"dev":"bun run src/cli.ts","test":"bun test","build":"tsc","typecheck":"tsc --noEmit","test:watch":"bun test --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"ascdong","email":"rongyu.dong@outlook.com"},"_npmVersion":"11.7.0","description":"Unified Azure data access CLI for Log Analytics, Kusto, SQL Server / Azure SQL, PostgreSQL, and Storage Account","directories":{},"_nodeVersion":"25.4.0","dependencies":{"pg":"^8.21.0","mssql":"^11.0.1","commander":"^12.1.0","@azure/identity":"^4.5.0","azure-kusto-data":"^6.0.0","@azure/data-tables":"^13.3.2","@azure/storage-blob":"^12.32.0","@azure/monitor-query":"^1.3.0","@azure/storage-queue":"^12.30.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/pg":"^8.20.0","@types/bun":"^1.1.0","typescript":"^5.6.0","@types/node":"^22.0.0","@types/mssql":"^9.1.5"},"_npmOperationalInternal":{"tmp":"tmp/nexus_0.1.5_1781098008854_0.4679996823135604","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"@ascdong/nexus","version":"0.1.6","description":"Unified Azure data access CLI for Log Analytics, Kusto, SQL Server / Azure SQL, PostgreSQL, and Storage Account","type":"module","bin":{"nexus":"dist/cli.js"},"publishConfig":{"access":"public"},"scripts":{"build":"tsc","dev":"bun run src/cli.ts","test":"bun test","test:watch":"bun test --watch","typecheck":"tsc --noEmit","prepublishOnly":"bun run build"},"engines":{"node":">=20"},"dependencies":{"@azure/data-tables":"^13.3.2","@azure/identity":"^4.5.0","@azure/monitor-query":"^1.3.0","@azure/storage-blob":"^12.32.0","@azure/storage-queue":"^12.30.0","azure-kusto-data":"^6.0.0","commander":"^12.1.0","mssql":"^11.0.1","pg":"^8.21.0"},"devDependencies":{"@types/bun":"^1.1.0","@types/mssql":"^9.1.5","@types/node":"^22.0.0","@types/pg":"^8.20.0","typescript":"^5.6.0"},"gitHead":"27c7eed56227d23b6d84d3c12f662e67a7976a46","_id":"@ascdong/nexus@0.1.6","_nodeVersion":"25.4.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-2Dg+yzpRhfAJQXxyCgrDC2AOMegGt3VMEjSaDt45TMDqKIisHDrOFD4qa0LkHjd1laqS0ttajNFwYkYe+MPfHg==","shasum":"f0fca5bb0bfaa881c21d602ee6d909b61f98b055","tarball":"https://registry.npmjs.org/@ascdong/nexus/-/nexus-0.1.6.tgz","fileCount":27,"unpackedSize":75612,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDMqYPbXd1K02J14hbLM0crc5Ug5v85x7zaZNqCYr5m6gIhAMiIkwd4bgFtfpor+feJRGJs99GQfeNjKPWaf3XEo2a5"}]},"_npmUser":{"name":"ascdong","email":"rongyu.dong@outlook.com"},"directories":{},"maintainers":[{"name":"ascdong","email":"rongyu.dong@outlook.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nexus_0.1.6_1781158050603_0.4833327395315663"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-09T14:42:14.051Z","modified":"2026-06-11T06:07:30.910Z","0.1.0":"2026-06-09T14:42:14.379Z","0.1.1":"2026-06-09T15:34:59.363Z","0.1.2":"2026-06-09T16:08:40.484Z","0.1.3":"2026-06-10T06:16:04.463Z","0.1.4":"2026-06-10T12:33:25.553Z","0.1.5":"2026-06-10T13:26:48.975Z","0.1.6":"2026-06-11T06:07:30.807Z"},"description":"Unified Azure data access CLI for Log Analytics, Kusto, SQL Server / Azure SQL, PostgreSQL, and Storage Account","maintainers":[{"name":"ascdong","email":"rongyu.dong@outlook.com"}],"readme":"# nexus\n\nUnified Azure data access CLI for **Log Analytics**, **Kusto** (Azure Data Explorer), **Azure SQL Database**, **PostgreSQL**, and **Storage Accounts** (Table/Blob/Queue). One command surface, named connectors, and Agent-friendly output.\n\n## Why\n\n`nexus` connects multiple Azure data resources through named *connectors* and exposes a single way to query them and inspect their schema. It is built primarily for **Agent consumption** (stable parsing, token-efficient output) while staying usable by humans.\n\n## Architecture\n\n`nexus` is a thin, uniform **data-access layer** in front of several data services that otherwise each have their own SDK, auth flow, query dialect, and result shape. A caller (an Agent or a human) issues one kind of command; nexus resolves the named connector, attaches the right credential, dispatches to the right backend adapter, and returns one normalized result shape in the caller's chosen format.\n\n```\n   +------------------------------------------------------------+\n   |   Caller:   an Agent   or   a human at a terminal          |\n   +------------------------------+-----------------------------+\n                                  |  one command surface\n                                  |  query / schema / sa / connector\n                                  v\n   +------------------------------------------------------------+\n   |  nexus CLI                                                 |\n   |                                                            |\n   |  commands --> registry(by type) --> Connector interface:   |\n   |                                       query                |\n   |                                       listTables           |\n   |                                       describeTable        |\n   |                                       testConnection       |\n   |                                                            |\n   |  config:     ~/.nexus/config.json                          |\n   |              (named connectors = coordinates only,         |\n   |               never secrets)                               |\n   |  credential: AAD / DefaultAzureCredential                  |\n   |              (+ on-disk token cache, per-service scope)    |\n   |                                                            |\n   |  output:     ResultSet --> table | json | envelope         |\n   |              (types normalized to one vocabulary:          |\n   |               string long real datetime bool dynamic)      |\n   +-----+---------------+---------------+---------------+------+\n         |               |               |               |\n         v               v               v               v\n   +-----------+   +-----------+   +-----------+   +-----------+\n   |log-       |   |kusto      |   |azure-     |   |storage-   |\n   |analytics  |   |(ADX)      |   |sql        |   |account    |\n   |(KQL)      |   |(KQL)      |   |(SQL)      |   |(no query  |\n   |           |   |           |   |           |   |language)  |\n   |Connector  |   |Connector  |   |Connector  |   |via sa:    |\n   |adapter    |   |adapter    |   |adapter    |   |tbl/blob/q |\n   +-----+-----+   +-----+-----+   +-----+-----+   +-----+-----+\n         v               v               v               v\n   Azure Monitor    ADX cluster    Azure SQL DB    Storage acct\n```\n\n**How it acts as a unified data-access layer:**\n\n1. **One surface, many backends.** `query` and `schema` work identically whether the target speaks KQL (Log Analytics, Kusto) or SQL (the `mssql` connector for SQL Server / Azure SQL, and `postgres`). You name a connector alias; nexus looks up its type and routes to the matching adapter — you never touch a per-service SDK or remember per-service flags.\n2. **A single `Connector` contract.** Every query-language backend implements the same four methods — `query`, `listTables`, `describeTable`, `testConnection`. A `registry` maps connector *type* → adapter, so adding a new resource type is one new adapter plus one registration; commands and core are untouched.\n3. **Shared identity, per-service scope.** All backends authenticate through one AAD credential (`DefaultAzureCredential`) with an on-disk token cache; each adapter just supplies its own token *scope*. Sign in once (`az login`) and every connector works.\n4. **One normalized result.** Backends return a common `ResultSet` (columns + rows), with column types normalized to a single vocabulary (`string`/`long`/`real`/`datetime`/`bool`/`dynamic`) regardless of source. The output layer renders that as `table` (humans) or `json`/`envelope` (Agents).\n5. **Honest about shape differences.** Storage Accounts aren't a query language, so they're deliberately *not* forced through `query`/`schema`; they get their own read-only `nexus sa` command group (Table/Blob/Queue) while still sharing the same connector config, credential, and output layer.\n\n## Install\n\nEnd users install from npm — no Bun required, it runs on Node:\n\n```bash\nnpm install -g @ascdong/nexus    # or: npm install @ascdong/nexus\n```\n\nRequires Node 20+.\n\n## Authentication\n\n`nexus` authenticates to Azure with **Microsoft Entra ID (AAD)** via `DefaultAzureCredential`. Before running queries, sign in with one of the standard mechanisms it understands:\n\n```bash\naz login        # most common for local use\n```\n\n`DefaultAzureCredential` also picks up environment variables, Managed Identity, and VS Code sign-in automatically.\n\n### Token cache\n\nAcquiring an AAD token cold is slow (~2–3s, because `DefaultAzureCredential` spawns the `az` CLI). To avoid paying that on every command, `nexus` caches the acquired token to `~/.nexus/token-cache.json` (file mode `0600`), keyed by scope, and refreshes it 1 minute before expiry. The first query in ~an hour is cold; subsequent queries reuse the cached token (token lookup drops from ~2s to ~0ms).\n\n> **Security note:** unlike `config.json`, the token cache **does contain a live access token** — anyone who can read the file can act as you against those resources until the token expires (typically ~1 hour). It is written `0600` (owner-only) and never committed to git. Clear it any time with:\n\n```bash\nnexus auth clear-cache\n```\n\nThe query round-trip and process startup are not affected by the cache; only token acquisition is.\n\n## Connectors\n\nConnectors are named aliases stored in `~/.nexus/config.json` (override the directory with `NEXUS_CONFIG_DIR`). Most connectors hold **connection coordinates only — never tokens or secrets** (they authenticate via AAD).\n\n> **Exception — secret-bearing auth modes.** Two opt-in modes persist a secret in `config.json`: a `storage-account` added with `--connection-string` (which embeds an account key) and a `postgres` connector (which stores its `--password`). When you use these, treat `~/.nexus/config.json` as sensitive — it is written owner-readable; do not commit it or share it. Prefer the AAD modes where a secret-free option exists (e.g. `storage-account --account`).\n\n```bash\n# Log Analytics\nnexus connector add prod-logs --type log-analytics --workspace-id <workspace-guid>\n\n# Kusto / Azure Data Explorer\nnexus connector add telemetry --type kusto \\\n  --cluster-uri https://help.kusto.windows.net --database Samples\n\n# SQL Server / Azure SQL Database\nnexus connector add warehouse --type mssql \\\n  --server myserver.database.windows.net --database Sales\n\n# PostgreSQL (username/password; works with Azure Database for PostgreSQL)\nnexus connector add pgwarehouse --type postgres \\\n  --host myserver.postgres.database.windows.net --database appdb \\\n  --user appuser --password <password> --ssl require   # --ssl disable for local/dev\n\n# Storage Account (Table + Blob + Queue) — AAD auth\nnexus connector add mydata --type storage-account --account <storageacct>\n\n# Storage Account — connection-string auth (embeds an account key)\nnexus connector add mydata-cs --type storage-account \\\n  --connection-string 'DefaultEndpointsProtocol=https;AccountName=<acct>;AccountKey=<key>;EndpointSuffix=core.windows.net'\n\nnexus connector list            # list all connectors (table; secrets redacted)\nnexus connector list --output json   # machine-readable (secrets still redacted)\nnexus connector test prod-logs  # verify connectivity\nnexus connector remove prod-logs\n```\n\n`connector list` renders a human-readable table (`alias`, `type`, `status`, `auth`, `detail`) and **never prints secrets** — a storage connection string or postgres password always shows as `<redacted>`, in every output format.\n\n### Disable / enable\n\nA connector can be **disabled** to block all data access through it (`query`, `schema`, `sa`, and `connector test`) without deleting its config:\n\n```bash\nnexus connector disable silicon-db   # anyone can disable (the safe direction)\nnexus connector enable  silicon-db   # interactive terminal only — re-type the alias to confirm\n```\n\nWhile disabled, every data-access command for that alias fails with a `CONFIG_ERROR` (exit 2); management commands (`list`, `remove`, `enable`) still work. **`enable` is human-gated**: it refuses to run unless invoked from an interactive TTY and the operator re-types the alias. A non-interactive caller (e.g. an automated agent piping `stdin`) is rejected before any change is made.\n\n> This is a guardrail against accidental/automated re-enabling, not a cryptographic boundary: a human and an agent share the same OS user and binary, so anything the human can type, the same shell could. The TTY gate raises the bar (an agent driving nexus non-interactively cannot enable), but it does not defend against an adversary that can allocate a real terminal.\n\n## Query\n\n```bash\nnexus query <alias> \"<statement>\" [--output <fmt>] [--max-rows N] [--timeout MS]\n```\n\nThe statement is KQL for Log Analytics / Kusto, and SQL for Azure SQL / PostgreSQL:\n\n```bash\nnexus query telemetry \"StormEvents | take 5\"\nnexus query warehouse \"SELECT TOP 5 * FROM Orders\"\n```\n\n`--max-rows` caps the returned rows (default 1000) to protect downstream context; when the cap is hit, the result is flagged `truncated`.\n\n## Schema introspection\n\n```bash\nnexus schema tables <alias>                 # list tables\nnexus schema describe <alias> <table>       # columns + normalized types\n```\n\n## Storage Account\n\nA `storage-account` connector exposes three services under `nexus sa` (alias of\n`storageaccount`). It is **not** used with `query`/`schema` — those are for the query\nlanguages. All operations are read-only.\n\n```bash\n# Table Storage — query is table + OData filter + select (not a single-string language)\nnexus sa table list  mydata\nnexus sa table query mydata MyTable --filter \"PartitionKey eq 'orders'\" --select RowKey,Amount\n\n# Blob\nnexus sa blob containers mydata\nnexus sa blob list mydata mycontainer --prefix logs/\nnexus sa blob read mydata mycontainer report.csv               # bytes -> stdout\nnexus sa blob read mydata mycontainer image.png -o image.png   # binary -> file\n\n# Queue\nnexus sa queue list  mydata\nnexus sa queue peek  mydata myqueue --count 10                 # does not dequeue\nnexus sa queue count mydata myqueue\n```\n\nThe tabular commands (`table list/query`, `blob containers/list`, `queue list/peek`) honor\n`--output table|json|envelope`. `blob read` returns raw bytes and ignores output formatting\nby design — use `-o <file>` for binary blobs. All three services authenticate with the same\nAAD identity (scope `https://storage.azure.com/.default`); data access requires a data-plane\nrole such as *Storage Blob/Table/Queue Data Reader* (control-plane roles like *Owner* do not\ngrant data access).\n\n## Output formats\n\n`--output` selects the format. Default is **table** (human-readable). Agents should use `json` or `envelope`.\n\n| Format | Shape | Best for |\n|---|---|---|\n| `table` (default) | aligned columns | humans |\n| `json` | array of objects keyed by column name | quick scripting |\n| `envelope` | columns declared once + rows as arrays + metadata | Agents (token-efficient) |\n\nExample `envelope` output:\n\n```json\n{\n  \"status\": \"ok\",\n  \"columns\": [{ \"name\": \"Name\", \"type\": \"string\" }, { \"name\": \"Count\", \"type\": \"long\" }],\n  \"rows\": [[\"a\", 1], [\"b\", 2]],\n  \"row_count\": 2,\n  \"truncated\": false\n}\n```\n\nThe `envelope` form declares column names once (instead of repeating them on every row), which keeps large result sets compact in an Agent's context window. Column types are normalized to a unified vocabulary (`string`, `long`, `real`, `datetime`, `bool`, `dynamic`) across all three resource types.\n\n## Output channels & exit codes\n\n- **Results** go to **stdout**; **diagnostic logs** go to **stderr** — so an Agent can parse stdout cleanly.\n- Exit codes: `0` success, `1` query/connection/auth error, `2` usage/config error.\n\nOn error, `json`/`envelope` mode writes a structured `{ \"status\": \"error\", \"code\": \"...\", \"message\": \"...\" }` to **stdout** (so the single stream stays self-describing — `status` is `\"ok\"` or `\"error\"`), while the default `table` mode prints `error [CODE]: message` to **stderr**. Either way the exit code is non-zero.\n\n## Extending\n\n- **New resource type:** implement the `Connector` interface in `src/connectors/`, then register it in `src/cli.ts` — no changes to commands or core.\n- **New auth method:** implement `CredentialProvider` in `src/core/credential.ts` and select it in `createCredential` — connectors are unaffected, since each connector supplies its own token scope.\n\n## Development\n\nDevelopment uses [Bun](https://bun.sh) for fast installs, running, and tests. The published package is plain Node — Bun is a dev-time tool only.\n\n```bash\nbun install            # install deps (generates bun.lock)\nbun test               # run the test suite\nbun run dev <args>     # run from source, no build step\nbun run typecheck      # tsc --noEmit\nbun run build          # tsc → dist/ (the Node-runnable artifact that ships)\n```\n\n**Publishing:** `bun run build` (via `prepublishOnly`) compiles `src/` to standard Node ESM in `dist/` with a `#!/usr/bin/env node` shebang, then `bun publish` (or `npm publish`) uploads it. End users `npm install` and run it on Node — they never need Bun.\n\n### Known limitation: the `mssql` connector under the Bun runtime\n\nQuerying via the **`mssql`** connector (SQL Server / Azure SQL) fails under `bun run` (`ESOCKET — Connection lost / socket hang up`). This is an open Bun regression in its `node:net` compatibility layer that breaks the `tedious` (mssql) TDS-over-TLS handshake on some kernels (including WSL2); it is **not** a bug in this project — the same `mssql` call works under Node. Kusto and Log Analytics use plain HTTPS and are unaffected.\n\nThe fix is to run `mssql` queries on **Node** during development:\n\n```bash\nbun run build                                   # produce dist/ once\nnode dist/cli.js query <mssql-alias> \"SELECT ...\" # mssql: use node\nbun run dev query <kusto-or-la-alias> \"...\"      # Kusto / LA: bun is fine\n```\n\nThe published package runs on Node, so **end users are never affected** — all three resource types work normally via `npm install`.\n\nSee `docs/superpowers/specs/` and `docs/superpowers/plans/` for the full design and implementation plan.\n","readmeFilename":"README.md"}