skill-chef 0.1.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 (81) hide show
  1. package/dist/cli/cmd_read.d.ts +3 -0
  2. package/dist/cli/cmd_read.d.ts.map +1 -0
  3. package/dist/cli/cmd_read.js +434 -0
  4. package/dist/cli/cmd_read.js.map +1 -0
  5. package/dist/fetch/db.d.ts +112 -0
  6. package/dist/fetch/db.d.ts.map +1 -0
  7. package/dist/fetch/db.js +463 -0
  8. package/dist/fetch/db.js.map +1 -0
  9. package/dist/fetch/errors.d.ts +13 -0
  10. package/dist/fetch/errors.d.ts.map +1 -0
  11. package/dist/fetch/errors.js +18 -0
  12. package/dist/fetch/errors.js.map +1 -0
  13. package/dist/fetch/index.d.ts +6 -0
  14. package/dist/fetch/index.d.ts.map +1 -0
  15. package/dist/fetch/index.js +4 -0
  16. package/dist/fetch/index.js.map +1 -0
  17. package/dist/fetch/paths.d.ts +6 -0
  18. package/dist/fetch/paths.d.ts.map +1 -0
  19. package/dist/fetch/paths.js +31 -0
  20. package/dist/fetch/paths.js.map +1 -0
  21. package/dist/help/index.d.ts +2 -0
  22. package/dist/help/index.d.ts.map +1 -0
  23. package/dist/help/index.js +2 -0
  24. package/dist/help/index.js.map +1 -0
  25. package/dist/help/lookup.d.ts +11 -0
  26. package/dist/help/lookup.d.ts.map +1 -0
  27. package/dist/help/lookup.js +49 -0
  28. package/dist/help/lookup.js.map +1 -0
  29. package/dist/index.d.ts +5 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +5 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/policy/category.d.ts +10 -0
  34. package/dist/policy/category.d.ts.map +1 -0
  35. package/dist/policy/category.js +45 -0
  36. package/dist/policy/category.js.map +1 -0
  37. package/dist/policy/index.d.ts +6 -0
  38. package/dist/policy/index.d.ts.map +1 -0
  39. package/dist/policy/index.js +4 -0
  40. package/dist/policy/index.js.map +1 -0
  41. package/dist/policy/recipe.d.ts +10 -0
  42. package/dist/policy/recipe.d.ts.map +1 -0
  43. package/dist/policy/recipe.js +52 -0
  44. package/dist/policy/recipe.js.map +1 -0
  45. package/dist/policy/wakewords.d.ts +14 -0
  46. package/dist/policy/wakewords.d.ts.map +1 -0
  47. package/dist/policy/wakewords.js +67 -0
  48. package/dist/policy/wakewords.js.map +1 -0
  49. package/dist/render/envelope.d.ts +6 -0
  50. package/dist/render/envelope.d.ts.map +1 -0
  51. package/dist/render/envelope.js +48 -0
  52. package/dist/render/envelope.js.map +1 -0
  53. package/dist/render/errors.d.ts +5 -0
  54. package/dist/render/errors.d.ts.map +1 -0
  55. package/dist/render/errors.js +9 -0
  56. package/dist/render/errors.js.map +1 -0
  57. package/dist/render/html.d.ts +13 -0
  58. package/dist/render/html.d.ts.map +1 -0
  59. package/dist/render/html.js +75 -0
  60. package/dist/render/html.js.map +1 -0
  61. package/dist/render/index.d.ts +8 -0
  62. package/dist/render/index.d.ts.map +1 -0
  63. package/dist/render/index.js +6 -0
  64. package/dist/render/index.js.map +1 -0
  65. package/dist/render/templates.d.ts +5 -0
  66. package/dist/render/templates.d.ts.map +1 -0
  67. package/dist/render/templates.js +42 -0
  68. package/dist/render/templates.js.map +1 -0
  69. package/dist/render/views.d.ts +85 -0
  70. package/dist/render/views.d.ts.map +1 -0
  71. package/dist/render/views.js +93 -0
  72. package/dist/render/views.js.map +1 -0
  73. package/package.json +32 -0
  74. package/templates/cooking_run.html +16 -0
  75. package/templates/help.html +16 -0
  76. package/templates/history_query.html +16 -0
  77. package/templates/history_record.html +16 -0
  78. package/templates/recipe_search.html +16 -0
  79. package/templates/recipe_view.html +16 -0
  80. package/templates/recipe_write.html +16 -0
  81. package/templates/shopping_query.html +16 -0
