@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.
- package/dist/commands/auth.d.ts +1 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +72 -8
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/canvas.d.ts.map +1 -1
- package/dist/commands/canvas.js +122 -20
- package/dist/commands/canvas.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +10 -3
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/operations.d.ts.map +1 -1
- package/dist/commands/operations.js +21 -19
- package/dist/commands/operations.js.map +1 -1
- package/dist/commands/workspace.d.ts.map +1 -1
- package/dist/commands/workspace.js +171 -1
- package/dist/commands/workspace.js.map +1 -1
- package/dist/lib/api-client.d.ts +35 -9
- package/dist/lib/api-client.d.ts.map +1 -1
- package/dist/lib/api-client.js +60 -24
- package/dist/lib/api-client.js.map +1 -1
- package/dist/lib/auth-store.d.ts +50 -11
- package/dist/lib/auth-store.d.ts.map +1 -1
- package/dist/lib/auth-store.js +47 -12
- package/dist/lib/auth-store.js.map +1 -1
- package/dist/lib/install-mcp.d.ts.map +1 -1
- package/dist/lib/install-mcp.js +19 -1
- package/dist/lib/install-mcp.js.map +1 -1
- package/dist/lib/output.d.ts +7 -0
- package/dist/lib/output.d.ts.map +1 -1
- package/dist/lib/output.js +16 -0
- package/dist/lib/output.js.map +1 -1
- package/dist/lib/server-url.d.ts +33 -0
- package/dist/lib/server-url.d.ts.map +1 -0
- package/dist/lib/server-url.js +106 -0
- package/dist/lib/server-url.js.map +1 -0
- package/package.json +3 -3
- package/skills/cnotes/SKILL.md +59 -4
package/dist/lib/auth-store.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
|
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 &&
|
|
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":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACpG,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;
|
|
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;
|
|
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"}
|
package/dist/lib/install-mcp.js
CHANGED
|
@@ -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":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"install-mcp.js","sourceRoot":"","sources":["../../src/lib/install-mcp.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/output.d.ts
CHANGED
|
@@ -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
|
*/
|
package/dist/lib/output.d.ts.map
CHANGED
|
@@ -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"}
|
package/dist/lib/output.js
CHANGED
|
@@ -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
|
*/
|
package/dist/lib/output.js.map
CHANGED
|
@@ -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.
|
|
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.
|
|
67
|
+
"typescript": "^5.7.0"
|
|
68
68
|
}
|
|
69
69
|
}
|
package/skills/cnotes/SKILL.md
CHANGED
|
@@ -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) |
|
|
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"
|
|
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.
|
|
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
|
|