cmdr-agent 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +238 -0
- package/dist/bin/cmdr.d.ts +9 -0
- package/dist/bin/cmdr.d.ts.map +1 -0
- package/dist/bin/cmdr.js +49 -0
- package/dist/bin/cmdr.js.map +1 -0
- package/dist/src/cli/args.d.ts +19 -0
- package/dist/src/cli/args.d.ts.map +1 -0
- package/dist/src/cli/args.js +89 -0
- package/dist/src/cli/args.js.map +1 -0
- package/dist/src/cli/commands.d.ts +12 -0
- package/dist/src/cli/commands.d.ts.map +1 -0
- package/dist/src/cli/commands.js +400 -0
- package/dist/src/cli/commands.js.map +1 -0
- package/dist/src/cli/renderer.d.ts +8 -0
- package/dist/src/cli/renderer.d.ts.map +1 -0
- package/dist/src/cli/renderer.js +47 -0
- package/dist/src/cli/renderer.js.map +1 -0
- package/dist/src/cli/repl.d.ts +18 -0
- package/dist/src/cli/repl.d.ts.map +1 -0
- package/dist/src/cli/repl.js +751 -0
- package/dist/src/cli/repl.js.map +1 -0
- package/dist/src/cli/spinner.d.ts +16 -0
- package/dist/src/cli/spinner.d.ts.map +1 -0
- package/dist/src/cli/spinner.js +233 -0
- package/dist/src/cli/spinner.js.map +1 -0
- package/dist/src/cli/theme.d.ts +95 -0
- package/dist/src/cli/theme.d.ts.map +1 -0
- package/dist/src/cli/theme.js +178 -0
- package/dist/src/cli/theme.js.map +1 -0
- package/dist/src/communication/message-bus.d.ts +35 -0
- package/dist/src/communication/message-bus.d.ts.map +1 -0
- package/dist/src/communication/message-bus.js +60 -0
- package/dist/src/communication/message-bus.js.map +1 -0
- package/dist/src/communication/shared-memory.d.ts +19 -0
- package/dist/src/communication/shared-memory.d.ts.map +1 -0
- package/dist/src/communication/shared-memory.js +37 -0
- package/dist/src/communication/shared-memory.js.map +1 -0
- package/dist/src/communication/task-queue.d.ts +50 -0
- package/dist/src/communication/task-queue.d.ts.map +1 -0
- package/dist/src/communication/task-queue.js +158 -0
- package/dist/src/communication/task-queue.js.map +1 -0
- package/dist/src/config/config-loader.d.ts +23 -0
- package/dist/src/config/config-loader.d.ts.map +1 -0
- package/dist/src/config/config-loader.js +91 -0
- package/dist/src/config/config-loader.js.map +1 -0
- package/dist/src/config/defaults.d.ts +6 -0
- package/dist/src/config/defaults.d.ts.map +1 -0
- package/dist/src/config/defaults.js +21 -0
- package/dist/src/config/defaults.js.map +1 -0
- package/dist/src/config/schema.d.ts +135 -0
- package/dist/src/config/schema.d.ts.map +1 -0
- package/dist/src/config/schema.js +35 -0
- package/dist/src/config/schema.js.map +1 -0
- package/dist/src/config/telemetry.d.ts +41 -0
- package/dist/src/config/telemetry.d.ts.map +1 -0
- package/dist/src/config/telemetry.js +57 -0
- package/dist/src/config/telemetry.js.map +1 -0
- package/dist/src/core/agent-pool.d.ts +40 -0
- package/dist/src/core/agent-pool.d.ts.map +1 -0
- package/dist/src/core/agent-pool.js +66 -0
- package/dist/src/core/agent-pool.js.map +1 -0
- package/dist/src/core/agent-runner.d.ts +51 -0
- package/dist/src/core/agent-runner.d.ts.map +1 -0
- package/dist/src/core/agent-runner.js +251 -0
- package/dist/src/core/agent-runner.js.map +1 -0
- package/dist/src/core/agent.d.ts +34 -0
- package/dist/src/core/agent.d.ts.map +1 -0
- package/dist/src/core/agent.js +143 -0
- package/dist/src/core/agent.js.map +1 -0
- package/dist/src/core/intent.d.ts +33 -0
- package/dist/src/core/intent.d.ts.map +1 -0
- package/dist/src/core/intent.js +91 -0
- package/dist/src/core/intent.js.map +1 -0
- package/dist/src/core/orchestrator.d.ts +43 -0
- package/dist/src/core/orchestrator.d.ts.map +1 -0
- package/dist/src/core/orchestrator.js +115 -0
- package/dist/src/core/orchestrator.js.map +1 -0
- package/dist/src/core/permissions.d.ts +36 -0
- package/dist/src/core/permissions.d.ts.map +1 -0
- package/dist/src/core/permissions.js +129 -0
- package/dist/src/core/permissions.js.map +1 -0
- package/dist/src/core/presets.d.ts +12 -0
- package/dist/src/core/presets.d.ts.map +1 -0
- package/dist/src/core/presets.js +148 -0
- package/dist/src/core/presets.js.map +1 -0
- package/dist/src/core/team.d.ts +44 -0
- package/dist/src/core/team.d.ts.map +1 -0
- package/dist/src/core/team.js +156 -0
- package/dist/src/core/team.js.map +1 -0
- package/dist/src/core/types.d.ts +257 -0
- package/dist/src/core/types.d.ts.map +1 -0
- package/dist/src/core/types.js +7 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/index.d.ts +44 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +45 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/llm/adapter.d.ts +5 -0
- package/dist/src/llm/adapter.d.ts.map +1 -0
- package/dist/src/llm/adapter.js +5 -0
- package/dist/src/llm/adapter.js.map +1 -0
- package/dist/src/llm/model-registry.d.ts +14 -0
- package/dist/src/llm/model-registry.d.ts.map +1 -0
- package/dist/src/llm/model-registry.js +30 -0
- package/dist/src/llm/model-registry.js.map +1 -0
- package/dist/src/llm/ollama.d.ts +26 -0
- package/dist/src/llm/ollama.d.ts.map +1 -0
- package/dist/src/llm/ollama.js +375 -0
- package/dist/src/llm/ollama.js.map +1 -0
- package/dist/src/llm/token-counter.d.ts +11 -0
- package/dist/src/llm/token-counter.d.ts.map +1 -0
- package/dist/src/llm/token-counter.js +35 -0
- package/dist/src/llm/token-counter.js.map +1 -0
- package/dist/src/plugins/mcp-client.d.ts +38 -0
- package/dist/src/plugins/mcp-client.d.ts.map +1 -0
- package/dist/src/plugins/mcp-client.js +113 -0
- package/dist/src/plugins/mcp-client.js.map +1 -0
- package/dist/src/plugins/plugin-manager.d.ts +37 -0
- package/dist/src/plugins/plugin-manager.d.ts.map +1 -0
- package/dist/src/plugins/plugin-manager.js +146 -0
- package/dist/src/plugins/plugin-manager.js.map +1 -0
- package/dist/src/scheduling/semaphore.d.ts +20 -0
- package/dist/src/scheduling/semaphore.d.ts.map +1 -0
- package/dist/src/scheduling/semaphore.js +52 -0
- package/dist/src/scheduling/semaphore.js.map +1 -0
- package/dist/src/scheduling/strategies.d.ts +39 -0
- package/dist/src/scheduling/strategies.d.ts.map +1 -0
- package/dist/src/scheduling/strategies.js +88 -0
- package/dist/src/scheduling/strategies.js.map +1 -0
- package/dist/src/session/compaction.d.ts +32 -0
- package/dist/src/session/compaction.d.ts.map +1 -0
- package/dist/src/session/compaction.js +172 -0
- package/dist/src/session/compaction.js.map +1 -0
- package/dist/src/session/cost-tracker.d.ts +41 -0
- package/dist/src/session/cost-tracker.d.ts.map +1 -0
- package/dist/src/session/cost-tracker.js +76 -0
- package/dist/src/session/cost-tracker.js.map +1 -0
- package/dist/src/session/project-context.d.ts +6 -0
- package/dist/src/session/project-context.d.ts.map +1 -0
- package/dist/src/session/project-context.js +147 -0
- package/dist/src/session/project-context.js.map +1 -0
- package/dist/src/session/prompt-builder.d.ts +11 -0
- package/dist/src/session/prompt-builder.d.ts.map +1 -0
- package/dist/src/session/prompt-builder.js +30 -0
- package/dist/src/session/prompt-builder.js.map +1 -0
- package/dist/src/session/session-manager.d.ts +32 -0
- package/dist/src/session/session-manager.d.ts.map +1 -0
- package/dist/src/session/session-manager.js +84 -0
- package/dist/src/session/session-manager.js.map +1 -0
- package/dist/src/session/session-persistence.d.ts +44 -0
- package/dist/src/session/session-persistence.d.ts.map +1 -0
- package/dist/src/session/session-persistence.js +150 -0
- package/dist/src/session/session-persistence.js.map +1 -0
- package/dist/src/session/undo-manager.d.ts +35 -0
- package/dist/src/session/undo-manager.d.ts.map +1 -0
- package/dist/src/session/undo-manager.js +79 -0
- package/dist/src/session/undo-manager.js.map +1 -0
- package/dist/src/tools/built-in/ask-user.d.ts +7 -0
- package/dist/src/tools/built-in/ask-user.d.ts.map +1 -0
- package/dist/src/tools/built-in/ask-user.js +28 -0
- package/dist/src/tools/built-in/ask-user.js.map +1 -0
- package/dist/src/tools/built-in/bash.d.ts +9 -0
- package/dist/src/tools/built-in/bash.d.ts.map +1 -0
- package/dist/src/tools/built-in/bash.js +67 -0
- package/dist/src/tools/built-in/bash.js.map +1 -0
- package/dist/src/tools/built-in/file-edit.d.ts +9 -0
- package/dist/src/tools/built-in/file-edit.d.ts.map +1 -0
- package/dist/src/tools/built-in/file-edit.js +39 -0
- package/dist/src/tools/built-in/file-edit.js.map +1 -0
- package/dist/src/tools/built-in/file-read.d.ts +9 -0
- package/dist/src/tools/built-in/file-read.d.ts.map +1 -0
- package/dist/src/tools/built-in/file-read.js +41 -0
- package/dist/src/tools/built-in/file-read.js.map +1 -0
- package/dist/src/tools/built-in/file-write.d.ts +8 -0
- package/dist/src/tools/built-in/file-write.d.ts.map +1 -0
- package/dist/src/tools/built-in/file-write.js +29 -0
- package/dist/src/tools/built-in/file-write.js.map +1 -0
- package/dist/src/tools/built-in/git-commit.d.ts +12 -0
- package/dist/src/tools/built-in/git-commit.d.ts.map +1 -0
- package/dist/src/tools/built-in/git-commit.js +96 -0
- package/dist/src/tools/built-in/git-commit.js.map +1 -0
- package/dist/src/tools/built-in/git-diff.d.ts +8 -0
- package/dist/src/tools/built-in/git-diff.d.ts.map +1 -0
- package/dist/src/tools/built-in/git-diff.js +43 -0
- package/dist/src/tools/built-in/git-diff.js.map +1 -0
- package/dist/src/tools/built-in/git-log.d.ts +8 -0
- package/dist/src/tools/built-in/git-log.d.ts.map +1 -0
- package/dist/src/tools/built-in/git-log.js +39 -0
- package/dist/src/tools/built-in/git-log.js.map +1 -0
- package/dist/src/tools/built-in/glob.d.ts +8 -0
- package/dist/src/tools/built-in/glob.d.ts.map +1 -0
- package/dist/src/tools/built-in/glob.js +60 -0
- package/dist/src/tools/built-in/glob.js.map +1 -0
- package/dist/src/tools/built-in/grep.d.ts +9 -0
- package/dist/src/tools/built-in/grep.d.ts.map +1 -0
- package/dist/src/tools/built-in/grep.js +115 -0
- package/dist/src/tools/built-in/grep.js.map +1 -0
- package/dist/src/tools/built-in/index.d.ts +21 -0
- package/dist/src/tools/built-in/index.d.ts.map +1 -0
- package/dist/src/tools/built-in/index.js +30 -0
- package/dist/src/tools/built-in/index.js.map +1 -0
- package/dist/src/tools/built-in/think.d.ts +7 -0
- package/dist/src/tools/built-in/think.d.ts.map +1 -0
- package/dist/src/tools/built-in/think.js +18 -0
- package/dist/src/tools/built-in/think.js.map +1 -0
- package/dist/src/tools/built-in/web-fetch.d.ts +11 -0
- package/dist/src/tools/built-in/web-fetch.d.ts.map +1 -0
- package/dist/src/tools/built-in/web-fetch.js +70 -0
- package/dist/src/tools/built-in/web-fetch.js.map +1 -0
- package/dist/src/tools/executor.d.ts +25 -0
- package/dist/src/tools/executor.d.ts.map +1 -0
- package/dist/src/tools/executor.js +61 -0
- package/dist/src/tools/executor.js.map +1 -0
- package/dist/src/tools/registry.d.ts +25 -0
- package/dist/src/tools/registry.d.ts.map +1 -0
- package/dist/src/tools/registry.js +135 -0
- package/dist/src/tools/registry.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CostTracker — tracks token usage and estimates cost per session.
|
|
3
|
+
*
|
|
4
|
+
* Local models have no direct cost, but tracking usage helps
|
|
5
|
+
* understand resource consumption and compare models.
|
|
6
|
+
*/
|
|
7
|
+
export interface CostEntry {
|
|
8
|
+
readonly timestamp: Date;
|
|
9
|
+
readonly model: string;
|
|
10
|
+
readonly inputTokens: number;
|
|
11
|
+
readonly outputTokens: number;
|
|
12
|
+
readonly toolCalls: number;
|
|
13
|
+
readonly duration: number;
|
|
14
|
+
}
|
|
15
|
+
export interface CostSummary {
|
|
16
|
+
readonly totalInputTokens: number;
|
|
17
|
+
readonly totalOutputTokens: number;
|
|
18
|
+
readonly totalTokens: number;
|
|
19
|
+
readonly totalToolCalls: number;
|
|
20
|
+
readonly totalDuration: number;
|
|
21
|
+
readonly turns: number;
|
|
22
|
+
readonly avgTokensPerTurn: number;
|
|
23
|
+
readonly model: string;
|
|
24
|
+
}
|
|
25
|
+
export declare class CostTracker {
|
|
26
|
+
private entries;
|
|
27
|
+
private sessionStart;
|
|
28
|
+
/** Record a turn's usage. */
|
|
29
|
+
record(model: string, inputTokens: number, outputTokens: number, toolCalls: number): void;
|
|
30
|
+
/** Get a summary of all tracked usage. */
|
|
31
|
+
getSummary(): CostSummary;
|
|
32
|
+
/** Get all entries. */
|
|
33
|
+
getEntries(): CostEntry[];
|
|
34
|
+
/** Get session elapsed time in seconds. */
|
|
35
|
+
getElapsedSeconds(): number;
|
|
36
|
+
/** Format elapsed as human-readable. */
|
|
37
|
+
formatElapsed(): string;
|
|
38
|
+
/** Reset all tracking. */
|
|
39
|
+
reset(): void;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=cost-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-tracker.d.ts","sourceRoot":"","sources":["../../../src/session/cost-tracker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,YAAY,CAAa;IAEjC,6BAA6B;IAC7B,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAazF,0CAA0C;IAC1C,UAAU,IAAI,WAAW;IA8BzB,uBAAuB;IACvB,UAAU,IAAI,SAAS,EAAE;IAIzB,2CAA2C;IAC3C,iBAAiB,IAAI,MAAM;IAI3B,wCAAwC;IACxC,aAAa,IAAI,MAAM;IAUvB,0BAA0B;IAC1B,KAAK,IAAI,IAAI;CAId"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CostTracker — tracks token usage and estimates cost per session.
|
|
3
|
+
*
|
|
4
|
+
* Local models have no direct cost, but tracking usage helps
|
|
5
|
+
* understand resource consumption and compare models.
|
|
6
|
+
*/
|
|
7
|
+
export class CostTracker {
|
|
8
|
+
entries = [];
|
|
9
|
+
sessionStart = Date.now();
|
|
10
|
+
/** Record a turn's usage. */
|
|
11
|
+
record(model, inputTokens, outputTokens, toolCalls) {
|
|
12
|
+
this.entries.push({
|
|
13
|
+
timestamp: new Date(),
|
|
14
|
+
model,
|
|
15
|
+
inputTokens,
|
|
16
|
+
outputTokens,
|
|
17
|
+
toolCalls,
|
|
18
|
+
duration: Date.now() - (this.entries.length > 0
|
|
19
|
+
? this.entries[this.entries.length - 1].timestamp.getTime()
|
|
20
|
+
: this.sessionStart),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/** Get a summary of all tracked usage. */
|
|
24
|
+
getSummary() {
|
|
25
|
+
let totalInput = 0;
|
|
26
|
+
let totalOutput = 0;
|
|
27
|
+
let totalToolCalls = 0;
|
|
28
|
+
let totalDuration = 0;
|
|
29
|
+
let model = 'unknown';
|
|
30
|
+
for (const entry of this.entries) {
|
|
31
|
+
totalInput += entry.inputTokens;
|
|
32
|
+
totalOutput += entry.outputTokens;
|
|
33
|
+
totalToolCalls += entry.toolCalls;
|
|
34
|
+
totalDuration += entry.duration;
|
|
35
|
+
model = entry.model;
|
|
36
|
+
}
|
|
37
|
+
const totalTokens = totalInput + totalOutput;
|
|
38
|
+
const turns = this.entries.length;
|
|
39
|
+
return {
|
|
40
|
+
totalInputTokens: totalInput,
|
|
41
|
+
totalOutputTokens: totalOutput,
|
|
42
|
+
totalTokens,
|
|
43
|
+
totalToolCalls,
|
|
44
|
+
totalDuration,
|
|
45
|
+
turns,
|
|
46
|
+
avgTokensPerTurn: turns > 0 ? Math.round(totalTokens / turns) : 0,
|
|
47
|
+
model,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** Get all entries. */
|
|
51
|
+
getEntries() {
|
|
52
|
+
return [...this.entries];
|
|
53
|
+
}
|
|
54
|
+
/** Get session elapsed time in seconds. */
|
|
55
|
+
getElapsedSeconds() {
|
|
56
|
+
return Math.round((Date.now() - this.sessionStart) / 1000);
|
|
57
|
+
}
|
|
58
|
+
/** Format elapsed as human-readable. */
|
|
59
|
+
formatElapsed() {
|
|
60
|
+
const secs = this.getElapsedSeconds();
|
|
61
|
+
if (secs < 60)
|
|
62
|
+
return `${secs}s`;
|
|
63
|
+
const mins = Math.floor(secs / 60);
|
|
64
|
+
const remainder = secs % 60;
|
|
65
|
+
if (mins < 60)
|
|
66
|
+
return `${mins}m ${remainder}s`;
|
|
67
|
+
const hours = Math.floor(mins / 60);
|
|
68
|
+
return `${hours}h ${mins % 60}m`;
|
|
69
|
+
}
|
|
70
|
+
/** Reset all tracking. */
|
|
71
|
+
reset() {
|
|
72
|
+
this.entries = [];
|
|
73
|
+
this.sessionStart = Date.now();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=cost-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-tracker.js","sourceRoot":"","sources":["../../../src/session/cost-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProjectContext — auto-discover project language, framework, and structure.
|
|
3
|
+
*/
|
|
4
|
+
import type { ProjectContext } from '../core/types.js';
|
|
5
|
+
export declare function discoverProject(rootDir: string): Promise<ProjectContext>;
|
|
6
|
+
//# sourceMappingURL=project-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-context.d.ts","sourceRoot":"","sources":["../../../src/session/project-context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEtD,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CA8F9E"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProjectContext — auto-discover project language, framework, and structure.
|
|
3
|
+
*/
|
|
4
|
+
import { readFile, stat, readdir } from 'fs/promises';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { spawn } from 'child_process';
|
|
7
|
+
export async function discoverProject(rootDir) {
|
|
8
|
+
const context = {
|
|
9
|
+
rootDir,
|
|
10
|
+
language: 'unknown',
|
|
11
|
+
relevantFiles: [],
|
|
12
|
+
};
|
|
13
|
+
const checks = await Promise.allSettled([
|
|
14
|
+
fileExists(join(rootDir, 'package.json')),
|
|
15
|
+
fileExists(join(rootDir, 'tsconfig.json')),
|
|
16
|
+
fileExists(join(rootDir, 'Cargo.toml')),
|
|
17
|
+
fileExists(join(rootDir, 'pyproject.toml')),
|
|
18
|
+
fileExists(join(rootDir, 'requirements.txt')),
|
|
19
|
+
fileExists(join(rootDir, 'go.mod')),
|
|
20
|
+
fileExists(join(rootDir, 'pom.xml')),
|
|
21
|
+
fileExists(join(rootDir, 'build.gradle')),
|
|
22
|
+
fileExists(join(rootDir, '.git')),
|
|
23
|
+
fileExists(join(rootDir, 'Dockerfile')),
|
|
24
|
+
]);
|
|
25
|
+
const exists = checks.map(c => c.status === 'fulfilled' && c.value);
|
|
26
|
+
// Language detection
|
|
27
|
+
if (exists[1]) {
|
|
28
|
+
context.language = 'typescript';
|
|
29
|
+
context.packageManager = 'npm';
|
|
30
|
+
}
|
|
31
|
+
else if (exists[0]) {
|
|
32
|
+
context.language = 'javascript';
|
|
33
|
+
context.packageManager = 'npm';
|
|
34
|
+
}
|
|
35
|
+
if (exists[2]) {
|
|
36
|
+
context.language = 'rust';
|
|
37
|
+
context.packageManager = 'cargo';
|
|
38
|
+
}
|
|
39
|
+
if (exists[3] || exists[4]) {
|
|
40
|
+
context.language = 'python';
|
|
41
|
+
context.packageManager = 'pip';
|
|
42
|
+
}
|
|
43
|
+
if (exists[5]) {
|
|
44
|
+
context.language = 'go';
|
|
45
|
+
context.packageManager = 'go';
|
|
46
|
+
}
|
|
47
|
+
if (exists[6] || exists[7]) {
|
|
48
|
+
context.language = 'java';
|
|
49
|
+
context.packageManager = 'maven';
|
|
50
|
+
}
|
|
51
|
+
// Framework detection from package.json
|
|
52
|
+
if (exists[0]) {
|
|
53
|
+
try {
|
|
54
|
+
const pkg = JSON.parse(await readFile(join(rootDir, 'package.json'), 'utf-8'));
|
|
55
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
56
|
+
if (deps['next'])
|
|
57
|
+
context.framework = 'next.js';
|
|
58
|
+
else if (deps['nuxt'])
|
|
59
|
+
context.framework = 'nuxt';
|
|
60
|
+
else if (deps['@angular/core'])
|
|
61
|
+
context.framework = 'angular';
|
|
62
|
+
else if (deps['vue'])
|
|
63
|
+
context.framework = 'vue';
|
|
64
|
+
else if (deps['react'])
|
|
65
|
+
context.framework = 'react';
|
|
66
|
+
else if (deps['express'])
|
|
67
|
+
context.framework = 'express';
|
|
68
|
+
else if (deps['fastify'])
|
|
69
|
+
context.framework = 'fastify';
|
|
70
|
+
else if (deps['hono'])
|
|
71
|
+
context.framework = 'hono';
|
|
72
|
+
// Detect package manager
|
|
73
|
+
if (await fileExists(join(rootDir, 'pnpm-lock.yaml')))
|
|
74
|
+
context.packageManager = 'pnpm';
|
|
75
|
+
else if (await fileExists(join(rootDir, 'yarn.lock')))
|
|
76
|
+
context.packageManager = 'yarn';
|
|
77
|
+
else if (await fileExists(join(rootDir, 'bun.lockb')))
|
|
78
|
+
context.packageManager = 'bun';
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// ignore parse errors
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Git branch
|
|
85
|
+
if (exists[8]) {
|
|
86
|
+
try {
|
|
87
|
+
context.gitBranch = await getGitBranch(rootDir);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// not a git repo or git not available
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// CMDR.md workspace instructions (check both CMDR.md and .cmdr/instructions.md)
|
|
94
|
+
const instructionParts = [];
|
|
95
|
+
try {
|
|
96
|
+
const cmdrMd = await readFile(join(rootDir, 'CMDR.md'), 'utf-8');
|
|
97
|
+
if (cmdrMd.trim())
|
|
98
|
+
instructionParts.push(cmdrMd.trim());
|
|
99
|
+
}
|
|
100
|
+
catch { /* no CMDR.md */ }
|
|
101
|
+
try {
|
|
102
|
+
const dotCmdrMd = await readFile(join(rootDir, '.cmdr', 'instructions.md'), 'utf-8');
|
|
103
|
+
if (dotCmdrMd.trim())
|
|
104
|
+
instructionParts.push(dotCmdrMd.trim());
|
|
105
|
+
}
|
|
106
|
+
catch { /* no .cmdr/instructions.md */ }
|
|
107
|
+
if (instructionParts.length > 0) {
|
|
108
|
+
context.cmdrInstructions = instructionParts.join('\n\n');
|
|
109
|
+
}
|
|
110
|
+
// Key files
|
|
111
|
+
try {
|
|
112
|
+
const entries = await readdir(rootDir);
|
|
113
|
+
const keyFiles = entries.filter(f => /^(readme|license|changelog|makefile|dockerfile|docker-compose)/i.test(f) ||
|
|
114
|
+
/\.(md|toml|yaml|yml|json)$/i.test(f)).slice(0, 20);
|
|
115
|
+
context.relevantFiles = keyFiles;
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// ignore
|
|
119
|
+
}
|
|
120
|
+
return context;
|
|
121
|
+
}
|
|
122
|
+
async function fileExists(path) {
|
|
123
|
+
try {
|
|
124
|
+
await stat(path);
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function getGitBranch(cwd) {
|
|
132
|
+
return new Promise((resolve, reject) => {
|
|
133
|
+
const child = spawn('git', ['branch', '--show-current'], {
|
|
134
|
+
cwd, stdio: ['ignore', 'pipe', 'pipe'],
|
|
135
|
+
});
|
|
136
|
+
const chunks = [];
|
|
137
|
+
child.stdout.on('data', (c) => chunks.push(c));
|
|
138
|
+
child.on('close', (code) => {
|
|
139
|
+
if (code === 0)
|
|
140
|
+
resolve(Buffer.concat(chunks).toString('utf-8').trim());
|
|
141
|
+
else
|
|
142
|
+
reject(new Error('git failed'));
|
|
143
|
+
});
|
|
144
|
+
child.on('error', reject);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=project-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-context.js","sourceRoot":"","sources":["../../../src/session/project-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PromptBuilder — composable prompt construction pipeline.
|
|
3
|
+
*/
|
|
4
|
+
import type { ProjectContext } from '../core/types.js';
|
|
5
|
+
export interface PromptBuildOptions {
|
|
6
|
+
basePrompt: string;
|
|
7
|
+
projectContext: ProjectContext;
|
|
8
|
+
model: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildSystemPrompt(options: PromptBuildOptions): string;
|
|
11
|
+
//# sourceMappingURL=prompt-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-builder.d.ts","sourceRoot":"","sources":["../../../src/session/prompt-builder.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEtD,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,cAAc,CAAA;IAC9B,KAAK,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CA8BrE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PromptBuilder — composable prompt construction pipeline.
|
|
3
|
+
*/
|
|
4
|
+
export function buildSystemPrompt(options) {
|
|
5
|
+
const parts = [options.basePrompt];
|
|
6
|
+
// Inject project context
|
|
7
|
+
const ctx = options.projectContext;
|
|
8
|
+
const contextParts = [];
|
|
9
|
+
if (ctx.language !== 'unknown') {
|
|
10
|
+
contextParts.push(`Language: ${ctx.language}`);
|
|
11
|
+
}
|
|
12
|
+
if (ctx.framework) {
|
|
13
|
+
contextParts.push(`Framework: ${ctx.framework}`);
|
|
14
|
+
}
|
|
15
|
+
if (ctx.packageManager) {
|
|
16
|
+
contextParts.push(`Package manager: ${ctx.packageManager}`);
|
|
17
|
+
}
|
|
18
|
+
if (ctx.gitBranch) {
|
|
19
|
+
contextParts.push(`Git branch: ${ctx.gitBranch}`);
|
|
20
|
+
}
|
|
21
|
+
if (contextParts.length > 0) {
|
|
22
|
+
parts.push(`\n\nProject context:\n${contextParts.join('\n')}\nRoot: ${ctx.rootDir}`);
|
|
23
|
+
}
|
|
24
|
+
// Inject CMDR.md workspace instructions
|
|
25
|
+
if (ctx.cmdrInstructions) {
|
|
26
|
+
parts.push(`\n\n<project_instructions>\nThe user has provided the following instructions for this project. Follow them unless they conflict with safety:\n\n${ctx.cmdrInstructions}\n</project_instructions>`);
|
|
27
|
+
}
|
|
28
|
+
return parts.join('');
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=prompt-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-builder.js","sourceRoot":"","sources":["../../../src/session/prompt-builder.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,MAAM,UAAU,iBAAiB,CAAC,OAA2B;IAC3D,MAAM,KAAK,GAAa,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IAE5C,yBAAyB;IACzB,MAAM,GAAG,GAAG,OAAO,CAAC,cAAc,CAAA;IAClC,MAAM,YAAY,GAAa,EAAE,CAAA;IAEjC,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC/B,YAAY,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAA;IAChD,CAAC;IACD,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,YAAY,CAAC,IAAI,CAAC,cAAc,GAAG,CAAC,SAAS,EAAE,CAAC,CAAA;IAClD,CAAC;IACD,IAAI,GAAG,CAAC,cAAc,EAAE,CAAC;QACvB,YAAY,CAAC,IAAI,CAAC,oBAAoB,GAAG,CAAC,cAAc,EAAE,CAAC,CAAA;IAC7D,CAAC;IACD,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,YAAY,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,SAAS,EAAE,CAAC,CAAA;IACnD,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,yBAAyB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;IACtF,CAAC;IAED,wCAAwC;IACxC,IAAI,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,mJAAmJ,GAAG,CAAC,gBAAgB,2BAA2B,CAAC,CAAA;IAChN,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AACvB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionManager — conversation history with token counting and compaction.
|
|
3
|
+
*/
|
|
4
|
+
import type { LLMMessage, LLMAdapter, SessionState, ProjectContext, TokenUsage } from '../core/types.js';
|
|
5
|
+
export declare class SessionManager {
|
|
6
|
+
private session;
|
|
7
|
+
private compactionConfig;
|
|
8
|
+
constructor(projectContext: ProjectContext, maxContextTokens?: number);
|
|
9
|
+
get id(): string;
|
|
10
|
+
get messages(): LLMMessage[];
|
|
11
|
+
get tokenCount(): number;
|
|
12
|
+
get projectContext(): ProjectContext;
|
|
13
|
+
addMessage(message: LLMMessage): void;
|
|
14
|
+
addMessages(messages: LLMMessage[]): void;
|
|
15
|
+
shouldCompact(): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Multi-stage compaction: truncate tool results → LLM summary → hard truncation.
|
|
18
|
+
* Returns the number of tokens saved.
|
|
19
|
+
*/
|
|
20
|
+
compact(adapter: LLMAdapter, model: string): Promise<{
|
|
21
|
+
before: number;
|
|
22
|
+
after: number;
|
|
23
|
+
tokensSaved: number;
|
|
24
|
+
}>;
|
|
25
|
+
clear(): void;
|
|
26
|
+
getTokenUsage(): TokenUsage;
|
|
27
|
+
getState(): SessionState;
|
|
28
|
+
addRelevantFile(file: string): void;
|
|
29
|
+
/** Replace session messages with the agent's current history. */
|
|
30
|
+
syncFromAgent(messages: LLMMessage[]): void;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=session-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../../src/session/session-manager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AASxG,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,gBAAgB,CAAkB;gBAE9B,cAAc,EAAE,cAAc,EAAE,gBAAgB,SAAQ;IAgBpE,IAAI,EAAE,IAAI,MAAM,CAA2B;IAC3C,IAAI,QAAQ,IAAI,UAAU,EAAE,CAAiC;IAC7D,IAAI,UAAU,IAAI,MAAM,CAAmC;IAC3D,IAAI,cAAc,IAAI,cAAc,CAAuC;IAE3E,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAMrC,WAAW,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI;IAQzC,aAAa,IAAI,OAAO;IAIxB;;;OAGG;IACG,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAqBlH,KAAK,IAAI,IAAI;IAKb,aAAa,IAAI,UAAU;IAO3B,QAAQ,IAAI,YAAY;IAIxB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAMnC,iEAAiE;IACjE,aAAa,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI;CAK5C"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionManager — conversation history with token counting and compaction.
|
|
3
|
+
*/
|
|
4
|
+
import { countMessageTokens } from '../llm/token-counter.js';
|
|
5
|
+
import { shouldCompact as checkCompact, compactHistory, DEFAULT_COMPACTION_CONFIG, } from './compaction.js';
|
|
6
|
+
export class SessionManager {
|
|
7
|
+
session;
|
|
8
|
+
compactionConfig;
|
|
9
|
+
constructor(projectContext, maxContextTokens = 32768) {
|
|
10
|
+
this.session = {
|
|
11
|
+
id: `session_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
|
|
12
|
+
messages: [],
|
|
13
|
+
tokenCount: 0,
|
|
14
|
+
maxContextTokens,
|
|
15
|
+
projectContext,
|
|
16
|
+
createdAt: new Date(),
|
|
17
|
+
lastActivity: new Date(),
|
|
18
|
+
};
|
|
19
|
+
this.compactionConfig = {
|
|
20
|
+
...DEFAULT_COMPACTION_CONFIG,
|
|
21
|
+
maxContextTokens,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
get id() { return this.session.id; }
|
|
25
|
+
get messages() { return this.session.messages; }
|
|
26
|
+
get tokenCount() { return this.session.tokenCount; }
|
|
27
|
+
get projectContext() { return this.session.projectContext; }
|
|
28
|
+
addMessage(message) {
|
|
29
|
+
this.session.messages.push(message);
|
|
30
|
+
this.session.tokenCount = countMessageTokens(this.session.messages);
|
|
31
|
+
this.session.lastActivity = new Date();
|
|
32
|
+
}
|
|
33
|
+
addMessages(messages) {
|
|
34
|
+
for (const msg of messages) {
|
|
35
|
+
this.session.messages.push(msg);
|
|
36
|
+
}
|
|
37
|
+
this.session.tokenCount = countMessageTokens(this.session.messages);
|
|
38
|
+
this.session.lastActivity = new Date();
|
|
39
|
+
}
|
|
40
|
+
shouldCompact() {
|
|
41
|
+
return checkCompact(this.session.messages, this.session.tokenCount, this.compactionConfig);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Multi-stage compaction: truncate tool results → LLM summary → hard truncation.
|
|
45
|
+
* Returns the number of tokens saved.
|
|
46
|
+
*/
|
|
47
|
+
async compact(adapter, model) {
|
|
48
|
+
const before = this.session.tokenCount;
|
|
49
|
+
const beforeCount = this.session.messages.length;
|
|
50
|
+
const result = await compactHistory(this.session.messages, this.compactionConfig, adapter, model);
|
|
51
|
+
this.session.messages = result.messages;
|
|
52
|
+
this.session.tokenCount = countMessageTokens(this.session.messages);
|
|
53
|
+
return {
|
|
54
|
+
before: beforeCount,
|
|
55
|
+
after: this.session.messages.length,
|
|
56
|
+
tokensSaved: result.tokensSaved,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
clear() {
|
|
60
|
+
this.session.messages = [];
|
|
61
|
+
this.session.tokenCount = 0;
|
|
62
|
+
}
|
|
63
|
+
getTokenUsage() {
|
|
64
|
+
return {
|
|
65
|
+
input_tokens: this.session.tokenCount,
|
|
66
|
+
output_tokens: 0,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
getState() {
|
|
70
|
+
return { ...this.session };
|
|
71
|
+
}
|
|
72
|
+
addRelevantFile(file) {
|
|
73
|
+
if (!this.session.projectContext.relevantFiles.includes(file)) {
|
|
74
|
+
this.session.projectContext.relevantFiles.push(file);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** Replace session messages with the agent's current history. */
|
|
78
|
+
syncFromAgent(messages) {
|
|
79
|
+
this.session.messages = [...messages];
|
|
80
|
+
this.session.tokenCount = countMessageTokens(this.session.messages);
|
|
81
|
+
this.session.lastActivity = new Date();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=session-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../../src/session/session-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session persistence — save/load conversation sessions to ~/.cmdr/sessions/.
|
|
3
|
+
*/
|
|
4
|
+
import type { LLMMessage, SessionState } from '../core/types.js';
|
|
5
|
+
export interface SavedSession {
|
|
6
|
+
id: string;
|
|
7
|
+
messages: LLMMessage[];
|
|
8
|
+
projectRoot: string;
|
|
9
|
+
model: string;
|
|
10
|
+
createdAt: string;
|
|
11
|
+
lastActivity: string;
|
|
12
|
+
toolsUsed?: string[];
|
|
13
|
+
summary?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function saveSession(sessionState: SessionState, model: string): Promise<string>;
|
|
16
|
+
export declare function loadSession(sessionId: string): Promise<SavedSession | null>;
|
|
17
|
+
/** Find the most recent session for a given project directory. */
|
|
18
|
+
export declare function findRecentSession(projectRoot: string): Promise<SavedSession | null>;
|
|
19
|
+
export declare function listSessions(): Promise<Array<{
|
|
20
|
+
id: string;
|
|
21
|
+
projectRoot: string;
|
|
22
|
+
model: string;
|
|
23
|
+
lastActivity: string;
|
|
24
|
+
messageCount: number;
|
|
25
|
+
toolsUsed?: string[];
|
|
26
|
+
summary?: string;
|
|
27
|
+
}>>;
|
|
28
|
+
/** Get the ~/.cmdr directory path. */
|
|
29
|
+
export declare function getCmdrDir(): string;
|
|
30
|
+
export declare class DebouncedSaver {
|
|
31
|
+
private timer;
|
|
32
|
+
private readonly intervalMs;
|
|
33
|
+
constructor(intervalMs?: number);
|
|
34
|
+
/**
|
|
35
|
+
* Schedule a save. If one is already pending, it's a no-op (coalesce).
|
|
36
|
+
* Guaranteed at most once per intervalMs.
|
|
37
|
+
*/
|
|
38
|
+
schedule(fn: () => Promise<void>): void;
|
|
39
|
+
/** Cancel any pending save. */
|
|
40
|
+
cancel(): void;
|
|
41
|
+
/** Flush immediately (e.g., on exit). */
|
|
42
|
+
flush(fn: () => Promise<void>): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=session-persistence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-persistence.d.ts","sourceRoot":"","sources":["../../../src/session/session-persistence.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAkB,MAAM,kBAAkB,CAAA;AAKhF,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,UAAU,EAAE,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAoCD,wBAAsB,WAAW,CAC/B,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAiBjB;AAED,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAQjF;AAED,kEAAkE;AAClE,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAKzF;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,KAAK,CAAC;IAClD,EAAE,EAAE,MAAM,CAAA;IACV,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAC,CAAC,CAuCF;AAED,sCAAsC;AACtC,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAMD,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAA6C;IAC1D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;gBAEvB,UAAU,SAAO;IAI7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAYvC,+BAA+B;IAC/B,MAAM,IAAI,IAAI;IAOd,yCAAyC;IACnC,KAAK,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAIpD"}
|