aiwcli 0.10.3 → 0.11.1

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 (191) hide show
  1. package/bin/run.js +1 -1
  2. package/dist/commands/clear.js +28 -131
  3. package/dist/commands/init/index.js +3 -3
  4. package/dist/lib/gitignore-manager.d.ts +32 -0
  5. package/dist/lib/gitignore-manager.js +141 -2
  6. package/dist/templates/CLAUDE.md +8 -8
  7. package/dist/templates/_shared/.claude/commands/handoff-resume.md +64 -0
  8. package/dist/templates/_shared/.claude/commands/handoff.md +16 -10
  9. package/dist/templates/_shared/.claude/settings.json +7 -7
  10. package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +2 -0
  11. package/dist/templates/_shared/hooks-ts/archive_plan.ts +159 -0
  12. package/dist/templates/_shared/hooks-ts/context_monitor.ts +147 -0
  13. package/dist/templates/_shared/hooks-ts/file-suggestion.ts +130 -0
  14. package/dist/templates/_shared/hooks-ts/pre_compact.ts +49 -0
  15. package/dist/templates/_shared/hooks-ts/session_end.ts +107 -0
  16. package/dist/templates/_shared/hooks-ts/session_start.ts +144 -0
  17. package/dist/templates/_shared/hooks-ts/task_create_capture.ts +48 -0
  18. package/dist/templates/_shared/hooks-ts/task_update_capture.ts +74 -0
  19. package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +83 -0
  20. package/dist/templates/_shared/lib-ts/CLAUDE.md +318 -0
  21. package/dist/templates/_shared/lib-ts/base/atomic-write.ts +12 -12
  22. package/dist/templates/_shared/lib-ts/base/constants.ts +22 -15
  23. package/dist/templates/_shared/lib-ts/base/git-state.ts +1 -1
  24. package/dist/templates/_shared/lib-ts/base/hook-utils.ts +129 -50
  25. package/dist/templates/_shared/lib-ts/base/inference.ts +28 -21
  26. package/dist/templates/_shared/lib-ts/base/logger.ts +15 -2
  27. package/dist/templates/_shared/lib-ts/base/state-io.ts +9 -7
  28. package/dist/templates/_shared/lib-ts/base/stop-words.ts +131 -131
  29. package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +142 -0
  30. package/dist/templates/_shared/lib-ts/base/utils.ts +69 -69
  31. package/dist/templates/_shared/lib-ts/context/context-formatter.ts +30 -24
  32. package/dist/templates/_shared/lib-ts/context/context-selector.ts +50 -32
  33. package/dist/templates/_shared/lib-ts/context/context-store.ts +76 -48
  34. package/dist/templates/_shared/lib-ts/context/plan-manager.ts +43 -23
  35. package/dist/templates/_shared/lib-ts/context/task-tracker.ts +10 -6
  36. package/dist/templates/_shared/lib-ts/handoff/document-generator.ts +11 -10
  37. package/dist/templates/_shared/lib-ts/handoff/handoff-reader.ts +158 -0
  38. package/dist/templates/_shared/lib-ts/templates/formatters.ts +6 -4
  39. package/dist/templates/_shared/lib-ts/types.ts +68 -55
  40. package/dist/templates/_shared/scripts/resolve_context.ts +24 -0
  41. package/dist/templates/_shared/scripts/resume_handoff.ts +345 -0
  42. package/dist/templates/_shared/scripts/save_handoff.ts +3 -3
  43. package/dist/templates/_shared/scripts/status_line.ts +687 -0
  44. package/dist/templates/cc-native/.claude/settings.json +175 -185
  45. package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +15 -17
  46. package/dist/templates/cc-native/_cc-native/agents/CLAUDE.md +0 -2
  47. package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +109 -135
  48. package/dist/templates/cc-native/_cc-native/hooks/add_plan_context.ts +119 -0
  49. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +1027 -0
  50. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +61 -0
  51. package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +156 -0
  52. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +792 -0
  53. package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +199 -0
  54. package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +144 -0
  55. package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +57 -0
  56. package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +83 -0
  57. package/dist/templates/cc-native/_cc-native/lib-ts/corroboration.ts +115 -0
  58. package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +80 -0
  59. package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +120 -0
  60. package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +168 -0
  61. package/dist/templates/cc-native/_cc-native/lib-ts/nul +3 -0
  62. package/dist/templates/cc-native/_cc-native/lib-ts/orchestrator.ts +250 -0
  63. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/agent.ts +275 -0
  64. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/codex.ts +130 -0
  65. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/gemini.ts +107 -0
  66. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/index.ts +10 -0
  67. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/types.ts +23 -0
  68. package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +240 -0
  69. package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +18 -0
  70. package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +385 -0
  71. package/dist/templates/cc-native/_cc-native/lib-ts/verdict.ts +72 -0
  72. package/dist/templates/cc-native/_cc-native/plan-review.config.json +14 -1
  73. package/oclif.manifest.json +1 -1
  74. package/package.json +2 -2
  75. package/dist/templates/_shared/hooks/__init__.py +0 -16
  76. package/dist/templates/_shared/hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  77. package/dist/templates/_shared/hooks/__pycache__/archive_plan.cpython-313.pyc +0 -0
  78. package/dist/templates/_shared/hooks/__pycache__/context_enforcer.cpython-313.pyc +0 -0
  79. package/dist/templates/_shared/hooks/__pycache__/context_monitor.cpython-313.pyc +0 -0
  80. package/dist/templates/_shared/hooks/__pycache__/file-suggestion.cpython-313.pyc +0 -0
  81. package/dist/templates/_shared/hooks/__pycache__/pre_compact.cpython-313.pyc +0 -0
  82. package/dist/templates/_shared/hooks/__pycache__/session_end.cpython-313.pyc +0 -0
  83. package/dist/templates/_shared/hooks/__pycache__/session_start.cpython-313.pyc +0 -0
  84. package/dist/templates/_shared/hooks/__pycache__/task_create_atomicity.cpython-313.pyc +0 -0
  85. package/dist/templates/_shared/hooks/__pycache__/task_create_capture.cpython-313.pyc +0 -0
  86. package/dist/templates/_shared/hooks/__pycache__/task_update_capture.cpython-313.pyc +0 -0
  87. package/dist/templates/_shared/hooks/__pycache__/user_prompt_submit.cpython-313.pyc +0 -0
  88. package/dist/templates/_shared/hooks/archive_plan.py +0 -177
  89. package/dist/templates/_shared/hooks/context_monitor.py +0 -270
  90. package/dist/templates/_shared/hooks/file-suggestion.py +0 -215
  91. package/dist/templates/_shared/hooks/pre_compact.py +0 -104
  92. package/dist/templates/_shared/hooks/session_end.py +0 -173
  93. package/dist/templates/_shared/hooks/session_start.py +0 -206
  94. package/dist/templates/_shared/hooks/task_create_capture.py +0 -108
  95. package/dist/templates/_shared/hooks/task_update_capture.py +0 -145
  96. package/dist/templates/_shared/hooks/user_prompt_submit.py +0 -139
  97. package/dist/templates/_shared/lib/__init__.py +0 -1
  98. package/dist/templates/_shared/lib/__pycache__/__init__.cpython-313.pyc +0 -0
  99. package/dist/templates/_shared/lib/base/__init__.py +0 -65
  100. package/dist/templates/_shared/lib/base/__pycache__/__init__.cpython-313.pyc +0 -0
  101. package/dist/templates/_shared/lib/base/__pycache__/atomic_write.cpython-313.pyc +0 -0
  102. package/dist/templates/_shared/lib/base/__pycache__/constants.cpython-313.pyc +0 -0
  103. package/dist/templates/_shared/lib/base/__pycache__/hook_utils.cpython-313.pyc +0 -0
  104. package/dist/templates/_shared/lib/base/__pycache__/inference.cpython-313.pyc +0 -0
  105. package/dist/templates/_shared/lib/base/__pycache__/logger.cpython-313.pyc +0 -0
  106. package/dist/templates/_shared/lib/base/__pycache__/stop_words.cpython-313.pyc +0 -0
  107. package/dist/templates/_shared/lib/base/__pycache__/subprocess_utils.cpython-313.pyc +0 -0
  108. package/dist/templates/_shared/lib/base/__pycache__/utils.cpython-313.pyc +0 -0
  109. package/dist/templates/_shared/lib/base/atomic_write.py +0 -180
  110. package/dist/templates/_shared/lib/base/constants.py +0 -358
  111. package/dist/templates/_shared/lib/base/hook_utils.py +0 -339
  112. package/dist/templates/_shared/lib/base/inference.py +0 -307
  113. package/dist/templates/_shared/lib/base/logger.py +0 -305
  114. package/dist/templates/_shared/lib/base/stop_words.py +0 -221
  115. package/dist/templates/_shared/lib/base/subprocess_utils.py +0 -46
  116. package/dist/templates/_shared/lib/base/utils.py +0 -263
  117. package/dist/templates/_shared/lib/context/__init__.py +0 -102
  118. package/dist/templates/_shared/lib/context/__pycache__/__init__.cpython-313.pyc +0 -0
  119. package/dist/templates/_shared/lib/context/__pycache__/cache.cpython-313.pyc +0 -0
  120. package/dist/templates/_shared/lib/context/__pycache__/context_extractor.cpython-313.pyc +0 -0
  121. package/dist/templates/_shared/lib/context/__pycache__/context_formatter.cpython-313.pyc +0 -0
  122. package/dist/templates/_shared/lib/context/__pycache__/context_manager.cpython-313.pyc +0 -0
  123. package/dist/templates/_shared/lib/context/__pycache__/context_selector.cpython-313.pyc +0 -0
  124. package/dist/templates/_shared/lib/context/__pycache__/context_store.cpython-313.pyc +0 -0
  125. package/dist/templates/_shared/lib/context/__pycache__/discovery.cpython-313.pyc +0 -0
  126. package/dist/templates/_shared/lib/context/__pycache__/event_log.cpython-313.pyc +0 -0
  127. package/dist/templates/_shared/lib/context/__pycache__/plan_archive.cpython-313.pyc +0 -0
  128. package/dist/templates/_shared/lib/context/__pycache__/plan_manager.cpython-313.pyc +0 -0
  129. package/dist/templates/_shared/lib/context/__pycache__/task_sync.cpython-313.pyc +0 -0
  130. package/dist/templates/_shared/lib/context/__pycache__/task_tracker.cpython-313.pyc +0 -0
  131. package/dist/templates/_shared/lib/context/context_formatter.py +0 -317
  132. package/dist/templates/_shared/lib/context/context_selector.py +0 -508
  133. package/dist/templates/_shared/lib/context/context_store.py +0 -653
  134. package/dist/templates/_shared/lib/context/plan_manager.py +0 -303
  135. package/dist/templates/_shared/lib/context/task_tracker.py +0 -188
  136. package/dist/templates/_shared/lib/handoff/__init__.py +0 -22
  137. package/dist/templates/_shared/lib/handoff/__pycache__/__init__.cpython-313.pyc +0 -0
  138. package/dist/templates/_shared/lib/handoff/__pycache__/document_generator.cpython-313.pyc +0 -0
  139. package/dist/templates/_shared/lib/handoff/document_generator.py +0 -278
  140. package/dist/templates/_shared/lib/templates/README.md +0 -206
  141. package/dist/templates/_shared/lib/templates/__init__.py +0 -36
  142. package/dist/templates/_shared/lib/templates/__pycache__/__init__.cpython-313.pyc +0 -0
  143. package/dist/templates/_shared/lib/templates/__pycache__/formatters.cpython-313.pyc +0 -0
  144. package/dist/templates/_shared/lib/templates/__pycache__/persona_questions.cpython-313.pyc +0 -0
  145. package/dist/templates/_shared/lib/templates/__pycache__/plan_context.cpython-313.pyc +0 -0
  146. package/dist/templates/_shared/lib/templates/formatters.py +0 -146
  147. package/dist/templates/_shared/lib/templates/plan_context.py +0 -73
  148. package/dist/templates/_shared/scripts/__pycache__/save_handoff.cpython-313.pyc +0 -0
  149. package/dist/templates/_shared/scripts/__pycache__/status_line.cpython-313.pyc +0 -0
  150. package/dist/templates/_shared/scripts/save_handoff.py +0 -357
  151. package/dist/templates/_shared/scripts/status_line.py +0 -716
  152. package/dist/templates/cc-native/.claude/commands/cc-native/fresh-perspective.md +0 -8
  153. package/dist/templates/cc-native/.windsurf/workflows/cc-native/fresh-perspective.md +0 -8
  154. package/dist/templates/cc-native/MIGRATION.md +0 -86
  155. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/add_plan_context.cpython-313.pyc +0 -0
  156. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/cc-native-plan-review.cpython-313.pyc +0 -0
  157. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/mark_questions_asked.cpython-313.pyc +0 -0
  158. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/plan_accepted.cpython-313.pyc +0 -0
  159. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/plan_questions_early.cpython-313.pyc +0 -0
  160. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/suggest-fresh-perspective.cpython-313.pyc +0 -0
  161. package/dist/templates/cc-native/_cc-native/hooks/add_plan_context.py +0 -130
  162. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.py +0 -954
  163. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.py +0 -81
  164. package/dist/templates/cc-native/_cc-native/hooks/suggest-fresh-perspective.py +0 -340
  165. package/dist/templates/cc-native/_cc-native/lib/CLAUDE.md +0 -265
  166. package/dist/templates/cc-native/_cc-native/lib/__init__.py +0 -53
  167. package/dist/templates/cc-native/_cc-native/lib/__pycache__/__init__.cpython-313.pyc +0 -0
  168. package/dist/templates/cc-native/_cc-native/lib/__pycache__/atomic_write.cpython-313.pyc +0 -0
  169. package/dist/templates/cc-native/_cc-native/lib/__pycache__/constants.cpython-313.pyc +0 -0
  170. package/dist/templates/cc-native/_cc-native/lib/__pycache__/debug.cpython-313.pyc +0 -0
  171. package/dist/templates/cc-native/_cc-native/lib/__pycache__/orchestrator.cpython-313.pyc +0 -0
  172. package/dist/templates/cc-native/_cc-native/lib/__pycache__/state.cpython-313.pyc +0 -0
  173. package/dist/templates/cc-native/_cc-native/lib/__pycache__/utils.cpython-313.pyc +0 -0
  174. package/dist/templates/cc-native/_cc-native/lib/constants.py +0 -45
  175. package/dist/templates/cc-native/_cc-native/lib/debug.py +0 -139
  176. package/dist/templates/cc-native/_cc-native/lib/orchestrator.py +0 -362
  177. package/dist/templates/cc-native/_cc-native/lib/reviewers/__init__.py +0 -28
  178. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/__init__.cpython-313.pyc +0 -0
  179. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/agent.cpython-313.pyc +0 -0
  180. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/base.cpython-313.pyc +0 -0
  181. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/codex.cpython-313.pyc +0 -0
  182. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/gemini.cpython-313.pyc +0 -0
  183. package/dist/templates/cc-native/_cc-native/lib/reviewers/agent.py +0 -215
  184. package/dist/templates/cc-native/_cc-native/lib/reviewers/base.py +0 -88
  185. package/dist/templates/cc-native/_cc-native/lib/reviewers/codex.py +0 -124
  186. package/dist/templates/cc-native/_cc-native/lib/reviewers/gemini.py +0 -108
  187. package/dist/templates/cc-native/_cc-native/lib/state.py +0 -268
  188. package/dist/templates/cc-native/_cc-native/lib/utils.py +0 -1071
  189. package/dist/templates/cc-native/_cc-native/scripts/__pycache__/aggregate_agents.cpython-313.pyc +0 -0
  190. package/dist/templates/cc-native/_cc-native/scripts/aggregate_agents.py +0 -168
  191. package/dist/templates/cc-native/_cc-native/workflows/fresh-perspective.md +0 -134
