@davidwoods/skylight-mcp 0.0.0-stage → 1.7.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.
Files changed (168) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +583 -2
  3. package/THIRD_PARTY_NOTICES.md +38 -0
  4. package/dist/api/auth.d.ts +34 -0
  5. package/dist/api/auth.d.ts.map +1 -0
  6. package/dist/api/auth.js +328 -0
  7. package/dist/api/auth.js.map +1 -0
  8. package/dist/api/client.d.ts +103 -0
  9. package/dist/api/client.d.ts.map +1 -0
  10. package/dist/api/client.js +324 -0
  11. package/dist/api/client.js.map +1 -0
  12. package/dist/api/constants.d.ts +4 -0
  13. package/dist/api/constants.d.ts.map +1 -0
  14. package/dist/api/constants.js +4 -0
  15. package/dist/api/constants.js.map +1 -0
  16. package/dist/api/credential-store.d.ts +38 -0
  17. package/dist/api/credential-store.d.ts.map +1 -0
  18. package/dist/api/credential-store.js +273 -0
  19. package/dist/api/credential-store.js.map +1 -0
  20. package/dist/api/credential-types.d.ts +15 -0
  21. package/dist/api/credential-types.d.ts.map +1 -0
  22. package/dist/api/credential-types.js +11 -0
  23. package/dist/api/credential-types.js.map +1 -0
  24. package/dist/api/endpoints/calendar.d.ts +36 -0
  25. package/dist/api/endpoints/calendar.d.ts.map +1 -0
  26. package/dist/api/endpoints/calendar.js +74 -0
  27. package/dist/api/endpoints/calendar.js.map +1 -0
  28. package/dist/api/endpoints/categories.d.ts +32 -0
  29. package/dist/api/endpoints/categories.d.ts.map +1 -0
  30. package/dist/api/endpoints/categories.js +77 -0
  31. package/dist/api/endpoints/categories.js.map +1 -0
  32. package/dist/api/endpoints/chores.d.ts +50 -0
  33. package/dist/api/endpoints/chores.d.ts.map +1 -0
  34. package/dist/api/endpoints/chores.js +106 -0
  35. package/dist/api/endpoints/chores.js.map +1 -0
  36. package/dist/api/endpoints/devices.d.ts +6 -0
  37. package/dist/api/endpoints/devices.d.ts.map +1 -0
  38. package/dist/api/endpoints/devices.js +10 -0
  39. package/dist/api/endpoints/devices.js.map +1 -0
  40. package/dist/api/endpoints/frames.d.ts +6 -0
  41. package/dist/api/endpoints/frames.d.ts.map +1 -0
  42. package/dist/api/endpoints/frames.js +10 -0
  43. package/dist/api/endpoints/frames.js.map +1 -0
  44. package/dist/api/endpoints/lists.d.ts +55 -0
  45. package/dist/api/endpoints/lists.d.ts.map +1 -0
  46. package/dist/api/endpoints/lists.js +125 -0
  47. package/dist/api/endpoints/lists.js.map +1 -0
  48. package/dist/api/endpoints/meals.d.ts +154 -0
  49. package/dist/api/endpoints/meals.d.ts.map +1 -0
  50. package/dist/api/endpoints/meals.js +194 -0
  51. package/dist/api/endpoints/meals.js.map +1 -0
  52. package/dist/api/endpoints/messages.d.ts +98 -0
  53. package/dist/api/endpoints/messages.d.ts.map +1 -0
  54. package/dist/api/endpoints/messages.js +116 -0
  55. package/dist/api/endpoints/messages.js.map +1 -0
  56. package/dist/api/endpoints/misc.d.ts +27 -0
  57. package/dist/api/endpoints/misc.d.ts.map +1 -0
  58. package/dist/api/endpoints/misc.js +19 -0
  59. package/dist/api/endpoints/misc.js.map +1 -0
  60. package/dist/api/endpoints/photos.d.ts +13 -0
  61. package/dist/api/endpoints/photos.d.ts.map +1 -0
  62. package/dist/api/endpoints/photos.js +10 -0
  63. package/dist/api/endpoints/photos.js.map +1 -0
  64. package/dist/api/endpoints/rewards.d.ts +49 -0
  65. package/dist/api/endpoints/rewards.d.ts.map +1 -0
  66. package/dist/api/endpoints/rewards.js +106 -0
  67. package/dist/api/endpoints/rewards.js.map +1 -0
  68. package/dist/api/endpoints/shape.d.ts +11 -0
  69. package/dist/api/endpoints/shape.d.ts.map +1 -0
  70. package/dist/api/endpoints/shape.js +34 -0
  71. package/dist/api/endpoints/shape.js.map +1 -0
  72. package/dist/api/endpoints/taskbox.d.ts +13 -0
  73. package/dist/api/endpoints/taskbox.d.ts.map +1 -0
  74. package/dist/api/endpoints/taskbox.js +22 -0
  75. package/dist/api/endpoints/taskbox.js.map +1 -0
  76. package/dist/api/oauth.d.ts +62 -0
  77. package/dist/api/oauth.d.ts.map +1 -0
  78. package/dist/api/oauth.js +206 -0
  79. package/dist/api/oauth.js.map +1 -0
  80. package/dist/api/types.d.ts +277 -0
  81. package/dist/api/types.d.ts.map +1 -0
  82. package/dist/api/types.js +5 -0
  83. package/dist/api/types.js.map +1 -0
  84. package/dist/cli.d.ts +23 -0
  85. package/dist/cli.d.ts.map +1 -0
  86. package/dist/cli.js +105 -0
  87. package/dist/cli.js.map +1 -0
  88. package/dist/config.d.ts +27 -0
  89. package/dist/config.d.ts.map +1 -0
  90. package/dist/config.js +78 -0
  91. package/dist/config.js.map +1 -0
  92. package/dist/context.d.ts +17 -0
  93. package/dist/context.d.ts.map +1 -0
  94. package/dist/context.js +17 -0
  95. package/dist/context.js.map +1 -0
  96. package/dist/doctor.d.ts +19 -0
  97. package/dist/doctor.d.ts.map +1 -0
  98. package/dist/doctor.js +109 -0
  99. package/dist/doctor.js.map +1 -0
  100. package/dist/index.d.ts +3 -0
  101. package/dist/index.d.ts.map +1 -0
  102. package/dist/index.js +24 -0
  103. package/dist/index.js.map +1 -0
  104. package/dist/server.d.ts +7 -0
  105. package/dist/server.d.ts.map +1 -0
  106. package/dist/server.js +29 -0
  107. package/dist/server.js.map +1 -0
  108. package/dist/tools/calendar.d.ts +3 -0
  109. package/dist/tools/calendar.d.ts.map +1 -0
  110. package/dist/tools/calendar.js +298 -0
  111. package/dist/tools/calendar.js.map +1 -0
  112. package/dist/tools/chores.d.ts +3 -0
  113. package/dist/tools/chores.d.ts.map +1 -0
  114. package/dist/tools/chores.js +349 -0
  115. package/dist/tools/chores.js.map +1 -0
  116. package/dist/tools/family.d.ts +3 -0
  117. package/dist/tools/family.d.ts.map +1 -0
  118. package/dist/tools/family.js +182 -0
  119. package/dist/tools/family.js.map +1 -0
  120. package/dist/tools/lists.d.ts +3 -0
  121. package/dist/tools/lists.d.ts.map +1 -0
  122. package/dist/tools/lists.js +481 -0
  123. package/dist/tools/lists.js.map +1 -0
  124. package/dist/tools/meals.d.ts +3 -0
  125. package/dist/tools/meals.d.ts.map +1 -0
  126. package/dist/tools/meals.js +491 -0
  127. package/dist/tools/meals.js.map +1 -0
  128. package/dist/tools/messages.d.ts +3 -0
  129. package/dist/tools/messages.d.ts.map +1 -0
  130. package/dist/tools/messages.js +195 -0
  131. package/dist/tools/messages.js.map +1 -0
  132. package/dist/tools/misc.d.ts +3 -0
  133. package/dist/tools/misc.d.ts.map +1 -0
  134. package/dist/tools/misc.js +102 -0
  135. package/dist/tools/misc.js.map +1 -0
  136. package/dist/tools/photos.d.ts +3 -0
  137. package/dist/tools/photos.d.ts.map +1 -0
  138. package/dist/tools/photos.js +42 -0
  139. package/dist/tools/photos.js.map +1 -0
  140. package/dist/tools/planning.d.ts +15 -0
  141. package/dist/tools/planning.d.ts.map +1 -0
  142. package/dist/tools/planning.js +303 -0
  143. package/dist/tools/planning.js.map +1 -0
  144. package/dist/tools/registry.d.ts +39 -0
  145. package/dist/tools/registry.d.ts.map +1 -0
  146. package/dist/tools/registry.js +142 -0
  147. package/dist/tools/registry.js.map +1 -0
  148. package/dist/tools/rewards.d.ts +3 -0
  149. package/dist/tools/rewards.d.ts.map +1 -0
  150. package/dist/tools/rewards.js +339 -0
  151. package/dist/tools/rewards.js.map +1 -0
  152. package/dist/tools/tasks.d.ts +3 -0
  153. package/dist/tools/tasks.d.ts.map +1 -0
  154. package/dist/tools/tasks.js +68 -0
  155. package/dist/tools/tasks.js.map +1 -0
  156. package/dist/utils/dates.d.ts +26 -0
  157. package/dist/utils/dates.d.ts.map +1 -0
  158. package/dist/utils/dates.js +109 -0
  159. package/dist/utils/dates.js.map +1 -0
  160. package/dist/utils/errors.d.ts +45 -0
  161. package/dist/utils/errors.d.ts.map +1 -0
  162. package/dist/utils/errors.js +102 -0
  163. package/dist/utils/errors.js.map +1 -0
  164. package/dist/utils/schedule.d.ts +86 -0
  165. package/dist/utils/schedule.d.ts.map +1 -0
  166. package/dist/utils/schedule.js +189 -0
  167. package/dist/utils/schedule.js.map +1 -0
  168. package/package.json +76 -4
