developer.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #!/usr/bin/env python3
  2. """
  3. Developer management utilities.
  4. Provides:
  5. init_developer - Initialize developer
  6. ensure_developer - Ensure developer is initialized (exit if not)
  7. show_developer_info - Show developer information
  8. """
  9. from __future__ import annotations
  10. import sys
  11. from datetime import datetime
  12. from pathlib import Path
  13. from .paths import (
  14. DIR_WORKFLOW,
  15. DIR_WORKSPACE,
  16. DIR_TASKS,
  17. FILE_DEVELOPER,
  18. FILE_JOURNAL_PREFIX,
  19. get_repo_root,
  20. get_developer,
  21. check_developer,
  22. )
  23. # =============================================================================
  24. # Developer Initialization
  25. # =============================================================================
  26. def init_developer(name: str, repo_root: Path | None = None) -> bool:
  27. """Initialize developer.
  28. Creates:
  29. - .trellis/.developer file with developer info
  30. - .trellis/workspace/<name>/ directory structure
  31. - Initial journal file and index.md
  32. Args:
  33. name: Developer name.
  34. repo_root: Repository root path. Defaults to auto-detected.
  35. Returns:
  36. True on success, False on error.
  37. """
  38. if not name:
  39. print("Error: developer name is required", file=sys.stderr)
  40. return False
  41. if repo_root is None:
  42. repo_root = get_repo_root()
  43. dev_file = repo_root / DIR_WORKFLOW / FILE_DEVELOPER
  44. workspace_dir = repo_root / DIR_WORKFLOW / DIR_WORKSPACE / name
  45. # Create .developer file
  46. initialized_at = datetime.now().isoformat()
  47. try:
  48. dev_file.write_text(
  49. f"name={name}\ninitialized_at={initialized_at}\n",
  50. encoding="utf-8"
  51. )
  52. except (OSError, IOError) as e:
  53. print(f"Error: Failed to create .developer file: {e}", file=sys.stderr)
  54. return False
  55. # Create workspace directory structure
  56. try:
  57. workspace_dir.mkdir(parents=True, exist_ok=True)
  58. except (OSError, IOError) as e:
  59. print(f"Error: Failed to create workspace directory: {e}", file=sys.stderr)
  60. return False
  61. # Create initial journal file
  62. journal_file = workspace_dir / f"{FILE_JOURNAL_PREFIX}1.md"
  63. if not journal_file.exists():
  64. today = datetime.now().strftime("%Y-%m-%d")
  65. journal_content = f"""# Journal - {name} (Part 1)
  66. > AI development session journal
  67. > Started: {today}
  68. ---
  69. """
  70. try:
  71. journal_file.write_text(journal_content, encoding="utf-8")
  72. except (OSError, IOError) as e:
  73. print(f"Error: Failed to create journal file: {e}", file=sys.stderr)
  74. return False
  75. # Create index.md with markers for auto-update
  76. index_file = workspace_dir / "index.md"
  77. if not index_file.exists():
  78. index_content = f"""# Workspace Index - {name}
  79. > Journal tracking for AI development sessions.
  80. ---
  81. ## Current Status
  82. <!-- @@@auto:current-status -->
  83. - **Active File**: `journal-1.md`
  84. - **Total Sessions**: 0
  85. - **Last Active**: -
  86. <!-- @@@/auto:current-status -->
  87. ---
  88. ## Active Documents
  89. <!-- @@@auto:active-documents -->
  90. | File | Lines | Status |
  91. |------|-------|--------|
  92. | `journal-1.md` | ~0 | Active |
  93. <!-- @@@/auto:active-documents -->
  94. ---
  95. ## Session History
  96. <!-- @@@auto:session-history -->
  97. | # | Date | Title | Commits | Branch |
  98. |---|------|-------|---------|--------|
  99. <!-- @@@/auto:session-history -->
  100. ---
  101. ## Notes
  102. - Sessions are appended to journal files
  103. - New journal file created when current exceeds 2000 lines
  104. - Use `add_session.py` to record sessions
  105. """
  106. try:
  107. index_file.write_text(index_content, encoding="utf-8")
  108. except (OSError, IOError) as e:
  109. print(f"Error: Failed to create index.md: {e}", file=sys.stderr)
  110. return False
  111. print(f"Developer initialized: {name}")
  112. print(f" .developer file: {dev_file}")
  113. print(f" Workspace dir: {workspace_dir}")
  114. return True
  115. def ensure_developer(repo_root: Path | None = None) -> None:
  116. """Ensure developer is initialized, exit if not.
  117. Args:
  118. repo_root: Repository root path. Defaults to auto-detected.
  119. """
  120. if repo_root is None:
  121. repo_root = get_repo_root()
  122. if not check_developer(repo_root):
  123. print("Error: Developer not initialized.", file=sys.stderr)
  124. print(f"Run: python3 ./{DIR_WORKFLOW}/scripts/init_developer.py <your-name>", file=sys.stderr)
  125. sys.exit(1)
  126. def show_developer_info(repo_root: Path | None = None) -> None:
  127. """Show developer information.
  128. Args:
  129. repo_root: Repository root path. Defaults to auto-detected.
  130. """
  131. if repo_root is None:
  132. repo_root = get_repo_root()
  133. developer = get_developer(repo_root)
  134. if not developer:
  135. print("Developer: (not initialized)")
  136. else:
  137. print(f"Developer: {developer}")
  138. print(f"Workspace: {DIR_WORKFLOW}/{DIR_WORKSPACE}/{developer}/")
  139. print(f"Tasks: {DIR_WORKFLOW}/{DIR_TASKS}/")
  140. # =============================================================================
  141. # Main Entry (for testing)
  142. # =============================================================================
  143. if __name__ == "__main__":
  144. show_developer_info()