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
@@ -2,30 +2,34 @@
2
2
  "name": "dev-browser",
3
3
  "version": "0.0.1",
4
4
  "type": "module",
5
- "imports": {
6
- "@/*": "./src/*"
5
+ "engines": {
6
+ "node": ">=22"
7
+ },
8
+ "packageManager": "npm@10.9.2",
9
+ "exports": {
10
+ "./client": {
11
+ "types": "./dist/src/client.d.ts",
12
+ "import": "./dist/src/client.js"
13
+ }
7
14
  },
8
15
  "scripts": {
9
- "start-server": "npx tsx scripts/start.ts standalone",
10
- "start-extension": "npx tsx scripts/start.ts extension",
11
- "dev": "npx tsx --watch src/index.ts",
16
+ "build": "tsc -p tsconfig.json",
17
+ "typecheck": "tsc -p tsconfig.json --noEmit",
18
+ "start": "node dist/scripts/start.js standalone",
19
+ "start-server": "node dist/scripts/start.js standalone",
20
+ "start-extension": "node dist/scripts/start.js extension",
12
21
  "test": "vitest run",
13
22
  "test:watch": "vitest"
14
23
  },
15
24
  "dependencies": {
16
- "@hono/node-server": "^1.19.7",
17
- "@hono/node-ws": "^1.2.0",
18
- "express": "^4.21.0",
19
- "hono": "^4.11.1",
25
+ "@hono/node-server": "^1.19.13",
26
+ "@hono/node-ws": "^1.3.1",
27
+ "hono": "^4.12.30",
20
28
  "playwright": "^1.49.0"
21
29
  },
22
30
  "devDependencies": {
23
- "@types/express": "^5.0.0",
24
- "tsx": "^4.21.0",
31
+ "@types/node": "^22.0.0",
25
32
  "typescript": "^5.0.0",
26
33
  "vitest": "^2.1.0"
27
- },
28
- "optionalDependencies": {
29
- "@rollup/rollup-linux-x64-gnu": "^4.0.0"
30
34
  }
31
35
  }
@@ -17,57 +17,106 @@ Scrolling is slow, unreliable, and wastes time. APIs return structured data with
17
17
 
18
18
  This prevents wasting time debugging a complex script when the issue is a simple path like `data.user.timeline` vs `data.user.result.timeline`.
19
19
 
