abelworkflow 0.1.0 → 0.2.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abelworkflow",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Install AbelWorkflow into ~/.agents and create Claude/Codex symlinks.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -2,113 +2,42 @@
2
2
  name: grok-search
3
3
  description: |
4
4
  Enhanced web search and real-time content retrieval via Grok API. Use when: (1) Web search / information retrieval / fact-checking, (2) Webpage content extraction / URL parsing, (3) Breaking knowledge cutoff limits for current information, (4) Real-time news and technical documentation, (5) Multi-source information aggregation. Triggers: "search for", "find information about", "latest news", "current", "fetch webpage", "get content from URL". IMPORTANT: This skill REPLACES built-in WebSearch/WebFetch with CLI commands.
5
+ allowed-tools: Bash(python:*), Bash(python3:*), Bash(uv:*), Read, Grep
5
6
  ---
6
7
 
7
8
  # Grok Search
8
9
 
9
- Enhanced web search via Grok API CLI.
10
+ Use this skill for web search, webpage retrieval, and current-information lookups. Replace built-in `WebSearch` and `WebFetch` with the CLI below.
10
11
 
11
- ## CLI Commands
12
+ ## Rules
12
13
 
13
- ```bash
14
- # Canonical entrypoint (agents + cross-platform)
15
- # - Resolve the installed skill directory first; do not assume the current repo contains skills/grok-search
16
- # - Prefer user-level skill directories under $HOME first, for example:
17
- # $HOME/.claude/skills/grok-search
18
- # $HOME/.codex/skills/grok-search
19
- # $HOME/.config/agents/skills/grok-search
20
- # - If not found, check project-level locations:
21
- # .claude/skills/grok-search
22
- # .codex/skills/grok-search
23
- # .agents/skills/grok-search
24
- # - Use system python only to bootstrap; entry.py creates/reuses repo-local .venv
25
- # - Never invoke scripts/groksearch_cli.py directly
26
- #
27
- # One-time setup:
28
- # cp .env.example .env
29
- python "<SKILL_DIR>/scripts/groksearch_entry.py" --help
14
+ - Always call `python "<SKILL_DIR>/scripts/groksearch_entry.py" ...`.
15
+ - Do not call `scripts/groksearch_cli.py` directly.
16
+ - The entrypoint auto-loads `<SKILL_DIR>/.env`.
17
+ - Required env: `GROK_API_URL`, `GROK_API_KEY`.
18
+ - Optional env: `GROK_MODEL`, `GROK_DEBUG`, `GROK_RETRY_*`, `TAVILY_API_KEY`, `TAVILY_API_URL`, `TAVILY_ENABLED`, `GROKSEARCH_VENV_DIR`, `GROKSEARCH_PYTHON`, `AGENTS_SKILLS_PYTHON`.
19
+ - For time-sensitive answers, include source URLs and the relevant date.
20
+ - Start with `web_search`; use `web_fetch` for page content; use `web_map` for site structure.
30
21
 
31
- # Environment (required): GROK_API_URL, GROK_API_KEY
32
- # Environment (optional): GROK_MODEL, GROK_DEBUG, GROK_RETRY_*
33
- # Environment (optional fetch/map): TAVILY_API_KEY, TAVILY_API_URL, TAVILY_ENABLED
34
- #
35
- # .env path:
36
- # skills/grok-search/.env
37
- #
38
- # Bootstrap controls (optional):
39
- # GROKSEARCH_VENV_DIR=/path/to/venv
40
- # GROKSEARCH_PYTHON=3.12
41
- # AGENTS_SKILLS_PYTHON=/abs/path/to/python
22
+ ## Commands
42
23
 
43
- # Optional if you intentionally change into the installed skill directory first:
44
- # cd "<SKILL_DIR>" && python scripts/groksearch_entry.py --help
24
+ ```bash
25
+ cp "<SKILL_DIR>/.env.example" "<SKILL_DIR>/.env"
45
26
 
46
- # Web search
47
- python "<SKILL_DIR>/scripts/groksearch_entry.py" web_search --query "search terms" [--platform "GitHub"] [--min-results 3] [--max-results 10] [--model "grok-4-fast"] [--extra-sources 6]
48
- # If you need broader search coverage, you can add Tavily sources explicitly, for example: --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-fast"] [--extra-sources 3]
49
28
 
50
- # Fetch webpage
51
29
  python "<SKILL_DIR>/scripts/groksearch_entry.py" web_fetch --url "https://..." [--out file.md] [--fallback-grok]
