@@ -168,8 +168,8 @@ def _load_standup_config() -> dict[str, Any]:
168168 with open (path , encoding = "utf-8" ) as f :
169169 data = yaml .safe_load (f ) or {}
170170 config = dict (data .get ("standup" , data ))
171- except Exception :
172- pass
171+ except Exception as exc :
172+ debug_log_operation ( "config_load" , str ( path ), "error" , error = repr ( exc ))
173173 break
174174 if os .environ .get ("SPECFACT_STANDUP_STATE" ):
175175 config ["default_state" ] = os .environ ["SPECFACT_STANDUP_STATE" ]
@@ -203,8 +203,8 @@ def _load_backlog_config() -> dict[str, Any]:
203203 config = dict (nested ) if isinstance (nested , dict ) else {}
204204 else :
205205 config = dict (data ) if isinstance (data , dict ) else {}
206- except Exception :
207- pass
206+ except Exception as exc :
207+ debug_log_operation ( "config_load" , str ( path ), "error" , error = repr ( exc ))
208208 break
209209 return config
210210
@@ -489,19 +489,25 @@ def _build_summarize_prompt_content(
489489 filter_context : dict [str , Any ],
490490 include_value_score : bool = False ,
491491 comments_by_item_id : dict [str , list [str ]] | None = None ,
492+ include_comments : bool = False ,
492493) -> str :
493494 """
494495 Build prompt content for standup summary: instruction + filter context + per-item data.
495496
496- Includes body (description) and annotations (comments) per item so an LLM can produce
497- a meaningful summary. For use with slash command (e.g. specfact.daily) or copy-paste to Copilot.
497+ When include_comments is True, includes body (description) and annotations (comments) per item
498+ so an LLM can produce a meaningful summary. When False, only metadata (id, title, status,
499+ assignees, last updated) is included to avoid leaking sensitive or large context.
500+ For use with slash command (e.g. specfact.daily) or copy-paste to Copilot.
498501 """
499502 lines : list [str ] = []
500503 lines .append ("--- BEGIN STANDUP PROMPT ---" )
501504 lines .append ("Generate a concise daily standup summary from the following data." )
502- lines .append (
503- "Include: current focus, blockers, and pending items. Use each item's description and comments for context. Keep it short and actionable."
504- )
505+ if include_comments :
506+ lines .append (
507+ "Include: current focus, blockers, and pending items. Use each item's description and comments for context. Keep it short and actionable."
508+ )
509+ else :
510+ lines .append ("Include: current focus and pending items from the metadata below. Keep it short and actionable." )
505511 lines .append ("" )
506512 lines .append ("## Filter context" )
507513 lines .append (f"- Adapter: { filter_context .get ('adapter' , '—' )} " )
@@ -510,7 +516,8 @@ def _build_summarize_prompt_content(
510516 lines .append (f"- Assignee: { filter_context .get ('assignee' , '—' )} " )
511517 lines .append (f"- Limit: { filter_context .get ('limit' , '—' )} " )
512518 lines .append ("" )
513- lines .append ("## Standup data (with description and comments)" )
519+ data_header = "Standup data (with description and comments)" if include_comments else "Standup data (metadata only)"
520+ lines .append (f"## { data_header } " )
514521 lines .append ("" )
515522 comments_map = comments_by_item_id or {}
516523 for item in items :
@@ -523,24 +530,25 @@ def _build_summarize_prompt_content(
523530 item .updated_at .strftime ("%Y-%m-%d %H:%M" ) if hasattr (item .updated_at , "strftime" ) else str (item .updated_at )
524531 )
525532 lines .append (f"- **Last updated:** { updated } " )
526- body = (item .body_markdown or "" ).strip ()
527- if body :
528- snippet = body [:_SUMMARIZE_BODY_TRUNCATE ]
529- if len (body ) > _SUMMARIZE_BODY_TRUNCATE :
530- snippet += "\n ..."
531- lines .append ("- **Description:**" )
532- lines .append (snippet )
533- lines .append ("" )
534- yesterday , today , blockers = _parse_standup_from_body (item .body_markdown or "" )
535- if yesterday or today :
536- lines .append (f"- **Progress:** Yesterday: { yesterday or '—' } ; Today: { today or '—' } " )
537- if blockers :
538- lines .append (f"- **Blockers:** { blockers } " )
539- item_comments = comments_map .get (item .id , [])
540- if item_comments :
541- lines .append ("- **Comments (annotations):**" )
542- for c in item_comments :
543- lines .append (f" - { c } " )
533+ if include_comments :
534+ body = (item .body_markdown or "" ).strip ()
535+ if body :
536+ snippet = body [:_SUMMARIZE_BODY_TRUNCATE ]
537+ if len (body ) > _SUMMARIZE_BODY_TRUNCATE :
538+ snippet += "\n ..."
539+ lines .append ("- **Description:**" )
540+ lines .append (snippet )
541+ lines .append ("" )
542+ yesterday , today , blockers = _parse_standup_from_body (item .body_markdown or "" )
543+ if yesterday or today :
544+ lines .append (f"- **Progress:** Yesterday: { yesterday or '—' } ; Today: { today or '—' } " )
545+ if blockers :
546+ lines .append (f"- **Blockers:** { blockers } " )
547+ item_comments = comments_map .get (item .id , [])
548+ if item_comments :
549+ lines .append ("- **Comments (annotations):**" )
550+ for c in item_comments :
551+ lines .append (f" - { c } " )
544552 if item .story_points is not None :
545553 lines .append (f"- **Story points:** { item .story_points } " )
546554 if item .priority is not None :
@@ -1224,6 +1232,7 @@ def daily(
12241232 filter_context = filter_ctx ,
12251233 include_value_score = include_score ,
12261234 comments_by_item_id = comments_by_item_id or None ,
1235+ include_comments = include_comments ,
12271236 )
12281237 if summarize_to :
12291238 Path (summarize_to ).write_text (content , encoding = "utf-8" )
@@ -1309,7 +1318,7 @@ def daily(
13091318 end_date = dt .strptime (str (sprint_end )[:10 ], "%Y-%m-%d" ).date ()
13101319 console .print (f"[dim]{ _format_sprint_end_header (end_date )} [/dim]" )
13111320 except (ValueError , TypeError ):
1312- pass
1321+ console . print ( "[dim]Sprint end date could not be parsed; header skipped.[/dim]" )
13131322
13141323 def _add_standup_rows_to_table (tbl : Table , row_list : list [dict [str , Any ]], include_pri : bool ) -> None :
13151324 for r in row_list :
0 commit comments