@opennous/cli 0.7.1 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +4 -8
  2. package/package.json +1 -1
  3. package/src/index.js +19 -14
package/README.md CHANGED
@@ -4,18 +4,14 @@ Nous CLI — set Nous up, connect it to your coding agent, and read the Context
4
4
 
5
5
  ## Get started
6
6
 
7
- ```bash
8
- curl -fsSL https://api.opennous.cloud/install | sh
9
- ```
10
-
11
- That installs the CLI and runs `nous init`, which signs you in (creating your account if you don't have one), registers the Nous MCP server with the agent on your machine, and hands off. Then tell your agent *"set up my Nous workspace"* — it reads your project, finds your ICP (or drafts one), and syncs it.
12
-
13
- Prefer to run it yourself:
7
+ One command. It signs you in (creating your account if you don't have one), registers the Nous MCP server with the agent on your machine, and hands off. The same command on macOS, Linux, and Windows (needs [Node 18+](https://nodejs.org)):
14
8
 
15
9
  ```bash
16
- npx -y @opennous/cli@latest init
10
+ npx @opennous/cli@latest init
17
11
  ```
18
12
 
13
+ Then tell your agent *"set up my Nous workspace"* — it reads your project, finds your ICP (or drafts one), and syncs it. On self-host, add `--url https://api.yourdomain.com`.
14
+
19
15
  ## Event tracking
20
16
 
21
17
  `nous track init` detects your stack (Next.js, Node, Python), writes a small `nous.js` (or `nous.py`) module with three helpers, and updates your `.env`:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opennous/cli",
3
- "version": "0.7.1",
3
+ "version": "0.7.4",
4
4
  "description": "Nous CLI — set up Nous, connect it to your coding agent, and read the Context API from your terminal",
5
5
  "type": "module",
6
6
  "bin": {
package/src/index.js CHANGED
@@ -8,7 +8,7 @@
8
8
  import { program, Command } from "commander";
9
9
  import { readFileSync, writeFileSync, existsSync, mkdirSync, appendFileSync } from "fs";
10
10
  import { homedir } from "os";
11
- import { join, resolve } from "path";
11
+ import { join, resolve, dirname } from "path";
12
12
  import { createInterface } from "readline";
13
13
  import { spawn, spawnSync } from "child_process";
14
14
 
@@ -32,12 +32,16 @@ function openBrowser(url) {
32
32
  if (process.platform === "darwin") {
33
33
  cmd = "open"; args = [url];
34
34
  } else if (process.platform === "win32") {
35
- // cmd.exe /c start "" "<url>". The empty "" is start's title argument (else a
36
- // quoted URL is taken as the window title). windowsVerbatimArguments keeps the
37
- // quotes we add, so an & in the auth URL's query string stays inside them and
38
- // isn't parsed by cmd as a command separator.
35
+ // cmd.exe /c start "" "<url>". `start` reads a lone quoted arg as the window
36
+ // TITLE, so it needs an explicit empty title before the URL — otherwise it just
37
+ // opens a shell titled with the URL and never launches the browser.
38
+ // CRITICAL: the title must be a LITERAL `""` string, not JS's zero-length "".
39
+ // With windowsVerbatimArguments the args are joined by spaces as-is, so a
40
+ // zero-length string collapses to nothing and the title is lost (the URL then
41
+ // becomes the title). Verbatim also keeps our quotes, so an & in the auth URL's
42
+ // query string stays inside them and isn't parsed by cmd as a command separator.
39
43
  cmd = process.env.ComSpec || "cmd.exe";
40
- args = ["/c", "start", "", `"${url}"`];
44
+ args = ["/c", "start", '""', `"${url}"`];
41
45
  opts.windowsVerbatimArguments = true;
42
46
  } else {
43
47
  cmd = "xdg-open"; args = [url];
@@ -831,7 +835,7 @@ program
831
835
  // ---------------------------------------------------------------------------
832
836
  // Browser sign-in (device authorization). Opens the browser, you approve, and a
833
837
  // freshly minted API key is saved to ~/.nous/config.json. No copy-paste. Shared
834
- // by `nous login`, `nous init`, and the plugin's /nous-login command.
838
+ // by `nous login` and `nous init`.
835
839
  // ---------------------------------------------------------------------------
836
840
  async function browserLogin(url) {
837
841
  const apiUrl = url || process.env.NOUS_API_URL || readConfig().apiUrl || "https://api.opennous.cloud";
@@ -894,10 +898,11 @@ program
894
898
  // ---------------------------------------------------------------------------
895
899
  // MCP registration — connect Nous to whatever agent is on this machine.
896
900
  //
897
- // We deliberately DO NOT use the Claude Code plugin/marketplace here. Two commands
898
- // (`/plugin marketplace add`, `/plugin install`), Claude-Code-only, with a marketplace
899
- // standing between a new user and the product — it's too much for a first run. The MCP
900
- // server is the whole integration, and `claude mcp add` registers it in one line.
901
+ // There is deliberately no Claude Code plugin/marketplace. A plugin would be Claude-Code-only
902
+ // and put a marketplace between a new user and the product — too much for a first run, and it
903
+ // wouldn't work for Cursor, Codex, or any other host. The MCP server is the whole integration,
904
+ // so registration is one cross-platform step: `claude mcp add` if the Claude CLI is here, else
905
+ // a `.mcp.json` any MCP host reads.
901
906
  //
902
907
  // The MCP resolves its key from ~/.nous/config.json on every call, so we never bake the
903
908
  // key into any of these configs — sign-in already wrote it there.
@@ -927,7 +932,7 @@ function writeJsonMcp(path, apiUrl) {
927
932
  // Only pin a non-default API URL (self-host). Cloud reads the key from the config file.
928
933
  ...(apiUrl && apiUrl !== "https://api.opennous.cloud" ? { env: { NOUS_API_URL: apiUrl } } : {}),
929
934
  };
930
- const dir = path.slice(0, path.lastIndexOf("/"));
935
+ const dir = dirname(path);
931
936
  if (dir && !existsSync(dir)) mkdirSync(dir, { recursive: true });
932
937
  writeFileSync(path, JSON.stringify(cfg, null, 2) + "\n");
933
938
  }
@@ -977,8 +982,8 @@ program
977
982
  }
978
983
  }
979
984
 
980
- console.log('\nYou\'re set. Tell your agent: "set up my GTM context layer and connect it to');
981
- console.log("Nous\" — it audits your project's context, drafts what's missing, and syncs it.\n");
985
+ console.log("\nYou're set. Tell your agent:\n");
986
+ console.log(' "set up my Nous workspace and walk me through onboarding"\n');
982
987
  console.log(dim("Docs: https://docs.opennous.cloud/mcp/introduction"));
983
988
  });
984
989