plaud-notes-to-notion 1.0.0
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/CHANGELOG.md +10 -0
- package/LICENSE +21 -0
- package/README.md +102 -0
- package/bin/plaud-notes-to-notion.js +16 -0
- package/dist/card.d.ts +30 -0
- package/dist/card.js +287 -0
- package/dist/card.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +266 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +41 -0
- package/dist/config.js +85 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts +52 -0
- package/dist/constants.js +53 -0
- package/dist/constants.js.map +1 -0
- package/dist/daemon.d.ts +13 -0
- package/dist/daemon.js +182 -0
- package/dist/daemon.js.map +1 -0
- package/dist/format.d.ts +36 -0
- package/dist/format.js +108 -0
- package/dist/format.js.map +1 -0
- package/dist/ingest.d.ts +49 -0
- package/dist/ingest.js +205 -0
- package/dist/ingest.js.map +1 -0
- package/dist/llm.d.ts +65 -0
- package/dist/llm.js +177 -0
- package/dist/llm.js.map +1 -0
- package/dist/lock.d.ts +26 -0
- package/dist/lock.js +134 -0
- package/dist/lock.js.map +1 -0
- package/dist/log.d.ts +14 -0
- package/dist/log.js +41 -0
- package/dist/log.js.map +1 -0
- package/dist/notion.d.ts +86 -0
- package/dist/notion.js +254 -0
- package/dist/notion.js.map +1 -0
- package/dist/paths.d.ts +11 -0
- package/dist/paths.js +51 -0
- package/dist/paths.js.map +1 -0
- package/dist/plaud/callback.d.ts +19 -0
- package/dist/plaud/callback.js +162 -0
- package/dist/plaud/callback.js.map +1 -0
- package/dist/plaud/client.d.ts +55 -0
- package/dist/plaud/client.js +246 -0
- package/dist/plaud/client.js.map +1 -0
- package/dist/plaud/constants.d.ts +18 -0
- package/dist/plaud/constants.js +19 -0
- package/dist/plaud/constants.js.map +1 -0
- package/dist/plaud/errors.d.ts +10 -0
- package/dist/plaud/errors.js +32 -0
- package/dist/plaud/errors.js.map +1 -0
- package/dist/plaud/login.d.ts +17 -0
- package/dist/plaud/login.js +89 -0
- package/dist/plaud/login.js.map +1 -0
- package/dist/plaud/oauth.d.ts +21 -0
- package/dist/plaud/oauth.js +197 -0
- package/dist/plaud/oauth.js.map +1 -0
- package/dist/plaud/pkce.d.ts +3 -0
- package/dist/plaud/pkce.js +11 -0
- package/dist/plaud/pkce.js.map +1 -0
- package/dist/plaud/session.d.ts +23 -0
- package/dist/plaud/session.js +77 -0
- package/dist/plaud/session.js.map +1 -0
- package/dist/plaud/types.d.ts +21 -0
- package/dist/plaud/types.js +2 -0
- package/dist/plaud/types.js.map +1 -0
- package/dist/redact.d.ts +3 -0
- package/dist/redact.js +37 -0
- package/dist/redact.js.map +1 -0
- package/dist/runtime.d.ts +44 -0
- package/dist/runtime.js +94 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scrub.d.ts +17 -0
- package/dist/scrub.js +124 -0
- package/dist/scrub.js.map +1 -0
- package/dist/secrets.d.ts +59 -0
- package/dist/secrets.js +220 -0
- package/dist/secrets.js.map +1 -0
- package/dist/ssn.d.ts +33 -0
- package/dist/ssn.js +170 -0
- package/dist/ssn.js.map +1 -0
- package/dist/state.d.ts +46 -0
- package/dist/state.js +23 -0
- package/dist/state.js.map +1 -0
- package/dist/sync.d.ts +60 -0
- package/dist/sync.js +190 -0
- package/dist/sync.js.map +1 -0
- package/examples/com.plaud-notes-to-notion.plist +34 -0
- package/examples/install-launchagent.sh +16 -0
- package/package.json +37 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { DEFAULT_AUTHORIZATION_URL, DEFAULT_MCP_API_BASE, DEFAULT_MCP_CLIENT_ID, DEFAULT_REFRESH_URL, DEFAULT_TOKEN_URL, OAUTH_REDIRECT_URI } from "./constants.js";
|
|
2
|
+
import { AuthExpiredError, AuthTransportError, isTransportError } from "./errors.js";
|
|
3
|
+
import { generateCodeChallenge, generateCodeVerifier, generateState } from "./pkce.js";
|
|
4
|
+
import { redactSecrets } from "../redact.js";
|
|
5
|
+
function isLoopbackRedirect(uri) {
|
|
6
|
+
try {
|
|
7
|
+
const url = new URL(uri);
|
|
8
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
const host = url.hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
12
|
+
if (host !== "localhost" && host !== "127.0.0.1" && host !== "::1") {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
if (url.username || url.password) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
return url.pathname === "/auth/callback";
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function resolveOAuthEndpoints(env = process.env) {
|
|
25
|
+
const clientId = (typeof env.PLAUD_MCP_CLIENT_ID === "string" && env.PLAUD_MCP_CLIENT_ID.trim()) ||
|
|
26
|
+
(typeof env.PLAUD_CLIENT_ID === "string" && env.PLAUD_CLIENT_ID.trim()) ||
|
|
27
|
+
DEFAULT_MCP_CLIENT_ID;
|
|
28
|
+
const redirectOverride = typeof env.PLAUD_CALLBACK_URL === "string" ? env.PLAUD_CALLBACK_URL.trim() : "";
|
|
29
|
+
const redirectUri = redirectOverride && isLoopbackRedirect(redirectOverride) ? redirectOverride : OAUTH_REDIRECT_URI;
|
|
30
|
+
return {
|
|
31
|
+
clientId,
|
|
32
|
+
redirectUri,
|
|
33
|
+
authorizationUrl: (typeof env.PLAUD_AUTH_URL === "string" && env.PLAUD_AUTH_URL.trim()) || DEFAULT_AUTHORIZATION_URL,
|
|
34
|
+
tokenUrl: (typeof env.PLAUD_TOKEN_URL === "string" && env.PLAUD_TOKEN_URL.trim()) || DEFAULT_TOKEN_URL,
|
|
35
|
+
refreshUrl: (typeof env.PLAUD_REFRESH_URL === "string" && env.PLAUD_REFRESH_URL.trim()) || DEFAULT_REFRESH_URL,
|
|
36
|
+
apiBase: (typeof env.PLAUD_MCP_API_BASE === "string" && env.PLAUD_MCP_API_BASE.trim()) || DEFAULT_MCP_API_BASE
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function createAuthorizationRequest(endpoints) {
|
|
40
|
+
const codeVerifier = generateCodeVerifier();
|
|
41
|
+
const codeChallenge = generateCodeChallenge(codeVerifier);
|
|
42
|
+
const state = generateState();
|
|
43
|
+
const params = new URLSearchParams({
|
|
44
|
+
client_id: endpoints.clientId,
|
|
45
|
+
redirect_uri: endpoints.redirectUri,
|
|
46
|
+
response_type: "code",
|
|
47
|
+
code_challenge: codeChallenge,
|
|
48
|
+
code_challenge_method: "S256",
|
|
49
|
+
state
|
|
50
|
+
});
|
|
51
|
+
return {
|
|
52
|
+
url: `${endpoints.authorizationUrl}?${params.toString()}`,
|
|
53
|
+
codeVerifier,
|
|
54
|
+
state
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export function parseTokenSet(data, nowMs, previous) {
|
|
58
|
+
if (!data || typeof data !== "object") {
|
|
59
|
+
throw new Error("Plaud token response was not JSON");
|
|
60
|
+
}
|
|
61
|
+
const rec = data;
|
|
62
|
+
const access = typeof rec.access_token === "string" && rec.access_token.trim() ? rec.access_token.trim() : "";
|
|
63
|
+
if (!access) {
|
|
64
|
+
throw new Error("Plaud token response missing access_token");
|
|
65
|
+
}
|
|
66
|
+
const refresh = typeof rec.refresh_token === "string" && rec.refresh_token.trim()
|
|
67
|
+
? rec.refresh_token.trim()
|
|
68
|
+
: previous?.refresh_token;
|
|
69
|
+
const expiresIn = typeof rec.expires_in === "number" && Number.isFinite(rec.expires_in) ? rec.expires_in : null;
|
|
70
|
+
const tokenType = typeof rec.token_type === "string" && rec.token_type.trim() ? rec.token_type.trim() : "Bearer";
|
|
71
|
+
const tokenSet = {
|
|
72
|
+
access_token: access,
|
|
73
|
+
token_type: tokenType
|
|
74
|
+
};
|
|
75
|
+
if (refresh) {
|
|
76
|
+
tokenSet.refresh_token = refresh;
|
|
77
|
+
}
|
|
78
|
+
if (expiresIn !== null) {
|
|
79
|
+
tokenSet.expires_at = nowMs + expiresIn * 1000;
|
|
80
|
+
}
|
|
81
|
+
return tokenSet;
|
|
82
|
+
}
|
|
83
|
+
export function parseStoredTokenSet(raw) {
|
|
84
|
+
try {
|
|
85
|
+
const parsed = JSON.parse(raw);
|
|
86
|
+
if (!parsed || typeof parsed !== "object") {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
const rec = parsed;
|
|
90
|
+
const access = typeof rec.access_token === "string" ? rec.access_token.trim() : "";
|
|
91
|
+
if (!access) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
const tokenSet = { access_token: access };
|
|
95
|
+
if (typeof rec.refresh_token === "string" && rec.refresh_token.trim()) {
|
|
96
|
+
tokenSet.refresh_token = rec.refresh_token.trim();
|
|
97
|
+
}
|
|
98
|
+
if (typeof rec.token_type === "string" && rec.token_type.trim()) {
|
|
99
|
+
tokenSet.token_type = rec.token_type.trim();
|
|
100
|
+
}
|
|
101
|
+
if (typeof rec.expires_at === "number" && Number.isFinite(rec.expires_at)) {
|
|
102
|
+
tokenSet.expires_at = rec.expires_at;
|
|
103
|
+
}
|
|
104
|
+
return tokenSet;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export function serializeTokenSet(tokenSet) {
|
|
111
|
+
return JSON.stringify(tokenSet);
|
|
112
|
+
}
|
|
113
|
+
export function tokenNeedsRefresh(tokenSet, nowMs, skewMs) {
|
|
114
|
+
if (!tokenSet.expires_at) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
return nowMs > tokenSet.expires_at - skewMs;
|
|
118
|
+
}
|
|
119
|
+
async function readJson(response) {
|
|
120
|
+
const text = await response.text();
|
|
121
|
+
if (!text) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
return JSON.parse(text);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return { error: "non_json", status: response.status };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export async function exchangeAuthorizationCode(options) {
|
|
132
|
+
const fetchImpl = options.fetchImpl || fetch;
|
|
133
|
+
const now = options.now || Date.now;
|
|
134
|
+
const basicAuth = Buffer.from(`${options.endpoints.clientId}:`).toString("base64");
|
|
135
|
+
let response;
|
|
136
|
+
try {
|
|
137
|
+
response = await fetchImpl(options.endpoints.tokenUrl, {
|
|
138
|
+
method: "POST",
|
|
139
|
+
headers: {
|
|
140
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
141
|
+
Accept: "application/json",
|
|
142
|
+
Authorization: `Basic ${basicAuth}`
|
|
143
|
+
},
|
|
144
|
+
body: new URLSearchParams({
|
|
145
|
+
code: options.code,
|
|
146
|
+
redirect_uri: options.endpoints.redirectUri,
|
|
147
|
+
code_verifier: options.codeVerifier,
|
|
148
|
+
state: options.state
|
|
149
|
+
})
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
throw new AuthTransportError("Plaud token exchange failed (network).");
|
|
154
|
+
}
|
|
155
|
+
if (!response.ok) {
|
|
156
|
+
throw new Error(redactSecrets(`Plaud token exchange failed (${response.status}).`));
|
|
157
|
+
}
|
|
158
|
+
const data = await readJson(response);
|
|
159
|
+
return parseTokenSet(data, now());
|
|
160
|
+
}
|
|
161
|
+
export async function refreshTokenSet(options) {
|
|
162
|
+
const refreshToken = options.tokenSet.refresh_token;
|
|
163
|
+
if (!refreshToken) {
|
|
164
|
+
throw new AuthExpiredError();
|
|
165
|
+
}
|
|
166
|
+
const fetchImpl = options.fetchImpl || fetch;
|
|
167
|
+
const now = options.now || Date.now;
|
|
168
|
+
let response;
|
|
169
|
+
try {
|
|
170
|
+
response = await fetchImpl(options.endpoints.refreshUrl, {
|
|
171
|
+
method: "POST",
|
|
172
|
+
headers: {
|
|
173
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
174
|
+
Accept: "application/json"
|
|
175
|
+
},
|
|
176
|
+
body: new URLSearchParams({ refresh_token: refreshToken })
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
if (isTransportError(err)) {
|
|
181
|
+
throw new AuthTransportError("Plaud token refresh failed (network).");
|
|
182
|
+
}
|
|
183
|
+
throw err;
|
|
184
|
+
}
|
|
185
|
+
if (!response.ok) {
|
|
186
|
+
if (response.status === 401 || response.status === 400 || response.status === 403) {
|
|
187
|
+
throw new AuthExpiredError();
|
|
188
|
+
}
|
|
189
|
+
if (response.status >= 500) {
|
|
190
|
+
throw new AuthTransportError(`Plaud token refresh failed (${response.status}).`);
|
|
191
|
+
}
|
|
192
|
+
throw new AuthExpiredError();
|
|
193
|
+
}
|
|
194
|
+
const data = await readJson(response);
|
|
195
|
+
return parseTokenSet(data, now(), options.tokenSet);
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/plaud/oauth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
2
|
+
export function generateCodeVerifier() {
|
|
3
|
+
return randomBytes(32).toString("base64url");
|
|
4
|
+
}
|
|
5
|
+
export function generateCodeChallenge(verifier) {
|
|
6
|
+
return createHash("sha256").update(verifier).digest("base64url");
|
|
7
|
+
}
|
|
8
|
+
export function generateState() {
|
|
9
|
+
return randomBytes(16).toString("base64url");
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=pkce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/plaud/pkce.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,UAAU,oBAAoB;IAClC,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,QAAgB;IACpD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { OAuthEndpoints, PlaudTokenSet } from "./types.js";
|
|
2
|
+
import type { SecretStore } from "../secrets.js";
|
|
3
|
+
export interface PlaudAuthSession {
|
|
4
|
+
endpoints: OAuthEndpoints;
|
|
5
|
+
getAccessToken(): Promise<string | null>;
|
|
6
|
+
/** Force a refresh (after a 401). */
|
|
7
|
+
refresh(): Promise<string>;
|
|
8
|
+
save(tokenSet: PlaudTokenSet): Promise<void>;
|
|
9
|
+
clear(): Promise<void>;
|
|
10
|
+
peek(): PlaudTokenSet | null;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* One Plaud sign-in stored in Keychain under a profile-specific account.
|
|
14
|
+
* Before refreshing, re-reads Keychain: if another process (daemon vs a manual
|
|
15
|
+
* CLI run) already rotated the refresh token, use that instead of burning ours.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createAuthSession(options: {
|
|
18
|
+
store: SecretStore;
|
|
19
|
+
account: string;
|
|
20
|
+
env?: NodeJS.ProcessEnv;
|
|
21
|
+
fetchImpl?: typeof fetch;
|
|
22
|
+
now?: () => number;
|
|
23
|
+
}): Promise<PlaudAuthSession>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { REFRESH_SKEW_MS } from "./constants.js";
|
|
2
|
+
import { AuthExpiredError, isAuthExpiredError, isTransportError } from "./errors.js";
|
|
3
|
+
import { parseStoredTokenSet, refreshTokenSet, resolveOAuthEndpoints, serializeTokenSet, tokenNeedsRefresh } from "./oauth.js";
|
|
4
|
+
/**
|
|
5
|
+
* One Plaud sign-in stored in Keychain under a profile-specific account.
|
|
6
|
+
* Before refreshing, re-reads Keychain: if another process (daemon vs a manual
|
|
7
|
+
* CLI run) already rotated the refresh token, use that instead of burning ours.
|
|
8
|
+
*/
|
|
9
|
+
export async function createAuthSession(options) {
|
|
10
|
+
const now = options.now || Date.now;
|
|
11
|
+
const endpoints = resolveOAuthEndpoints(options.env || process.env);
|
|
12
|
+
const load = async () => {
|
|
13
|
+
const raw = await options.store.get(options.account);
|
|
14
|
+
return raw ? parseStoredTokenSet(raw) : null;
|
|
15
|
+
};
|
|
16
|
+
let current = await load();
|
|
17
|
+
async function persist(next) {
|
|
18
|
+
current = next;
|
|
19
|
+
await options.store.set(options.account, serializeTokenSet(next));
|
|
20
|
+
}
|
|
21
|
+
async function refresh() {
|
|
22
|
+
const stored = await load();
|
|
23
|
+
if (stored && current && stored.access_token !== current.access_token && !tokenNeedsRefresh(stored, now(), REFRESH_SKEW_MS)) {
|
|
24
|
+
current = stored;
|
|
25
|
+
return stored.access_token;
|
|
26
|
+
}
|
|
27
|
+
if (stored) {
|
|
28
|
+
current = stored;
|
|
29
|
+
}
|
|
30
|
+
if (!current?.refresh_token) {
|
|
31
|
+
throw new AuthExpiredError();
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const next = await refreshTokenSet({ endpoints, tokenSet: current, fetchImpl: options.fetchImpl, now });
|
|
35
|
+
await persist(next);
|
|
36
|
+
return next.access_token;
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
if (isTransportError(err) || isAuthExpiredError(err)) {
|
|
40
|
+
throw err;
|
|
41
|
+
}
|
|
42
|
+
throw new AuthExpiredError();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function getAccessToken() {
|
|
46
|
+
if (!current) {
|
|
47
|
+
current = await load();
|
|
48
|
+
if (!current) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (tokenNeedsRefresh(current, now(), REFRESH_SKEW_MS)) {
|
|
53
|
+
try {
|
|
54
|
+
return await refresh();
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
if (isTransportError(err) && current?.access_token) {
|
|
58
|
+
return current.access_token;
|
|
59
|
+
}
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return current.access_token;
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
endpoints,
|
|
67
|
+
getAccessToken,
|
|
68
|
+
refresh,
|
|
69
|
+
save: persist,
|
|
70
|
+
clear: async () => {
|
|
71
|
+
current = null;
|
|
72
|
+
await options.store.delete(options.account);
|
|
73
|
+
},
|
|
74
|
+
peek: () => current
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/plaud/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACrF,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAcpB;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAMvC;IACC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,MAAM,SAAS,GAAG,qBAAqB,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,KAAK,IAAmC,EAAE;QACrD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACrD,OAAO,GAAG,CAAC,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/C,CAAC,CAAC;IACF,IAAI,OAAO,GAAG,MAAM,IAAI,EAAE,CAAC;IAE3B,KAAK,UAAU,OAAO,CAAC,IAAmB;QACxC,OAAO,GAAG,IAAI,CAAC;QACf,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,UAAU,OAAO;QACpB,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QAC5B,IAAI,MAAM,IAAI,OAAO,IAAI,MAAM,CAAC,YAAY,KAAK,OAAO,CAAC,YAAY,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,eAAe,CAAC,EAAE,CAAC;YAC5H,OAAO,GAAG,MAAM,CAAC;YACjB,OAAO,MAAM,CAAC,YAAY,CAAC;QAC7B,CAAC;QACD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,GAAG,MAAM,CAAC;QACnB,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,CAAC;YAC5B,MAAM,IAAI,gBAAgB,EAAE,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;YACxG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;YACpB,OAAO,IAAI,CAAC,YAAY,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,gBAAgB,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrD,MAAM,GAAG,CAAC;YACZ,CAAC;YACD,MAAM,IAAI,gBAAgB,EAAE,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,KAAK,UAAU,cAAc;QAC3B,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,MAAM,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,IAAI,iBAAiB,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,eAAe,CAAC,EAAE,CAAC;YACvD,IAAI,CAAC;gBACH,OAAO,MAAM,OAAO,EAAE,CAAC;YACzB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,gBAAgB,CAAC,GAAG,CAAC,IAAI,OAAO,EAAE,YAAY,EAAE,CAAC;oBACnD,OAAO,OAAO,CAAC,YAAY,CAAC;gBAC9B,CAAC;gBACD,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC,YAAY,CAAC;IAC9B,CAAC;IAED,OAAO;QACL,SAAS;QACT,cAAc;QACd,OAAO;QACP,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,OAAO,GAAG,IAAI,CAAC;YACf,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO;KACpB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Token document persisted in Keychain (compatible with `@plaud-ai/mcp` token files). */
|
|
2
|
+
export interface PlaudTokenSet {
|
|
3
|
+
access_token: string;
|
|
4
|
+
refresh_token?: string;
|
|
5
|
+
token_type?: string;
|
|
6
|
+
/** epoch ms; omitted if Plaud did not send expires_in */
|
|
7
|
+
expires_at?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface OAuthEndpoints {
|
|
10
|
+
clientId: string;
|
|
11
|
+
redirectUri: string;
|
|
12
|
+
authorizationUrl: string;
|
|
13
|
+
tokenUrl: string;
|
|
14
|
+
refreshUrl: string;
|
|
15
|
+
apiBase: string;
|
|
16
|
+
}
|
|
17
|
+
export interface AuthorizationRequest {
|
|
18
|
+
url: string;
|
|
19
|
+
codeVerifier: string;
|
|
20
|
+
state: string;
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/plaud/types.ts"],"names":[],"mappings":""}
|
package/dist/redact.d.ts
ADDED
package/dist/redact.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const SECRET_PATTERN = /(PLAUD_API_TOKEN\s*[=:=]\s*)([^\s"',}]+)|(X-Amz-(?:Security-Token|Signature|Credential)=)([^\s&"']+)|(code=)([^\s&"']+)|(NOTION_TOKEN\s*[=:=]\s*)([^\s"',}]+)|((?:OPENAI|ANTHROPIC)_API_KEY\s*[=:=]\s*)([^\s"',}]+)|(Bearer\s+)([A-Za-z0-9._\-+=/]+)|(authorization["']?\s*[:=]\s*["']?)([^"'\s]+)|((?:access_token|refresh_token)\s*[=:]\s*["']?)([^"'\s,}]+)|(sk-[A-Za-z0-9_-]{16,})|(ntn_[A-Za-z0-9]+)|(secret_[A-Za-z0-9]+)/gi;
|
|
2
|
+
export function redactSecrets(text) {
|
|
3
|
+
if (!text) {
|
|
4
|
+
return text;
|
|
5
|
+
}
|
|
6
|
+
return text
|
|
7
|
+
.replace(SECRET_PATTERN, (full, a, _b, c, _d, e, _f, g, _h, i, _j, k, _l, m, _n, o) => {
|
|
8
|
+
if (a)
|
|
9
|
+
return `${a}[REDACTED]`;
|
|
10
|
+
if (c)
|
|
11
|
+
return `${c}[REDACTED]`;
|
|
12
|
+
if (e)
|
|
13
|
+
return `${e}[REDACTED]`;
|
|
14
|
+
if (g)
|
|
15
|
+
return `${g}[REDACTED]`;
|
|
16
|
+
if (i)
|
|
17
|
+
return `${i}[REDACTED]`;
|
|
18
|
+
if (k)
|
|
19
|
+
return `${k}[REDACTED]`;
|
|
20
|
+
if (m)
|
|
21
|
+
return `${m}[REDACTED]`;
|
|
22
|
+
if (o)
|
|
23
|
+
return `${o}[REDACTED]`;
|
|
24
|
+
return "[REDACTED]";
|
|
25
|
+
})
|
|
26
|
+
.replace(/\beyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g, "[REDACTED]");
|
|
27
|
+
}
|
|
28
|
+
export function looksLikeSecret(value) {
|
|
29
|
+
return /sk-[A-Za-z0-9_-]{16,}|ntn_[A-Za-z0-9]{8,}|secret_[A-Za-z0-9]{8,}|Bearer\s+[A-Za-z0-9._\-]{20,}|eyJ[A-Za-z0-9_-]{20,}\./.test(value);
|
|
30
|
+
}
|
|
31
|
+
export function safeErrorMessage(err) {
|
|
32
|
+
if (err instanceof Error) {
|
|
33
|
+
return redactSecrets(err.message);
|
|
34
|
+
}
|
|
35
|
+
return redactSecrets(String(err));
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=redact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"AAAA,MAAM,cAAc,GAClB,maAAma,CAAC;AAEta,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,IAAI;SACR,OAAO,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE;QACpF,IAAI,CAAC;YAAE,OAAO,GAAG,CAAC,YAAY,CAAC;QAC/B,IAAI,CAAC;YAAE,OAAO,GAAG,CAAC,YAAY,CAAC;QAC/B,IAAI,CAAC;YAAE,OAAO,GAAG,CAAC,YAAY,CAAC;QAC/B,IAAI,CAAC;YAAE,OAAO,GAAG,CAAC,YAAY,CAAC;QAC/B,IAAI,CAAC;YAAE,OAAO,GAAG,CAAC,YAAY,CAAC;QAC/B,IAAI,CAAC;YAAE,OAAO,GAAG,CAAC,YAAY,CAAC;QAC/B,IAAI,CAAC;YAAE,OAAO,GAAG,CAAC,YAAY,CAAC;QAC/B,IAAI,CAAC;YAAE,OAAO,GAAG,CAAC,YAAY,CAAC;QAC/B,OAAO,YAAY,CAAC;IACtB,CAAC,CAAC;SACD,OAAO,CAAC,4DAA4D,EAAE,YAAY,CAAC,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,wHAAwH,CAAC,IAAI,CAClI,KAAK,CACN,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { AppConfig, ProfileConfig } from "./config.js";
|
|
2
|
+
import { type Labeler } from "./llm.js";
|
|
3
|
+
import { type NotionStore } from "./notion.js";
|
|
4
|
+
import { type PlaudClient } from "./plaud/client.js";
|
|
5
|
+
import type { SecretStore } from "./secrets.js";
|
|
6
|
+
export declare class SetupError extends Error {
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
export interface ProfileRuntime {
|
|
10
|
+
plaud: PlaudClient;
|
|
11
|
+
notion: NotionStore;
|
|
12
|
+
labeler: Labeler;
|
|
13
|
+
}
|
|
14
|
+
export declare function openaiKey(store: SecretStore, credentials: string, env: NodeJS.ProcessEnv): Promise<string>;
|
|
15
|
+
export declare function anthropicKey(store: SecretStore, credentials: string, env: NodeJS.ProcessEnv): Promise<string>;
|
|
16
|
+
/** The API key for the configured model's provider; SetupError naming the right `set-secret` if missing. */
|
|
17
|
+
export declare function llmKey(store: SecretStore, credentials: string, model: string, env: NodeJS.ProcessEnv): Promise<string>;
|
|
18
|
+
export declare function buildProfileRuntime(options: {
|
|
19
|
+
name: string;
|
|
20
|
+
profile: ProfileConfig;
|
|
21
|
+
config: AppConfig;
|
|
22
|
+
store: SecretStore;
|
|
23
|
+
env?: NodeJS.ProcessEnv;
|
|
24
|
+
needPlaud: boolean;
|
|
25
|
+
needLabeler: boolean;
|
|
26
|
+
}): Promise<ProfileRuntime>;
|
|
27
|
+
export interface ProfileStatus {
|
|
28
|
+
lastPollAt?: string;
|
|
29
|
+
lastPollOkAt?: string;
|
|
30
|
+
lastSyncOkAt?: string;
|
|
31
|
+
lastWritten?: {
|
|
32
|
+
title: string;
|
|
33
|
+
at: string;
|
|
34
|
+
};
|
|
35
|
+
pending?: number;
|
|
36
|
+
lastError?: string;
|
|
37
|
+
lastErrorAt?: string;
|
|
38
|
+
alertedAt?: string;
|
|
39
|
+
}
|
|
40
|
+
export type StatusFile = Record<string, ProfileStatus>;
|
|
41
|
+
export declare function readStatus(env?: NodeJS.ProcessEnv): StatusFile;
|
|
42
|
+
export declare function updateStatus(profile: string, patch: Partial<ProfileStatus>, env?: NodeJS.ProcessEnv): ProfileStatus;
|
|
43
|
+
/** macOS banner so an expired sign-in never fails silently. Best effort. */
|
|
44
|
+
export declare function notifyMac(title: string, message: string): void;
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { ANTHROPIC_ACCOUNT, OPENAI_ACCOUNT, RELLOGIN_ANTHROPIC, RELLOGIN_LLM, RELLOGIN_NOTION, anthropicAccount, isAnthropicModel, notionAccount, openaiAccount, plaudAccount, relogin } from "./constants.js";
|
|
3
|
+
import { createLabeler } from "./llm.js";
|
|
4
|
+
import { HttpNotionStore } from "./notion.js";
|
|
5
|
+
import { getStatusPath, readJson, writeJsonAtomic } from "./paths.js";
|
|
6
|
+
import { HttpPlaudClient } from "./plaud/client.js";
|
|
7
|
+
import { createAuthSession } from "./plaud/session.js";
|
|
8
|
+
export class SetupError extends Error {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = "SetupError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export async function openaiKey(store, credentials, env) {
|
|
15
|
+
const key = env.OPENAI_API_KEY?.trim() || (await store.get(openaiAccount(credentials))) || (await store.get(OPENAI_ACCOUNT));
|
|
16
|
+
if (!key) {
|
|
17
|
+
throw new SetupError(RELLOGIN_LLM);
|
|
18
|
+
}
|
|
19
|
+
return key;
|
|
20
|
+
}
|
|
21
|
+
export async function anthropicKey(store, credentials, env) {
|
|
22
|
+
const key = env.ANTHROPIC_API_KEY?.trim() || (await store.get(anthropicAccount(credentials))) || (await store.get(ANTHROPIC_ACCOUNT));
|
|
23
|
+
if (!key) {
|
|
24
|
+
throw new SetupError(RELLOGIN_ANTHROPIC);
|
|
25
|
+
}
|
|
26
|
+
return key;
|
|
27
|
+
}
|
|
28
|
+
/** The API key for the configured model's provider; SetupError naming the right `set-secret` if missing. */
|
|
29
|
+
export async function llmKey(store, credentials, model, env) {
|
|
30
|
+
return isAnthropicModel(model) ? anthropicKey(store, credentials, env) : openaiKey(store, credentials, env);
|
|
31
|
+
}
|
|
32
|
+
export async function buildProfileRuntime(options) {
|
|
33
|
+
const env = options.env || process.env;
|
|
34
|
+
const creds = options.profile.credentials;
|
|
35
|
+
const notionToken = await options.store.get(notionAccount(creds));
|
|
36
|
+
if (!notionToken) {
|
|
37
|
+
throw new SetupError(RELLOGIN_NOTION(creds));
|
|
38
|
+
}
|
|
39
|
+
const notion = new HttpNotionStore({ token: notionToken, dataSourceId: options.profile.notionDataSourceId });
|
|
40
|
+
let plaud = {
|
|
41
|
+
listFiles: () => Promise.reject(new SetupError("Plaud not needed for this command")),
|
|
42
|
+
getRecording: () => Promise.reject(new SetupError("Plaud not needed for this command")),
|
|
43
|
+
currentUser: () => Promise.reject(new SetupError("Plaud not needed for this command"))
|
|
44
|
+
};
|
|
45
|
+
if (options.needPlaud) {
|
|
46
|
+
const session = await createAuthSession({ store: options.store, account: plaudAccount(creds), env });
|
|
47
|
+
if (!session.peek()) {
|
|
48
|
+
throw new SetupError(relogin(creds));
|
|
49
|
+
}
|
|
50
|
+
plaud = new HttpPlaudClient(session);
|
|
51
|
+
}
|
|
52
|
+
let labeler = { label: () => Promise.reject(new SetupError("Labeler not needed for this command")) };
|
|
53
|
+
if (options.needLabeler) {
|
|
54
|
+
const { llmModel, llmEffort, openaiBaseUrl, anthropicBaseUrl } = options.config;
|
|
55
|
+
const key = await llmKey(options.store, creds, llmModel, env);
|
|
56
|
+
labeler = createLabeler({
|
|
57
|
+
model: llmModel,
|
|
58
|
+
effort: llmEffort,
|
|
59
|
+
openaiKey: isAnthropicModel(llmModel) ? undefined : key,
|
|
60
|
+
anthropicKey: isAnthropicModel(llmModel) ? key : undefined,
|
|
61
|
+
openaiBaseUrl,
|
|
62
|
+
anthropicBaseUrl
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return { plaud, notion, labeler };
|
|
66
|
+
}
|
|
67
|
+
export function readStatus(env = process.env) {
|
|
68
|
+
return readJson(getStatusPath(env)) || {};
|
|
69
|
+
}
|
|
70
|
+
export function updateStatus(profile, patch, env = process.env) {
|
|
71
|
+
const all = readStatus(env);
|
|
72
|
+
const next = { ...(all[profile] || {}), ...patch };
|
|
73
|
+
all[profile] = next;
|
|
74
|
+
writeJsonAtomic(getStatusPath(env), all);
|
|
75
|
+
return next;
|
|
76
|
+
}
|
|
77
|
+
/** macOS banner so an expired sign-in never fails silently. Best effort. */
|
|
78
|
+
export function notifyMac(title, message) {
|
|
79
|
+
if (process.platform !== "darwin") {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const esc = (s) => s.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
83
|
+
try {
|
|
84
|
+
const child = spawn("/usr/bin/osascript", ["-e", `display notification "${esc(message)}" with title "${esc(title)}"`], {
|
|
85
|
+
stdio: "ignore",
|
|
86
|
+
detached: true
|
|
87
|
+
});
|
|
88
|
+
child.unref();
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
/* ignore */
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|
package/dist/scrub.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ScrubResult {
|
|
2
|
+
rowsScanned: number;
|
|
3
|
+
rowsAffected: Array<{
|
|
4
|
+
title: string;
|
|
5
|
+
type: string;
|
|
6
|
+
ssn: number;
|
|
7
|
+
card: number;
|
|
8
|
+
}>;
|
|
9
|
+
blocksUpdated: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function scrubSensitive(options: {
|
|
12
|
+
token: string;
|
|
13
|
+
dataSourceId: string;
|
|
14
|
+
apply: boolean;
|
|
15
|
+
log: (m: string) => void;
|
|
16
|
+
fetchImpl?: typeof fetch;
|
|
17
|
+
}): Promise<ScrubResult>;
|