@phamvuhoang/otto-core 0.10.0 → 0.12.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 (60) hide show
  1. package/dist/bench.d.ts +104 -0
  2. package/dist/bench.d.ts.map +1 -0
  3. package/dist/bench.js +175 -0
  4. package/dist/bench.js.map +1 -0
  5. package/dist/cli-help.d.ts +2 -0
  6. package/dist/cli-help.d.ts.map +1 -1
  7. package/dist/cli-help.js +6 -0
  8. package/dist/cli-help.js.map +1 -1
  9. package/dist/eval-run.d.ts +61 -0
  10. package/dist/eval-run.d.ts.map +1 -0
  11. package/dist/eval-run.js +162 -0
  12. package/dist/eval-run.js.map +1 -0
  13. package/dist/eval.d.ts +49 -0
  14. package/dist/eval.d.ts.map +1 -0
  15. package/dist/eval.js +111 -0
  16. package/dist/eval.js.map +1 -0
  17. package/dist/git.d.ts +10 -0
  18. package/dist/git.d.ts.map +1 -1
  19. package/dist/git.js +27 -0
  20. package/dist/git.js.map +1 -1
  21. package/dist/index.d.ts +8 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +8 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/inspect.d.ts +24 -0
  26. package/dist/inspect.d.ts.map +1 -0
  27. package/dist/inspect.js +97 -0
  28. package/dist/inspect.js.map +1 -0
  29. package/dist/loop.d.ts +9 -0
  30. package/dist/loop.d.ts.map +1 -1
  31. package/dist/loop.js +192 -4
  32. package/dist/loop.js.map +1 -1
  33. package/dist/panel.d.ts +7 -0
  34. package/dist/panel.d.ts.map +1 -1
  35. package/dist/panel.js +8 -1
  36. package/dist/panel.js.map +1 -1
  37. package/dist/policy.d.ts +38 -0
  38. package/dist/policy.d.ts.map +1 -0
  39. package/dist/policy.js +32 -0
  40. package/dist/policy.js.map +1 -0
  41. package/dist/progress.d.ts +41 -0
  42. package/dist/progress.d.ts.map +1 -0
  43. package/dist/progress.js +37 -0
  44. package/dist/progress.js.map +1 -0
  45. package/dist/render.d.ts +1 -0
  46. package/dist/render.d.ts.map +1 -1
  47. package/dist/render.js +1 -1
  48. package/dist/render.js.map +1 -1
  49. package/dist/risk.d.ts +50 -0
  50. package/dist/risk.d.ts.map +1 -0
  51. package/dist/risk.js +113 -0
  52. package/dist/risk.js.map +1 -0
  53. package/dist/run-bin.d.ts.map +1 -1
  54. package/dist/run-bin.js +23 -10
  55. package/dist/run-bin.js.map +1 -1
  56. package/dist/run-report.d.ts +105 -0
  57. package/dist/run-report.d.ts.map +1 -0
  58. package/dist/run-report.js +118 -0
  59. package/dist/run-report.js.map +1 -0
  60. package/package.json +1 -1
