adelie-ai 0.2.4 → 0.2.6

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.
@@ -88,6 +88,80 @@ def _get_recent_build_errors() -> str:
88
88
  return content[:500] # 토큰 제한
89
89
 
90
90
 
91
+ def _get_project_file_snapshot() -> str:
92
+ """
93
+ Scan the actual project directory and return a reality summary.
94
+ This gives Expert AI ground-truth about what code actually exists,
95
+ preventing premature EXPORT/PAUSE when no source code is present.
96
+ """
97
+ from adelie.config import PROJECT_ROOT
98
+
99
+ if not PROJECT_ROOT.exists():
100
+ return "Project directory not found."
101
+
102
+ SOURCE_EXTS = {".ts", ".tsx", ".js", ".jsx", ".py", ".go", ".rs", ".java", ".kt", ".swift", ".vue", ".svelte"}
103
+ CONFIG_EXTS = {".json", ".toml", ".yaml", ".yml", ".env", ".cfg", ".ini"}
104
+ SKIP_DIRS = {"node_modules", "__pycache__", ".git", ".adelie", "dist", "build", ".venv", "venv"}
105
+
106
+ source_files: list[str] = []
107
+ config_files: list[str] = []
108
+ total_lines = 0
109
+
110
+ for path in PROJECT_ROOT.rglob("*"):
111
+ if path.is_file():
112
+ # Skip hidden/build dirs
113
+ parts = set(path.parts)
114
+ if parts & SKIP_DIRS:
115
+ continue
116
+ rel = str(path.relative_to(PROJECT_ROOT))
117
+ if path.suffix in SOURCE_EXTS:
118
+ source_files.append(rel)
119
+ try:
120
+ total_lines += len(path.read_text(encoding="utf-8", errors="ignore").splitlines())
121
+ except Exception:
122
+ pass
123
+ elif path.suffix in CONFIG_EXTS:
124
+ config_files.append(rel)
125
+
126
+ src_count = len(source_files)
127
+ cfg_count = len(config_files)
128
+
129
+ # Determine deployment readiness contextually
130
+ if src_count == 0:
131
+ readiness = "❌ NO SOURCE CODE — implementation has not started"
132
+ advice = (
133
+ "IMPORTANT CONTEXT: There are no source files in the project yet. "
134
+ "EXPORT or PAUSE at this stage provides zero value to the user. "
135
+ "The highest priority is to create coder_tasks to build the actual application."
136
+ )
137
+ elif src_count < 5:
138
+ readiness = f"⚠️ EARLY STAGE — only {src_count} source file(s), scaffolding phase"
139
+ advice = (
140
+ "The project is in early scaffolding. "
141
+ "Prioritize coder_tasks to build core features before any documentation exports."
142
+ )
143
+ elif total_lines < 200:
144
+ readiness = f"🔶 SKELETON — {src_count} files but only {total_lines} total lines"
145
+ advice = "Source files exist but content is minimal. Focus on implementation over exports."
146
+ else:
147
+ readiness = f"✅ CODE EXISTS — {src_count} source file(s), {total_lines:,} lines"
148
+ advice = "Source code is present. Documentation and exports are appropriate."
149
+
150
+ # Show up to 10 source files
151
+ sample = source_files[:10]
152
+ sample_str = "\n ".join(sample) if sample else "(none)"
153
+ if len(source_files) > 10:
154
+ sample_str += f"\n ... and {len(source_files) - 10} more"
155
+
156
+ return f"""## Current Project Reality (File System Snapshot)
157
+ Status: {readiness}
158
+ Source files: {src_count} | Config files: {cfg_count} | Total lines: {total_lines:,}
159
+
160
+ Source files found:
161
+ {sample_str}
162
+
163
+ {advice}"""
164
+
91
165
  def _get_scaffolding_need() -> str:
