@autopilot-harness/cli 0.1.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/LICENSE +21 -0
  2. package/README.md +55 -0
  3. package/assets/autopilot-harness-hook.mjs +193 -0
  4. package/assets/vendor/migrations/001_initial.sql +62 -0
  5. package/assets/vendor/migrations/002_pending_followup.sql +4 -0
  6. package/assets/vendor/migrations/003_reviewing_item.sql +1 -0
  7. package/assets/vendor/runtime.mjs +5524 -0
  8. package/dist/assets/autopilot-harness-hook.mjs +193 -0
  9. package/dist/assets/vendor/migrations/001_initial.sql +62 -0
  10. package/dist/assets/vendor/migrations/002_pending_followup.sql +4 -0
  11. package/dist/assets/vendor/migrations/003_reviewing_item.sql +1 -0
  12. package/dist/assets/vendor/runtime.mjs +5524 -0
  13. package/dist/bin.d.ts +3 -0
  14. package/dist/bin.d.ts.map +1 -0
  15. package/dist/bin.js +300 -0
  16. package/dist/bin.js.map +1 -0
  17. package/dist/index.d.ts +23 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +13 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/init/config-merge.d.ts +27 -0
  22. package/dist/init/config-merge.d.ts.map +1 -0
  23. package/dist/init/config-merge.js +115 -0
  24. package/dist/init/config-merge.js.map +1 -0
  25. package/dist/init/default-config.d.ts +17 -0
  26. package/dist/init/default-config.d.ts.map +1 -0
  27. package/dist/init/default-config.js +101 -0
  28. package/dist/init/default-config.js.map +1 -0
  29. package/dist/init/hooks-merge.d.ts +25 -0
  30. package/dist/init/hooks-merge.d.ts.map +1 -0
  31. package/dist/init/hooks-merge.js +134 -0
  32. package/dist/init/hooks-merge.js.map +1 -0
  33. package/dist/init/install.d.ts +31 -0
  34. package/dist/init/install.d.ts.map +1 -0
  35. package/dist/init/install.js +829 -0
  36. package/dist/init/install.js.map +1 -0
  37. package/dist/init/platforms.d.ts +60 -0
  38. package/dist/init/platforms.d.ts.map +1 -0
  39. package/dist/init/platforms.js +275 -0
  40. package/dist/init/platforms.js.map +1 -0
  41. package/dist/init/tui.d.ts +65 -0
  42. package/dist/init/tui.d.ts.map +1 -0
  43. package/dist/init/tui.js +549 -0
  44. package/dist/init/tui.js.map +1 -0
  45. package/dist/init/types.d.ts +75 -0
  46. package/dist/init/types.d.ts.map +1 -0
  47. package/dist/init/types.js +9 -0
  48. package/dist/init/types.js.map +1 -0
  49. package/dist/init/wizard-copy.d.ts +74 -0
  50. package/dist/init/wizard-copy.d.ts.map +1 -0
  51. package/dist/init/wizard-copy.js +173 -0
  52. package/dist/init/wizard-copy.js.map +1 -0
  53. package/dist/init/wizard-helpers.d.ts +103 -0
  54. package/dist/init/wizard-helpers.d.ts.map +1 -0
  55. package/dist/init/wizard-helpers.js +724 -0
  56. package/dist/init/wizard-helpers.js.map +1 -0
  57. package/dist/locale-set.d.ts +24 -0
  58. package/dist/locale-set.d.ts.map +1 -0
  59. package/dist/locale-set.js +286 -0
  60. package/dist/locale-set.js.map +1 -0
  61. package/dist/names.d.ts +5 -0
  62. package/dist/names.d.ts.map +1 -0
  63. package/dist/names.js +5 -0
  64. package/dist/names.js.map +1 -0
  65. package/dist/project-fs.d.ts +48 -0
  66. package/dist/project-fs.d.ts.map +1 -0
  67. package/dist/project-fs.js +210 -0
  68. package/dist/project-fs.js.map +1 -0
  69. package/dist/read-untrusted-file.d.ts +41 -0
  70. package/dist/read-untrusted-file.d.ts.map +1 -0
  71. package/dist/read-untrusted-file.js +362 -0
  72. package/dist/read-untrusted-file.js.map +1 -0
  73. package/dist/session.d.ts +38 -0
  74. package/dist/session.d.ts.map +1 -0
  75. package/dist/session.js +242 -0
  76. package/dist/session.js.map +1 -0
  77. package/dist/status-doctor.d.ts +22 -0
  78. package/dist/status-doctor.d.ts.map +1 -0
  79. package/dist/status-doctor.js +712 -0
  80. package/dist/status-doctor.js.map +1 -0
  81. package/dist/uninstall.d.ts +31 -0
  82. package/dist/uninstall.d.ts.map +1 -0
  83. package/dist/uninstall.js +333 -0
  84. package/dist/uninstall.js.map +1 -0
  85. package/dist/upgrade.d.ts +29 -0
  86. package/dist/upgrade.d.ts.map +1 -0
  87. package/dist/upgrade.js +290 -0
  88. package/dist/upgrade.js.map +1 -0
  89. package/dist/vendor-entry.d.ts +6 -0
  90. package/dist/vendor-entry.d.ts.map +1 -0
  91. package/dist/vendor-entry.js +16 -0
  92. package/dist/vendor-entry.js.map +1 -0
  93. package/package.json +54 -0
