openstoat 0.2.3 → 0.3.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 (41) hide show
  1. package/dist/chunk-VB4FOZ57.js +490 -0
  2. package/dist/chunk-VB4FOZ57.js.map +7 -0
  3. package/dist/dist-AVI5RCKQ.js +520 -0
  4. package/dist/dist-AVI5RCKQ.js.map +7 -0
  5. package/dist/index.js +5561 -60
  6. package/dist/index.js.map +7 -0
  7. package/package.json +19 -9
  8. package/skills/openstoat-planner/SKILL.md +107 -0
  9. package/skills/openstoat-worker/SKILL.md +115 -0
  10. package/dist/agent-manual.d.ts +0 -6
  11. package/dist/agent-manual.d.ts.map +0 -1
  12. package/dist/agent-manual.js +0 -159
  13. package/dist/commands/daemon.d.ts +0 -12
  14. package/dist/commands/daemon.d.ts.map +0 -1
  15. package/dist/commands/daemon.js +0 -85
  16. package/dist/commands/install.d.ts +0 -12
  17. package/dist/commands/install.d.ts.map +0 -1
  18. package/dist/commands/install.js +0 -40
  19. package/dist/commands/project.d.ts +0 -11
  20. package/dist/commands/project.d.ts.map +0 -1
  21. package/dist/commands/project.js +0 -62
  22. package/dist/commands/task.d.ts +0 -11
  23. package/dist/commands/task.d.ts.map +0 -1
  24. package/dist/commands/task.js +0 -212
  25. package/dist/index.d.ts +0 -7
  26. package/dist/index.d.ts.map +0 -1
  27. package/dist/lib/installSkills.d.ts +0 -16
  28. package/dist/lib/installSkills.d.ts.map +0 -1
  29. package/dist/lib/installSkills.js +0 -60
  30. package/dist/lib/prompt.d.ts +0 -5
  31. package/dist/lib/prompt.d.ts.map +0 -1
  32. package/dist/lib/prompt.js +0 -15
  33. package/src/agent-manual.ts +0 -160
  34. package/src/commands/daemon.ts +0 -94
  35. package/src/commands/install.ts +0 -45
  36. package/src/commands/project.ts +0 -71
  37. package/src/commands/task.ts +0 -254
  38. package/src/index.ts +0 -71
  39. package/src/lib/installSkills.ts +0 -76
  40. package/src/lib/prompt.ts +0 -17
  41. package/tsconfig.json +0 -9