52
30
 
53
- # Map website structure (Tavily)
54
- python "<SKILL_DIR>/scripts/groksearch_entry.py" web_map --url "https://..." [--max-depth 2] [--limit 80]
31
+ python "<SKILL_DIR>/scripts/groksearch_entry.py" web_map --url "https://..." [--instructions "focus area"] [--max-depth 2] [--limit 80]
55
32
 
56
- # Check config
57
33
  python "<SKILL_DIR>/scripts/groksearch_entry.py" get_config_info [--no-test]
58
34
 
59
- # Toggle built-in tools
60
35
  python "<SKILL_DIR>/scripts/groksearch_entry.py" toggle_builtin_tools --action on|off|status [--root /path/to/project]
61
36
  ```
62
37
 
63
- ## Tool Routing Policy
64
- ### Forced Replacement Rules
65
-
66
- | Scenario | Disabled | Use Instead |
67
- |----------|----------|-------------|
68
- | Web Search | `WebSearch` | CLI `web_search` via `groksearch_entry.py` |
69
- | Web Fetch | `WebFetch` | CLI `web_fetch` via `groksearch_entry.py` |
70
-
71
- ### Tool Capability Matrix
72
-
73
- | Tool | Parameters | Output |
74
- |------|------------|--------|
75
- | `web_search` | `query`(required), `platform`/`min_results`/`max_results`/`model`/`extra_sources`(optional) | `[{title,url,description}]` |
76
- | `web_fetch` | `url`(required), `out`/`fallback_grok`(optional) | Structured Markdown |
77
- | `web_map` | `url`(required), `instructions`/`max_depth`/`max_breadth`/`limit`/`timeout`(optional) | JSON string |
78
- | `get_config_info` | `no_test`(optional) | `{api_url,status,connection_test}` |
79
- | `toggle_builtin_tools` | `action`(on/off/status), `root`(optional) | `{blocked,deny_list}` |
80
-
81
- ## Search Workflow
82
-
83
- ### Phase 1: Query Construction
84
- - **Intent Recognition**: Broad search → `web_search` | Deep retrieval → `web_fetch`
85
- - **Parameter Optimization**: Set `platform` for specific sources, adjust result counts; if you need broader source coverage, consider adding `--extra-sources 3`
86
-
87
- ### Phase 2: Search Execution
88
- 1. Start with `web_search` for structured summaries
89
- 2. Use `web_fetch` on key URLs if summaries insufficient
90
- 3. Retry with adjusted query if first round unsatisfactory
91
-
92
- ### Phase 3: Result Synthesis
93
- 1. Cross-reference multiple sources
94
- 2. **Must annotate source and date** for time-sensitive info
95
- 3. **Must include source URLs**: `Title [<sup>1</sup>](URL)`
96
-
97
- ## Error Handling
98
-
99
- | Error | Recovery |
100
- |-------|----------|
101
- | Connection Failure | Run `get_config_info`, verify API URL/Key |
102
- | No Results | Broaden search terms |
103
- | Fetch Timeout | Try alternative sources |
104
- | Tavily unavailable while using `--extra-sources` | Command keeps Grok results and prints a Tavily warning to stderr |
105
- | Tavily extract failure | Use `--fallback-grok`, or inspect the Tavily warning/error message |
106
-
107
- ## Anti-Patterns
38
+ ## Failure Recovery
108
39
 
109
- | Prohibited | Correct |
110
- |------------|---------|
111
- | No source citation | Include `Source [<sup>1</sup>](URL)` |
112
- | Assume current repo has `skills/grok-search` | Check global skill directories under `$HOME` first, then project-level `.claude/.codex/.agents`, then call `<SKILL_DIR>/scripts/groksearch_entry.py` |
113
- | Call `scripts/groksearch_cli.py` directly | Call `python scripts/groksearch_entry.py ...` |
114
- | Use built-in WebSearch/WebFetch | Use GrokSearch CLI |
40
+ - Connection or auth failure: run `get_config_info` and verify `GROK_API_URL` and `GROK_API_KEY`.
41
+ - `web_search` needs broader coverage: add `--extra-sources N`; if Tavily is unavailable, keep Grok results and note the warning.
42
+ - `web_fetch` fails on Tavily extract: retry with `--fallback-grok`.
43
+ - Hash-route/docsify pages may require the materialized markdown URL hinted by the CLI error.
@@ -0,0 +1,28 @@
1
+ """Shared .env loader for Grok Search scripts."""
2
+
3
+ import os
4
+ from pathlib import Path
5
+
6
+
7
+ def load_dotenv() -> bool:
8
+ env_path = Path(__file__).resolve().parent.parent / ".env"
9
+ if not env_path.exists():
10
+ return False
11
+ try:
12
+ with open(env_path, "r", encoding="utf-8") as f:
13
+ for line in f:
14
+ line = line.strip()
15
+ if not line or line.startswith("#") or "=" not in line:
16
+ continue
17
+ key, _, value = line.partition("=")
18
+ key = key.strip()
19
+ value = value.strip()
20
+ if (value.startswith('"') and value.endswith('"')) or (
21
+ value.startswith("'") and value.endswith("'")
22
+ ):
23
+ value = value[1:-1]
24
+ if key and not os.environ.get(key):
25
+ os.environ[key] = value
26
+ return True
27
+ except IOError:
28
+ return False
@@ -46,8 +46,8 @@ def load_dotenv() -> bool:
46
46
  if (value.startswith('"') and value.endswith('"')) or \
47
47
  (value.startswith("'") and value.endswith("'")):
48
48
  value = value[1:-1]
49
- # 仅在环境变量中未设置时才设置
50
- if key and key not in os.environ:
49
+ # 允许 .env 覆盖空字符串环境变量
50
+ if key and not os.environ.get(key):
51
51
  os.environ[key] = value
52
52
  return True
53
53
  except IOError:
@@ -8,23 +8,35 @@ import sys
8
8
  from pathlib import Path
9
9
  from typing import Optional
10
10
 
11
+ from _dotenv import load_dotenv
12
+
11
13
 
12
14
  ROOT_DIR = Path(__file__).resolve().parent.parent
13
- VENV_DIR = Path(os.environ.get("GROKSEARCH_VENV_DIR", str(ROOT_DIR / ".venv")))
14
15
  REQ_FILE = ROOT_DIR / "requirements.txt"
15
16
  CLI_PY = ROOT_DIR / "scripts" / "groksearch_cli.py"
16
17
 
17
18
 
19
+ def venv_dir() -> Path:
20
+ configured = os.environ.get("GROKSEARCH_VENV_DIR")
21
+ if not configured:
22
+ return ROOT_DIR / ".venv"
23
+ dir_path = Path(configured).expanduser()
24
+ if dir_path.is_absolute():
25
+ return dir_path
26
+ return ROOT_DIR / dir_path
27
+
28
+
18
29
  def venv_python() -> Optional[Path]:
30
+ dir_path = venv_dir()
19
31
  candidates = []
20
32
  if sys.platform == "win32":
21
33
  candidates.extend(
22
34
  [
23
- VENV_DIR / "Scripts" / "python.exe",
24
- VENV_DIR / "Scripts" / "python",
35
+ dir_path / "Scripts" / "python.exe",
36
+ dir_path / "Scripts" / "python",
25
37
  ]
26
38
  )
27
- candidates.append(VENV_DIR / "bin" / "python")
39
+ candidates.append(dir_path / "bin" / "python")
28
40
  for candidate in candidates:
29
41
  if candidate.is_file():
30
42
  return candidate
@@ -57,19 +69,20 @@ def find_system_python() -> Optional[str]:
57
69
 
58
70
 
59
71
  def create_venv() -> None:
72
+ dir_path = venv_dir()
60
73
  if has_uv():
61
74
  command = ["uv", "venv"]
62
75
  spec = python_spec()
63
76
  if spec:
64
77
  command.extend(["--python", spec])
65
- command.append(str(VENV_DIR))
78
+ command.append(str(dir_path))
66
79
  subprocess.run(command, check=True)
67
80
  return
68
81
  python_bin = find_system_python()
69
82
  if not python_bin:
70
83
  print("Error: No usable uv or python found. Cannot create virtual environment.", file=sys.stderr)
71
84
  sys.exit(1)
72
- subprocess.run([python_bin, "-m", "venv", str(VENV_DIR)], check=True)
85
+ subprocess.run([python_bin, "-m", "venv", str(dir_path)], check=True)
73
86
 
74
87
 
75
88
  def install_deps(python_bin: Path) -> None:
@@ -90,15 +103,17 @@ def install_deps(python_bin: Path) -> None:
90
103
 
91
104
 
92
105
  def validate_venv_dir() -> None:
93
- if VENV_DIR.exists() and not VENV_DIR.is_dir():
94
- print(f"Error: {VENV_DIR} exists but is not a directory.", file=sys.stderr)
106
+ dir_path = venv_dir()
107
+ if dir_path.exists() and not dir_path.is_dir():
108
+ print(f"Error: {dir_path} exists but is not a directory.", file=sys.stderr)
95
109
  sys.exit(1)
96
- if VENV_DIR.is_dir() and not (VENV_DIR / "pyvenv.cfg").exists() and venv_python() is None:
97
- print(f"Error: {VENV_DIR} exists but is not a valid venv.", file=sys.stderr)
110
+ if dir_path.is_dir() and not (dir_path / "pyvenv.cfg").exists() and venv_python() is None:
111
+ print(f"Error: {dir_path} exists but is not a valid venv.", file=sys.stderr)
98
112
  sys.exit(1)
99
113
 
100
114
 
101
115
  def main() -> None:
116
+ load_dotenv()
102
117
  validate_venv_dir()
103
118
  python_bin = venv_python()
104
119
  if python_bin is None:
@@ -0,0 +1,14 @@
1
+ # Prompt Enhancer CLI configuration
2
+ # Copy this file to .env and fill in the values you want to use.
3
+
4
+ # Optional: Anthropic API key (preferred when set)
5
+ ANTHROPIC_API_KEY=
6
+
7
+ # Optional: OpenAI API key (fallback when Anthropic key is absent)
8
+ OPENAI_API_KEY=
9
+
10
+ # Optional: model override
11
+ # Examples:
12
+ # claude-sonnet-4-20250514
13
+ # gpt-4o
14
+ PE_MODEL=
@@ -2,16 +2,18 @@
2
2
 
3
3
  ## Using the Python Script Directly
4
4
 
5
- The `scripts/enhance.py` script can be used standalone:
5
+ Use the bootstrap entrypoint from the installed skill directory:
6
6
 
7
7
  ```bash
