@creator-notes/cnotes 0.16.11
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/.claude-plugin/plugin.json +14 -0
- package/.mcp.json +12 -0
- package/LICENSE +21 -0
- package/README.md +303 -0
- package/dist/cn.d.ts +3 -0
- package/dist/cn.d.ts.map +1 -0
- package/dist/cn.js +124 -0
- package/dist/cn.js.map +1 -0
- package/dist/commands/auth.d.ts +10 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +188 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/canvas.d.ts +3 -0
- package/dist/commands/canvas.d.ts.map +1 -0
- package/dist/commands/canvas.js +1383 -0
- package/dist/commands/canvas.js.map +1 -0
- package/dist/commands/claude-hook.d.ts +28 -0
- package/dist/commands/claude-hook.d.ts.map +1 -0
- package/dist/commands/claude-hook.js +59 -0
- package/dist/commands/claude-hook.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +47 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/files.d.ts +3 -0
- package/dist/commands/files.d.ts.map +1 -0
- package/dist/commands/files.js +119 -0
- package/dist/commands/files.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +473 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/mcp.d.ts +15 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +118 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/memory.d.ts +3 -0
- package/dist/commands/memory.d.ts.map +1 -0
- package/dist/commands/memory.js +150 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/notes.d.ts +3 -0
- package/dist/commands/notes.d.ts.map +1 -0
- package/dist/commands/notes.js +706 -0
- package/dist/commands/notes.js.map +1 -0
- package/dist/commands/operations.d.ts +18 -0
- package/dist/commands/operations.d.ts.map +1 -0
- package/dist/commands/operations.js +231 -0
- package/dist/commands/operations.js.map +1 -0
- package/dist/commands/relationships.d.ts +3 -0
- package/dist/commands/relationships.d.ts.map +1 -0
- package/dist/commands/relationships.js +94 -0
- package/dist/commands/relationships.js.map +1 -0
- package/dist/commands/schema.d.ts +12 -0
- package/dist/commands/schema.d.ts.map +1 -0
- package/dist/commands/schema.js +85 -0
- package/dist/commands/schema.js.map +1 -0
- package/dist/commands/search.d.ts +3 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +57 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/theme.d.ts +3 -0
- package/dist/commands/theme.d.ts.map +1 -0
- package/dist/commands/theme.js +184 -0
- package/dist/commands/theme.js.map +1 -0
- package/dist/commands/timeline.d.ts +3 -0
- package/dist/commands/timeline.d.ts.map +1 -0
- package/dist/commands/timeline.js +97 -0
- package/dist/commands/timeline.js.map +1 -0
- package/dist/commands/types.d.ts +3 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +139 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/commands/versions.d.ts +3 -0
- package/dist/commands/versions.d.ts.map +1 -0
- package/dist/commands/versions.js +120 -0
- package/dist/commands/versions.js.map +1 -0
- package/dist/commands/workspace.d.ts +13 -0
- package/dist/commands/workspace.d.ts.map +1 -0
- package/dist/commands/workspace.js +176 -0
- package/dist/commands/workspace.js.map +1 -0
- package/dist/lib/api-client.d.ts +45 -0
- package/dist/lib/api-client.d.ts.map +1 -0
- package/dist/lib/api-client.js +198 -0
- package/dist/lib/api-client.js.map +1 -0
- package/dist/lib/auth-store.d.ts +47 -0
- package/dist/lib/auth-store.d.ts.map +1 -0
- package/dist/lib/auth-store.js +116 -0
- package/dist/lib/auth-store.js.map +1 -0
- package/dist/lib/brand.d.ts +32 -0
- package/dist/lib/brand.d.ts.map +1 -0
- package/dist/lib/brand.js +32 -0
- package/dist/lib/brand.js.map +1 -0
- package/dist/lib/build-schema.d.ts +97 -0
- package/dist/lib/build-schema.d.ts.map +1 -0
- package/dist/lib/build-schema.js +139 -0
- package/dist/lib/build-schema.js.map +1 -0
- package/dist/lib/canvas-read.d.ts +54 -0
- package/dist/lib/canvas-read.d.ts.map +1 -0
- package/dist/lib/canvas-read.js +145 -0
- package/dist/lib/canvas-read.js.map +1 -0
- package/dist/lib/claude-session.d.ts +73 -0
- package/dist/lib/claude-session.d.ts.map +1 -0
- package/dist/lib/claude-session.js +104 -0
- package/dist/lib/claude-session.js.map +1 -0
- package/dist/lib/config.d.ts +28 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +66 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/env.d.ts +14 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +16 -0
- package/dist/lib/env.js.map +1 -0
- package/dist/lib/errors.d.ts +47 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +194 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/fs-utils.d.ts +2 -0
- package/dist/lib/fs-utils.d.ts.map +1 -0
- package/dist/lib/fs-utils.js +16 -0
- package/dist/lib/fs-utils.js.map +1 -0
- package/dist/lib/install-hook.d.ts +86 -0
- package/dist/lib/install-hook.d.ts.map +1 -0
- package/dist/lib/install-hook.js +168 -0
- package/dist/lib/install-hook.js.map +1 -0
- package/dist/lib/install-mcp.d.ts +21 -0
- package/dist/lib/install-mcp.d.ts.map +1 -0
- package/dist/lib/install-mcp.js +133 -0
- package/dist/lib/install-mcp.js.map +1 -0
- package/dist/lib/install-skill.d.ts +49 -0
- package/dist/lib/install-skill.d.ts.map +1 -0
- package/dist/lib/install-skill.js +113 -0
- package/dist/lib/install-skill.js.map +1 -0
- package/dist/lib/output.d.ts +29 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +78 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/resolve-note.d.ts +7 -0
- package/dist/lib/resolve-note.d.ts.map +1 -0
- package/dist/lib/resolve-note.js +23 -0
- package/dist/lib/resolve-note.js.map +1 -0
- package/dist/lib/stdin.d.ts +5 -0
- package/dist/lib/stdin.d.ts.map +1 -0
- package/dist/lib/stdin.js +11 -0
- package/dist/lib/stdin.js.map +1 -0
- package/dist/lib/style.d.ts +10 -0
- package/dist/lib/style.d.ts.map +1 -0
- package/dist/lib/style.js +17 -0
- package/dist/lib/style.js.map +1 -0
- package/dist/lib/themes.d.ts +44 -0
- package/dist/lib/themes.d.ts.map +1 -0
- package/dist/lib/themes.js +168 -0
- package/dist/lib/themes.js.map +1 -0
- package/dist/mcp-server.d.ts +3 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +782 -0
- package/dist/mcp-server.js.map +1 -0
- package/package.json +66 -0
- package/skills/cnotes/SKILL.md +680 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join, relative, isAbsolute } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { BRAND } from "./brand.js";
|
|
5
|
+
import { cnotesEnv } from "./env.js";
|
|
6
|
+
/**
|
|
7
|
+
* Where `cnotes claude-hook` (a Claude Code SessionStart hook) persists the
|
|
8
|
+
* current session id. A single "latest" file — simple and correct for the
|
|
9
|
+
* common one-session-per-machine case. Concurrent Claude Code sessions on the
|
|
10
|
+
* same machine would clobber it; set CNOTES_AGENT_SESSION_ID to disambiguate.
|
|
11
|
+
*/
|
|
12
|
+
export const CLAUDE_SESSION_FILE = join(homedir(), BRAND.configDir, "claude-session.json");
|
|
13
|
+
/**
|
|
14
|
+
* How long a hook-captured session stays trustworthy as "the agent driving
|
|
15
|
+
* this cnotes run". The SessionStart hook stamps `updatedAt` when the session is
|
|
16
|
+
* (re)opened, but there's no heartbeat — so this is age-since-opened, not
|
|
17
|
+
* since-last-activity. A generous window keeps long-running sessions valid
|
|
18
|
+
* while stopping a file left behind by a session that ended days ago from
|
|
19
|
+
* stamping a later, unrelated run.
|
|
20
|
+
*/
|
|
21
|
+
export const SESSION_FILE_MAX_AGE_MS = 24 * 60 * 60 * 1000; // 24h
|
|
22
|
+
/**
|
|
23
|
+
* Decide whether a stored hook session is still a trustworthy stand-in for
|
|
24
|
+
* "the agent driving THIS cnotes run". Pure (takes `now` + `cwd` rather than
|
|
25
|
+
* reading them) so the rules stay easy to reason about:
|
|
26
|
+
*
|
|
27
|
+
* - Must carry an `id` — the only thing we can actually resume.
|
|
28
|
+
* - Not older than {@link SESSION_FILE_MAX_AGE_MS} — a stale file left after
|
|
29
|
+
* a session ended must not stamp a later run as if that chat drove it.
|
|
30
|
+
* - If the file recorded the session's `cwd`, the current directory must sit
|
|
31
|
+
* inside that subtree — a cnotes run in a *different* project isn't this
|
|
32
|
+
* session's work. (No recorded cwd → can't scope, so we don't reject on
|
|
33
|
+
* that basis.)
|
|
34
|
+
*
|
|
35
|
+
* Erring toward rejection is the safe bias here: a false negative just drops
|
|
36
|
+
* the (optional) resume affordance, whereas a false positive mislabels the
|
|
37
|
+
* run's provenance and offers a resume to the wrong chat.
|
|
38
|
+
*/
|
|
39
|
+
export function isStoredSessionUsable(stored, ctx) {
|
|
40
|
+
if (!stored.id)
|
|
41
|
+
return false;
|
|
42
|
+
if (typeof stored.updatedAt === "number" &&
|
|
43
|
+
ctx.now - stored.updatedAt > SESSION_FILE_MAX_AGE_MS) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
if (stored.cwd && !isWithin(ctx.cwd, stored.cwd))
|
|
47
|
+
return false;
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
/** True when `child` is `parent` or nested beneath it. */
|
|
51
|
+
function isWithin(child, parent) {
|
|
52
|
+
const rel = relative(parent, child);
|
|
53
|
+
return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Resolve the agent conversation/session driving the current cnotes run, so
|
|
57
|
+
* `cnotes operations begin` can stamp it on the operation row (making the run
|
|
58
|
+
* traceable + resumable from the timeline). Resolution order, most explicit
|
|
59
|
+
* first:
|
|
60
|
+
*
|
|
61
|
+
* 1. CN_AGENT_SESSION_ID (+ optional CN_AGENT_SESSION_KIND) — explicit
|
|
62
|
+
* override, wins everything. Lets any agent runtime opt in by hand.
|
|
63
|
+
* 2. The SessionStart-hook file written by `cnotes claude-hook`, when it's still
|
|
64
|
+
* fresh + scoped to this directory (see {@link isStoredSessionUsable}).
|
|
65
|
+
* This is the Claude Code TOP-LEVEL session id, captured once when the
|
|
66
|
+
* session starts — the most correct value to resume (a subagent's own
|
|
67
|
+
* bash would otherwise report the subagent's id via the env var below).
|
|
68
|
+
* 3. CLAUDE_CODE_SESSION_ID — Claude Code's per-process env var. Zero-config
|
|
69
|
+
* but undocumented; best-effort fallback when no hook is installed. It's
|
|
70
|
+
* the live process's own env, so no staleness check applies.
|
|
71
|
+
*
|
|
72
|
+
* Returns null when nothing is known (e.g. cnotes run outside any agent), in which
|
|
73
|
+
* case the run simply isn't session-stamped — no error.
|
|
74
|
+
*/
|
|
75
|
+
export function resolveAgentSession() {
|
|
76
|
+
const overrideId = cnotesEnv("AGENT_SESSION_ID")?.trim();
|
|
77
|
+
if (overrideId) {
|
|
78
|
+
return {
|
|
79
|
+
kind: cnotesEnv("AGENT_SESSION_KIND")?.trim() || "claude-code",
|
|
80
|
+
id: overrideId,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const fromFile = readSessionFile(Date.now(), process.cwd());
|
|
84
|
+
if (fromFile)
|
|
85
|
+
return fromFile;
|
|
86
|
+
const envId = process.env.CLAUDE_CODE_SESSION_ID?.trim();
|
|
87
|
+
if (envId)
|
|
88
|
+
return { kind: "claude-code", id: envId };
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
function readSessionFile(now, cwd) {
|
|
92
|
+
try {
|
|
93
|
+
const raw = readFileSync(CLAUDE_SESSION_FILE, "utf-8");
|
|
94
|
+
const parsed = JSON.parse(raw);
|
|
95
|
+
if (isStoredSessionUsable(parsed, { now, cwd })) {
|
|
96
|
+
return { kind: parsed.kind || "claude-code", id: parsed.id };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// No hook file / unreadable / malformed → fall through to env.
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=claude-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-session.js","sourceRoot":"","sources":["../../src/lib/claude-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface ResolvedConfig {
|
|
2
|
+
serverUrl: string;
|
|
3
|
+
token: string;
|
|
4
|
+
workspaceId: string;
|
|
5
|
+
json: boolean;
|
|
6
|
+
quiet: boolean;
|
|
7
|
+
fields?: string[];
|
|
8
|
+
}
|
|
9
|
+
interface GlobalOpts {
|
|
10
|
+
server?: string;
|
|
11
|
+
workspace?: string;
|
|
12
|
+
json?: boolean;
|
|
13
|
+
quiet?: boolean;
|
|
14
|
+
fields?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Resolve server URL, token, and workspace from env vars, flags, and config file.
|
|
18
|
+
* Priority: flags > env vars > config file.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveConfig(opts: GlobalOpts): ResolvedConfig;
|
|
21
|
+
/**
|
|
22
|
+
* Resolve config without requiring workspace (for auth/config/workspace commands).
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveBaseConfig(opts: GlobalOpts): Omit<ResolvedConfig, "workspaceId"> & {
|
|
25
|
+
workspaceId?: string;
|
|
26
|
+
};
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,UAAU,UAAU;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAWD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,cAAc,CAqC9D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC,cAAc,EAAE,aAAa,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAmBlH"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { loadConfig, getServerConfig } from "./auth-store.js";
|
|
2
|
+
import { AuthError, ValidationError } from "./errors.js";
|
|
3
|
+
import { cnotesEnv } from "./env.js";
|
|
4
|
+
/**
|
|
5
|
+
* Parse a `--fields a,b,c` option into a trimmed list, or undefined when unset.
|
|
6
|
+
*/
|
|
7
|
+
function parseFields(fields) {
|
|
8
|
+
if (!fields)
|
|
9
|
+
return undefined;
|
|
10
|
+
const list = fields.split(",").map((f) => f.trim()).filter(Boolean);
|
|
11
|
+
return list.length > 0 ? list : undefined;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Resolve server URL, token, and workspace from env vars, flags, and config file.
|
|
15
|
+
* Priority: flags > env vars > config file.
|
|
16
|
+
*/
|
|
17
|
+
export function resolveConfig(opts) {
|
|
18
|
+
const config = loadConfig();
|
|
19
|
+
// Server URL
|
|
20
|
+
const serverUrl = opts.server || cnotesEnv("SERVER") || config.currentServer;
|
|
21
|
+
// Token
|
|
22
|
+
const envToken = cnotesEnv("TOKEN");
|
|
23
|
+
const configToken = getServerConfig(config, serverUrl)?.token;
|
|
24
|
+
const token = envToken || configToken;
|
|
25
|
+
if (!token) {
|
|
26
|
+
throw new AuthError();
|
|
27
|
+
}
|
|
28
|
+
// Workspace ID
|
|
29
|
+
const envWorkspace = cnotesEnv("WORKSPACE");
|
|
30
|
+
const configWorkspace = getServerConfig(config, serverUrl)?.workspaceId;
|
|
31
|
+
const workspaceId = opts.workspace || envWorkspace || configWorkspace;
|
|
32
|
+
if (!workspaceId) {
|
|
33
|
+
throw new ValidationError("No workspace selected. Run `cnotes workspace select` or pass --workspace <id>");
|
|
34
|
+
}
|
|
35
|
+
// Output format
|
|
36
|
+
const json = opts.json || cnotesEnv("JSON") === "1" || !process.stdout.isTTY;
|
|
37
|
+
return {
|
|
38
|
+
serverUrl,
|
|
39
|
+
token,
|
|
40
|
+
workspaceId,
|
|
41
|
+
json: json ?? false,
|
|
42
|
+
quiet: opts.quiet ?? false,
|
|
43
|
+
fields: parseFields(opts.fields),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Resolve config without requiring workspace (for auth/config/workspace commands).
|
|
48
|
+
*/
|
|
49
|
+
export function resolveBaseConfig(opts) {
|
|
50
|
+
const config = loadConfig();
|
|
51
|
+
const serverUrl = opts.server || cnotesEnv("SERVER") || config.currentServer;
|
|
52
|
+
const envToken = cnotesEnv("TOKEN");
|
|
53
|
+
const configToken = getServerConfig(config, serverUrl)?.token;
|
|
54
|
+
const token = envToken || configToken || "";
|
|
55
|
+
const configWorkspace = getServerConfig(config, serverUrl)?.workspaceId;
|
|
56
|
+
const json = opts.json || cnotesEnv("JSON") === "1" || !process.stdout.isTTY;
|
|
57
|
+
return {
|
|
58
|
+
serverUrl,
|
|
59
|
+
token,
|
|
60
|
+
workspaceId: opts.workspace || cnotesEnv("WORKSPACE") || configWorkspace,
|
|
61
|
+
json: json ?? false,
|
|
62
|
+
quiet: opts.quiet ?? false,
|
|
63
|
+
fields: parseFields(opts.fields),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read a cnotes environment variable, honoring the pre-rename `CN_` prefix as a
|
|
3
|
+
* fallback.
|
|
4
|
+
*
|
|
5
|
+
* The cn→cnotes rename moved the env contract from `CN_*` to `CNOTES_*`. New
|
|
6
|
+
* config (`.mcp.json`, the Claude Desktop / Codex install templates) writes the
|
|
7
|
+
* `CNOTES_*` form, but MCP configs written before the rename still carry `CN_*`
|
|
8
|
+
* — so we read `CNOTES_<suffix>` first and fall back to `CN_<suffix>` until the
|
|
9
|
+
* user re-runs `cnotes mcp setup-*` (which rewrites the config to the new form).
|
|
10
|
+
*
|
|
11
|
+
* Pass the suffix only, e.g. `cnotesEnv("SERVER")` for CNOTES_SERVER/CN_SERVER.
|
|
12
|
+
*/
|
|
13
|
+
export declare function cnotesEnv(suffix: string): string | undefined;
|
|
14
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE5D"}
|
package/dist/lib/env.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read a cnotes environment variable, honoring the pre-rename `CN_` prefix as a
|
|
3
|
+
* fallback.
|
|
4
|
+
*
|
|
5
|
+
* The cn→cnotes rename moved the env contract from `CN_*` to `CNOTES_*`. New
|
|
6
|
+
* config (`.mcp.json`, the Claude Desktop / Codex install templates) writes the
|
|
7
|
+
* `CNOTES_*` form, but MCP configs written before the rename still carry `CN_*`
|
|
8
|
+
* — so we read `CNOTES_<suffix>` first and fall back to `CN_<suffix>` until the
|
|
9
|
+
* user re-runs `cnotes mcp setup-*` (which rewrites the config to the new form).
|
|
10
|
+
*
|
|
11
|
+
* Pass the suffix only, e.g. `cnotesEnv("SERVER")` for CNOTES_SERVER/CN_SERVER.
|
|
12
|
+
*/
|
|
13
|
+
export function cnotesEnv(suffix) {
|
|
14
|
+
return process.env[`CNOTES_${suffix}`] ?? process.env[`CN_${suffix}`];
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,OAAO,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,EAAE,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exit codes are part of the CLI's contract with agents. Branching on the
|
|
3
|
+
* exit code is cheaper and more reliable than parsing stderr prose.
|
|
4
|
+
*
|
|
5
|
+
* 0 ok
|
|
6
|
+
* 1 generic error
|
|
7
|
+
* 2 auth required
|
|
8
|
+
* 3 validation (bad input)
|
|
9
|
+
* 4 not found
|
|
10
|
+
* 5 conflict (already exists / state collision)
|
|
11
|
+
* 6 rate-limited
|
|
12
|
+
* 7 permission denied
|
|
13
|
+
*/
|
|
14
|
+
export declare const EXIT_CODES: {
|
|
15
|
+
readonly OK: 0;
|
|
16
|
+
readonly GENERIC: 1;
|
|
17
|
+
readonly AUTH: 2;
|
|
18
|
+
readonly VALIDATION: 3;
|
|
19
|
+
readonly NOT_FOUND: 4;
|
|
20
|
+
readonly CONFLICT: 5;
|
|
21
|
+
readonly RATE_LIMIT: 6;
|
|
22
|
+
readonly PERMISSION: 7;
|
|
23
|
+
};
|
|
24
|
+
export declare class CliError extends Error {
|
|
25
|
+
exitCode: number;
|
|
26
|
+
hint?: string;
|
|
27
|
+
constructor(message: string, exitCode?: number, hint?: string);
|
|
28
|
+
}
|
|
29
|
+
export declare class AuthError extends CliError {
|
|
30
|
+
constructor(message?: string, hint?: string);
|
|
31
|
+
}
|
|
32
|
+
export declare class ValidationError extends CliError {
|
|
33
|
+
constructor(message: string, hint?: string);
|
|
34
|
+
}
|
|
35
|
+
export declare class NotFoundError extends CliError {
|
|
36
|
+
constructor(message: string, hint?: string);
|
|
37
|
+
}
|
|
38
|
+
export declare class ApiError extends CliError {
|
|
39
|
+
status: number;
|
|
40
|
+
body: Record<string, unknown>;
|
|
41
|
+
constructor(status: number, body: Record<string, unknown>);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Handle errors from CLI commands uniformly.
|
|
45
|
+
*/
|
|
46
|
+
export declare function handleError(error: unknown, json: boolean): never;
|
|
47
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,UAAU;;;;;;;;;CASb,CAAC;AAEX,qBAAa,QAAS,SAAQ,KAAK;IAKxB,QAAQ,EAAE,MAAM;IAJzB,IAAI,CAAC,EAAE,MAAM,CAAC;gBAGZ,OAAO,EAAE,MAAM,EACR,QAAQ,GAAE,MAA2B,EAC5C,IAAI,CAAC,EAAE,MAAM;CAMhB;AAED,qBAAa,SAAU,SAAQ,QAAQ;gBAEnC,OAAO,GAAE,MAAmC,EAC5C,IAAI,GAAE,MAAmD;CAK5D;AAED,qBAAa,eAAgB,SAAQ,QAAQ;gBAC/B,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;CAI3C;AAED,qBAAa,aAAc,SAAQ,QAAQ;gBAC7B,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;CAI3C;AAED,qBAAa,QAAS,SAAQ,QAAQ;IAE3B,MAAM,EAAE,MAAM;IACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gBAD7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAgBvC;AA4FD;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,KAAK,CA8BhE"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exit codes are part of the CLI's contract with agents. Branching on the
|
|
3
|
+
* exit code is cheaper and more reliable than parsing stderr prose.
|
|
4
|
+
*
|
|
5
|
+
* 0 ok
|
|
6
|
+
* 1 generic error
|
|
7
|
+
* 2 auth required
|
|
8
|
+
* 3 validation (bad input)
|
|
9
|
+
* 4 not found
|
|
10
|
+
* 5 conflict (already exists / state collision)
|
|
11
|
+
* 6 rate-limited
|
|
12
|
+
* 7 permission denied
|
|
13
|
+
*/
|
|
14
|
+
export const EXIT_CODES = {
|
|
15
|
+
OK: 0,
|
|
16
|
+
GENERIC: 1,
|
|
17
|
+
AUTH: 2,
|
|
18
|
+
VALIDATION: 3,
|
|
19
|
+
NOT_FOUND: 4,
|
|
20
|
+
CONFLICT: 5,
|
|
21
|
+
RATE_LIMIT: 6,
|
|
22
|
+
PERMISSION: 7,
|
|
23
|
+
};
|
|
24
|
+
export class CliError extends Error {
|
|
25
|
+
exitCode;
|
|
26
|
+
hint;
|
|
27
|
+
constructor(message, exitCode = EXIT_CODES.GENERIC, hint) {
|
|
28
|
+
super(message);
|
|
29
|
+
this.exitCode = exitCode;
|
|
30
|
+
this.name = "CliError";
|
|
31
|
+
if (hint)
|
|
32
|
+
this.hint = hint;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export class AuthError extends CliError {
|
|
36
|
+
constructor(message = "Authentication required.", hint = "Run `cnotes auth login` to authenticate.") {
|
|
37
|
+
super(message, EXIT_CODES.AUTH, hint);
|
|
38
|
+
this.name = "AuthError";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export class ValidationError extends CliError {
|
|
42
|
+
constructor(message, hint) {
|
|
43
|
+
super(message, EXIT_CODES.VALIDATION, hint);
|
|
44
|
+
this.name = "ValidationError";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export class NotFoundError extends CliError {
|
|
48
|
+
constructor(message, hint) {
|
|
49
|
+
super(message, EXIT_CODES.NOT_FOUND, hint);
|
|
50
|
+
this.name = "NotFoundError";
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export class ApiError extends CliError {
|
|
54
|
+
status;
|
|
55
|
+
body;
|
|
56
|
+
constructor(status, body) {
|
|
57
|
+
const baseMsg = body.error || `API error: HTTP ${status}`;
|
|
58
|
+
const fieldLines = formatFieldErrors(body.details);
|
|
59
|
+
const msg = fieldLines.length > 0
|
|
60
|
+
? `${baseMsg}\n${fieldLines.map((l) => ` - ${l}`).join("\n")}`
|
|
61
|
+
: baseMsg;
|
|
62
|
+
const exitCode = exitCodeForStatus(status);
|
|
63
|
+
const resource = typeof body.resource === "string" ? body.resource : undefined;
|
|
64
|
+
const hint = typeof body.hint === "string"
|
|
65
|
+
? body.hint
|
|
66
|
+
: hintForStatus(status, baseMsg, resource);
|
|
67
|
+
super(msg, exitCode, hint);
|
|
68
|
+
this.status = status;
|
|
69
|
+
this.body = body;
|
|
70
|
+
this.name = "ApiError";
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function exitCodeForStatus(status) {
|
|
74
|
+
if (status === 401)
|
|
75
|
+
return EXIT_CODES.AUTH;
|
|
76
|
+
if (status === 403)
|
|
77
|
+
return EXIT_CODES.PERMISSION;
|
|
78
|
+
if (status === 404)
|
|
79
|
+
return EXIT_CODES.NOT_FOUND;
|
|
80
|
+
if (status === 409)
|
|
81
|
+
return EXIT_CODES.CONFLICT;
|
|
82
|
+
if (status === 422)
|
|
83
|
+
return EXIT_CODES.VALIDATION;
|
|
84
|
+
if (status === 429)
|
|
85
|
+
return EXIT_CODES.RATE_LIMIT;
|
|
86
|
+
if (status >= 400 && status < 500)
|
|
87
|
+
return EXIT_CODES.VALIDATION;
|
|
88
|
+
return EXIT_CODES.GENERIC;
|
|
89
|
+
}
|
|
90
|
+
function hintForStatus(status, message, resource) {
|
|
91
|
+
if (status === 401)
|
|
92
|
+
return "Run `cnotes auth login` to authenticate.";
|
|
93
|
+
if (status === 403)
|
|
94
|
+
return "Check workspace membership with `cnotes workspace current`.";
|
|
95
|
+
if (status === 404) {
|
|
96
|
+
// Prefer a server-provided `resource` field; fall back to regex on the
|
|
97
|
+
// error message. Regex is best-effort because server messages vary.
|
|
98
|
+
const r = (resource ?? "").toLowerCase();
|
|
99
|
+
if (r === "workspace" || (!r && /workspace/i.test(message))) {
|
|
100
|
+
return "Run `cnotes workspace list` to see available workspaces.";
|
|
101
|
+
}
|
|
102
|
+
if (r === "note" || (!r && /note/i.test(message))) {
|
|
103
|
+
return "Run `cnotes notes list` to see valid display IDs.";
|
|
104
|
+
}
|
|
105
|
+
if (r === "canvas" || (!r && /canvas/i.test(message))) {
|
|
106
|
+
return "Run `cnotes canvas list` to see available canvases.";
|
|
107
|
+
}
|
|
108
|
+
return "Run `cnotes schema` to see valid resource identifiers.";
|
|
109
|
+
}
|
|
110
|
+
if (status === 429)
|
|
111
|
+
return "Slow down requests or retry with backoff.";
|
|
112
|
+
if (status === 409)
|
|
113
|
+
return "Re-fetch current state and retry; another writer may have modified the resource.";
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
function isBatchItem(v) {
|
|
117
|
+
return (!!v &&
|
|
118
|
+
typeof v === "object" &&
|
|
119
|
+
typeof v.index === "number" &&
|
|
120
|
+
typeof v.field === "string" &&
|
|
121
|
+
typeof v.message === "string");
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Extract human-readable lines from a server `details` payload. Recognises:
|
|
125
|
+
* - `{ items: [{ index, key?, field, message }, ...] }` — `cnotes notes create` per-item errors
|
|
126
|
+
* - Zod `.flatten()` shape `{ fieldErrors, formErrors }` — generic validation
|
|
127
|
+
*/
|
|
128
|
+
function formatFieldErrors(details) {
|
|
129
|
+
if (!details || typeof details !== "object")
|
|
130
|
+
return [];
|
|
131
|
+
const d = details;
|
|
132
|
+
const lines = [];
|
|
133
|
+
if (Array.isArray(d.items)) {
|
|
134
|
+
for (const raw of d.items) {
|
|
135
|
+
if (!isBatchItem(raw))
|
|
136
|
+
continue;
|
|
137
|
+
const keyLabel = raw.key ? `(${raw.key})` : "(?)";
|
|
138
|
+
lines.push(`item ${raw.index} ${keyLabel}: ${raw.field}: ${raw.message}`);
|
|
139
|
+
}
|
|
140
|
+
if (lines.length > 0)
|
|
141
|
+
return lines;
|
|
142
|
+
}
|
|
143
|
+
if (d.fieldErrors) {
|
|
144
|
+
for (const [field, errs] of Object.entries(d.fieldErrors)) {
|
|
145
|
+
if (!errs || errs.length === 0)
|
|
146
|
+
continue;
|
|
147
|
+
for (const err of errs)
|
|
148
|
+
lines.push(`${field}: ${err}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (lines.length === 0 && Array.isArray(d.formErrors)) {
|
|
152
|
+
for (const err of d.formErrors)
|
|
153
|
+
lines.push(err);
|
|
154
|
+
}
|
|
155
|
+
return lines;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Handle errors from CLI commands uniformly.
|
|
159
|
+
*/
|
|
160
|
+
export function handleError(error, json) {
|
|
161
|
+
if (error instanceof CliError) {
|
|
162
|
+
if (json) {
|
|
163
|
+
const payload = {
|
|
164
|
+
error: error.message,
|
|
165
|
+
code: error.name,
|
|
166
|
+
exitCode: error.exitCode,
|
|
167
|
+
};
|
|
168
|
+
if (error.hint)
|
|
169
|
+
payload.hint = error.hint;
|
|
170
|
+
if (error instanceof ApiError) {
|
|
171
|
+
payload.status = error.status;
|
|
172
|
+
if (error.body && typeof error.body === "object" && "details" in error.body) {
|
|
173
|
+
payload.details = error.body.details;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
console.error(JSON.stringify(payload));
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
console.error(`Error: ${error.message}`);
|
|
180
|
+
if (error.hint)
|
|
181
|
+
console.error(` hint: ${error.hint}`);
|
|
182
|
+
}
|
|
183
|
+
process.exit(error.exitCode);
|
|
184
|
+
}
|
|
185
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
186
|
+
if (json) {
|
|
187
|
+
console.error(JSON.stringify({ error: message, code: "unknown_error", exitCode: EXIT_CODES.GENERIC }));
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
console.error(`Error: ${message}`);
|
|
191
|
+
}
|
|
192
|
+
process.exit(EXIT_CODES.GENERIC);
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-utils.d.ts","sourceRoot":"","sources":["../../src/lib/fs-utils.ts"],"names":[],"mappings":"AAGA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASjD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { CliError, ValidationError } from "./errors.js";
|
|
3
|
+
export function readFileSafe(path) {
|
|
4
|
+
try {
|
|
5
|
+
return readFileSync(path, "utf-8");
|
|
6
|
+
}
|
|
7
|
+
catch (err) {
|
|
8
|
+
const nodeErr = err;
|
|
9
|
+
if (nodeErr.code === "ENOENT")
|
|
10
|
+
throw new ValidationError(`File not found: ${path}`);
|
|
11
|
+
if (nodeErr.code === "EACCES")
|
|
12
|
+
throw new ValidationError(`Permission denied: ${path}`);
|
|
13
|
+
throw new CliError(`Failed to read file: ${path} — ${nodeErr.message}`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=fs-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-utils.js","sourceRoot":"","sources":["../../src/lib/fs-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAExD,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAA4B,CAAC;QAC7C,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,IAAI,eAAe,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;QACpF,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,IAAI,eAAe,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;QACvF,MAAM,IAAI,QAAQ,CAAC,wBAAwB,IAAI,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Install a Claude Code SessionStart hook that captures the session id.
|
|
3
|
+
*
|
|
4
|
+
* The hook runs `cnotes claude-hook` at session start, which writes the current
|
|
5
|
+
* session id to a file (see lib/claude-session.ts). `cnotes operations begin` then
|
|
6
|
+
* stamps it on the operation row, so an agent run on the timeline can be traced
|
|
7
|
+
* back to — and resumed from — the conversation that produced it.
|
|
8
|
+
*
|
|
9
|
+
* Target: the USER-GLOBAL ~/.claude/settings.json (so capture works in every
|
|
10
|
+
* repo, not just one). We preserve all existing settings + other hooks, back up
|
|
11
|
+
* the file before writing, and are idempotent (a second install is a no-op).
|
|
12
|
+
*
|
|
13
|
+
* Unlike the MCP installer, a parse failure here ABORTS rather than starting
|
|
14
|
+
* fresh: settings.json holds the user's entire Claude Code config, so silently
|
|
15
|
+
* overwriting it would be destructive.
|
|
16
|
+
*/
|
|
17
|
+
/** The user-global Claude Code settings file. */
|
|
18
|
+
export declare const CLAUDE_SETTINGS_PATH: string;
|
|
19
|
+
/** The command the hook runs when `cnotes` is on PATH (a global install). */
|
|
20
|
+
export declare const SESSION_HOOK_COMMAND = "cnotes claude-hook";
|
|
21
|
+
/**
|
|
22
|
+
* Fallback command for when `cnotes` won't be on PATH — e.g. the user ran
|
|
23
|
+
* `npx @creator-notes/cnotes init` without installing globally. Resolving the hook
|
|
24
|
+
* through npx keeps it working instead of failing `command not found` on every
|
|
25
|
+
* session start. Costs npx resolution latency per session, so we only use it
|
|
26
|
+
* when `cnotes` genuinely isn't available. `npx cnotes` does NOT resolve (the published
|
|
27
|
+
* package is @creator-notes/cnotes); detection tolerates this form for idempotency.
|
|
28
|
+
*/
|
|
29
|
+
export declare const SESSION_HOOK_COMMAND_NPX = "npx @creator-notes/cnotes claude-hook";
|
|
30
|
+
export interface HookInstallResult {
|
|
31
|
+
configPath: string;
|
|
32
|
+
/** created → new file; installed → merged into existing; already-present →
|
|
33
|
+
* a claude-hook SessionStart entry was already there (no write). */
|
|
34
|
+
status: "created" | "installed" | "already-present";
|
|
35
|
+
backedUp?: string;
|
|
36
|
+
}
|
|
37
|
+
interface HookEntry {
|
|
38
|
+
type?: string;
|
|
39
|
+
command?: string;
|
|
40
|
+
}
|
|
41
|
+
interface HookGroup {
|
|
42
|
+
matcher?: string;
|
|
43
|
+
hooks?: HookEntry[];
|
|
44
|
+
}
|
|
45
|
+
interface ClaudeSettings {
|
|
46
|
+
hooks?: Record<string, HookGroup[]>;
|
|
47
|
+
[key: string]: unknown;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A plain JSON object — the only shape a Claude Code settings.json can validly
|
|
51
|
+
* take. Arrays, `null`, and primitives parse as valid JSON but aren't a config
|
|
52
|
+
* we can safely merge into, so callers treat them like a parse failure rather
|
|
53
|
+
* than silently clobbering the file. Exported for direct unit testing.
|
|
54
|
+
*/
|
|
55
|
+
export declare function isPlainSettingsObject(value: unknown): value is ClaudeSettings;
|
|
56
|
+
/**
|
|
57
|
+
* Identify our entry by the `claude-hook` command (tolerates both the `cnotes` and
|
|
58
|
+
* `npx …` forms). Exported for direct unit testing.
|
|
59
|
+
*/
|
|
60
|
+
export declare function groupHasSessionHook(group: HookGroup): boolean;
|
|
61
|
+
/** True when any SessionStart group already carries our hook. Exported for tests. */
|
|
62
|
+
export declare function settingsHaveSessionHook(settings: ClaudeSettings): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Rewrite any SessionStart hook that targets our `claude-hook` subcommand but
|
|
65
|
+
* isn't the command we're installing — e.g. a pre-rename `cn claude-hook` entry
|
|
66
|
+
* left dead once the `cn` binary was dropped — to `command`, in place. Returns
|
|
67
|
+
* true if anything changed. Exported for direct unit testing.
|
|
68
|
+
*/
|
|
69
|
+
export declare function upgradeStaleSessionHooks(settings: ClaudeSettings, command: string): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* True when a `cnotes claude-hook` SessionStart entry already exists. Read-only —
|
|
72
|
+
* lets callers skip prompting on re-runs without mutating anything. Returns
|
|
73
|
+
* false (rather than throwing) when the file is missing or unreadable.
|
|
74
|
+
*/
|
|
75
|
+
export declare function isClaudeSessionHookInstalled(): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Idempotently add the SessionStart hook to ~/.claude/settings.json.
|
|
78
|
+
* Preserves existing settings + hooks, backs up an existing file first.
|
|
79
|
+
*
|
|
80
|
+
* @throws if an existing settings.json is present but not valid JSON — we will
|
|
81
|
+
* not overwrite the user's whole config; the caller should surface the manual
|
|
82
|
+
* install instructions instead.
|
|
83
|
+
*/
|
|
84
|
+
export declare function installClaudeSessionHook(command?: string): HookInstallResult;
|
|
85
|
+
export {};
|
|
86
|
+
//# sourceMappingURL=install-hook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-hook.d.ts","sourceRoot":"","sources":["../../src/lib/install-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAaH,iDAAiD;AACjD,eAAO,MAAM,oBAAoB,QAAiD,CAAC;AAEnF,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAEzD;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,0CAA0C,CAAC;AAEhF,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB;yEACqE;IACrE,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,iBAAiB,CAAC;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,SAAS;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,UAAU,SAAS;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;CACrB;AACD,UAAU,cAAc;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IACpC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAE7E;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAO7D;AAED,qFAAqF;AACrF,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAGzE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,MAAM,GACd,OAAO,CAqBT;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,IAAI,OAAO,CAStD;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,GAAE,MAA6B,GACrC,iBAAiB,CAsEnB"}
|