@@ -1,278 +0,0 @@
1
- """Handoff document generator for context-aware session management.
2
-
3
- Creates structured handoff documents when a session needs to transfer
4
- work to a new session (typically due to context window limits).
5
-
6
- Handoff documents capture:
7
- - Links to active plan and context folder
8
- - Current task state from events.jsonl
9
- - Work in progress summary
10
- - Next steps for continuation
11
- """
12
- import json
13
- import uuid
14
- from dataclasses import dataclass, field
15
- from datetime import datetime
16
- from pathlib import Path
17
- from typing import Any, Dict, List, Optional
18
-
19
- from ..base.atomic_write import atomic_write
20
- from ..base.constants import get_context_handoffs_dir, get_context_dir
21
- from ..base.logger import log_info, log_error
22
- from ..base.utils import now_iso
23
- from ..context.context_store import get_context as _get_context_state, save_state as _save_state
24
- from ..context.task_tracker import get_tasks
25
- from ..templates.formatters import render_task_list, format_continuation_header, format_reason
26
-
27
-
28
- @dataclass
29
- class HandoffDocument:
30
- """Structured handoff document content."""
31
- context_id: str
32
- context_summary: str
33
- session_id: str
34
- reason: str # e.g., "low_context", "user_requested", "error_recovery"
35
- created_at: str
36
-
37
- # Links
38
- plan_path: Optional[str] = None
39
- context_folder: str = ""
40
- events_log_path: str = ""
41
-
42
- # Task state
43
- active_tasks: List[Dict[str, Any]] = field(default_factory=list)
44
- completed_tasks_this_session: List[Dict[str, Any]] = field(default_factory=list)
45
-
46
- # Context summary
47
- work_summary: str = ""
48
- next_steps: List[str] = field(default_factory=list)
49
- important_notes: List[str] = field(default_factory=list)
50
-
51
- # File path (set after saving)
52
- file_path: Optional[str] = None
53
-
54
-
55
- def generate_handoff_document(
56
- context_id: str,
57
- reason: str = "low_context",
58
- work_summary: str = "",
59
- next_steps: Optional[List[str]] = None,
60
- important_notes: Optional[List[str]] = None,
61
- completed_this_session: Optional[List[str]] = None,
62
- project_root: Path = None
63
- ) -> Optional[HandoffDocument]:
64
- """
65
- Generate and save a handoff document for a context.
66
-
67
- This creates a markdown document capturing current work state,
68
- saves it to the context's handoffs folder, and records the event.
69
-
70
- Args:
71
- context_id: Context identifier
72
- reason: Why handoff is happening (low_context, user_requested, etc.)
73
- work_summary: Summary of current work in progress
74
- next_steps: List of next steps for continuation
75
- important_notes: Important decisions or context to preserve
76
- completed_this_session: List of task subjects completed this session
77
- project_root: Project root directory
78
-
79
- Returns:
80
- HandoffDocument with file_path set, or None on failure
81
- """
82
- context = _get_context_state(context_id, project_root)
83
- if not context:
84
- log_error("handoff", f"Context '{context_id}' not found")
85
- return None
86
-
87
- # Generate session ID
88
- session_id = str(uuid.uuid4())[:8]
89
-
90
- # Get pending tasks from state.json
91
- all_tasks = get_tasks(context_id, project_root)
92
- pending_tasks = [t for t in all_tasks if t.get("status") in ("pending", "in_progress", "blocked")]
93
-
94
- # Build document
95
- now = now_iso()
96
- context_dir = get_context_dir(context_id, project_root)
97
-
98
- doc = HandoffDocument(
99
- context_id=context_id,
100
- context_summary=context.summary,
101
- session_id=session_id,
102
- reason=reason,
103
- created_at=now,
104
- plan_path=context.plan_path,
105
- context_folder=str(context_dir),
106
- events_log_path=str(context_dir / "state.json"),
107
- active_tasks=pending_tasks,
108
- completed_tasks_this_session=[
109
- {"subject": s} for s in (completed_this_session or [])
110
- ],
111
- work_summary=work_summary,
112
- next_steps=next_steps or [],
113
- important_notes=important_notes or [],
114
- )
115
-
116
- # Compute file path BEFORE rendering markdown
117
- handoffs_dir = get_context_handoffs_dir(context_id, project_root)
118
- handoffs_dir.mkdir(parents=True, exist_ok=True)
119
-
120
- # Filename: YYYY-MM-DD-session-{session_id}.md
121
- date_str = datetime.now().strftime("%Y-%m-%d")
122
- filename = f"{date_str}-session-{session_id}.md"
123
- file_path = handoffs_dir / filename
124
-
125
- # Set file_path on doc BEFORE rendering markdown
126
- doc.file_path = str(file_path)
127
-
128
- # Generate markdown content
129
- markdown = _render_handoff_markdown(doc)
130
-
131
- # Save to handoffs folder
132
-
133
- success, error = atomic_write(file_path, markdown)
134
- if not success:
135
- log_error("handoff", f"Failed to write handoff document: {error}")
136
- return None
137
-
138
- log_info("handoff", f"Created handoff document: {file_path}")
139
- return doc
140
-
141
-
142
- def _render_handoff_markdown(doc: HandoffDocument) -> str:
143
- """Render handoff document as markdown."""
144
- lines = [
145
- format_continuation_header("handoff", doc.context_id),
146
- "",
147
- f"**Created**: {doc.created_at}",
148
- f"**Context ID**: {doc.context_id}",
149
- f"**Session ID**: {doc.session_id}",
150
- f"**Reason**: {format_reason(doc.reason)}",
151
- "",
152
- "## Links",
153
- "",
154
- ]
155
-
156
- # Plan link
157
- if doc.plan_path:
158
- lines.append(f"- **Plan**: [{Path(doc.plan_path).name}]({doc.plan_path})")
159
-
160
- lines.extend([
161
- f"- **Context Folder**: `{doc.context_folder}`",
162
- f"- **Events Log**: `{doc.events_log_path}`",
163
- "",
164
- "## Current State",
165
- "",
166
- ])
167
-
168
- # Active tasks
169
- lines.append(render_task_list(doc.active_tasks, header="Active Tasks", show_description=True).rstrip())
170
- lines.append("")
171
-
172
- # Completed this session
173
- if doc.completed_tasks_this_session:
174
- lines.append(render_task_list(
175
- doc.completed_tasks_this_session,
176
- header="Completed This Session",
177
- show_description=False
178
- ).rstrip())
179
- lines.append("")
180
-
181
- # Work summary
182
- if doc.work_summary:
183
- lines.extend([
184
- "## Context Summary",
185
- "",
186
- doc.work_summary,
187
- "",
188
- ])
189
-
190
- # Next steps
191
- if doc.next_steps:
192
- lines.extend([
193
- "## Next Steps",
194
- "",
195
- ])
196
- for i, step in enumerate(doc.next_steps, 1):
197
- lines.append(f"{i}. {step}")
198
- lines.append("")
199
-
200
- # Important notes
201
- if doc.important_notes:
202
- lines.extend([
203
- "## Important Notes",
204
- "",
205
- ])
206
- for note in doc.important_notes:
207
- lines.append(f"- {note}")
208
- lines.append("")
209
-
210
- # Continuation prompt
211
- lines.extend([
212
- "---",
213
- "",
214
- "**Continuation Prompt**:",
215
- "```",
216
- f'Continue working on context "{doc.context_id}".',
217
- "",
218
- f"Handoff document: {doc.file_path or 'See above'}",
219
- "",
220
- "Read the handoff document, restore tasks with TaskCreate, and continue implementation.",
221
- "```",
222
- ])
223
-
224
- return "\n".join(lines)
225
-
226
-
227
- def get_handoff_continuation_prompt(doc: HandoffDocument) -> str:
228
- """
229
- Generate the prompt to paste into new session for continuation.
230
-
231
- Args:
232
- doc: HandoffDocument with file_path set
233
-
234
- Returns:
235
- Prompt string for continuing work
236
- """
237
- return f"""Continue working on context "{doc.context_id}".
238
-
239
- Handoff document: {doc.file_path}
240
-
241
- Read the handoff document, restore tasks with TaskCreate, and continue implementation."""
242
-
243
-
244
- def get_low_context_warning(context_remaining_percent: int, context_id: str) -> str:
245
- """
246
- Generate system reminder for low context warning.
247
-
248
- This is injected by the UserPromptSubmit hook when context is low.
249
-
250
- Args:
251
- context_remaining_percent: Percentage of context remaining
252
- context_id: Current context identifier
253
-
254
- Returns:
255
- System reminder markdown
256
- """
257
- return f"""<system-reminder>
258
- ## LOW CONTEXT WARNING ({context_remaining_percent}% remaining)
259
-
260
- Your context window is running low. Please:
261
-
262
- 1. **Finish current task** if 1-2 steps away, OR save current progress
263
- 2. **Create handoff document** by calling:
264
- ```python
265
- from _shared.lib.handoff import generate_handoff_document
266
- doc = generate_handoff_document(
267
- context_id="{context_id}",
268
- reason="low_context",
269
- work_summary="<describe current work>",
270
- next_steps=["<step 1>", "<step 2>"],
271
- important_notes=["<key decision 1>"]
272
- )
273
- ```
274
- 3. **Ask permission** to clear and paste continuation prompt
275
-
276
- After creating handoff, ask the user:
277
- "Context is low. I've created a handoff document. May I clear and continue in a new session?"
278
- </system-reminder>"""
@@ -1,206 +0,0 @@
1
- # Shared Templates Module
2
-
3
- Centralized templates and formatters for consistent context management output across context formatting, handoff, and hooks.
4
-
5
- ## Purpose
6
-
7
- This module eliminates duplication by providing a single source of truth for:
8
- - Mode displays (planning, implementing, etc.)
9
- - Status icons (pending, in_progress, completed)
10
- - Task rendering formatters
11
- - Context continuation headers
12
- - Plan context templates
13
- - Handoff reason formatting
14
-
15
- ## Modules
16
-
17
- ### `formatters.py`
18
-
19
- Core formatters and constants for context management output.
20
-
21
- #### Constants
22
-
23
- ```python
24
- MODE_DISPLAY_MAP = {
25
- "planning": "[Planning]",
26
- "pending_implementation": "[Plan Ready]",
27
- "implementing": "[Implementing]",
28
- "none": "",
29
- }
30
-
31
- STATUS_ICON_MAP = {
32
- "pending": "⬜",
33
- "in_progress": "🔄",
34
- "blocked": "🚫",
35
- "completed": "✅",
36
- }
37
-
38
- REASON_MAP = {
39
- "low_context": "Context window running low",
40
- "user_requested": "User requested handoff",
41
- "error_recovery": "Error recovery",
42
- "session_end": "Session ending",
43
- }
44
- ```
45
-
46
- #### Functions
47
-
48
- **`get_mode_display(mode: str) -> str`**
49
-
50
- Get display string for in-flight mode.
51
-
52
- ```python
53
- >>> get_mode_display("planning")
54
- "[Planning]"
55
- >>> get_mode_display("none")
56
- ""
57
- ```
58
-
59
- **`get_status_icon(status: str) -> str`**
60
-
61
- Get emoji icon for task status.
62
-
63
- ```python
64
- >>> get_status_icon("pending")
65
- "⬜"
66
- >>> get_status_icon("completed")
67
- "✅"
68
- ```
69
-
70
- **`render_task_item(task, show_description=True, max_description_length=100) -> str`**
71
-
72
- Render single task with status icon and subject.
73
-
74
- ```python
75
- task = {"status": "pending", "subject": "Fix bug", "description": "Details"}
76
- >>> render_task_item(task)
77
- "- ⬜ [PENDING] Fix bug\n - Details"
78
- ```
79
-
80
- **`render_task_list(tasks, header="Active Tasks", show_description=True) -> str`**
81
-
82
- Render list of tasks with header.
83
-
84
- ```python
85
- tasks = [{"status": "pending", "subject": "Task 1", "description": "Details"}]
86
- >>> render_task_list(tasks, header="My Tasks")
87
- "### My Tasks\n\n- ⬜ [PENDING] Task 1\n - Details\n"
88
- ```
89
-
90
- **`format_continuation_header(header_type: str, context_id: str) -> str`**
91
-
92
- Format continuation header for various scenarios.
93
-
94
- ```python
95
- >>> format_continuation_header("resuming", "my-context")
96
- "## RESUMING FROM HANDOFF: my-context"
97
- ```
98
-
99
- Types: `context`, `resuming`, `implementing`, `handoff`
100
-
101
- **`format_reason(reason: str) -> str`**
102
-
103
- Format handoff reason code as human-readable string.
104
-
105
- ```python
106
- >>> format_reason("low_context")
107
- "Context window running low"
108
- ```
109
-
110
- ### `plan_context.py`
111
-
112
- Plan context templates for the add_plan_context hook.
113
-
114
- **`get_evaluation_context_reminder() -> str`**
115
-
116
- Returns the evaluation context reminder template that prompts Claude to add evaluation context to plans.
117
-
118
- ## Usage
119
-
120
- ### In Discovery Functions
121
-
122
- ```python
123
- from ..templates.formatters import (
124
- get_mode_display,
125
- get_status_icon,
126
- format_continuation_header,
127
- )
128
-
129
- # Display mode status
130
- mode_display = get_mode_display(context.in_flight.mode)
131
- status = f"Context: {context.id} {mode_display}"
132
-
133
- # Render task with icon
134
- icon = get_status_icon(task.status)
135
- output = f"{icon} {task.subject}"
136
-
137
- # Create continuation header
138
- header = format_continuation_header("implementing", context.id)
139
- ```
140
-
141
- ### In Document Generator
142
-
143
- ```python
144
- from ..templates.formatters import render_task_list, format_reason
145
-
146
- # Render task list section
147
- tasks_md = render_task_list(doc.active_tasks, header="Active Tasks")
148
- lines.append(tasks_md)
149
-
150
- # Format handoff reason
151
- reason_text = format_reason(doc.reason)
152
- ```
153
-
154
- ### In Hooks
155
-
156
- ```python
157
- from templates.plan_context import get_evaluation_context_reminder
158
-
159
- # Get plan context template
160
- CONTEXT_REMINDER = get_evaluation_context_reminder()
161
- ```
162
-
163
- ## Dependent Files
164
-
165
- Files that import from this module:
166
-
167
- - `.aiwcli/_shared/lib/context/context_formatter.py`
168
- - Uses: `get_mode_display`, `get_status_icon`, `format_continuation_header`
169
-
170
- - `.aiwcli/_shared/lib/handoff/document_generator.py`
171
- - Uses: `render_task_list`, `format_continuation_header`, `format_reason`
172
-
173
- - `.aiwcli/_cc-native/hooks/add_plan_context.py`
174
- - Uses: `get_evaluation_context_reminder`
175
-
176
- ## Design Principles
177
-
178
- 1. **Single Source of Truth**: Each constant/function exists in one location only
179
- 2. **Backward Compatible**: All functions preserve existing output formats
180
- 3. **Type Flexible**: Functions handle both Task objects and dicts
181
- 4. **Fail-Safe**: Use `.get()` with defaults for missing keys
182
-
183
- ## Testing
184
-
185
- ```bash
186
- # Test imports
187
- cd .aiwcli
188
- python -c "from _shared.lib.templates.formatters import get_mode_display; \
189
- assert get_mode_display('planning') == '[Planning]'"
190
-
191
- # Test task rendering
192
- python -c "from _shared.lib.templates.formatters import get_status_icon; \
193
- assert get_status_icon('pending') != ''"
194
- ```
195
-
196
- ## Synchronization
197
-
198
- Changes to this module must be synchronized to the template directory:
199
-
200
- ```bash
201
- # After editing
202
- cp .aiwcli/_shared/lib/templates/*.py \
203
- packages/cli/src/templates/_shared/lib/templates/
204
- ```
205
-
206
- See `CLAUDE.md` for template synchronization requirements.
@@ -1,36 +0,0 @@
1
- """Shared templates and formatters for context management output.
2
-
3
- This module provides centralized templates for:
4
- - Mode displays (planning, implementing, etc.)
5
- - Status icons (pending, in_progress, completed)
6
- - Task rendering
7
- - Context continuation headers
8
-
9
- Used by context_formatter.py, document_generator.py, and hooks.
10
- """
11
-
12
- from .formatters import (
13
- MODE_DISPLAY_MAP,
14
- STATUS_ICON_MAP,
15
- REASON_MAP,
16
- get_mode_display,
17
- get_status_icon,
18
- render_task_item,
19
- render_task_list,
20
- format_continuation_header,
21
- format_reason,
22
- )
23
- from .plan_context import get_evaluation_context_reminder
24
-
25
- __all__ = [
26
- "MODE_DISPLAY_MAP",
27
- "STATUS_ICON_MAP",
28
- "REASON_MAP",
29
- "get_mode_display",
30
- "get_status_icon",
31
- "render_task_item",
32
- "render_task_list",
33
- "format_continuation_header",
34
- "format_reason",
35
- "get_evaluation_context_reminder",
36
- ]
@@ -1,146 +0,0 @@
1
- """Formatters for context management templates.
2
-
3
- Provides constants and helper functions for consistent formatting
4
- across discovery, handoff, and hook output.
5
- """
6
-
7
- from typing import Any, Dict, List, Optional, Union
8
-
9
- # Mode display mapping for in-flight work states
10
- MODE_DISPLAY_MAP = {
11
- "planning": "[Planning]",
12
- "pending_implementation": "[Plan Ready]",
13
- "implementing": "[Implementing]",
14
- "none": "",
15
- }
16
-
17
- # Status icon mapping for task states
18
- STATUS_ICON_MAP = {
19
- "pending": "⬜",
20
- "in_progress": "🔄",
21
- "blocked": "🚫",
22
- "completed": "✅",
23
- }
24
-
25
-
26
- def get_mode_display(mode: str) -> str:
27
- """Get display string for in-flight mode.
28
-
29
- Args:
30
- mode: In-flight mode string (planning, implementing, etc.)
31
-
32
- Returns:
33
- Display string like "[Planning]" or empty string for "none"
34
- """
35
- return MODE_DISPLAY_MAP.get(mode, "")
36
-
37
-
38
- def get_status_icon(status: str) -> str:
39
- """Get emoji icon for task status.
40
-
41
- Args:
42
- status: Task status (pending, in_progress, blocked, completed)
43
-
44
- Returns:
45
- Emoji icon like "⬜" or "✅"
46
- """
47
- return STATUS_ICON_MAP.get(status, "⬜")
48
-
49
-
50
- def render_task_item(
51
- task: Union["Task", Dict[str, Any]],
52
- show_description: bool = True,
53
- max_description_length: int = 100
54
- ) -> str:
55
- """Render single task with status icon and subject.
56
-
57
- Args:
58
- task: Task object or dict with status, subject, description
59
- show_description: Whether to include description
60
- max_description_length: Maximum length for description before truncating
61
-
62
- Returns:
63
- Formatted string: "- {icon} [{STATUS}] {subject}"
64
- """
65
- # Handle both Task objects and dicts
66
- status = task.get("status") if isinstance(task, dict) else task.status
67
- subject = task.get("subject") if isinstance(task, dict) else task.subject
68
- description = task.get("description") if isinstance(task, dict) else task.description
69
-
70
- icon = get_status_icon(status)
71
- status_text = f"[{status.upper()}]"
72
- line = f"- {icon} {status_text} {subject}"
73
-
74
- if show_description and description:
75
- truncated = description[:max_description_length]
76
- if len(description) > max_description_length:
77
- truncated += "..."
78
- return f"{line}\n - {truncated}"
79
- return line
80
-
81
-
82
- def render_task_list(
83
- tasks: List[Union["Task", Dict[str, Any]]],
84
- header: Optional[str] = "Active Tasks",
85
- show_description: bool = True
86
- ) -> str:
87
- """Render list of tasks with header.
88
-
89
- Args:
90
- tasks: List of Task objects or dicts
91
- header: Section header text
92
- show_description: Whether to show task descriptions
93
-
94
- Returns:
95
- Formatted markdown section with task list
96
- """
97
- lines = [f"### {header}", ""]
98
-
99
- if not tasks:
100
- lines.append("No active tasks.")
101
- else:
102
- for task in tasks:
103
- lines.append(render_task_item(task, show_description))
104
-
105
- lines.append("")
106
- return "\n".join(lines)
107
-
108
-
109
- def format_continuation_header(header_type: str, context_id: str) -> str:
110
- """Format continuation header for various scenarios.
111
-
112
- Args:
113
- header_type: Type of continuation (context, resuming, implementing, handoff)
114
- context_id: Context identifier
115
-
116
- Returns:
117
- Formatted markdown header
118
- """
119
- headers = {
120
- "context": f"## CONTINUING CONTEXT: {context_id}",
121
- "resuming": f"## RESUMING FROM HANDOFF: {context_id}",
122
- "implementing": f"## CONTINUING IMPLEMENTATION: {context_id}",
123
- "handoff": f"# Session Handoff: {context_id}",
124
- }
125
- return headers.get(header_type, f"## {context_id}")
126
-
127
-
128
- # Handoff reason display mapping
129
- REASON_MAP = {
130
- "low_context": "Context window running low",
131
- "user_requested": "User requested handoff",
132
- "error_recovery": "Error recovery",
133
- "session_end": "Session ending",
134
- }
135
-
136
-
137
- def format_reason(reason: str) -> str:
138
- """Format handoff reason code as human-readable string.
139
-
140
- Args:
141
- reason: Reason code (low_context, user_requested, etc.)
142
-
143
- Returns:
144
- Human-readable reason string
145
- """
146
- return REASON_MAP.get(reason, reason)