@mc1global/opencode-jarvis 0.8.1 → 0.10.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 (91) hide show
  1. package/dist/application/azure-sync/push-use-cases.d.ts +6 -1
  2. package/dist/application/azure-sync/push-use-cases.d.ts.map +1 -1
  3. package/dist/application/azure-sync/push-use-cases.js +31 -5
  4. package/dist/application/azure-sync/push-use-cases.js.map +1 -1
  5. package/dist/application/bootstrap/index.d.ts +1 -1
  6. package/dist/application/bootstrap/index.d.ts.map +1 -1
  7. package/dist/application/bootstrap/index.js +1 -1
  8. package/dist/application/bootstrap/index.js.map +1 -1
  9. package/dist/application/bootstrap/use-cases.d.ts +16 -2
  10. package/dist/application/bootstrap/use-cases.d.ts.map +1 -1
  11. package/dist/application/bootstrap/use-cases.js +66 -215
  12. package/dist/application/bootstrap/use-cases.js.map +1 -1
  13. package/dist/application/config/config-write-service.d.ts +86 -0
  14. package/dist/application/config/config-write-service.d.ts.map +1 -0
  15. package/dist/application/config/config-write-service.js +237 -0
  16. package/dist/application/config/config-write-service.js.map +1 -0
  17. package/dist/application/config/index.d.ts +2 -0
  18. package/dist/application/config/index.d.ts.map +1 -1
  19. package/dist/application/config/index.js +1 -0
  20. package/dist/application/config/index.js.map +1 -1
  21. package/dist/application/context-memory/execution-journal-use-cases.d.ts +69 -0
  22. package/dist/application/context-memory/execution-journal-use-cases.d.ts.map +1 -0
  23. package/dist/application/context-memory/execution-journal-use-cases.js +89 -0
  24. package/dist/application/context-memory/execution-journal-use-cases.js.map +1 -0
  25. package/dist/cli/config-wizard.d.ts +14 -0
  26. package/dist/cli/config-wizard.d.ts.map +1 -0
  27. package/dist/cli/config-wizard.js +120 -0
  28. package/dist/cli/config-wizard.js.map +1 -0
  29. package/dist/cli/section-editors.d.ts +33 -0
  30. package/dist/cli/section-editors.d.ts.map +1 -0
  31. package/dist/cli/section-editors.js +286 -0
  32. package/dist/cli/section-editors.js.map +1 -0
  33. package/dist/cli/wizard-prompts.d.ts +76 -0
  34. package/dist/cli/wizard-prompts.d.ts.map +1 -0
  35. package/dist/cli/wizard-prompts.js +98 -0
  36. package/dist/cli/wizard-prompts.js.map +1 -0
  37. package/dist/domain/azure-sync/value-objects.d.ts +10 -0
  38. package/dist/domain/azure-sync/value-objects.d.ts.map +1 -1
  39. package/dist/domain/azure-sync/value-objects.js +24 -0
  40. package/dist/domain/azure-sync/value-objects.js.map +1 -1
  41. package/dist/domain/config/index.d.ts +1 -1
  42. package/dist/domain/config/index.d.ts.map +1 -1
  43. package/dist/domain/config/repositories.d.ts +26 -6
  44. package/dist/domain/config/repositories.d.ts.map +1 -1
  45. package/dist/domain/config/repositories.js +6 -6
  46. package/dist/domain/context-memory/entities.d.ts +50 -2
  47. package/dist/domain/context-memory/entities.d.ts.map +1 -1
  48. package/dist/domain/context-memory/entities.js +92 -2
  49. package/dist/domain/context-memory/entities.js.map +1 -1
  50. package/dist/domain/context-memory/repositories.d.ts +15 -2
  51. package/dist/domain/context-memory/repositories.d.ts.map +1 -1
  52. package/dist/domain/context-memory/value-objects.d.ts +18 -1
  53. package/dist/domain/context-memory/value-objects.d.ts.map +1 -1
  54. package/dist/domain/context-memory/value-objects.js +39 -1
  55. package/dist/domain/context-memory/value-objects.js.map +1 -1
  56. package/dist/hooks/config-command.d.ts +37 -0
  57. package/dist/hooks/config-command.d.ts.map +1 -0
  58. package/dist/hooks/config-command.js +68 -0
  59. package/dist/hooks/config-command.js.map +1 -0
  60. package/dist/hooks/execution-journal.d.ts +40 -0
  61. package/dist/hooks/execution-journal.d.ts.map +1 -0
  62. package/dist/hooks/execution-journal.js +102 -0
  63. package/dist/hooks/execution-journal.js.map +1 -0
  64. package/dist/hooks/first-run-guide.d.ts +2 -0
  65. package/dist/hooks/first-run-guide.d.ts.map +1 -1
  66. package/dist/hooks/first-run-guide.js +9 -0
  67. package/dist/hooks/first-run-guide.js.map +1 -1
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +58 -3
  70. package/dist/index.js.map +1 -1
  71. package/dist/infrastructure/azure-sync/azure-devops-client.d.ts.map +1 -1
  72. package/dist/infrastructure/azure-sync/azure-devops-client.js +9 -10
  73. package/dist/infrastructure/azure-sync/azure-devops-client.js.map +1 -1
  74. package/dist/infrastructure/config/index.d.ts +1 -0
  75. package/dist/infrastructure/config/index.d.ts.map +1 -1
  76. package/dist/infrastructure/config/index.js +1 -0
  77. package/dist/infrastructure/config/index.js.map +1 -1
  78. package/dist/infrastructure/config/yaml-config-writer.d.ts +16 -0
  79. package/dist/infrastructure/config/yaml-config-writer.d.ts.map +1 -0
  80. package/dist/infrastructure/config/yaml-config-writer.js +49 -0
  81. package/dist/infrastructure/config/yaml-config-writer.js.map +1 -0
  82. package/dist/infrastructure/context-memory/execution-journal-repository.d.ts +26 -0
  83. package/dist/infrastructure/context-memory/execution-journal-repository.d.ts.map +1 -0
  84. package/dist/infrastructure/context-memory/execution-journal-repository.js +110 -0
  85. package/dist/infrastructure/context-memory/execution-journal-repository.js.map +1 -0
  86. package/dist/tools/config-tools.d.ts +12 -0
  87. package/dist/tools/config-tools.d.ts.map +1 -0
  88. package/dist/tools/config-tools.js +136 -0
  89. package/dist/tools/config-tools.js.map +1 -0
  90. package/package.json +5 -2
  91. package/templates/agents-md.template.md +232 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-write-service.d.ts","sourceRoot":"","sources":["../../../src/application/config/config-write-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AAMtE,oCAAoC;AACpC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,8CAA8C;AAC9C,MAAM,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,gBAAgB,CAAC;AAIpE;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,SAAS,CAAC;AAelD;;GAEG;AACH,qBAAa,kBAAkB;IAI3B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAJ5B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsC;gBAG9C,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,qBAAqB;IAOnD;;;;;;;;;;;;;;;;OAgBG;IACH,aAAa,CAAC,WAAW,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;IA+ChG;;;;;OAKG;IACH,YAAY,CAAC,WAAW,EAAE,mBAAmB,GAAG,IAAI;IAUpD;;OAEG;IACH,mBAAmB,IAAI,SAAS,mBAAmB,EAAE;IAIrD;;;OAGG;IACH,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,GAAG,IAAI;IAMxE,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,yBAAyB;CAKlC;AAuED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,OAAO,EACjB,SAAS,EAAE,OAAO,GACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAgCrC"}
