@davidwoods/skylight-mcp 0.0.0-stage → 1.8.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/LICENSE +22 -0
- package/README.md +633 -3
- package/THIRD_PARTY_NOTICES.md +38 -0
- package/dist/api/auth.d.ts +34 -0
- package/dist/api/auth.d.ts.map +1 -0
- package/dist/api/auth.js +328 -0
- package/dist/api/auth.js.map +1 -0
- package/dist/api/client.d.ts +103 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +324 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/constants.d.ts +4 -0
- package/dist/api/constants.d.ts.map +1 -0
- package/dist/api/constants.js +4 -0
- package/dist/api/constants.js.map +1 -0
- package/dist/api/credential-store.d.ts +38 -0
- package/dist/api/credential-store.d.ts.map +1 -0
- package/dist/api/credential-store.js +274 -0
- package/dist/api/credential-store.js.map +1 -0
- package/dist/api/credential-types.d.ts +15 -0
- package/dist/api/credential-types.d.ts.map +1 -0
- package/dist/api/credential-types.js +11 -0
- package/dist/api/credential-types.js.map +1 -0
- package/dist/api/endpoints/calendar.d.ts +36 -0
- package/dist/api/endpoints/calendar.d.ts.map +1 -0
- package/dist/api/endpoints/calendar.js +74 -0
- package/dist/api/endpoints/calendar.js.map +1 -0
- package/dist/api/endpoints/categories.d.ts +32 -0
- package/dist/api/endpoints/categories.d.ts.map +1 -0
- package/dist/api/endpoints/categories.js +70 -0
- package/dist/api/endpoints/categories.js.map +1 -0
- package/dist/api/endpoints/chores.d.ts +58 -0
- package/dist/api/endpoints/chores.d.ts.map +1 -0
- package/dist/api/endpoints/chores.js +115 -0
- package/dist/api/endpoints/chores.js.map +1 -0
- package/dist/api/endpoints/devices.d.ts +6 -0
- package/dist/api/endpoints/devices.d.ts.map +1 -0
- package/dist/api/endpoints/devices.js +10 -0
- package/dist/api/endpoints/devices.js.map +1 -0
- package/dist/api/endpoints/frames.d.ts +6 -0
- package/dist/api/endpoints/frames.d.ts.map +1 -0
- package/dist/api/endpoints/frames.js +10 -0
- package/dist/api/endpoints/frames.js.map +1 -0
- package/dist/api/endpoints/lists.d.ts +55 -0
- package/dist/api/endpoints/lists.d.ts.map +1 -0
- package/dist/api/endpoints/lists.js +125 -0
- package/dist/api/endpoints/lists.js.map +1 -0
- package/dist/api/endpoints/meals.d.ts +154 -0
- package/dist/api/endpoints/meals.d.ts.map +1 -0
- package/dist/api/endpoints/meals.js +194 -0
- package/dist/api/endpoints/meals.js.map +1 -0
- package/dist/api/endpoints/messages.d.ts +98 -0
- package/dist/api/endpoints/messages.d.ts.map +1 -0
- package/dist/api/endpoints/messages.js +116 -0
- package/dist/api/endpoints/messages.js.map +1 -0
- package/dist/api/endpoints/misc.d.ts +27 -0
- package/dist/api/endpoints/misc.d.ts.map +1 -0
- package/dist/api/endpoints/misc.js +19 -0
- package/dist/api/endpoints/misc.js.map +1 -0
- package/dist/api/endpoints/photos.d.ts +13 -0
- package/dist/api/endpoints/photos.d.ts.map +1 -0
- package/dist/api/endpoints/photos.js +10 -0
- package/dist/api/endpoints/photos.js.map +1 -0
- package/dist/api/endpoints/rewards.d.ts +49 -0
- package/dist/api/endpoints/rewards.d.ts.map +1 -0
- package/dist/api/endpoints/rewards.js +106 -0
- package/dist/api/endpoints/rewards.js.map +1 -0
- package/dist/api/endpoints/shape.d.ts +11 -0
- package/dist/api/endpoints/shape.d.ts.map +1 -0
- package/dist/api/endpoints/shape.js +34 -0
- package/dist/api/endpoints/shape.js.map +1 -0
- package/dist/api/endpoints/taskbox.d.ts +21 -0
- package/dist/api/endpoints/taskbox.d.ts.map +1 -0
- package/dist/api/endpoints/taskbox.js +39 -0
- package/dist/api/endpoints/taskbox.js.map +1 -0
- package/dist/api/oauth.d.ts +62 -0
- package/dist/api/oauth.d.ts.map +1 -0
- package/dist/api/oauth.js +206 -0
- package/dist/api/oauth.js.map +1 -0
- package/dist/api/types.d.ts +291 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +5 -0
- package/dist/api/types.js.map +1 -0
- package/dist/cli.d.ts +23 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +106 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +27 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +78 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +17 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +17 -0
- package/dist/context.js.map +1 -0
- package/dist/doctor.d.ts +29 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +125 -0
- package/dist/doctor.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +29 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/calendar.d.ts +8 -0
- package/dist/tools/calendar.d.ts.map +1 -0
- package/dist/tools/calendar.js +334 -0
- package/dist/tools/calendar.js.map +1 -0
- package/dist/tools/chores.d.ts +3 -0
- package/dist/tools/chores.d.ts.map +1 -0
- package/dist/tools/chores.js +321 -0
- package/dist/tools/chores.js.map +1 -0
- package/dist/tools/family.d.ts +3 -0
- package/dist/tools/family.d.ts.map +1 -0
- package/dist/tools/family.js +182 -0
- package/dist/tools/family.js.map +1 -0
- package/dist/tools/lists.d.ts +3 -0
- package/dist/tools/lists.d.ts.map +1 -0
- package/dist/tools/lists.js +481 -0
- package/dist/tools/lists.js.map +1 -0
- package/dist/tools/meals.d.ts +3 -0
- package/dist/tools/meals.d.ts.map +1 -0
- package/dist/tools/meals.js +491 -0
- package/dist/tools/meals.js.map +1 -0
- package/dist/tools/messages.d.ts +3 -0
- package/dist/tools/messages.d.ts.map +1 -0
- package/dist/tools/messages.js +183 -0
- package/dist/tools/messages.js.map +1 -0
- package/dist/tools/misc.d.ts +3 -0
- package/dist/tools/misc.d.ts.map +1 -0
- package/dist/tools/misc.js +102 -0
- package/dist/tools/misc.js.map +1 -0
- package/dist/tools/photos.d.ts +3 -0
- package/dist/tools/photos.d.ts.map +1 -0
- package/dist/tools/photos.js +42 -0
- package/dist/tools/photos.js.map +1 -0
- package/dist/tools/planning.d.ts +15 -0
- package/dist/tools/planning.d.ts.map +1 -0
- package/dist/tools/planning.js +304 -0
- package/dist/tools/planning.js.map +1 -0
- package/dist/tools/registry.d.ts +39 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +143 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/rewards.d.ts +3 -0
- package/dist/tools/rewards.d.ts.map +1 -0
- package/dist/tools/rewards.js +323 -0
- package/dist/tools/rewards.js.map +1 -0
- package/dist/tools/tasks.d.ts +3 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +103 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/utils/dates.d.ts +26 -0
- package/dist/utils/dates.d.ts.map +1 -0
- package/dist/utils/dates.js +109 -0
- package/dist/utils/dates.js.map +1 -0
- package/dist/utils/errors.d.ts +45 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +102 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/schedule.d.ts +86 -0
- package/dist/utils/schedule.d.ts.map +1 -0
- package/dist/utils/schedule.js +189 -0
- package/dist/utils/schedule.js.map +1 -0
- package/package.json +78 -6
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-paste OAuth login and token refresh.
|
|
3
|
+
*
|
|
4
|
+
* The user signs in to Skylight in their own browser, then pastes the final
|
|
5
|
+
* https://ourskylight.com/welcome?code=... URL back into the CLI. The password
|
|
6
|
+
* never reaches this process. The authorization code is bound to a PKCE
|
|
7
|
+
* verifier and a random state value that are kept in a short-lived, 0600
|
|
8
|
+
* "pending login" file between the two CLI steps.
|
|
9
|
+
*
|
|
10
|
+
* Design informed by kamilio/skylight-calendar-agent (MIT); see
|
|
11
|
+
* THIRD_PARTY_NOTICES.md. Unlike that project's flow, this one uses PKCE (S256)
|
|
12
|
+
* and verifies the returned state against the pending login.
|
|
13
|
+
*/
|
|
14
|
+
import { createHash, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
|
15
|
+
import { SKYLIGHT_BASE_URL, SKYLIGHT_WEB_APP_URL } from "./constants.js";
|
|
16
|
+
export const OAUTH_CLIENT_ID = "skylight-mobile";
|
|
17
|
+
const SCOPE = "everything";
|
|
18
|
+
const REDIRECT_URI = `${SKYLIGHT_WEB_APP_URL}/welcome`;
|
|
19
|
+
const REQUEST_TIMEOUT_MS = 30_000;
|
|
20
|
+
const MAX_FIELD_LENGTH = 8_192;
|
|
21
|
+
const DEFAULT_EXPIRES_IN_S = 3_600;
|
|
22
|
+
/** How long a pending login stays valid between `auth login` and `auth complete`. */
|
|
23
|
+
export const PENDING_LOGIN_TTL_MS = 10 * 60 * 1000;
|
|
24
|
+
/** Refresh this long before the access token actually expires. */
|
|
25
|
+
export const EXPIRY_SKEW_MS = 60 * 1000;
|
|
26
|
+
export class OAuthError extends Error {
|
|
27
|
+
constructor(message) {
|
|
28
|
+
super(message);
|
|
29
|
+
this.name = "OAuthError";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function base64url(bytes) {
|
|
33
|
+
return bytes.toString("base64url");
|
|
34
|
+
}
|
|
35
|
+
function deviceMetadata(fingerprint) {
|
|
36
|
+
const hardware = process.platform === "darwin"
|
|
37
|
+
? "Macintosh"
|
|
38
|
+
: process.platform === "win32"
|
|
39
|
+
? "Windows"
|
|
40
|
+
: process.platform === "linux"
|
|
41
|
+
? "Linux"
|
|
42
|
+
: process.platform;
|
|
43
|
+
return {
|
|
44
|
+
skylight_api_client_device_fingerprint: fingerprint,
|
|
45
|
+
skylight_api_client_device_platform: "web",
|
|
46
|
+
skylight_api_client_device_name: "unknown",
|
|
47
|
+
skylight_api_client_device_os_version: "unknown",
|
|
48
|
+
skylight_api_client_device_app_version: "unknown",
|
|
49
|
+
skylight_api_client_device_hardware: hardware,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** The S256 challenge for a verifier. */
|
|
53
|
+
export function codeChallengeFor(codeVerifier) {
|
|
54
|
+
return base64url(createHash("sha256").update(codeVerifier).digest());
|
|
55
|
+
}
|
|
56
|
+
/** Fresh PKCE verifier, state and device fingerprint for a new login. */
|
|
57
|
+
export function newPendingLogin(now = Date.now(), overrides = {}) {
|
|
58
|
+
return {
|
|
59
|
+
state: overrides.state ?? randomBytes(16).toString("hex"),
|
|
60
|
+
codeVerifier: base64url(randomBytes(32)),
|
|
61
|
+
fingerprint: overrides.fingerprint ?? randomUUID(),
|
|
62
|
+
createdAt: now,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/** The Skylight authorize URL for a pending login. */
|
|
66
|
+
export function authorizeUrlFor(pending) {
|
|
67
|
+
const url = new URL("/oauth/authorize", SKYLIGHT_BASE_URL);
|
|
68
|
+
url.searchParams.set("client_id", OAUTH_CLIENT_ID);
|
|
69
|
+
url.searchParams.set("response_type", "code");
|
|
70
|
+
url.searchParams.set("redirect_uri", REDIRECT_URI);
|
|
71
|
+
url.searchParams.set("scope", SCOPE);
|
|
72
|
+
url.searchParams.set("state", pending.state);
|
|
73
|
+
url.searchParams.set("code_challenge", codeChallengeFor(pending.codeVerifier));
|
|
74
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
75
|
+
url.searchParams.set("skylight_api_client_device_fingerprint", pending.fingerprint);
|
|
76
|
+
return url.toString();
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Start a login: returns the URL the user must open in their browser and the
|
|
80
|
+
* pending-login record the caller must persist until `completeBrowserLogin`.
|
|
81
|
+
*/
|
|
82
|
+
export function beginBrowserLogin(now = Date.now(), overrides = {}) {
|
|
83
|
+
const pending = newPendingLogin(now, overrides);
|
|
84
|
+
return { loginUrl: authorizeUrlFor(pending), pending };
|
|
85
|
+
}
|
|
86
|
+
function safeEqual(a, b) {
|
|
87
|
+
const left = Buffer.from(a);
|
|
88
|
+
const right = Buffer.from(b);
|
|
89
|
+
return left.length === right.length && timingSafeEqual(left, right);
|
|
90
|
+
}
|
|
91
|
+
/** Extract and validate the authorization code from the pasted callback URL. */
|
|
92
|
+
export function parseCallbackUrl(callbackUrl, pending, now = Date.now()) {
|
|
93
|
+
if (now - pending.createdAt > PENDING_LOGIN_TTL_MS) {
|
|
94
|
+
throw new OAuthError("The login attempt expired. Run `skylight-mcp auth login` again.");
|
|
95
|
+
}
|
|
96
|
+
let callback;
|
|
97
|
+
try {
|
|
98
|
+
callback = new URL(callbackUrl.trim());
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
throw new OAuthError("Paste the complete URL shown in your browser after signing in.");
|
|
102
|
+
}
|
|
103
|
+
const expected = new URL(REDIRECT_URI);
|
|
104
|
+
if (callback.protocol !== "https:" || callback.hostname !== expected.hostname || callback.pathname !== expected.pathname) {
|
|
105
|
+
throw new OAuthError(`The URL must start with ${REDIRECT_URI}.`);
|
|
106
|
+
}
|
|
107
|
+
const error = callback.searchParams.get("error");
|
|
108
|
+
if (error) {
|
|
109
|
+
throw new OAuthError(`Skylight returned an error during sign-in: ${error.slice(0, 100)}`);
|
|
110
|
+
}
|
|
111
|
+
const code = callback.searchParams.get("code");
|
|
112
|
+
const state = callback.searchParams.get("state");
|
|
113
|
+
if (!code || !state) {
|
|
114
|
+
throw new OAuthError("The URL did not contain a code and state. Run `skylight-mcp auth login` again.");
|
|
115
|
+
}
|
|
116
|
+
if (code.length > MAX_FIELD_LENGTH || state.length > MAX_FIELD_LENGTH) {
|
|
117
|
+
throw new OAuthError("The URL contained an unexpectedly long value.");
|
|
118
|
+
}
|
|
119
|
+
if (!safeEqual(state, pending.state)) {
|
|
120
|
+
throw new OAuthError("State mismatch: this URL does not belong to the pending login. Run `skylight-mcp auth login` again.");
|
|
121
|
+
}
|
|
122
|
+
return code;
|
|
123
|
+
}
|
|
124
|
+
async function tokenRequest(values, fingerprint, fetchImpl, now) {
|
|
125
|
+
const response = await fetchImpl(`${SKYLIGHT_BASE_URL}/oauth/token`, {
|
|
126
|
+
method: "POST",
|
|
127
|
+
headers: {
|
|
128
|
+
Accept: "application/json",
|
|
129
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
130
|
+
},
|
|
131
|
+
body: values,
|
|
132
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
133
|
+
});
|
|
134
|
+
const text = await response.text();
|
|
135
|
+
if (!response.ok) {
|
|
136
|
+
// Error bodies carry OAuth error codes only; cap length defensively.
|
|
137
|
+
throw new OAuthError(`Skylight token request failed (HTTP ${response.status}): ${text.slice(0, 200)}`);
|
|
138
|
+
}
|
|
139
|
+
let json;
|
|
140
|
+
try {
|
|
141
|
+
json = JSON.parse(text);
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
throw new OAuthError("Skylight token response was not valid JSON.");
|
|
145
|
+
}
|
|
146
|
+
const accessToken = json.access_token ?? json.token;
|
|
147
|
+
if (typeof accessToken !== "string" || accessToken.length === 0 || accessToken.length > MAX_FIELD_LENGTH) {
|
|
148
|
+
throw new OAuthError("Skylight token response did not contain an access token.");
|
|
149
|
+
}
|
|
150
|
+
const refreshToken = json.refresh_token;
|
|
151
|
+
if (typeof refreshToken !== "string" || refreshToken.length === 0 || refreshToken.length > MAX_FIELD_LENGTH) {
|
|
152
|
+
throw new OAuthError("Skylight token response did not contain a refresh token.");
|
|
153
|
+
}
|
|
154
|
+
const expiresIn = typeof json.expires_in === "number" && Number.isFinite(json.expires_in) && json.expires_in > 0
|
|
155
|
+
? json.expires_in
|
|
156
|
+
: DEFAULT_EXPIRES_IN_S;
|
|
157
|
+
return {
|
|
158
|
+
version: 1,
|
|
159
|
+
type: "oauth",
|
|
160
|
+
accessToken,
|
|
161
|
+
refreshToken,
|
|
162
|
+
fingerprint,
|
|
163
|
+
expiresAt: now + Math.floor(expiresIn * 1000),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
/** Exchange the pasted callback URL for a credential. */
|
|
167
|
+
export async function completeBrowserLogin(callbackUrl, pending, fetchImpl = fetch, now = Date.now()) {
|
|
168
|
+
const code = parseCallbackUrl(callbackUrl, pending, now);
|
|
169
|
+
return tokenRequest(new URLSearchParams({
|
|
170
|
+
grant_type: "authorization_code",
|
|
171
|
+
client_id: OAUTH_CLIENT_ID,
|
|
172
|
+
scope: SCOPE,
|
|
173
|
+
redirect_uri: REDIRECT_URI,
|
|
174
|
+
code,
|
|
175
|
+
code_verifier: pending.codeVerifier,
|
|
176
|
+
...deviceMetadata(pending.fingerprint),
|
|
177
|
+
}), pending.fingerprint, fetchImpl, now);
|
|
178
|
+
}
|
|
179
|
+
/** Use the refresh token to obtain a new credential. Refresh tokens rotate. */
|
|
180
|
+
export async function refreshCredential(credential, fetchImpl = fetch, now = Date.now()) {
|
|
181
|
+
return tokenRequest(new URLSearchParams({
|
|
182
|
+
grant_type: "refresh_token",
|
|
183
|
+
client_id: OAUTH_CLIENT_ID,
|
|
184
|
+
refresh_token: credential.refreshToken,
|
|
185
|
+
...deviceMetadata(credential.fingerprint),
|
|
186
|
+
}), credential.fingerprint, fetchImpl, now);
|
|
187
|
+
}
|
|
188
|
+
export function isExpired(credential, now = Date.now()) {
|
|
189
|
+
return credential.expiresAt - EXPIRY_SKEW_MS <= now;
|
|
190
|
+
}
|
|
191
|
+
export function parseStoredCredential(value) {
|
|
192
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
193
|
+
return null;
|
|
194
|
+
const record = value;
|
|
195
|
+
if (record.version !== 1 ||
|
|
196
|
+
record.type !== "oauth" ||
|
|
197
|
+
typeof record.accessToken !== "string" ||
|
|
198
|
+
typeof record.refreshToken !== "string" ||
|
|
199
|
+
typeof record.fingerprint !== "string" ||
|
|
200
|
+
typeof record.expiresAt !== "number" ||
|
|
201
|
+
!Number.isFinite(record.expiresAt)) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
return record;
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/api/oauth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript types for Skylight API responses (JSON:API format)
|
|
3
|
+
*/
|
|
4
|
+
export interface JsonApiResourceId {
|
|
5
|
+
type: string;
|
|
6
|
+
id: string;
|
|
7
|
+
}
|
|
8
|
+
export interface JsonApiResponse<D, I = unknown> {
|
|
9
|
+
data: D;
|
|
10
|
+
included?: I[];
|
|
11
|
+
meta?: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
export interface CategoryAttributes {
|
|
14
|
+
label: string | null;
|
|
15
|
+
color: string | null;
|
|
16
|
+
selected_for_chore_chart: boolean | null;
|
|
17
|
+
linked_to_profile: boolean | null;
|
|
18
|
+
profile_pic_url: string | null;
|
|
19
|
+
}
|
|
20
|
+
export interface CategoryResource {
|
|
21
|
+
type: "category";
|
|
22
|
+
id: string;
|
|
23
|
+
attributes: CategoryAttributes;
|
|
24
|
+
}
|
|
25
|
+
export interface ChoreAttributes {
|
|
26
|
+
id?: number | null;
|
|
27
|
+
summary: string;
|
|
28
|
+
status: string;
|
|
29
|
+
start: string;
|
|
30
|
+
start_time: string | null;
|
|
31
|
+
completed_on: string | null;
|
|
32
|
+
is_future: boolean | null;
|
|
33
|
+
recurring: boolean;
|
|
34
|
+
recurring_until: string | null;
|
|
35
|
+
recurrence_set: string | null;
|
|
36
|
+
reward_points: number | null;
|
|
37
|
+
emoji_icon: string | null;
|
|
38
|
+
routine: boolean | null;
|
|
39
|
+
position: number | null;
|
|
40
|
+
up_for_grabs?: boolean | null;
|
|
41
|
+
}
|
|
42
|
+
export interface ChoreRelationships {
|
|
43
|
+
category?: {
|
|
44
|
+
data: JsonApiResourceId | null;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export interface ChoreResource {
|
|
48
|
+
type: "chore";
|
|
49
|
+
id: string;
|
|
50
|
+
attributes: ChoreAttributes;
|
|
51
|
+
relationships?: ChoreRelationships;
|
|
52
|
+
}
|
|
53
|
+
export interface ListAttributes {
|
|
54
|
+
label: string;
|
|
55
|
+
color: string | null;
|
|
56
|
+
kind: "shopping" | "to_do";
|
|
57
|
+
default_grocery_list: boolean;
|
|
58
|
+
}
|
|
59
|
+
export interface ListRelationships {
|
|
60
|
+
list_items?: {
|
|
61
|
+
data: JsonApiResourceId[];
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export interface ListResource {
|
|
65
|
+
type: "list";
|
|
66
|
+
id: string;
|
|
67
|
+
attributes: ListAttributes;
|
|
68
|
+
relationships?: ListRelationships;
|
|
69
|
+
}
|
|
70
|
+
export interface ListItemAttributes {
|
|
71
|
+
label: string;
|
|
72
|
+
status: "pending" | "completed";
|
|
73
|
+
section: string | null;
|
|
74
|
+
position: number | null;
|
|
75
|
+
created_at: string | null;
|
|
76
|
+
}
|
|
77
|
+
export interface ListItemResource {
|
|
78
|
+
type: "list_item";
|
|
79
|
+
id: string;
|
|
80
|
+
attributes: ListItemAttributes;
|
|
81
|
+
}
|
|
82
|
+
export interface TaskBoxItemAttributes {
|
|
83
|
+
id?: number | null;
|
|
84
|
+
summary: string;
|
|
85
|
+
emoji_icon: string | null;
|
|
86
|
+
routine: boolean | null;
|
|
87
|
+
reward_points: number | null;
|
|
88
|
+
}
|
|
89
|
+
export interface TaskBoxItemResource {
|
|
90
|
+
type: "task_box_item";
|
|
91
|
+
id: string;
|
|
92
|
+
attributes: TaskBoxItemAttributes;
|
|
93
|
+
}
|
|
94
|
+
export interface FrameAttributes {
|
|
95
|
+
[key: string]: unknown;
|
|
96
|
+
}
|
|
97
|
+
export interface FrameResource {
|
|
98
|
+
type: "frame";
|
|
99
|
+
id: string;
|
|
100
|
+
attributes: FrameAttributes;
|
|
101
|
+
}
|
|
102
|
+
export interface SourceCalendarAttributes {
|
|
103
|
+
[key: string]: unknown;
|
|
104
|
+
}
|
|
105
|
+
export interface SourceCalendarResource {
|
|
106
|
+
type: "source_calendar";
|
|
107
|
+
id: string;
|
|
108
|
+
attributes: SourceCalendarAttributes;
|
|
109
|
+
}
|
|
110
|
+
export interface CalendarEventAttributes {
|
|
111
|
+
[key: string]: unknown;
|
|
112
|
+
}
|
|
113
|
+
export interface CalendarEventResource {
|
|
114
|
+
type: "calendar_event";
|
|
115
|
+
id: string;
|
|
116
|
+
attributes: CalendarEventAttributes;
|
|
117
|
+
relationships?: {
|
|
118
|
+
categories?: {
|
|
119
|
+
data?: Array<{
|
|
120
|
+
id: string;
|
|
121
|
+
}> | null;
|
|
122
|
+
};
|
|
123
|
+
category?: {
|
|
124
|
+
data?: {
|
|
125
|
+
id: string;
|
|
126
|
+
} | null;
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
export interface DeviceAttributes {
|
|
131
|
+
[key: string]: unknown;
|
|
132
|
+
}
|
|
133
|
+
export interface DeviceResource {
|
|
134
|
+
type: "device";
|
|
135
|
+
id: string;
|
|
136
|
+
attributes: DeviceAttributes;
|
|
137
|
+
}
|
|
138
|
+
export interface RewardAttributes {
|
|
139
|
+
[key: string]: unknown;
|
|
140
|
+
}
|
|
141
|
+
export interface RewardResource {
|
|
142
|
+
type: "reward";
|
|
143
|
+
id: string;
|
|
144
|
+
attributes: RewardAttributes;
|
|
145
|
+
}
|
|
146
|
+
export interface RewardPointAttributes {
|
|
147
|
+
[key: string]: unknown;
|
|
148
|
+
}
|
|
149
|
+
export interface RewardPointResource {
|
|
150
|
+
type: "reward_point";
|
|
151
|
+
id: string;
|
|
152
|
+
attributes: RewardPointAttributes;
|
|
153
|
+
}
|
|
154
|
+
export type TaskBoxItemsResponse = JsonApiResponse<TaskBoxItemResource[]>;
|
|
155
|
+
export type ChoresResponse = JsonApiResponse<ChoreResource[], CategoryResource>;
|
|
156
|
+
export type ChoreResponse = JsonApiResponse<ChoreResource, CategoryResource>;
|
|
157
|
+
export type ListsResponse = JsonApiResponse<ListResource[]>;
|
|
158
|
+
export type ListResponse = JsonApiResponse<ListResource, ListItemResource>;
|
|
159
|
+
export type CategoriesResponse = JsonApiResponse<CategoryResource[]>;
|
|
160
|
+
export type DevicesResponse = JsonApiResponse<DeviceResource[]>;
|
|
161
|
+
export type FrameResponse = JsonApiResponse<FrameResource>;
|
|
162
|
+
export type SourceCalendarsResponse = JsonApiResponse<SourceCalendarResource[]>;
|
|
163
|
+
export type CalendarEventsResponse = JsonApiResponse<CalendarEventResource[], CategoryResource | SourceCalendarResource>;
|
|
164
|
+
export type TaskBoxItemResponse = JsonApiResponse<TaskBoxItemResource>;
|
|
165
|
+
export type RewardsResponse = JsonApiResponse<RewardResource[]>;
|
|
166
|
+
export type RewardPointsResponse = JsonApiResponse<RewardPointResource[]>;
|
|
167
|
+
export interface CreateChoreRequest {
|
|
168
|
+
data: {
|
|
169
|
+
type: "chore";
|
|
170
|
+
attributes: Partial<ChoreAttributes>;
|
|
171
|
+
relationships?: ChoreRelationships;
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
export interface CreateTaskBoxItemRequest {
|
|
175
|
+
data: {
|
|
176
|
+
type: "task_box_item";
|
|
177
|
+
attributes: Partial<TaskBoxItemAttributes>;
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
export interface CreateListRequest {
|
|
181
|
+
data: {
|
|
182
|
+
type: "list";
|
|
183
|
+
attributes: {
|
|
184
|
+
label: string;
|
|
185
|
+
kind: "shopping" | "to_do";
|
|
186
|
+
color?: string | null;
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
export interface UpdateListRequest {
|
|
191
|
+
data: {
|
|
192
|
+
type: "list";
|
|
193
|
+
attributes: Partial<{
|
|
194
|
+
label: string;
|
|
195
|
+
kind: "shopping" | "to_do";
|
|
196
|
+
color: string | null;
|
|
197
|
+
}>;
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
export interface CreateListItemRequest {
|
|
201
|
+
data: {
|
|
202
|
+
type: "list_item";
|
|
203
|
+
attributes: {
|
|
204
|
+
label: string;
|
|
205
|
+
section?: string | null;
|
|
206
|
+
};
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
export interface UpdateListItemRequest {
|
|
210
|
+
data: {
|
|
211
|
+
type: "list_item";
|
|
212
|
+
attributes: Partial<{
|
|
213
|
+
label: string;
|
|
214
|
+
status: "pending" | "completed";
|
|
215
|
+
section: string | null;
|
|
216
|
+
position: number | null;
|
|
217
|
+
}>;
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
export type ListItemResponse = JsonApiResponse<ListItemResource>;
|
|
221
|
+
export interface CreateCalendarEventRequest {
|
|
222
|
+
summary: string;
|
|
223
|
+
starts_at: string;
|
|
224
|
+
ends_at: string;
|
|
225
|
+
all_day?: boolean;
|
|
226
|
+
description?: string;
|
|
227
|
+
location?: string;
|
|
228
|
+
category_ids?: string[];
|
|
229
|
+
calendar_account_id?: string;
|
|
230
|
+
calendar_id?: string;
|
|
231
|
+
rrule?: string[] | null;
|
|
232
|
+
timezone?: string;
|
|
233
|
+
countdown_enabled?: boolean;
|
|
234
|
+
kind?: string;
|
|
235
|
+
}
|
|
236
|
+
export interface UpdateCalendarEventRequest {
|
|
237
|
+
summary?: string;
|
|
238
|
+
starts_at?: string;
|
|
239
|
+
ends_at?: string;
|
|
240
|
+
all_day?: boolean;
|
|
241
|
+
description?: string;
|
|
242
|
+
location?: string;
|
|
243
|
+
category_ids?: string[];
|
|
244
|
+
rrule?: string[] | null;
|
|
245
|
+
timezone?: string;
|
|
246
|
+
countdown_enabled?: boolean;
|
|
247
|
+
}
|
|
248
|
+
export type CalendarEventResponse = JsonApiResponse<CalendarEventResource>;
|
|
249
|
+
export interface UpdateChoreRequest {
|
|
250
|
+
data: {
|
|
251
|
+
type: "chore";
|
|
252
|
+
attributes: Partial<ChoreAttributes>;
|
|
253
|
+
relationships?: ChoreRelationships;
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
export interface CreateRewardRequest {
|
|
257
|
+
data: {
|
|
258
|
+
type: "reward";
|
|
259
|
+
attributes: {
|
|
260
|
+
name: string;
|
|
261
|
+
description?: string | null;
|
|
262
|
+
emoji_icon?: string | null;
|
|
263
|
+
point_value: number;
|
|
264
|
+
respawn_on_redemption?: boolean;
|
|
265
|
+
};
|
|
266
|
+
relationships?: {
|
|
267
|
+
categories?: {
|
|
268
|
+
data: JsonApiResourceId[];
|
|
269
|
+
};
|
|
270
|
+
};
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
export interface UpdateRewardRequest {
|
|
274
|
+
data: {
|
|
275
|
+
type: "reward";
|
|
276
|
+
attributes: Partial<{
|
|
277
|
+
name: string;
|
|
278
|
+
description: string | null;
|
|
279
|
+
emoji_icon: string | null;
|
|
280
|
+
point_value: number;
|
|
281
|
+
respawn_on_redemption: boolean;
|
|
282
|
+
}>;
|
|
283
|
+
relationships?: {
|
|
284
|
+
categories?: {
|
|
285
|
+
data: JsonApiResourceId[];
|
|
286
|
+
};
|
|
287
|
+
};
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
export type RewardResponse = JsonApiResponse<RewardResource>;
|
|
291
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `skylight-mcp auth ...` commands. These are CLI-only on purpose: credential
|
|
3
|
+
* handling is never exposed as an MCP tool.
|
|
4
|
+
*
|
|
5
|
+
* skylight-mcp auth login print the sign-in URL
|
|
6
|
+
* skylight-mcp auth complete [url] paste the final redirect URL to finish
|
|
7
|
+
* skylight-mcp auth status show whether a credential is stored
|
|
8
|
+
* skylight-mcp auth logout delete the stored credential
|
|
9
|
+
*/
|
|
10
|
+
import { type CredentialStore } from "./api/credential-store.js";
|
|
11
|
+
import { type PendingLogin, type StoredCredential } from "./api/oauth.js";
|
|
12
|
+
export interface CliDeps {
|
|
13
|
+
store: CredentialStore;
|
|
14
|
+
out: (line: string) => void;
|
|
15
|
+
prompt: (question: string) => Promise<string>;
|
|
16
|
+
savePending: (pending: PendingLogin) => Promise<void>;
|
|
17
|
+
takePending: () => Promise<PendingLogin | null>;
|
|
18
|
+
complete: (url: string, pending: PendingLogin) => Promise<StoredCredential>;
|
|
19
|
+
refresh: (credential: StoredCredential) => Promise<StoredCredential>;
|
|
20
|
+
now: () => number;
|
|
21
|
+
}
|
|
22
|
+
export declare function runAuthCommand(args: readonly string[], overrides?: Partial<CliDeps>): Promise<number>;
|
|
23
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAA8D,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC7H,OAAO,EAOL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,eAAe,CAAC;IACvB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,WAAW,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,WAAW,EAAE,MAAM,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAChD,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC5E,OAAO,EAAE,CAAC,UAAU,EAAE,gBAAgB,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACrE,GAAG,EAAE,MAAM,MAAM,CAAC;CACnB;AA6BD,wBAAsB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,GAAE,OAAO,CAAC,OAAO,CAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwE/G"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `skylight-mcp auth ...` commands. These are CLI-only on purpose: credential
|
|
3
|
+
* handling is never exposed as an MCP tool.
|
|
4
|
+
*
|
|
5
|
+
* skylight-mcp auth login print the sign-in URL
|
|
6
|
+
* skylight-mcp auth complete [url] paste the final redirect URL to finish
|
|
7
|
+
* skylight-mcp auth status show whether a credential is stored
|
|
8
|
+
* skylight-mcp auth logout delete the stored credential
|
|
9
|
+
*/
|
|
10
|
+
import { createInterface } from "node:readline/promises";
|
|
11
|
+
import { defaultCredentialStore, savePendingLogin, takePendingLogin } from "./api/credential-store.js";
|
|
12
|
+
import { OAuthError, PENDING_LOGIN_TTL_MS, beginBrowserLogin, completeBrowserLogin, isExpired, refreshCredential, } from "./api/oauth.js";
|
|
13
|
+
function defaultDeps() {
|
|
14
|
+
return {
|
|
15
|
+
store: defaultCredentialStore(),
|
|
16
|
+
out: (line) => console.log(line),
|
|
17
|
+
prompt: async (question) => {
|
|
18
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
19
|
+
try {
|
|
20
|
+
return await rl.question(question);
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
rl.close();
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
savePending: (pending) => savePendingLogin(pending),
|
|
27
|
+
takePending: () => takePendingLogin(),
|
|
28
|
+
complete: (url, pending) => completeBrowserLogin(url, pending),
|
|
29
|
+
refresh: (credential) => refreshCredential(credential),
|
|
30
|
+
now: () => Date.now(),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const USAGE = `Usage: skylight-mcp auth <command>
|
|
34
|
+
|
|
35
|
+
login Print a Skylight sign-in URL. Open it in your browser.
|
|
36
|
+
complete [url] After signing in, paste the final URL (https://ourskylight.com/welcome?...).
|
|
37
|
+
status Show whether you are signed in.
|
|
38
|
+
logout Remove the stored credential.`;
|
|
39
|
+
export async function runAuthCommand(args, overrides = {}) {
|
|
40
|
+
const deps = { ...defaultDeps(), ...overrides };
|
|
41
|
+
const [command, ...rest] = args;
|
|
42
|
+
try {
|
|
43
|
+
switch (command) {
|
|
44
|
+
case "login": {
|
|
45
|
+
const { loginUrl, pending } = beginBrowserLogin(deps.now());
|
|
46
|
+
await deps.savePending(pending);
|
|
47
|
+
deps.out("1. Open this URL in your browser and sign in to Skylight\n (Windows Terminal: hold Ctrl and click it; otherwise copy it into your browser):\n");
|
|
48
|
+
deps.out(` ${loginUrl}\n`);
|
|
49
|
+
deps.out("2. Skylight bounces the browser through https://ourskylight.com/welcome?code=... too fast");
|
|
50
|
+
deps.out(" to copy. Get it from browser history: Cmd-Y (Mac) / Ctrl-H (PC), search \"welcome?code\",");
|
|
51
|
+
deps.out(" right-click the Skylight result dated today (top of the list; older ones are earlier");
|
|
52
|
+
deps.out(" sign-ins and will not work), Copy link address.\n");
|
|
53
|
+
deps.out("3. Run the same command you just ran, with `complete` instead of `login`,");
|
|
54
|
+
deps.out(` and paste the URL at the prompt. This login expires in ${PENDING_LOGIN_TTL_MS / 60_000} minutes.`);
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
case "complete": {
|
|
58
|
+
const url = rest[0] ?? (await deps.prompt("Paste the full redirect URL: "));
|
|
59
|
+
if (!url.trim()) {
|
|
60
|
+
deps.out("No URL provided.");
|
|
61
|
+
return 1;
|
|
62
|
+
}
|
|
63
|
+
const pending = await deps.takePending();
|
|
64
|
+
if (!pending) {
|
|
65
|
+
deps.out("No login in progress. Run `skylight-mcp auth login` first.");
|
|
66
|
+
return 1;
|
|
67
|
+
}
|
|
68
|
+
const credential = await deps.complete(url, pending);
|
|
69
|
+
await deps.store.write(credential);
|
|
70
|
+
deps.out(`Signed in. Credential saved (${deps.store.name}).`);
|
|
71
|
+
deps.out("Restart your MCP client to pick it up.");
|
|
72
|
+
return 0;
|
|
73
|
+
}
|
|
74
|
+
case "status": {
|
|
75
|
+
const credential = await deps.store.read();
|
|
76
|
+
if (!credential) {
|
|
77
|
+
deps.out("Not signed in. Run `skylight-mcp auth login`.");
|
|
78
|
+
return 1;
|
|
79
|
+
}
|
|
80
|
+
const expiry = new Date(credential.expiresAt).toISOString();
|
|
81
|
+
deps.out(`Signed in. Storage: ${deps.store.name}.`);
|
|
82
|
+
deps.out(isExpired(credential, deps.now())
|
|
83
|
+
? `Access token expired at ${expiry}; it will refresh on next use.`
|
|
84
|
+
: `Access token valid until ${expiry}.`);
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
87
|
+
case "logout": {
|
|
88
|
+
const removed = await deps.store.delete();
|
|
89
|
+
deps.out(removed ? "Signed out. Stored credential removed." : "Nothing to remove.");
|
|
90
|
+
deps.out("Note: this does not revoke the session on Skylight's side.");
|
|
91
|
+
return 0;
|
|
92
|
+
}
|
|
93
|
+
default:
|
|
94
|
+
deps.out(USAGE);
|
|
95
|
+
return command === undefined || command === "help" || command === "--help" ? 0 : 1;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
if (error instanceof OAuthError || error instanceof Error) {
|
|
100
|
+
deps.out(`Error: ${error.message}`);
|
|
101
|
+
return 1;
|
|
102
|
+
}
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=cli.js.map
|