@@ -0,0 +1,118 @@
1
+ import { mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync, } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ /**
4
+ * Allocate a sortable, filesystem-safe run id: an ISO timestamp with its
5
+ * colons/periods replaced by dashes, suffixed by the pid to keep concurrent
6
+ * runs on one host from colliding. Lexicographic order matches chronological
7
+ * order, so "latest" is a plain string sort. `date`/`pid` are injectable so
8
+ * tests are deterministic.
9
+ */
10
+ export function allocateRunId(date = new Date(), pid = process.pid) {
11
+ const stamp = date.toISOString().replace(/[:.]/g, "-");
12
+ return `${stamp}-${pid}`;
13
+ }
14
+ const RUNS_REL = join(".otto", "runs");
15
+ /** Absolute path to the workspace's run-bundle root (`.otto/runs`). */
16
+ export function runsDir(workspaceDir) {
17
+ return join(workspaceDir, RUNS_REL);
18
+ }
19
+ /** Absolute path to one run's bundle dir (`.otto/runs/<run-id>`). */
20
+ export function runReportDir(workspaceDir, runId) {
21
+ return join(runsDir(workspaceDir), runId);
22
+ }
23
+ /**
24
+ * List the run ids present under `.otto/runs/`, sorted ascending. Because run
25
+ * ids are lexicographically sortable (see {@link allocateRunId}), the last
26
+ * entry is the most recent run — so "latest" is `at(-1)`. Absent/unreadable
27
+ * dir → `[]` (never throws).
28
+ */
29
+ export function listRunIds(workspaceDir) {
30
+ try {
31
+ return readdirSync(runsDir(workspaceDir), { withFileTypes: true })
32
+ .filter((e) => e.isDirectory())
33
+ .map((e) => e.name)
34
+ .sort();
35
+ }
36
+ catch {
37
+ return [];
38
+ }
39
+ }
40
+ function manifestPath(workspaceDir, runId) {
41
+ return join(runReportDir(workspaceDir, runId), "manifest.json");
42
+ }
43
+ function stagesDir(workspaceDir, runId) {
44
+ return join(runReportDir(workspaceDir, runId), "stages");
45
+ }
46
+ /** Write the run manifest (creates `.otto/runs/<run-id>/`). */
47
+ export function writeManifest(workspaceDir, manifest) {
48
+ const p = manifestPath(workspaceDir, manifest.runId);
49
+ mkdirSync(dirname(p), { recursive: true });
50
+ writeFileSync(p, JSON.stringify(manifest, null, 2) + "\n");
51
+ }
52
+ /** Read a run manifest. Absent or malformed → null (never throws). */
53
+ export function readManifest(workspaceDir, runId) {
54
+ try {
55
+ return JSON.parse(readFileSync(manifestPath(workspaceDir, runId), "utf8"));
56
+ }
57
+ catch {
58
+ return null;
59
+ }
60
+ }
61
+ /**
62
+ * Write one normalized stage record under the run's `stages/` dir. `seq` is a
63
+ * monotonic per-run counter that zero-pads into the filename so records sort in
64
+ * execution order. The stage segment is sanitized to `[A-Za-z0-9_-]` because
65
+ * panel lens names (from `OTTO_REVIEW_LENSES`) are free text that becomes a
66
+ * filename. Returns the written basename.
67
+ */
68
+ export function writeStageRecord(workspaceDir, runId, seq, record) {
69
+ const dir = stagesDir(workspaceDir, runId);
70
+ mkdirSync(dir, { recursive: true });
71
+ const safeStage = record.stage.replace(/[^A-Za-z0-9_-]/g, "-");
72
+ const name = `${String(seq).padStart(4, "0")}-iter${record.iteration}-${safeStage}.json`;
73
+ writeFileSync(join(dir, name), JSON.stringify(record, null, 2) + "\n");
74
+ return name;
75
+ }
76
+ /**
77
+ * Delete the named stage-record files (basenames from {@link writeStageRecord})
78
+ * from a run's `stages/` dir. Used to roll back records written by a panel
79
+ * attempt that later rate-limited and is being retried, so the bundle keeps one
80
+ * record per stage rather than a duplicate per retry. Best-effort: a missing or
81
+ * unremovable file is skipped (never throws).
82
+ */
83
+ export function removeStageRecords(workspaceDir, runId, names) {
84
+ const dir = stagesDir(workspaceDir, runId);
85
+ for (const name of names) {
86
+ try {
87
+ rmSync(join(dir, name), { force: true });
88
+ }
89
+ catch {
90
+ // Best-effort: never fail a run because a stale record could not be removed.
91
+ }
92
+ }
93
+ }
94
+ /**
95
+ * Read every stage record for a run in execution (seq) order. Absent/unreadable
96
+ * dir or a malformed entry → the records read so far (never throws); a malformed
97
+ * file is skipped.
98
+ */
99
+ export function readStageRecords(workspaceDir, runId) {
100
+ let names;
101
+ try {
102
+ names = readdirSync(stagesDir(workspaceDir, runId));
103
+ }
104
+ catch {
105
+ return [];
106
+ }
107
+ const records = [];
108
+ for (const name of names.filter((n) => n.endsWith(".json")).sort()) {
109
+ try {
110
+ records.push(JSON.parse(readFileSync(join(stagesDir(workspaceDir, runId), name), "utf8")));
111
+ }
112
+ catch {
113
+ // Skip a malformed record rather than failing the whole read.
114
+ }
115
+ }
116
+ return records;
117
+ }
118
+ //# sourceMappingURL=run-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-report.js","sourceRoot":"","sources":["../src/run-report.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phamvuhoang/otto-core",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "Claude Code AFK orchestration: iteration loop, native-sandbox runner, template renderer.",
5
5
  "type": "module",
6
6
  "license": "MIT",