abelworkflow 0.9.2 → 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 (134) hide show
  1. package/README.md +54 -182
  2. package/bin/abelworkflow.mjs +5 -3
  3. package/extensions/pi-gpt-responses-compat/index.ts +1 -1
  4. package/lib/cli/args.mjs +76 -0
  5. package/lib/cli/main.mjs +385 -0
  6. package/lib/cli/prompts.mjs +106 -0
  7. package/lib/config/dotenv.mjs +102 -0
  8. package/lib/config/jsonc.mjs +80 -0
  9. package/lib/config/store.mjs +310 -0
  10. package/lib/config/toml.mjs +638 -0
  11. package/lib/installer/assets.mjs +324 -0
  12. package/lib/installer/install.mjs +153 -0
  13. package/lib/installer/links.mjs +427 -0
  14. package/lib/installer/state.mjs +163 -0
  15. package/lib/paths.mjs +99 -0
  16. package/lib/providers/claude.mjs +197 -0
  17. package/lib/providers/codex.mjs +433 -0
  18. package/lib/providers/pi.mjs +577 -0
  19. package/lib/providers/skills.mjs +105 -0
  20. package/lib/templates/codex/agents/default.toml +7 -0
  21. package/lib/templates/codex/agents/explorer.toml +7 -0
  22. package/lib/templates/codex/agents/planner.toml +7 -0
  23. package/lib/templates/codex/agents/reviewer.toml +7 -0
  24. package/lib/templates/codex/agents/worker.toml +7 -0
  25. package/lib/templates/codex/config-base.toml +11 -3
  26. package/lib/templates/workflow/AGENTS.md +50 -0
  27. package/lib/templates/workflow/commands/abel-design.md +175 -0
  28. package/{commands → lib/templates/workflow/commands}/abel-diagnose.md +5 -5
  29. package/lib/templates/workflow/commands/abel-implement.md +170 -0
  30. package/{commands → lib/templates/workflow/commands}/abel-init.md +3 -5
  31. package/{.gitignore → lib/templates/workflow/gitignore.template} +0 -2
  32. package/lib/tools/cli-installer.mjs +277 -0
  33. package/package.json +37 -10
  34. package/skills/context7-auto-research/SKILL.md +5 -5
  35. package/skills/context7-auto-research/{context7-api.js → context7-api.cjs} +5 -8
  36. package/skills/dev-browser/SKILL.md +53 -33
  37. package/skills/dev-browser/dist/scripts/start.d.ts +2 -0
  38. package/skills/dev-browser/dist/scripts/start.d.ts.map +1 -0
  39. package/skills/dev-browser/dist/scripts/start.js +118 -0
  40. package/skills/dev-browser/dist/scripts/start.js.map +1 -0
  41. package/skills/dev-browser/dist/src/client.d.ts +93 -0
  42. package/skills/dev-browser/dist/src/client.d.ts.map +1 -0
  43. package/skills/dev-browser/dist/src/client.js +310 -0
  44. package/skills/dev-browser/dist/src/client.js.map +1 -0
  45. package/skills/dev-browser/dist/src/entrypoint.d.ts +29 -0
  46. package/skills/dev-browser/dist/src/entrypoint.d.ts.map +1 -0
  47. package/skills/dev-browser/dist/src/entrypoint.js +106 -0
  48. package/skills/dev-browser/dist/src/entrypoint.js.map +1 -0
  49. package/skills/dev-browser/dist/src/index.d.ts +4 -0
  50. package/skills/dev-browser/dist/src/index.d.ts.map +1 -0
  51. package/skills/dev-browser/dist/src/index.js +2 -0
  52. package/skills/dev-browser/dist/src/index.js.map +1 -0
  53. package/skills/dev-browser/dist/src/page-api.d.ts +25 -0
  54. package/skills/dev-browser/dist/src/page-api.d.ts.map +1 -0
  55. package/skills/dev-browser/dist/src/page-api.js +104 -0
  56. package/skills/dev-browser/dist/src/page-api.js.map +1 -0
  57. package/skills/dev-browser/dist/src/relay.d.ts +27 -0
  58. package/skills/dev-browser/dist/src/relay.d.ts.map +1 -0
  59. package/skills/dev-browser/dist/src/relay.js +521 -0
  60. package/skills/dev-browser/dist/src/relay.js.map +1 -0
  61. package/skills/dev-browser/dist/src/runtime.d.ts +45 -0
  62. package/skills/dev-browser/dist/src/runtime.d.ts.map +1 -0
  63. package/skills/dev-browser/dist/src/runtime.js +54 -0
  64. package/skills/dev-browser/dist/src/runtime.js.map +1 -0
  65. package/skills/dev-browser/dist/src/snapshot/browser-script.d.ts +23 -0
  66. package/skills/dev-browser/dist/src/snapshot/browser-script.d.ts.map +1 -0
  67. package/skills/dev-browser/{src/snapshot/browser-script.ts → dist/src/snapshot/browser-script.js} +21 -30
  68. package/skills/dev-browser/dist/src/snapshot/browser-script.js.map +1 -0
  69. package/skills/dev-browser/dist/src/snapshot/index.d.ts +14 -0
  70. package/skills/dev-browser/dist/src/snapshot/index.d.ts.map +1 -0
  71. package/skills/dev-browser/{src/snapshot/index.ts → dist/src/snapshot/index.js} +2 -2
  72. package/skills/dev-browser/dist/src/snapshot/index.js.map +1 -0
  73. package/skills/dev-browser/dist/src/snapshot/inject.d.ts +13 -0
  74. package/skills/dev-browser/dist/src/snapshot/inject.d.ts.map +1 -0
  75. package/skills/dev-browser/{src/snapshot/inject.ts → dist/src/snapshot/inject.js} +2 -2
  76. package/skills/dev-browser/dist/src/snapshot/inject.js.map +1 -0
  77. package/skills/dev-browser/dist/src/standalone.d.ts +32 -0
  78. package/skills/dev-browser/dist/src/standalone.d.ts.map +1 -0
  79. package/skills/dev-browser/dist/src/standalone.js +174 -0
  80. package/skills/dev-browser/dist/src/standalone.js.map +1 -0
  81. package/skills/dev-browser/dist/src/startup.d.ts +55 -0
  82. package/skills/dev-browser/dist/src/startup.d.ts.map +1 -0
  83. package/skills/dev-browser/dist/src/startup.js +81 -0
  84. package/skills/dev-browser/dist/src/startup.js.map +1 -0
  85. package/skills/dev-browser/dist/src/target-registry.d.ts +29 -0
  86. package/skills/dev-browser/dist/src/target-registry.d.ts.map +1 -0
  87. package/skills/dev-browser/dist/src/target-registry.js +135 -0
  88. package/skills/dev-browser/dist/src/target-registry.js.map +1 -0
  89. package/skills/dev-browser/dist/src/types.d.ts +27 -0
  90. package/skills/dev-browser/dist/src/types.d.ts.map +1 -0
  91. package/skills/dev-browser/dist/src/types.js +2 -0
  92. package/skills/dev-browser/dist/src/types.js.map +1 -0
  93. package/skills/dev-browser/package-lock.json +67 -1510
  94. package/skills/dev-browser/package.json +18 -14
  95. package/skills/dev-browser/references/scraping.md +94 -105
  96. package/skills/grok-search/.env.example +3 -3
  97. package/skills/grok-search/SKILL.md +1 -1
  98. package/skills/grok-search/defaults.json +3 -0
  99. package/skills/grok-search/gitignore.template +4 -0
  100. package/skills/grok-search/scripts/_dotenv.py +5 -1
  101. package/skills/grok-search/scripts/groksearch_cli.py +15 -33
  102. package/skills/prompt-enhancer/SKILL.md +2 -27
  103. package/skills/prompt-enhancer/TEMPLATE.md +0 -4
  104. package/.skill-lock.json +0 -29
  105. package/AGENTS.md +0 -45
  106. package/commands/abel-implement.md +0 -157
  107. package/commands/abel-plan.md +0 -88
  108. package/commands/abel-research.md +0 -126
  109. package/lib/cli/logic.mjs +0 -213
  110. package/lib/cli.mjs +0 -3016
  111. package/skills/confidence-check/SKILL.md +0 -34
  112. package/skills/confidence-check/confidence.ts +0 -276
  113. package/skills/dev-browser/bun.lock +0 -460
  114. package/skills/dev-browser/scripts/start.ts +0 -280
  115. package/skills/dev-browser/src/client.ts +0 -474
  116. package/skills/dev-browser/src/entrypoint.ts +0 -157
  117. package/skills/dev-browser/src/index.ts +0 -289
  118. package/skills/dev-browser/src/relay.ts +0 -731
  119. package/skills/dev-browser/src/runtime.test.ts +0 -60
  120. package/skills/dev-browser/src/runtime.ts +0 -171
  121. package/skills/dev-browser/src/startup.test.ts +0 -95
  122. package/skills/dev-browser/src/startup.ts +0 -153
  123. package/skills/dev-browser/src/types.ts +0 -35
  124. package/skills/dev-browser/tsconfig.json +0 -36
  125. package/skills/dev-browser/vitest.config.ts +0 -12
  126. package/skills/prompt-enhancer/.env.example +0 -12
  127. package/skills/prompt-enhancer/ADVANCED.md +0 -103
  128. package/skills/prompt-enhancer/requirements.txt +0 -2
  129. package/skills/prompt-enhancer/scripts/_dotenv.py +0 -28
  130. package/skills/prompt-enhancer/scripts/enhance.py +0 -191
  131. package/skills/prompt-enhancer/scripts/prompt_enhancer_entry.py +0 -253
  132. package/skills/sequential-think/SKILL.md +0 -198
  133. package/skills/sequential-think/scripts/.env.example +0 -5
  134. package/skills/sequential-think/scripts/sequential_think_cli.py +0 -253