@@ -0,0 +1,237 @@
1
+ import { CONFIG_DEFAULTS } from "../../domain/config/value-objects.js";
2
+ import { deepMerge } from "./config-service.js";
3
+ /** All writable context names as a runtime set for validation. */
4
+ const WRITABLE_CONTEXTS = new Set([
5
+ "rag",
6
+ "pipeline",
7
+ "agent-registry",
8
+ "azure-sync",
9
+ "mcp-server",
10
+ "kanban",
11
+ "token-metrics",
12
+ ]);
13
+ // ─── Service ───────────────────────────────────────────────────────────
14
+ /**
15
+ * Orchestrates configuration writes with validation and minimal-diff persistence.
16
+ */
17
+ export class ConfigWriteService {
18
+ readRepo;
19
+ writeRepo;
20
+ validators = new Map();
21
+ constructor(readRepo, writeRepo) {
22
+ this.readRepo = readRepo;
23
+ this.writeRepo = writeRepo;
24
+ this.registerBuiltInValidators();
25
+ }
26
+ // ── Public API ─────────────────────────────────────────────────
27
+ /**
28
+ * Update a configuration context with partial values.
29
+ *
30
+ * Flow:
31
+ * 1. Validate that the context name is writable
32
+ * 2. Load current overrides from the read repo
33
+ * 3. Deep-merge partial update into current overrides for this context
34
+ * 4. Deep-merge result with defaults to get the effective merged config
35
+ * 5. Validate the merged config
36
+ * 6. Compute minimal overrides (only values differing from defaults)
37
+ * 7. Persist the full overrides object (all contexts)
38
+ *
39
+ * @param contextName — The context section to update
40
+ * @param partialUpdate — Partial values to merge into the context
41
+ * @returns The effective merged config after the update
42
+ * @throws Error if context is not writable or validation fails
43
+ */
44
+ updateContext(contextName, partialUpdate) {
45
+ if (!WRITABLE_CONTEXTS.has(contextName)) {
46
+ throw new Error(`Context "${contextName}" is not writable. Writable contexts: ${[...WRITABLE_CONTEXTS].join(", ")}`);
47
+ }
48
+ // Step 1: Load current overrides for ALL contexts
49
+ const currentOverrides = { ...this.readRepo.loadAll() };
50
+ // Step 2: Merge partial update into existing overrides for this context
51
+ const currentContextOverride = currentOverrides[contextName];
52
+ const updatedContextOverride = currentContextOverride !== undefined
53
+ ? deepMerge(currentContextOverride, partialUpdate)
54
+ : partialUpdate;
55
+ // Step 3: Compute effective merged config (defaults + updated overrides)
56
+ const defaults = CONFIG_DEFAULTS[contextName];
57
+ const effectiveMerged = defaults !== undefined
58
+ ? deepMerge(defaults, updatedContextOverride)
59
+ : updatedContextOverride;
60
+ // Step 4: Validate the merged result
61
+ const validation = this.validate(contextName, effectiveMerged);
62
+ if (!validation.valid) {
63
+ throw new Error(`Validation failed for "${contextName}": ${validation.errors.join("; ")}`);
64
+ }
65
+ // Step 5: Compute minimal overrides for this context
66
+ const minimalOverride = defaults !== undefined
67
+ ? computeOverrides(defaults, effectiveMerged)
68
+ : effectiveMerged;
69
+ // Step 6: Build full overrides object and persist
70
+ const newOverrides = { ...currentOverrides };
71
+ if (minimalOverride !== undefined && Object.keys(minimalOverride).length > 0) {
72
+ newOverrides[contextName] = minimalOverride;
73
+ }
74
+ else {
75
+ // All values match defaults — remove section from overrides
76
+ delete newOverrides[contextName];
77
+ }
78
+ this.writeRepo.writeAll(newOverrides);
79
+ return effectiveMerged;
80
+ }
81
+ /**
82
+ * Remove a context section from the overrides file entirely.
83
+ * After removal, the context will use pure defaults.
84
+ *
85
+ * @param contextName — The context section to reset
86
+ */
87
+ resetContext(contextName) {
88
+ if (!WRITABLE_CONTEXTS.has(contextName)) {
89
+ throw new Error(`Context "${contextName}" is not writable.`);
90
+ }
91
+ const currentOverrides = { ...this.readRepo.loadAll() };
92
+ delete currentOverrides[contextName];
93
+ this.writeRepo.writeAll(currentOverrides);
94
+ }
95
+ /**
96
+ * Get all writable context names.
97
+ */
98
+ getWritableContexts() {
99
+ return [...WRITABLE_CONTEXTS];
100
+ }
101
+ /**
102
+ * Register a custom validator for a context.
103
+ * Replaces any existing validator for that context.
104
+ */
105
+ registerValidator(contextName, validator) {
106
+ this.validators.set(contextName, validator);
107
+ }
108
+ // ── Validation ─────────────────────────────────────────────────
109
+ validate(contextName, merged) {
110
+ const validator = this.validators.get(contextName);
111
+ if (validator === undefined) {
112
+ return { valid: true, errors: [] };
113
+ }
114
+ return validator(merged);
115
+ }
116
+ registerBuiltInValidators() {
117
+ this.validators.set("azure-sync", validateAzureSyncConfig);
118
+ this.validators.set("token-metrics", validateTokenMetricsConfig);
119
+ this.validators.set("pipeline", validatePipelineConfig);
120
+ }
121
+ }
122
+ // ─── Built-in Validators ─────────────────────────────────────────────
123
+ function validateAzureSyncConfig(merged) {
124
+ const errors = [];
125
+ const config = merged;
126
+ if (config.pollEnabled === true) {
127
+ if (!config.organization || config.organization.trim() === "") {
128
+ errors.push("pollEnabled requires a non-empty organization");
129
+ }
130
+ if (!config.project || config.project.trim() === "") {
131
+ errors.push("pollEnabled requires a non-empty project");
132
+ }
133
+ }
134
+ if (config.pollIntervalSecs !== undefined) {
135
+ const interval = config.pollIntervalSecs;
136
+ if (typeof interval !== "number" || interval < 30) {
137
+ errors.push("pollIntervalSecs must be a number >= 30");
138
+ }
139
+ }
140
+ return { valid: errors.length === 0, errors };
141
+ }
142
+ function validateTokenMetricsConfig(merged) {
143
+ const errors = [];
144
+ const config = merged;
145
+ if (config.budgetAlertThreshold !== undefined) {
146
+ const threshold = config.budgetAlertThreshold;
147
+ if (typeof threshold !== "number" || threshold < 0 || threshold > 1) {
148
+ errors.push("budgetAlertThreshold must be a number between 0 and 1");
149
+ }
150
+ }
151
+ if (config.sprintBudgetUsd !== null && config.sprintBudgetUsd !== undefined) {
152
+ const budget = config.sprintBudgetUsd;
153
+ if (typeof budget !== "number" || budget < 0) {
154
+ errors.push("sprintBudgetUsd must be a non-negative number or null");
155
+ }
156
+ }
157
+ return { valid: errors.length === 0, errors };
158
+ }
159
+ function validatePipelineConfig(merged) {
160
+ const errors = [];
161
+ const config = merged;
162
+ if (config.defaultTimeoutMs !== undefined) {
163
+ const timeout = config.defaultTimeoutMs;
164
+ if (typeof timeout !== "number" || timeout < 1000) {
165
+ errors.push("defaultTimeoutMs must be a number >= 1000");
166
+ }
167
+ }
168
+ if (config.checkTimeoutMs !== undefined) {
169
+ const timeout = config.checkTimeoutMs;
170
+ if (typeof timeout !== "number" || timeout < 1000) {
171
+ errors.push("checkTimeoutMs must be a number >= 1000");
172
+ }
173
+ }
174
+ return { valid: errors.length === 0, errors };
175
+ }
176
+ // ─── Override Computation ────────────────────────────────────────────
177
+ /**
178
+ * Compute the minimal set of overrides by diffing effective config against defaults.
179
+ *
180
+ * Rules:
181
+ * - If a value equals the default, omit it
182
+ * - If an object has nested differences, include only the differing subtree
183
+ * - Arrays are compared by JSON equality (override replaces entire array)
184
+ * - Returns undefined if the entire section matches defaults
185
+ */
186
+ export function computeOverrides(defaults, effective) {
187
+ if (!isPlainObject(defaults) || !isPlainObject(effective)) {
188
+ // Primitive or array comparison
189
+ return deepEqual(defaults, effective) ? undefined : effective;
190
+ }
191
+ const result = {};
192
+ let hasOverrides = false;
193
+ // Check all keys in effective
194
+ for (const key of Object.keys(effective)) {
195
+ const defaultVal = defaults[key];
196
+ const effectiveVal = effective[key];
197
+ if (defaultVal === undefined) {
198
+ // Key not in defaults — it's always an override
199
+ result[key] = effectiveVal;
200
+ hasOverrides = true;
201
+ }
202
+ else if (isPlainObject(defaultVal) && isPlainObject(effectiveVal)) {
203
+ // Recurse into nested objects
204
+ const nested = computeOverrides(defaultVal, effectiveVal);
205
+ if (nested !== undefined && Object.keys(nested).length > 0) {
206
+ result[key] = nested;
207
+ hasOverrides = true;
208
+ }
209
+ }
210
+ else if (!deepEqual(defaultVal, effectiveVal)) {
211
+ result[key] = effectiveVal;
212
+ hasOverrides = true;
213
+ }
214
+ }
215
+ return hasOverrides ? result : undefined;
216
+ }
217
+ // ─── Utility Functions ───────────────────────────────────────────────
218
+ function isPlainObject(value) {
219
+ return value !== null && typeof value === "object" && !Array.isArray(value);
220
+ }
221
+ /**
222
+ * Deep equality check for JSON-serializable values.
223
+ * Uses JSON.stringify for reliable comparison of nested structures.
224
+ */
225
+ function deepEqual(a, b) {
226
+ if (a === b)
227
+ return true;
228
+ if (a === null || b === null)
229
+ return false;
230
+ if (typeof a !== typeof b)
231
+ return false;
232
+ if (typeof a === "object") {
233
+ return JSON.stringify(a) === JSON.stringify(b);
234
+ }
235
+ return false;
236
+ }
237
+ //# sourceMappingURL=config-write-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-write-service.js","sourceRoot":"","sources":["../../../src/application/config/config-write-service.ts"],"names":[],"mappings":"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"}
@@ -2,4 +2,6 @@
2
2
  * Configuration Application — Barrel Exports