20
- ## Step-by-Step Workflow
21
-
22
- ### 1. Capture Request Details
23
-
24
- First, intercept a request to understand URL structure and required headers:
25
-
26
- ```typescript
27
- import { connect, waitForPageLoad } from "@/client.js";
28
- import * as fs from "node:fs";
29
-
30
- const client = await connect();
31
- const page = await client.page("site");
32
-
33
- let capturedRequest = null;
34
- page.on("request", (request) => {
35
- const url = request.url();
36
- // Look for API endpoints (adjust pattern for your target site)
37
- if (url.includes("/api/") || url.includes("/graphql/")) {
38
- capturedRequest = {
39
- url: url,
40
- headers: request.headers(),
41
- method: request.method(),
42
- };
43
- fs.writeFileSync("tmp/request-details.json", JSON.stringify(capturedRequest, null, 2));
44
- console.log("Captured request:", url.substring(0, 80) + "...");
20
+ ## External Script Setup
21
+
22
+ Keep the installed skill directory read-only. Put scripts and temporary artifacts in the OS temporary directory or the task workspace, and remove them when the task finishes. External scripts receive the installed skill directory as their first argument and dynamically import the compiled client by file URL.
23
+
24
+ Never persist complete authentication headers. Keep captured headers in memory, and write only redacted metadata or final non-sensitive results.
25
+
26
+ ```javascript
27
+ import { mkdtemp, rm, writeFile } from "node:fs/promises";
28
+ import { tmpdir } from "node:os";
29
+ import { join } from "node:path";
30
+ import { pathToFileURL } from "node:url";
31
+
32
+ const skillDir = process.argv[2];
33
+ if (!skillDir) throw new Error("Pass the installed dev-browser skill directory");
34
+ const { connect, waitForPageLoad } = await import(
35
+ pathToFileURL(join(skillDir, "dist", "src", "client.js")).href
36
+ );
37
+
38
+ const workDir = await mkdtemp(join(tmpdir(), "dev-browser-scrape-"));
39
+ let client;
40
+ try {
41
+ client = await connect();
42
+ const page = await client.page("site");
43
+ let capturedRequest;
44
+
45
+ page.on("request", (request) => {
46
+ const url = request.url();
47
+ if (url.includes("/api/") || url.includes("/graphql/")) {
48
+ capturedRequest = {
49
+ url,
50
+ method: request.method(),
51
+ headers: request.headers(),
52
+ };
53
+ }
54
+ });
55
+
56
+ await page.goto("https://example.com/profile");
57
+ await waitForPageLoad(page);
58
+ await page.waitForTimeout(3000);
59
+
60
+ if (!capturedRequest) throw new Error("No matching API request captured");
61
+ const capturedUrl = new URL(capturedRequest.url);
62
+ console.log({
63
+ url: `${capturedUrl.origin}${capturedUrl.pathname}`,
64
+ method: capturedRequest.method,
65
+ headerNames: Object.keys(capturedRequest.headers),
66
+ });
67
+
68
+ const results = new Map();
69
+ let cursor;
70
+ do {
71
+ const params = { count: 20, ...(cursor ? { cursor } : {}) };
72
+ const url = new URL(capturedRequest.url);
73
+ url.searchParams.set("params", JSON.stringify(params));
74
+ const response = await page.evaluate(
75
+ async ({ url, headers }) => {
76
+ const result = await fetch(url, { headers });
77
+ return result.json();
78
+ },
79
+ { url: url.href, headers: capturedRequest.headers }
80
+ );
81
+
82
+ const entries = response?.data?.entries ?? [];
83
+ cursor = undefined;
84
+ for (const entry of entries) {
85
+ if (entry.type === "cursor-bottom") cursor = entry.value;
86
+ else if (entry.id) results.set(entry.id, entry);
87
+ }
88
+ await new Promise((resolve) => setTimeout(resolve, 500));
89
+ } while (cursor);
90
+
91
+ const resultPath = join(workDir, "results.json");
92
+ await writeFile(resultPath, JSON.stringify([...results.values()], null, 2));
93
+ console.log({ count: results.size, resultPath });
94
+ } finally {
95
+ try {
96
+ await client?.disconnect();
97
+ } finally {
98
+ await rm(workDir, { recursive: true, force: true });
45
99
  }
46
- });
100
+ }
101
+ ```
47
102
 
48
- await page.goto("https://example.com/profile");
49
- await waitForPageLoad(page);
50
- await page.waitForTimeout(3000);
103
+ Run it with quoted paths on Linux, PowerShell, or Command Prompt:
51
104
 
52
- await client.disconnect();
105
+ ```text
106
+ node "PATH_TO_SCRIPT.mjs" "PATH_TO_INSTALLED_DEV_BROWSER"
53
107
  ```
54
108
 
55
- ### 2. Capture Response to Understand Schema
109
+ If a result must survive the script, write the sanitized deliverable to the task workspace instead of `workDir`, then delete it at task completion unless the user asks to retain it.
56
110
 
57
- Save a raw response to inspect the data structure:
111
+ ## Step-by-Step Workflow
58
112
 
59
- ```typescript
60
- page.on("response", async (response) => {
61
- const url = response.url();
62
- if (url.includes("UserTweets") || url.includes("/api/data")) {
63
- const json = await response.json();
64
- fs.writeFileSync("tmp/api-response.json", JSON.stringify(json, null, 2));
65
- console.log("Captured response");
66
- }
67
- });
68
- ```
113
+ ### 1. Capture One Request
114
+
115
+ Match a narrow API or GraphQL URL pattern. Keep the request URL and headers in memory. Log only the URL origin/path, method, and header names while confirming the endpoint; query parameters can contain credentials.
69
116
 
70
- Then analyze the structure to find:
117
+ ### 2. Inspect One Response
118
+
119
+ Inspect the response in memory before building pagination. Find:
71
120
 
72
121
  - Where the data array lives (e.g., `data.user.result.timeline.instructions[].entries`)
73
122
  - Where pagination cursors are (e.g., `cursor-bottom` entries)
@@ -75,67 +124,7 @@ Then analyze the structure to find:
75
124
 
76
125
  ### 3. Replay API with Pagination
77
126
 
78
- Once you understand the schema, replay requests directly:
79
-
80
- ```typescript
81
- import { connect } from "@/client.js";
82
- import * as fs from "node:fs";
83
-
84
- const client = await connect();
85
- const page = await client.page("site");
86
-
87
- const results = new Map(); // Use Map for deduplication
88
- const headers = JSON.parse(fs.readFileSync("tmp/request-details.json", "utf8")).headers;
89
- const baseUrl = "https://example.com/api/data";
90
-
91
- let cursor = null;
92
- let hasMore = true;
93
-
94
- while (hasMore) {
95
- // Build URL with pagination cursor
96
- const params = { count: 20 };
97
- if (cursor) params.cursor = cursor;
98
- const url = `${baseUrl}?params=${encodeURIComponent(JSON.stringify(params))}`;
99
-
100
- // Execute fetch in browser context (has auth cookies/headers)
101
- const response = await page.evaluate(
102
- async ({ url, headers }) => {
103
- const res = await fetch(url, { headers });
104
- return res.json();
105
- },
106
- { url, headers }
107
- );
108
-
109
- // Extract data and cursor (adjust paths for your API)
110
- const entries = response?.data?.entries || [];
111
- for (const entry of entries) {
112
- if (entry.type === "cursor-bottom") {
113
- cursor = entry.value;
114
- } else if (entry.id && !results.has(entry.id)) {
115
- results.set(entry.id, {
116
- id: entry.id,
117
- text: entry.content,
118
- timestamp: entry.created_at,
119
- });
120
- }
121
- }
122
-
123
- console.log(`Fetched page, total: ${results.size}`);
124
-
125
- // Check stop conditions
126
- if (!cursor || entries.length === 0) hasMore = false;
127
-
128
- // Rate limiting - be respectful
129
- await new Promise((r) => setTimeout(r, 500));
130
- }
131
-
132
- // Export results
133
- const data = Array.from(results.values());
134
- fs.writeFileSync("tmp/results.json", JSON.stringify(data, null, 2));
135
- console.log(`Saved ${data.length} items`);
136
-
137
- await client.disconnect();
138
- ```
127
+ Replay through `page.evaluate(fetch)` so the browser supplies its session cookies. Pass only the in-memory headers required by the endpoint, deduplicate with a `Map`, stop when the cursor or results end, and rate-limit requests.
139
128
 
140
129
  ## Key Patterns
141
130
 
@@ -149,7 +138,7 @@ await client.disconnect();
149
138
 
150
139
  ## Tips
151
140
 
152
- - **Extension mode**: `page.context().cookies()` doesn't work - capture auth headers from intercepted requests instead
141
+ - **Extension mode**: `page.context().cookies()` doesn't work - keep intercepted auth headers in memory instead
153
142
  - **Rate limiting**: Add 500ms+ delays between requests to avoid blocks
154
143
  - **Stop conditions**: Check for empty results, missing cursor, or reaching a date/ID threshold
155
144
  - **GraphQL APIs**: URL params often include `variables` and `features` JSON objects - capture and reuse them
@@ -6,9 +6,9 @@ GROK_API_URL=
6
6
  # 必填项:你的 API 密钥
7
7
  GROK_API_KEY=
8
8
 
9
- # 可选项:使用的 Grok 模型(默认:grok-4.20-auto
10
- # 常用选项:grok-4.20-auto, grok-4-fast
11
- GROK_MODEL=grok-4.20-auto
9
+ # 可选项:使用的 Grok 模型(默认:grok-4.20-non-reasoning
10
+ # 常用选项:grok-4.20-non-reasoning, grok-4.20-auto, grok-4-fast
11
+ GROK_MODEL=grok-4.20-non-reasoning
12
12
 
13
13
  # 可选项:启用调试模式(true/false)
14
14
  GROK_DEBUG=false
@@ -24,7 +24,7 @@ Use this skill for web search, webpage retrieval, and current-information lookup
24
24
  ```bash