@@ -0,0 +1,242 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { normalizeSessionTitle, sanitizeSessionDisplayText, shortConversationId, StateStore, } from "@autopilot-harness/core";
4
+ import { assertNotSymlink } from "./init/wizard-helpers.js";
5
+ export { shortConversationId as shortSessionId };
6
+ const DEFAULT_STALE_HOURS = 72;
7
+ function resolveProjectRoot(projectRoot) {
8
+ if (typeof projectRoot !== "string" || projectRoot.trim() === "") {
9
+ return { ok: false, error: "projectRoot must be a non-empty string" };
10
+ }
11
+ return { ok: true, root: path.resolve(projectRoot.trim()) };
12
+ }
13
+ function assertInitialized(projectRoot) {
14
+ const configPath = path.join(projectRoot, ".autopilot", "config.yml");
15
+ try {
16
+ // Prefer lstat over existsSync: dangling symlinks look "missing" to existsSync.
17
+ const st = fs.lstatSync(configPath);
18
+ if (st.isSymbolicLink()) {
19
+ return {
20
+ ok: false,
21
+ error: ".autopilot/config.yml is a symlink; refusing to open",
22
+ };
23
+ }
24
+ if (!st.isFile()) {
25
+ return {
26
+ ok: false,
27
+ error: ".autopilot/config.yml is not a regular file",
28
+ };
29
+ }
30
+ }
31
+ catch (err) {
32
+ const code = err?.code;
33
+ if (code === "ENOENT") {
34
+ return {
35
+ ok: false,
36
+ error: "Project is not initialized (.autopilot/config.yml missing). Run init first.",
37
+ };
38
+ }
39
+ const msg = err instanceof Error ? err.message : String(err);
40
+ return { ok: false, error: `Cannot access config.yml: ${msg}` };
41
+ }
42
+ return null;
43
+ }
44
+ function openStore(projectRoot) {
45
+ const resolved = resolveProjectRoot(projectRoot);
46
+ if (!resolved.ok)
47
+ return resolved;
48
+ const root = resolved.root;
49
+ const initErr = assertInitialized(root);
50
+ if (initErr)
51
+ return initErr;
52
+ const dbPath = path.join(root, ".autopilot", "state.db");
53
+ try {
54
+ const st = fs.lstatSync(dbPath);
55
+ if (st.isSymbolicLink()) {
56
+ return {
57
+ ok: false,
58
+ error: "Cannot open state.db: .autopilot/state.db is a symlink; refusing to open",
59
+ };
60
+ }
61
+ if (!st.isFile()) {
62
+ return {
63
+ ok: false,
64
+ error: "Cannot open state.db: .autopilot/state.db is not a regular file",
65
+ };
66
+ }
67
+ }
68
+ catch (err) {
69
+ const code = err?.code;
70
+ if (code === "ENOENT") {
71
+ return { ok: false, error: "No state.db yet (no sessions)." };
72
+ }
73
+ const msg = err instanceof Error ? err.message : String(err);
74
+ return { ok: false, error: `Cannot open state.db: ${msg}` };
75
+ }
76
+ try {
77
+ assertNotSymlink(path.join(root, ".autopilot"), ".autopilot/");
78
+ assertNotSymlink(dbPath, ".autopilot/state.db");
79
+ return new StateStore(root);
80
+ }
81
+ catch (err) {
82
+ const msg = err instanceof Error ? err.message : String(err);
83
+ return { ok: false, error: `Cannot open state.db: ${msg}` };
84
+ }
85
+ }
86
+ function asStoreFail(value) {
87
+ return !(value instanceof StateStore);
88
+ }
89
+ export function formatSessionDisplayName(row) {
90
+ const track = sanitizeSessionDisplayText(row.track_title?.trim() ||
91
+ (row.track_id && row.track_id !== "_pending" ? row.track_id : "") ||
92
+ "");
93
+ const session = sanitizeSessionDisplayText(row.session_title?.trim() || "");
94
+ if (track && session)
95
+ return `${track} · ${session}`;
96
+ if (track)
97
+ return track;
98
+ if (session)
99
+ return session;
100
+ return "(untitled)";
101
+ }
102
+ function formatPhase(row) {
103
+ if (row.paused === 1) {
104
+ return `${row.phase} (paused)`;
105
+ }
106
+ return row.phase;
107
+ }
108
+ function formatRelativeAge(iso, nowMs = Date.now()) {
109
+ const t = Date.parse(iso);
110
+ if (Number.isNaN(t))
111
+ return iso;
112
+ const sec = Math.max(0, Math.floor((nowMs - t) / 1000));
113
+ if (sec < 60)
114
+ return `${sec}s ago`;
115
+ const min = Math.floor(sec / 60);
116
+ if (min < 60)
117
+ return `${min}m ago`;
118
+ const hr = Math.floor(min / 60);
119
+ if (hr < 48)
120
+ return `${hr}h ago`;
121
+ const days = Math.floor(hr / 24);
122
+ return `${days}d ago`;
123
+ }
124
+ function isStale(row, staleAfterHours, nowMs = Date.now()) {
125
+ if (!(staleAfterHours > 0))
126
+ return false;
127
+ const t = Date.parse(row.last_active_at);
128
+ if (Number.isNaN(t))
129
+ return false;
130
+ return nowMs - t > staleAfterHours * 3600 * 1000;
131
+ }
132
+ function pad(s, n) {
133
+ if (s.length >= n)
134
+ return s.slice(0, n);
135
+ return s + " ".repeat(n - s.length);
136
+ }
137
+ export function formatSessionList(opts) {
138
+ const storeOrErr = openStore(opts.projectRoot);
139
+ if (asStoreFail(storeOrErr))
140
+ return storeOrErr;
141
+ const store = storeOrErr;
142
+ try {
143
+ const rows = store.listSessions();
144
+ if (rows.length === 0) {
145
+ return { ok: true, lines: ["(no sessions)"] };
146
+ }
147
+ const staleH = opts.staleAfterHours ?? DEFAULT_STALE_HOURS;
148
+ const header = pad("ID", 10) +
149
+ pad("Title", 36) +
150
+ pad("Track", 16) +
151
+ pad("Phase", 22) +
152
+ "Last active";
153
+ const lines = [header];
154
+ for (const row of rows) {
155
+ const short = shortConversationId(row.conversation_id);
156
+ const title = formatSessionDisplayName(row);
157
+ const track = sanitizeSessionDisplayText(row.track_id === "_pending" ? "(pending)" : row.track_id);
158
+ const phase = formatPhase(row);
159
+ const age = formatRelativeAge(row.last_active_at);
160
+ const stale = isStale(row, staleH) ? " ← stale" : "";
161
+ lines.push(pad(short, 10) +
162
+ pad(title, 36) +
163
+ pad(track, 16) +
164
+ pad(phase, 22) +
165
+ age +
166
+ stale);
167
+ }
168
+ return { ok: true, lines };
169
+ }
170
+ catch (err) {
171
+ const msg = err instanceof Error ? err.message : String(err);
172
+ // Do not prefix here — bin.ts adds "session list failed:".
173
+ return { ok: false, error: msg };
174
+ }
175
+ finally {
176
+ store.close();
177
+ }
178
+ }
179
+ function withResolvedSession(projectRoot, idQuery, fn) {
180
+ if (typeof idQuery !== "string" || idQuery.trim() === "") {
181
+ return { ok: false, error: "Session id required" };
182
+ }
183
+ const storeOrErr = openStore(projectRoot);
184
+ if (asStoreFail(storeOrErr))
185
+ return storeOrErr;
186
+ const store = storeOrErr;
187
+ try {
188
+ const resolved = store.resolveSessionId(idQuery);
189
+ if (!resolved.ok)
190
+ return resolved;
191
+ return fn(store, resolved.id);
192
+ }
193
+ catch (err) {
194
+ const msg = err instanceof Error ? err.message : String(err);
195
+ return { ok: false, error: msg };
196
+ }
197
+ finally {
198
+ store.close();
199
+ }
200
+ }
201
+ export function renameProjectSession(opts) {
202
+ if (typeof opts.title !== "string") {
203
+ return { ok: false, error: "Title must be a non-empty string" };
204
+ }
205
+ let title;
206
+ try {
207
+ title = normalizeSessionTitle(opts.title);
208
+ }
209
+ catch (err) {
210
+ const msg = err instanceof Error ? err.message : String(err);
211
+ return { ok: false, error: msg };
212
+ }
213
+ return withResolvedSession(opts.projectRoot, opts.id, (store, id) => {
214
+ try {
215
+ const row = store.renameSession(id, title);
216
+ if (!row)
217
+ return { ok: false, error: `No session matching "${opts.id}"` };
218
+ return { ok: true };
219
+ }
220
+ catch (err) {
221
+ const msg = err instanceof Error ? err.message : String(err);
222
+ return { ok: false, error: msg };
223
+ }
224
+ });
225
+ }
226
+ export function purgeProjectSession(opts) {
227
+ return withResolvedSession(opts.projectRoot, opts.id, (store, id) => {
228
+ if (!store.purgeSession(id)) {
229
+ return { ok: false, error: `No session matching "${opts.id}"` };
230
+ }
231
+ return { ok: true };
232
+ });
233
+ }
234
+ export function resetProjectSessionReview(opts) {
235
+ return withResolvedSession(opts.projectRoot, opts.id, (store, id) => {
236
+ if (!store.resetReviewChain(id)) {
237
+ return { ok: false, error: `No session matching "${opts.id}"` };
238
+ }
239
+ return { ok: true };
240
+ });
241
+ }
242
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export type DoctorOptions = {
2
+ pruneStale?: boolean;
3
+ /** Injectable clock for stale checks (tests). */
4
+ nowMs?: number;
5
+ /** Injectable package version (defaults to PACKAGE_VERSION). */
6
+ packageVersion?: string;
7
+ /** Injectable home directory for global hooks dual-inject check (tests). */
8
+ homeDir?: string;
9
+ };
10
+ export type DoctorResult = {
11
+ ok: boolean;
12
+ lines: string[];
13
+ pruned?: number;
14
+ };
15
+ /** True when user-level Cursor hooks still run a legacy global self-review script. */
16
+ export declare function hasGlobalSelfReviewHooks(homeDir: string): boolean;
17
+ export declare function readPinVersion(projectRoot: string): string | null;
18
+ /** Read `session.stale_after_hours` (0 = disabled). Missing file → default 72; bad/invalid config → 0. */
19
+ export declare function readStaleAfterHours(projectRoot: string): number;
20
+ export declare function formatStatus(projectRoot: string): string;
21
+ export declare function runDoctor(projectRoot: string, opts?: DoctorOptions): DoctorResult;
22
+ //# sourceMappingURL=status-doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-doctor.d.ts","sourceRoot":"","sources":["../src/status-doctor.ts"],"names":[],"mappings":"AA4GA,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAKF,sFAAsF;AACtF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAmBjE;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkBjE;AAqGD,0GAA0G;AAC1G,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAe/D;AAiDD,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA+DxD;AAED,wBAAgB,SAAS,CACvB,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE,aAAkB,GACvB,YAAY,CA0bd"}