@kodrunhq/opencode-autopilot 1.15.2 → 1.17.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 (93) hide show
  1. package/bin/cli.ts +5 -0
  2. package/bin/inspect.ts +337 -0
  3. package/package.json +1 -1
  4. package/src/agents/autopilot.ts +7 -15
  5. package/src/config/index.ts +29 -0
  6. package/src/config/migrations.ts +196 -0
  7. package/src/config/v7.ts +45 -0
  8. package/src/config.ts +3 -3
  9. package/src/health/checks.ts +126 -4
  10. package/src/health/types.ts +1 -1
  11. package/src/index.ts +128 -13
  12. package/src/inspect/formatters.ts +225 -0
  13. package/src/inspect/repository.ts +882 -0
  14. package/src/kernel/database.ts +45 -0
  15. package/src/kernel/migrations.ts +62 -0
  16. package/src/kernel/repository.ts +571 -0
  17. package/src/kernel/schema.ts +122 -0
  18. package/src/kernel/transaction.ts +48 -0
  19. package/src/kernel/types.ts +65 -0
  20. package/src/logging/domains.ts +39 -0
  21. package/src/logging/forensic-writer.ts +177 -0
  22. package/src/logging/index.ts +4 -0
  23. package/src/logging/logger.ts +44 -0
  24. package/src/logging/performance.ts +59 -0
  25. package/src/logging/rotation.ts +261 -0
  26. package/src/logging/types.ts +33 -0
  27. package/src/memory/capture-utils.ts +149 -0
  28. package/src/memory/capture.ts +82 -67
  29. package/src/memory/database.ts +74 -12
  30. package/src/memory/decay.ts +11 -2
  31. package/src/memory/index.ts +17 -1
  32. package/src/memory/injector.ts +4 -1
  33. package/src/memory/lessons.ts +85 -0
  34. package/src/memory/observations.ts +177 -0
  35. package/src/memory/preferences.ts +718 -0
  36. package/src/memory/project-key.ts +6 -0
  37. package/src/memory/projects.ts +83 -0
  38. package/src/memory/repository.ts +52 -216
  39. package/src/memory/retrieval.ts +88 -170
  40. package/src/memory/schemas.ts +39 -7
  41. package/src/memory/types.ts +4 -0
  42. package/src/observability/context-display.ts +8 -0
  43. package/src/observability/event-handlers.ts +69 -20
  44. package/src/observability/event-store.ts +29 -1
  45. package/src/observability/forensic-log.ts +167 -0
  46. package/src/observability/forensic-schemas.ts +77 -0
  47. package/src/observability/forensic-types.ts +10 -0
  48. package/src/observability/index.ts +21 -27
  49. package/src/observability/log-reader.ts +161 -111
  50. package/src/observability/log-writer.ts +41 -83
  51. package/src/observability/retention.ts +2 -2
  52. package/src/observability/session-logger.ts +36 -57
  53. package/src/observability/summary-generator.ts +31 -19
  54. package/src/observability/types.ts +12 -24
  55. package/src/orchestrator/contracts/invariants.ts +14 -0
  56. package/src/orchestrator/contracts/legacy-result-adapter.ts +8 -20
  57. package/src/orchestrator/error-context.ts +24 -0
  58. package/src/orchestrator/fallback/event-handler.ts +47 -3
  59. package/src/orchestrator/handlers/architect.ts +2 -1
  60. package/src/orchestrator/handlers/build-utils.ts +118 -0
  61. package/src/orchestrator/handlers/build.ts +42 -219
  62. package/src/orchestrator/handlers/retrospective.ts +2 -2
  63. package/src/orchestrator/handlers/types.ts +0 -1
  64. package/src/orchestrator/lesson-memory.ts +36 -11
  65. package/src/orchestrator/orchestration-logger.ts +53 -24
  66. package/src/orchestrator/phase.ts +8 -4
  67. package/src/orchestrator/progress.ts +63 -0
  68. package/src/orchestrator/state.ts +79 -17
  69. package/src/projects/database.ts +47 -0
  70. package/src/projects/repository.ts +264 -0
  71. package/src/projects/resolve.ts +301 -0
  72. package/src/projects/schemas.ts +30 -0
  73. package/src/projects/types.ts +12 -0
  74. package/src/review/memory.ts +39 -11
  75. package/src/review/parse-findings.ts +116 -0
  76. package/src/review/pipeline.ts +3 -107
  77. package/src/review/selection.ts +38 -4
  78. package/src/scoring/time-provider.ts +23 -0
  79. package/src/tools/doctor.ts +28 -4
  80. package/src/tools/forensics.ts +7 -12
  81. package/src/tools/logs.ts +38 -11
  82. package/src/tools/memory-preferences.ts +157 -0
  83. package/src/tools/memory-status.ts +17 -96
  84. package/src/tools/orchestrate.ts +108 -90
  85. package/src/tools/pipeline-report.ts +3 -2
  86. package/src/tools/quick.ts +2 -2
  87. package/src/tools/replay.ts +42 -0
  88. package/src/tools/review.ts +46 -7
  89. package/src/tools/session-stats.ts +3 -2
  90. package/src/tools/summary.ts +43 -0
  91. package/src/utils/paths.ts +20 -1
  92. package/src/utils/random.ts +33 -0
  93. package/src/ux/session-summary.ts +56 -0
@@ -1,13 +1,24 @@
1
1
  import { homedir } from "node:os";
2
- import { dirname, join } from "node:path";
2
+ import { basename, dirname, join } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
 
