@creator-notes/cnotes 0.24.3 → 0.25.2

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 (37) hide show
  1. package/dist/commands/auth.d.ts +1 -1
  2. package/dist/commands/auth.d.ts.map +1 -1
  3. package/dist/commands/auth.js +72 -8
  4. package/dist/commands/auth.js.map +1 -1
  5. package/dist/commands/canvas.d.ts.map +1 -1
  6. package/dist/commands/canvas.js +122 -20
  7. package/dist/commands/canvas.js.map +1 -1
  8. package/dist/commands/config.d.ts.map +1 -1
  9. package/dist/commands/config.js +10 -3
  10. package/dist/commands/config.js.map +1 -1
  11. package/dist/commands/operations.d.ts.map +1 -1
  12. package/dist/commands/operations.js +21 -19
  13. package/dist/commands/operations.js.map +1 -1
  14. package/dist/commands/workspace.d.ts.map +1 -1
  15. package/dist/commands/workspace.js +171 -1
  16. package/dist/commands/workspace.js.map +1 -1
  17. package/dist/lib/api-client.d.ts +35 -9
  18. package/dist/lib/api-client.d.ts.map +1 -1
  19. package/dist/lib/api-client.js +60 -24
  20. package/dist/lib/api-client.js.map +1 -1
  21. package/dist/lib/auth-store.d.ts +50 -11
  22. package/dist/lib/auth-store.d.ts.map +1 -1
  23. package/dist/lib/auth-store.js +47 -12
  24. package/dist/lib/auth-store.js.map +1 -1
  25. package/dist/lib/install-mcp.d.ts.map +1 -1
  26. package/dist/lib/install-mcp.js +19 -1
  27. package/dist/lib/install-mcp.js.map +1 -1
  28. package/dist/lib/output.d.ts +7 -0
  29. package/dist/lib/output.d.ts.map +1 -1
  30. package/dist/lib/output.js +16 -0
  31. package/dist/lib/output.js.map +1 -1
  32. package/dist/lib/server-url.d.ts +33 -0
  33. package/dist/lib/server-url.d.ts.map +1 -0
  34. package/dist/lib/server-url.js +106 -0
  35. package/dist/lib/server-url.js.map +1 -0
  36. package/package.json +3 -3
  37. package/skills/cnotes/SKILL.md +59 -4
