fix: resolve argument-too-long error and pass press context to all fallback paths (#134)

The copilot CLI command failed with 'Argument list too long' because the full prompt (with 117 correlations + 280 unpublicized items) was passed via shell command substitution. This caused the analysis to fall through to the no-AI path which hardcoded 'no press data available'. Changes: - Use --attachment flag instead of -p $(cat ...) for Copilot CLI - Add --press-context arg to analyze_fallback.py for GitHub Models path - Pass press context to no-AI summary so it includes correlation data - All 482 existing tests pass Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Juan Manuel Servera committed May 19, 2026 at 20:42 UTC f9ad13e36bbc3e24b2c70284c6dd2f3b299e6248
2 files changed +37 -5
.github/workflows/crawl-and-publish.yml
+6 -2
@@ -299,7 +299,9 @@ jobs:
299 cat "$PRESS_FILE" >> "$PROMPT_FILE"
300 fi
301
302 - if command -v copilot >/dev/null 2>&1 && copilot -p "$(cat "$PROMPT_FILE")" \
302 + if command -v copilot >/dev/null 2>&1 && copilot \
303 + -p "Analyze the attached weekly GitHub data and produce a markdown summary following the instructions in the attached file." \
304 + --attachment "$PROMPT_FILE" \
305 -s \
306 --no-ask-user \
307 --model claude-sonnet-4 \
@@ -314,7 +316,8 @@ jobs:
316 elif python3 scripts/analyze_fallback.py \
317 --raw-json "$WEEK_FILE" \
318 --output "$OUTPUT_FILE" \
317 - --current-datetime "$CURRENT_DATETIME" 2>/dev/null; then
319 + --current-datetime "$CURRENT_DATETIME" \
320 + --press-context "$PRESS_FILE" 2>/dev/null; then
321 echo "Copilot CLI unavailable or failed; used GitHub Models API."
322 ANALYSIS_SOURCE="github-models"
323 ANALYSIS_MODEL="${GITHUB_MODELS_MODEL:-openai/gpt-4.1}"
@@ -324,6 +327,7 @@ jobs:
327 --raw-json "$WEEK_FILE" \
328 --output "$OUTPUT_FILE" \
329 --current-datetime "$CURRENT_DATETIME" \
330 + --press-context "$PRESS_FILE" \
331 --no-ai
332 ANALYSIS_SOURCE="no-ai"
333 ANALYSIS_MODEL="none"
scripts/analyze_fallback.py
+31 -3
@@ -50,6 +50,12 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
50 default=DEFAULT_SKILLS_DIR,
51 help="Directory containing learned skill markdown files.",
52 )
53 + parser.add_argument(
54 + "--press-context",
55 + type=Path,
56 + default=None,
57 + help="Path to rendered press context markdown (appended to prompt).",
58 + )
59 parser.add_argument(
60 "--print-prompt",
61 action="store_true",
@@ -117,6 +123,7 @@ def render_prompt(
123 analyzed_dir: Path,
124 wisdom_file: Path = DEFAULT_WISDOM_FILE,
125 skills_dir: Path = DEFAULT_SKILLS_DIR,
126 + press_context_path: Path | None = None,
127 ) -> str:
128 payload = load_json(raw_json_path)
129 current_week = payload["week"]
@@ -136,6 +143,12 @@ def render_prompt(
143 }
144 for needle, value in replacements.items():
145 prompt = prompt.replace(needle, value)
146 +
147 + # Append press context if available
148 + if press_context_path and press_context_path.exists() and press_context_path.stat().st_size > 0:
149 + press_content = press_context_path.read_text(encoding="utf-8").strip()
150 + prompt += f"\n\n---\n## Press Context\n\n{press_content}\n"
151 +
152 return prompt
153
154
@@ -245,7 +258,21 @@ def call_github_models(prompt: str) -> str:
258 raise RuntimeError("GitHub Models API request failed after retries") from last_exc
259
260
248 -def generate_no_ai_summary(raw_json_path: Path, current_datetime: str) -> str:
261 +def _render_press_section_no_ai(press_context_path: Path | None) -> str:
262 + """Render press context data for the no-AI summary."""
263 + if not press_context_path or not press_context_path.exists() or press_context_path.stat().st_size == 0:
264 + return (
265 + "No industry press data was available for this week's analysis. "
266 + "Future runs with TechCrunch integration enabled will provide "
267 + "correlation analysis between developer activity and industry coverage, "
268 + "highlighting press-driven hype versus organic growth patterns."
269 + )
270 + content = press_context_path.read_text(encoding="utf-8").strip()
271 + # Include the press context as-is (it's already formatted markdown)
272 + return content
273 +
274 +
275 +def generate_no_ai_summary(raw_json_path: Path, current_datetime: str, press_context_path: Path | None = None) -> str:
276 """Generate a valid summary from raw JSON without any AI API calls."""
277 payload = load_json(raw_json_path)
278 week = payload["week"]
@@ -332,7 +359,7 @@ The presence of established projects alongside newer entries indicates both sust
359
360 ## Industry & Press Correlation
361
335 -No industry press data was available for this week's analysis. Future runs with TechCrunch integration enabled will provide correlation analysis between developer activity and industry coverage, highlighting press-driven hype versus organic growth patterns.
362 +{_render_press_section_no_ai(press_context_path)}
363
364 ## Trend Analysis
365
@@ -367,6 +394,7 @@ def main(argv: list[str] | None = None) -> int:
394 analyzed_dir=args.analyzed_dir,
395 wisdom_file=args.wisdom_file,
396 skills_dir=args.skills_dir,
397 + press_context_path=args.press_context,
398 )
399
400 if args.print_prompt:
@@ -374,7 +402,7 @@ def main(argv: list[str] | None = None) -> int:
402 return 0
403
404 if args.no_ai:
377 - markdown = generate_no_ai_summary(args.raw_json, args.current_datetime)
405 + markdown = generate_no_ai_summary(args.raw_json, args.current_datetime, args.press_context)
406 else:
407 markdown = call_github_models(prompt)
408