8
8
  # Basic usage
9
- python3 scripts/enhance.py "your prompt here"
9
+ python "<SKILL_DIR>/scripts/prompt_enhancer_entry.py" "your prompt here"
10
10
 
11
- # With custom model (if API key is set)
12
- ANTHROPIC_API_KEY=sk-ant-... python3 scripts/enhance.py "your prompt"
11
+ # With custom model
12
+ PE_MODEL=claude-sonnet-4-20250514 python "<SKILL_DIR>/scripts/prompt_enhancer_entry.py" "your prompt"
13
13
  ```
14
14
 
15
+ `prompt_enhancer_entry.py` is the canonical entrypoint. It creates or reuses a skill-local virtual environment and then runs `scripts/enhance.py`.
16
+
15
17
  ## Environment Variables
16
18
 
17
19
  | Variable | Description | Default |
@@ -19,27 +21,42 @@ ANTHROPIC_API_KEY=sk-ant-... python3 scripts/enhance.py "your prompt"
19
21
  | `ANTHROPIC_API_KEY` | Anthropic API key for Claude | - |
20
22
  | `OPENAI_API_KEY` | OpenAI API key (fallback) | - |
21
23
  | `PE_MODEL` | Model to use | `claude-sonnet-4-20250514` |
24
+ | `PE_DEBUG` | Print bootstrap and fallback diagnostics to `stderr` | `0` |
25
+ | `PROMPT_ENHANCER_VENV_DIR` | Override the skill-local venv path | `skills/prompt-enhancer/.venv` |
26
+ | `PROMPT_ENHANCER_PYTHON` | Python version/spec for `uv venv --python` | - |
27
+ | `AGENTS_SKILLS_PYTHON` | Absolute path to fallback/bootstrap Python | - |
28
+
29
+ ## Local `.env`
30
+
31
+ The CLI loads `<SKILL_DIR>/.env` automatically if present:
32
+
33
+ ```bash
34
+ cp "<SKILL_DIR>/.env.example" "<SKILL_DIR>/.env"
35
+ python "<SKILL_DIR>/scripts/prompt_enhancer_entry.py" "your prompt here"
36
+ ```
22
37
 
23
38
  ## Integration with Other Tools
24
39
 
40
+ The enhanced prompt is written to `stdout`. Usage or debug diagnostics stay on `stderr`, and bootstrap/fallback diagnostics are only emitted when `PE_DEBUG=1`.
41
+
25
42
  ### Piping Output
26
43
 
27
44
  ```bash