25
25
  cp "<SKILL_DIR>/.env.example" "<SKILL_DIR>/.env"
26
26
 
27
- python "<SKILL_DIR>/scripts/groksearch_entry.py" web_search --query "search terms" [--platform "GitHub"] [--min-results 3] [--max-results 10] [--model "grok-4.20-auto"] [--extra-sources 3]
27
+ python "<SKILL_DIR>/scripts/groksearch_entry.py" web_search --query "search terms" [--platform "GitHub"] [--min-results 3] [--max-results 10] [--model "grok-4.20-non-reasoning"] [--extra-sources 3]
28
28
 
29
29
  python "<SKILL_DIR>/scripts/groksearch_entry.py" web_fetch --url "https://..." [--out file.md] [--fallback-grok]
30
30
 
@@ -0,0 +1,3 @@
1
+ {
2
+ "model": "grok-4.20-non-reasoning"
3
+ }
@@ -0,0 +1,4 @@
1
+ GrokSearch_new/
2
+ .env
3
+ .venv/
4
+ *__pycache__*
@@ -9,6 +9,7 @@ def load_dotenv() -> bool:
9
9
  if not env_path.exists():
10
10
  return False
11
11
  try:
12
+ seen_keys = set()
12
13
  with open(env_path, "r", encoding="utf-8") as f:
