aiwcli 0.9.7 → 0.10.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.
Files changed (119) hide show
  1. package/bin/run.js +5 -2
  2. package/dist/lib/claude-settings-types.d.ts +2 -0
  3. package/dist/templates/CLAUDE.md +49 -18
  4. package/dist/templates/_shared/.claude/settings.json +4 -0
  5. package/dist/templates/_shared/hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  6. package/dist/templates/_shared/hooks/__pycache__/archive_plan.cpython-313.pyc +0 -0
  7. package/dist/templates/_shared/hooks/__pycache__/context_enforcer.cpython-313.pyc +0 -0
  8. package/dist/templates/_shared/hooks/__pycache__/context_monitor.cpython-313.pyc +0 -0
  9. package/dist/templates/_shared/hooks/__pycache__/file-suggestion.cpython-313.pyc +0 -0
  10. package/dist/templates/_shared/hooks/__pycache__/pre_compact.cpython-313.pyc +0 -0
  11. package/dist/templates/_shared/hooks/__pycache__/session_end.cpython-313.pyc +0 -0
  12. package/dist/templates/_shared/hooks/__pycache__/session_start.cpython-313.pyc +0 -0
  13. package/dist/templates/_shared/hooks/__pycache__/task_create_atomicity.cpython-313.pyc +0 -0
  14. package/dist/templates/_shared/hooks/__pycache__/task_create_capture.cpython-313.pyc +0 -0
  15. package/dist/templates/_shared/hooks/__pycache__/task_update_capture.cpython-313.pyc +0 -0
  16. package/dist/templates/_shared/hooks/__pycache__/user_prompt_submit.cpython-313.pyc +0 -0
  17. package/dist/templates/_shared/hooks/archive_plan.py +87 -178
  18. package/dist/templates/_shared/hooks/context_monitor.py +128 -194
  19. package/dist/templates/_shared/hooks/file-suggestion.py +26 -23
  20. package/dist/templates/_shared/hooks/pre_compact.py +104 -0
  21. package/dist/templates/_shared/hooks/session_end.py +154 -0
  22. package/dist/templates/_shared/hooks/session_start.py +145 -59
  23. package/dist/templates/_shared/hooks/task_create_capture.py +26 -49
  24. package/dist/templates/_shared/hooks/task_update_capture.py +42 -100
  25. package/dist/templates/_shared/hooks/user_prompt_submit.py +63 -77
  26. package/dist/templates/_shared/lib/base/__init__.py +16 -0
  27. package/dist/templates/_shared/lib/base/__pycache__/__init__.cpython-313.pyc +0 -0
  28. package/dist/templates/_shared/lib/base/__pycache__/constants.cpython-313.pyc +0 -0
  29. package/dist/templates/_shared/lib/base/__pycache__/hook_utils.cpython-313.pyc +0 -0
  30. package/dist/templates/_shared/lib/base/__pycache__/inference.cpython-313.pyc +0 -0
  31. package/dist/templates/_shared/lib/base/__pycache__/logger.cpython-313.pyc +0 -0
  32. package/dist/templates/_shared/lib/base/__pycache__/utils.cpython-313.pyc +0 -0
  33. package/dist/templates/_shared/lib/base/constants.py +18 -4
  34. package/dist/templates/_shared/lib/base/hook_utils.py +199 -11
  35. package/dist/templates/_shared/lib/base/inference.py +121 -0
  36. package/dist/templates/_shared/lib/base/logger.py +291 -0
  37. package/dist/templates/_shared/lib/base/utils.py +49 -11
  38. package/dist/templates/_shared/lib/context/__init__.py +72 -80
  39. package/dist/templates/_shared/lib/context/__pycache__/__init__.cpython-313.pyc +0 -0
  40. package/dist/templates/_shared/lib/context/__pycache__/context_formatter.cpython-313.pyc +0 -0
  41. package/dist/templates/_shared/lib/context/__pycache__/context_manager.cpython-313.pyc +0 -0
  42. package/dist/templates/_shared/lib/context/__pycache__/context_selector.cpython-313.pyc +0 -0
  43. package/dist/templates/_shared/lib/context/__pycache__/context_store.cpython-313.pyc +0 -0
  44. package/dist/templates/_shared/lib/context/__pycache__/discovery.cpython-313.pyc +0 -0
  45. package/dist/templates/_shared/lib/context/__pycache__/plan_manager.cpython-313.pyc +0 -0
  46. package/dist/templates/_shared/lib/context/__pycache__/task_tracker.cpython-313.pyc +0 -0
  47. package/dist/templates/_shared/lib/context/context_formatter.py +316 -0
  48. package/dist/templates/_shared/lib/context/context_selector.py +491 -0
  49. package/dist/templates/_shared/lib/context/context_store.py +636 -0
  50. package/dist/templates/_shared/lib/context/plan_manager.py +204 -0
  51. package/dist/templates/_shared/lib/context/task_tracker.py +188 -0
  52. package/dist/templates/_shared/lib/handoff/__pycache__/__init__.cpython-313.pyc +0 -0
  53. package/dist/templates/_shared/lib/handoff/__pycache__/document_generator.cpython-313.pyc +0 -0
  54. package/dist/templates/_shared/lib/handoff/document_generator.py +14 -40
  55. package/dist/templates/_shared/lib/templates/README.md +5 -13
  56. package/dist/templates/_shared/lib/templates/__init__.py +2 -6
  57. package/dist/templates/_shared/lib/templates/__pycache__/__init__.cpython-313.pyc +0 -0
  58. package/dist/templates/_shared/lib/templates/__pycache__/formatters.cpython-313.pyc +0 -0
  59. package/dist/templates/_shared/lib/templates/__pycache__/plan_context.cpython-313.pyc +0 -0
  60. package/dist/templates/_shared/lib/templates/plan_context.py +25 -79
  61. package/dist/templates/_shared/scripts/__pycache__/save_handoff.cpython-313.pyc +0 -0
  62. package/dist/templates/_shared/scripts/__pycache__/status_line.cpython-313.pyc +0 -0
  63. package/dist/templates/_shared/scripts/save_handoff.py +39 -19
  64. package/dist/templates/_shared/scripts/status_line.py +701 -0
  65. package/dist/templates/_shared/workflows/handoff.md +9 -3
  66. package/dist/templates/cc-native/.claude/settings.json +64 -9
  67. package/dist/templates/cc-native/CC-NATIVE-README.md +25 -28
  68. package/dist/templates/cc-native/MIGRATION.md +1 -1
  69. package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +14 -39
  70. package/dist/templates/cc-native/_cc-native/agents/CLAUDE.md +1 -1
  71. package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +57 -22
  72. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/add_plan_context.cpython-313.pyc +0 -0
  73. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/cc-native-plan-review.cpython-313.pyc +0 -0
  74. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/mark_questions_asked.cpython-313.pyc +0 -0
  75. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/plan_accepted.cpython-313.pyc +0 -0
  76. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/plan_questions_early.cpython-313.pyc +0 -0
  77. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/suggest-fresh-perspective.cpython-313.pyc +0 -0
  78. package/dist/templates/cc-native/_cc-native/hooks/add_plan_context.py +57 -57
  79. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.py +208 -158
  80. package/dist/templates/cc-native/_cc-native/hooks/plan_accepted.py +127 -0
  81. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.py +81 -0
  82. package/dist/templates/cc-native/_cc-native/hooks/suggest-fresh-perspective.py +26 -25
  83. package/dist/templates/cc-native/_cc-native/lib/CLAUDE.md +35 -10
  84. package/dist/templates/cc-native/_cc-native/lib/__pycache__/__init__.cpython-313.pyc +0 -0
  85. package/dist/templates/cc-native/_cc-native/lib/__pycache__/constants.cpython-313.pyc +0 -0
  86. package/dist/templates/cc-native/_cc-native/lib/__pycache__/debug.cpython-313.pyc +0 -0
  87. package/dist/templates/cc-native/_cc-native/lib/__pycache__/orchestrator.cpython-313.pyc +0 -0
  88. package/dist/templates/cc-native/_cc-native/lib/__pycache__/state.cpython-313.pyc +0 -0
  89. package/dist/templates/cc-native/_cc-native/lib/__pycache__/utils.cpython-313.pyc +0 -0
  90. package/dist/templates/cc-native/_cc-native/lib/debug.py +37 -22
  91. package/dist/templates/cc-native/_cc-native/lib/orchestrator.py +103 -42
  92. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/__init__.cpython-313.pyc +0 -0
  93. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/agent.cpython-313.pyc +0 -0
  94. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/base.cpython-313.pyc +0 -0
  95. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/codex.cpython-313.pyc +0 -0
  96. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/gemini.cpython-313.pyc +0 -0
  97. package/dist/templates/cc-native/_cc-native/lib/reviewers/agent.py +26 -21
  98. package/dist/templates/cc-native/_cc-native/lib/reviewers/codex.py +12 -7
  99. package/dist/templates/cc-native/_cc-native/lib/reviewers/gemini.py +12 -7
  100. package/dist/templates/cc-native/_cc-native/lib/state.py +31 -16
  101. package/dist/templates/cc-native/_cc-native/lib/utils.py +210 -43
  102. package/dist/templates/cc-native/_cc-native/plan-review.config.json +1 -2
  103. package/oclif.manifest.json +1 -1
  104. package/package.json +1 -1
  105. package/dist/templates/_shared/hooks/context_enforcer.py +0 -625
  106. package/dist/templates/_shared/hooks/task_create_atomicity.py +0 -205
  107. package/dist/templates/_shared/lib/context/cache.py +0 -444
  108. package/dist/templates/_shared/lib/context/context_extractor.py +0 -115
  109. package/dist/templates/_shared/lib/context/context_manager.py +0 -1054
  110. package/dist/templates/_shared/lib/context/discovery.py +0 -444
  111. package/dist/templates/_shared/lib/context/event_log.py +0 -308
  112. package/dist/templates/_shared/lib/context/plan_archive.py +0 -101
  113. package/dist/templates/_shared/lib/context/task_sync.py +0 -290
  114. package/dist/templates/_shared/lib/templates/persona_questions.py +0 -113
  115. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/archive_plan.cpython-313.pyc +0 -0
  116. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/cc-native-agent-review.cpython-313.pyc +0 -0
  117. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/test_permission_request.cpython-313.pyc +0 -0
  118. package/dist/templates/cc-native/_cc-native/lib/async_archive.py +0 -68
  119. package/dist/templates/cc-native/_cc-native/lib/atomic_write.py +0 -98