92
166
  """
93
167
  프로젝트 진입 파일 존재 여부 검사.
@@ -347,6 +421,9 @@ Total KB files across all categories: {total_kb_files}
347
421
  ## ⚠️ Missing Project Entry Files (CREATE THESE FIRST)
348
422
  {_get_scaffolding_need()}
349
423
 
424
+ {_get_project_file_snapshot()}
425
+
426
+
350
427
  ## This Cycle — Writer AI Output
351
428
  {writer_summary}
352
429
  {get_context_prompt_section()}{get_rules_prompt_section()}{get_skills_prompt_section("expert")}{get_tool_registry().get_tools_prompt("expert")}
@@ -15,7 +15,7 @@ from pathlib import Path
15
15
 
16
16
  from rich.console import Console
17
17
 
18
- from adelie.config import WORKSPACE_PATH, KB_CATEGORIES
18
+ from adelie.config import WORKSPACE_PATH, KB_CATEGORIES, PROJECT_ROOT
19
19
  from adelie.context_compactor import (
20
20
  compact_system_state,
21
21
  compact_expert_output,
@@ -28,6 +28,45 @@ from adelie.phases import get_phase_prompt
28
28
  console = Console()
29
29
 
30
30
 
31
+ def _get_project_file_snapshot_for_writer() -> str:
32
+ """
33
+ Provide Writer AI with scope guidance based on actual project files.
34
+ Prevents writing deployment/security docs before code exists.
35
+ """
36
+ if not PROJECT_ROOT.exists():
37
+ return ""
38
+
39
+ SOURCE_EXTS = {".ts", ".tsx", ".js", ".jsx", ".py", ".go", ".rs", ".java", ".kt", ".vue", ".svelte"}
40
+ SKIP_DIRS = {"node_modules", "__pycache__", ".git", ".adelie", "dist", "build", ".venv", "venv"}
41
+
42
+ source_files = [
43
+ p for p in PROJECT_ROOT.rglob("*")
44
+ if p.is_file()
45
+ and p.suffix in SOURCE_EXTS
46
+ and not (set(p.parts) & SKIP_DIRS)
47
+ ]
48
+ src_count = len(source_files)
49
+
50
+ if src_count == 0:
51
+ return (
52
+ "⚠️ WRITER SCOPE: No source code exists yet in this project.\n"
53
+ "- DO NOT write deployment guides, security audits, or CI/CD pipelines.\n"
54
+ " Those are premature when there is no code to deploy.\n"
55
+ "- Instead write: architecture plans, tech stack decisions, implementation\n"
56
+ " roadmaps, and component design documents.\n"
57
+ "- Spec files describe FUTURE goals, not current reality."
58
+ )
59
+ elif src_count < 5:
60
+ return (
61
+ f"⚠️ WRITER SCOPE: Only {src_count} source file(s) exist (early scaffolding).\n"
62
+ "- Focus on implementation guides, coding patterns, and API specs.\n"
63
+ "- Deployment/security docs are premature at this stage.\n"
64
+ "- Prioritize writing content that helps the Coder AI build features."
65
+ )
66
+ else:
67
+ return f"✅ WRITER SCOPE: {src_count} source files found — all documentation types are appropriate."
68
+
69
+
31
70
  def _list_existing_files() -> str:
32
71
  """Build a summary of all existing KB files per category for the Writer AI prompt."""
33
72
  lines = []
@@ -140,6 +179,9 @@ def run(
140
179
  - Focus on creating files that cover DIFFERENT topics than what already exists.
141
180
  - If the KB already has planning docs, create implementation/technical docs instead.
142
181
 
182
+ ## SCOPE GUIDANCE — Read Before Writing
183
+ {_get_project_file_snapshot_for_writer()}
184
+
143
185
  Based on the above context, what knowledge files should be created or updated?
144
186
  Do NOT recreate files with roughly the same content as existing ones.
145
187
  Remember: output ONLY a valid JSON array.
@@ -194,6 +194,9 @@ class AdelieApp:
194
194
  workspace=str(cfg.PROJECT_ROOT),
195
195
  )
196
196
 
197
+ # Start dashboard server FIRST (so _setup_logger can reference it)
198
+ self._start_dashboard(cfg)
199
+
197
200
  # Setup UILogger
198
201
  self._setup_logger()
199
202
 
@@ -203,9 +206,6 @@ class AdelieApp:
203
206
  # Wire orchestrator callbacks
204
207
  self._wire_orchestrator()
205
208
 
206
- # Start dashboard server
207
- self._start_dashboard(cfg)
208
-
209
209
  self._real_console.print("[dim]Type '/help' for a list of commands.[/dim]")
210
210
  self._real_console.print()
211
211
 
@@ -251,11 +251,11 @@ class AdelieApp:
251
251
  """Create UILogger and wire callbacks."""
252
252
  # Use the saved real console so callbacks never recurse through UILogger
253
253
  real_con = self._real_console
254
- ds = self._dashboard_state # may be None if dashboard disabled
255
254
  self._ui_logger = UILogger()
256
255
 
257
256
  def _on_agent_update(name, info):
258
257
  print_agent_event(name, info)
258
+ ds = self._dashboard_state
259
259
  if ds:
260
260
  ds.update_agent(name, {
261
261
  "state": info.state.value if hasattr(info, 'state') else str(info.state) if hasattr(info, 'state') else "idle",
@@ -265,6 +265,7 @@ class AdelieApp:
265
265
 
266
266
  def _on_log(category, obj):
267
267
  real_con.print(obj)
268
+ ds = self._dashboard_state
268
269
  if ds:
269
270
  import re
270
271
  msg = re.sub(r'\[/?[^\]]*\]', '', str(obj))
@@ -272,11 +273,13 @@ class AdelieApp:
272
273
 
273
274
  def _on_cycle_start(it, ph, st):
274
275
  print_cycle_header(it, ph, st)
276
+ ds = self._dashboard_state
275
277
  if ds:
276
278
  ds.update_cycle(it, ph, st)
277
279
 
278
280
  def _on_cycle_metrics(m):
279
281
  print_cycle_metrics(m)
282
+ ds = self._dashboard_state
280
283
  if ds:
281
284
  ds.update_metrics({
282
285
  "total_tokens": getattr(m, 'total_tokens', 0),
@@ -293,6 +296,7 @@ class AdelieApp:
293
296
  self._ui_logger.on_cycle_start = _on_cycle_start
294
297
  self._ui_logger.on_cycle_metrics = _on_cycle_metrics
295
298
 
299
+
296
300
  def _wire_orchestrator(self):
297
301
  """Wire orchestrator event callbacks."""
298
302
  def _on_agent_start(agent_name: str):
package/adelie/phases.py CHANGED
@@ -57,7 +57,7 @@ Your decision criteria in this phase:
57
57
  - Check if these KB files exist: project_vision, architecture, roadmap
58
58
  - If any are missing, request them via kb_updates_needed""",