13
14
  for line in f:
14
15
  line = line.strip()
@@ -21,7 +22,10 @@ def load_dotenv() -> bool:
21
22
  value.startswith("'") and value.endswith("'")
22
23
  ):
23
24
  value = value[1:-1]
24
- if key and not os.environ.get(key):
25
+ if not key or key in seen_keys:
26
+ continue
27
+ seen_keys.add(key)
28
+ if not os.environ.get(key):
25
29
  os.environ[key] = value
26
30
  return True
27
31
  except IOError:
@@ -15,6 +15,8 @@ from pathlib import Path
15
15
  from typing import Optional
16
16
  from urllib.parse import urlsplit, urlunsplit
17
17
 
18
+ from _dotenv import load_dotenv
19
+
18
20
  try:
19
21
  import httpx
20
22
  from tenacity import AsyncRetrying, retry_if_exception, stop_after_attempt, wait_random_exponential
@@ -24,38 +26,6 @@ except ImportError:
24
26
  sys.exit(1)
25
27
 
26
28
 
27
- # ============================================================================
28
- # .env 文件支持
29
- # ============================================================================
30
-
31
- def load_dotenv() -> bool:
32
- """从项目根目录的 .env 文件加载环境变量。"""
33
- env_path = Path(__file__).parent.parent / ".env"
34
- if env_path.exists():
35
- try:
36
- with open(env_path, 'r', encoding='utf-8') as f:
37
- for line in f:
38
- line = line.strip()
39
- if not line or line.startswith('#'):
40
- continue
41
- if '=' in line:
42
- key, _, value = line.partition('=')
43
- key = key.strip()
44
- value = value.strip()
45
- # 如果存在引号则移除
46
- if (value.startswith('"') and value.endswith('"')) or \
47
- (value.startswith("'") and value.endswith("'")):
48
- value = value[1:-1]
49
- # 允许 .env 覆盖空字符串环境变量
50
- if key and not os.environ.get(key):
51
- os.environ[key] = value
52
- return True
53
- except IOError:
54
- pass
55
- return False
56
-
57
-
58
- # 模块导入时加载 .env
59
29
  load_dotenv()