5
5
  const __dirname = import.meta.dir ?? dirname(fileURLToPath(import.meta.url));
6
+ const AUTOPILOT_DB_FILE = "autopilot.db";
7
+ const LEGACY_MEMORY_DIR = "memory";
8
+ const LEGACY_MEMORY_DB_FILE = "memory.db";
6
9
 
7
10
  export function getGlobalConfigDir(): string {
8
11
  return join(homedir(), ".config", "opencode");
9
12
  }
10
13
 
14
+ export function getAutopilotDbPath(baseDir?: string): string {
15
+ return join(baseDir ?? getGlobalConfigDir(), AUTOPILOT_DB_FILE);
16
+ }
17
+
18
+ export function getLegacyMemoryDbPath(baseDir?: string): string {
19
+ return join(baseDir ?? getGlobalConfigDir(), LEGACY_MEMORY_DIR, LEGACY_MEMORY_DB_FILE);
20
+ }
21
+
11
22
  export function getAssetsDir(): string {
12
23
  return join(__dirname, "..", "..", "assets");
13
24
  }
@@ -15,3 +26,11 @@ export function getAssetsDir(): string {
15
26
  export function getProjectArtifactDir(projectRoot: string): string {
16
27
  return join(projectRoot, ".opencode-autopilot");
17
28
  }
29
+
30
+ export function isProjectArtifactDir(path: string): boolean {
31
+ return basename(path) === ".opencode-autopilot";
32
+ }
33
+
34
+ export function getProjectRootFromArtifactDir(artifactDir: string): string {
35
+ return isProjectArtifactDir(artifactDir) ? dirname(artifactDir) : artifactDir;
36
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * A simple seeded random number generator.
3
+ * Uses the Mulberry32 algorithm which provides decent quality and is very fast.
4
+ */
5
+ export function createSeededRandom(seedString: string) {
6
+ // Simple hash function (djb2) to convert string to 32-bit integer seed
7
+ let seed = 5381;
8
+ for (let i = 0; i < seedString.length; i++) {
9
+ seed = (seed * 33) ^ seedString.charCodeAt(i);
10
+ }
11
+ // Add an arbitrary constant to avoid passing 0 to mulberry32
12
+ let a = seed + 1831565813;
13
+
14
+ // Mulberry32 generator
15
+ return function random(): number {
16
+ a += 0x6d2b79f5;
17
+ let t = a;
18
+ t = Math.imul(t ^ (t >>> 15), t | 1);
19
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
20
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
21
+ };
22
+ }
23
+
24
+ /**
25
+ * Shuffles an array in-place deterministically using the provided seeded RNG.
26
+ */
27
+ export function deterministicShuffle<T>(array: T[], rng: () => number): T[] {
28
+ for (let i = array.length - 1; i > 0; i--) {
29
+ const j = Math.floor(rng() * (i + 1));
30
+ [array[i], array[j]] = [array[j], array[i]];
31
+ }
32
+ return array;
33
+ }
@@ -0,0 +1,56 @@
1
+ import type { SessionEvents } from "../observability/event-store";
2
+ import type { PipelineState } from "../orchestrator/types";
3
+
4
+ export function generateSessionSummary(
5
+ sessionData: SessionEvents | undefined,
6
+ pipelineState: PipelineState | null,
7
+ ): string {
8
+ const sections: string[] = ["## Session Summary"];
9
+
10
+ if (pipelineState) {
11
+ const phaseInfo = pipelineState.currentPhase
12
+ ? ` (Current Phase: ${pipelineState.currentPhase})`
13
+ : "";
14
+ sections.push(`**Pipeline Status**: ${pipelineState.status}${phaseInfo}`);
15
+
16
+ const done = pipelineState.phases.filter((p) => p.status === "DONE").map((p) => p.name);
17
+
18
+ sections.push(`**Phases Completed**: ${done.length > 0 ? done.join(", ") : "None"}`);
19
+ } else {
20
+ sections.push("**Pipeline Status**: Unknown");
21
+ }
22
+
23
+ if (sessionData?.tokens) {
24
+ const { inputTokens, outputTokens, reasoningTokens } = sessionData.tokens;
25
+ sections.push(
26
+ "\n**Context Used**:",
27
+ `- Input: ${inputTokens.toLocaleString()} tokens`,
28
+ `- Output: ${outputTokens.toLocaleString()} tokens`,
29
+ ...(reasoningTokens > 0 ? [`- Reasoning: ${reasoningTokens.toLocaleString()} tokens`] : []),
30
+ );
31
+ }
32
+
33
+ const errors = (sessionData?.events ?? []).filter((e) => e.type === "error");
34
+ if (errors.length > 0) {
35
+ sections.push("\n**Errors Encountered**:");
36
+ for (const e of errors) {
37
+ if (e.type === "error") {
38
+ sections.push(`- ${e.errorType.toUpperCase()}: ${e.message}`);
39
+ }
40
+ }
41
+ }
42
+
43
+ if (sessionData) {
44
+ const endEvent = sessionData.events.find((e) => e.type === "session_end");
45
+ if (endEvent && endEvent.type === "session_end") {
46
+ const seconds = (endEvent.durationMs / 1000).toFixed(1);
47
+ sections.push(`\n**Duration**: ${seconds}s`);
48
+ } else {
49
+ const start = new Date(sessionData.startedAt).getTime();
50
+ const seconds = ((Date.now() - start) / 1000).toFixed(1);
51
+ sections.push(`\n**Duration (active)**: ${seconds}s`);
52
+ }
53
+ }
54
+
55
+ return sections.join("\n").trim();
56
+ }