@@ -0,0 +1,463 @@
1
+ // 取数层·文件 DB(老家 scripts/db.py + init_db.py + 17 表 schema 对应):node:sqlite。
2
+ // 缺失/损坏大声失败,不返空。废弃 = status 置已废弃(只增不删,无物理删除)。
3
+ import { DatabaseSync } from 'node:sqlite';
4
+ import { randomUUID } from 'node:crypto';
5
+ import { ChefFetchError } from './errors.js';
6
+ function now() {
7
+ return new Date().toISOString().slice(0, 19).replace('T', ' ');
8
+ }
9
+ function today() {
10
+ return new Date().toISOString().slice(0, 10);
11
+ }
12
+ const DDL = [
13
+ `CREATE TABLE IF NOT EXISTS recipes (id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, description TEXT DEFAULT '', difficulty TEXT DEFAULT '', servings INTEGER DEFAULT 2, total_time_minutes INTEGER DEFAULT 30, status TEXT DEFAULT '未做', photo_url TEXT DEFAULT '', source TEXT DEFAULT '', source_url TEXT DEFAULT '', created_at TEXT DEFAULT '', updated_at TEXT DEFAULT '')`,
14
+ `CREATE INDEX IF NOT EXISTS idx_recipes_name ON recipes(name)`,
15
+ `CREATE INDEX IF NOT EXISTS idx_recipes_difficulty ON recipes(difficulty)`,
16
+ `CREATE INDEX IF NOT EXISTS idx_recipes_status ON recipes(status)`,
17
+ `CREATE TABLE IF NOT EXISTS recipe_categories (id TEXT PRIMARY KEY, recipe_id TEXT NOT NULL, cuisine_type TEXT DEFAULT '', region TEXT DEFAULT '', country TEXT DEFAULT '', FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE)`,
18
+ `CREATE INDEX IF NOT EXISTS idx_recipe_categories_recipe ON recipe_categories(recipe_id)`,
19
+ `CREATE INDEX IF NOT EXISTS idx_recipe_categories_cuisine ON recipe_categories(cuisine_type)`,
20
+ `CREATE TABLE IF NOT EXISTS recipe_seasons (id TEXT PRIMARY KEY, recipe_id TEXT NOT NULL, season TEXT NOT NULL, FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE)`,
21
+ `CREATE INDEX IF NOT EXISTS idx_recipe_seasons_recipe ON recipe_seasons(recipe_id)`,
22
+ `CREATE TABLE IF NOT EXISTS recipe_cooking_methods (id TEXT PRIMARY KEY, recipe_id TEXT NOT NULL, method TEXT NOT NULL, FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE)`,
23
+ `CREATE INDEX IF NOT EXISTS idx_recipe_cooking_methods_recipe ON recipe_cooking_methods(recipe_id)`,
24
+ `CREATE TABLE IF NOT EXISTS recipe_flavors (id TEXT PRIMARY KEY, recipe_id TEXT NOT NULL, flavor TEXT NOT NULL, FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE)`,
25
+ `CREATE INDEX IF NOT EXISTS idx_recipe_flavors_recipe ON recipe_flavors(recipe_id)`,
26
+ `CREATE TABLE IF NOT EXISTS recipe_diet_tags (id TEXT PRIMARY KEY, recipe_id TEXT NOT NULL, tag TEXT NOT NULL, FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE)`,
27
+ `CREATE INDEX IF NOT EXISTS idx_recipe_diet_tags_recipe ON recipe_diet_tags(recipe_id)`,
28
+ `CREATE TABLE IF NOT EXISTS recipe_meal_types (id TEXT PRIMARY KEY, recipe_id TEXT NOT NULL, meal_type TEXT NOT NULL, FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE)`,
29
+ `CREATE INDEX IF NOT EXISTS idx_recipe_meal_types_recipe ON recipe_meal_types(recipe_id)`,
30
+ `CREATE TABLE IF NOT EXISTS ingredients (id TEXT PRIMARY KEY, recipe_id TEXT NOT NULL, sequence INTEGER DEFAULT 0, name TEXT NOT NULL, category TEXT DEFAULT '', quantity REAL DEFAULT NULL, unit TEXT DEFAULT '', quantity_text TEXT DEFAULT '', is_optional INTEGER DEFAULT 0, substitute TEXT DEFAULT '', FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE)`,
31
+ `CREATE INDEX IF NOT EXISTS idx_ingredients_recipe ON ingredients(recipe_id)`,
32
+ `CREATE INDEX IF NOT EXISTS idx_ingredients_name ON ingredients(name)`,
33
+ `CREATE TABLE IF NOT EXISTS cooking_steps (id TEXT PRIMARY KEY, recipe_id TEXT NOT NULL, sequence INTEGER NOT NULL, action TEXT NOT NULL, duration_minutes INTEGER DEFAULT NULL, heat_level TEXT DEFAULT '', temperature TEXT DEFAULT '', expected_result TEXT DEFAULT '', FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE)`,
34
+ `CREATE INDEX IF NOT EXISTS idx_cooking_steps_recipe ON cooking_steps(recipe_id)`,
35
+ `CREATE INDEX IF NOT EXISTS idx_cooking_steps_sequence ON cooking_steps(recipe_id, sequence)`,
36
+ `CREATE TABLE IF NOT EXISTS step_ingredients (id TEXT PRIMARY KEY, step_id TEXT NOT NULL, ingredient_id TEXT NOT NULL, quantity_used REAL DEFAULT NULL, introduced_at TEXT DEFAULT '', unit TEXT DEFAULT '', FOREIGN KEY (step_id) REFERENCES cooking_steps(id) ON DELETE CASCADE, FOREIGN KEY (ingredient_id) REFERENCES ingredients(id) ON DELETE CASCADE)`,
37
+ `CREATE INDEX IF NOT EXISTS idx_step_ingredients_step ON step_ingredients(step_id)`,
38
+ `CREATE INDEX IF NOT EXISTS idx_step_ingredients_ingredient ON step_ingredients(ingredient_id)`,
39
+ `CREATE TABLE IF NOT EXISTS step_techniques (id TEXT PRIMARY KEY, step_id TEXT NOT NULL, recipe_id TEXT NOT NULL, technique_name TEXT NOT NULL, description TEXT DEFAULT '', key_points TEXT DEFAULT '', FOREIGN KEY (step_id) REFERENCES cooking_steps(id) ON DELETE CASCADE, FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE)`,
40
+ `CREATE INDEX IF NOT EXISTS idx_step_techniques_step ON step_techniques(step_id)`,
41
+ `CREATE INDEX IF NOT EXISTS idx_step_techniques_recipe ON step_techniques(recipe_id)`,
42
+ `CREATE TABLE IF NOT EXISTS tips (id TEXT PRIMARY KEY, recipe_id TEXT NOT NULL, step_id TEXT DEFAULT NULL, ingredient_id TEXT DEFAULT NULL, category TEXT DEFAULT '', content TEXT NOT NULL, priority INTEGER DEFAULT 0, FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE, FOREIGN KEY (step_id) REFERENCES cooking_steps(id) ON DELETE SET NULL, FOREIGN KEY (ingredient_id) REFERENCES ingredients(id) ON DELETE SET NULL)`,
43
+ `CREATE INDEX IF NOT EXISTS idx_tips_recipe ON tips(recipe_id)`,
44
+ `CREATE INDEX IF NOT EXISTS idx_tips_step ON tips(step_id)`,
45
+ `CREATE INDEX IF NOT EXISTS idx_tips_ingredient ON tips(ingredient_id)`,
46
+ `CREATE TABLE IF NOT EXISTS recipe_history (id TEXT PRIMARY KEY, recipe_id TEXT NOT NULL, cook_date TEXT NOT NULL, cook_sequence INTEGER DEFAULT 1, rating REAL DEFAULT NULL, feedback TEXT DEFAULT '', photo TEXT DEFAULT NULL, FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE)`,
47
+ `CREATE INDEX IF NOT EXISTS idx_recipe_history_recipe ON recipe_history(recipe_id)`,
48
+ `CREATE INDEX IF NOT EXISTS idx_recipe_history_date ON recipe_history(cook_date)`,
49
+ `CREATE TABLE IF NOT EXISTS background_knowledge (id TEXT PRIMARY KEY, recipe_id TEXT NOT NULL UNIQUE, origin_story TEXT DEFAULT '', historical_background TEXT DEFAULT '', cultural_significance TEXT DEFAULT '', FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE)`,
50
+ `CREATE INDEX IF NOT EXISTS idx_background_recipe ON background_knowledge(recipe_id)`,
51
+ `CREATE TABLE IF NOT EXISTS recipe_relations (id TEXT PRIMARY KEY, parent_id TEXT NOT NULL, child_id TEXT NOT NULL, relation_type TEXT DEFAULT '', change_summary TEXT DEFAULT '', FOREIGN KEY (parent_id) REFERENCES recipes(id) ON DELETE CASCADE, FOREIGN KEY (child_id) REFERENCES recipes(id) ON DELETE CASCADE)`,
52
+ `CREATE INDEX IF NOT EXISTS idx_recipe_relations_parent ON recipe_relations(parent_id)`,
53
+ `CREATE INDEX IF NOT EXISTS idx_recipe_relations_child ON recipe_relations(child_id)`,
54
+ `CREATE TABLE IF NOT EXISTS cookware (id TEXT PRIMARY KEY, recipe_id TEXT NOT NULL, name TEXT NOT NULL, category TEXT DEFAULT '', FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE)`,
55
+ `CREATE INDEX IF NOT EXISTS idx_cookware_recipe ON cookware(recipe_id)`,
56
+ `CREATE TABLE IF NOT EXISTS nutrition_info (id TEXT PRIMARY KEY, recipe_id TEXT NOT NULL UNIQUE, serving_size REAL DEFAULT NULL, serving_unit TEXT DEFAULT '', calories INTEGER DEFAULT NULL, protein REAL DEFAULT NULL, fat REAL DEFAULT NULL, carbs REAL DEFAULT NULL, fiber REAL DEFAULT NULL, sodium REAL DEFAULT NULL, FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE)`,
57
+ `CREATE INDEX IF NOT EXISTS idx_nutrition_recipe ON nutrition_info(recipe_id)`,
58
+ ];
59
+ function qAll(h, sql, params = []) {
60
+ try {
61
+ const stmt = h.db.prepare(sql);
62
+ return stmt.all(...params);
63
+ }
64
+ catch (e) {
65
+ throw new ChefFetchError('CHEF_DB_UNREADABLE', '查询失败', { cause: e });
66
+ }
67
+ }
68
+ function qGet(h, sql, params = []) {
69
+ try {
70
+ const stmt = h.db.prepare(sql);
71
+ return stmt.get(...params);
72
+ }
73
+ catch (e) {
74
+ throw new ChefFetchError('CHEF_DB_UNREADABLE', '查询失败', { cause: e });
75
+ }
76
+ }
77
+ function qRun(h, sql, params = []) {
78
+ try {
79
+ const stmt = h.db.prepare(sql);
80
+ stmt.run(...params);
81
+ }
82
+ catch (e) {
83
+ if (e instanceof ChefFetchError)
84
+ throw e;
85
+ throw new ChefFetchError('CHEF_DB_UNREADABLE', '写库失败', { cause: e });
86
+ }
87
+ }
88
+ function toRecipe(r) {
89
+ return {
90
+ id: String(r.id ?? ''), name: String(r.name ?? ''), description: String(r.description ?? ''),
91
+ difficulty: String(r.difficulty ?? ''), servings: Number(r.servings ?? 2),
92
+ total_time_minutes: Number(r.total_time_minutes ?? 30), status: String(r.status ?? ''),
93
+ photo_url: String(r.photo_url ?? ''), source: String(r.source ?? ''),
94
+ source_url: String(r.source_url ?? ''), created_at: String(r.created_at ?? ''),
95
+ updated_at: String(r.updated_at ?? ''),
96
+ };
97
+ }
98
+ function toIngredient(r) {
99
+ const q = r.quantity === null || r.quantity === undefined || r.quantity === '' ? null : Number(r.quantity);
100
+ return {
101
+ id: String(r.id ?? ''), recipe_id: String(r.recipe_id ?? ''), sequence: Number(r.sequence ?? 0),
102
+ name: String(r.name ?? ''), category: String(r.category ?? ''),
103
+ quantity: q === null || Number.isNaN(q) ? null : q, unit: String(r.unit ?? ''),
104
+ quantity_text: String(r.quantity_text ?? ''), is_optional: Number(r.is_optional ?? 0),
105
+ substitute: String(r.substitute ?? ''),
106
+ };
107
+ }
108
+ function toStep(r) {
109
+ const d = r.duration_minutes === null || r.duration_minutes === undefined || r.duration_minutes === '' ? null : Number(r.duration_minutes);
110
+ return {
111
+ id: String(r.id ?? ''), recipe_id: String(r.recipe_id ?? ''), sequence: Number(r.sequence ?? 0),
112
+ action: String(r.action ?? ''), duration_minutes: d === null || Number.isNaN(d) ? null : d,
113
+ heat_level: String(r.heat_level ?? ''), temperature: String(r.temperature ?? ''),
114
+ expected_result: String(r.expected_result ?? ''),
115
+ };
116
+ }
117
+ function toHistory(r) {
118
+ const rt = r.rating === null || r.rating === undefined || r.rating === '' ? null : Number(r.rating);
119
+ return {
120
+ id: String(r.id ?? ''), recipe_id: String(r.recipe_id ?? ''),
121
+ cook_date: String(r.cook_date ?? ''), cook_sequence: Number(r.cook_sequence ?? 0),
122
+ rating: rt === null || Number.isNaN(rt) ? null : rt, feedback: String(r.feedback ?? ''),
123
+ };
124
+ }
125
+ export function openChefDb(dbPath) {
126
+ if (typeof dbPath !== 'string' || dbPath.length === 0) {
127
+ throw new ChefFetchError('CHEF_DB_MISSING', '大厨 DB 路径未指定');
128
+ }
129
+ let db;
130
+ try {
131
+ db = new DatabaseSync(dbPath);
132
+ }
133
+ catch (e) {
134
+ throw new ChefFetchError('CHEF_DB_UNREADABLE', '大厨 DB 打不开:' + dbPath, { cause: e });
135
+ }
136
+ const h = { db, path: dbPath, initialized: false };
137
+ try {
138
+ db.exec('PRAGMA journal_mode=WAL');
139
+ db.exec('PRAGMA busy_timeout=5000');
140
+ let existed = false;
141
+ try {
142
+ const row = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='recipes'").get();
143
+ existed = !!row;
144
+ }
145
+ catch {
146
+ existed = false;
147
+ }
148
+ for (const ddl of DDL)
149
+ db.exec(ddl);
150
+ h.initialized = !existed;
151
+ }
152
+ catch (e) {
153
+ try {
154
+ db.close();
155
+ }
156
+ catch { /* ignore */ }
157
+ throw new ChefFetchError('CHEF_DB_UNREADABLE', '大厨 DB 初始化失败:' + dbPath, { cause: e });
158
+ }
159
+ return h;
160
+ }
161
+ export function closeChefDb(handle) {
162
+ try {
163
+ handle.db.close();
164
+ }
165
+ catch { /* ignore */ }
166
+ }
167
+ function mustRecipe(h, idOrName) {
168
+ const row = qGet(h, 'SELECT * FROM recipes WHERE id = ? OR name = ?', [idOrName, idOrName]);
169
+ if (!row)
170
+ throw new ChefFetchError('CHEF_RECIPE_NOT_FOUND', '无此菜谱:' + idOrName);
171
+ return toRecipe(row);
172
+ }
173
+ export function addRecipe(h, input) {
174
+ const name = typeof input?.name === 'string' ? String(input.name).trim() : '';
175
+ if (!name)
176
+ throw new ChefFetchError('CHEF_BAD_QUERY', '加菜须给菜名 name');
177
+ const id = randomUUID();
178
+ const ts = now();
179
+ const p = input;
180
+ const servings = p.servings === undefined || p.servings === '' ? 2 : Number(p.servings);
181
+ const totalTime = (p.total_time_minutes === undefined || p.total_time_minutes === '') ? (p.total_time === undefined || p.total_time === '' ? 30 : Number(p.total_time)) : Number(p.total_time_minutes);
182
+ try {
183
+ qRun(h, 'INSERT INTO recipes (id, name, description, difficulty, servings, total_time_minutes, status, photo_url, source, source_url, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
184
+ id, name,
185
+ String(p.description ?? ''), String(p.difficulty ?? ''), servings,
186
+ totalTime, String(p.status ?? '未做'),
187
+ String(p.photo_url ?? ''), String(p.source ?? ''), String(p.source_url ?? ''), ts, ts,
188
+ ]);
189
+ }
190
+ catch (e) {
191
+ if (e instanceof ChefFetchError)
192
+ throw e;
193
+ throw new ChefFetchError('CHEF_DB_UNREADABLE', '加菜写盘失败:' + name, { cause: e });
194
+ }
195
+ return mustRecipe(h, id);
196
+ }
197
+ export function addIngredient(h, recipeIdOrParams, input) {
198
+ const params = typeof recipeIdOrParams === 'string' ? { ...(input ?? {}), recipe_id: recipeIdOrParams } : recipeIdOrParams;
199
+ const recipeId = String(params.recipe_id ?? params.recipeId ?? '');
200
+ if (!recipeId)
201
+ throw new ChefFetchError('CHEF_BAD_QUERY', '加食材须给 recipe_id');
202
+ mustRecipe(h, recipeId);
203
+ const name = typeof params?.name === 'string' ? String(params.name).trim() : '';
204
+ if (!name)
205
+ throw new ChefFetchError('CHEF_BAD_QUERY', '食材须给名 name');
206
+ const maxRow = qGet(h, 'SELECT MAX(sequence) AS m FROM ingredients WHERE recipe_id = ?', [recipeId]);
207
+ const seq = (maxRow?.m ?? 0) + 1;
208
+ const id = randomUUID();
209
+ const qtyRaw = params.quantity;
210
+ const qtyNum = qtyRaw === undefined || qtyRaw === null || qtyRaw === '' ? null : Number(qtyRaw);
211
+ const qty = qtyNum === null || Number.isNaN(qtyNum) ? null : qtyNum;
212
+ const isOptRaw = params.is_optional;
213
+ const isOpt = isOptRaw === true || isOptRaw === 1 || isOptRaw === '1' ? 1 : 0;
214
+ try {
215
+ qRun(h, 'INSERT INTO ingredients (id, recipe_id, sequence, name, category, quantity, unit, quantity_text, is_optional, substitute) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
216
+ id, recipeId, seq, name, String(params.category ?? ''), qty, String(params.unit ?? ''), String(params.quantity_text ?? ''), isOpt, String(params.substitute ?? ''),
217
+ ]);
218
+ }
219
+ catch (e) {
220
+ throw new ChefFetchError('CHEF_DB_UNREADABLE', '食材写盘失败:' + name, { cause: e });
221
+ }
222
+ const row = qGet(h, 'SELECT * FROM ingredients WHERE id = ?', [id]);
223
+ if (!row)
224
+ throw new ChefFetchError('CHEF_RECIPE_CORRUPT', '食材写后读回失败:' + name);
225
+ return toIngredient(row);
226
+ }
227
+ export function addStep(h, recipeIdOrParams, input) {
228
+ const params = typeof recipeIdOrParams === 'string' ? { ...(input ?? {}), recipe_id: recipeIdOrParams } : recipeIdOrParams;
229
+ const recipeId = String(params.recipe_id ?? params.recipeId ?? '');
230
+ if (!recipeId)
231
+ throw new ChefFetchError('CHEF_BAD_QUERY', '加步骤须给 recipe_id');
232
+ mustRecipe(h, recipeId);
233
+ const action = typeof params?.action === 'string' ? String(params.action).trim() : '';
234
+ if (!action)
235
+ throw new ChefFetchError('CHEF_BAD_QUERY', '步骤须给操作 action');
236
+ const maxRow = qGet(h, 'SELECT MAX(sequence) AS m FROM cooking_steps WHERE recipe_id = ?', [recipeId]);
237
+ const seq = (maxRow?.m ?? 0) + 1;
238
+ const id = randomUUID();
239
+ const durRaw = params.duration_minutes;
240
+ const durNum = durRaw === undefined || durRaw === null || durRaw === '' ? null : Number(durRaw);
241
+ const dur = durNum === null || Number.isNaN(durNum) ? null : durNum;
242
+ try {
243
+ qRun(h, 'INSERT INTO cooking_steps (id, recipe_id, sequence, action, duration_minutes, heat_level, temperature, expected_result) VALUES (?, ?, ?, ?, ?, ?, ?, ?)', [
244
+ id, recipeId, seq, action, dur, String(params.heat_level ?? ''), String(params.temperature ?? ''), String(params.expected_result ?? ''),
245
+ ]);
246
+ }
247
+ catch (e) {
248
+ throw new ChefFetchError('CHEF_DB_UNREADABLE', '步骤写盘失败', { cause: e });
249
+ }
250
+ const row = qGet(h, 'SELECT * FROM cooking_steps WHERE id = ?', [id]);
251
+ if (!row)
252
+ throw new ChefFetchError('CHEF_RECIPE_CORRUPT', '步骤写后读回失败');
253
+ return toStep(row);
254
+ }
255
+ export function listRecipes(h, opts = {}) {
256
+ const conds = ['1=1'];
257
+ const params = [];
258
+ if (!opts.includeDeprecated)
259
+ conds.push("status != '已废弃'");
260
+ if (opts.difficulty !== undefined) {
261
+ conds.push('difficulty = ?');
262
+ params.push(opts.difficulty);
263
+ }
264
+ const rows = qAll(h, 'SELECT * FROM recipes WHERE ' + conds.join(' AND ') + ' ORDER BY name ASC', params);
265
+ return rows.map(toRecipe);
266
+ }
267
+ export function searchRecipes(h, kw) {
268
+ if (typeof kw !== 'string' || kw.trim().length === 0) {
269
+ throw new ChefFetchError('CHEF_BAD_QUERY', '搜索须给关键词(空查询不返全量)');
270
+ }
271
+ const k = '%' + kw.trim() + '%';
272
+ const rows = qAll(h, "SELECT DISTINCT r.* FROM recipes r LEFT JOIN ingredients i ON i.recipe_id = r.id WHERE (r.name LIKE ? OR r.description LIKE ? OR i.name LIKE ?) AND r.status != '已废弃' ORDER BY r.name ASC", [k, k, k]);
273
+ return rows.map(toRecipe);
274
+ }
275
+ export function getRecipeDetail(h, idOrName) {
276
+ if (typeof idOrName !== 'string' || idOrName.trim().length === 0) {
277
+ throw new ChefFetchError('CHEF_BAD_QUERY', '查看须给菜名或 id');
278
+ }
279
+ const recipe = mustRecipe(h, idOrName.trim());
280
+ const ings = qAll(h, 'SELECT * FROM ingredients WHERE recipe_id = ? ORDER BY sequence ASC', [recipe.id]);
281
+ const steps = qAll(h, 'SELECT * FROM cooking_steps WHERE recipe_id = ? ORDER BY sequence ASC', [recipe.id]);
282
+ return { recipe, ingredients: ings.map(toIngredient), steps: steps.map(toStep) };
283
+ }
284
+ export function deprecateRecipe(h, id) {
285
+ const r = mustRecipe(h, id);
286
+ qRun(h, 'UPDATE recipes SET status = ?, updated_at = ? WHERE id = ?', ['已废弃', now(), r.id]);
287
+ return mustRecipe(h, r.id);
288
+ }
289
+ export function updateRecipe(h, id, patch) {
290
+ const r = mustRecipe(h, id);
291
+ const allowed = ['name', 'description', 'difficulty', 'servings', 'total_time_minutes', 'status', 'photo_url', 'source', 'source_url'];
292
+ const sets = [];
293
+ const params = [];
294
+ for (const k of allowed) {
295
+ const v = patch[k];
296
+ if (v !== undefined) {
297
+ sets.push(k + ' = ?');
298
+ params.push(k === 'servings' || k === 'total_time_minutes' ? Number(v) : String(v));
299
+ }
300
+ }
301
+ if (!sets.length)
302
+ throw new ChefFetchError('CHEF_BAD_QUERY', 'update 至少改一个字段');
303
+ sets.push('updated_at = ?');
304
+ params.push(now());
305
+ params.push(r.id);
306
+ try {
307
+ qRun(h, 'UPDATE recipes SET ' + sets.join(', ') + ' WHERE id = ?', params);
308
+ }
309
+ catch (e) {
310
+ throw new ChefFetchError('CHEF_DB_UNREADABLE', '菜谱更新失败:' + id, { cause: e });
311
+ }
312
+ return mustRecipe(h, r.id);
313
+ }
314
+ export function filterRecipes(h, filters = {}) {
315
+ const conds = ['1=1'];
316
+ const params = [];
317
+ if (filters.status !== undefined && filters.status !== '') {
318
+ conds.push('r.status = ?');
319
+ params.push(String(filters.status));
320
+ }
321
+ else
322
+ conds.push("r.status != '已废弃'");
323
+ if (filters.difficulty !== undefined && filters.difficulty !== '') {
324
+ conds.push('r.difficulty = ?');
325
+ params.push(String(filters.difficulty));
326
+ }
327
+ if (filters.maxTime !== undefined && filters.maxTime !== '') {
328
+ conds.push('r.total_time_minutes <= ?');
329
+ params.push(Number(filters.maxTime));
330
+ }
331
+ const exists = (table, col, val) => {
332
+ conds.push('EXISTS (SELECT 1 FROM ' + table + ' t WHERE t.recipe_id = r.id AND t.' + col + ' = ?)');
333
+ params.push(String(val));
334
+ };
335
+ if (filters.cuisine !== undefined && filters.cuisine !== '')
336
+ exists('recipe_categories', 'cuisine_type', filters.cuisine);
337
+ if (filters.season !== undefined && filters.season !== '')
338
+ exists('recipe_seasons', 'season', filters.season);
339
+ if (filters.method !== undefined && filters.method !== '')
340
+ exists('recipe_cooking_methods', 'method', filters.method);
341
+ if (filters.flavor !== undefined && filters.flavor !== '')
342
+ exists('recipe_flavors', 'flavor', filters.flavor);
343
+ if (filters.tag !== undefined && filters.tag !== '')
344
+ exists('recipe_diet_tags', 'tag', filters.tag);
345
+ if (filters.meal !== undefined && filters.meal !== '')
346
+ exists('recipe_meal_types', 'meal_type', filters.meal);
347
+ if (filters.cookware !== undefined && filters.cookware !== '')
348
+ exists('cookware', 'name', filters.cookware);
349
+ const rows = qAll(h, 'SELECT DISTINCT r.* FROM recipes r WHERE ' + conds.join(' AND ') + ' ORDER BY r.name ASC', params);
350
+ return rows.map(toRecipe);
351
+ }
352
+ export function recordHistory(h, input) {
353
+ const rid = typeof input?.recipe_id === 'string' ? input.recipe_id.trim() : '';
354
+ if (!rid)
355
+ throw new ChefFetchError('CHEF_BAD_QUERY', '记录做菜须给 recipe_id');
356
+ const recipe = mustRecipe(h, rid);
357
+ let rating = null;
358
+ const rawRt = input.rating;
359
+ if (rawRt !== undefined && rawRt !== null && rawRt !== '') {
360
+ const n = typeof rawRt === 'string' ? Number(String(rawRt).trim()) : rawRt;
361
+ if (typeof n !== 'number' || !Number.isFinite(n))
362
+ throw new ChefFetchError('CHEF_HISTORY_CORRUPT', '评分须为数字');
363
+ rating = n;
364
+ }
365
+ const cookDate = typeof input.cook_date === 'string' && input.cook_date.trim() ? input.cook_date.trim() : today();
366
+ const maxRow = qGet(h, 'SELECT MAX(cook_sequence) AS m FROM recipe_history WHERE recipe_id = ?', [recipe.id]);
367
+ const seq = (maxRow?.m ?? 0) + 1;
368
+ const id = randomUUID();
369
+ try {
370
+ qRun(h, 'INSERT INTO recipe_history (id, recipe_id, cook_date, cook_sequence, rating, feedback) VALUES (?, ?, ?, ?, ?, ?)', [id, recipe.id, cookDate, seq, rating, input.feedback ?? '']);
371
+ if (recipe.status === '未做')
372
+ qRun(h, 'UPDATE recipes SET status = ?, updated_at = ? WHERE id = ?', ['已做', now(), recipe.id]);
373
+ }
374
+ catch (e) {
375
+ if (e instanceof ChefFetchError)
376
+ throw e;
377
+ throw new ChefFetchError('CHEF_DB_UNREADABLE', '历史写盘失败', { cause: e });
378
+ }
379
+ const row = qGet(h, 'SELECT * FROM recipe_history WHERE id = ?', [id]);
380
+ if (!row)
381
+ throw new ChefFetchError('CHEF_HISTORY_CORRUPT', '历史写后读回失败');
382
+ return toHistory(row);
383
+ }
384
+ export function queryHistory(h, recipeId) {
385
+ if (recipeId === undefined || recipeId === null || recipeId === '') {
386
+ const rows = qAll(h, 'SELECT * FROM recipe_history ORDER BY cook_date DESC, cook_sequence ASC');
387
+ return rows.map(toHistory);
388
+ }
389
+ const recipe = mustRecipe(h, recipeId);
390
+ const rows = qAll(h, 'SELECT * FROM recipe_history WHERE recipe_id = ? ORDER BY cook_sequence ASC', [recipe.id]);
391
+ return rows.map(toHistory);
392
+ }
393
+ export function historyStats(h, recipeId) {
394
+ const recipe = mustRecipe(h, recipeId);
395
+ const row = qGet(h, 'SELECT COUNT(*) AS c, AVG(rating) AS a FROM recipe_history WHERE recipe_id = ?', [recipe.id]);
396
+ const count = Number(row?.c ?? 0);
397
+ const avg = row?.a === null || row?.a === undefined ? null : Number(row.a);
398
+ return { count, avgRating: avg };
399
+ }
400
+ export function buildShoppingList(h, names) {
401
+ if (!Array.isArray(names) || names.length === 0) {
402
+ throw new ChefFetchError('CHEF_BAD_QUERY', '采购须给菜名(空查询不返空)');
403
+ }
404
+ const ids = [];
405
+ const nameById = new Map();
406
+ for (const n of names) {
407
+ if (typeof n !== 'string' || !n.trim())
408
+ throw new ChefFetchError('CHEF_BAD_QUERY', '采购菜名含空串');
409
+ const r = mustRecipe(h, n.trim());
410
+ if (!ids.includes(r.id)) {
411
+ ids.push(r.id);
412
+ nameById.set(r.id, r.name);
413
+ }
414
+ }
415
+ const placeholders = ids.map(() => '?').join(',');
416
+ const rows = qAll(h, 'SELECT i.*, r.name AS _recipe_name FROM ingredients i JOIN recipes r ON r.id = i.recipe_id WHERE i.recipe_id IN (' + placeholders + ') ORDER BY i.name ASC', ids);
417
+ const merged = new Map();
418
+ for (const r of rows) {
419
+ const ing = toIngredient(r);
420
+ const recipeName = String(r._recipe_name ?? nameById.get(ing.recipe_id) ?? '');
421
+ const key = ing.name + '|||' + ing.unit;
422
+ const qty = ing.quantity ?? 0;
423
+ const hit = merged.get(key);
424
+ const qt = ing.quantity_text || (ing.quantity !== null ? String(ing.quantity) + ing.unit : '');
425
+ if (!hit) {
426
+ merged.set(key, { name: ing.name, quantity: qty, unit: ing.unit, recipes: [recipeName], quantity_text: qt, from: recipeName, optional: ing.is_optional === 1, category: ing.category });
427
+ }
428
+ else {
429
+ hit.quantity += qty;
430
+ if (!hit.recipes.includes(recipeName))
431
+ hit.recipes.push(recipeName);
432
+ hit.from = hit.recipes.join('+');
433
+ if (ing.is_optional !== 1)
434
+ hit.optional = false;
435
+ }
436
+ }
437
+ return [...merged.values()].sort((a, b) => a.name.localeCompare(b.name, 'zh'));
438
+ }
439
+ export function healthCheck(h) {
440
+ const issues = [];
441
+ try {
442
+ const noIng = qAll(h, "SELECT r.name AS name FROM recipes r LEFT JOIN ingredients i ON i.recipe_id = r.id WHERE i.id IS NULL AND r.status != '已废弃'");
443
+ for (const r of noIng)
444
+ issues.push({ level: 'warn', message: '无食材:' + String(r.name ?? '') });
445
+ const noStep = qAll(h, "SELECT r.name AS name FROM recipes r LEFT JOIN cooking_steps s ON s.recipe_id = r.id WHERE s.id IS NULL AND r.status != '已废弃'");
446
+ for (const r of noStep)
447
+ issues.push({ level: 'warn', message: '无步骤:' + String(r.name ?? '') });
448
+ const noHeat = qAll(h, "SELECT r.name AS name, s.sequence AS seq FROM cooking_steps s JOIN recipes r ON r.id = s.recipe_id WHERE (s.heat_level IS NULL OR s.heat_level = '') AND r.status != '已废弃'");
449
+ for (const r of noHeat)
450
+ issues.push({ level: 'warn', message: '步骤缺火候:' + String(r.name ?? '') + '第' + String(r.seq ?? '') + '步' });
451
+ const never = qAll(h, "SELECT r.name AS name FROM recipes r LEFT JOIN recipe_history hh ON hh.recipe_id = r.id WHERE hh.id IS NULL AND r.status != '已废弃'");
452
+ for (const r of never)
453
+ issues.push({ level: 'info', message: '从未做过:' + String(r.name ?? '') });
454
+ }
455
+ catch (e) {
456
+ if (e instanceof ChefFetchError)
457
+ throw e;
458
+ throw new ChefFetchError('CHEF_DB_UNREADABLE', '体检查询失败', { cause: e });
459
+ }
460
+ issues.sort((a, b) => (a.level < b.level ? -1 : a.level > b.level ? 1 : String(a.message ?? '').localeCompare(String(b.message ?? ''), 'zh')));
461
+ return issues;
462
+ }
463
+ //# sourceMappingURL=db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/fetch/db.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export declare class ChefFetchError extends Error {
2
+ readonly code: 'CHEF_DB_MISSING' | 'CHEF_DB_UNREADABLE' | 'CHEF_RECIPE_CORRUPT' | 'CHEF_RECIPE_NOT_FOUND' | 'CHEF_BAD_QUERY' | 'CHEF_EMPTY_RESULT' | 'CHEF_HISTORY_CORRUPT';
3
+ constructor(code: ChefFetchError['code'], message: string, options?: {
4
+ cause?: unknown;
5
+ });
6
+ }
7
+ export declare class ChefPolicyError extends Error {
8
+ readonly code: 'POLICY_NO_MATCH' | 'POLICY_MISSING_SLOT' | 'POLICY_BAD_CATEGORY' | 'POLICY_BAD_DIFFICULTY' | 'POLICY_BAD_STATUS' | 'POLICY_BAD_HEAT' | 'POLICY_BAD_RATING' | 'POLICY_BAD_TIME' | 'POLICY_BAD_INPUT' | 'POLICY_CONFLICT';
9
+ constructor(code: ChefPolicyError['code'], message: string, options?: {
10
+ cause?: unknown;
11
+ });
12
+ }
13
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/fetch/errors.ts"],"names":[],"mappings":"AACA,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,IAAI,EACT,iBAAiB,GAAG,oBAAoB,GAAG,qBAAqB,GAChE,uBAAuB,GAAG,gBAAgB,GAAG,mBAAmB,GAChE,sBAAsB,CAAC;gBACf,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAKzF;AAED,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,IAAI,EACT,iBAAiB,GAAG,qBAAqB,GAAG,qBAAqB,GACjE,uBAAuB,GAAG,mBAAmB,GAAG,iBAAiB,GACjE,mBAAmB,GAAG,iBAAiB,GAAG,kBAAkB,GAAG,iBAAiB,CAAC;gBACzE,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAK1F"}
@@ -0,0 +1,18 @@
1
+ // 取数/口径错误:坏输入与缺失一律 throw,永不返空数组冒充正常。
2
+ export class ChefFetchError extends Error {
3
+ code;
4
+ constructor(code, message, options) {
5
+ super(message, options);
6
+ this.name = 'ChefFetchError';
7
+ this.code = code;
8
+ }
9
+ }
10
+ export class ChefPolicyError extends Error {
11
+ code;
12
+ constructor(code, message, options) {
13
+ super(message, options);
14
+ this.name = 'ChefPolicyError';
15
+ this.code = code;
16
+ }
17
+ }
18
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/fetch/errors.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,IAAI,CAGc;IAC3B,YAAY,IAA4B,EAAE,OAAe,EAAE,OAA6B;QACtF,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAC/B,IAAI,CAGwE;IACrF,YAAY,IAA6B,EAAE,OAAe,EAAE,OAA6B;QACvF,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ export { ChefFetchError, ChefPolicyError } from './errors.js';
2
+ export { DB_FILENAME, resolveDbDir, resolveDbPath, assertWritablePath } from './paths.js';
3
+ export { openChefDb, closeChefDb, addRecipe, addIngredient, addStep, listRecipes, filterRecipes, searchRecipes, getRecipeDetail, deprecateRecipe, updateRecipe, recordHistory, queryHistory, historyStats, buildShoppingList, healthCheck } from './db.js';
4
+ export type { RecipeRow, IngredientRow, StepRow, HistoryRow, HealthIssue, ChefDb } from './db.js';
5
+ export type { ShoppingItem as ChefShoppingItem } from './db.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fetch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC1F,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3P,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAClG,YAAY,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { ChefFetchError, ChefPolicyError } from './errors.js';
2
+ export { DB_FILENAME, resolveDbDir, resolveDbPath, assertWritablePath } from './paths.js';
3
+ export { openChefDb, closeChefDb, addRecipe, addIngredient, addStep, listRecipes, filterRecipes, searchRecipes, getRecipeDetail, deprecateRecipe, updateRecipe, recordHistory, queryHistory, historyStats, buildShoppingList, healthCheck } from './db.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fetch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC1F,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare const DB_FILENAME = "chef_data.db";
2
+ export declare function resolveDbDir(): string;
3
+ export declare function resolveDbPath(filename?: string, dir?: string): string;
4
+ /** 测试隔离守卫:非 tmp 路径写库须 CHEF_FORCE_PROD=1(bill 哨兵语义的大厨版)。 */
5
+ export declare function assertWritablePath(dbPath: string): void;
6
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/fetch/paths.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,WAAW,iBAAiB,CAAC;AAE1C,wBAAgB,YAAY,IAAI,MAAM,CASrC;AAED,wBAAgB,aAAa,CAAC,QAAQ,SAAc,EAAE,GAAG,SAAiB,GAAG,MAAM,CAGlF;AAED,2DAA2D;AAC3D,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAYvD"}
@@ -0,0 +1,31 @@
1
+ // DB 路径解析与隔离守卫:SKILLS_DB_PATH 必设,无默认值(铁律缺失阻断)。
2
+ // 老家 db_config._fallback_db_dir(D:/CookHub)TS 线有意不继承:拒绝隐式写生产。
3
+ import { mkdirSync } from 'node:fs';
4
+ import { tmpdir } from 'node:os';
5
+ import { join, resolve } from 'node:path';
6
+ export const DB_FILENAME = 'chef_data.db';
7
+ export function resolveDbDir() {
8
+ const env = process.env.SKILLS_DB_PATH;
9
+ if (!env) {
10
+ throw new Error('[skill-chef] SKILLS_DB_PATH 未设置:拒绝隐式落盘。' +
11
+ '生产请设置 SKILLS_DB_PATH;测试请传显式 tmp 路径。');
12
+ }
13
+ return env;
14
+ }
15
+ export function resolveDbPath(filename = DB_FILENAME, dir = resolveDbDir()) {
16
+ mkdirSync(dir, { recursive: true });
17
+ return join(dir, filename);
18
+ }
19
+ /** 测试隔离守卫:非 tmp 路径写库须 CHEF_FORCE_PROD=1(bill 哨兵语义的大厨版)。 */
20
+ export function assertWritablePath(dbPath) {
21
+ const forceProd = process.env.CHEF_FORCE_PROD === '1';
22
+ const underTmp = resolve(dbPath).startsWith(resolve(tmpdir()));
23
+ if (!underTmp && !forceProd) {
24
+ throw new Error('[skill-chef] 拒绝写入非 tmp 路径 ' + dbPath + ':测试隔离守卫。' +
25
+ '如确需生产写,请设置 CHEF_FORCE_PROD=1(opt-in 可见)。');
26
+ }
27
+ if (!underTmp && forceProd) {
28
+ console.error('[skill-chef] CHEF_FORCE_PROD=1: 写入 ' + dbPath);
29
+ }
30
+ }
31
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/fetch/paths.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,8DAA8D;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,CAAC,MAAM,WAAW,GAAG,cAAc,CAAC;AAE1C,MAAM,UAAU,YAAY;IAC1B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACvC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,yCAAyC;YACvC,qCAAqC,CACxC,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAAQ,GAAG,WAAW,EAAE,GAAG,GAAG,YAAY,EAAE;IACxE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,GAAG,CAAC;IACtD,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC/D,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,4BAA4B,GAAG,MAAM,GAAG,UAAU;YAChD,0CAA0C,CAC7C,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,QAAQ,IAAI,SAAS,EAAE,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,qCAAqC,GAAG,MAAM,CAAC,CAAC;IAChE,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { buildHelpLookup, lookupWake, type HelpHit } from './lookup.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/help/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC"}