60
30
 
61
31
 
@@ -63,9 +33,21 @@ load_dotenv()
63
33
  # 配置
64
34
  # ============================================================================
65
35
 
36
+ def load_default_model() -> str:
37
+ defaults_path = Path(__file__).resolve().parent.parent / "defaults.json"
38
+ try:
39
+ defaults = json.loads(defaults_path.read_text(encoding="utf-8"))
40
+ model = defaults["model"]
41
+ except (OSError, json.JSONDecodeError, KeyError, TypeError) as error:
42
+ raise RuntimeError(f"无法读取 Grok 默认配置 {defaults_path}: {error}") from error
43
+ if not isinstance(model, str) or not model.strip():
44
+ raise RuntimeError(f"Grok 默认配置缺少有效 model: {defaults_path}")
45
+ return model
46
+
47
+
66
48
  class Config:
67
49
  _instance = None
68
- _DEFAULT_MODEL = "grok-4.20-auto"
50
+ _DEFAULT_MODEL = load_default_model()
69
51
 
70
52
  def __new__(cls):
71
53
  if cls._instance is None:
@@ -2,7 +2,6 @@
2
2
  name: prompt-enhancer
3
3
  description: |
4
4
  Rewrite a raw prompt into a clearer prompt for a coding agent. Use only when the user explicitly asks to improve, optimize, rewrite, or structure a prompt for Codex, Claude Code, Gemini CLI, or another AI agent. Triggers: "improve this prompt", "rewrite this prompt", "optimize this prompt for Codex", "make this prompt better for an AI agent".
5
- allowed-tools: Bash(python:*), Bash(python3:*), Bash(uv:*), Read, Grep
6
5
  ---
7
6
 
8
7
  # Prompt Enhancer
@@ -19,31 +18,7 @@ Do not use this for general writing edits like email, docs, or PR copy.
19
18
 
20
19
  ## Do
21
20
 
22
- - Default path: rewrite the prompt directly with the current agent using the structure from [TEMPLATE.md](TEMPLATE.md).
23
- - Third-party path: use the Python entrypoint only when the user explicitly provides `url`, `apiKey`, and `model`, or when all three are already configured in `<SKILL_DIR>/.env`.
24
-
25
- ```bash
26
- python "<SKILL_DIR>/scripts/prompt_enhancer_entry.py" "user's raw prompt here"
27
- ```
28
-
29
- - Do not call `scripts/enhance.py` directly.
30
- - Use the installed skill directory for `<SKILL_DIR>`.
31
- - If any of `url`, `apiKey`, or `model` is missing, do not invoke the script. Use the current agent directly instead.
32
- - Optional setup: `cp "<SKILL_DIR>/.env.example" "<SKILL_DIR>/.env"`
33
-
34
- ## Output
35
-
36
- - Read the enhanced prompt from `stdout`.
37
- - Keep `stderr` for usage or optional debug output only.
21
+ - Rewrite the prompt directly with the current agent, following the structure from [TEMPLATE.md](TEMPLATE.md).
38
22
  - Preserve the user's intent and explicit constraints.
39
23
  - Add structure and missing execution context only when it helps the agent act.
40
- - When running directly in the current agent, use placeholders for unknown context instead of inventing new requirements.
41
-
42
- ## Notes
43
-
44
- - Local config file: `<SKILL_DIR>/.env`
45
- - The entrypoint auto-loads `<SKILL_DIR>/.env` before bootstrap and dependency install.
46
- - Optional debug flag: `PE_DEBUG=1`
47
- - Bootstrap controls: `PROMPT_ENHANCER_VENV_DIR`, `PROMPT_ENHANCER_PYTHON`, `AGENTS_SKILLS_PYTHON`
48
- - Setup and troubleshooting: [ADVANCED.md](ADVANCED.md)
49
- - Prompt template reference: [TEMPLATE.md](TEMPLATE.md)
24
+ - Use placeholders for unknown context instead of inventing new requirements.
@@ -84,8 +84,4 @@ Identify and fix the sorting bug in the codebase.
84
84
  5. Add or update tests to cover the bug scenario