@@ -1,289 +0,0 @@
1
- import express, { type Express, type Request, type Response } from "express";
2
- import { chromium, type BrowserContext, type Page } from "playwright";
3
- import { mkdirSync } from "fs";
4
- import { join } from "path";
5
- import type { Socket } from "net";
6
- import { formatHttpUrl } from "./entrypoint";
7
- import type {
8
- ServeOptions,
9
- GetPageRequest,
10
- GetPageResponse,
11
- ListPagesResponse,
12
- ServerInfoResponse,
13
- } from "./types";
14
-
15
- export type { ServeOptions, GetPageResponse, ListPagesResponse, ServerInfoResponse };
16
-
17
- export interface DevBrowserServer {
18
- wsEndpoint: string;
19
- port: number;
20
- stop: () => Promise<void>;
21
- }
22
-
23
- // Helper to retry fetch with exponential backoff
24
- async function fetchWithRetry(
25
- url: string,
26
- maxRetries = 5,
27
- delayMs = 500
28
- ): Promise<globalThis.Response> {
29
- let lastError: Error | null = null;
30
- for (let i = 0; i < maxRetries; i++) {
31
- try {
32
- const res = await fetch(url);
33
- if (res.ok) return res;
34
- throw new Error(`HTTP ${res.status}: ${res.statusText}`);
35
- } catch (err) {
36
- lastError = err instanceof Error ? err : new Error(String(err));
37
- if (i < maxRetries - 1) {
38
- await new Promise((resolve) => setTimeout(resolve, delayMs * (i + 1)));
39
- }
40
- }
41
- }
42
- throw new Error(`Failed after ${maxRetries} retries: ${lastError?.message}`);
43
- }
44
-
45
- // Helper to add timeout to promises
46
- function withTimeout<T>(promise: Promise<T>, ms: number, message: string): Promise<T> {
47
- return Promise.race([
48
- promise,
49
- new Promise<never>((_, reject) =>
50
- setTimeout(() => reject(new Error(`Timeout: ${message}`)), ms)
51
- ),
52
- ]);
53
- }
54
-
55
- export async function serve(options: ServeOptions = {}): Promise<DevBrowserServer> {
56
- const port = options.port ?? 9222;
57
- const host = options.host ?? "localhost";
58
- const headless = options.headless ?? false;
59
- const cdpPort = options.cdpPort ?? 9223;
60
- const profileDir = options.profileDir;
61
-
62
- // Validate port numbers
63
- if (port < 1 || port > 65535) {
64
- throw new Error(`Invalid port: ${port}. Must be between 1 and 65535`);
65
- }
66
- if (cdpPort < 1 || cdpPort > 65535) {
67
- throw new Error(`Invalid cdpPort: ${cdpPort}. Must be between 1 and 65535`);
68
- }
69
- if (port === cdpPort) {
70
- throw new Error("port and cdpPort must be different");
71
- }
72
-
73
- // Determine user data directory for persistent context
74
- const userDataDir = profileDir
75
- ? join(profileDir, "browser-data")
76
- : join(process.cwd(), ".browser-data");
77
-
78
- // Create directory if it doesn't exist
79
- mkdirSync(userDataDir, { recursive: true });
80
- console.log(`Using persistent browser profile: ${userDataDir}`);
81
-
82
- console.log("Launching browser with persistent context...");
83
-
84
- // Launch persistent context - this persists cookies, localStorage, cache, etc.
85
- const context: BrowserContext = await chromium.launchPersistentContext(userDataDir, {
86
- headless,
87
- args: [`--remote-debugging-port=${cdpPort}`],
88
- });
89
- console.log("Browser launched with persistent profile...");
90
-
91
- // Get the CDP WebSocket endpoint from Chrome's JSON API (with retry for slow startup)
92
- const cdpResponse = await fetchWithRetry(`http://127.0.0.1:${cdpPort}/json/version`);
93
- const cdpInfo = (await cdpResponse.json()) as { webSocketDebuggerUrl: string };
94
- const wsEndpoint = cdpInfo.webSocketDebuggerUrl;
95
- console.log(`CDP WebSocket endpoint: ${wsEndpoint}`);
96
-
97
- // Registry entry type for page tracking
98
- interface PageEntry {
99
- page: Page;
100
- targetId: string;
101
- }
102
-
103
- // Registry: name -> PageEntry
104
- const registry = new Map<string, PageEntry>();
105
-
106
- // Helper to get CDP targetId for a page
107
- async function getTargetId(page: Page): Promise<string> {
108
- const cdpSession = await context.newCDPSession(page);
109
- try {
110
- const { targetInfo } = await cdpSession.send("Target.getTargetInfo");
111
- return targetInfo.targetId;
112
- } finally {
113
- await cdpSession.detach();
114
- }
115
- }
116
-
117
- // Express server for page management
118
- const app: Express = express();
119
- app.use(express.json());
120
-
121
- // GET / - server info
122
- app.get("/", (_req: Request, res: Response) => {
123
- const response: ServerInfoResponse = { wsEndpoint };
124
- res.json(response);
125
- });
126
-
127
- // GET /pages - list all pages
128
- app.get("/pages", (_req: Request, res: Response) => {
129
- const response: ListPagesResponse = {
130
- pages: Array.from(registry.keys()),
131
- };
132
- res.json(response);
133
- });
134
-
135
- // POST /pages - get or create page
136
- app.post("/pages", async (req: Request, res: Response) => {
137
- const body = req.body as GetPageRequest;
138
- const { name, viewport } = body;
139
-
140
- if (!name || typeof name !== "string") {
141
- res.status(400).json({ error: "name is required and must be a string" });
142
- return;
143
- }
144
-
145
- if (name.length === 0) {
146
- res.status(400).json({ error: "name cannot be empty" });
147
- return;
148
- }
149
-
150
- if (name.length > 256) {
151
- res.status(400).json({ error: "name must be 256 characters or less" });
152
- return;
153
- }
154
-
155
- // Check if page already exists
156
- let entry = registry.get(name);
157
- if (!entry) {
158
- // Create new page in the persistent context (with timeout to prevent hangs)
159
- const page = await withTimeout(context.newPage(), 30000, "Page creation timed out after 30s");
160
-
161
- // Apply viewport if provided
162
- if (viewport) {
163
- await page.setViewportSize(viewport);
164
- }
165
-
166
- const targetId = await getTargetId(page);
167
- entry = { page, targetId };
168
- registry.set(name, entry);
169
-
170
- // Clean up registry when page is closed (e.g., user clicks X)
171
- page.on("close", () => {
172
- registry.delete(name);
173
- });
174
- }
175
-
176
- const response: GetPageResponse = { wsEndpoint, name, targetId: entry.targetId };
177
- res.json(response);
178
- });
179
-
180
- // DELETE /pages/:name - close a page
181
- app.delete("/pages/:name", async (req: Request<{ name: string }>, res: Response) => {
182
- const name = decodeURIComponent(req.params.name);
183
- const entry = registry.get(name);
184
-
185
- if (entry) {
186
- await entry.page.close();
187
- registry.delete(name);
188
- res.json({ success: true });
189
- return;
190
- }
191
-
192
- res.status(404).json({ error: "page not found" });
193
- });
194
-
195
- // Start the server
196
- const server = app.listen(port, host, () => {
197
- console.log(`HTTP API server running on ${formatHttpUrl(host, port)}`);
198
- });
199
-
200
- // Track active connections for clean shutdown
201
- const connections = new Set<Socket>();
202
- server.on("connection", (socket: Socket) => {
203
- connections.add(socket);
204
- socket.on("close", () => connections.delete(socket));
205
- });
206
-
207
- // Track if cleanup has been called to avoid double cleanup
208
- let cleaningUp = false;
209
-
210
- // Cleanup function
211
- const cleanup = async () => {
212
- if (cleaningUp) return;
213
- cleaningUp = true;
214
-
215
- console.log("\nShutting down...");
216
-
217
- // Close all active HTTP connections
218
- for (const socket of connections) {
219
- socket.destroy();
220
- }
221
- connections.clear();
222
-
223
- // Close all pages
224
- for (const entry of registry.values()) {
225
- try {
226
- await entry.page.close();
227
- } catch {
228
- // Page might already be closed
229
- }
230
- }
231
- registry.clear();
232
-
233
- // Close context (this also closes the browser)
234
- try {
235
- await context.close();
236
- } catch {
237
- // Context might already be closed
238
- }
239
-
240
- server.close();
241
- console.log("Server stopped.");
242
- };
243
-
244
- // Synchronous cleanup for forced exits
245
- const syncCleanup = () => {
246
- try {
247
- context.close();
248
- } catch {
249
- // Best effort
250
- }
251
- };
252
-
253
- // Signal handlers (consolidated to reduce duplication)
254
- const signals = ["SIGINT", "SIGTERM", "SIGHUP"] as const;
255
-
256
- const signalHandler = async () => {
257
- await cleanup();
258
- process.exit(0);
259
- };
260
-
261
- const errorHandler = async (err: unknown) => {
262
- console.error("Unhandled error:", err);
263
- await cleanup();
264
- process.exit(1);
265
- };
266
-
267
- // Register handlers
268
- signals.forEach((sig) => process.on(sig, signalHandler));
269
- process.on("uncaughtException", errorHandler);
270
- process.on("unhandledRejection", errorHandler);
271
- process.on("exit", syncCleanup);
272
-
273
- // Helper to remove all handlers
274
- const removeHandlers = () => {
275
- signals.forEach((sig) => process.off(sig, signalHandler));
276
- process.off("uncaughtException", errorHandler);
277
- process.off("unhandledRejection", errorHandler);
278
- process.off("exit", syncCleanup);
279
- };
280
-
281
- return {
282
- wsEndpoint,
283
- port,
284
- async stop() {
285
- removeHandlers();
286
- await cleanup();
287
- },
288
- };
289
- }