@@ -2,7 +2,10 @@ import { readFileSync, writeFileSync, mkdirSync, chmodSync, existsSync, renameSy
2
2
  import { join } from "node:path";
3
3
  import { homedir } from "node:os";
4
4
  import { BRAND } from "./brand.js";
5
- const CONFIG_DIR = join(homedir(), BRAND.configDir);
5
+ // CNOTES_CONFIG_DIR redirects the whole config store (used by tests to work
6
+ // against a temp dir instead of the real ~/.cnotes, and handy for sandboxed or
7
+ // multi-profile setups). Unset in normal use, which is the homedir default.
8
+ const CONFIG_DIR = process.env.CNOTES_CONFIG_DIR || join(homedir(), BRAND.configDir);
6
9
  const CONFIG_FILE = join(CONFIG_DIR, "config.json");
7
10
  /**
8
11
  * One-time migration of the pre-rename config dir (`~/.creatornotes`) to the
@@ -80,40 +83,71 @@ export function setCurrentServer(config, serverUrl) {
80
83
  config.currentServer = serverUrl;
81
84
  saveConfig(config);
82
85
  }
86
+ /**
87
+ * Persist the active workspace for a server. Returns false (a no-op) when there
88
+ * is no stored config entry for `serverUrl` — i.e. the token came from a flag or
89
+ * env var against a server never logged into with `cnotes auth login`, so there
90
+ * is nowhere on disk to record the selection. Callers that report activation
91
+ * back to a caller should surface this instead of claiming success.
92
+ */
83
93
  export function setWorkspaceId(config, serverUrl, workspaceId) {
84
94
  const sc = config.servers[serverUrl];
85
95
  if (sc) {
86
96
  sc.workspaceId = workspaceId;
87
97
  saveConfig(config);
98
+ return true;
88
99
  }
100
+ return false;
89
101
  }
90
102
  /**
91
103
  * Mark a given agent-run as the active one for a server. Subsequent cnotes
92
- * writes against this server will carry X-Agent-Run-Id automatically.
104
+ * writes against this server will carry X-Agent-Run-Id automatically —
105
+ * plus X-Agent-Before-Snapshot-Id when `beforeSnapshotId` is given (canvas
106
+ * runs), which is what makes the run revertable.
107
+ *
108
+ * Returns false (a no-op) when there is no stored config entry for `serverUrl`
109
+ * — i.e. the token came from a flag or env var against a server never logged
110
+ * into with `cnotes auth login`, so there is nowhere on disk to record the run.
111
+ * Callers MUST surface this instead of claiming the run is active: silently
112
+ * persisting nothing is exactly how bracketed agent writes end up recorded as
113
+ * unattributed human edits. Same contract as setWorkspaceId above.
93
114
  */
94
- export function setActiveAgentRunId(config, serverUrl, agentRunId, startedAt) {
115
+ export function setActiveAgentRunId(config, serverUrl, agentRunId, startedAt, beforeSnapshotId) {
95
116
  const sc = config.servers[serverUrl];
96
- if (sc) {
97
- sc.activeAgentRunId = agentRunId;
98
- sc.activeAgentRunStartedAt = startedAt;
99
- saveConfig(config);
117
+ if (!sc)
118
+ return false;
119
+ sc.activeAgentRunId = agentRunId;
120
+ sc.activeAgentRunStartedAt = startedAt;
121
+ // Always write the slot, so a canvas run never inherits the stale
122
+ // before-snapshot of a previous run (which belongs to a different canvas and
123
+ // would be dropped server-side anyway, silently costing revertability).
124
+ if (beforeSnapshotId) {
125
+ sc.activeAgentBeforeSnapshotId = beforeSnapshotId;
126
+ }
127
+ else {
128
+ delete sc.activeAgentBeforeSnapshotId;
100
129
  }
130
+ saveConfig(config);
131
+ return true;
101
132
  }
102
133
  /**
103
- * Clear the active agent-run for a server. Called by `cnotes operations end`
104
- * after a successful close, so the next cnotes write reverts to "unattached"
105
- * unless the user opens a new run.
134
+ * Clear the active agent-run for a server. Called by `cnotes operations end` /
135
+ * `cnotes canvas agent-run end` after a successful close, so the next cnotes
136
+ * write reverts to "unattached" unless the user opens a new run.
106
137
  */
107
138
  export function clearActiveAgentRunId(config, serverUrl) {
108
139
  const sc = config.servers[serverUrl];
109
- if (sc && (sc.activeAgentRunId || sc.activeAgentRunStartedAt)) {
140
+ if (sc &&
141
+ (sc.activeAgentRunId || sc.activeAgentRunStartedAt || sc.activeAgentBeforeSnapshotId)) {
110
142
  delete sc.activeAgentRunId;
111
143
  delete sc.activeAgentRunStartedAt;
144
+ delete sc.activeAgentBeforeSnapshotId;
112
145
  saveConfig(config);
113
146
  }
114
147
  }
115
148
  /**
116
- * Read the active agent-run for a server (if any).
149
+ * Read the active agent-run for a server (if any). `beforeSnapshotId` is
150
+ * present only for canvas runs (see the field docs on ServerConfig).
117
151
  */
118
152
  export function getActiveAgentRunId(config, serverUrl) {
119
153
  const sc = config.servers[serverUrl];
@@ -121,6 +155,7 @@ export function getActiveAgentRunId(config, serverUrl) {
121
155
  return {
122
156
  agentRunId: sc.activeAgentRunId,
123
157
  startedAt: sc.activeAgentRunStartedAt,
158
+ beforeSnapshotId: sc.activeAgentBeforeSnapshotId,
124
159
  };
125
160
  }
126
161
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"auth-store.js","sourceRoot":"","sources":["../../src/lib/auth-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth-store.js","sourceRoot":"","sources":["../../src/lib/auth-store.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"install-mcp.d.ts","sourceRoot":"","sources":["../../src/lib/install-mcp.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE3C,UAAU,aAAa;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAuBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAEvD;AAwHD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,GAAG,aAAa,CAExF"}
1
+ {"version":3,"file":"install-mcp.d.ts","sourceRoot":"","sources":["../../src/lib/install-mcp.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE3C,UAAU,aAAa;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAuBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAEvD;AA0ID,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,GAAG,aAAa,CAExF"}
@@ -4,7 +4,7 @@
4
4
  * Reads existing config, merges the CN MCP server entry, writes back.
5
5
  * Creates config file/directory if they don't exist.
6
6
  */
7
- import { readFileSync, writeFileSync, mkdirSync, existsSync, copyFileSync } from "fs";
7
+ import { readFileSync, writeFileSync, mkdirSync, existsSync, copyFileSync, chmodSync } from "fs";
8
8
  import { dirname, resolve } from "path";
9
9
  import { homedir } from "os";
10
10
  import { fileURLToPath } from "url";
@@ -28,6 +28,22 @@ function getCodexConfigPath() {
28
28
  export function getConfigPath(target) {
29
29
  return target === "claude" ? getClaudeConfigPath() : getCodexConfigPath();
30
30
  }
31
+ /**
32
+ * Restrict an MCP config file to owner read/write (0600). These files embed
33
+ * CNOTES_TOKEN in plaintext (the MCP env convention), so they carry a bearer
34
+ * credential and should match ~/.cnotes/config.json's posture rather than
35
+ * inherit the default umask (typically 0644, group/world-readable). SOC2
36
+ * pen-test HIGH-2 remediation. Best-effort: a chmod failure (e.g. Windows,
37
+ * where POSIX modes don't apply) must not abort a successful install.
38
+ */
39
+ function lockDownConfigFile(configPath) {
40
+ try {
41
+ chmodSync(configPath, 0o600);
42
+ }
43
+ catch {
44
+ /* non-POSIX FS or perms already managed — the write itself succeeded */
45
+ }
46
+ }
31
47
  // ── MCP server entry ────────────────────────────────────────
32
48
  function getMcpServerPath() {
33
49
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -76,6 +92,7 @@ function installClaude(cfg) {
76
92
  mcpServers.cnotes = buildMcpEntry(cfg);
77
93
  existing.mcpServers = mcpServers;
78
94
  writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
95
+ lockDownConfigFile(configPath);
79
96
  return { configPath, created, backedUp: created ? undefined : backedUp };
80
97
  }
81
98
  // ── Codex (TOML) ────────────────────────────────────────────
@@ -124,6 +141,7 @@ function installCodex(cfg) {
124
141
  else {
125
142
  writeFileSync(configPath, block + "\n", "utf-8");
126
143
  }
144
+ lockDownConfigFile(configPath);
127
145
  return { configPath, created, backedUp: created ? undefined : backedUp };
128
146
  }
129
147
  // ── Public API ──────────────────────────────────────────────
@@ -1 +1 @@
1
- {"version":3,"file":"install-mcp.js","sourceRoot":"","sources":["../../src/lib/install-mcp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"install-mcp.js","sourceRoot":"","sources":["../../src/lib/install-mcp.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,13 @@ export declare function outputTable(headers: string[], rows: string[][]): void;
22
22
  * Format a timestamp as relative time (e.g., "2h ago", "3d ago").
23
23
  */
24
24
  export declare function timeAgo(timestamp: number | string): string;
25
+ /**
26
+ * Like timeAgo, but keeps second-level precision instead of collapsing the
27
+ * first minute to "just now". Used by the agent-run conflict messages, where
28
+ * "started 8s ago" vs "started 3h ago" is the whole signal: it tells you
29
+ * whether you just opened this run in another shell or left one stranded.
30
+ */
31
+ export declare function formatAgo(startedAtMs: number): string;
25
32
  /**
26
33
  * Truncate a string to a max length with ellipsis.
27
34
  */
@@ -1 +1 @@
1
- {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAYvE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAEjE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,EAAE,MAAM,EAAE,EAAE,GACf,IAAI,CAeN;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAa1D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGzD"}
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAYvE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAEjE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,EAAE,MAAM,EAAE,EAAE,GACf,IAAI,CAeN;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAa1D;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAOrD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGzD"}
@@ -67,6 +67,22 @@ export function timeAgo(timestamp) {
67
67
  return `${minutes}m ago`;
68
68
  return "just now";
69
69
  }
70
+ /**
71
+ * Like timeAgo, but keeps second-level precision instead of collapsing the
72
+ * first minute to "just now". Used by the agent-run conflict messages, where
73
+ * "started 8s ago" vs "started 3h ago" is the whole signal: it tells you
74
+ * whether you just opened this run in another shell or left one stranded.
75
+ */
76
+ export function formatAgo(startedAtMs) {
77
+ const sec = Math.max(0, Math.round((Date.now() - startedAtMs) / 1000));
78
+ if (sec < 60)
79
+ return `${sec}s ago`;
80
+ const min = Math.round(sec / 60);
81
+ if (min < 60)
82
+ return `${min}m ago`;
83
+ const hr = Math.round(min / 60);
84
+ return `${hr}h ago`;
85
+ }
70
86
  /**
71
87
  * Truncate a string to a max length with ellipsis.
72
88
  */
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The host is the official product host or a subdomain of it
3
+ * (e.g. clio.creatornotes.app for the single-tenant enterprise instance).
4
+ */
5
+ export declare function isOfficialServer(url: string): boolean;
6
+ /**
7
+ * Parse + validate a server URL. Throws a legible Error on input that can't be
8
+ * a real server: non-absolute, a scheme other than http/https, or plain http to
9
+ * a remote host. Returns the normalized origin + path (query/hash dropped —
10
+ * they're meaningless on a server base URL, and leaving them would defeat the
11
+ * trailing-slash normalization).
12
+ */
13
+ export declare function validateServerUrl(raw: string): string;
14
+ /**
15
+ * The set of browser origins allowed to call the CLI's localhost login callback.
16
+ *
17
+ * Normally just the server's own origin. For a LOOPBACK dev server we also allow
18
+ * the sibling form, because the /auth/cli page rewrites 127.0.0.1 -> localhost so
19
+ * that OAuth cookies (set on `localhost`) resolve — meaning a CLI pointed at
20
+ * `http://127.0.0.1:3000` receives the callback from origin `http://localhost:3000`.
21
+ * Without the sibling, CORS would mismatch: login still completes (CORS gates
22
+ * READING the response, not sending the GET), but the page would fall back to the
23
+ * manual screen for no reason. The first entry is the canonical origin.
24
+ */
25
+ export declare function allowedCallbackOrigins(serverUrl: string): Set<string>;
26
+ /**
27
+ * A one-line human warning when the target host isn't the official product host
28
+ * or localhost — the moment where a phished custom server would bite. Returns
29
+ * the warning string (so callers can print it once) or null when the host is
30
+ * trusted. Callers decide where to print; this never throws.
31
+ */
32
+ export declare function unofficialServerWarning(url: string): string | null;
33
+ //# sourceMappingURL=server-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-url.d.ts","sourceRoot":"","sources":["../../src/lib/server-url.ts"],"names":[],"mappings":"AA4BA;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAUrD;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA2BrD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CASrE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWlE"}
@@ -0,0 +1,106 @@
1
+ import { BRAND } from "./brand.js";
2
+ /**
3
+ * Server-URL safety checks (SOC2 pen-test MEDIUM-2 remediation).
4
+ *
5
+ * `cnotes config set-server` and `auth login` will talk to whatever URL they're
6
+ * given, and `auth login --token` sends your real API key there to validate it.
7
+ * A malicious doc that says "run `cnotes config set-server https://evil.example`"
8
+ * could otherwise phish the key. We don't hard-block custom servers — local dev
9
+ * (`--server http://localhost:3000`) and enterprise subdomains
10
+ * (`https://clio.creatornotes.app`) are legitimate — but we reject obviously
11
+ * malformed input and warn loudly before trusting an unofficial host.
12
+ */
13
+ // hostname, not host: `host` carries the port, so an enterprise instance on a
14
+ // nonstandard port (clio.creatornotes.app:8443) would otherwise read as
15
+ // unofficial and warn on every command.
16
+ const OFFICIAL_HOSTNAME = new URL(BRAND.url).hostname; // creatornotes.app
17
+ // URL.hostname drops the port but KEEPS the brackets on IPv6 literals, so the
18
+ // loopback address arrives as "[::1]", never bare. Both forms are listed so a
19
+ // caller that hands us a pre-stripped hostname is still recognized.
20
+ const LOOPBACK_HOSTNAMES = new Set(["localhost", "127.0.0.1", "[::1]", "::1"]);
21
+ function isLoopbackHostname(hostname) {
22
+ return LOOPBACK_HOSTNAMES.has(hostname.toLowerCase());
23
+ }
24
+ /**
25
+ * The host is the official product host or a subdomain of it
26
+ * (e.g. clio.creatornotes.app for the single-tenant enterprise instance).
27
+ */
28
+ export function isOfficialServer(url) {
29
+ try {
30
+ const hostname = new URL(url).hostname.toLowerCase();
31
+ return (hostname === OFFICIAL_HOSTNAME ||
32
+ hostname.endsWith(`.${OFFICIAL_HOSTNAME}`));
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ }
38
+ /**
39
+ * Parse + validate a server URL. Throws a legible Error on input that can't be
40
+ * a real server: non-absolute, a scheme other than http/https, or plain http to
41
+ * a remote host. Returns the normalized origin + path (query/hash dropped —
42
+ * they're meaningless on a server base URL, and leaving them would defeat the
43
+ * trailing-slash normalization).
44
+ */
45
+ export function validateServerUrl(raw) {
46
+ let parsed;
47
+ try {
48
+ parsed = new URL(raw);
49
+ }
50
+ catch {
51
+ throw new Error(`Invalid server URL: "${raw}". Use an absolute URL like https://creatornotes.app or http://localhost:3000.`);
52
+ }
53
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
54
+ throw new Error(`Unsupported server URL scheme "${parsed.protocol}" in "${raw}". Only http and https are allowed.`);
55
+ }
56
+ // Plain http is only reasonable for local development. Anything else in the
57
+ // clear is a downgrade that would expose the Bearer key on the wire.
58
+ if (parsed.protocol === "http:" && !isLoopbackHostname(parsed.hostname)) {
59
+ throw new Error(`Refusing an insecure http:// server for a non-local host ("${parsed.hostname}"). ` +
60
+ `Use https:// (or http://localhost for local dev).`);
61
+ }
62
+ // Normalize off the parsed parts rather than string-replacing the tail of
63
+ // toString(): a trailing slash isn't terminal when a query/hash follows
64
+ // ("https://x.com/?a=1"), so a regex on the full string would miss it.
65
+ const path = parsed.pathname.replace(/\/+$/, "");
66
+ return `${parsed.origin}${path}`;
67
+ }
68
+ /**
69
+ * The set of browser origins allowed to call the CLI's localhost login callback.
70
+ *
71
+ * Normally just the server's own origin. For a LOOPBACK dev server we also allow
72
+ * the sibling form, because the /auth/cli page rewrites 127.0.0.1 -> localhost so
73
+ * that OAuth cookies (set on `localhost`) resolve — meaning a CLI pointed at
74
+ * `http://127.0.0.1:3000` receives the callback from origin `http://localhost:3000`.
75
+ * Without the sibling, CORS would mismatch: login still completes (CORS gates
76
+ * READING the response, not sending the GET), but the page would fall back to the
77
+ * manual screen for no reason. The first entry is the canonical origin.
78
+ */
79
+ export function allowedCallbackOrigins(serverUrl) {
80
+ const { origin, protocol, hostname, port } = new URL(serverUrl);
81
+ const origins = new Set([origin]);
82
+ const sibling = hostname === "localhost" ? "127.0.0.1" : hostname === "127.0.0.1" ? "localhost" : null;
83
+ if (sibling) {
84
+ origins.add(`${protocol}//${sibling}${port ? `:${port}` : ""}`);
85
+ }
86
+ return origins;
87
+ }
88
+ /**
89
+ * A one-line human warning when the target host isn't the official product host
90
+ * or localhost — the moment where a phished custom server would bite. Returns
91
+ * the warning string (so callers can print it once) or null when the host is
92
+ * trusted. Callers decide where to print; this never throws.
93
+ */
94
+ export function unofficialServerWarning(url) {
95
+ try {
96
+ const { hostname, host } = new URL(url);
97
+ if (isLoopbackHostname(hostname) || isOfficialServer(url))
98
+ return null;
99
+ return (`Warning: "${host}" is not an official CreatorNotes server. ` +
100
+ `Only continue if you set this deliberately — a custom server you send your API key to can capture it.`);
101
+ }
102
+ catch {
103
+ return null;
104
+ }
105
+ }
106
+ //# sourceMappingURL=server-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-url.js","sourceRoot":"","sources":["../../src/lib/server-url.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@creator-notes/cnotes",
3
- "version": "0.24.3",
3
+ "version": "0.25.2",
4
4
  "description": "CLI for CreatorNotes — create notes, build canvases, search knowledge from the terminal",
5
5
  "type": "module",
6
6
  "bin": {
@@ -22,7 +22,7 @@
22
22
  "build": "tsc",
23
23
  "dev": "tsc --watch",
24
24
  "start": "node dist/cn.js",
25
- "test": "node --experimental-transform-types --test \"src/**/*.test.ts\"",
25
+ "test": "npm run build && node --experimental-transform-types --test \"src/**/*.test.ts\"",
26
26
  "prepublishOnly": "npm run build"
27
27
  },
28
28
  "keywords": [
@@ -64,6 +64,6 @@
64
64
  "devDependencies": {
65
65
  "@types/node": "^20.0.0",
66
66
  "@types/update-notifier": "^6.0.8",
67
- "typescript": "^5.5.0"
67
+ "typescript": "^5.7.0"
68
68
  }
69
69
  }
@@ -37,6 +37,42 @@ cnotes workspace current # Verify active workspace + see its relationship typ
37
37
  workspace — reuse those labels when cross-linking notes rather than coining new ones
38
38
  (see [Relationship mentions](#content-via-markdown)).
39
39
 
40
+ ### Paid actions (writes need Pro)
41
+
42
+ Reads work on any plan. **CLI/API writes require the target workspace to be on Pro** — this is the most common wall you will hit (exit `8`, `serverCode: "subscription_required"`). There are three distinct walls, and only two of them need a human. Do not collapse them into "tell the user to go pay."
43
+
44
+ **Wall 1 — free workspace, write blocked. You can fix this yourself.**
45
+
46
+ If the caller owns the workspace and hasn't used its one-time trial, `cnotes upgrade` starts a free 7-day Pro trial and writes unlock immediately. **No credit card, no browser, no human hand-off** — it's a single command you can run.
47
+
48
+ ```bash
49
+ cnotes upgrade # start the free trial on the ACTIVE workspace, then retry the write
50
+ cnotes upgrade -w <id> # target a specific workspace
51
+ ```
52
+
53
+ **Ask before running it.** The trial is one-time and cannot be restarted, so never fire it unprompted. Offer it in one line and wait for a yes:
54
+
55
+ > "This workspace is on the free plan, so I can't write to it. Want me to start your free 7-day Pro trial (no credit card)?"
56
+
57
+ On yes: run `cnotes upgrade`, then retry the write. That's the whole flow.
58
+
59
+ **Wall 2 — trial already used. A human must pay.**
60
+
61
+ `cnotes upgrade` fails with `trial_used`. Card entry is browser-only, so you cannot subscribe on the user's behalf. Surface the `upgradeUrl` from the error (the workspace's billing page, $49/mo), keep doing read-only work in the meantime, and retry the write once they confirm they've paid.
62
+
63
+ **Wall 3 — they want an ADDITIONAL workspace. Human pays at checkout.**
64
+
65
+ `cnotes workspace create` **buys a new workspace** — it is not the fix for a blocked write on the current one (that's Wall 1). Only reach for it when the user actually asks for another workspace.
66
+
67
+ ```bash
68
+ cnotes workspace create "Acme Research" --json # returns { checkoutUrl, sessionId }
69
+ cnotes workspace create --verify <sessionId> --json # poll after the human pays
70
+ ```
71
+
72
+ The CLI never charges a card: `create` returns a Stripe Checkout URL a HUMAN must open and pay. Relay `checkoutUrl` to the user, then poll `--verify` every few seconds until `status` is `"ready"` — the new workspace is set active automatically. `--trial` starts that subscription with a 7-day trial (a card is still collected at checkout).
73
+
74
+ **If the caller is not the workspace owner**, never tell them to run `cnotes upgrade` — it dead-ends on an owner-only 403. The error `hint` already branches for this case: ask the *owner* to upgrade.
75
+
40
76
  ## Command Reference
41
77
 
42
78
  ### Global Flags (apply to ALL commands)
@@ -62,9 +98,9 @@ workspace — reuse those labels when cross-linking notes rather than coining ne
62
98
  | `5` | conflict (already exists / state collision) | re-fetch and retry |
63
99
  | `6` | rate limited | back off and retry |
64
100
  | `7` | permission denied | `cnotes workspace current` |
65
- | `8` | subscription required (free workspace, write blocked) | tell your user to start the free trial at the `upgradeUrl` in the error, then retry |
101
+ | `8` | subscription required (free workspace, write blocked) | offer to run `cnotes upgrade` (free trial, no card) — see [Paid actions](#paid-actions-writes-need-pro) |
66
102
 
67
- Exit `8` is specific: CLI/API **writes** require a Pro workspace, but **reads work on any plan**. The `--json` error carries `serverCode: "subscription_required"` and an `upgradeUrl` (the workspace's billing page). You can't start the trial yourself — surface the `upgradeUrl` to your user (the trial is free, no card), keep doing read-only work meanwhile, and retry the write once they confirm.
103
+ Exit `8` is specific: CLI/API **writes** require a Pro workspace, but **reads work on any plan**. The `--json` error carries `serverCode: "subscription_required"`, an `upgradeUrl` (the workspace's billing page), and a `hint`. **You are not stuck here.** If the caller owns the workspace and hasn't used its one-time trial, `cnotes upgrade` unlocks writes in a single command — free, no credit card, no browser. Ask the user first (it burns the one-time trial), run it, then retry the write. Only when the trial is already spent does this become a hand-off to the `upgradeUrl`. Full playbook, including the not-the-owner case: [Paid actions](#paid-actions-writes-need-pro).
68
104
 
69
105
  2. **Reads return their data directly; writes return an envelope.** `cnotes notes list/get/search --json` emit a bare array, so `… --json | jq '.[0].displayId'` works. `cnotes notes create --json` returns an object: `{ results, relationshipsCreated, relationshipTypesCreated }`. The created notes live under **`results`** (not `notes`, not `ok`). Read them with `jq '.results[].displayId'`. Each result carries `displayId` and `title`, the identifiers you reuse next, not only the internal id.
70
106
 
@@ -248,13 +284,31 @@ cnotes canvas from-template <templateId> --populate # Auto-populat
248
284
 
249
285
  # Agent-run bracketing — group a sequence of canvas changes into one operation
250
286
  # with before/after snapshots so the user can see "AI did X" and revert as a unit.
251
- # REQUIRED when an AI agent modifies a canvas. See "Agent-Run Bracketing" below.
287
+ # REQUIRED when an AI agent modifies a canvas. Notes directly below the block.
252
288
  cnotes canvas agent-run wrap --canvas <id> --prompt "<intent>" -- <command> # one-shot
253
289
  cnotes canvas agent-run begin --canvas <id> --prompt "<intent>" [--rationale "<plan>"] # multi-step
254
- cnotes canvas agent-run end --canvas <id>
290
+ cnotes canvas agent-run end --canvas <id> # no --run-id needed; ends the active run
255
291
  cnotes canvas activity <canvasId> # inspect operations + attribution after the fact
256
292
  ```
257
293
 
294
+ `begin` persists the run as the active run for this server (the same pointer
295
+ `cnotes operations begin` uses), so **every subsequent cnotes write attaches to
296
+ it automatically** — across separate shells and stateless tool calls, with no
297
+ env var to thread through. `end` closes that active run, so it needs no
298
+ `--run-id`. Only one run can be open at a time: a second `begin` refuses with
299
+ exit 5 (CONFLICT) rather than silently clobbering the first — pass `--force` to
300
+ end the prior run server-side and start fresh.
301
+
302
+ Prefer `wrap` for a single command (it auto-closes even on failure, and its run
303
+ is scoped to the subprocess, so it nests correctly inside an open `operations`
304
+ run). Use `begin`/`end` when the batch spans several commands.
305
+
306
+ **Always close the run.** If you can't, a later `begin --force` ends the stale
307
+ one and starts clean. Verify attribution with `cnotes canvas activity <id>`:
308
+ writes made inside a run show `operationType: agent.run` / `actorSource: agent`.
309
+ If you see `manual.edit` / `actorSource: human`, the bracket did not take and
310
+ the timeline is crediting your edits to the user.
311
+
258
312
  ### Timeline (`cnotes timeline` / `cnotes tl`)
259
313
  ```bash
260
314
  # Show recent changes (default: last 7 days)
@@ -891,6 +945,7 @@ Before creating or updating notes on a topic, **query memory first** to understa
891
945
  - Branch on the **exit code** first (see the table in [Reading output](#reading-output-start-here)) — it classes the failure without parsing prose — then read the `hint` in the `{ error, code, exitCode, hint }` JSON error on stderr; it names the command that fixes it.
892
946
  - If a command fails with auth errors (exit `2`), run `cnotes auth status` to verify credentials.
893
947
  - If a workspace error occurs (exit `4` not found, or `7` permission), verify with `cnotes workspace current` and list options with `cnotes workspace list`.
948
+ - If a **write** fails with exit `8` (`subscription_required`), the workspace is on the free plan. Don't dead-end the user on a billing URL: if they own it and haven't used the trial, offer to run `cnotes upgrade` (free, no card) and retry. See [Paid actions](#paid-actions-writes-need-pro).
894
949
 
895
950
  ### Closing the loop: submit feedback when you hit friction
896
951