85
85
 
86
86
  # Constraints
87
- - Maintain backward compatibility
88
- - Do not change the function signature unless necessary
89
- - Add inline comments explaining the fix
90
87
  ```
91
-
package/.skill-lock.json DELETED
@@ -1,29 +0,0 @@
1
- {
2
- "version": 3,
3
- "skills": {
4
- "git-commit": {
5
- "source": "github/awesome-copilot",
6
- "sourceType": "github",
7
- "sourceUrl": "https://github.com/github/awesome-copilot.git",
8
- "skillPath": "skills/git-commit/SKILL.md",
9
- "skillFolderHash": "883a6a7466f55a9cd9f22cf1cce2d9333fc9b998",
10
- "installedAt": "2026-03-12T08:25:08.313Z",
11
- "updatedAt": "2026-03-12T08:25:08.313Z"
12
- }
13
- },
14
- "dismissed": {
15
- "findSkillsPrompt": true
16
- },
17
- "lastSelectedAgents": [
18
- "amp",
19
- "cline",
20
- "codex",
21
- "cursor",
22
- "gemini-cli",
23
- "github-copilot",
24
- "kimi-cli",
25
- "opencode",
26
- "claude-code",
27
- "crush"
28
- ]
29
- }
package/AGENTS.md DELETED
@@ -1,45 +0,0 @@
1
- # Configuration
2
-
3
- ## Language
4
-
5
- - Tool/model interactions: **English**
6
- - User-facing output: **Chinese**
7
-
8
- ## Code Style
9
-
10
- - Concise, efficient, no redundancy
11
- - Minimal comments/docs (only when necessary)
12
- - Targeted changes only; never touch unrelated functionality
13
-
14
- ## Context Rules
15
-
16
- - {{CODEBASE_RETRIEVAL_POLICY}}
17
- - Rely only on project code plus `grok/context7` results
18
- - If information is insufficient or uncertain, state it explicitly
19
-
20
- ## Workflow
21
-
22
- ```
23
- /abel-init → /abel-research → /abel-plan → /abel-implement(TDD)
24
- ↘ /abel-diagnose (bug fix)
25
- ```
26
-
27
- ## Universal Constraints
28
-
29
- 1. Use `unified diff patch` format for proposed/applied changes
30
- 2. Require confidence ≥90% before applying changes
31
-
32
- ## Stage Skill Matrix
33
-
34
- | Skill | Research | Plan | Implement | Diagnose | Capability & Triggers |
35
- | --- | :---: | :---: | :---: | :---: | --- |
36
- | /sequential-think | ✅ | ✅ | ❌ | ✅ | Multi-step reasoning, hypothesis testing. Trigger: 3+ interconnected components |
37
- | /grok-search | ✅ | ○ | ❌ | ✅ | Deep research, concept understanding. Trigger: architectural patterns, best practices |
38
- | /context7-auto-research | ✅ | ✅ | ✅ | ✅ | Official docs retrieval. Trigger: framework/library usage, APIs |
39
- | /dev-browser | ○ | ○ | ✅ | ✅ | Browser automation. Trigger: E2E testing, UI verification |
40
- | /confidence-check | ❌ | ✅ | ✅ | ✅ | Readiness verification. Trigger: before implementation/fix (≥90%) |
41
- | /time | ○ | ✅ | ✅ | ○ | Time/timezone operations. Trigger: scheduling logic |
42
-
43
- Legend: ✅ Primary, ○ Optional, ❌ Forbidden
44
-
45
- OpenSpec commands: `/opsx:new` `/opsx:ff` `/opsx:archive` `openspec view` `openspec status`