sequant 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/dist/src/commands/doctor.d.ts +1 -4
- package/dist/src/commands/doctor.d.ts.map +1 -1
- package/dist/src/commands/doctor.integration.test.d.ts +10 -0
- package/dist/src/commands/doctor.integration.test.d.ts.map +1 -0
- package/dist/src/commands/doctor.integration.test.js +71 -0
- package/dist/src/commands/doctor.integration.test.js.map +1 -0
- package/dist/src/commands/doctor.js +1 -1
- package/dist/src/commands/doctor.js.map +1 -1
- package/dist/src/commands/doctor.test.js +20 -20
- package/dist/src/commands/doctor.test.js.map +1 -1
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/init.js +0 -2
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/run.d.ts.map +1 -1
- package/dist/src/commands/run.js +161 -96
- package/dist/src/commands/run.js.map +1 -1
- package/dist/src/commands/run.test.js.map +1 -1
- package/dist/src/lib/settings.d.ts +26 -0
- package/dist/src/lib/settings.d.ts.map +1 -1
- package/dist/src/lib/settings.js +12 -0
- package/dist/src/lib/settings.js.map +1 -1
- package/dist/src/lib/shutdown.d.ts +118 -0
- package/dist/src/lib/shutdown.d.ts.map +1 -0
- package/dist/src/lib/shutdown.js +174 -0
- package/dist/src/lib/shutdown.js.map +1 -0
- package/dist/src/lib/shutdown.test.d.ts +5 -0
- package/dist/src/lib/shutdown.test.d.ts.map +1 -0
- package/dist/src/lib/shutdown.test.js +216 -0
- package/dist/src/lib/shutdown.test.js.map +1 -0
- package/dist/src/lib/templates.js.map +1 -1
- package/dist/src/lib/tty.test.js.map +1 -1
- package/dist/src/lib/workflow/log-rotation.d.ts.map +1 -1
- package/dist/src/lib/workflow/log-rotation.js +0 -1
- package/dist/src/lib/workflow/log-rotation.js.map +1 -1
- package/dist/src/lib/workflow/run-log-schema.test.js +1 -0
- package/dist/src/lib/workflow/run-log-schema.test.js.map +1 -1
- package/package.json +8 -2
- package/templates/skills/assess/SKILL.md +31 -0
- package/templates/skills/exec/SKILL.md +164 -15
- package/templates/skills/fullsolve/SKILL.md +61 -10
- package/templates/skills/loop/SKILL.md +48 -3
- package/templates/skills/spec/SKILL.md +97 -2
|
@@ -25,6 +25,26 @@ export interface RotationSettings {
|
|
|
25
25
|
/** Maximum file count before rotation (default: 100) */
|
|
26
26
|
maxFiles: number;
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Agent execution settings
|
|
30
|
+
*
|
|
31
|
+
* Controls how sub-agents are spawned in multi-issue skills.
|
|
32
|
+
* Affects token usage and execution speed.
|
|
33
|
+
*/
|
|
34
|
+
export interface AgentSettings {
|
|
35
|
+
/**
|
|
36
|
+
* Run agents in parallel (faster, higher token usage).
|
|
37
|
+
* When false, agents run sequentially (slower, lower token usage).
|
|
38
|
+
* Default: false (cost-optimized)
|
|
39
|
+
*/
|
|
40
|
+
parallel: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Default model for sub-agents.
|
|
43
|
+
* Options: "haiku" (cheapest), "sonnet" (balanced), "opus" (most capable)
|
|
44
|
+
* Default: "haiku"
|
|
45
|
+
*/
|
|
46
|
+
model: "haiku" | "sonnet" | "opus";
|
|
47
|
+
}
|
|
28
48
|
/**
|
|
29
49
|
* Run command settings
|
|
30
50
|
*/
|
|
@@ -56,11 +76,17 @@ export interface SequantSettings {
|
|
|
56
76
|
version: string;
|
|
57
77
|
/** Run command settings */
|
|
58
78
|
run: RunSettings;
|
|
79
|
+
/** Agent execution settings */
|
|
80
|
+
agents: AgentSettings;
|
|
59
81
|
}
|
|
60
82
|
/**
|
|
61
83
|
* Default rotation settings
|
|
62
84
|
*/
|
|
63
85
|
export declare const DEFAULT_ROTATION_SETTINGS: RotationSettings;
|
|
86
|
+
/**
|
|
87
|
+
* Default agent settings (cost-optimized)
|
|
88
|
+
*/
|
|
89
|
+
export declare const DEFAULT_AGENT_SETTINGS: AgentSettings;
|
|
64
90
|
/**
|
|
65
91
|
* Default settings
|
|
66
92
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/lib/settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,0CAA0C;AAC1C,eAAO,MAAM,aAAa,2BAA2B,CAAC;AAEtD,sCAAsC;AACtC,eAAO,MAAM,gBAAgB,QAAQ,CAAC;AAEtC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oDAAoD;IACpD,OAAO,EAAE,OAAO,CAAC;IACjB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,gBAAgB,EAAE,OAAO,CAAC;IAC1B,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,UAAU,EAAE,OAAO,CAAC;IACpB,qCAAqC;IACrC,WAAW,EAAE,OAAO,CAAC;IACrB,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,4BAA4B;IAC5B,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,GAAG,EAAE,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/lib/settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,0CAA0C;AAC1C,eAAO,MAAM,aAAa,2BAA2B,CAAC;AAEtD,sCAAsC;AACtC,eAAO,MAAM,gBAAgB,QAAQ,CAAC;AAEtC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oDAAoD;IACpD,OAAO,EAAE,OAAO,CAAC;IACjB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,gBAAgB,EAAE,OAAO,CAAC;IAC1B,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,UAAU,EAAE,OAAO,CAAC;IACpB,qCAAqC;IACrC,WAAW,EAAE,OAAO,CAAC;IACrB,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,4BAA4B;IAC5B,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,GAAG,EAAE,WAAW,CAAC;IACjB,+BAA+B;IAC/B,MAAM,EAAE,aAAa,CAAC;CACvB;AAED;;GAEG;AACH,eAAO,MAAM,yBAAyB,EAAE,gBAIvC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,aAGpC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,eAc9B,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC,CAwB5D;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3E;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAEtD;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3D"}
|
package/dist/src/lib/settings.js
CHANGED
|
@@ -24,6 +24,13 @@ export const DEFAULT_ROTATION_SETTINGS = {
|
|
|
24
24
|
maxSizeMB: 10,
|
|
25
25
|
maxFiles: 100,
|
|
26
26
|
};
|
|
27
|
+
/**
|
|
28
|
+
* Default agent settings (cost-optimized)
|
|
29
|
+
*/
|
|
30
|
+
export const DEFAULT_AGENT_SETTINGS = {
|
|
31
|
+
parallel: false,
|
|
32
|
+
model: "haiku",
|
|
33
|
+
};
|
|
27
34
|
/**
|
|
28
35
|
* Default settings
|
|
29
36
|
*/
|
|
@@ -40,6 +47,7 @@ export const DEFAULT_SETTINGS = {
|
|
|
40
47
|
smartTests: true,
|
|
41
48
|
rotation: DEFAULT_ROTATION_SETTINGS,
|
|
42
49
|
},
|
|
50
|
+
agents: DEFAULT_AGENT_SETTINGS,
|
|
43
51
|
};
|
|
44
52
|
/**
|
|
45
53
|
* Get the current project settings
|
|
@@ -60,6 +68,10 @@ export async function getSettings() {
|
|
|
60
68
|
...DEFAULT_SETTINGS.run,
|
|
61
69
|
...parsed.run,
|
|
62
70
|
},
|
|
71
|
+
agents: {
|
|
72
|
+
...DEFAULT_AGENT_SETTINGS,
|
|
73
|
+
...parsed.agents,
|
|
74
|
+
},
|
|
63
75
|
};
|
|
64
76
|
}
|
|
65
77
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/lib/settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,0CAA0C;AAC1C,MAAM,CAAC,MAAM,aAAa,GAAG,wBAAwB,CAAC;AAEtD,sCAAsC;AACtC,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/lib/settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,0CAA0C;AAC1C,MAAM,CAAC,MAAM,aAAa,GAAG,wBAAwB,CAAC;AAEtD,sCAAsC;AACtC,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAuEtC;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAqB;IACzD,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,EAAE;IACb,QAAQ,EAAE,GAAG;CACd,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,QAAQ,EAAE,KAAK;IACf,KAAK,EAAE,OAAO;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAoB;IAC/C,OAAO,EAAE,gBAAgB;IACzB,GAAG,EAAE;QACH,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,eAAe;QACxB,gBAAgB,EAAE,IAAI;QACtB,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,KAAK;QACjB,WAAW,EAAE,KAAK;QAClB,aAAa,EAAE,CAAC;QAChB,UAAU,EAAE,IAAI;QAChB,QAAQ,EAAE,yBAAyB;KACpC;IACD,MAAM,EAAE,sBAAsB;CAC/B,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;QACvC,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,aAAa,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA6B,CAAC;QAE/D,iDAAiD;QACjD,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,gBAAgB,CAAC,OAAO;YACnD,GAAG,EAAE;gBACH,GAAG,gBAAgB,CAAC,GAAG;gBACvB,GAAG,MAAM,CAAC,GAAG;aACd;YACD,MAAM,EAAE;gBACN,GAAG,sBAAsB;gBACzB,GAAG,MAAM,CAAC,MAAM;aACjB;SACF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,gBAAgB,CAAC;IAC1B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAyB;IAC1D,MAAM,SAAS,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;IACxC,MAAM,SAAS,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,OAAO,UAAU,CAAC,aAAa,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,YAAY,CAAC,gBAAgB,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graceful shutdown manager for sequant run
|
|
3
|
+
*
|
|
4
|
+
* Handles SIGINT/SIGTERM signals and coordinates cleanup tasks
|
|
5
|
+
* when the process is interrupted.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const shutdown = new ShutdownManager();
|
|
10
|
+
*
|
|
11
|
+
* // Register cleanup tasks
|
|
12
|
+
* shutdown.registerCleanup('Save logs', async () => {
|
|
13
|
+
* await logWriter.finalize();
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* // Set abort controller for current phase
|
|
17
|
+
* shutdown.setAbortController(abortController);
|
|
18
|
+
*
|
|
19
|
+
* // In finally block
|
|
20
|
+
* shutdown.dispose();
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Options for ShutdownManager
|
|
25
|
+
*/
|
|
26
|
+
export interface ShutdownManagerOptions {
|
|
27
|
+
/** Timeout for cleanup tasks in milliseconds (default: 10000) */
|
|
28
|
+
forceExitTimeout?: number;
|
|
29
|
+
/** Custom output function for testing (default: console.log) */
|
|
30
|
+
output?: (message: string) => void;
|
|
31
|
+
/** Custom error output function for testing (default: console.error) */
|
|
32
|
+
errorOutput?: (message: string) => void;
|
|
33
|
+
/** Custom exit function for testing (default: process.exit) */
|
|
34
|
+
exit?: (code: number) => void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Manages graceful shutdown for sequant run
|
|
38
|
+
*
|
|
39
|
+
* Features:
|
|
40
|
+
* - Registers SIGINT/SIGTERM handlers
|
|
41
|
+
* - Manages cleanup tasks (executed in LIFO order)
|
|
42
|
+
* - Integrates with AbortController for phase cancellation
|
|
43
|
+
* - Supports double Ctrl+C for force exit
|
|
44
|
+
* - Has configurable timeout to prevent hanging
|
|
45
|
+
*/
|
|
46
|
+
export declare class ShutdownManager {
|
|
47
|
+
private cleanupTasks;
|
|
48
|
+
private _isShuttingDown;
|
|
49
|
+
private abortController;
|
|
50
|
+
private forceExitTimeout;
|
|
51
|
+
private output;
|
|
52
|
+
private errorOutput;
|
|
53
|
+
private exit;
|
|
54
|
+
private sigintHandler;
|
|
55
|
+
private sigtermHandler;
|
|
56
|
+
constructor(options?: ShutdownManagerOptions);
|
|
57
|
+
/**
|
|
58
|
+
* Whether a shutdown is currently in progress
|
|
59
|
+
*/
|
|
60
|
+
get isShuttingDown(): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Alias for isShuttingDown (matches proposed API)
|
|
63
|
+
*/
|
|
64
|
+
get shuttingDown(): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Set the abort controller for the current phase
|
|
67
|
+
*
|
|
68
|
+
* When shutdown is triggered, this controller will be aborted
|
|
69
|
+
* to cancel any in-flight operations.
|
|
70
|
+
*/
|
|
71
|
+
setAbortController(controller: AbortController): void;
|
|
72
|
+
/**
|
|
73
|
+
* Clear the abort controller (e.g., after phase completes)
|
|
74
|
+
*/
|
|
75
|
+
clearAbortController(): void;
|
|
76
|
+
/**
|
|
77
|
+
* Register a cleanup task
|
|
78
|
+
*
|
|
79
|
+
* Tasks are executed in LIFO order (last registered = first executed).
|
|
80
|
+
* This allows dependent cleanup to happen in correct order.
|
|
81
|
+
*
|
|
82
|
+
* @param name - Human-readable name for user feedback
|
|
83
|
+
* @param task - Async function to execute during cleanup
|
|
84
|
+
*/
|
|
85
|
+
registerCleanup(name: string, task: () => Promise<void>): void;
|
|
86
|
+
/**
|
|
87
|
+
* Unregister a cleanup task by name
|
|
88
|
+
*
|
|
89
|
+
* Use this when a resource is cleaned up normally (e.g., worktree
|
|
90
|
+
* removed after successful merge).
|
|
91
|
+
*/
|
|
92
|
+
unregisterCleanup(name: string): void;
|
|
93
|
+
/**
|
|
94
|
+
* Get the number of registered cleanup tasks
|
|
95
|
+
*/
|
|
96
|
+
getCleanupTaskCount(): number;
|
|
97
|
+
/**
|
|
98
|
+
* Trigger graceful shutdown
|
|
99
|
+
*
|
|
100
|
+
* This is called automatically on SIGINT/SIGTERM, but can also
|
|
101
|
+
* be called programmatically for testing.
|
|
102
|
+
*/
|
|
103
|
+
gracefulShutdown(signal: string): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* Remove signal handlers and clean up
|
|
106
|
+
*
|
|
107
|
+
* Call this in a finally block to prevent handler accumulation
|
|
108
|
+
* across multiple runs in the same process.
|
|
109
|
+
*/
|
|
110
|
+
dispose(): void;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Create a shutdown manager with default options
|
|
114
|
+
*
|
|
115
|
+
* Convenience function for standard usage.
|
|
116
|
+
*/
|
|
117
|
+
export declare function createShutdownManager(options?: ShutdownManagerOptions): ShutdownManager;
|
|
118
|
+
//# sourceMappingURL=shutdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../../../src/lib/shutdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAYH;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,iEAAiE;IACjE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gEAAgE;IAChE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,wEAAwE;IACxE,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,+DAA+D;IAC/D,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED;;;;;;;;;GASG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,IAAI,CAAyB;IAGrC,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,cAAc,CAAa;gBAEvB,OAAO,GAAE,sBAA2B;IAehD;;OAEG;IACH,IAAI,cAAc,IAAI,OAAO,CAE5B;IAED;;OAEG;IACH,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI;IAIrD;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAI5B;;;;;;;;OAQG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAI9D;;;;;OAKG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIrC;;OAEG;IACH,mBAAmB,IAAI,MAAM;IAI7B;;;;;OAKG;IACG,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA+CrD;;;;;OAKG;IACH,OAAO,IAAI,IAAI;CAMhB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,CAAC,EAAE,sBAAsB,GAC/B,eAAe,CAEjB"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graceful shutdown manager for sequant run
|
|
3
|
+
*
|
|
4
|
+
* Handles SIGINT/SIGTERM signals and coordinates cleanup tasks
|
|
5
|
+
* when the process is interrupted.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const shutdown = new ShutdownManager();
|
|
10
|
+
*
|
|
11
|
+
* // Register cleanup tasks
|
|
12
|
+
* shutdown.registerCleanup('Save logs', async () => {
|
|
13
|
+
* await logWriter.finalize();
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* // Set abort controller for current phase
|
|
17
|
+
* shutdown.setAbortController(abortController);
|
|
18
|
+
*
|
|
19
|
+
* // In finally block
|
|
20
|
+
* shutdown.dispose();
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
import chalk from "chalk";
|
|
24
|
+
/**
|
|
25
|
+
* Manages graceful shutdown for sequant run
|
|
26
|
+
*
|
|
27
|
+
* Features:
|
|
28
|
+
* - Registers SIGINT/SIGTERM handlers
|
|
29
|
+
* - Manages cleanup tasks (executed in LIFO order)
|
|
30
|
+
* - Integrates with AbortController for phase cancellation
|
|
31
|
+
* - Supports double Ctrl+C for force exit
|
|
32
|
+
* - Has configurable timeout to prevent hanging
|
|
33
|
+
*/
|
|
34
|
+
export class ShutdownManager {
|
|
35
|
+
cleanupTasks = [];
|
|
36
|
+
_isShuttingDown = false;
|
|
37
|
+
abortController = null;
|
|
38
|
+
forceExitTimeout;
|
|
39
|
+
output;
|
|
40
|
+
errorOutput;
|
|
41
|
+
exit;
|
|
42
|
+
// Store bound handlers for removal in dispose()
|
|
43
|
+
sigintHandler;
|
|
44
|
+
sigtermHandler;
|
|
45
|
+
constructor(options = {}) {
|
|
46
|
+
this.forceExitTimeout = options.forceExitTimeout ?? 10000;
|
|
47
|
+
this.output = options.output ?? console.log.bind(console);
|
|
48
|
+
this.errorOutput = options.errorOutput ?? console.error.bind(console);
|
|
49
|
+
this.exit = options.exit ?? process.exit.bind(process);
|
|
50
|
+
// Bind handlers so we can remove them later
|
|
51
|
+
this.sigintHandler = () => this.gracefulShutdown("SIGINT");
|
|
52
|
+
this.sigtermHandler = () => this.gracefulShutdown("SIGTERM");
|
|
53
|
+
// Register signal handlers
|
|
54
|
+
process.on("SIGINT", this.sigintHandler);
|
|
55
|
+
process.on("SIGTERM", this.sigtermHandler);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Whether a shutdown is currently in progress
|
|
59
|
+
*/
|
|
60
|
+
get isShuttingDown() {
|
|
61
|
+
return this._isShuttingDown;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Alias for isShuttingDown (matches proposed API)
|
|
65
|
+
*/
|
|
66
|
+
get shuttingDown() {
|
|
67
|
+
return this._isShuttingDown;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Set the abort controller for the current phase
|
|
71
|
+
*
|
|
72
|
+
* When shutdown is triggered, this controller will be aborted
|
|
73
|
+
* to cancel any in-flight operations.
|
|
74
|
+
*/
|
|
75
|
+
setAbortController(controller) {
|
|
76
|
+
this.abortController = controller;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Clear the abort controller (e.g., after phase completes)
|
|
80
|
+
*/
|
|
81
|
+
clearAbortController() {
|
|
82
|
+
this.abortController = null;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Register a cleanup task
|
|
86
|
+
*
|
|
87
|
+
* Tasks are executed in LIFO order (last registered = first executed).
|
|
88
|
+
* This allows dependent cleanup to happen in correct order.
|
|
89
|
+
*
|
|
90
|
+
* @param name - Human-readable name for user feedback
|
|
91
|
+
* @param task - Async function to execute during cleanup
|
|
92
|
+
*/
|
|
93
|
+
registerCleanup(name, task) {
|
|
94
|
+
this.cleanupTasks.push({ name, task });
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Unregister a cleanup task by name
|
|
98
|
+
*
|
|
99
|
+
* Use this when a resource is cleaned up normally (e.g., worktree
|
|
100
|
+
* removed after successful merge).
|
|
101
|
+
*/
|
|
102
|
+
unregisterCleanup(name) {
|
|
103
|
+
this.cleanupTasks = this.cleanupTasks.filter((t) => t.name !== name);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get the number of registered cleanup tasks
|
|
107
|
+
*/
|
|
108
|
+
getCleanupTaskCount() {
|
|
109
|
+
return this.cleanupTasks.length;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Trigger graceful shutdown
|
|
113
|
+
*
|
|
114
|
+
* This is called automatically on SIGINT/SIGTERM, but can also
|
|
115
|
+
* be called programmatically for testing.
|
|
116
|
+
*/
|
|
117
|
+
async gracefulShutdown(signal) {
|
|
118
|
+
// Double signal = force exit
|
|
119
|
+
if (this._isShuttingDown) {
|
|
120
|
+
this.errorOutput(chalk.red("\nForce exiting..."));
|
|
121
|
+
this.exit(1);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
this._isShuttingDown = true;
|
|
125
|
+
this.output(chalk.yellow(`\n⚠️ Received ${signal}, shutting down gracefully...`));
|
|
126
|
+
// Abort in-flight phase immediately
|
|
127
|
+
if (this.abortController) {
|
|
128
|
+
this.abortController.abort();
|
|
129
|
+
this.output(chalk.green("✓ Aborted active phase"));
|
|
130
|
+
}
|
|
131
|
+
// Set up force exit timeout
|
|
132
|
+
const forceExitTimer = setTimeout(() => {
|
|
133
|
+
this.errorOutput(chalk.red("Cleanup timeout, force exiting"));
|
|
134
|
+
this.exit(1);
|
|
135
|
+
}, this.forceExitTimeout);
|
|
136
|
+
// Run cleanup tasks in reverse order (LIFO)
|
|
137
|
+
const tasksToRun = [...this.cleanupTasks].reverse();
|
|
138
|
+
for (const { name, task } of tasksToRun) {
|
|
139
|
+
try {
|
|
140
|
+
await task();
|
|
141
|
+
this.output(chalk.green(`✓ ${name}`));
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
145
|
+
this.errorOutput(chalk.red(`✗ ${name}: ${message}`));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
clearTimeout(forceExitTimer);
|
|
149
|
+
// Print summary
|
|
150
|
+
this.output(chalk.yellow("\nInterrupted. Cleanup complete."));
|
|
151
|
+
this.exit(0);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Remove signal handlers and clean up
|
|
155
|
+
*
|
|
156
|
+
* Call this in a finally block to prevent handler accumulation
|
|
157
|
+
* across multiple runs in the same process.
|
|
158
|
+
*/
|
|
159
|
+
dispose() {
|
|
160
|
+
process.removeListener("SIGINT", this.sigintHandler);
|
|
161
|
+
process.removeListener("SIGTERM", this.sigtermHandler);
|
|
162
|
+
this.cleanupTasks = [];
|
|
163
|
+
this.abortController = null;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Create a shutdown manager with default options
|
|
168
|
+
*
|
|
169
|
+
* Convenience function for standard usage.
|
|
170
|
+
*/
|
|
171
|
+
export function createShutdownManager(options) {
|
|
172
|
+
return new ShutdownManager(options);
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=shutdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../../src/lib/shutdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown.test.d.ts","sourceRoot":"","sources":["../../../src/lib/shutdown.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for ShutdownManager
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
5
|
+
import { ShutdownManager } from "./shutdown.js";
|
|
6
|
+
describe("ShutdownManager", () => {
|
|
7
|
+
let mockOutput;
|
|
8
|
+
let mockErrorOutput;
|
|
9
|
+
let mockExit;
|
|
10
|
+
let manager;
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
mockOutput = vi.fn();
|
|
13
|
+
mockErrorOutput = vi.fn();
|
|
14
|
+
mockExit = vi.fn();
|
|
15
|
+
});
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
// Always dispose to remove signal handlers
|
|
18
|
+
manager?.dispose();
|
|
19
|
+
});
|
|
20
|
+
function createManager(options) {
|
|
21
|
+
manager = new ShutdownManager({
|
|
22
|
+
output: mockOutput,
|
|
23
|
+
errorOutput: mockErrorOutput,
|
|
24
|
+
exit: mockExit,
|
|
25
|
+
forceExitTimeout: options?.forceExitTimeout ?? 10000,
|
|
26
|
+
});
|
|
27
|
+
return manager;
|
|
28
|
+
}
|
|
29
|
+
describe("initialization", () => {
|
|
30
|
+
it("should start with isShuttingDown = false", () => {
|
|
31
|
+
const mgr = createManager();
|
|
32
|
+
expect(mgr.isShuttingDown).toBe(false);
|
|
33
|
+
expect(mgr.shuttingDown).toBe(false);
|
|
34
|
+
});
|
|
35
|
+
it("should start with no cleanup tasks", () => {
|
|
36
|
+
const mgr = createManager();
|
|
37
|
+
expect(mgr.getCleanupTaskCount()).toBe(0);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
describe("cleanup task registration", () => {
|
|
41
|
+
it("should register cleanup tasks", () => {
|
|
42
|
+
const mgr = createManager();
|
|
43
|
+
mgr.registerCleanup("Task 1", async () => { });
|
|
44
|
+
expect(mgr.getCleanupTaskCount()).toBe(1);
|
|
45
|
+
mgr.registerCleanup("Task 2", async () => { });
|
|
46
|
+
expect(mgr.getCleanupTaskCount()).toBe(2);
|
|
47
|
+
});
|
|
48
|
+
it("should unregister cleanup tasks by name", () => {
|
|
49
|
+
const mgr = createManager();
|
|
50
|
+
mgr.registerCleanup("Task 1", async () => { });
|
|
51
|
+
mgr.registerCleanup("Task 2", async () => { });
|
|
52
|
+
expect(mgr.getCleanupTaskCount()).toBe(2);
|
|
53
|
+
mgr.unregisterCleanup("Task 1");
|
|
54
|
+
expect(mgr.getCleanupTaskCount()).toBe(1);
|
|
55
|
+
});
|
|
56
|
+
it("should not error when unregistering non-existent task", () => {
|
|
57
|
+
const mgr = createManager();
|
|
58
|
+
mgr.registerCleanup("Task 1", async () => { });
|
|
59
|
+
// Should not throw
|
|
60
|
+
mgr.unregisterCleanup("Non-existent");
|
|
61
|
+
expect(mgr.getCleanupTaskCount()).toBe(1);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
describe("graceful shutdown", () => {
|
|
65
|
+
it("should set isShuttingDown to true", async () => {
|
|
66
|
+
const mgr = createManager();
|
|
67
|
+
await mgr.gracefulShutdown("SIGINT");
|
|
68
|
+
expect(mgr.isShuttingDown).toBe(true);
|
|
69
|
+
expect(mockExit).toHaveBeenCalledWith(0);
|
|
70
|
+
});
|
|
71
|
+
it("should abort the active controller", async () => {
|
|
72
|
+
const mgr = createManager();
|
|
73
|
+
const abortController = new AbortController();
|
|
74
|
+
mgr.setAbortController(abortController);
|
|
75
|
+
expect(abortController.signal.aborted).toBe(false);
|
|
76
|
+
await mgr.gracefulShutdown("SIGINT");
|
|
77
|
+
expect(abortController.signal.aborted).toBe(true);
|
|
78
|
+
expect(mockOutput).toHaveBeenCalledWith(expect.stringContaining("Aborted active phase"));
|
|
79
|
+
});
|
|
80
|
+
it("should execute cleanup tasks in LIFO order", async () => {
|
|
81
|
+
const mgr = createManager();
|
|
82
|
+
const executionOrder = [];
|
|
83
|
+
mgr.registerCleanup("First", async () => {
|
|
84
|
+
executionOrder.push("First");
|
|
85
|
+
});
|
|
86
|
+
mgr.registerCleanup("Second", async () => {
|
|
87
|
+
executionOrder.push("Second");
|
|
88
|
+
});
|
|
89
|
+
mgr.registerCleanup("Third", async () => {
|
|
90
|
+
executionOrder.push("Third");
|
|
91
|
+
});
|
|
92
|
+
await mgr.gracefulShutdown("SIGINT");
|
|
93
|
+
// LIFO: Third, Second, First
|
|
94
|
+
expect(executionOrder).toEqual(["Third", "Second", "First"]);
|
|
95
|
+
});
|
|
96
|
+
it("should continue cleanup even if a task fails", async () => {
|
|
97
|
+
const mgr = createManager();
|
|
98
|
+
const executionOrder = [];
|
|
99
|
+
mgr.registerCleanup("First", async () => {
|
|
100
|
+
executionOrder.push("First");
|
|
101
|
+
});
|
|
102
|
+
mgr.registerCleanup("Failing", async () => {
|
|
103
|
+
throw new Error("Cleanup failed");
|
|
104
|
+
});
|
|
105
|
+
mgr.registerCleanup("Third", async () => {
|
|
106
|
+
executionOrder.push("Third");
|
|
107
|
+
});
|
|
108
|
+
await mgr.gracefulShutdown("SIGINT");
|
|
109
|
+
// Should execute Third, fail on Failing, then execute First
|
|
110
|
+
expect(executionOrder).toEqual(["Third", "First"]);
|
|
111
|
+
expect(mockErrorOutput).toHaveBeenCalledWith(expect.stringContaining("Failing: Cleanup failed"));
|
|
112
|
+
});
|
|
113
|
+
it("should print success message for completed cleanup tasks", async () => {
|
|
114
|
+
const mgr = createManager();
|
|
115
|
+
mgr.registerCleanup("Save logs", async () => { });
|
|
116
|
+
await mgr.gracefulShutdown("SIGINT");
|
|
117
|
+
expect(mockOutput).toHaveBeenCalledWith(expect.stringContaining("✓ Save logs"));
|
|
118
|
+
});
|
|
119
|
+
it("should exit with code 0 on successful shutdown", async () => {
|
|
120
|
+
const mgr = createManager();
|
|
121
|
+
await mgr.gracefulShutdown("SIGINT");
|
|
122
|
+
expect(mockExit).toHaveBeenCalledWith(0);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
describe("double signal (force exit)", () => {
|
|
126
|
+
it("should force exit on second signal", async () => {
|
|
127
|
+
vi.useFakeTimers();
|
|
128
|
+
const mgr = createManager({ forceExitTimeout: 10000 });
|
|
129
|
+
// Register a slow task that we'll never complete
|
|
130
|
+
let taskStarted = false;
|
|
131
|
+
mgr.registerCleanup("Slow task", async () => {
|
|
132
|
+
taskStarted = true;
|
|
133
|
+
// This task hangs indefinitely
|
|
134
|
+
await new Promise(() => { });
|
|
135
|
+
});
|
|
136
|
+
// First signal - starts shutdown (don't await)
|
|
137
|
+
const shutdownPromise = mgr.gracefulShutdown("SIGINT");
|
|
138
|
+
// Wait a tick for the task to start
|
|
139
|
+
await vi.advanceTimersByTimeAsync(10);
|
|
140
|
+
expect(taskStarted).toBe(true);
|
|
141
|
+
expect(mgr.isShuttingDown).toBe(true);
|
|
142
|
+
// Second signal while shutting down - should force exit immediately
|
|
143
|
+
await mgr.gracefulShutdown("SIGINT");
|
|
144
|
+
expect(mockExit).toHaveBeenCalledWith(1);
|
|
145
|
+
expect(mockErrorOutput).toHaveBeenCalledWith(expect.stringContaining("Force exiting"));
|
|
146
|
+
vi.useRealTimers();
|
|
147
|
+
// Don't await the hanging promise
|
|
148
|
+
shutdownPromise.catch(() => { });
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
describe("timeout", () => {
|
|
152
|
+
it("should force exit if cleanup takes too long", async () => {
|
|
153
|
+
vi.useFakeTimers();
|
|
154
|
+
const mgr = createManager({ forceExitTimeout: 100 });
|
|
155
|
+
mgr.registerCleanup("Hanging task", async () => {
|
|
156
|
+
// This task never completes
|
|
157
|
+
await new Promise(() => { });
|
|
158
|
+
});
|
|
159
|
+
// Start shutdown (don't await - it will hang)
|
|
160
|
+
const shutdownPromise = mgr.gracefulShutdown("SIGINT");
|
|
161
|
+
// Advance timer past timeout
|
|
162
|
+
await vi.advanceTimersByTimeAsync(150);
|
|
163
|
+
expect(mockExit).toHaveBeenCalledWith(1);
|
|
164
|
+
expect(mockErrorOutput).toHaveBeenCalledWith(expect.stringContaining("Cleanup timeout"));
|
|
165
|
+
vi.useRealTimers();
|
|
166
|
+
// Don't await the hanging promise
|
|
167
|
+
shutdownPromise.catch(() => { });
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
describe("abort controller management", () => {
|
|
171
|
+
it("should set and clear abort controller", () => {
|
|
172
|
+
const mgr = createManager();
|
|
173
|
+
const controller = new AbortController();
|
|
174
|
+
mgr.setAbortController(controller);
|
|
175
|
+
// Can't directly test the internal state, but we can test behavior
|
|
176
|
+
mgr.clearAbortController();
|
|
177
|
+
// After clear, graceful shutdown should not abort anything
|
|
178
|
+
});
|
|
179
|
+
it("should not error when aborting with no controller set", async () => {
|
|
180
|
+
const mgr = createManager();
|
|
181
|
+
// Should not throw
|
|
182
|
+
await mgr.gracefulShutdown("SIGINT");
|
|
183
|
+
expect(mockExit).toHaveBeenCalledWith(0);
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
describe("dispose", () => {
|
|
187
|
+
it("should clear cleanup tasks", () => {
|
|
188
|
+
const mgr = createManager();
|
|
189
|
+
mgr.registerCleanup("Task 1", async () => { });
|
|
190
|
+
mgr.registerCleanup("Task 2", async () => { });
|
|
191
|
+
expect(mgr.getCleanupTaskCount()).toBe(2);
|
|
192
|
+
mgr.dispose();
|
|
193
|
+
expect(mgr.getCleanupTaskCount()).toBe(0);
|
|
194
|
+
});
|
|
195
|
+
it("should allow multiple managers in sequence", () => {
|
|
196
|
+
// Create and dispose first manager
|
|
197
|
+
const mgr1 = createManager();
|
|
198
|
+
mgr1.registerCleanup("Task", async () => { });
|
|
199
|
+
mgr1.dispose();
|
|
200
|
+
// Create second manager - should work without issues
|
|
201
|
+
const mgr2 = createManager();
|
|
202
|
+
mgr2.registerCleanup("Task", async () => { });
|
|
203
|
+
expect(mgr2.getCleanupTaskCount()).toBe(1);
|
|
204
|
+
mgr2.dispose();
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
describe("signal handling", () => {
|
|
208
|
+
it("should handle SIGTERM same as SIGINT", async () => {
|
|
209
|
+
const mgr = createManager();
|
|
210
|
+
await mgr.gracefulShutdown("SIGTERM");
|
|
211
|
+
expect(mockOutput).toHaveBeenCalledWith(expect.stringContaining("SIGTERM"));
|
|
212
|
+
expect(mockExit).toHaveBeenCalledWith(0);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
//# sourceMappingURL=shutdown.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown.test.js","sourceRoot":"","sources":["../../../src/lib/shutdown.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/lib/templates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/lib/templates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,sCAAsC;AACtC,SAAS,eAAe;IACtB,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,gDAAgD;IAChD,iEAAiE;IACjE,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IAE/D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAe,EACf,SAAiC;IAEjC,IAAI,MAAM,GAAG,OAAO,CAAC;IACrB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACrD,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,SAAS,GAAG,QAAQ,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,UAAU,IAAI,CAAC,GAAW,EAAE,SAAiB,EAAE;QAClD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAEvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;oBACxB,MAAM,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;gBACrC,CAAC;qBAAM,CAAC;oBACN,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;gBAC9C,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,0BAA0B;QAC5B,CAAC;IACH,CAAC;IAED,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC;IACzB,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,YAAoB;IAEpB,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,MAAM,YAAY,GAAG,YAAY,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IAElD,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAa,EACb,MAA+B;IAE/B,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG;QAChB,GAAG,WAAW,CAAC,SAAS;QACxB,GAAG,MAAM;QACT,YAAY,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,SAAS;QAClD,KAAK,EAAE,KAAK;KACb,CAAC;IAEF,KAAK,UAAU,OAAO,CAAC,MAAc,EAAE,OAAe;QACpD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/D,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;YAEzB,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAE3C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;oBACxB,MAAM,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;gBACnC,CAAC;qBAAM,CAAC;oBACN,2BAA2B;oBAC3B,IAAI,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;oBACtC,OAAO,GAAG,eAAe,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;oBAC9C,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAEnC,gCAAgC;oBAChC,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;wBAC/B,MAAM,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;oBAC/B,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,+BAA+B;YAC/B,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IAED,cAAc;IACd,MAAM,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAE9D,aAAa;IACb,MAAM,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,EAAE,eAAe,CAAC,CAAC;IAE5D,mCAAmC;IACnC,MAAM,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAE9D,wCAAwC;IACxC,MAAM,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,EAAE,aAAa,CAAC,CAAC;IAE5D,qBAAqB;IACrB,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;IACzD,IAAI,MAAM,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC7C,MAAM,SAAS,CACb,uBAAuB,EACvB,eAAe,CAAC,OAAO,EAAE,SAAS,CAAC,CACpC,CAAC;IACJ,CAAC;AACH,CAAC"}
|