28
45
  # Pipe to clipboard (macOS)
29
- python3 scripts/enhance.py "my prompt" | pbcopy
46
+ python "<SKILL_DIR>/scripts/prompt_enhancer_entry.py" "my prompt" | pbcopy
30
47
 
31
48
  # Pipe to file
32
- python3 scripts/enhance.py "my prompt" > enhanced.md
49
+ python "<SKILL_DIR>/scripts/prompt_enhancer_entry.py" "my prompt" > enhanced.md
33
50
 
34
51
  # Chain with other commands
35
- python3 scripts/enhance.py "my prompt" | claude -p
52
+ python "<SKILL_DIR>/scripts/prompt_enhancer_entry.py" "my prompt" | claude -p
36
53
  ```
37
54
 
38
55
  ### In Shell Scripts
39
56
 
40
57
  ```bash
41
58
  #!/bin/bash
42
- ENHANCED=$(python3 ~/.agents/skills/prompt-enhancer/scripts/enhance.py "$1")
59
+ ENHANCED=$(python "$HOME/.agents/skills/prompt-enhancer/scripts/prompt_enhancer_entry.py" "$1")
43
60
  echo "$ENHANCED"
44
61
  ```
45
62
 
@@ -49,7 +66,9 @@ If no API key is available, you can manually apply the enhancement principles:
49
66
 
50
67
  1. Read the user's prompt
51
68
  2. Apply the template from [TEMPLATE.md](TEMPLATE.md)
52
- 3. Structure the output with:
69
+ 3. Preserve every explicit user constraint
70
+ 4. Use placeholders for unknown context instead of inventing requirements
71
+ 5. Structure the output with:
53
72
  - Context section
54
73
  - Objective section
55
74
  - Step-by-step instructions
@@ -58,17 +77,25 @@ If no API key is available, you can manually apply the enhancement principles:
58
77
  ## Troubleshooting
59
78
 
60
79
  ### Script Not Found
61
- Ensure the skill is installed in the correct location:
80
+ Verify the canonical entrypoint exists:
62
81
  ```bash
