@mindfoldhq/trellis 0.6.0-beta.8 → 0.6.0-rc.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.
- package/README.md +49 -49
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +59 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/channel/adapters/claude.d.ts +29 -0
- package/dist/commands/channel/adapters/claude.d.ts.map +1 -0
- package/dist/commands/channel/adapters/claude.js +203 -0
- package/dist/commands/channel/adapters/claude.js.map +1 -0
- package/dist/commands/channel/adapters/codex.d.ts +85 -0
- package/dist/commands/channel/adapters/codex.d.ts.map +1 -0
- package/dist/commands/channel/adapters/codex.js +505 -0
- package/dist/commands/channel/adapters/codex.js.map +1 -0
- package/dist/commands/channel/adapters/index.d.ts +84 -0
- package/dist/commands/channel/adapters/index.d.ts.map +1 -0
- package/dist/commands/channel/adapters/index.js +115 -0
- package/dist/commands/channel/adapters/index.js.map +1 -0
- package/dist/commands/channel/adapters/types.d.ts +33 -0
- package/dist/commands/channel/adapters/types.d.ts.map +1 -0
- package/dist/commands/channel/adapters/types.js +2 -0
- package/dist/commands/channel/adapters/types.js.map +1 -0
- package/dist/commands/channel/agent-loader.d.ts +32 -0
- package/dist/commands/channel/agent-loader.d.ts.map +1 -0
- package/dist/commands/channel/agent-loader.js +154 -0
- package/dist/commands/channel/agent-loader.js.map +1 -0
- package/dist/commands/channel/context-loader.d.ts +26 -0
- package/dist/commands/channel/context-loader.d.ts.map +1 -0
- package/dist/commands/channel/context-loader.js +290 -0
- package/dist/commands/channel/context-loader.js.map +1 -0
- package/dist/commands/channel/context.d.ts +16 -0
- package/dist/commands/channel/context.d.ts.map +1 -0
- package/dist/commands/channel/context.js +83 -0
- package/dist/commands/channel/context.js.map +1 -0
- package/dist/commands/channel/create.d.ts +27 -0
- package/dist/commands/channel/create.d.ts.map +1 -0
- package/dist/commands/channel/create.js +39 -0
- package/dist/commands/channel/create.js.map +1 -0
- package/dist/commands/channel/dev-parse-trace.d.ts +14 -0
- package/dist/commands/channel/dev-parse-trace.d.ts.map +1 -0
- package/dist/commands/channel/dev-parse-trace.js +70 -0
- package/dist/commands/channel/dev-parse-trace.js.map +1 -0
- package/dist/commands/channel/guard.d.ts +150 -0
- package/dist/commands/channel/guard.d.ts.map +1 -0
- package/dist/commands/channel/guard.js +474 -0
- package/dist/commands/channel/guard.js.map +1 -0
- package/dist/commands/channel/index.d.ts +3 -0
- package/dist/commands/channel/index.d.ts.map +1 -0
- package/dist/commands/channel/index.js +531 -0
- package/dist/commands/channel/index.js.map +1 -0
- package/dist/commands/channel/interrupt.d.ts +10 -0
- package/dist/commands/channel/interrupt.d.ts.map +1 -0
- package/dist/commands/channel/interrupt.js +22 -0
- package/dist/commands/channel/interrupt.js.map +1 -0
- package/dist/commands/channel/kill.d.ts +7 -0
- package/dist/commands/channel/kill.d.ts.map +1 -0
- package/dist/commands/channel/kill.js +121 -0
- package/dist/commands/channel/kill.js.map +1 -0
- package/dist/commands/channel/list.d.ts +17 -0
- package/dist/commands/channel/list.d.ts.map +1 -0
- package/dist/commands/channel/list.js +233 -0
- package/dist/commands/channel/list.js.map +1 -0
- package/dist/commands/channel/messages.d.ts +15 -0
- package/dist/commands/channel/messages.d.ts.map +1 -0
- package/dist/commands/channel/messages.js +245 -0
- package/dist/commands/channel/messages.js.map +1 -0
- package/dist/commands/channel/rm.d.ts +27 -0
- package/dist/commands/channel/rm.d.ts.map +1 -0
- package/dist/commands/channel/rm.js +216 -0
- package/dist/commands/channel/rm.js.map +1 -0
- package/dist/commands/channel/run.d.ts +30 -0
- package/dist/commands/channel/run.d.ts.map +1 -0
- package/dist/commands/channel/run.js +130 -0
- package/dist/commands/channel/run.js.map +1 -0
- package/dist/commands/channel/send.d.ts +11 -0
- package/dist/commands/channel/send.d.ts.map +1 -0
- package/dist/commands/channel/send.js +24 -0
- package/dist/commands/channel/send.js.map +1 -0
- package/dist/commands/channel/spawn.d.ts +40 -0
- package/dist/commands/channel/spawn.d.ts.map +1 -0
- package/dist/commands/channel/spawn.js +244 -0
- package/dist/commands/channel/spawn.js.map +1 -0
- package/dist/commands/channel/store/events.d.ts +39 -0
- package/dist/commands/channel/store/events.d.ts.map +1 -0
- package/dist/commands/channel/store/events.js +87 -0
- package/dist/commands/channel/store/events.js.map +1 -0
- package/dist/commands/channel/store/filter.d.ts +3 -0
- package/dist/commands/channel/store/filter.d.ts.map +1 -0
- package/dist/commands/channel/store/filter.js +2 -0
- package/dist/commands/channel/store/filter.js.map +1 -0
- package/dist/commands/channel/store/lock.d.ts +23 -0
- package/dist/commands/channel/store/lock.d.ts.map +1 -0
- package/dist/commands/channel/store/lock.js +99 -0
- package/dist/commands/channel/store/lock.js.map +1 -0
- package/dist/commands/channel/store/paths.d.ts +63 -0
- package/dist/commands/channel/store/paths.d.ts.map +1 -0
- package/dist/commands/channel/store/paths.js +246 -0
- package/dist/commands/channel/store/paths.js.map +1 -0
- package/dist/commands/channel/store/schema.d.ts +27 -0
- package/dist/commands/channel/store/schema.d.ts.map +1 -0
- package/dist/commands/channel/store/schema.js +34 -0
- package/dist/commands/channel/store/schema.js.map +1 -0
- package/dist/commands/channel/store/thread-state.d.ts +5 -0
- package/dist/commands/channel/store/thread-state.d.ts.map +1 -0
- package/dist/commands/channel/store/thread-state.js +16 -0
- package/dist/commands/channel/store/thread-state.js.map +1 -0
- package/dist/commands/channel/store/watch.d.ts +19 -0
- package/dist/commands/channel/store/watch.d.ts.map +1 -0
- package/dist/commands/channel/store/watch.js +146 -0
- package/dist/commands/channel/store/watch.js.map +1 -0
- package/dist/commands/channel/supervisor/idle.d.ts +46 -0
- package/dist/commands/channel/supervisor/idle.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/idle.js +72 -0
- package/dist/commands/channel/supervisor/idle.js.map +1 -0
- package/dist/commands/channel/supervisor/inbox.d.ts +30 -0
- package/dist/commands/channel/supervisor/inbox.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/inbox.js +160 -0
- package/dist/commands/channel/supervisor/inbox.js.map +1 -0
- package/dist/commands/channel/supervisor/shutdown.d.ts +68 -0
- package/dist/commands/channel/supervisor/shutdown.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/shutdown.js +146 -0
- package/dist/commands/channel/supervisor/shutdown.js.map +1 -0
- package/dist/commands/channel/supervisor/stdout.d.ts +51 -0
- package/dist/commands/channel/supervisor/stdout.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/stdout.js +121 -0
- package/dist/commands/channel/supervisor/stdout.js.map +1 -0
- package/dist/commands/channel/supervisor/turns.d.ts +31 -0
- package/dist/commands/channel/supervisor/turns.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/turns.js +45 -0
- package/dist/commands/channel/supervisor/turns.js.map +1 -0
- package/dist/commands/channel/supervisor/warning.d.ts +48 -0
- package/dist/commands/channel/supervisor/warning.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/warning.js +77 -0
- package/dist/commands/channel/supervisor/warning.js.map +1 -0
- package/dist/commands/channel/supervisor.d.ts +59 -0
- package/dist/commands/channel/supervisor.d.ts.map +1 -0
- package/dist/commands/channel/supervisor.js +344 -0
- package/dist/commands/channel/supervisor.js.map +1 -0
- package/dist/commands/channel/text-body.d.ts +13 -0
- package/dist/commands/channel/text-body.d.ts.map +1 -0
- package/dist/commands/channel/text-body.js +47 -0
- package/dist/commands/channel/text-body.js.map +1 -0
- package/dist/commands/channel/threads.d.ts +39 -0
- package/dist/commands/channel/threads.d.ts.map +1 -0
- package/dist/commands/channel/threads.js +106 -0
- package/dist/commands/channel/threads.js.map +1 -0
- package/dist/commands/channel/title.d.ts +12 -0
- package/dist/commands/channel/title.d.ts.map +1 -0
- package/dist/commands/channel/title.js +24 -0
- package/dist/commands/channel/title.js.map +1 -0
- package/dist/commands/channel/wait.d.ts +17 -0
- package/dist/commands/channel/wait.d.ts.map +1 -0
- package/dist/commands/channel/wait.js +75 -0
- package/dist/commands/channel/wait.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +162 -43
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mem.d.ts +13 -217
- package/dist/commands/mem.d.ts.map +1 -1
- package/dist/commands/mem.js +142 -1587
- package/dist/commands/mem.js.map +1 -1
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/uninstall.js +28 -2
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +104 -7
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/upgrade.d.ts +28 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +84 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/commands/workflow.d.ts +35 -0
- package/dist/commands/workflow.d.ts.map +1 -0
- package/dist/commands/workflow.js +232 -0
- package/dist/commands/workflow.js.map +1 -0
- package/dist/configurators/claude.d.ts.map +1 -1
- package/dist/configurators/claude.js +1 -0
- package/dist/configurators/claude.js.map +1 -1
- package/dist/configurators/index.d.ts.map +1 -1
- package/dist/configurators/index.js +5 -0
- package/dist/configurators/index.js.map +1 -1
- package/dist/configurators/reasonix.d.ts +23 -0
- package/dist/configurators/reasonix.d.ts.map +1 -0
- package/dist/configurators/reasonix.js +60 -0
- package/dist/configurators/reasonix.js.map +1 -0
- package/dist/configurators/shared.d.ts.map +1 -1
- package/dist/configurators/shared.js +8 -0
- package/dist/configurators/shared.js.map +1 -1
- package/dist/configurators/workflow.d.ts +8 -0
- package/dist/configurators/workflow.d.ts.map +1 -1
- package/dist/configurators/workflow.js +14 -3
- package/dist/configurators/workflow.js.map +1 -1
- package/dist/constants/paths.d.ts +4 -0
- package/dist/constants/paths.d.ts.map +1 -1
- package/dist/constants/paths.js +4 -0
- package/dist/constants/paths.js.map +1 -1
- package/dist/migrations/manifests/0.5.13.json +9 -0
- package/dist/migrations/manifests/0.5.14.json +9 -0
- package/dist/migrations/manifests/0.5.15.json +9 -0
- package/dist/migrations/manifests/0.5.16.json +9 -0
- package/dist/migrations/manifests/0.5.17.json +9 -0
- package/dist/migrations/manifests/0.5.18.json +9 -0
- package/dist/migrations/manifests/0.5.19.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.11.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.12.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.13.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.14.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.15.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.16.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.17.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.18.json +16 -0
- package/dist/migrations/manifests/0.6.0-beta.19.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.20.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.21.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.22.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.23.json +88 -0
- package/dist/migrations/manifests/0.6.0-beta.9.json +9 -0
- package/dist/migrations/manifests/0.6.0-rc.0.json +9 -0
- package/dist/templates/claude/agents/trellis-check.md +12 -6
- package/dist/templates/claude/agents/trellis-implement.md +1 -1
- package/dist/templates/claude/agents/trellis-research.md +1 -1
- package/dist/templates/claude/settings.json +4 -4
- package/dist/templates/codebuddy/agents/trellis-check.md +12 -6
- package/dist/templates/codebuddy/agents/trellis-implement.md +1 -1
- package/dist/templates/codebuddy/agents/trellis-research.md +1 -1
- package/dist/templates/codebuddy/settings.json +4 -4
- package/dist/templates/codex/agents/trellis-check.toml +0 -25
- package/dist/templates/codex/agents/trellis-implement.toml +0 -25
- package/dist/templates/codex/config.toml +9 -16
- package/dist/templates/codex/hooks/session-start.py +22 -0
- package/dist/templates/codex/hooks.json +2 -2
- package/dist/templates/codex/skills/brainstorm/SKILL.md +69 -519
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +27 -0
- package/dist/templates/common/bundled-skills/trellis-session-insight/SKILL.md +81 -0
- package/dist/templates/common/bundled-skills/trellis-session-insight/references/cli-quick-reference.md +66 -0
- package/dist/templates/common/bundled-skills/trellis-session-insight/references/triggering-patterns.md +93 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/SKILL.md +41 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/mcp-setup.md +90 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/repository-analysis.md +59 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/spec-task-planning.md +61 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/spec-writing.md +70 -0
- package/dist/templates/common/skills/brainstorm.md +68 -518
- package/dist/templates/copilot/hooks/session-start.py +36 -11
- package/dist/templates/copilot/hooks.json +2 -2
- package/dist/templates/copilot/prompts/brainstorm.prompt.md +69 -519
- package/dist/templates/cursor/agents/trellis-check.md +12 -6
- package/dist/templates/cursor/agents/trellis-implement.md +1 -1
- package/dist/templates/cursor/agents/trellis-research.md +1 -1
- package/dist/templates/cursor/hooks.json +1 -7
- package/dist/templates/droid/droids/trellis-check.md +12 -6
- package/dist/templates/droid/droids/trellis-implement.md +1 -1
- package/dist/templates/droid/droids/trellis-research.md +1 -1
- package/dist/templates/droid/settings.json +4 -4
- package/dist/templates/gemini/agents/trellis-check.md +11 -5
- package/dist/templates/gemini/settings.json +2 -2
- package/dist/templates/kiro/agents/trellis-check.json +1 -1
- package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +127 -9
- package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +171 -6
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +48 -4
- package/dist/templates/markdown/spec/guides/index.md.txt +18 -0
- package/dist/templates/opencode/agents/trellis-check.md +11 -5
- package/dist/templates/opencode/lib/trellis-context.js +73 -11
- package/dist/templates/opencode/plugins/inject-subagent-context.js +112 -26
- package/dist/templates/opencode/plugins/inject-workflow-state.js +8 -1
- package/dist/templates/opencode/plugins/session-start.js +9 -1
- package/dist/templates/pi/agents/trellis-check.md +5 -4
- package/dist/templates/pi/agents/trellis-implement.md +5 -4
- package/dist/templates/pi/extensions/trellis/index.ts.txt +1339 -913
- package/dist/templates/pi/settings.json +0 -9
- package/dist/templates/qoder/agents/trellis-check.md +12 -6
- package/dist/templates/qoder/agents/trellis-implement.md +1 -1
- package/dist/templates/qoder/agents/trellis-research.md +1 -1
- package/dist/templates/qoder/settings.json +4 -4
- package/dist/templates/reasonix/agents/trellis-check.md +36 -0
- package/dist/templates/reasonix/agents/trellis-implement.md +41 -0
- package/dist/templates/reasonix/index.d.ts +13 -0
- package/dist/templates/reasonix/index.d.ts.map +1 -0
- package/dist/templates/reasonix/index.js +16 -0
- package/dist/templates/reasonix/index.js.map +1 -0
- package/dist/templates/shared-hooks/index.d.ts.map +1 -1
- package/dist/templates/shared-hooks/index.js +0 -1
- package/dist/templates/shared-hooks/index.js.map +1 -1
- package/dist/templates/shared-hooks/inject-workflow-state.py +22 -0
- package/dist/templates/shared-hooks/session-start.py +25 -8
- package/dist/templates/trellis/agents/check.md +70 -0
- package/dist/templates/trellis/agents/implement.md +71 -0
- package/dist/templates/trellis/config.yaml +20 -0
- package/dist/templates/trellis/index.d.ts +13 -0
- package/dist/templates/trellis/index.d.ts.map +1 -1
- package/dist/templates/trellis/index.js +22 -0
- package/dist/templates/trellis/index.js.map +1 -1
- package/dist/templates/trellis/scripts/common/safe_commit.py +49 -19
- package/dist/templates/trellis/scripts/common/session_context.py +215 -138
- package/dist/templates/trellis/scripts/common/task_store.py +94 -16
- package/dist/templates/trellis/workflow.md +21 -0
- package/dist/types/ai-tools.d.ts +4 -4
- package/dist/types/ai-tools.d.ts.map +1 -1
- package/dist/types/ai-tools.js +16 -0
- package/dist/types/ai-tools.js.map +1 -1
- package/dist/utils/agent-refs.d.ts +31 -0
- package/dist/utils/agent-refs.d.ts.map +1 -0
- package/dist/utils/agent-refs.js +63 -0
- package/dist/utils/agent-refs.js.map +1 -0
- package/dist/utils/cwd-guard.d.ts +38 -0
- package/dist/utils/cwd-guard.d.ts.map +1 -0
- package/dist/utils/cwd-guard.js +62 -0
- package/dist/utils/cwd-guard.js.map +1 -0
- package/dist/utils/file-writer.d.ts +13 -0
- package/dist/utils/file-writer.d.ts.map +1 -1
- package/dist/utils/file-writer.js +59 -1
- package/dist/utils/file-writer.js.map +1 -1
- package/dist/utils/manifest-prune.d.ts +61 -0
- package/dist/utils/manifest-prune.d.ts.map +1 -0
- package/dist/utils/manifest-prune.js +136 -0
- package/dist/utils/manifest-prune.js.map +1 -0
- package/dist/utils/registry-config.d.ts +7 -0
- package/dist/utils/registry-config.d.ts.map +1 -0
- package/dist/utils/registry-config.js +171 -0
- package/dist/utils/registry-config.js.map +1 -0
- package/dist/utils/task-json.d.ts +9 -42
- package/dist/utils/task-json.d.ts.map +1 -1
- package/dist/utils/task-json.js +8 -45
- package/dist/utils/task-json.js.map +1 -1
- package/dist/utils/template-fetcher.d.ts +11 -0
- package/dist/utils/template-fetcher.d.ts.map +1 -1
- package/dist/utils/template-fetcher.js +51 -2
- package/dist/utils/template-fetcher.js.map +1 -1
- package/dist/utils/template-hash.d.ts +32 -6
- package/dist/utils/template-hash.d.ts.map +1 -1
- package/dist/utils/template-hash.js +53 -31
- package/dist/utils/template-hash.js.map +1 -1
- package/dist/utils/workflow-resolver.d.ts +86 -0
- package/dist/utils/workflow-resolver.d.ts.map +1 -0
- package/dist/utils/workflow-resolver.js +265 -0
- package/dist/utils/workflow-resolver.js.map +1 -0
- package/package.json +9 -8
|
@@ -111,31 +111,61 @@ def safe_trellis_paths_to_add(repo_root: Path) -> list[str]:
|
|
|
111
111
|
return paths
|
|
112
112
|
|
|
113
113
|
|
|
114
|
-
def safe_archive_paths_to_add(
|
|
114
|
+
def safe_archive_paths_to_add(
|
|
115
|
+
repo_root: Path,
|
|
116
|
+
task_name: str | None = None,
|
|
117
|
+
modified_children: list[str] | None = None,
|
|
118
|
+
) -> list[str]:
|
|
115
119
|
"""Return paths to stage after `task.py archive`.
|
|
116
120
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
Scoped to ONLY the paths the archive operation actually touched:
|
|
122
|
+
|
|
123
|
+
- the archive subtree (where the freshly-moved task lives)
|
|
124
|
+
- the source task directory (for source-side deletes; caller pairs
|
|
125
|
+
this with `git rm --cached` since `git add` won't stage deletes
|
|
126
|
+
for a path that no longer exists in the working tree)
|
|
127
|
+
- any child task directories whose `task.json` was edited to drop
|
|
128
|
+
the archived parent (parent-children relationship update)
|
|
129
|
+
|
|
130
|
+
This narrow scope avoids "scope creep" — dirty changes in OTHER
|
|
131
|
+
active task dirs (parallel-window edits) are NOT bundled into the
|
|
132
|
+
archive commit. Callers handle each kind of change in its own
|
|
133
|
+
commit boundary.
|
|
134
|
+
|
|
135
|
+
Backwards-compat: with no arguments, the function walks the whole
|
|
136
|
+
`.trellis/tasks/` subtree the old way (active tasks + archive). New
|
|
137
|
+
callers should always pass `task_name`.
|
|
122
138
|
"""
|
|
123
139
|
paths: list[str] = []
|
|
124
140
|
tasks_dir = repo_root / DIR_WORKFLOW / DIR_TASKS
|
|
125
|
-
if tasks_dir.is_dir():
|
|
126
|
-
|
|
127
|
-
|
|
141
|
+
if not tasks_dir.is_dir():
|
|
142
|
+
return paths
|
|
143
|
+
|
|
144
|
+
archive_dir = tasks_dir / DIR_ARCHIVE
|
|
145
|
+
|
|
146
|
+
if task_name is not None:
|
|
147
|
+
# Narrow scope — only paths that still exist on disk (so
|
|
148
|
+
# `git add` doesn't choke on the moved-away source). The caller
|
|
149
|
+
# handles the source-side deletes via `git rm --cached`
|
|
150
|
+
# explicitly.
|
|
128
151
|
if archive_dir.is_dir():
|
|
129
|
-
paths.append(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
152
|
+
paths.append(
|
|
153
|
+
f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}"
|
|
154
|
+
)
|
|
155
|
+
for child_name in modified_children or []:
|
|
156
|
+
paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{child_name}")
|
|
157
|
+
return paths
|
|
158
|
+
|
|
159
|
+
# Legacy wide scope (no task_name): preserve old behavior so callers
|
|
160
|
+
# that have not been updated keep working.
|
|
161
|
+
if archive_dir.is_dir():
|
|
162
|
+
paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}")
|
|
163
|
+
for child in sorted(tasks_dir.iterdir()):
|
|
164
|
+
if not child.is_dir():
|
|
165
|
+
continue
|
|
166
|
+
if child.name == DIR_ARCHIVE:
|
|
167
|
+
continue
|
|
168
|
+
paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{child.name}")
|
|
139
169
|
return paths
|
|
140
170
|
|
|
141
171
|
|
|
@@ -50,12 +50,140 @@ _VERSION_RE = re.compile(
|
|
|
50
50
|
r"^\s*(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-([0-9A-Za-z.-]+))?\s*$"
|
|
51
51
|
)
|
|
52
52
|
_VERSION_TOKEN_RE = re.compile(r"\b\d+(?:\.\d+){1,2}(?:-[0-9A-Za-z.-]+)?\b")
|
|
53
|
+
_POLYREPO_IGNORED_DIRS = {
|
|
54
|
+
"node_modules",
|
|
55
|
+
"target",
|
|
56
|
+
"dist",
|
|
57
|
+
"build",
|
|
58
|
+
"out",
|
|
59
|
+
"bin",
|
|
60
|
+
"obj",
|
|
61
|
+
"vendor",
|
|
62
|
+
"coverage",
|
|
63
|
+
"tmp",
|
|
64
|
+
"__pycache__",
|
|
65
|
+
}
|
|
66
|
+
_POLYREPO_SCAN_MAX_DEPTH = 2
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _is_git_worktree(path: Path) -> bool:
|
|
70
|
+
"""Return True when path is inside a Git worktree."""
|
|
71
|
+
rc, out, _ = run_git(["rev-parse", "--is-inside-work-tree"], cwd=path)
|
|
72
|
+
return rc == 0 and out.strip().lower() == "true"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _parse_recent_commits(log_output: str) -> list[dict]:
|
|
76
|
+
"""Parse `git log --oneline` output into structured commit entries."""
|
|
77
|
+
commits = []
|
|
78
|
+
for line in log_output.splitlines():
|
|
79
|
+
if not line.strip():
|
|
80
|
+
continue
|
|
81
|
+
parts = line.split(" ", 1)
|
|
82
|
+
if len(parts) >= 2:
|
|
83
|
+
commits.append({"hash": parts[0], "message": parts[1]})
|
|
84
|
+
elif len(parts) == 1:
|
|
85
|
+
commits.append({"hash": parts[0], "message": ""})
|
|
86
|
+
return commits
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _collect_git_repo_info(name: str, rel_path: str, repo_dir: Path) -> dict | None:
|
|
90
|
+
"""Collect Git status for one known repository directory."""
|
|
91
|
+
if not (repo_dir / ".git").exists():
|
|
92
|
+
return None
|
|
93
|
+
|
|
94
|
+
_, branch_out, _ = run_git(["branch", "--show-current"], cwd=repo_dir)
|
|
95
|
+
branch = branch_out.strip() or "unknown"
|
|
96
|
+
|
|
97
|
+
_, status_out, _ = run_git(["status", "--porcelain"], cwd=repo_dir)
|
|
98
|
+
changes = len([l for l in status_out.splitlines() if l.strip()])
|
|
99
|
+
|
|
100
|
+
_, log_out, _ = run_git(["log", "--oneline", "-5"], cwd=repo_dir)
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
"name": name,
|
|
104
|
+
"path": rel_path,
|
|
105
|
+
"branch": branch,
|
|
106
|
+
"isClean": changes == 0,
|
|
107
|
+
"uncommittedChanges": changes,
|
|
108
|
+
"recentCommits": _parse_recent_commits(log_out),
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _collect_root_git_info(repo_root: Path) -> dict:
|
|
113
|
+
"""Collect root Git info without pretending a non-Git root is clean."""
|
|
114
|
+
if not _is_git_worktree(repo_root):
|
|
115
|
+
return {
|
|
116
|
+
"isRepo": False,
|
|
117
|
+
"branch": "",
|
|
118
|
+
"isClean": False,
|
|
119
|
+
"uncommittedChanges": 0,
|
|
120
|
+
"recentCommits": [],
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
_, branch_out, _ = run_git(["branch", "--show-current"], cwd=repo_root)
|
|
124
|
+
branch = branch_out.strip() or "unknown"
|
|
125
|
+
|
|
126
|
+
_, status_out, _ = run_git(["status", "--porcelain"], cwd=repo_root)
|
|
127
|
+
status_lines = [line for line in status_out.splitlines() if line.strip()]
|
|
128
|
+
|
|
129
|
+
_, short_out, _ = run_git(["status", "--short"], cwd=repo_root)
|
|
130
|
+
|
|
131
|
+
_, log_out, _ = run_git(["log", "--oneline", "-5"], cwd=repo_root)
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
"isRepo": True,
|
|
135
|
+
"branch": branch,
|
|
136
|
+
"isClean": len(status_lines) == 0,
|
|
137
|
+
"uncommittedChanges": len(status_lines),
|
|
138
|
+
"statusShort": short_out.splitlines(),
|
|
139
|
+
"recentCommits": _parse_recent_commits(log_out),
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _discover_child_git_repos(repo_root: Path) -> list[tuple[str, str]]:
|
|
144
|
+
"""Discover child Git repositories using the init-time polyrepo heuristic."""
|
|
145
|
+
found: list[str] = []
|
|
53
146
|
|
|
147
|
+
def is_candidate_dir(path: Path) -> bool:
|
|
148
|
+
name = path.name
|
|
149
|
+
return not name.startswith(".") and name not in _POLYREPO_IGNORED_DIRS
|
|
54
150
|
|
|
55
|
-
def
|
|
56
|
-
|
|
151
|
+
def scan(rel_dir: Path, depth: int) -> None:
|
|
152
|
+
if depth >= _POLYREPO_SCAN_MAX_DEPTH:
|
|
153
|
+
return
|
|
154
|
+
abs_dir = repo_root / rel_dir
|
|
155
|
+
try:
|
|
156
|
+
children = sorted(abs_dir.iterdir(), key=lambda p: p.name)
|
|
157
|
+
except OSError:
|
|
158
|
+
return
|
|
57
159
|
|
|
58
|
-
|
|
160
|
+
for child in children:
|
|
161
|
+
if not child.is_dir() or not is_candidate_dir(child):
|
|
162
|
+
continue
|
|
163
|
+
|
|
164
|
+
child_rel = (
|
|
165
|
+
rel_dir / child.name if rel_dir != Path(".") else Path(child.name)
|
|
166
|
+
)
|
|
167
|
+
if (child / ".git").exists():
|
|
168
|
+
found.append(child_rel.as_posix())
|
|
169
|
+
continue
|
|
170
|
+
scan(child_rel, depth + 1)
|
|
171
|
+
|
|
172
|
+
scan(Path("."), 0)
|
|
173
|
+
if len(found) < 2:
|
|
174
|
+
return []
|
|
175
|
+
return [(path.replace("/", "_"), path) for path in sorted(found)]
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def _collect_package_git_info(
|
|
179
|
+
repo_root: Path,
|
|
180
|
+
discover_unconfigured: bool = False,
|
|
181
|
+
) -> list[dict]:
|
|
182
|
+
"""Collect Git status for independent package repositories.
|
|
183
|
+
|
|
184
|
+
Packages marked with ``git: true`` in config.yaml are authoritative.
|
|
185
|
+
When the Trellis root is not a Git repo and no configured package repos are
|
|
186
|
+
available, optionally fall back to the bounded polyrepo child scan.
|
|
59
187
|
|
|
60
188
|
Returns:
|
|
61
189
|
List of dicts with keys: name, path, branch, isClean,
|
|
@@ -63,41 +191,56 @@ def _collect_package_git_info(repo_root: Path) -> list[dict]:
|
|
|
63
191
|
Empty list if no git-repo packages are configured.
|
|
64
192
|
"""
|
|
65
193
|
git_pkgs = get_git_packages(repo_root)
|
|
66
|
-
if not git_pkgs:
|
|
67
|
-
return []
|
|
68
|
-
|
|
69
194
|
result = []
|
|
70
195
|
for pkg_name, pkg_path in git_pkgs.items():
|
|
71
196
|
pkg_dir = repo_root / pkg_path
|
|
72
|
-
|
|
73
|
-
|
|
197
|
+
info = _collect_git_repo_info(pkg_name, pkg_path, pkg_dir)
|
|
198
|
+
if info is not None:
|
|
199
|
+
result.append(info)
|
|
74
200
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if line.strip():
|
|
85
|
-
parts = line.split(" ", 1)
|
|
86
|
-
if len(parts) >= 2:
|
|
87
|
-
commits.append({"hash": parts[0], "message": parts[1]})
|
|
88
|
-
elif len(parts) == 1:
|
|
89
|
-
commits.append({"hash": parts[0], "message": ""})
|
|
90
|
-
|
|
91
|
-
result.append({
|
|
92
|
-
"name": pkg_name,
|
|
93
|
-
"path": pkg_path,
|
|
94
|
-
"branch": branch,
|
|
95
|
-
"isClean": changes == 0,
|
|
96
|
-
"uncommittedChanges": changes,
|
|
97
|
-
"recentCommits": commits,
|
|
98
|
-
})
|
|
201
|
+
if result or not discover_unconfigured:
|
|
202
|
+
return result
|
|
203
|
+
|
|
204
|
+
discovered = []
|
|
205
|
+
for pkg_name, pkg_path in _discover_child_git_repos(repo_root):
|
|
206
|
+
info = _collect_git_repo_info(pkg_name, pkg_path, repo_root / pkg_path)
|
|
207
|
+
if info is not None:
|
|
208
|
+
discovered.append(info)
|
|
209
|
+
return discovered
|
|
99
210
|
|
|
100
|
-
|
|
211
|
+
|
|
212
|
+
def _append_root_git_context(lines: list[str], root_git_info: dict) -> None:
|
|
213
|
+
"""Append root Git status without misleading non-Git roots."""
|
|
214
|
+
lines.append("## GIT STATUS")
|
|
215
|
+
if not root_git_info["isRepo"]:
|
|
216
|
+
lines.append("Root is not a Git repository.")
|
|
217
|
+
lines.append("Run Git commands from the package repository paths listed below.")
|
|
218
|
+
else:
|
|
219
|
+
lines.append(f"Branch: {root_git_info['branch']}")
|
|
220
|
+
if root_git_info["isClean"]:
|
|
221
|
+
lines.append("Working directory: Clean")
|
|
222
|
+
else:
|
|
223
|
+
lines.append(
|
|
224
|
+
f"Working directory: {root_git_info['uncommittedChanges']} "
|
|
225
|
+
"uncommitted change(s)"
|
|
226
|
+
)
|
|
227
|
+
lines.append("")
|
|
228
|
+
lines.append("Changes:")
|
|
229
|
+
for line in root_git_info.get("statusShort", [])[:10]:
|
|
230
|
+
lines.append(line)
|
|
231
|
+
lines.append("")
|
|
232
|
+
|
|
233
|
+
lines.append("## RECENT COMMITS")
|
|
234
|
+
if not root_git_info["isRepo"]:
|
|
235
|
+
lines.append(
|
|
236
|
+
"Root has no Git commit history because it is not a Git repository."
|
|
237
|
+
)
|
|
238
|
+
elif root_git_info["recentCommits"]:
|
|
239
|
+
for commit in root_git_info["recentCommits"]:
|
|
240
|
+
lines.append(f"{commit['hash']} {commit['message']}")
|
|
241
|
+
else:
|
|
242
|
+
lines.append("(no commits)")
|
|
243
|
+
lines.append("")
|
|
101
244
|
|
|
102
245
|
|
|
103
246
|
def _append_package_git_context(lines: list[str], package_git_info: list[dict]) -> None:
|
|
@@ -269,7 +412,7 @@ def _get_update_hint(repo_root: Path) -> str | None:
|
|
|
269
412
|
|
|
270
413
|
return (
|
|
271
414
|
f"Trellis update available: {current_version} -> {latest_version}, "
|
|
272
|
-
|
|
415
|
+
"run trellis upgrade"
|
|
273
416
|
)
|
|
274
417
|
|
|
275
418
|
|
|
@@ -301,24 +444,7 @@ def get_context_json(repo_root: Path | None = None) -> dict:
|
|
|
301
444
|
f"{DIR_WORKFLOW}/{DIR_WORKSPACE}/{developer}/{journal_file.name}"
|
|
302
445
|
)
|
|
303
446
|
|
|
304
|
-
|
|
305
|
-
_, branch_out, _ = run_git(["branch", "--show-current"], cwd=repo_root)
|
|
306
|
-
branch = branch_out.strip() or "unknown"
|
|
307
|
-
|
|
308
|
-
_, status_out, _ = run_git(["status", "--porcelain"], cwd=repo_root)
|
|
309
|
-
git_status_count = len([line for line in status_out.splitlines() if line.strip()])
|
|
310
|
-
is_clean = git_status_count == 0
|
|
311
|
-
|
|
312
|
-
# Recent commits
|
|
313
|
-
_, log_out, _ = run_git(["log", "--oneline", "-5"], cwd=repo_root)
|
|
314
|
-
commits = []
|
|
315
|
-
for line in log_out.splitlines():
|
|
316
|
-
if line.strip():
|
|
317
|
-
parts = line.split(" ", 1)
|
|
318
|
-
if len(parts) >= 2:
|
|
319
|
-
commits.append({"hash": parts[0], "message": parts[1]})
|
|
320
|
-
elif len(parts) == 1:
|
|
321
|
-
commits.append({"hash": parts[0], "message": ""})
|
|
447
|
+
root_git_info = _collect_root_git_info(repo_root)
|
|
322
448
|
|
|
323
449
|
# Tasks
|
|
324
450
|
tasks = [
|
|
@@ -333,15 +459,19 @@ def get_context_json(repo_root: Path | None = None) -> dict:
|
|
|
333
459
|
]
|
|
334
460
|
|
|
335
461
|
# Package git repos (independent sub-repositories)
|
|
336
|
-
pkg_git_info = _collect_package_git_info(
|
|
462
|
+
pkg_git_info = _collect_package_git_info(
|
|
463
|
+
repo_root,
|
|
464
|
+
discover_unconfigured=not root_git_info["isRepo"],
|
|
465
|
+
)
|
|
337
466
|
|
|
338
467
|
result = {
|
|
339
468
|
"developer": developer or "",
|
|
340
469
|
"git": {
|
|
341
|
-
"
|
|
342
|
-
"
|
|
343
|
-
"
|
|
344
|
-
"
|
|
470
|
+
"isRepo": root_git_info["isRepo"],
|
|
471
|
+
"branch": root_git_info["branch"],
|
|
472
|
+
"isClean": root_git_info["isClean"],
|
|
473
|
+
"uncommittedChanges": root_git_info["uncommittedChanges"],
|
|
474
|
+
"recentCommits": root_git_info["recentCommits"],
|
|
345
475
|
},
|
|
346
476
|
"tasks": {
|
|
347
477
|
"active": tasks,
|
|
@@ -405,39 +535,17 @@ def get_context_text(repo_root: Path | None = None) -> str:
|
|
|
405
535
|
lines.append(f"Name: {developer}")
|
|
406
536
|
lines.append("")
|
|
407
537
|
|
|
408
|
-
|
|
409
|
-
lines
|
|
410
|
-
_, branch_out, _ = run_git(["branch", "--show-current"], cwd=repo_root)
|
|
411
|
-
branch = branch_out.strip() or "unknown"
|
|
412
|
-
lines.append(f"Branch: {branch}")
|
|
413
|
-
|
|
414
|
-
_, status_out, _ = run_git(["status", "--porcelain"], cwd=repo_root)
|
|
415
|
-
status_lines = [line for line in status_out.splitlines() if line.strip()]
|
|
416
|
-
status_count = len(status_lines)
|
|
417
|
-
|
|
418
|
-
if status_count == 0:
|
|
419
|
-
lines.append("Working directory: Clean")
|
|
420
|
-
else:
|
|
421
|
-
lines.append(f"Working directory: {status_count} uncommitted change(s)")
|
|
422
|
-
lines.append("")
|
|
423
|
-
lines.append("Changes:")
|
|
424
|
-
_, short_out, _ = run_git(["status", "--short"], cwd=repo_root)
|
|
425
|
-
for line in short_out.splitlines()[:10]:
|
|
426
|
-
lines.append(line)
|
|
427
|
-
lines.append("")
|
|
428
|
-
|
|
429
|
-
# Recent commits
|
|
430
|
-
lines.append("## RECENT COMMITS")
|
|
431
|
-
_, log_out, _ = run_git(["log", "--oneline", "-5"], cwd=repo_root)
|
|
432
|
-
if log_out.strip():
|
|
433
|
-
for line in log_out.splitlines():
|
|
434
|
-
lines.append(line)
|
|
435
|
-
else:
|
|
436
|
-
lines.append("(no commits)")
|
|
437
|
-
lines.append("")
|
|
538
|
+
root_git_info = _collect_root_git_info(repo_root)
|
|
539
|
+
_append_root_git_context(lines, root_git_info)
|
|
438
540
|
|
|
439
541
|
# Package git repos — independent sub-repositories
|
|
440
|
-
_append_package_git_context(
|
|
542
|
+
_append_package_git_context(
|
|
543
|
+
lines,
|
|
544
|
+
_collect_package_git_info(
|
|
545
|
+
repo_root,
|
|
546
|
+
discover_unconfigured=not root_git_info["isRepo"],
|
|
547
|
+
),
|
|
548
|
+
)
|
|
441
549
|
|
|
442
550
|
# Current task
|
|
443
551
|
lines.append("## CURRENT TASK")
|
|
@@ -557,20 +665,7 @@ def get_context_record_json(repo_root: Path | None = None) -> dict:
|
|
|
557
665
|
developer = get_developer(repo_root)
|
|
558
666
|
tasks_dir = get_tasks_dir(repo_root)
|
|
559
667
|
|
|
560
|
-
|
|
561
|
-
_, branch_out, _ = run_git(["branch", "--show-current"], cwd=repo_root)
|
|
562
|
-
branch = branch_out.strip() or "unknown"
|
|
563
|
-
|
|
564
|
-
_, status_out, _ = run_git(["status", "--porcelain"], cwd=repo_root)
|
|
565
|
-
git_status_count = len([line for line in status_out.splitlines() if line.strip()])
|
|
566
|
-
|
|
567
|
-
_, log_out, _ = run_git(["log", "--oneline", "-5"], cwd=repo_root)
|
|
568
|
-
commits = []
|
|
569
|
-
for line in log_out.splitlines():
|
|
570
|
-
if line.strip():
|
|
571
|
-
parts = line.split(" ", 1)
|
|
572
|
-
if len(parts) >= 2:
|
|
573
|
-
commits.append({"hash": parts[0], "message": parts[1]})
|
|
668
|
+
root_git_info = _collect_root_git_info(repo_root)
|
|
574
669
|
|
|
575
670
|
# My tasks (single pass — collect statuses and filter by assignee)
|
|
576
671
|
all_tasks_list = list(iter_active_tasks(tasks_dir))
|
|
@@ -610,15 +705,19 @@ def get_context_record_json(repo_root: Path | None = None) -> dict:
|
|
|
610
705
|
}
|
|
611
706
|
|
|
612
707
|
# Package git repos
|
|
613
|
-
pkg_git_info = _collect_package_git_info(
|
|
708
|
+
pkg_git_info = _collect_package_git_info(
|
|
709
|
+
repo_root,
|
|
710
|
+
discover_unconfigured=not root_git_info["isRepo"],
|
|
711
|
+
)
|
|
614
712
|
|
|
615
713
|
result = {
|
|
616
714
|
"developer": developer or "",
|
|
617
715
|
"git": {
|
|
618
|
-
"
|
|
619
|
-
"
|
|
620
|
-
"
|
|
621
|
-
"
|
|
716
|
+
"isRepo": root_git_info["isRepo"],
|
|
717
|
+
"branch": root_git_info["branch"],
|
|
718
|
+
"isClean": root_git_info["isClean"],
|
|
719
|
+
"uncommittedChanges": root_git_info["uncommittedChanges"],
|
|
720
|
+
"recentCommits": root_git_info["recentCommits"],
|
|
622
721
|
},
|
|
623
722
|
"myTasks": my_tasks,
|
|
624
723
|
"currentTask": current_task_info,
|
|
@@ -673,39 +772,17 @@ def get_context_text_record(repo_root: Path | None = None) -> str:
|
|
|
673
772
|
lines.append("(no active tasks assigned to you)")
|
|
674
773
|
lines.append("")
|
|
675
774
|
|
|
676
|
-
|
|
677
|
-
lines
|
|
678
|
-
_, branch_out, _ = run_git(["branch", "--show-current"], cwd=repo_root)
|
|
679
|
-
branch = branch_out.strip() or "unknown"
|
|
680
|
-
lines.append(f"Branch: {branch}")
|
|
681
|
-
|
|
682
|
-
_, status_out, _ = run_git(["status", "--porcelain"], cwd=repo_root)
|
|
683
|
-
status_lines = [line for line in status_out.splitlines() if line.strip()]
|
|
684
|
-
status_count = len(status_lines)
|
|
685
|
-
|
|
686
|
-
if status_count == 0:
|
|
687
|
-
lines.append("Working directory: Clean")
|
|
688
|
-
else:
|
|
689
|
-
lines.append(f"Working directory: {status_count} uncommitted change(s)")
|
|
690
|
-
lines.append("")
|
|
691
|
-
lines.append("Changes:")
|
|
692
|
-
_, short_out, _ = run_git(["status", "--short"], cwd=repo_root)
|
|
693
|
-
for line in short_out.splitlines()[:10]:
|
|
694
|
-
lines.append(line)
|
|
695
|
-
lines.append("")
|
|
696
|
-
|
|
697
|
-
# RECENT COMMITS
|
|
698
|
-
lines.append("## RECENT COMMITS")
|
|
699
|
-
_, log_out, _ = run_git(["log", "--oneline", "-5"], cwd=repo_root)
|
|
700
|
-
if log_out.strip():
|
|
701
|
-
for line in log_out.splitlines():
|
|
702
|
-
lines.append(line)
|
|
703
|
-
else:
|
|
704
|
-
lines.append("(no commits)")
|
|
705
|
-
lines.append("")
|
|
775
|
+
root_git_info = _collect_root_git_info(repo_root)
|
|
776
|
+
_append_root_git_context(lines, root_git_info)
|
|
706
777
|
|
|
707
778
|
# Package git repos — independent sub-repositories
|
|
708
|
-
_append_package_git_context(
|
|
779
|
+
_append_package_git_context(
|
|
780
|
+
lines,
|
|
781
|
+
_collect_package_git_info(
|
|
782
|
+
repo_root,
|
|
783
|
+
discover_unconfigured=not root_git_info["isRepo"],
|
|
784
|
+
),
|
|
785
|
+
)
|
|
709
786
|
|
|
710
787
|
# CURRENT TASK
|
|
711
788
|
lines.append("## CURRENT TASK")
|