wile 0.4.22 → 0.5.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.
@@ -96,8 +96,9 @@ fi
96
96
 
97
97
  # Authentication for selected coding agent
98
98
  if [ "$CODING_AGENT" = "OC" ]; then
99
- if [ -z "$OC_OPENROUTER_API_KEY" ]; then
100
- echo "ERROR: OC_OPENROUTER_API_KEY is required for OpenCode"
99
+ OC_PROVIDER="${OC_PROVIDER:-native}"
100
+ if [ "$OC_PROVIDER" = "openrouter" ] && [ -z "$OC_OPENROUTER_API_KEY" ]; then
101
+ echo "ERROR: OC_OPENROUTER_API_KEY is required for OpenCode with OpenRouter provider"
101
102
  exit 1
102
103
  fi
103
104
  if [ -z "$OC_MODEL" ]; then
@@ -130,10 +131,11 @@ if [ "${WILE_MOCK_CLAUDE:-}" = "true" ] && [ "$CODING_AGENT" = "CC" ]; then
130
131
  fi
131
132
 
132
133
  if [ "$CODING_AGENT" = "OC" ]; then
133
- echo " Auth: OpenRouter (OpenCode)"
134
- OPENCODE_DATA_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/opencode"
135
- mkdir -p "$OPENCODE_DATA_DIR"
136
- cat > "$OPENCODE_DATA_DIR/auth.json" << OPENCODEAUTH
134
+ if [ "$OC_PROVIDER" = "openrouter" ]; then
135
+ echo " Auth: OpenRouter (OpenCode)"
136
+ OPENCODE_DATA_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/opencode"
137
+ mkdir -p "$OPENCODE_DATA_DIR"
138
+ cat > "$OPENCODE_DATA_DIR/auth.json" << OPENCODEAUTH
137
139
  {
138
140
  "openrouter": {
139
141
  "type": "api",
@@ -141,8 +143,11 @@ if [ "$CODING_AGENT" = "OC" ]; then
141
143
  }
142
144
  }
143
145
  OPENCODEAUTH
144
- chmod 600 "$OPENCODE_DATA_DIR/auth.json"
145
- export OPENROUTER_API_KEY="$OC_OPENROUTER_API_KEY"
146
+ chmod 600 "$OPENCODE_DATA_DIR/auth.json"
147
+ export OPENROUTER_API_KEY="$OC_OPENROUTER_API_KEY"
148
+ else
149
+ echo " Auth: Native (free models)"
150
+ fi
146
151
  else
147
152
  # Set up Claude Code authentication
148
153
  if [ -n "$CC_CLAUDE_CODE_OAUTH_TOKEN" ]; then
@@ -44,6 +44,6 @@ if [ "$COUNT" -eq 0 ]; then
44
44
  JSON
45
45
  else
46
46
  cat <<'JSON'
47
- {"type":"assistant","message":{"content":[{"type":"text","text":"<promise>COMPLETE</promise>\n"}]}}
47
+ {"type":"assistant","message":{"content":[{"type":"text","text":"<promise>ALL_STORIES_COMPLETED</promise>\n"}]}}
48
48
  JSON
49
49
  fi
@@ -88,7 +88,7 @@ After completing steps 1-8, check if ALL stories in `.wile/prd.json` have `passe
88
88
 
89
89
  **If ALL stories pass**, respond with exactly:
90
90
  ```