63
- ls ~/.agents/skills/prompt-enhancer/scripts/enhance.py
82
+ ls "$HOME/.agents/skills/prompt-enhancer/scripts/prompt_enhancer_entry.py"
64
83
  ```
65
84
 
66
85
  ### Permission Denied
67
- Make the script executable:
86
+ Run it through Python instead of executing the file directly:
87
+ ```bash
88
+ python "$HOME/.agents/skills/prompt-enhancer/scripts/prompt_enhancer_entry.py" "your prompt here"
89
+ ```
90
+
91
+ ### Show Usage
92
+ Run the entrypoint without a prompt to print usage information:
68
93
  ```bash
69
- chmod +x ~/.agents/skills/prompt-enhancer/scripts/enhance.py
94
+ python "$HOME/.agents/skills/prompt-enhancer/scripts/prompt_enhancer_entry.py"
70
95
  ```
71
96
 
72
97
  ### No API Key
73
98
  The script will fall back to a local template-based enhancement if no API key is found.
74
99
 
100
+ ### Debug Fallbacks
101
+ Set `PE_DEBUG=1` to show dependency-install, provider, or fallback diagnostics on `stderr`.
@@ -1,71 +1,45 @@
1
1
  ---
2
2
  name: prompt-enhancer
3
- description: Enhance and refine prompts for AI coding agents using Chain-of-Thought reasoning. Use when user asks to improve, optimize, rewrite, or enhance a prompt. Transforms vague requests into structured, high-context instructions for Claude Code, Codex, or Gemini CLI.
4
- allowed-tools: Bash(python3:*), Bash(pe:*), Read, Grep
3
+ description: |
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
5
6
  ---
6
7
 
7
- # Prompt Enhancer Skill
8
+ # Prompt Enhancer
8
9
 
9
- Transforms vague or simple prompts into structured, high-context instructions optimized for AI coding agents.
10
+ Rewrite raw prompts into concise, structured prompts for coding agents.
10
11
 
11
- ## When to Use
12
+ ## Use When
12
13
 
13
- - User asks to "improve my prompt" or "make this prompt better"
14
- - User wants to "optimize this instruction for Claude/Codex"
15
- - User needs help writing a better prompt for an AI agent
16
- - User mentions "prompt engineering" or "rewrite this"
14
+ - The input itself is a prompt or instruction for an AI agent.
15
+ - The user explicitly asks to improve, optimize, or rewrite that prompt.
16
+ - The target is a coding agent such as Codex, Claude Code, or Gemini CLI.
17
17
 
18
- ## Quick Start
18
+ Do not use this for general writing edits like email, docs, or PR copy.
19
19
 
20
- Run the enhance script with the user's prompt:
20
+ ## Do
21
21
 
22
22
  ```bash