@@ -0,0 +1,125 @@
1
+ import { getClient } from "../client.js";
2
+ /**
3
+ * Get all lists
4
+ */
5
+ export async function getLists() {
6
+ const client = getClient();
7
+ const response = await client.get("/api/frames/{frameId}/lists");
8
+ return response.data;
9
+ }
10
+ /**
11
+ * Get a specific list with its items
12
+ */
13
+ export async function getListWithItems(listId) {
14
+ const client = getClient();
15
+ const response = await client.get(`/api/frames/{frameId}/lists/${listId}`);
16
+ return {
17
+ list: response.data,
18
+ items: response.included ?? [],
19
+ sections: response.meta?.sections,
20
+ };
21
+ }
22
+ /**
23
+ * Find a list by name (case-insensitive)
24
+ */
25
+ export async function findListByName(name) {
26
+ const lists = await getLists();
27
+ const lowerName = name.toLowerCase();
28
+ return lists.find((list) => list.attributes.label.toLowerCase().includes(lowerName));
29
+ }
30
+ /**
31
+ * Find a list by type (shopping or to_do)
32
+ */
33
+ export async function findListByType(kind, preferDefault = true) {
34
+ const lists = await getLists();
35
+ const filtered = lists.filter((list) => list.attributes.kind === kind);
36
+ if (preferDefault && kind === "shopping") {
37
+ const defaultList = filtered.find((list) => list.attributes.default_grocery_list);
38
+ if (defaultList)
39
+ return defaultList;
40
+ }
41
+ return filtered[0];
42
+ }
43
+ /**
44
+ * Create a new list
45
+ */
46
+ export async function createList(label, kind, color) {
47
+ const client = getClient();
48
+ const request = {
49
+ data: {
50
+ type: "list",
51
+ attributes: {
52
+ label,
53
+ kind,
54
+ color: color ?? null,
55
+ },
56
+ },
57
+ };
58
+ const response = await client.post("/api/frames/{frameId}/lists", request);
59
+ return response.data;
60
+ }
61
+ /**
62
+ * Update an existing list
63
+ */
64
+ export async function updateList(listId, updates) {
65
+ const client = getClient();
66
+ const request = {
67
+ data: {
68
+ type: "list",
69
+ attributes: updates,
70
+ },
71
+ };
72
+ const response = await client.request(`/api/frames/{frameId}/lists/${listId}`, {
73
+ method: "PUT",
74
+ body: request,
75
+ });
76
+ return response.data;
77
+ }
78
+ /**
79
+ * Delete a list
80
+ */
81
+ export async function deleteList(listId) {
82
+ const client = getClient();
83
+ await client.request(`/api/frames/{frameId}/lists/${listId}`, { method: "DELETE" });
84
+ }
85
+ /**
86
+ * Create a new list item
87
+ */
88
+ export async function createListItem(listId, label, section) {
89
+ const client = getClient();
90
+ const request = {
91
+ data: {
92
+ type: "list_item",
93
+ attributes: {
94
+ label,
95
+ section: section ?? null,
96
+ },
97
+ },
98
+ };
99
+ const response = await client.post(`/api/frames/{frameId}/lists/${listId}/list_items`, request);
100
+ return response.data;
101
+ }
102
+ /**
103
+ * Update a list item
104
+ */
105
+ export async function updateListItem(listId, itemId, updates) {
106
+ const client = getClient();
107
+ const request = {
108
+ data: {
109
+ type: "list_item",
110
+ attributes: updates,
111
+ },
112
+ };
113
+ const response = await client.request(`/api/frames/{frameId}/lists/${listId}/list_items/${itemId}`, { method: "PUT", body: request });
114
+ return response.data;
115
+ }
116
+ /**
117
+ * Delete a list item
118
+ */
119
+ export async function deleteListItem(listId, itemId) {
120
+ const client = getClient();
121
+ await client.request(`/api/frames/{frameId}/lists/${listId}/list_items/${itemId}`, {
122
+ method: "DELETE",
123
+ });
124
+ }
125
+ //# sourceMappingURL=lists.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lists.js","sourceRoot":"","sources":["../../../src/api/endpoints/lists.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,154 @@
1
+ export interface MealCategoryResource {
2
+ type: "meal_category";
3
+ id: string;
4
+ attributes: {
5
+ /** Skylight calls the display name `label`; older code assumed `name`. */
6
+ label?: string;
7
+ name?: string;
8
+ color?: string;
9
+ position?: number;
10
+ [key: string]: unknown;
11
+ };
12
+ }
13
+ /** Display name of a meal category, whichever field the API used. */
14
+ export declare function mealCategoryName(category: MealCategoryResource): string;
15
+ export interface MealRecipeResource {
16
+ type: "meal_recipe";
17
+ id: string;
18
+ attributes: {
19
+ summary?: string;
20
+ description?: string | null;
21
+ [key: string]: unknown;
22
+ };
23
+ relationships?: {
24
+ meal_category?: {
25
+ data: {
26
+ type: string;
27
+ id: string;
28
+ } | null;
29
+ };
30
+ };
31
+ }
32
+ export interface MealSittingResource {
33
+ type: "meal_sitting";
34
+ id: string;
35
+ attributes: {
36
+ /** Free-text meal name, e.g. "Thai green curry". May be empty when a recipe is linked. */
37
+ summary?: string | null;
38
+ /** Dates (YYYY-MM-DD) this sitting appears on. */
39
+ instances?: string[];
40
+ date?: string;
41
+ meal_time?: string;
42
+ [key: string]: unknown;
43
+ };
44
+ relationships?: {
45
+ meal_recipe?: {
46
+ data: {
47
+ type: string;
48
+ id: string;
49
+ } | null;
50
+ };
51
+ meal_category?: {
52
+ data: {
53
+ type: string;
54
+ id: string;
55
+ } | null;
56
+ };
57
+ };
58
+ }
59
+ /**
60
+ * Get meal categories (Breakfast, Lunch, Dinner, etc.)
61
+ */
62
+ export declare function getMealCategories(): Promise<MealCategoryResource[]>;
63
+ export interface GetRecipesOptions {
64
+ include?: string;
65
+ }
66
+ /**
67
+ * Get all recipes
68
+ */
69
+ export declare function getRecipes(options?: GetRecipesOptions): Promise<MealRecipeResource[]>;
70
+ /**
71
+ * Get a specific recipe
72
+ */
73
+ export declare function getRecipe(recipeId: string): Promise<MealRecipeResource>;
74
+ export interface CreateRecipeOptions {
75
+ summary: string;
76
+ description?: string;
77
+ mealCategoryId?: string;
78
+ }
79
+ /**
80
+ * Create a new recipe
81
+ */
82
+ export declare function createRecipe(options: CreateRecipeOptions): Promise<MealRecipeResource>;
83
+ export interface UpdateRecipeOptions {
84
+ summary?: string;
85
+ description?: string | null;
86
+ mealCategoryId?: string | null;
87
+ }
88
+ /**
89
+ * Update a recipe
90
+ */
91
+ export declare function updateRecipe(recipeId: string, options: UpdateRecipeOptions): Promise<MealRecipeResource>;
92
+ /**
93
+ * Delete a recipe
94
+ */
95
+ export declare function deleteRecipe(recipeId: string): Promise<void>;
96
+ /**
97
+ * Add recipe ingredients to grocery list
98
+ */
99
+ export declare function addRecipeToGroceryList(recipeId: string): Promise<void>;
100
+ export interface GetMealSittingsOptions {
101
+ dateMin?: string;
102
+ dateMax?: string;
103
+ }
104
+ /**
105
+ * Get meal sittings (scheduled meals)
106
+ */
107
+ export declare function getMealSittings(options?: GetMealSittingsOptions): Promise<MealSittingResource[]>;
108
+ export interface CreateMealSittingOptions {
109
+ date: string;
110
+ mealCategoryId: string;
111
+ /** Free-text meal name. Either this or recipeId should be given. */
112
+ summary?: string;
113
+ recipeId?: string;
114
+ }
115
+ /**
116
+ * Create a meal sitting (schedule a meal)
117
+ */
118
+ export declare function createMealSitting(options: CreateMealSittingOptions): Promise<MealSittingResource>;
119
+ /**
120
+ * Editing and deleting a sitting use the API version the web app sends; the
121
+ * captures behind them were made with it. Create and list keep the repo default.
122
+ */
123
+ export declare const MEAL_EDIT_API_VERSION = "2026-10-15";
124
+ /** Sitting ids are numeric. Validate before one ever reaches a URL path. */
125
+ export declare function assertSittingId(id: string): string;
126
+ /** A real calendar date as YYYY-MM-DD, validated before it reaches a URL path. */
127
+ export declare function assertIsoDate(date: string): string;
128
+ /**
129
+ * Find the sitting that has an occurrence on `date`. Read under the edit API
130
+ * version so recurring/rrule fields are present for the one-off guard.
131
+ */
132
+ export declare function findMealSitting(sittingId: string, date: string): Promise<MealSittingResource | null>;
133
+ export interface UpdateMealSittingOptions {
134
+ existing: MealSittingResource;
135
+ /** The occurrence being edited (its current date). */
136
+ date: string;
137
+ /** Move the meal to this date. */
138
+ newDate?: string;
139
+ summary?: string;
140
+ note?: string;
141
+ mealCategoryId?: string;
142
+ }
143
+ /**
144
+ * Edit a one-off sitting the way the web app does: PATCH the whole form to
145
+ * /meals/sittings/{id}/instances/{currentDate}. Fields not being changed are
146
+ * sent back as they are, because the API takes the full form.
147
+ */
148
+ export declare function updateMealSitting(options: UpdateMealSittingOptions): Promise<void>;
149
+ /**
150
+ * Delete a one-off sitting: DELETE /meals/sittings/{id}/instances/{date}, no
151
+ * body. Returns whether Skylight confirmed the removal in meta.deleted_sitting_ids.
152
+ */
153
+ export declare function deleteMealSitting(existing: MealSittingResource, date: string): Promise<boolean>;
154
+ //# sourceMappingURL=meals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meals.d.ts","sourceRoot":"","sources":["../../../src/api/endpoints/meals.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,194 @@
1
+ import { getClient } from "../client.js";
2
+ import { addDays } from "../../utils/schedule.js";
3
+ /** Display name of a meal category, whichever field the API used. */
4
+ export function mealCategoryName(category) {
5
+ return category.attributes.label ?? category.attributes.name ?? "Unnamed";
6
+ }
7
+ /**
8
+ * Get meal categories (Breakfast, Lunch, Dinner, etc.)
9
+ */
10
+ export async function getMealCategories() {
11
+ const client = getClient();
12
+ const response = await client.get("/api/frames/{frameId}/meals/categories");
13
+ return response.data;
14
+ }
15
+ /**
16
+ * Get all recipes
17
+ */
18
+ export async function getRecipes(options = {}) {
19
+ const client = getClient();
20
+ const response = await client.get("/api/frames/{frameId}/meals/recipes", { include: options.include ?? "meal_category" });
21
+ return response.data;
22
+ }
23
+ /**
24
+ * Get a specific recipe
25
+ */
26
+ export async function getRecipe(recipeId) {
27
+ const client = getClient();
28
+ const response = await client.get(`/api/frames/{frameId}/meals/recipes/${recipeId}`, { include: "meal_category" });
29
+ return response.data;
30
+ }
31
+ /**
32
+ * Create a new recipe
33
+ */
34
+ export async function createRecipe(options) {
35
+ const client = getClient();
36
+ const body = {
37
+ summary: options.summary,
38
+ description: options.description ?? null,
39
+ };
40
+ if (options.mealCategoryId) {
41
+ body.meal_category_id = options.mealCategoryId;
42
+ }
43
+ const response = await client.post("/api/frames/{frameId}/meals/recipes", body);
44
+ return response.data;
45
+ }
46
+ /**
47
+ * Update a recipe
48
+ */
49
+ export async function updateRecipe(recipeId, options) {
50
+ const client = getClient();
51
+ const body = {};
52
+ if (options.summary !== undefined)
53
+ body.summary = options.summary;
54
+ if (options.description !== undefined)
55
+ body.description = options.description;
56
+ if (options.mealCategoryId !== undefined)
57
+ body.meal_category_id = options.mealCategoryId;
58
+ const response = await client.request(`/api/frames/{frameId}/meals/recipes/${recipeId}`, { method: "PATCH", body });
59
+ return response.data;
60
+ }
61
+ /**
62
+ * Delete a recipe
63
+ */
64
+ export async function deleteRecipe(recipeId) {
65
+ const client = getClient();
66
+ await client.request(`/api/frames/{frameId}/meals/recipes/${recipeId}`, {
67
+ method: "DELETE",
68
+ });
69
+ }
70
+ /**
71
+ * Add recipe ingredients to grocery list
72
+ */
73
+ export async function addRecipeToGroceryList(recipeId) {
74
+ const client = getClient();
75
+ await client.post(`/api/frames/{frameId}/meals/recipes/${recipeId}/add_to_grocery_list`, {});
76
+ }
77
+ /**
78
+ * Get meal sittings (scheduled meals)
79
+ */
80
+ export async function getMealSittings(options = {}) {
81
+ const client = getClient();
82
+ const params = {};
83
+ if (options.dateMin)
84
+ params.date_min = options.dateMin;
85
+ if (options.dateMax)
86
+ params.date_max = options.dateMax;
87
+ const response = await client.get("/api/frames/{frameId}/meals/sittings", params);
88
+ return response.data;
89
+ }
90
+ /**
91
+ * Create a meal sitting (schedule a meal)
92
+ */
93
+ export async function createMealSitting(options) {
94
+ const client = getClient();
95
+ const body = {
96
+ date: options.date,
97
+ meal_category_id: options.mealCategoryId,
98
+ };
99
+ if (options.summary) {
100
+ body.summary = options.summary;
101
+ }
102
+ if (options.recipeId) {
103
+ body.meal_recipe_id = options.recipeId;
104
+ }
105
+ // The API answers a create with a list envelope (one element), unlike GET by id.
106
+ const response = await client.post("/api/frames/{frameId}/meals/sittings", body);
107
+ const data = Array.isArray(response.data) ? response.data[0] : response.data;
108
+ if (!data)
109
+ throw new Error("Skylight returned an empty response when creating the meal sitting");
110
+ return data;
111
+ }
112
+ /**
113
+ * Editing and deleting a sitting use the API version the web app sends; the
114
+ * captures behind them were made with it. Create and list keep the repo default.
115
+ */
116
+ export const MEAL_EDIT_API_VERSION = "2026-10-15";
117
+ /** Sitting ids are numeric. Validate before one ever reaches a URL path. */
118
+ export function assertSittingId(id) {
119
+ if (!/^\d{1,12}$/.test(id))
120
+ throw new Error("Sitting ID must be numeric (see get_meal_sittings).");
121
+ return id;
122
+ }
123
+ /** A real calendar date as YYYY-MM-DD, validated before it reaches a URL path. */
124
+ export function assertIsoDate(date) {
125
+ const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(date);
126
+ const valid = m && new Date(Date.UTC(+m[1], +m[2] - 1, +m[3])).toISOString().slice(0, 10) === date;
127
+ if (!valid)
128
+ throw new Error("Date must be a real calendar date in YYYY-MM-DD form.");
129
+ return date;
130
+ }
131
+ function instanceQuery(date) {
132
+ return {
133
+ date_min: date,
134
+ date_max: addDays(date, 1),
135
+ include: "meal_category,meal_recipe,profiles",
136
+ };
137
+ }
138
+ /**
139
+ * Find the sitting that has an occurrence on `date`. Read under the edit API
140
+ * version so recurring/rrule fields are present for the one-off guard.
141
+ */
142
+ export async function findMealSitting(sittingId, date) {
143
+ assertSittingId(sittingId);
144
+ assertIsoDate(date);
145
+ const response = await getClient().request("/api/frames/{frameId}/meals/sittings", {
146
+ method: "GET",
147
+ params: instanceQuery(date),
148
+ apiVersion: MEAL_EDIT_API_VERSION,
149
+ });
150
+ return (response.data ?? []).find((s) => s.id === sittingId && s.attributes.instances?.includes(date)) ?? null;
151
+ }
152
+ /** Only one-off sittings were captured. Repeating ones are edited in the app. */
153
+ function assertOneOff(sitting) {
154
+ const a = sitting.attributes;
155
+ if (a.recurring === true || a.rrule) {
156
+ throw new Error("This meal repeats. Editing or deleting one occurrence of a repeating meal is not supported here; use the Skylight app.");
157
+ }
158
+ }
159
+ /**
160
+ * Edit a one-off sitting the way the web app does: PATCH the whole form to
161
+ * /meals/sittings/{id}/instances/{currentDate}. Fields not being changed are
162
+ * sent back as they are, because the API takes the full form.
163
+ */
164
+ export async function updateMealSitting(options) {
165
+ const { existing } = options;
166
+ assertOneOff(existing);
167
+ const date = assertIsoDate(options.date);
168
+ const target = assertIsoDate(options.newDate ?? date);
169
+ const a = existing.attributes;
170
+ const payload = {
171
+ date: target,
172
+ note: options.note ?? (typeof a.note === "string" ? a.note : ""),
173
+ rrule: null,
174
+ summary: options.summary ?? a.summary ?? "",
175
+ description: typeof a.description === "string" ? a.description : "",
176
+ meal_category_id: options.mealCategoryId ?? existing.relationships?.meal_category?.data?.id ?? null,
177
+ meal_recipe_id: existing.relationships?.meal_recipe?.data?.id ?? null,
178
+ profile_ids: (existing.relationships?.profiles?.data ?? []).map((p) => p.id),
179
+ saveToRecipeBox: false,
180
+ };
181
+ await getClient().request(`/api/frames/{frameId}/meals/sittings/${assertSittingId(existing.id)}/instances/${date}`, { method: "PATCH", body: payload, params: instanceQuery(date), apiVersion: MEAL_EDIT_API_VERSION });
182
+ }
183
+ /**
184
+ * Delete a one-off sitting: DELETE /meals/sittings/{id}/instances/{date}, no
185
+ * body. Returns whether Skylight confirmed the removal in meta.deleted_sitting_ids.
186
+ */
187
+ export async function deleteMealSitting(existing, date) {
188
+ assertOneOff(existing);
189
+ assertIsoDate(date);
190
+ const id = assertSittingId(existing.id);
191
+ const response = await getClient().request(`/api/frames/{frameId}/meals/sittings/${id}/instances/${date}`, { method: "DELETE", params: instanceQuery(date), apiVersion: MEAL_EDIT_API_VERSION });
192
+ return (response?.meta?.deleted_sitting_ids ?? []).map(String).includes(id);
193
+ }
194
+ //# sourceMappingURL=meals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meals.js","sourceRoot":"","sources":["../../../src/api/endpoints/meals.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Messages need the API version the web app sends. Under the repo-wide older
3
+ * version the responses omit all_profiles / all_devices / voice_kind, which
4
+ * made get_messages misreport recipients and the edit guard refuse everything.
5
+ */
6
+ export declare const NUDGES_API_VERSION = "2026-10-15";
7
+ /**
8
+ * Skylight calls frame messages "nudges". Shape taken from the web app's
9
+ * list call: GET /api/frames/{frameId}/nudges?after=<ISO>&before=<ISO>.
10
+ */
11
+ export interface NudgeResource {
12
+ type: "nudge";
13
+ id: string;
14
+ attributes: {
15
+ body?: string | null;
16
+ /** ISO instant the message is (or was) delivered to the frame. */
17
+ deliver_at?: string;
18
+ rrule?: string | null;
19
+ recurring_until?: string | null;
20
+ voice_kind?: string | null;
21
+ recurring?: boolean;
22
+ all_profiles?: boolean;
23
+ all_devices?: boolean;
24
+ /** Short-lived presigned storage URL. Never surfaced by this server. */
25
+ audio_url?: string | null;
26
+ [key: string]: unknown;
27
+ };
28
+ relationships?: {
29
+ /** Recipient profiles. */
30
+ categories?: {
31
+ data: Array<{
32
+ type: string;
33
+ id: string;
34
+ }>;
35
+ };
36
+ /** The optional "From" profile. */
37
+ sender_category?: {
38
+ data: {
39
+ type: string;
40
+ id: string;
41
+ } | null;
42
+ };
43
+ devices?: {
44
+ data: Array<{
45
+ type: string;
46
+ id: string;
47
+ }>;
48
+ };
49
+ };
50
+ }
51
+ /** ISO-8601 with the zone's numeric offset, e.g. 2026-10-01T00:00:00.000-07:00. */
52
+ export declare function isoWithOffset(epochMs: number, timeZone: string): string;
53
+ /** Messages delivered between two local dates, inclusive. */
54
+ export declare function getNudges(startDate: string, endDate: string, timeZone: string): Promise<NudgeResource[]>;
55
+ export interface CreateNudgeOptions {
56
+ body: string;
57
+ /** Read aloud on the frame when delivered. Off by default. */
58
+ readAloud?: boolean;
59
+ /** Profile (category) id shown as the sender. Omitted when not given. */
60
+ senderCategoryId?: string;
61
+ /** Send only to these profile (category) ids. Omitted means everyone. */
62
+ recipientCategoryIds?: string[];
63
+ timeZone: string;
64
+ }
65
+ /**
66
+ * Send a message to every profile and every device, delivered now.
67
+ * Payload shape is from the web app's "Send Now" call. Targeting specific
68
+ * profiles is inferred from how Skylight stores a message sent to one profile
69
+ * (all_profiles false plus that profile in categories) and from another open
70
+ * source client that sends category_ids; the POST itself has not been captured.
71
+ * Targeting devices and scheduling are not offered.
72
+ */
73
+ export declare function createNudge(options: CreateNudgeOptions): Promise<NudgeResource | null>;
74
+ /** Message ids are numeric. Validate before one ever reaches a URL path. */
75
+ export declare function assertNudgeId(id: string): string;
76
+ /** Find one message by id within +/- 31 days of today. */
77
+ export declare function findNudge(id: string, timeZone: string): Promise<NudgeResource | null>;
78
+ export interface UpdateNudgeOptions {
79
+ existing: NudgeResource;
80
+ body: string;
81
+ /** Replace the sender profile id. Keeps the current sender when undefined. */
82
+ senderCategoryId?: string;
83
+ timeZone: string;
84
+ }
85
+ /**
86
+ * Edit a message the way the web app does: PATCH with the whole form.
87
+ * Only messages sent to everyone on all devices and not repeating are
88
+ * supported, because those are the only shapes captured.
89
+ */
90
+ export declare function updateNudge(options: UpdateNudgeOptions): Promise<void>;
91
+ /**
92
+ * Delete a message: DELETE /nudges/{id}. The Skylight web app offers no delete
93
+ * button, so this call is taken from two other open-source clients and has not
94
+ * been confirmed against this account's API version until a live run says so.
95
+ * Returns the HTTP outcome only; callers must read back to confirm removal.
96
+ */
97
+ export declare function deleteNudge(existing: NudgeResource): Promise<void>;
98
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/api/endpoints/messages.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,eAAe,CAAC;AAE/C;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE;QACV,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,kEAAkE;QAClE,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAChC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,wEAAwE;QACxE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,aAAa,CAAC,EAAE;QACd,0BAA0B;QAC1B,UAAU,CAAC,EAAE;YAAE,IAAI,EAAE,KAAK,CAAC;gBAAE,IAAI,EAAE,MAAM,CAAC;gBAAC,EAAE,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,CAAC;QAC3D,mCAAmC;QACnC,eAAe,CAAC,EAAE;YAAE,IAAI,EAAE;gBAAE,IAAI,EAAE,MAAM,CAAC;gBAAC,EAAE,EAAE,MAAM,CAAA;aAAE,GAAG,IAAI,CAAA;SAAE,CAAC;QAChE,OAAO,CAAC,EAAE;YAAE,IAAI,EAAE,KAAK,CAAC;gBAAE,IAAI,EAAE,MAAM,CAAC;gBAAC,EAAE,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,CAAC;KACzD,CAAC;CACH;AAMD,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQvE;AAED,6DAA6D;AAC7D,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAS9G;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAMD;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAiB5F;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED,0DAA0D;AAC1D,wBAAsB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAQ3F;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,aAAa,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB5E;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAKxE"}