91
- <promise>COMPLETE</promise>
91
+ <promise>ALL_STORIES_COMPLETED</promise>
92
92
  ```
93
93
  The entire response must be exactly that single line. No other text before or after. No extra lines. No markdown. No backticks. No code blocks.
94
94
 
@@ -47,7 +47,7 @@ EOF
47
47
  cat > "$BIN_DIR/claude" <<'EOF'
48
48
  #!/bin/sh
49
49
  cat > "$CLAUDE_CAPTURE"
50
- printf '%s\n' '{"type":"assistant","message":{"content":[{"type":"text","text":"<promise>COMPLETE</promise>\n"}]}}'
50
+ printf '%s\n' '{"type":"assistant","message":{"content":[{"type":"text","text":"<promise>ALL_STORIES_COMPLETED</promise>\n"}]}}'
51
51
  EOF
52
52
  chmod +x "$BIN_DIR/claude"
53
53
 
@@ -7,8 +7,11 @@ set -e
7
7
 
8
8
  CODING_AGENT=${CODING_AGENT:-CC}
9
9
  CLAUDE_MODEL=${CC_CLAUDE_MODEL:-sonnet}
10
- OC_MODEL=${OC_MODEL:-glm-4.7}
11
- if [[ "$OC_MODEL" != */* ]]; then
10
+ OC_PROVIDER=${OC_PROVIDER:-native}
11
+ OC_MODEL=${OC_MODEL:-opencode/grok-code}
12
+
13
+ # For openrouter provider, prepend vendor prefix if missing
14
+ if [ "$OC_PROVIDER" = "openrouter" ] && [[ "$OC_MODEL" != */* ]]; then
12
15
  OC_MODEL="z-ai/$OC_MODEL"
13
16
  fi
14
17
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@@ -23,6 +26,7 @@ echo " 🌵 WILE - Preflight"
23
26
  echo "══════════════════════════════════════════════════════"
24
27
  echo " Agent: $CODING_AGENT"
25
28
  if [ "$CODING_AGENT" = "OC" ]; then
29
+ echo " Provider: $OC_PROVIDER"
26
30
  echo " Model: $OC_MODEL"
27
31
  else
28
32
  echo " Model: $CLAUDE_MODEL"
@@ -45,8 +49,12 @@ run_claude() {
45
49
 
46
50
  run_opencode() {
47
51
  local prompt_path="$1"
52
+ local model_arg="$OC_MODEL"
53
+ if [ "$OC_PROVIDER" = "openrouter" ]; then
54
+ model_arg="openrouter/$OC_MODEL"
55
+ fi
48
56
  cat "$prompt_path" \
49
- | opencode run --format json --model "openrouter/$OC_MODEL" \
57
+ | opencode run --format json --model "$model_arg" \
50
58
  | node "$SCRIPT_DIR/opencode-stream.js"
51
59
  }
52
60
 
@@ -9,14 +9,16 @@ set -e
9
9
  MAX_ITERATIONS=${1:-25}
10
10
  CODING_AGENT=${CODING_AGENT:-CC}
11
11
  CLAUDE_MODEL=${CC_CLAUDE_MODEL:-sonnet}
12
- OC_MODEL=${OC_MODEL:-glm-4.7}
13
- if [[ "$OC_MODEL" != */* ]]; then
12
+ OC_PROVIDER=${OC_PROVIDER:-native}
13
+ OC_MODEL=${OC_MODEL:-opencode/grok-code}
14
+
15
+ # For openrouter provider, prepend vendor prefix if missing
16
+ if [ "$OC_PROVIDER" = "openrouter" ] && [[ "$OC_MODEL" != */* ]]; then
14
17
  OC_MODEL="z-ai/$OC_MODEL"
15
18
  fi
16
19
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
17
20
  PROMPT_FILE="$SCRIPT_DIR/prompt.md"
18
21
  PREFLIGHT_PROMPT_FILE="$SCRIPT_DIR/prompt-preflight.md"
19
- SETUP_PROMPT_FILE="$SCRIPT_DIR/prompt-setup.md"
20
22
  ADDITIONAL_PROMPT_FILE="${WILE_ADDITIONAL_INSTRUCTIONS:-}"
21
23
  TEE_TARGET="${WILE_TEE_TARGET:-/dev/stderr}"
22
24
  if ! ( : > "$TEE_TARGET" ) 2>/dev/null; then
@@ -29,6 +31,7 @@ echo "════════════════════════
29
31
  echo " Agent: $CODING_AGENT"
30
32
  echo " Max iterations: $MAX_ITERATIONS"
31
33
  if [ "$CODING_AGENT" = "OC" ]; then
34
+ echo " Provider: $OC_PROVIDER"
32
35
  echo " Model: $OC_MODEL"
33
36
  else
34
37
  echo " Model: $CLAUDE_MODEL"
@@ -63,8 +66,12 @@ run_claude() {
63
66
 
64
67
  run_opencode() {
65
68
  local prompt_path="$1"
69
+ local model_arg="$OC_MODEL"
70
+ if [ "$OC_PROVIDER" = "openrouter" ]; then
71
+ model_arg="openrouter/$OC_MODEL"
72
+ fi
66
73
  cat "$prompt_path" \
67
- | opencode run --format json --model "openrouter/$OC_MODEL" \
74
+ | opencode run --format json --model "$model_arg" \
68
75
  | node "$SCRIPT_DIR/opencode-stream.js"
69
76
  }
70
77
 
@@ -108,21 +115,6 @@ if [ -f "$PREFLIGHT_PROMPT_FILE" ]; then
108
115
  echo ""
109
116
  echo "Preflight complete. Starting main loop..."
110
117
  sleep 2
111
- elif [ -f "$SETUP_PROMPT_FILE" ]; then
112
- OUTPUT=$(run_agent "$SETUP_PROMPT_FILE" | tee "$TEE_TARGET") || true
113
-
114
- # Check if setup failed critically
115
- if echo "$OUTPUT" | grep -q "<promise>SETUP_FAILED</promise>"; then
116
- echo ""
117
- echo "══════════════════════════════════════════════════════"
118
- echo " ❌ SETUP FAILED - Cannot continue"
119
- echo "══════════════════════════════════════════════════════"
120
- exit 2
121
- fi
122
-
123
- echo ""
124
- echo "Setup complete. Starting main loop..."
125
- sleep 2
126
118
  else
127
119
  echo "No setup prompt found, skipping iteration 0..."
128
120
  fi
@@ -144,10 +136,10 @@ for i in $(seq 1 $MAX_ITERATIONS); do
144
136
 
145
137
  # Check for completion signal (tag must be on its own line; reject backticks/code fences)
146
138
  CLEAN_OUTPUT=$(printf '%s' "$OUTPUT" | tr -d '\r' | sed -e 's/[[:space:]]*$//')
147
- if printf '%s\n' "$CLEAN_OUTPUT" | grep -q -E '^[[:space:]]*<promise>COMPLETE</promise>[[:space:]]*$'; then
139
+ if printf '%s\n' "$CLEAN_OUTPUT" | grep -q -E '^[[:space:]]*<promise>ALL_STORIES_COMPLETED</promise>[[:space:]]*$'; then
148
140
  if printf '%s' "$CLEAN_OUTPUT" | grep -F '```' >/dev/null 2>&1; then