3
3
  */
4
4
  export { ConfigService, deepMerge } from "./config-service.js";
5
+ export { ConfigWriteService, computeOverrides } from "./config-write-service.js";
6
+ export type { ValidationResult, ConfigValidator, WritableContextName } from "./config-write-service.js";
5
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/application/config/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/application/config/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACjF,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC"}
@@ -2,4 +2,5 @@
2
2
  * Configuration Application — Barrel Exports
3
3
  */
4
4
  export { ConfigService, deepMerge } from "./config-service.js";
5
+ export { ConfigWriteService, computeOverrides } from "./config-write-service.js";
5
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/application/config/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/application/config/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Execution Journal Use Cases
3
+ *
4
+ * Application service for recording tool execution lifecycle and
5
+ * detecting crashes via orphaned running entries.
6
+ *
7
+ * SOLID: SRP — execution journal orchestration only
8
+ * SOLID: DIP — depends on ExecutionJournalRepository port
9
+ * DDD: Application use case coordinating domain entities + infra repo
10
+ */
11
+ import type { ExecutionJournalRepository } from "../../domain/context-memory/repositories.js";
12
+ import type { ExecutionEntryId } from "../../domain/context-memory/value-objects.js";
13
+ import type { WorkspaceId } from "../../domain/shared/value-objects.js";
14
+ export interface RecordStartRequest {
15
+ readonly toolName: string;
16
+ readonly argsSummary: string;
17
+ readonly workspace: WorkspaceId;
18
+ readonly sessionId?: string;
19
+ }
20
+ export interface RecordStartResponse {
21
+ readonly entryId: string;
22
+ readonly toolName: string;
23
+ readonly state: string;
24
+ readonly startedAt: string;
25
+ }
26
+ export interface RecordFinishRequest {
27
+ readonly entryId: ExecutionEntryId;
28
+ }
29
+ export interface CrashReport {
30
+ readonly orphanedEntries: readonly CrashEntry[];
31
+ readonly totalCrashed: number;
32
+ readonly summary: string;
33
+ }
34
+ export interface CrashEntry {
35
+ readonly entryId: string;
36
+ readonly toolName: string;
37
+ readonly argsSummary: string;
38
+ readonly startedAt: string;
39
+ }
40
+ export declare class ExecutionJournalUseCases {
41
+ private readonly repository;
42
+ constructor(repository: ExecutionJournalRepository);
43
+ /**
44
+ * Record the start of a tool execution.
45
+ * Creates a Running entry in the journal.
46
+ * Returns the persisted entry with its real ID for later correlation.
47
+ */
48
+ recordStart(request: RecordStartRequest): Promise<RecordStartResponse>;
49
+ /**
50
+ * Record successful completion of a tool execution.
51
+ */
52
+ recordSuccess(request: RecordFinishRequest): Promise<void>;
53
+ /**
54
+ * Record error completion of a tool execution.
55
+ */
56
+ recordError(request: RecordFinishRequest, errorMessage: string): Promise<void>;
57
+ /**
58
+ * Detect orphaned running entries from prior sessions.
59
+ * Marks them as Crashed and returns a crash report.
60
+ * Should be called once on plugin initialization.
61
+ */
62
+ detectCrashes(workspace: WorkspaceId): Promise<CrashReport>;
63
+ /**
64
+ * Prune completed/error/crashed entries older than the retention period.
65
+ * Running entries are never pruned (they indicate ongoing or crashed executions).
66
+ */
67
+ prune(workspace: WorkspaceId, retentionDays?: number): Promise<number>;
68
+ }
69
+ //# sourceMappingURL=execution-journal-use-cases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution-journal-use-cases.d.ts","sourceRoot":"","sources":["../../../src/application/context-memory/execution-journal-use-cases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,6CAA6C,CAAC;AAE9F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAIxE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;CACpC;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,eAAe,EAAE,SAAS,UAAU,EAAE,CAAC;IAChD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAQD,qBAAa,wBAAwB;IAEjC,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,0BAA0B;IAGzD;;;;OAIG;IACG,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAiB5E;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhE;;OAEG;IACG,WAAW,CACf,OAAO,EAAE,mBAAmB,EAC5B,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC;IAQhB;;;;OAIG;IACG,aAAa,CAAC,SAAS,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAgCjE;;;OAGG;IACG,KAAK,CACT,SAAS,EAAE,WAAW,EACtB,aAAa,GAAE,MAA+B,GAC7C,OAAO,CAAC,MAAM,CAAC;CAKnB"}
@@ -0,0 +1,89 @@
1
+ import { ExecutionEntry } from "../../domain/context-memory/entities.js";
2
+ // ── Default retention: 7 days ─────────────────────────────────────────
3
+ const DEFAULT_RETENTION_DAYS = 7;
4
+ // ── Use Cases ─────────────────────────────────────────────────────────
5
+ export class ExecutionJournalUseCases {
6
+ repository;
7
+ constructor(repository) {
8
+ this.repository = repository;
9
+ }
10
+ /**
11
+ * Record the start of a tool execution.
12
+ * Creates a Running entry in the journal.
13
+ * Returns the persisted entry with its real ID for later correlation.
14
+ */
15
+ async recordStart(request) {
16
+ const entry = ExecutionEntry.create({
17
+ toolName: request.toolName,
18
+ argsSummary: request.argsSummary,
19
+ workspace: request.workspace,
20
+ });
21
+ const persisted = await this.repository.save(entry);
22
+ return {
23
+ entryId: persisted.id.value,
24
+ toolName: persisted.toolName,
25
+ state: persisted.state,
26
+ startedAt: persisted.startedAt.toISO(),
27
+ };
28
+ }
29
+ /**
30
+ * Record successful completion of a tool execution.
31
+ */
32
+ async recordSuccess(request) {
33
+ const entry = await this.repository.findById(request.entryId);
34
+ if (entry === null)
35
+ return; // Silently ignore if entry was pruned
36
+ entry.markSuccess();
37
+ await this.repository.update(entry);
38
+ }
39
+ /**
40
+ * Record error completion of a tool execution.
41
+ */
42
+ async recordError(request, errorMessage) {
43
+ const entry = await this.repository.findById(request.entryId);
44
+ if (entry === null)
45
+ return; // Silently ignore if entry was pruned
46
+ entry.markError(errorMessage);
47
+ await this.repository.update(entry);
48
+ }
49
+ /**
50
+ * Detect orphaned running entries from prior sessions.
51
+ * Marks them as Crashed and returns a crash report.
52
+ * Should be called once on plugin initialization.
53
+ */
54
+ async detectCrashes(workspace) {
55
+ const orphaned = await this.repository.findRunning(workspace);
56
+ if (orphaned.length === 0) {
57
+ return { orphanedEntries: [], totalCrashed: 0, summary: "" };
58
+ }
59
+ const crashEntries = [];
60
+ for (const entry of orphaned) {
61
+ entry.markCrashed();
62
+ await this.repository.update(entry);
63
+ crashEntries.push({
64
+ entryId: entry.id.value,
65
+ toolName: entry.toolName,
66
+ argsSummary: entry.argsSummary,
67
+ startedAt: entry.startedAt.toISO(),
68
+ });
69
+ }
70
+ const toolList = crashEntries.map((e) => e.toolName).join(", ");
71
+ const summary = `Crash detected: ${crashEntries.length} tool(s) were interrupted — ${toolList}. ` +
72
+ `These were running when the previous session ended unexpectedly.`;
73
+ return {
74
+ orphanedEntries: crashEntries,
75
+ totalCrashed: crashEntries.length,
76
+ summary,
77
+ };
78
+ }
79
+ /**
80
+ * Prune completed/error/crashed entries older than the retention period.
81
+ * Running entries are never pruned (they indicate ongoing or crashed executions).
82
+ */
83
+ async prune(workspace, retentionDays = DEFAULT_RETENTION_DAYS) {
84
+ const cutoff = new Date();
85
+ cutoff.setDate(cutoff.getDate() - retentionDays);
86
+ return this.repository.pruneOlderThan(workspace, cutoff);
87
+ }
88
+ }
89
+ //# sourceMappingURL=execution-journal-use-cases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution-journal-use-cases.js","sourceRoot":"","sources":["../../../src/application/context-memory/execution-journal-use-cases.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env bun
2
+ import { ConfigService } from "../application/config/config-service.js";
3
+ import { ConfigWriteService } from "../application/config/config-write-service.js";
4
+ import type { PromptPort } from "./wizard-prompts.js";
5
+ /**
6
+ * Run the config wizard loop.
7
+ * Exported for testability — accepts injected dependencies.
8
+ */
9
+ export declare function runWizard(opts: {
10
+ configService: ConfigService;
11
+ configWriteService: ConfigWriteService;
12
+ prompt: PromptPort;
13
+ }): Promise<void>;
14
+ //# sourceMappingURL=config-wizard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-wizard.d.ts","sourceRoot":"","sources":["../../src/cli/config-wizard.ts"],"names":[],"mappings":";AAqBA,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+CAA+C,CAAC;AAGnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAsBtD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE;IACpC,aAAa,EAAE,aAAa,CAAC;IAC7B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,MAAM,EAAE,UAAU,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6DhB"}
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * JARVIS Config Wizard — Standalone CLI Entry Point
4
+ *
5
+ * Interactive terminal wizard for configuring JARVIS per-project.
6
+ * Guides users through each config section with prompts, shows current
7
+ * values, validates input, and persists minimal overrides.
8
+ *
9
+ * Usage: jarvis config [--directory <path>]
10
+ *
11
+ * Architecture: Minimal wiring — only config infrastructure is needed.
12
+ * No database, no kanban, no RAG — just YAML read/write + prompts.
13
+ *
14
+ * SOLID: SRP — CLI entry point and orchestration only
15
+ * SOLID: DIP — depends on PromptPort abstraction for testability
16
+ */
17
+ import { resolve, join } from "node:path";
18
+ import { existsSync, mkdirSync } from "node:fs";
19
+ import { YamlConfigRepository } from "../infrastructure/config/yaml-config-repository.js";
20
+ import { YamlConfigWriter } from "../infrastructure/config/yaml-config-writer.js";
21
+ import { ConfigService } from "../application/config/config-service.js";
22
+ import { ConfigWriteService } from "../application/config/config-write-service.js";
23
+ import { ClackPromptAdapter } from "./wizard-prompts.js";
24
+ import { getSectionEntries } from "./section-editors.js";
25
+ // ── CLI Argument Parsing ──────────────────────────────────────────────
26
+ function parseArgs(argv) {
27
+ let directory = process.cwd();
28
+ for (let i = 0; i < argv.length; i++) {
29
+ const arg = argv[i];
30
+ if (arg === "--directory" || arg === "-d") {
31
+ const next = argv[i + 1];
32
+ if (next !== undefined) {
33
+ directory = resolve(next);
34
+ i++;
35
+ }
36
+ }
37
+ }
38
+ return { directory };
39
+ }
40
+ // ── Wizard Orchestration ──────────────────────────────────────────────
41
+ /**
42
+ * Run the config wizard loop.
43
+ * Exported for testability — accepts injected dependencies.
44
+ */
45
+ export async function runWizard(opts) {
46
+ const { configService, configWriteService, prompt } = opts;
47
+ const sections = getSectionEntries();
48
+ prompt.intro("JARVIS Configuration Wizard");
49
+ const configAvailable = configService.isExternalConfigAvailable();
50
+ if (!configAvailable) {
51
+ prompt.log("No config/jarvis.yaml found — using defaults. Changes will create the file.");
52
+ }
53
+ // Main loop — select section, edit, save, repeat
54
+ let running = true;
55
+ while (running) {
56
+ const sectionOptions = [
57
+ ...sections.map((s) => ({
58
+ value: s.name,
59
+ label: s.label,
60
+ hint: s.hint,
61
+ })),
62
+ { value: "__exit__", label: "Exit", hint: "save and quit" },
63
+ ];
64
+ const choice = await prompt.select({
65
+ message: "Select a section to configure",
66
+ options: sectionOptions,
67
+ });
68
+ if (choice === undefined || choice === "__exit__") {
69
+ running = false;
70
+ continue;
71
+ }
72
+ const section = sections.find((s) => s.name === choice);
73
+ if (section === undefined)
74
+ continue;
75
+ // Read current effective config
76
+ const effective = configService.getConfig(choice);
77
+ // Run the section editor
78
+ const changes = await section.editor(effective, prompt);
79
+ if (changes === undefined) {
80
+ prompt.log("No changes made.");
81
+ continue;
82
+ }
83
+ // Persist changes via ConfigWriteService
84
+ try {
85
+ configWriteService.updateContext(choice, changes);
86
+ prompt.log(`Section "${section.label}" updated successfully.`);
87
+ }
88
+ catch (err) {
89
+ const msg = err instanceof Error ? err.message : String(err);
90
+ prompt.warn(`Failed to save: ${msg}`);
91
+ }
92
+ }
93
+ prompt.outro("Configuration saved. Goodbye!");
94
+ }
95
+ // ── Main ──────────────────────────────────────────────────────────────
96
+ async function main() {
97
+ const { directory } = parseArgs(process.argv.slice(2));
98
+ // Ensure config directory exists
99
+ const configDir = join(directory, "config");
100
+ if (!existsSync(configDir)) {
101
+ mkdirSync(configDir, { recursive: true });
102
+ }
103
+ // Wire minimal infrastructure
104
+ const configPath = join(configDir, "jarvis.yaml");
105
+ const configRepo = new YamlConfigRepository(configPath);
106
+ const configWriter = new YamlConfigWriter(configPath);
107
+ const configService = new ConfigService(configRepo);
108
+ const configWriteService = new ConfigWriteService(configRepo, configWriter);
109
+ // Run wizard with production prompt adapter
110
+ await runWizard({
111
+ configService,
112
+ configWriteService,
113
+ prompt: new ClackPromptAdapter(),
114
+ });
115
+ }
116
+ main().catch((err) => {
117
+ console.error("Fatal error:", err);
118
+ process.exit(1);
119
+ });
120
+ //# sourceMappingURL=config-wizard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-wizard.js","sourceRoot":"","sources":["../../src/cli/config-wizard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Section Editors — Config Section Interactive Editing
3
+ *
4
+ * Each section editor reads the current effective config, presents
5
+ * values to the user via the PromptPort, and returns the partial
6
+ * update object (only changed values). Returns undefined if cancelled.
7
+ *
8
+ * SOLID: SRP — section editing logic only
9
+ * SOLID: OCP — new sections added by creating new editor functions
10
+ * SOLID: DIP — depends on PromptPort abstraction, not clack directly
11
+ */
12
+ import type { PromptPort } from "./wizard-prompts.js";
13
+ /** A section editor function signature. */
14
+ export type SectionEditor = (current: unknown, prompt: PromptPort) => Promise<Record<string, unknown> | undefined>;
15
+ /** Section metadata for the wizard menu. */
16
+ export interface SectionEntry {
17
+ readonly name: string;
18
+ readonly label: string;
19
+ readonly hint: string;
20
+ readonly editor: SectionEditor;
21
+ }
22
+ /**
23
+ * Returns all editable sections with metadata and editor functions.
24
+ */
25
+ export declare function getSectionEntries(): readonly SectionEntry[];
26
+ /** Format a value for display in the current-value summary. */
27
+ export declare function formatDisplayValue(value: unknown): string;
28
+ /** Build a summary of current values for a section. */
29
+ export declare function buildSectionSummary(fields: readonly {
30
+ label: string;
31
+ value: unknown;
32
+ }[]): string;
33
+ //# sourceMappingURL=section-editors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section-editors.d.ts","sourceRoot":"","sources":["../../src/cli/section-editors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAYtD,2CAA2C;AAC3C,MAAM,MAAM,aAAa,GAAG,CAC1B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,UAAU,KACf,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;AAElD,4CAA4C;AAC5C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;CAChC;AAID;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,SAAS,YAAY,EAAE,CAS3D;AAID,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CASzD;AAED,uDAAuD;AACvD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,EAAE,GACnD,MAAM,CAKR"}