@@ -1,8 +1,7 @@
1
1
  """Plan context templates for add_plan_context hook.
2
2
 
3
3
  Provides standardized templates for:
4
- - Evaluation context reminder
5
- - Clarifying questions offer
4
+ - Evaluation context reminder (injected on plan writes)
6
5
  """
7
6
 
8
7
 
@@ -13,93 +12,40 @@ def get_evaluation_context_reminder() -> str:
13
12
  Formatted markdown reminder about adding evaluation context
14
13
  """
15
14
  return """
16
- ## IMPORTANT: This Plan Will Be Executed in a Fresh Context
15
+ ## CRITICAL: Write This Plan for a Different Agent
17
16
 
18
- Your plan will be:
19
- 1. **Reviewed** by agents who have NO access to this conversation
20
- 2. **Executed** by a Claude agent starting with a completely fresh context
17
+ The agent executing this plan has ZERO context from this conversation — no chat history, no memory of files you explored or research you did.
21
18
 
22
- The implementing agent won't have access to your research, file explorations, or any conversation history. Your plan must be **self-contained** and provide everything needed to execute it successfully.
19
+ **Write as if YOU are that agent. What would you need?**
23
20
 
24
- ### Required Plan Elements
21
+ ### Required Structure
25
22
 
26
- 1. **A title line** at the very top: `# Plan: <descriptive title>`
27
-
28
- 2. **Context Section** near the top with:
29
- - **Background**: The bigger picture - why this change is needed and what problem it solves
30
- - **Task**: What is being built/changed (specific and actionable)
31
- - **Goal**: The underlying problem the user wants solved
32
- - **Constraints**: Technical requirements, preferences, or limitations mentioned
33
-
34
- 3. **Relevant Files** section listing:
35
- - Files that will be modified (with brief description of what changes)
36
- - Files to reference for patterns/context (with why they're relevant)
37
- - Any configuration files that matter
38
-
39
- 4. **Implementation Details** that are explicit enough for someone unfamiliar with your research:
40
- - Don't assume the implementer knows what you discovered
41
- - Include specific function names, patterns, or approaches to use
42
- - Reference line numbers or code snippets if helpful
43
-
44
- ### Example
45
-
46
- ```markdown
47
- # Plan: Add OAuth2 Authentication
48
-
49
- ## Context
50
- **Background**: The app currently only supports username/password auth. Users have requested social login to reduce friction during signup.
51
- **Task**: Implement OAuth2 flow for user authentication
52
- **Goal**: Enable secure third-party authentication via Google and GitHub
53
- **Constraints**: Must integrate with existing session management; no new dependencies preferred
54
-
55
- ## Relevant Files
56
- **Modify:**
57
- - `src/auth/middleware.ts` - Add OAuth callback handlers
58
- - `src/routes/auth.ts` - Add OAuth routes
59
-
60
- **Reference for patterns:**
61
- - `src/auth/password.ts` - Shows existing auth flow pattern
62
- - `src/config/index.ts` - Where to add OAuth credentials
63
-
64
- ## Implementation Steps
65
- [Detailed steps here...]
66
23
  ```
24
+ # Plan: <descriptive title>
67
25
 
68
- This context allows reviewers to assess whether your plan addresses the user's needs, AND enables the implementing agent to execute it without needing to re-discover your research.
69
- """.strip()
70
-
71
-
72
- def get_questions_offer_template() -> str:
73
- """Get the clarifying questions offer template.
74
-
75
- Uses persona-based questioning to surface hidden constraints.
76
-
77
- Returns:
78
- Formatted markdown prompt for offering clarifying questions
79
- """
80
- from .persona_questions import format_questions_for_prompt
26
+ ## Background
27
+ Why this change is needed (2-3 sentences)
81
28
 
82
- persona_questions = format_questions_for_prompt()
29
+ ## Task
30
+ What exactly to build/change
83
31
 
84
- return f"""
85
- ## First Plan Write - Optional Clarifying Questions
86
-
87
- Your initial plan has been saved. Before finalizing, ask the user if they'd like to answer clarifying questions to refine it.
88
-
89
- **Use AskUserQuestion now:**
90
-
91
- Header: "Questions?"
92
- Question: "I've drafted an initial plan. Would you like to answer a few clarifying questions from different perspectives so I can refine it?"
93
- Options:
94
- - "Yes, ask me questions" (description: "I'll ask targeted questions to surface hidden constraints, then update the plan")
95
- - "No, proceed as-is" (description: "Skip questions and proceed with the current plan")
32
+ ## Files
33
+ **Modify:**
34
+ - `exact/path/to/file.py` - What changes (reference line numbers or patterns)
96
35
 
97
- ### If user chooses YES:
36
+ **Reference:**
37
+ - `exact/path/to/reference.py` - Why relevant (e.g., "pattern to follow at lines 12-30")
98
38
 
99
- {persona_questions}
39
+ ## Steps
40
+ 1. [Specific steps with function names, patterns, or code snippets]
41
+ 2. [Enough detail for someone who never saw this conversation]
100
42
 
101
- After gathering answers, **update the plan file** with refined content before calling ExitPlanMode.
43
+ ## Constraints
44
+ - Technical requirements, preferences, or limitations
45
+ ```
102
46
 
103
- ### If user chooses NO:
104
- Proceed directly to ExitPlanMode with the current plan.
47
+ ### Self-Check
48
+ - [ ] Could I execute this if I forgot our entire conversation?
49
+ - [ ] Are file paths exact (not "the auth file")?
50
+ - [ ] Are implementation details specific (not "use the approach we discussed")?
105
51
  """.strip()
@@ -31,8 +31,8 @@ SCRIPT_DIR = Path(__file__).resolve().parent
31
31
  SHARED_ROOT = SCRIPT_DIR.parent
32
32
  sys.path.insert(0, str(SHARED_ROOT))
33
33
 
34
- from lib.context.context_manager import get_context
35
- from lib.base.utils import eprint
34
+ from lib.context.context_store import get_context, save_state, update_mode
35
+ from lib.base.logger import log_info, log_warn, log_error
36
36
  from lib.base.atomic_write import atomic_write
37
37
  from lib.base.constants import get_handoff_folder_path
38
38
 
@@ -106,16 +106,14 @@ def get_git_status() -> str:
106
106
 
107
107
 
108
108
  def get_plan_path_from_context(context_id: str, project_root: Path) -> Optional[Path]:
109
- """Get the plan path from context.json if available."""
109
+ """Get the plan path from state.json if available."""
110
110
  context = get_context(context_id, project_root)
111
- if not context or not context.in_flight:
111
+ if not context or not context.plan_path:
112
112
  return None
113
113
 
114
- artifact_path = context.in_flight.artifact_path
115
- if artifact_path:
116
- plan_path = Path(artifact_path)
117
- if plan_path.exists():
118
- return plan_path
114
+ plan_path = Path(context.plan_path)
115
+ if plan_path.exists():
116
+ return plan_path
119
117
 
120
118
  return None
121
119
 
@@ -206,7 +204,7 @@ def write_section_file(folder: Path, filename: str, title: str, content: str) ->
206
204
  file_path = folder / filename
207
205
  success, error = atomic_write(file_path, '\n'.join(lines))
208
206
  if not success:
209
- eprint(f"[save_handoff] Warning: Failed to write {filename}: {error}")
207
+ log_warn("save_handoff", f"Failed to write {filename}: {error}")
210
208
  return False
211
209
  return True
212
210
 
@@ -224,7 +222,7 @@ def main():
224
222
  # Read content from stdin
225
223
  content = sys.stdin.read()
226
224
  if not content.strip():
227
- print("Error: No content provided via stdin", file=sys.stderr)
225
+ log_error("save_handoff", "No content provided via stdin")
228
226
  sys.exit(1)
229
227
 
230
228
  # Project root is the parent of .aiwcli
@@ -233,19 +231,19 @@ def main():
233
231
  # Verify context exists
234
232
  context = get_context(context_id, project_root)
235
233
  if not context:
236
- print(f"Error: Context not found: {context_id}", file=sys.stderr)
234
+ log_error("save_handoff", f"Context not found: {context_id}")
237
235
  sys.exit(1)
238
236
 
239
237
  # Parse frontmatter and sections
240
238
  frontmatter, body = parse_frontmatter(content)
241
239
  sections = parse_handoff_sections(body)
242
240
 
243
- eprint(f"[save_handoff] Parsed {len(sections)} sections: {list(sections.keys())}")
241
+ log_info("save_handoff", f"Parsed {len(sections)} sections: {list(sections.keys())}")
244
242
 
245
243
  # Create handoff folder
246
244
  handoff_folder = get_handoff_folder_path(context_id, project_root)
247
245
  handoff_folder.mkdir(parents=True, exist_ok=True)
248
- eprint(f"[save_handoff] Created folder: {handoff_folder}")
246
+ log_info("save_handoff", f"Created folder: {handoff_folder}")
249
247
 
250
248
  # Get git status
251
249
  git_status = get_git_status()
@@ -261,18 +259,18 @@ def main():
261
259
  plan_dest = handoff_folder / "plan.md"
262
260
  success, error = atomic_write(plan_dest, plan_content)
263
261
  if success:
264
- eprint(f"[save_handoff] Copied plan from {plan_path}")
262
+ log_info("save_handoff", f"Copied plan from {plan_path}")
265
263
  else:
266
- eprint(f"[save_handoff] Warning: Failed to copy plan: {error}")
264
+ log_warn("save_handoff", f"Failed to copy plan: {error}")
267
265
  except Exception as e:
268
- eprint(f"[save_handoff] Warning: Failed to read plan: {e}")
266
+ log_warn("save_handoff", f"Failed to read plan: {e}")
269
267
 
270
268
  # Write index.md
271
269
  index_content = generate_index(frontmatter, sections, git_status, has_plan)
272
270
  index_path = handoff_folder / "index.md"
273
271
  success, error = atomic_write(index_path, index_content)
274
272
  if not success:
275
- print(f"Error: Failed to write index.md: {error}", file=sys.stderr)
273
+ log_error("save_handoff", f"Failed to write index.md: {error}")
276
274
  sys.exit(1)
277
275
 
278
276
  # Write section files
@@ -313,7 +311,7 @@ def main():
313
311
  full_content = '\n'.join(content_parts) + '\n'
314
312
  success, error = atomic_write(file_path, full_content)
315
313
  if not success:
316
- eprint(f"[save_handoff] Warning: Failed to write {filename}: {error}")
314
+ log_warn("save_handoff", f"Failed to write {filename}: {error}")
317
315
 
318
316
  # Ensure all expected files exist (even if empty)
319
317
  expected_files = ['completed-work.md', 'dead-ends.md', 'decisions.md', 'pending.md', 'context.md']
@@ -330,6 +328,28 @@ def main():
330
328
  if not file_path.exists():
331
329
  write_section_file(handoff_folder, filename, titles[filename], "")
332
330
 
331
+ # Set handoff_path so next session auto-detects it
332
+ try:
333
+ index_path_str = str(handoff_folder / "index.md")
334
+ state = get_context(context_id, project_root)
335
+ if state:
336
+ state.handoff_path = index_path_str
337
+ save_state(state, project_root)
338
+ log_info("save_handoff", f"Set handoff_path: {index_path_str}")
339
+ else:
340
+ log_warn("save_handoff", f"Could not load context state for {context_id}")
341
+ except Exception as e:
342
+ log_warn("save_handoff", f"Handoff saved but auto-resume won't work (context update failed): {e}")
343
+
344
+ # Transition context to idle — handoff is saved, no longer "active work"
345
+ # This prevents auto-selection in new sessions while keeping the context
346
+ # accessible via explicit caret commands (^, ^N)
347
+ try:
348
+ update_mode(context_id, "idle", project_root=project_root)
349
+ log_info("save_handoff", f"Set mode to 'idle' (dormant) for context: {context_id}")
350
+ except Exception as e:
351
+ log_warn("save_handoff", f"Failed to set dormant mode: {e}")
352
+
333
353
  # Output success message (ASCII-safe for Windows)
334
354
  print(f"[OK] Created handoff folder: {handoff_folder}")
335
355
  print(f" - index.md (entry point with navigation)")