@@ -0,0 +1,490 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // ../openstoat-core/dist/db.js
9
+ import { Database } from "bun:sqlite";
10
+ import { join } from "path";
11
+ import { mkdirSync, existsSync } from "fs";
12
+ var OPENSTOAT_DIR = join(process.env.HOME || process.env.USERPROFILE || ".", ".openstoat");
13
+ var DEFAULT_DB_PATH = join(OPENSTOAT_DIR, "openstoat.db");
14
+ var dbInstance = null;
15
+ var dbPathOverride = null;
16
+ function getDbPathInternal() {
17
+ if (dbPathOverride !== null)
18
+ return dbPathOverride;
19
+ return process.env.OPENSTOAT_DB_PATH || DEFAULT_DB_PATH;
20
+ }
21
+ function getDb() {
22
+ if (!dbInstance) {
23
+ const path = getDbPathInternal();
24
+ if (path !== ":memory:") {
25
+ const dir = join(path, "..");
26
+ if (!existsSync(dir)) {
27
+ mkdirSync(dir, { recursive: true });
28
+ }
29
+ }
30
+ dbInstance = new Database(path, { create: true });
31
+ initSchema(dbInstance);
32
+ }
33
+ return dbInstance;
34
+ }
35
+ function initSchema(db) {
36
+ db.run(`
37
+ CREATE TABLE IF NOT EXISTS projects (
38
+ id TEXT PRIMARY KEY,
39
+ name TEXT NOT NULL,
40
+ template_context TEXT NOT NULL,
41
+ status TEXT DEFAULT 'active' CHECK(status IN ('active', 'archived')),
42
+ created_at TEXT DEFAULT (datetime('now')),
43
+ updated_at TEXT DEFAULT (datetime('now'))
44
+ )
45
+ `);
46
+ db.run(`
47
+ CREATE TABLE IF NOT EXISTS tasks (
48
+ id TEXT PRIMARY KEY,
49
+ project TEXT NOT NULL REFERENCES projects(id),
50
+ title TEXT NOT NULL,
51
+ description TEXT NOT NULL,
52
+ acceptance_criteria TEXT NOT NULL,
53
+ depends_on TEXT NOT NULL,
54
+ status TEXT NOT NULL CHECK(status IN ('ready', 'in_progress', 'done')),
55
+ owner TEXT NOT NULL CHECK(owner IN ('agent_worker', 'human_worker')),
56
+ task_type TEXT NOT NULL CHECK(task_type IN ('implementation', 'testing', 'review', 'credentials', 'deploy', 'docs', 'custom')),
57
+ output TEXT,
58
+ logs TEXT NOT NULL,
59
+ created_by TEXT,
60
+ claimed_by TEXT,
61
+ created_at TEXT DEFAULT (datetime('now')),
62
+ updated_at TEXT DEFAULT (datetime('now'))
63
+ )
64
+ `);
65
+ db.run(`
66
+ CREATE TABLE IF NOT EXISTS handoffs (
67
+ id TEXT PRIMARY KEY,
68
+ from_task_id TEXT NOT NULL REFERENCES tasks(id),
69
+ to_task_id TEXT,
70
+ summary TEXT NOT NULL,
71
+ created_at TEXT DEFAULT (datetime('now'))
72
+ )
73
+ `);
74
+ db.run(`
75
+ CREATE TABLE IF NOT EXISTS config (
76
+ key TEXT PRIMARY KEY,
77
+ value TEXT
78
+ )
79
+ `);
80
+ }
81
+
82
+ // ../openstoat-core/dist/project.js
83
+ function createProject(id, name, template, options) {
84
+ const templateContext = {
85
+ version: "1.0",
86
+ rules: getTemplateRules(template),
87
+ ...options?.workflow_instructions !== void 0 && {
88
+ workflow_instructions: options.workflow_instructions
89
+ }
90
+ };
91
+ const db = getDb();
92
+ const now = (/* @__PURE__ */ new Date()).toISOString();
93
+ db.query(`INSERT INTO projects (id, name, template_context, status, created_at, updated_at)
94
+ VALUES (?, ?, ?, 'active', ?, ?)`).run(id, name, JSON.stringify(templateContext), now, now);
95
+ return {
96
+ id,
97
+ name,
98
+ template_context: templateContext,
99
+ status: "active",
100
+ created_at: now,
101
+ updated_at: now
102
+ };
103
+ }
104
+ function updateProjectWorkflowInstructions(projectId, workflowInstructions) {
105
+ const project = getProject(projectId);
106
+ if (!project)
107
+ return null;
108
+ const updatedContext = {
109
+ ...project.template_context,
110
+ workflow_instructions: workflowInstructions
111
+ };
112
+ const db = getDb();
113
+ const now = (/* @__PURE__ */ new Date()).toISOString();
114
+ db.query(`UPDATE projects SET template_context = ?, updated_at = ? WHERE id = ?`).run(JSON.stringify(updatedContext), now, projectId);
115
+ return {
116
+ ...project,
117
+ template_context: updatedContext,
118
+ updated_at: now
119
+ };
120
+ }
121
+ function getTemplateRules(template) {
122
+ const rules = [
123
+ { task_type: "credentials", default_owner: "human_worker" },
124
+ { task_type: "implementation", default_owner: "agent_worker" },
125
+ { task_type: "testing", default_owner: "agent_worker" },
126
+ { task_type: "review", default_owner: "human_worker" },
127
+ { task_type: "deploy", default_owner: "human_worker" },
128
+ { task_type: "docs", default_owner: "agent_worker" },
129
+ { task_type: "custom", default_owner: "agent_worker" }
130
+ ];
131
+ return rules;
132
+ }
133
+ function getProject(id) {
134
+ const db = getDb();
135
+ const row = db.query("SELECT * FROM projects WHERE id = ?").get(id);
136
+ if (!row)
137
+ return null;
138
+ return {
139
+ id: row.id,
140
+ name: row.name,
141
+ template_context: JSON.parse(row.template_context),
142
+ status: row.status,
143
+ created_at: row.created_at,
144
+ updated_at: row.updated_at
145
+ };
146
+ }
147
+ function listProjects() {
148
+ const db = getDb();
149
+ const rows = db.query("SELECT * FROM projects ORDER BY created_at DESC").all();
150
+ return rows.map((row) => ({
151
+ id: row.id,
152
+ name: row.name,
153
+ template_context: JSON.parse(row.template_context),
154
+ status: row.status,
155
+ created_at: row.created_at,
156
+ updated_at: row.updated_at
157
+ }));
158
+ }
159
+
160
+ // ../openstoat-core/dist/handoff.js
161
+ function generateHandoffId() {
162
+ const db = getDb();
163
+ const count = db.query("SELECT COUNT(*) as c FROM handoffs").get();
164
+ return `handoff_${String((count?.c ?? 0) + 1).padStart(3, "0")}`;
165
+ }
166
+ function createHandoff(input) {
167
+ const db = getDb();
168
+ const id = generateHandoffId();
169
+ db.query(`INSERT INTO handoffs (id, from_task_id, to_task_id, summary) VALUES (?, ?, ?, ?)`).run(id, input.from_task_id, input.to_task_id, input.summary);
170
+ }
171
+ function listHandoffs(options) {
172
+ const db = getDb();
173
+ let sql = "SELECT * FROM handoffs WHERE 1=1";
174
+ const params = [];
175
+ if (options?.from_task_id) {
176
+ sql += " AND from_task_id = ?";
177
+ params.push(options.from_task_id);
178
+ }
179
+ if (options?.to_task_id !== void 0) {
180
+ if (options.to_task_id === null) {
181
+ sql += " AND to_task_id IS NULL";
182
+ } else {
183
+ sql += " AND to_task_id = ?";
184
+ params.push(options.to_task_id);
185
+ }
186
+ }
187
+ sql += " ORDER BY created_at DESC";
188
+ const rows = db.query(sql).all(...params);
189
+ return rows.map((row) => ({
190
+ id: row.id,
191
+ from_task_id: row.from_task_id,
192
+ to_task_id: row.to_task_id,
193
+ summary: row.summary,
194
+ created_at: row.created_at
195
+ }));
196
+ }
197
+ function getDownstreamTaskIds(fromTaskId) {
198
+ const db = getDb();
199
+ const rows = db.query("SELECT id FROM tasks WHERE depends_on LIKE ?").all(`%"${fromTaskId}"%`);
200
+ return rows.map((r) => r.id).filter((id) => {
201
+ const task = db.query("SELECT depends_on FROM tasks WHERE id = ?").get(id);
202
+ if (!task)
203
+ return false;
204
+ const deps = JSON.parse(task.depends_on || "[]");
205
+ return deps.includes(fromTaskId);
206
+ });
207
+ }
208
+
209
+ // ../openstoat-core/dist/task.js
210
+ var MIN_HANDOFF_LENGTH = 200;
211
+ function generateTaskId(project) {
212
+ const db = getDb();
213
+ const count = db.query("SELECT COUNT(*) as c FROM tasks WHERE project = ?").get(project);
214
+ return `task_${String((count?.c ?? 0) + 1).padStart(3, "0")}`;
215
+ }
216
+ function createTask(input) {
217
+ const project = getProject(input.project);
218
+ if (!project) {
219
+ throw new Error(`Project '${input.project}' does not exist`);
220
+ }
221
+ const db = getDb();
222
+ const id = generateTaskId(input.project);
223
+ const now = (/* @__PURE__ */ new Date()).toISOString();
224
+ const dependsOn = input.depends_on ?? [];
225
+ for (const depId of dependsOn) {
226
+ const dep = db.query("SELECT id FROM tasks WHERE id = ?").get(depId);
227
+ if (!dep) {
228
+ throw new Error(`Dependency task '${depId}' does not exist`);
229
+ }
230
+ }
231
+ db.query(`INSERT INTO tasks (id, project, title, description, acceptance_criteria, depends_on, status, owner, task_type, output, logs, created_by, claimed_by, created_at, updated_at)
232
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, '[]', ?, NULL, ?, ?)`).run(id, input.project, input.title, input.description, JSON.stringify(input.acceptance_criteria), JSON.stringify(dependsOn), input.status, input.owner, input.task_type, input.created_by ?? null, now, now);
233
+ return getTask(id);
234
+ }
235
+ function getTask(id) {
236
+ const db = getDb();
237
+ const row = db.query("SELECT * FROM tasks WHERE id = ?").get(id);
238
+ if (!row)
239
+ return null;
240
+ return rowToTask(row);
241
+ }
242
+ function listTasks(project, options) {
243
+ const db = getDb();
244
+ let sql = "SELECT * FROM tasks WHERE 1=1";
245
+ const params = [];
246
+ if (project) {
247
+ sql += " AND project = ?";
248
+ params.push(project);
249
+ }
250
+ if (options?.status?.length) {
251
+ sql += ` AND status IN (${options.status.map(() => "?").join(",")})`;
252
+ params.push(...options.status);
253
+ }
254
+ if (options?.owner) {
255
+ sql += " AND owner = ?";
256
+ params.push(options.owner);
257
+ }
258
+ if (options?.task_type) {
259
+ sql += " AND task_type = ?";
260
+ params.push(options.task_type);
261
+ }
262
+ sql += " ORDER BY project ASC, created_at ASC";
263
+ const rows = db.query(sql).all(...params);
264
+ return rows.map(rowToTask);
265
+ }
266
+ function rowToTask(row) {
267
+ return {
268
+ id: row.id,
269
+ project: row.project,
270
+ title: row.title,
271
+ description: row.description,
272
+ acceptance_criteria: JSON.parse(row.acceptance_criteria || "[]"),
273
+ depends_on: JSON.parse(row.depends_on || "[]"),
274
+ status: row.status,
275
+ owner: row.owner,
276
+ task_type: row.task_type,
277
+ output: row.output || null,
278
+ logs: JSON.parse(row.logs || "[]"),
279
+ created_by: row.created_by || null,
280
+ claimed_by: row.claimed_by || null,
281
+ created_at: row.created_at,
282
+ updated_at: row.updated_at
283
+ };
284
+ }
285
+ function updateTask(id, updates) {
286
+ const db = getDb();
287
+ const now = (/* @__PURE__ */ new Date()).toISOString();
288
+ const setClauses = ["updated_at = ?"];
289
+ const params = [now];
290
+ if (updates.status !== void 0) {
291
+ setClauses.push("status = ?");
292
+ params.push(updates.status);
293
+ }
294
+ if (updates.output !== void 0) {
295
+ setClauses.push("output = ?");
296
+ params.push(updates.output);
297
+ }
298
+ if (updates.logs !== void 0) {
299
+ setClauses.push("logs = ?");
300
+ params.push(JSON.stringify(updates.logs));
301
+ }
302
+ if (updates.claimed_by !== void 0) {
303
+ setClauses.push("claimed_by = ?");
304
+ params.push(updates.claimed_by);
305
+ }
306
+ params.push(id);
307
+ db.query(`UPDATE tasks SET ${setClauses.join(", ")} WHERE id = ?`).run(...params);
308
+ }
309
+ function appendLogs(id, log) {
310
+ const task = getTask(id);
311
+ if (!task)
312
+ throw new Error(`Task '${id}' not found`);
313
+ const logs = [...task.logs, log];
314
+ updateTask(id, { logs });
315
+ }
316
+ function areDependenciesSatisfied(task) {
317
+ if (task.depends_on.length === 0)
318
+ return true;
319
+ const db = getDb();
320
+ for (const depId of task.depends_on) {
321
+ const dep = db.query("SELECT status FROM tasks WHERE id = ?").get(depId);
322
+ if (!dep || dep.status !== "done")
323
+ return false;
324
+ }
325
+ return true;
326
+ }
327
+ function claimTask(taskId, as, logsAppend) {
328
+ const task = getTask(taskId);
329
+ if (!task)
330
+ throw new Error(`Task '${taskId}' not found`);
331
+ if (task.status !== "ready") {
332
+ throw new Error(`Task '${taskId}' is not ready to claim (status: ${task.status})`);
333
+ }
334
+ if (task.owner !== as) {
335
+ throw new Error(`Owner mismatch: task owner is ${task.owner}, claimer is ${as}`);
336
+ }
337
+ if (!areDependenciesSatisfied(task)) {
338
+ throw new Error(`Task '${taskId}' has unsatisfied dependencies`);
339
+ }
340
+ const logs = [...task.logs];
341
+ if (logsAppend)
342
+ logs.push(logsAppend);
343
+ updateTask(taskId, {
344
+ status: "in_progress",
345
+ claimed_by: as,
346
+ logs
347
+ });
348
+ return getTask(taskId);
349
+ }
350
+ function startTask(taskId, as, logsAppend) {
351
+ const task = getTask(taskId);
352
+ if (!task)
353
+ throw new Error(`Task '${taskId}' not found`);
354
+ if (task.status !== "in_progress") {
355
+ throw new Error(`Task '${taskId}' is not in progress (status: ${task.status})`);
356
+ }
357
+ if (task.claimed_by !== as) {
358
+ throw new Error(`Task '${taskId}' was claimed by ${task.claimed_by}, not ${as}`);
359
+ }
360
+ if (logsAppend)
361
+ appendLogs(taskId, logsAppend);
362
+ return getTask(taskId);
363
+ }
364
+ function completeTask(taskId, input, as) {
365
+ const task = getTask(taskId);
366
+ if (!task)
367
+ throw new Error(`Task '${taskId}' not found`);
368
+ if (task.status !== "in_progress") {
369
+ throw new Error(`Task '${taskId}' is not in progress (status: ${task.status})`);
370
+ }
371
+ if (task.claimed_by !== as) {
372
+ throw new Error(`Task '${taskId}' was claimed by ${task.claimed_by}, not ${as}`);
373
+ }
374
+ if (input.handoff_summary.length < MIN_HANDOFF_LENGTH) {
375
+ throw new Error(`Handoff summary must be at least ${MIN_HANDOFF_LENGTH} characters (got ${input.handoff_summary.length})`);
376
+ }
377
+ const downstreamIds = getDownstreamTaskIds(taskId);
378
+ if (downstreamIds.length > 0) {
379
+ for (const toTaskId of downstreamIds) {
380
+ createHandoff({
381
+ from_task_id: taskId,
382
+ to_task_id: toTaskId,
383
+ summary: input.handoff_summary
384
+ });
385
+ }
386
+ } else {
387
+ createHandoff({
388
+ from_task_id: taskId,
389
+ to_task_id: null,
390
+ summary: input.handoff_summary
391
+ });
392
+ }
393
+ const logs = [...task.logs];
394
+ if (input.logs_append)
395
+ logs.push(input.logs_append);
396
+ updateTask(taskId, {
397
+ status: "done",
398
+ output: input.output,
399
+ logs
400
+ });
401
+ for (const downstreamId of downstreamIds) {
402
+ const downstream = getTask(downstreamId);
403
+ if (downstream && downstream.status !== "done" && areDependenciesSatisfied(downstream)) {
404
+ updateTask(downstreamId, { status: "ready" });
405
+ }
406
+ }
407
+ return getTask(taskId);
408
+ }
409
+ function selfUnblockTask(taskId, input, as) {
410
+ const task = getTask(taskId);
411
+ if (!task)
412
+ throw new Error(`Task '${taskId}' not found`);
413
+ if (task.status !== "in_progress") {
414
+ throw new Error(`Task '${taskId}' is not in progress (status: ${task.status})`);
415
+ }
416
+ if (task.owner !== "agent_worker" || as !== "agent_worker") {
417
+ throw new Error("Self-unblock is only for agent_worker tasks");
418
+ }
419
+ if (!input.depends_on || input.depends_on.length === 0) {
420
+ throw new Error("Self-unblock requires at least one --depends-on (new human task)");
421
+ }
422
+ const db = getDb();
423
+ for (const depId of input.depends_on) {
424
+ const dep = db.query("SELECT id, owner FROM tasks WHERE id = ?").get(depId);
425
+ if (!dep)
426
+ throw new Error(`Dependency task '${depId}' does not exist`);
427
+ if (dep.owner !== "human_worker") {
428
+ throw new Error(`Self-unblock depends_on must reference human_worker tasks; '${depId}' is ${dep.owner}`);
429
+ }
430
+ }
431
+ const newDeps = input.depends_on.filter((d) => !task.depends_on.includes(d));
432
+ if (newDeps.length === 0) {
433
+ throw new Error("Self-unblock must add at least one new dependency (human task)");
434
+ }
435
+ const mergedDependsOn = [.../* @__PURE__ */ new Set([...task.depends_on, ...input.depends_on])];
436
+ db.query(`UPDATE tasks SET depends_on = ?, status = 'ready', claimed_by = NULL, updated_at = ? WHERE id = ?`).run(JSON.stringify(mergedDependsOn), (/* @__PURE__ */ new Date()).toISOString(), taskId);
437
+ if (input.logs_append)
438
+ appendLogs(taskId, input.logs_append);
439
+ return getTask(taskId);
440
+ }
441
+
442
+ // ../openstoat-core/dist/projectConfig.js
443
+ import { readFileSync, writeFileSync, existsSync as existsSync2 } from "fs";
444
+ import { join as join2 } from "path";
445
+ var CONFIG_FILENAME = ".openstoat.json";
446
+ function loadProjectConfig(cwd) {
447
+ const dir = cwd ?? process.cwd();
448
+ const path = join2(dir, CONFIG_FILENAME);
449
+ if (!existsSync2(path))
450
+ return null;
451
+ try {
452
+ const raw = readFileSync(path, "utf-8");
453
+ const parsed = JSON.parse(raw);
454
+ if (typeof parsed !== "object" || parsed === null)
455
+ return null;
456
+ const project = typeof parsed.project === "string" ? parsed.project : void 0;
457
+ const agent = typeof parsed.agent === "string" ? parsed.agent : void 0;
458
+ const agent_args_template = typeof parsed.agent_args_template === "string" ? parsed.agent_args_template : void 0;
459
+ return { project, agent, agent_args_template };
460
+ } catch {
461
+ return null;
462
+ }
463
+ }
464
+ function saveProjectConfig(config, cwd) {
465
+ const dir = cwd ?? process.cwd();
466
+ const path = join2(dir, CONFIG_FILENAME);
467
+ const content = JSON.stringify(config, null, 2) + "\n";
468
+ writeFileSync(path, content, "utf-8");
469
+ }
470
+
471
+ export {
472
+ __require,
473
+ getDb,
474
+ loadProjectConfig,
475
+ saveProjectConfig,
476
+ createProject,
477
+ updateProjectWorkflowInstructions,
478
+ getProject,
479
+ listProjects,
480
+ listHandoffs,
481
+ createTask,
482
+ getTask,
483
+ listTasks,
484
+ areDependenciesSatisfied,
485
+ claimTask,
486
+ startTask,
487
+ completeTask,
488
+ selfUnblockTask
489
+ };
490
+ //# sourceMappingURL=chunk-VB4FOZ57.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../openstoat-core/dist/db.js", "../../openstoat-core/dist/project.js", "../../openstoat-core/dist/handoff.js", "../../openstoat-core/dist/task.js", "../../openstoat-core/dist/projectConfig.js"],
4
+ "sourcesContent": ["/**\n * SQLite database connection and schema initialization\n * Storage location: ~/.openstoat/openstoat.db\n */\nimport { Database } from 'bun:sqlite';\nimport { join } from 'path';\nimport { mkdirSync, existsSync } from 'fs';\nconst OPENSTOAT_DIR = join(process.env.HOME || process.env.USERPROFILE || '.', '.openstoat');\nconst DEFAULT_DB_PATH = join(OPENSTOAT_DIR, 'openstoat.db');\nlet dbInstance = null;\nlet dbPathOverride = null;\nfunction ensureDir() {\n if (!existsSync(OPENSTOAT_DIR)) {\n mkdirSync(OPENSTOAT_DIR, { recursive: true });\n }\n}\nfunction getDbPathInternal() {\n if (dbPathOverride !== null)\n return dbPathOverride;\n return process.env.OPENSTOAT_DB_PATH || DEFAULT_DB_PATH;\n}\nexport function getDb() {\n if (!dbInstance) {\n const path = getDbPathInternal();\n if (path !== ':memory:') {\n const dir = join(path, '..');\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n }\n dbInstance = new Database(path, { create: true });\n initSchema(dbInstance);\n }\n return dbInstance;\n}\nexport function getDbPath() {\n return getDbPathInternal();\n}\nexport function setDbPath(path) {\n if (dbInstance) {\n dbInstance.close();\n dbInstance = null;\n }\n dbPathOverride = path;\n // Re-initialize with new path when setDbPath is called (e.g. in tests)\n getDb();\n}\nexport function closeDb() {\n if (dbInstance) {\n dbInstance.close();\n dbInstance = null;\n }\n}\nfunction initSchema(db) {\n db.run(`\n CREATE TABLE IF NOT EXISTS projects (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n template_context TEXT NOT NULL,\n status TEXT DEFAULT 'active' CHECK(status IN ('active', 'archived')),\n created_at TEXT DEFAULT (datetime('now')),\n updated_at TEXT DEFAULT (datetime('now'))\n )\n `);\n db.run(`\n CREATE TABLE IF NOT EXISTS tasks (\n id TEXT PRIMARY KEY,\n project TEXT NOT NULL REFERENCES projects(id),\n title TEXT NOT NULL,\n description TEXT NOT NULL,\n acceptance_criteria TEXT NOT NULL,\n depends_on TEXT NOT NULL,\n status TEXT NOT NULL CHECK(status IN ('ready', 'in_progress', 'done')),\n owner TEXT NOT NULL CHECK(owner IN ('agent_worker', 'human_worker')),\n task_type TEXT NOT NULL CHECK(task_type IN ('implementation', 'testing', 'review', 'credentials', 'deploy', 'docs', 'custom')),\n output TEXT,\n logs TEXT NOT NULL,\n created_by TEXT,\n claimed_by TEXT,\n created_at TEXT DEFAULT (datetime('now')),\n updated_at TEXT DEFAULT (datetime('now'))\n )\n `);\n db.run(`\n CREATE TABLE IF NOT EXISTS handoffs (\n id TEXT PRIMARY KEY,\n from_task_id TEXT NOT NULL REFERENCES tasks(id),\n to_task_id TEXT,\n summary TEXT NOT NULL,\n created_at TEXT DEFAULT (datetime('now'))\n )\n `);\n db.run(`\n CREATE TABLE IF NOT EXISTS config (\n key TEXT PRIMARY KEY,\n value TEXT\n )\n `);\n}\n", "/**\n * Project model (template-bound)\n */\nimport { getDb } from './db.js';\nexport function createProject(id, name, template, options) {\n const templateContext = {\n version: '1.0',\n rules: getTemplateRules(template),\n ...(options?.workflow_instructions !== undefined && {\n workflow_instructions: options.workflow_instructions,\n }),\n };\n const db = getDb();\n const now = new Date().toISOString();\n db.query(`INSERT INTO projects (id, name, template_context, status, created_at, updated_at)\n VALUES (?, ?, ?, 'active', ?, ?)`).run(id, name, JSON.stringify(templateContext), now, now);\n return {\n id,\n name,\n template_context: templateContext,\n status: 'active',\n created_at: now,\n updated_at: now,\n };\n}\nexport function updateProjectWorkflowInstructions(projectId, workflowInstructions) {\n const project = getProject(projectId);\n if (!project)\n return null;\n const updatedContext = {\n ...project.template_context,\n workflow_instructions: workflowInstructions,\n };\n const db = getDb();\n const now = new Date().toISOString();\n db.query(`UPDATE projects SET template_context = ?, updated_at = ? WHERE id = ?`).run(JSON.stringify(updatedContext), now, projectId);\n return {\n ...project,\n template_context: updatedContext,\n updated_at: now,\n };\n}\nfunction getTemplateRules(template) {\n // Default template rules; can be extended for named templates\n const rules = [\n { task_type: 'credentials', default_owner: 'human_worker' },\n { task_type: 'implementation', default_owner: 'agent_worker' },\n { task_type: 'testing', default_owner: 'agent_worker' },\n { task_type: 'review', default_owner: 'human_worker' },\n { task_type: 'deploy', default_owner: 'human_worker' },\n { task_type: 'docs', default_owner: 'agent_worker' },\n { task_type: 'custom', default_owner: 'agent_worker' },\n ];\n return rules;\n}\nexport function getProject(id) {\n const db = getDb();\n const row = db.query('SELECT * FROM projects WHERE id = ?').get(id);\n if (!row)\n return null;\n return {\n id: row.id,\n name: row.name,\n template_context: JSON.parse(row.template_context),\n status: row.status,\n created_at: row.created_at,\n updated_at: row.updated_at,\n };\n}\nexport function listProjects() {\n const db = getDb();\n const rows = db.query('SELECT * FROM projects ORDER BY created_at DESC').all();\n return rows.map((row) => ({\n id: row.id,\n name: row.name,\n template_context: JSON.parse(row.template_context),\n status: row.status,\n created_at: row.created_at,\n updated_at: row.updated_at,\n }));\n}\n", "/**\n * Handoff model - context transfer between completed and downstream tasks\n */\nimport { getDb } from './db.js';\nfunction generateHandoffId() {\n const db = getDb();\n const count = db.query('SELECT COUNT(*) as c FROM handoffs').get();\n return `handoff_${String((count?.c ?? 0) + 1).padStart(3, '0')}`;\n}\nexport function createHandoff(input) {\n const db = getDb();\n const id = generateHandoffId();\n db.query(`INSERT INTO handoffs (id, from_task_id, to_task_id, summary) VALUES (?, ?, ?, ?)`).run(id, input.from_task_id, input.to_task_id, input.summary);\n}\nexport function listHandoffs(options) {\n const db = getDb();\n let sql = 'SELECT * FROM handoffs WHERE 1=1';\n const params = [];\n if (options?.from_task_id) {\n sql += ' AND from_task_id = ?';\n params.push(options.from_task_id);\n }\n if (options?.to_task_id !== undefined) {\n if (options.to_task_id === null) {\n sql += ' AND to_task_id IS NULL';\n }\n else {\n sql += ' AND to_task_id = ?';\n params.push(options.to_task_id);\n }\n }\n sql += ' ORDER BY created_at DESC';\n const rows = db.query(sql).all(...params);\n return rows.map((row) => ({\n id: row.id,\n from_task_id: row.from_task_id,\n to_task_id: row.to_task_id,\n summary: row.summary,\n created_at: row.created_at,\n }));\n}\nexport function getDownstreamTaskIds(fromTaskId) {\n const db = getDb();\n const rows = db\n .query('SELECT id FROM tasks WHERE depends_on LIKE ?')\n .all(`%\"${fromTaskId}\"%`);\n return rows\n .map((r) => r.id)\n .filter((id) => {\n const task = db.query('SELECT depends_on FROM tasks WHERE id = ?').get(id);\n if (!task)\n return false;\n const deps = JSON.parse(task.depends_on || '[]');\n return deps.includes(fromTaskId);\n });\n}\n", "/**\n * Task model and Kanban operations\n */\nimport { getDb } from './db.js';\nimport { getProject } from './project.js';\nimport { createHandoff, getDownstreamTaskIds } from './handoff.js';\nconst MIN_HANDOFF_LENGTH = 200;\nfunction generateTaskId(project) {\n const db = getDb();\n const count = db.query('SELECT COUNT(*) as c FROM tasks WHERE project = ?').get(project);\n return `task_${String((count?.c ?? 0) + 1).padStart(3, '0')}`;\n}\nexport function createTask(input) {\n const project = getProject(input.project);\n if (!project) {\n throw new Error(`Project '${input.project}' does not exist`);\n }\n const db = getDb();\n const id = generateTaskId(input.project);\n const now = new Date().toISOString();\n const dependsOn = input.depends_on ?? [];\n for (const depId of dependsOn) {\n const dep = db.query('SELECT id FROM tasks WHERE id = ?').get(depId);\n if (!dep) {\n throw new Error(`Dependency task '${depId}' does not exist`);\n }\n }\n db.query(`INSERT INTO tasks (id, project, title, description, acceptance_criteria, depends_on, status, owner, task_type, output, logs, created_by, claimed_by, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, '[]', ?, NULL, ?, ?)`).run(id, input.project, input.title, input.description, JSON.stringify(input.acceptance_criteria), JSON.stringify(dependsOn), input.status, input.owner, input.task_type, input.created_by ?? null, now, now);\n return getTask(id);\n}\nexport function getTask(id) {\n const db = getDb();\n const row = db.query('SELECT * FROM tasks WHERE id = ?').get(id);\n if (!row)\n return null;\n return rowToTask(row);\n}\nexport function listTasks(project, options) {\n const db = getDb();\n let sql = 'SELECT * FROM tasks WHERE 1=1';\n const params = [];\n if (project) {\n sql += ' AND project = ?';\n params.push(project);\n }\n if (options?.status?.length) {\n sql += ` AND status IN (${options.status.map(() => '?').join(',')})`;\n params.push(...options.status);\n }\n if (options?.owner) {\n sql += ' AND owner = ?';\n params.push(options.owner);\n }\n if (options?.task_type) {\n sql += ' AND task_type = ?';\n params.push(options.task_type);\n }\n sql += ' ORDER BY project ASC, created_at ASC';\n const rows = db.query(sql).all(...params);\n return rows.map(rowToTask);\n}\nfunction rowToTask(row) {\n return {\n id: row.id,\n project: row.project,\n title: row.title,\n description: row.description,\n acceptance_criteria: JSON.parse(row.acceptance_criteria || '[]'),\n depends_on: JSON.parse(row.depends_on || '[]'),\n status: row.status,\n owner: row.owner,\n task_type: row.task_type,\n output: row.output || null,\n logs: JSON.parse(row.logs || '[]'),\n created_by: row.created_by || null,\n claimed_by: row.claimed_by || null,\n created_at: row.created_at,\n updated_at: row.updated_at,\n };\n}\nfunction updateTask(id, updates) {\n const db = getDb();\n const now = new Date().toISOString();\n const setClauses = ['updated_at = ?'];\n const params = [now];\n if (updates.status !== undefined) {\n setClauses.push('status = ?');\n params.push(updates.status);\n }\n if (updates.output !== undefined) {\n setClauses.push('output = ?');\n params.push(updates.output);\n }\n if (updates.logs !== undefined) {\n setClauses.push('logs = ?');\n params.push(JSON.stringify(updates.logs));\n }\n if (updates.claimed_by !== undefined) {\n setClauses.push('claimed_by = ?');\n params.push(updates.claimed_by);\n }\n params.push(id);\n db.query(`UPDATE tasks SET ${setClauses.join(', ')} WHERE id = ?`).run(...params);\n}\nfunction appendLogs(id, log) {\n const task = getTask(id);\n if (!task)\n throw new Error(`Task '${id}' not found`);\n const logs = [...task.logs, log];\n updateTask(id, { logs });\n}\nexport function areDependenciesSatisfied(task) {\n if (task.depends_on.length === 0)\n return true;\n const db = getDb();\n for (const depId of task.depends_on) {\n const dep = db.query('SELECT status FROM tasks WHERE id = ?').get(depId);\n if (!dep || dep.status !== 'done')\n return false;\n }\n return true;\n}\nexport function claimTask(taskId, as, logsAppend) {\n const task = getTask(taskId);\n if (!task)\n throw new Error(`Task '${taskId}' not found`);\n if (task.status !== 'ready') {\n throw new Error(`Task '${taskId}' is not ready to claim (status: ${task.status})`);\n }\n if (task.owner !== as) {\n throw new Error(`Owner mismatch: task owner is ${task.owner}, claimer is ${as}`);\n }\n if (!areDependenciesSatisfied(task)) {\n throw new Error(`Task '${taskId}' has unsatisfied dependencies`);\n }\n const logs = [...task.logs];\n if (logsAppend)\n logs.push(logsAppend);\n updateTask(taskId, {\n status: 'in_progress',\n claimed_by: as,\n logs,\n });\n return getTask(taskId);\n}\nexport function startTask(taskId, as, logsAppend) {\n const task = getTask(taskId);\n if (!task)\n throw new Error(`Task '${taskId}' not found`);\n if (task.status !== 'in_progress') {\n throw new Error(`Task '${taskId}' is not in progress (status: ${task.status})`);\n }\n if (task.claimed_by !== as) {\n throw new Error(`Task '${taskId}' was claimed by ${task.claimed_by}, not ${as}`);\n }\n if (logsAppend)\n appendLogs(taskId, logsAppend);\n return getTask(taskId);\n}\nexport function completeTask(taskId, input, as) {\n const task = getTask(taskId);\n if (!task)\n throw new Error(`Task '${taskId}' not found`);\n if (task.status !== 'in_progress') {\n throw new Error(`Task '${taskId}' is not in progress (status: ${task.status})`);\n }\n if (task.claimed_by !== as) {\n throw new Error(`Task '${taskId}' was claimed by ${task.claimed_by}, not ${as}`);\n }\n if (input.handoff_summary.length < MIN_HANDOFF_LENGTH) {\n throw new Error(`Handoff summary must be at least ${MIN_HANDOFF_LENGTH} characters (got ${input.handoff_summary.length})`);\n }\n const downstreamIds = getDownstreamTaskIds(taskId);\n if (downstreamIds.length > 0) {\n for (const toTaskId of downstreamIds) {\n createHandoff({\n from_task_id: taskId,\n to_task_id: toTaskId,\n summary: input.handoff_summary,\n });\n }\n }\n else {\n createHandoff({\n from_task_id: taskId,\n to_task_id: null,\n summary: input.handoff_summary,\n });\n }\n const logs = [...task.logs];\n if (input.logs_append)\n logs.push(input.logs_append);\n updateTask(taskId, {\n status: 'done',\n output: input.output,\n logs,\n });\n // Re-evaluate downstream tasks - they may become ready\n for (const downstreamId of downstreamIds) {\n const downstream = getTask(downstreamId);\n if (downstream && downstream.status !== 'done' && areDependenciesSatisfied(downstream)) {\n updateTask(downstreamId, { status: 'ready' });\n }\n }\n return getTask(taskId);\n}\nexport function selfUnblockTask(taskId, input, as) {\n const task = getTask(taskId);\n if (!task)\n throw new Error(`Task '${taskId}' not found`);\n if (task.status !== 'in_progress') {\n throw new Error(`Task '${taskId}' is not in progress (status: ${task.status})`);\n }\n if (task.owner !== 'agent_worker' || as !== 'agent_worker') {\n throw new Error('Self-unblock is only for agent_worker tasks');\n }\n if (!input.depends_on || input.depends_on.length === 0) {\n throw new Error('Self-unblock requires at least one --depends-on (new human task)');\n }\n const db = getDb();\n for (const depId of input.depends_on) {\n const dep = db.query('SELECT id, owner FROM tasks WHERE id = ?').get(depId);\n if (!dep)\n throw new Error(`Dependency task '${depId}' does not exist`);\n if (dep.owner !== 'human_worker') {\n throw new Error(`Self-unblock depends_on must reference human_worker tasks; '${depId}' is ${dep.owner}`);\n }\n }\n const newDeps = input.depends_on.filter((d) => !task.depends_on.includes(d));\n if (newDeps.length === 0) {\n throw new Error('Self-unblock must add at least one new dependency (human task)');\n }\n const mergedDependsOn = [...new Set([...task.depends_on, ...input.depends_on])];\n db.query(`UPDATE tasks SET depends_on = ?, status = 'ready', claimed_by = NULL, updated_at = ? WHERE id = ?`).run(JSON.stringify(mergedDependsOn), new Date().toISOString(), taskId);\n if (input.logs_append)\n appendLogs(taskId, input.logs_append);\n return getTask(taskId);\n}\n", "/**\n * Project-local config from .openstoat.json in current directory.\n * Daemon reads agent path from here. Skills use project ID for task commands.\n */\nimport { readFileSync, writeFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nconst CONFIG_FILENAME = '.openstoat.json';\n/**\n * Load .openstoat.json from the given directory (default: process.cwd()).\n * Returns null if file does not exist or is invalid.\n */\nexport function loadProjectConfig(cwd) {\n const dir = cwd ?? process.cwd();\n const path = join(dir, CONFIG_FILENAME);\n if (!existsSync(path))\n return null;\n try {\n const raw = readFileSync(path, 'utf-8');\n const parsed = JSON.parse(raw);\n if (typeof parsed !== 'object' || parsed === null)\n return null;\n const project = typeof parsed.project === 'string' ? parsed.project : undefined;\n const agent = typeof parsed.agent === 'string' ? parsed.agent : undefined;\n const agent_args_template = typeof parsed.agent_args_template === 'string' ? parsed.agent_args_template : undefined;\n return { project, agent, agent_args_template };\n }\n catch {\n return null;\n }\n}\n/**\n * Write .openstoat.json to the given directory (default: process.cwd()).\n */\nexport function saveProjectConfig(config, cwd) {\n const dir = cwd ?? process.cwd();\n const path = join(dir, CONFIG_FILENAME);\n const content = JSON.stringify(config, null, 2) + '\\n';\n writeFileSync(path, content, 'utf-8');\n}\n"],
5
+ "mappings": ";;;;;;;;AAIA,SAAS,gBAAgB;AACzB,SAAS,YAAY;AACrB,SAAS,WAAW,kBAAkB;AACtC,IAAM,gBAAgB,KAAK,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe,KAAK,YAAY;AAC3F,IAAM,kBAAkB,KAAK,eAAe,cAAc;AAC1D,IAAI,aAAa;AACjB,IAAI,iBAAiB;AAMrB,SAAS,oBAAoB;AACzB,MAAI,mBAAmB;AACnB,WAAO;AACX,SAAO,QAAQ,IAAI,qBAAqB;AAC5C;AACO,SAAS,QAAQ;AACpB,MAAI,CAAC,YAAY;AACb,UAAM,OAAO,kBAAkB;AAC/B,QAAI,SAAS,YAAY;AACrB,YAAM,MAAM,KAAK,MAAM,IAAI;AAC3B,UAAI,CAAC,WAAW,GAAG,GAAG;AAClB,kBAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,MACtC;AAAA,IACJ;AACA,iBAAa,IAAI,SAAS,MAAM,EAAE,QAAQ,KAAK,CAAC;AAChD,eAAW,UAAU;AAAA,EACzB;AACA,SAAO;AACX;AAmBA,SAAS,WAAW,IAAI;AACpB,KAAG,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASR;AACC,KAAG,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAkBR;AACC,KAAG,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAQR;AACC,KAAG,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,GAKR;AACH;;;AC9FO,SAAS,cAAc,IAAI,MAAM,UAAU,SAAS;AACvD,QAAM,kBAAkB;AAAA,IACpB,SAAS;AAAA,IACT,OAAO,iBAAiB,QAAQ;AAAA,IAChC,GAAI,SAAS,0BAA0B,UAAa;AAAA,MAChD,uBAAuB,QAAQ;AAAA,IACnC;AAAA,EACJ;AACA,QAAM,KAAK,MAAM;AACjB,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,KAAG,MAAM;AAAA,sCACyB,EAAE,IAAI,IAAI,MAAM,KAAK,UAAU,eAAe,GAAG,KAAK,GAAG;AAC3F,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,IAClB,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,YAAY;AAAA,EAChB;AACJ;AACO,SAAS,kCAAkC,WAAW,sBAAsB;AAC/E,QAAM,UAAU,WAAW,SAAS;AACpC,MAAI,CAAC;AACD,WAAO;AACX,QAAM,iBAAiB;AAAA,IACnB,GAAG,QAAQ;AAAA,IACX,uBAAuB;AAAA,EAC3B;AACA,QAAM,KAAK,MAAM;AACjB,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,KAAG,MAAM,uEAAuE,EAAE,IAAI,KAAK,UAAU,cAAc,GAAG,KAAK,SAAS;AACpI,SAAO;AAAA,IACH,GAAG;AAAA,IACH,kBAAkB;AAAA,IAClB,YAAY;AAAA,EAChB;AACJ;AACA,SAAS,iBAAiB,UAAU;AAEhC,QAAM,QAAQ;AAAA,IACV,EAAE,WAAW,eAAe,eAAe,eAAe;AAAA,IAC1D,EAAE,WAAW,kBAAkB,eAAe,eAAe;AAAA,IAC7D,EAAE,WAAW,WAAW,eAAe,eAAe;AAAA,IACtD,EAAE,WAAW,UAAU,eAAe,eAAe;AAAA,IACrD,EAAE,WAAW,UAAU,eAAe,eAAe;AAAA,IACrD,EAAE,WAAW,QAAQ,eAAe,eAAe;AAAA,IACnD,EAAE,WAAW,UAAU,eAAe,eAAe;AAAA,EACzD;AACA,SAAO;AACX;AACO,SAAS,WAAW,IAAI;AAC3B,QAAM,KAAK,MAAM;AACjB,QAAM,MAAM,GAAG,MAAM,qCAAqC,EAAE,IAAI,EAAE;AAClE,MAAI,CAAC;AACD,WAAO;AACX,SAAO;AAAA,IACH,IAAI,IAAI;AAAA,IACR,MAAM,IAAI;AAAA,IACV,kBAAkB,KAAK,MAAM,IAAI,gBAAgB;AAAA,IACjD,QAAQ,IAAI;AAAA,IACZ,YAAY,IAAI;AAAA,IAChB,YAAY,IAAI;AAAA,EACpB;AACJ;AACO,SAAS,eAAe;AAC3B,QAAM,KAAK,MAAM;AACjB,QAAM,OAAO,GAAG,MAAM,iDAAiD,EAAE,IAAI;AAC7E,SAAO,KAAK,IAAI,CAAC,SAAS;AAAA,IACtB,IAAI,IAAI;AAAA,IACR,MAAM,IAAI;AAAA,IACV,kBAAkB,KAAK,MAAM,IAAI,gBAAgB;AAAA,IACjD,QAAQ,IAAI;AAAA,IACZ,YAAY,IAAI;AAAA,IAChB,YAAY,IAAI;AAAA,EACpB,EAAE;AACN;;;AC5EA,SAAS,oBAAoB;AACzB,QAAM,KAAK,MAAM;AACjB,QAAM,QAAQ,GAAG,MAAM,oCAAoC,EAAE,IAAI;AACjE,SAAO,WAAW,QAAQ,OAAO,KAAK,KAAK,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC;AAClE;AACO,SAAS,cAAc,OAAO;AACjC,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,kBAAkB;AAC7B,KAAG,MAAM,kFAAkF,EAAE,IAAI,IAAI,MAAM,cAAc,MAAM,YAAY,MAAM,OAAO;AAC5J;AACO,SAAS,aAAa,SAAS;AAClC,QAAM,KAAK,MAAM;AACjB,MAAI,MAAM;AACV,QAAM,SAAS,CAAC;AAChB,MAAI,SAAS,cAAc;AACvB,WAAO;AACP,WAAO,KAAK,QAAQ,YAAY;AAAA,EACpC;AACA,MAAI,SAAS,eAAe,QAAW;AACnC,QAAI,QAAQ,eAAe,MAAM;AAC7B,aAAO;AAAA,IACX,OACK;AACD,aAAO;AACP,aAAO,KAAK,QAAQ,UAAU;AAAA,IAClC;AAAA,EACJ;AACA,SAAO;AACP,QAAM,OAAO,GAAG,MAAM,GAAG,EAAE,IAAI,GAAG,MAAM;AACxC,SAAO,KAAK,IAAI,CAAC,SAAS;AAAA,IACtB,IAAI,IAAI;AAAA,IACR,cAAc,IAAI;AAAA,IAClB,YAAY,IAAI;AAAA,IAChB,SAAS,IAAI;AAAA,IACb,YAAY,IAAI;AAAA,EACpB,EAAE;AACN;AACO,SAAS,qBAAqB,YAAY;AAC7C,QAAM,KAAK,MAAM;AACjB,QAAM,OAAO,GACR,MAAM,8CAA8C,EACpD,IAAI,KAAK,UAAU,IAAI;AAC5B,SAAO,KACF,IAAI,CAAC,MAAM,EAAE,EAAE,EACf,OAAO,CAAC,OAAO;AAChB,UAAM,OAAO,GAAG,MAAM,2CAA2C,EAAE,IAAI,EAAE;AACzE,QAAI,CAAC;AACD,aAAO;AACX,UAAM,OAAO,KAAK,MAAM,KAAK,cAAc,IAAI;AAC/C,WAAO,KAAK,SAAS,UAAU;AAAA,EACnC,CAAC;AACL;;;ACjDA,IAAM,qBAAqB;AAC3B,SAAS,eAAe,SAAS;AAC7B,QAAM,KAAK,MAAM;AACjB,QAAM,QAAQ,GAAG,MAAM,mDAAmD,EAAE,IAAI,OAAO;AACvF,SAAO,QAAQ,QAAQ,OAAO,KAAK,KAAK,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC;AAC/D;AACO,SAAS,WAAW,OAAO;AAC9B,QAAM,UAAU,WAAW,MAAM,OAAO;AACxC,MAAI,CAAC,SAAS;AACV,UAAM,IAAI,MAAM,YAAY,MAAM,OAAO,kBAAkB;AAAA,EAC/D;AACA,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,eAAe,MAAM,OAAO;AACvC,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,QAAM,YAAY,MAAM,cAAc,CAAC;AACvC,aAAW,SAAS,WAAW;AAC3B,UAAM,MAAM,GAAG,MAAM,mCAAmC,EAAE,IAAI,KAAK;AACnE,QAAI,CAAC,KAAK;AACN,YAAM,IAAI,MAAM,oBAAoB,KAAK,kBAAkB;AAAA,IAC/D;AAAA,EACJ;AACA,KAAG,MAAM;AAAA,mEACsD,EAAE,IAAI,IAAI,MAAM,SAAS,MAAM,OAAO,MAAM,aAAa,KAAK,UAAU,MAAM,mBAAmB,GAAG,KAAK,UAAU,SAAS,GAAG,MAAM,QAAQ,MAAM,OAAO,MAAM,WAAW,MAAM,cAAc,MAAM,KAAK,GAAG;AAC5Q,SAAO,QAAQ,EAAE;AACrB;AACO,SAAS,QAAQ,IAAI;AACxB,QAAM,KAAK,MAAM;AACjB,QAAM,MAAM,GAAG,MAAM,kCAAkC,EAAE,IAAI,EAAE;AAC/D,MAAI,CAAC;AACD,WAAO;AACX,SAAO,UAAU,GAAG;AACxB;AACO,SAAS,UAAU,SAAS,SAAS;AACxC,QAAM,KAAK,MAAM;AACjB,MAAI,MAAM;AACV,QAAM,SAAS,CAAC;AAChB,MAAI,SAAS;AACT,WAAO;AACP,WAAO,KAAK,OAAO;AAAA,EACvB;AACA,MAAI,SAAS,QAAQ,QAAQ;AACzB,WAAO,mBAAmB,QAAQ,OAAO,IAAI,MAAM,GAAG,EAAE,KAAK,GAAG,CAAC;AACjE,WAAO,KAAK,GAAG,QAAQ,MAAM;AAAA,EACjC;AACA,MAAI,SAAS,OAAO;AAChB,WAAO;AACP,WAAO,KAAK,QAAQ,KAAK;AAAA,EAC7B;AACA,MAAI,SAAS,WAAW;AACpB,WAAO;AACP,WAAO,KAAK,QAAQ,SAAS;AAAA,EACjC;AACA,SAAO;AACP,QAAM,OAAO,GAAG,MAAM,GAAG,EAAE,IAAI,GAAG,MAAM;AACxC,SAAO,KAAK,IAAI,SAAS;AAC7B;AACA,SAAS,UAAU,KAAK;AACpB,SAAO;AAAA,IACH,IAAI,IAAI;AAAA,IACR,SAAS,IAAI;AAAA,IACb,OAAO,IAAI;AAAA,IACX,aAAa,IAAI;AAAA,IACjB,qBAAqB,KAAK,MAAM,IAAI,uBAAuB,IAAI;AAAA,IAC/D,YAAY,KAAK,MAAM,IAAI,cAAc,IAAI;AAAA,IAC7C,QAAQ,IAAI;AAAA,IACZ,OAAO,IAAI;AAAA,IACX,WAAW,IAAI;AAAA,IACf,QAAQ,IAAI,UAAU;AAAA,IACtB,MAAM,KAAK,MAAM,IAAI,QAAQ,IAAI;AAAA,IACjC,YAAY,IAAI,cAAc;AAAA,IAC9B,YAAY,IAAI,cAAc;AAAA,IAC9B,YAAY,IAAI;AAAA,IAChB,YAAY,IAAI;AAAA,EACpB;AACJ;AACA,SAAS,WAAW,IAAI,SAAS;AAC7B,QAAM,KAAK,MAAM;AACjB,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,QAAM,aAAa,CAAC,gBAAgB;AACpC,QAAM,SAAS,CAAC,GAAG;AACnB,MAAI,QAAQ,WAAW,QAAW;AAC9B,eAAW,KAAK,YAAY;AAC5B,WAAO,KAAK,QAAQ,MAAM;AAAA,EAC9B;AACA,MAAI,QAAQ,WAAW,QAAW;AAC9B,eAAW,KAAK,YAAY;AAC5B,WAAO,KAAK,QAAQ,MAAM;AAAA,EAC9B;AACA,MAAI,QAAQ,SAAS,QAAW;AAC5B,eAAW,KAAK,UAAU;AAC1B,WAAO,KAAK,KAAK,UAAU,QAAQ,IAAI,CAAC;AAAA,EAC5C;AACA,MAAI,QAAQ,eAAe,QAAW;AAClC,eAAW,KAAK,gBAAgB;AAChC,WAAO,KAAK,QAAQ,UAAU;AAAA,EAClC;AACA,SAAO,KAAK,EAAE;AACd,KAAG,MAAM,oBAAoB,WAAW,KAAK,IAAI,CAAC,eAAe,EAAE,IAAI,GAAG,MAAM;AACpF;AACA,SAAS,WAAW,IAAI,KAAK;AACzB,QAAM,OAAO,QAAQ,EAAE;AACvB,MAAI,CAAC;AACD,UAAM,IAAI,MAAM,SAAS,EAAE,aAAa;AAC5C,QAAM,OAAO,CAAC,GAAG,KAAK,MAAM,GAAG;AAC/B,aAAW,IAAI,EAAE,KAAK,CAAC;AAC3B;AACO,SAAS,yBAAyB,MAAM;AAC3C,MAAI,KAAK,WAAW,WAAW;AAC3B,WAAO;AACX,QAAM,KAAK,MAAM;AACjB,aAAW,SAAS,KAAK,YAAY;AACjC,UAAM,MAAM,GAAG,MAAM,uCAAuC,EAAE,IAAI,KAAK;AACvE,QAAI,CAAC,OAAO,IAAI,WAAW;AACvB,aAAO;AAAA,EACf;AACA,SAAO;AACX;AACO,SAAS,UAAU,QAAQ,IAAI,YAAY;AAC9C,QAAM,OAAO,QAAQ,MAAM;AAC3B,MAAI,CAAC;AACD,UAAM,IAAI,MAAM,SAAS,MAAM,aAAa;AAChD,MAAI,KAAK,WAAW,SAAS;AACzB,UAAM,IAAI,MAAM,SAAS,MAAM,oCAAoC,KAAK,MAAM,GAAG;AAAA,EACrF;AACA,MAAI,KAAK,UAAU,IAAI;AACnB,UAAM,IAAI,MAAM,iCAAiC,KAAK,KAAK,gBAAgB,EAAE,EAAE;AAAA,EACnF;AACA,MAAI,CAAC,yBAAyB,IAAI,GAAG;AACjC,UAAM,IAAI,MAAM,SAAS,MAAM,gCAAgC;AAAA,EACnE;AACA,QAAM,OAAO,CAAC,GAAG,KAAK,IAAI;AAC1B,MAAI;AACA,SAAK,KAAK,UAAU;AACxB,aAAW,QAAQ;AAAA,IACf,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ;AAAA,EACJ,CAAC;AACD,SAAO,QAAQ,MAAM;AACzB;AACO,SAAS,UAAU,QAAQ,IAAI,YAAY;AAC9C,QAAM,OAAO,QAAQ,MAAM;AAC3B,MAAI,CAAC;AACD,UAAM,IAAI,MAAM,SAAS,MAAM,aAAa;AAChD,MAAI,KAAK,WAAW,eAAe;AAC/B,UAAM,IAAI,MAAM,SAAS,MAAM,iCAAiC,KAAK,MAAM,GAAG;AAAA,EAClF;AACA,MAAI,KAAK,eAAe,IAAI;AACxB,UAAM,IAAI,MAAM,SAAS,MAAM,oBAAoB,KAAK,UAAU,SAAS,EAAE,EAAE;AAAA,EACnF;AACA,MAAI;AACA,eAAW,QAAQ,UAAU;AACjC,SAAO,QAAQ,MAAM;AACzB;AACO,SAAS,aAAa,QAAQ,OAAO,IAAI;AAC5C,QAAM,OAAO,QAAQ,MAAM;AAC3B,MAAI,CAAC;AACD,UAAM,IAAI,MAAM,SAAS,MAAM,aAAa;AAChD,MAAI,KAAK,WAAW,eAAe;AAC/B,UAAM,IAAI,MAAM,SAAS,MAAM,iCAAiC,KAAK,MAAM,GAAG;AAAA,EAClF;AACA,MAAI,KAAK,eAAe,IAAI;AACxB,UAAM,IAAI,MAAM,SAAS,MAAM,oBAAoB,KAAK,UAAU,SAAS,EAAE,EAAE;AAAA,EACnF;AACA,MAAI,MAAM,gBAAgB,SAAS,oBAAoB;AACnD,UAAM,IAAI,MAAM,oCAAoC,kBAAkB,oBAAoB,MAAM,gBAAgB,MAAM,GAAG;AAAA,EAC7H;AACA,QAAM,gBAAgB,qBAAqB,MAAM;AACjD,MAAI,cAAc,SAAS,GAAG;AAC1B,eAAW,YAAY,eAAe;AAClC,oBAAc;AAAA,QACV,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,SAAS,MAAM;AAAA,MACnB,CAAC;AAAA,IACL;AAAA,EACJ,OACK;AACD,kBAAc;AAAA,MACV,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,SAAS,MAAM;AAAA,IACnB,CAAC;AAAA,EACL;AACA,QAAM,OAAO,CAAC,GAAG,KAAK,IAAI;AAC1B,MAAI,MAAM;AACN,SAAK,KAAK,MAAM,WAAW;AAC/B,aAAW,QAAQ;AAAA,IACf,QAAQ;AAAA,IACR,QAAQ,MAAM;AAAA,IACd;AAAA,EACJ,CAAC;AAED,aAAW,gBAAgB,eAAe;AACtC,UAAM,aAAa,QAAQ,YAAY;AACvC,QAAI,cAAc,WAAW,WAAW,UAAU,yBAAyB,UAAU,GAAG;AACpF,iBAAW,cAAc,EAAE,QAAQ,QAAQ,CAAC;AAAA,IAChD;AAAA,EACJ;AACA,SAAO,QAAQ,MAAM;AACzB;AACO,SAAS,gBAAgB,QAAQ,OAAO,IAAI;AAC/C,QAAM,OAAO,QAAQ,MAAM;AAC3B,MAAI,CAAC;AACD,UAAM,IAAI,MAAM,SAAS,MAAM,aAAa;AAChD,MAAI,KAAK,WAAW,eAAe;AAC/B,UAAM,IAAI,MAAM,SAAS,MAAM,iCAAiC,KAAK,MAAM,GAAG;AAAA,EAClF;AACA,MAAI,KAAK,UAAU,kBAAkB,OAAO,gBAAgB;AACxD,UAAM,IAAI,MAAM,6CAA6C;AAAA,EACjE;AACA,MAAI,CAAC,MAAM,cAAc,MAAM,WAAW,WAAW,GAAG;AACpD,UAAM,IAAI,MAAM,kEAAkE;AAAA,EACtF;AACA,QAAM,KAAK,MAAM;AACjB,aAAW,SAAS,MAAM,YAAY;AAClC,UAAM,MAAM,GAAG,MAAM,0CAA0C,EAAE,IAAI,KAAK;AAC1E,QAAI,CAAC;AACD,YAAM,IAAI,MAAM,oBAAoB,KAAK,kBAAkB;AAC/D,QAAI,IAAI,UAAU,gBAAgB;AAC9B,YAAM,IAAI,MAAM,+DAA+D,KAAK,QAAQ,IAAI,KAAK,EAAE;AAAA,IAC3G;AAAA,EACJ;AACA,QAAM,UAAU,MAAM,WAAW,OAAO,CAAC,MAAM,CAAC,KAAK,WAAW,SAAS,CAAC,CAAC;AAC3E,MAAI,QAAQ,WAAW,GAAG;AACtB,UAAM,IAAI,MAAM,gEAAgE;AAAA,EACpF;AACA,QAAM,kBAAkB,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,KAAK,YAAY,GAAG,MAAM,UAAU,CAAC,CAAC;AAC9E,KAAG,MAAM,mGAAmG,EAAE,IAAI,KAAK,UAAU,eAAe,IAAG,oBAAI,KAAK,GAAE,YAAY,GAAG,MAAM;AACnL,MAAI,MAAM;AACN,eAAW,QAAQ,MAAM,WAAW;AACxC,SAAO,QAAQ,MAAM;AACzB;;;AC1OA,SAAS,cAAc,eAAe,cAAAA,mBAAkB;AACxD,SAAS,QAAAC,aAAY;AACrB,IAAM,kBAAkB;AAKjB,SAAS,kBAAkB,KAAK;AACnC,QAAM,MAAM,OAAO,QAAQ,IAAI;AAC/B,QAAM,OAAOA,MAAK,KAAK,eAAe;AACtC,MAAI,CAACD,YAAW,IAAI;AAChB,WAAO;AACX,MAAI;AACA,UAAM,MAAM,aAAa,MAAM,OAAO;AACtC,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,OAAO,WAAW,YAAY,WAAW;AACzC,aAAO;AACX,UAAM,UAAU,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;AACtE,UAAM,QAAQ,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AAChE,UAAM,sBAAsB,OAAO,OAAO,wBAAwB,WAAW,OAAO,sBAAsB;AAC1G,WAAO,EAAE,SAAS,OAAO,oBAAoB;AAAA,EACjD,QACM;AACF,WAAO;AAAA,EACX;AACJ;AAIO,SAAS,kBAAkB,QAAQ,KAAK;AAC3C,QAAM,MAAM,OAAO,QAAQ,IAAI;AAC/B,QAAM,OAAOC,MAAK,KAAK,eAAe;AACtC,QAAM,UAAU,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI;AAClD,gBAAc,MAAM,SAAS,OAAO;AACxC;",
6
+ "names": ["existsSync", "join"]
7
+ }