59
59
 
60
- "transition_criteria": "Transition to MID when: roadmap.md exists, architecture is documented, and at least 5 KB files exist.",
60
+ "transition_criteria": "Transition to MID when: roadmap.md exists, architecture is documented, at least 5 KB files exist, AND at least one coder_task has been issued (even scaffolding).",
61
61
  },
62
62
 
63
63
  Phase.MID: {
@@ -160,13 +160,18 @@ Priority files:
160
160
  "expert_directive": """PHASE: MID_2 (중기 2기)
161
161
  Your decision criteria in this phase:
162
162
  - Prioritize STABILITY and OPTIMIZATION
163
- - Request deployment documentation
164
- - Check that security and performance are addressed
165
- - Use EXPORT for deployment-ready artifacts
166
- - Focus on business viability documentation
167
- - Suggest PAUSE for careful review before major deployments""",
168
-
169
- "transition_criteria": "Transition to LATE when: deployed, stable, monetization strategy documented.",
163
+ - CRITICAL: Check the 'Current Project Reality' section for actual file counts.
164
+ * If source_files = 0: treat this as MID phase — create coder_tasks to build the app.
165
+ EXPORT and PAUSE when no code exists is meaningless.
166
+ * If source_files < 5: prioritize coder_tasks to complete core implementation first.
167
+ * If source_files >= 5 and total_lines > 500: then documentation/deployment exports are appropriate.
168
+ - Request deployment documentation only AFTER code exists
169
+ - Check that security and performance are addressed in the codebase
170
+ - Use EXPORT for deployment-ready artifacts — only when the project actually has code
171
+ - Focus on business viability documentation only after implementation is underway
172
+ - Suggest PAUSE for careful review before major deployments (not before code exists)""",
173
+
174
+ "transition_criteria": "Transition to LATE when: source code exists (>5 files), deployed, stable, monetization strategy documented.",
170
175
  },
171
176
 
172
177
  Phase.LATE: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adelie-ai",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "Adelie — Self-Communicating Autonomous AI Loop CLI",
5
5
  "bin": {
6
6
  "adelie": "bin/adelie.js"