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.
Files changed (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +238 -0
  3. package/dist/bin/cmdr.d.ts +9 -0
  4. package/dist/bin/cmdr.d.ts.map +1 -0
  5. package/dist/bin/cmdr.js +49 -0
  6. package/dist/bin/cmdr.js.map +1 -0
  7. package/dist/src/cli/args.d.ts +19 -0
  8. package/dist/src/cli/args.d.ts.map +1 -0
  9. package/dist/src/cli/args.js +89 -0
  10. package/dist/src/cli/args.js.map +1 -0
  11. package/dist/src/cli/commands.d.ts +12 -0
  12. package/dist/src/cli/commands.d.ts.map +1 -0
  13. package/dist/src/cli/commands.js +400 -0
  14. package/dist/src/cli/commands.js.map +1 -0
  15. package/dist/src/cli/renderer.d.ts +8 -0
  16. package/dist/src/cli/renderer.d.ts.map +1 -0
  17. package/dist/src/cli/renderer.js +47 -0
  18. package/dist/src/cli/renderer.js.map +1 -0
  19. package/dist/src/cli/repl.d.ts +18 -0
  20. package/dist/src/cli/repl.d.ts.map +1 -0
  21. package/dist/src/cli/repl.js +751 -0
  22. package/dist/src/cli/repl.js.map +1 -0
  23. package/dist/src/cli/spinner.d.ts +16 -0
  24. package/dist/src/cli/spinner.d.ts.map +1 -0
  25. package/dist/src/cli/spinner.js +233 -0
  26. package/dist/src/cli/spinner.js.map +1 -0
  27. package/dist/src/cli/theme.d.ts +95 -0
  28. package/dist/src/cli/theme.d.ts.map +1 -0
  29. package/dist/src/cli/theme.js +178 -0
  30. package/dist/src/cli/theme.js.map +1 -0
  31. package/dist/src/communication/message-bus.d.ts +35 -0
  32. package/dist/src/communication/message-bus.d.ts.map +1 -0
  33. package/dist/src/communication/message-bus.js +60 -0
  34. package/dist/src/communication/message-bus.js.map +1 -0
  35. package/dist/src/communication/shared-memory.d.ts +19 -0
  36. package/dist/src/communication/shared-memory.d.ts.map +1 -0
  37. package/dist/src/communication/shared-memory.js +37 -0
  38. package/dist/src/communication/shared-memory.js.map +1 -0
  39. package/dist/src/communication/task-queue.d.ts +50 -0
  40. package/dist/src/communication/task-queue.d.ts.map +1 -0
  41. package/dist/src/communication/task-queue.js +158 -0
  42. package/dist/src/communication/task-queue.js.map +1 -0
  43. package/dist/src/config/config-loader.d.ts +23 -0
  44. package/dist/src/config/config-loader.d.ts.map +1 -0
  45. package/dist/src/config/config-loader.js +91 -0
  46. package/dist/src/config/config-loader.js.map +1 -0
  47. package/dist/src/config/defaults.d.ts +6 -0
  48. package/dist/src/config/defaults.d.ts.map +1 -0
  49. package/dist/src/config/defaults.js +21 -0
  50. package/dist/src/config/defaults.js.map +1 -0
  51. package/dist/src/config/schema.d.ts +135 -0
  52. package/dist/src/config/schema.d.ts.map +1 -0
  53. package/dist/src/config/schema.js +35 -0
  54. package/dist/src/config/schema.js.map +1 -0
  55. package/dist/src/config/telemetry.d.ts +41 -0
  56. package/dist/src/config/telemetry.d.ts.map +1 -0
  57. package/dist/src/config/telemetry.js +57 -0
  58. package/dist/src/config/telemetry.js.map +1 -0
  59. package/dist/src/core/agent-pool.d.ts +40 -0
  60. package/dist/src/core/agent-pool.d.ts.map +1 -0
  61. package/dist/src/core/agent-pool.js +66 -0
  62. package/dist/src/core/agent-pool.js.map +1 -0
  63. package/dist/src/core/agent-runner.d.ts +51 -0
  64. package/dist/src/core/agent-runner.d.ts.map +1 -0
  65. package/dist/src/core/agent-runner.js +251 -0
  66. package/dist/src/core/agent-runner.js.map +1 -0
  67. package/dist/src/core/agent.d.ts +34 -0
  68. package/dist/src/core/agent.d.ts.map +1 -0
  69. package/dist/src/core/agent.js +143 -0
  70. package/dist/src/core/agent.js.map +1 -0
  71. package/dist/src/core/intent.d.ts +33 -0
  72. package/dist/src/core/intent.d.ts.map +1 -0
  73. package/dist/src/core/intent.js +91 -0
  74. package/dist/src/core/intent.js.map +1 -0
  75. package/dist/src/core/orchestrator.d.ts +43 -0
  76. package/dist/src/core/orchestrator.d.ts.map +1 -0
  77. package/dist/src/core/orchestrator.js +115 -0
  78. package/dist/src/core/orchestrator.js.map +1 -0
  79. package/dist/src/core/permissions.d.ts +36 -0
  80. package/dist/src/core/permissions.d.ts.map +1 -0
  81. package/dist/src/core/permissions.js +129 -0
  82. package/dist/src/core/permissions.js.map +1 -0
  83. package/dist/src/core/presets.d.ts +12 -0
  84. package/dist/src/core/presets.d.ts.map +1 -0
  85. package/dist/src/core/presets.js +148 -0
  86. package/dist/src/core/presets.js.map +1 -0
  87. package/dist/src/core/team.d.ts +44 -0
  88. package/dist/src/core/team.d.ts.map +1 -0
  89. package/dist/src/core/team.js +156 -0
  90. package/dist/src/core/team.js.map +1 -0
  91. package/dist/src/core/types.d.ts +257 -0
  92. package/dist/src/core/types.d.ts.map +1 -0
  93. package/dist/src/core/types.js +7 -0
  94. package/dist/src/core/types.js.map +1 -0
  95. package/dist/src/index.d.ts +44 -0
  96. package/dist/src/index.d.ts.map +1 -0
  97. package/dist/src/index.js +45 -0
  98. package/dist/src/index.js.map +1 -0
  99. package/dist/src/llm/adapter.d.ts +5 -0
  100. package/dist/src/llm/adapter.d.ts.map +1 -0
  101. package/dist/src/llm/adapter.js +5 -0
  102. package/dist/src/llm/adapter.js.map +1 -0
  103. package/dist/src/llm/model-registry.d.ts +14 -0
  104. package/dist/src/llm/model-registry.d.ts.map +1 -0
  105. package/dist/src/llm/model-registry.js +30 -0
  106. package/dist/src/llm/model-registry.js.map +1 -0
  107. package/dist/src/llm/ollama.d.ts +26 -0
  108. package/dist/src/llm/ollama.d.ts.map +1 -0
  109. package/dist/src/llm/ollama.js +375 -0
  110. package/dist/src/llm/ollama.js.map +1 -0
  111. package/dist/src/llm/token-counter.d.ts +11 -0
  112. package/dist/src/llm/token-counter.d.ts.map +1 -0
  113. package/dist/src/llm/token-counter.js +35 -0
  114. package/dist/src/llm/token-counter.js.map +1 -0
  115. package/dist/src/plugins/mcp-client.d.ts +38 -0
  116. package/dist/src/plugins/mcp-client.d.ts.map +1 -0
  117. package/dist/src/plugins/mcp-client.js +113 -0
  118. package/dist/src/plugins/mcp-client.js.map +1 -0
  119. package/dist/src/plugins/plugin-manager.d.ts +37 -0
  120. package/dist/src/plugins/plugin-manager.d.ts.map +1 -0
  121. package/dist/src/plugins/plugin-manager.js +146 -0
  122. package/dist/src/plugins/plugin-manager.js.map +1 -0
  123. package/dist/src/scheduling/semaphore.d.ts +20 -0
  124. package/dist/src/scheduling/semaphore.d.ts.map +1 -0
  125. package/dist/src/scheduling/semaphore.js +52 -0
  126. package/dist/src/scheduling/semaphore.js.map +1 -0
  127. package/dist/src/scheduling/strategies.d.ts +39 -0
  128. package/dist/src/scheduling/strategies.d.ts.map +1 -0
  129. package/dist/src/scheduling/strategies.js +88 -0
  130. package/dist/src/scheduling/strategies.js.map +1 -0
  131. package/dist/src/session/compaction.d.ts +32 -0
  132. package/dist/src/session/compaction.d.ts.map +1 -0
  133. package/dist/src/session/compaction.js +172 -0
  134. package/dist/src/session/compaction.js.map +1 -0
  135. package/dist/src/session/cost-tracker.d.ts +41 -0
  136. package/dist/src/session/cost-tracker.d.ts.map +1 -0
  137. package/dist/src/session/cost-tracker.js +76 -0
  138. package/dist/src/session/cost-tracker.js.map +1 -0
  139. package/dist/src/session/project-context.d.ts +6 -0
  140. package/dist/src/session/project-context.d.ts.map +1 -0
  141. package/dist/src/session/project-context.js +147 -0
  142. package/dist/src/session/project-context.js.map +1 -0
  143. package/dist/src/session/prompt-builder.d.ts +11 -0
  144. package/dist/src/session/prompt-builder.d.ts.map +1 -0
  145. package/dist/src/session/prompt-builder.js +30 -0
  146. package/dist/src/session/prompt-builder.js.map +1 -0
  147. package/dist/src/session/session-manager.d.ts +32 -0
  148. package/dist/src/session/session-manager.d.ts.map +1 -0
  149. package/dist/src/session/session-manager.js +84 -0
  150. package/dist/src/session/session-manager.js.map +1 -0
  151. package/dist/src/session/session-persistence.d.ts +44 -0
  152. package/dist/src/session/session-persistence.d.ts.map +1 -0
  153. package/dist/src/session/session-persistence.js +150 -0
  154. package/dist/src/session/session-persistence.js.map +1 -0
  155. package/dist/src/session/undo-manager.d.ts +35 -0
  156. package/dist/src/session/undo-manager.d.ts.map +1 -0
  157. package/dist/src/session/undo-manager.js +79 -0
  158. package/dist/src/session/undo-manager.js.map +1 -0
  159. package/dist/src/tools/built-in/ask-user.d.ts +7 -0
  160. package/dist/src/tools/built-in/ask-user.d.ts.map +1 -0
  161. package/dist/src/tools/built-in/ask-user.js +28 -0
  162. package/dist/src/tools/built-in/ask-user.js.map +1 -0
  163. package/dist/src/tools/built-in/bash.d.ts +9 -0
  164. package/dist/src/tools/built-in/bash.d.ts.map +1 -0
  165. package/dist/src/tools/built-in/bash.js +67 -0
  166. package/dist/src/tools/built-in/bash.js.map +1 -0
  167. package/dist/src/tools/built-in/file-edit.d.ts +9 -0
  168. package/dist/src/tools/built-in/file-edit.d.ts.map +1 -0
  169. package/dist/src/tools/built-in/file-edit.js +39 -0
  170. package/dist/src/tools/built-in/file-edit.js.map +1 -0
  171. package/dist/src/tools/built-in/file-read.d.ts +9 -0
  172. package/dist/src/tools/built-in/file-read.d.ts.map +1 -0
  173. package/dist/src/tools/built-in/file-read.js +41 -0
  174. package/dist/src/tools/built-in/file-read.js.map +1 -0
  175. package/dist/src/tools/built-in/file-write.d.ts +8 -0
  176. package/dist/src/tools/built-in/file-write.d.ts.map +1 -0
  177. package/dist/src/tools/built-in/file-write.js +29 -0
  178. package/dist/src/tools/built-in/file-write.js.map +1 -0
  179. package/dist/src/tools/built-in/git-commit.d.ts +12 -0
  180. package/dist/src/tools/built-in/git-commit.d.ts.map +1 -0
  181. package/dist/src/tools/built-in/git-commit.js +96 -0
  182. package/dist/src/tools/built-in/git-commit.js.map +1 -0
  183. package/dist/src/tools/built-in/git-diff.d.ts +8 -0
  184. package/dist/src/tools/built-in/git-diff.d.ts.map +1 -0
  185. package/dist/src/tools/built-in/git-diff.js +43 -0
  186. package/dist/src/tools/built-in/git-diff.js.map +1 -0
  187. package/dist/src/tools/built-in/git-log.d.ts +8 -0
  188. package/dist/src/tools/built-in/git-log.d.ts.map +1 -0
  189. package/dist/src/tools/built-in/git-log.js +39 -0
  190. package/dist/src/tools/built-in/git-log.js.map +1 -0
  191. package/dist/src/tools/built-in/glob.d.ts +8 -0
  192. package/dist/src/tools/built-in/glob.d.ts.map +1 -0
  193. package/dist/src/tools/built-in/glob.js +60 -0
  194. package/dist/src/tools/built-in/glob.js.map +1 -0
  195. package/dist/src/tools/built-in/grep.d.ts +9 -0
  196. package/dist/src/tools/built-in/grep.d.ts.map +1 -0
  197. package/dist/src/tools/built-in/grep.js +115 -0
  198. package/dist/src/tools/built-in/grep.js.map +1 -0
  199. package/dist/src/tools/built-in/index.d.ts +21 -0
  200. package/dist/src/tools/built-in/index.d.ts.map +1 -0
  201. package/dist/src/tools/built-in/index.js +30 -0
  202. package/dist/src/tools/built-in/index.js.map +1 -0
  203. package/dist/src/tools/built-in/think.d.ts +7 -0
  204. package/dist/src/tools/built-in/think.d.ts.map +1 -0
  205. package/dist/src/tools/built-in/think.js +18 -0
  206. package/dist/src/tools/built-in/think.js.map +1 -0
  207. package/dist/src/tools/built-in/web-fetch.d.ts +11 -0
  208. package/dist/src/tools/built-in/web-fetch.d.ts.map +1 -0
  209. package/dist/src/tools/built-in/web-fetch.js +70 -0
  210. package/dist/src/tools/built-in/web-fetch.js.map +1 -0
  211. package/dist/src/tools/executor.d.ts +25 -0
  212. package/dist/src/tools/executor.d.ts.map +1 -0
  213. package/dist/src/tools/executor.js +61 -0
  214. package/dist/src/tools/executor.js.map +1 -0
  215. package/dist/src/tools/registry.d.ts +25 -0
  216. package/dist/src/tools/registry.d.ts.map +1 -0
  217. package/dist/src/tools/registry.js +135 -0
  218. package/dist/src/tools/registry.js.map +1 -0
  219. 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"}