23
- python3 ~/.agents/skills/prompt-enhancer/scripts/enhance.py "user's raw prompt here"
23
+ python "<SKILL_DIR>/scripts/prompt_enhancer_entry.py" "user's raw prompt here"
24
24
  ```
25
25
 
26
- ## How It Works
26
+ - Do not call `scripts/enhance.py` directly.
27
+ - Use the installed skill directory for `<SKILL_DIR>`.
28
+ - Optional setup: `cp "<SKILL_DIR>/.env.example" "<SKILL_DIR>/.env"`
27
29
 
28
- The enhancer applies these principles:
30
+ ## Output
29
31
 
30
- 1. **Add Context**: What project/tech stack is involved?
31
- 2. **Clarify Objective**: What exactly should be accomplished?
32
- 3. **Chain of Thought**: Add step-by-step reasoning instructions
33
- 4. **Define Constraints**: What are the boundaries and requirements?
34
- 5. **Specify Output**: What format should the result be in?
32
+ - Read the enhanced prompt from `stdout`.
33
+ - Keep `stderr` for usage or optional debug output only.
34
+ - Preserve the user's intent and explicit constraints.
35
+ - Add structure and missing execution context only when it helps the agent act.
36
+ - When falling back to the local template, use placeholders for unknown context instead of inventing new requirements.
35
37
 
36
- ## Output Format
37
-
38
- The enhanced prompt follows this structure:
39
-
40
- ```markdown
41
- # Context
42
- [Refined context description]
43
-
44
- # Objective
45
- [Precise task definition]
46
-
47
- # Step-by-Step Instructions
48
- 1. [Step 1]
49
- 2. [Step 2]
50
- ...
51
-
52
- # Constraints
53
- - [Constraint 1]
54
- - [Constraint 2]
55
- ```
56
-
57
- ## Additional Resources
58
-
59
- - For advanced usage patterns, see [ADVANCED.md](ADVANCED.md)
60
- - For the system prompt template, see [TEMPLATE.md](TEMPLATE.md)
61
-
62
- ## Alternative: Use `pe` CLI
63
-
64
- If you have the `pe` CLI installed globally:
65
-
66
- ```bash
67
- pe "user's raw prompt here"
68
- ```
69
-
70
- Install via: `npm install -g prompt-enhancer` (or clone repo and `npm link`)
38
+ ## Notes
71
39
 
40
+ - Local config file: `<SKILL_DIR>/.env`
41
+ - The entrypoint auto-loads `<SKILL_DIR>/.env` before bootstrap and dependency install.
42
+ - Optional debug flag: `PE_DEBUG=1`
43
+ - Bootstrap controls: `PROMPT_ENHANCER_VENV_DIR`, `PROMPT_ENHANCER_PYTHON`, `AGENTS_SKILLS_PYTHON`
44
+ - Setup and troubleshooting: [ADVANCED.md](ADVANCED.md)
45
+ - Prompt template reference: [TEMPLATE.md](TEMPLATE.md)
@@ -0,0 +1,2 @@
1
+ anthropic>=0.34,<1
2
+ openai>=1.30,<2
@@ -0,0 +1,28 @@
1
+ """Shared .env loader for Prompt Enhancer scripts."""
2
+
3
+ import os
4
+ from pathlib import Path
5
+
6
+
7
+ def load_dotenv() -> bool:
8
+ env_path = Path(__file__).resolve().parent.parent / ".env"
9
+ if not env_path.exists():
10
+ return False
11
+ try:
12
+ with open(env_path, "r", encoding="utf-8") as f:
13
+ for line in f:
14
+ line = line.strip()
15
+ if not line or line.startswith("#") or "=" not in line:
16
+ continue
17
+ key, _, value = line.partition("=")
18
+ key = key.strip()
19
+ value = value.strip()
20
+ if (value.startswith('"') and value.endswith('"')) or (
21
+ value.startswith("'") and value.endswith("'")
22
+ ):
23
+ value = value[1:-1]
24
+ if key and not os.environ.get(key):
25
+ os.environ[key] = value
26
+ return True
27
+ except IOError:
28
+ return False