149
141
  :
150
- elif printf '%s' "$CLEAN_OUTPUT" | grep -F '`<promise>COMPLETE</promise>`' >/dev/null 2>&1; then
142
+ elif printf '%s' "$CLEAN_OUTPUT" | grep -F '`<promise>ALL_STORIES_COMPLETED</promise>`' >/dev/null 2>&1; then
151
143
  :
152
144
  else
153
145
  echo ""
package/dist/cli.js CHANGED
@@ -7544,9 +7544,15 @@ var prdExample = {
7544
7544
  var tips = {
7545
7545
  oauth: "Tip: run 'claude setup-token' on your machine to generate an OAuth token (uses Pro/Max subscription).",
7546
7546
  apiKey: "Tip: create an Anthropic API key in the console (uses API credits).",
7547
- openrouter: "Tip: create an OpenRouter API key for OpenCode (used for z-ai/glm-4.7).",
7547
+ openrouter: "Tip: create an OpenRouter API key at https://openrouter.ai/keys (pay per token).",
7548
7548
  github: "Tip: use a GitHub Personal Access Token (fine-grained recommended). Create at https://github.com/settings/tokens?type=beta with Contents (read/write) and Metadata (read)."
7549
7549
  };
7550
+ var nativeOcModels = [
7551
+ { title: "Grok Code Fast 1 (recommended)", value: "opencode/grok-code" },
7552
+ { title: "Big Pickle", value: "opencode/big-pickle" },
7553
+ { title: "GLM-4.7", value: "opencode/glm-4.7-free" },
7554
+ { title: "MiniMax M2.1", value: "opencode/minimax-m2.1-free" }
7555
+ ];
7550
7556
  var readEnvFile = async (path) => {
7551
7557
  if (!existsSync(path)) {
7552
7558
  return {};
@@ -7640,8 +7646,10 @@ var runConfig = async () => {
7640
7646
  let authMethod = null;
7641
7647
  let authValueResponse = {};
7642
7648
  let defaultModelResponse = {};
7649
+ let ocProviderResponse = {};
7643
7650
  let ocKeyResponse = {};
7644
7651
  let ocModelResponse = {};
7652
+ let ocNativeModelResponse = {};
7645
7653
  if (codingAgent === "CC") {
7646
7654
  const authDefault = existingEnv.CC_CLAUDE_CODE_OAUTH_TOKEN ? "oauth" : existingEnv.CC_ANTHROPIC_API_KEY ? "apiKey" : "oauth";
7647
7655
  const authResponse = await prompt({
@@ -7676,22 +7684,45 @@ var runConfig = async () => {
7676
7684
  initial: existingEnv.CC_CLAUDE_MODEL === "opus" ? 1 : existingEnv.CC_CLAUDE_MODEL === "haiku" ? 2 : 0
7677
7685
  });
7678
7686
  } else {
7679
- console.log("");
7680
- console.log(tips.openrouter);
7681
- console.log("");
7682
- ocKeyResponse = await prompt({
7683
- type: "password",
7684
- name: "ocKey",
7685
- message: "OpenRouter API key (press enter to keep existing)",
7686
- initial: existingEnv.OC_OPENROUTER_API_KEY ?? ""
7687
- });
7688
- ocModelResponse = await prompt({
7687
+ const providerDefault = existingEnv.OC_PROVIDER === "openrouter" ? "openrouter" : "native";
7688
+ ocProviderResponse = await prompt({
7689
7689
  type: "select",
7690
- name: "ocModel",
7691
- message: "OpenCode model (OpenRouter)",
7692
- choices: [{ title: "glm-4.7", value: "glm-4.7" }],
7693
- initial: existingEnv.OC_MODEL === "glm-4.7" ? 0 : 0
7690
+ name: "ocProvider",
7691
+ message: "OpenCode provider",
7692
+ choices: [
7693
+ { title: "Native free models (no API key)", value: "native" },
7694
+ { title: "OpenRouter (pay per token)", value: "openrouter" }
7695
+ ],
7696
+ initial: providerDefault === "openrouter" ? 1 : 0
7694
7697
  });
7698
+ const ocProvider2 = ocProviderResponse.ocProvider;
7699
+ if (ocProvider2 === "openrouter") {
7700
+ console.log("");
7701
+ console.log(tips.openrouter);
7702
+ console.log("");
7703
+ ocKeyResponse = await prompt({
7704
+ type: "password",
7705
+ name: "ocKey",
7706
+ message: "OpenRouter API key (press enter to keep existing)",
7707
+ initial: existingEnv.OC_OPENROUTER_API_KEY ?? ""
7708
+ });
7709
+ ocModelResponse = await prompt({
7710
+ type: "select",
7711
+ name: "ocModel",
7712
+ message: "OpenCode model (OpenRouter)",
7713
+ choices: [{ title: "glm-4.7", value: "glm-4.7" }],
7714
+ initial: 0
7715
+ });
7716
+ } else {
7717
+ const existingNativeIdx = nativeOcModels.findIndex((m) => m.value === existingEnv.OC_MODEL);
7718
+ ocNativeModelResponse = await prompt({
7719
+ type: "select",
7720
+ name: "ocNativeModel",
7721
+ message: "OpenCode model (free)",
7722
+ choices: nativeOcModels,
7723
+ initial: existingNativeIdx >= 0 ? existingNativeIdx : 0
7724
+ });
7725
+ }
7695
7726
  }
7696
7727
  const repoSourceResponse = await prompt({
7697
7728
  type: "select",
@@ -7743,8 +7774,9 @@ var runConfig = async () => {
7743
7774
  const maxIterations = Number.isFinite(iterationsResponse.maxIterations) && iterationsResponse.maxIterations > 0 ? iterationsResponse.maxIterations : fallbackIterations;
7744
7775
  const authFallback = authMethod === "oauth" ? existingEnv.CC_CLAUDE_CODE_OAUTH_TOKEN : existingEnv.CC_ANTHROPIC_API_KEY;
7745
7776
  const authValue = codingAgent === "CC" ? coalesceValue(authValueResponse.authValue, authFallback) : undefined;
7746
- const ocKey = codingAgent === "OC" ? coalesceValue(ocKeyResponse.ocKey, existingEnv.OC_OPENROUTER_API_KEY) : undefined;
7747
- const ocModel = codingAgent === "OC" ? coalesceValue(ocModelResponse.ocModel, existingEnv.OC_MODEL ?? "glm-4.7") : undefined;
7777
+ const ocProvider = codingAgent === "OC" ? ocProviderResponse.ocProvider ?? "native" : undefined;
7778
+ const ocKey = codingAgent === "OC" && ocProvider === "openrouter" ? coalesceValue(ocKeyResponse.ocKey, existingEnv.OC_OPENROUTER_API_KEY) : undefined;
7779
+ const ocModel = codingAgent === "OC" ? ocProvider === "openrouter" ? coalesceValue(ocModelResponse.ocModel, existingEnv.OC_MODEL ?? "glm-4.7") : coalesceValue(ocNativeModelResponse.ocNativeModel, existingEnv.OC_MODEL ?? "opencode/grok-code") : undefined;
7748
7780
  const githubToken = repoSource === "github" ? coalesceValue(githubTokenResponse.githubToken, existingEnv.GITHUB_TOKEN) : existingEnv.GITHUB_TOKEN;
7749
7781
  const repoUrl = repoSource === "github" ? coalesceValue(repoResponse.repoUrl, existingEnv.GITHUB_REPO_URL) : existingEnv.GITHUB_REPO_URL;
7750
7782
  const envProjectPathValue = coalesceValue(envProjectPathResponse.envProjectPath, existingEnv.WILE_ENV_PROJECT_PATH ?? ".wile/.env.project") ?? ".wile/.env.project";
@@ -7766,8 +7798,11 @@ var runConfig = async () => {
7766
7798
  envLines.push(`CC_ANTHROPIC_API_KEY=${authValue ?? ""}`);
7767
7799
  }
7768
7800
  } else {
7769
- envLines.push(`OC_MODEL=${ocModel ?? "glm-4.7"}`);
7770
- envLines.push(`OC_OPENROUTER_API_KEY=${ocKey ?? ""}`);
7801
+ envLines.push(`OC_PROVIDER=${ocProvider ?? "native"}`);
7802
+ envLines.push(`OC_MODEL=${ocModel ?? "opencode/grok-code"}`);
7803
+ if (ocProvider === "openrouter") {
7804
+ envLines.push(`OC_OPENROUTER_API_KEY=${ocKey ?? ""}`);
7805
+ }
7771
7806
  }
7772
7807
  await writeFile(envPath, envLines.join(`
7773
7808
  `) + `
@@ -7818,7 +7853,6 @@ Use bullet points for preflight checks, e.g.
7818
7853
  '- Avoid vague terms like "should" or "nice".',
7819
7854
  "- Keep stories small enough to finish in one iteration.",
7820
7855
  "- Mark `passes: false` for work not done yet.",
7821
- "- Place the STOP HERE note only on the last story that requires human approval.",
7822
7856
  "- Prefer concrete files/commands only when they reflect the real outcome.",
7823
7857
  "",
7824
7858
  "Environment notes:",
@@ -7909,7 +7943,10 @@ var readWileConfig = (options = {}) => {
7909
7943
  ensureRequired(Boolean(env.CC_CLAUDE_CODE_OAUTH_TOKEN || env.CC_ANTHROPIC_API_KEY), "Either CC_CLAUDE_CODE_OAUTH_TOKEN or CC_ANTHROPIC_API_KEY is required in .wile/secrets/.env.");
7910
7944
  }
7911
7945
  if (env.CODING_AGENT === "OC") {
7912
- ensureRequired(Boolean(env.OC_OPENROUTER_API_KEY), "OC_OPENROUTER_API_KEY is required in .wile/secrets/.env for OpenCode.");
7946
+ const ocProvider = env.OC_PROVIDER || "native";
7947
+ if (ocProvider === "openrouter") {
7948
+ ensureRequired(Boolean(env.OC_OPENROUTER_API_KEY), "OC_OPENROUTER_API_KEY is required in .wile/secrets/.env for OpenCode with OpenRouter provider.");
7949
+ }
7913
7950
  ensureRequired(Boolean(env.OC_MODEL), "OC_MODEL is required in .wile/secrets/.env for OpenCode.");
7914
7951
  }
7915
7952
  }
@@ -7928,6 +7965,7 @@ var readWileConfig = (options = {}) => {
7928
7965
  maxIterations: env.WILE_MAX_ITERATIONS,
7929
7966
  ccClaudeCodeOauthToken: env.CC_CLAUDE_CODE_OAUTH_TOKEN,
7930
7967
  ccAnthropicApiKey: env.CC_ANTHROPIC_API_KEY,
7968
+ ocProvider: env.OC_PROVIDER ?? "native",
7931
7969
  ocOpenrouterApiKey: env.OC_OPENROUTER_API_KEY,
7932
7970
  ocModel: env.OC_MODEL,
7933
7971
  envProject
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wile",
3
- "version": "0.4.22",
3
+ "version": "0.5.0",
4
4
  "description": "Autonomous AI coding agent that ships features while you sleep",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,23 +0,0 @@
1
- # Wile Setup (Iteration 0)
2
-
3
- You are running the setup phase for a Wile autonomous coding session.
4
-
5
- ## Tasks
6
-
7
- 1. Verify `.wile/prd.json` exists and is valid JSON:
8
-
9
- ```bash
10
- cat .wile/prd.json
11
- ```
12
-
13
- If the file is missing or invalid JSON, respond with:
14
- ```
15
- <promise>SETUP_FAILED</promise>
16
- ```
17
-
18
- Otherwise, **do nothing else**. Do not modify files, do not run git commands, and do not print extra output.
19
-
20
- ## Notes
21
-
22
- - Setup should have no side effects.
23
- - Only emit `<promise>SETUP_FAILED</promise>` on failure.