@mindfoldhq/trellis 0.6.0-beta.17 → 0.6.0-beta.19

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 (76) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/channel/adapters/claude.d.ts +7 -16
  3. package/dist/commands/channel/adapters/claude.d.ts.map +1 -1
  4. package/dist/commands/channel/adapters/claude.js +19 -25
  5. package/dist/commands/channel/adapters/claude.js.map +1 -1
  6. package/dist/commands/channel/adapters/codex.d.ts +5 -1
  7. package/dist/commands/channel/adapters/codex.d.ts.map +1 -1
  8. package/dist/commands/channel/adapters/codex.js +8 -15
  9. package/dist/commands/channel/adapters/codex.js.map +1 -1
  10. package/dist/commands/channel/adapters/index.d.ts +6 -1
  11. package/dist/commands/channel/adapters/index.d.ts.map +1 -1
  12. package/dist/commands/channel/adapters/index.js +12 -6
  13. package/dist/commands/channel/adapters/index.js.map +1 -1
  14. package/dist/commands/channel/guard.d.ts +150 -0
  15. package/dist/commands/channel/guard.d.ts.map +1 -0
  16. package/dist/commands/channel/guard.js +474 -0
  17. package/dist/commands/channel/guard.js.map +1 -0
  18. package/dist/commands/channel/index.d.ts +1 -1
  19. package/dist/commands/channel/index.d.ts.map +1 -1
  20. package/dist/commands/channel/index.js +38 -10
  21. package/dist/commands/channel/index.js.map +1 -1
  22. package/dist/commands/channel/interrupt.d.ts +10 -0
  23. package/dist/commands/channel/interrupt.d.ts.map +1 -0
  24. package/dist/commands/channel/interrupt.js +22 -0
  25. package/dist/commands/channel/interrupt.js.map +1 -0
  26. package/dist/commands/channel/messages.d.ts +0 -1
  27. package/dist/commands/channel/messages.d.ts.map +1 -1
  28. package/dist/commands/channel/messages.js +2 -6
  29. package/dist/commands/channel/messages.js.map +1 -1
  30. package/dist/commands/channel/run.d.ts +0 -1
  31. package/dist/commands/channel/run.d.ts.map +1 -1
  32. package/dist/commands/channel/run.js +5 -12
  33. package/dist/commands/channel/run.js.map +1 -1
  34. package/dist/commands/channel/send.d.ts +0 -2
  35. package/dist/commands/channel/send.d.ts.map +1 -1
  36. package/dist/commands/channel/send.js +0 -2
  37. package/dist/commands/channel/send.js.map +1 -1
  38. package/dist/commands/channel/spawn.d.ts +10 -0
  39. package/dist/commands/channel/spawn.d.ts.map +1 -1
  40. package/dist/commands/channel/spawn.js +57 -7
  41. package/dist/commands/channel/spawn.js.map +1 -1
  42. package/dist/commands/channel/supervisor/idle.d.ts +46 -0
  43. package/dist/commands/channel/supervisor/idle.d.ts.map +1 -0
  44. package/dist/commands/channel/supervisor/idle.js +72 -0
  45. package/dist/commands/channel/supervisor/idle.js.map +1 -0
  46. package/dist/commands/channel/supervisor/inbox.d.ts +4 -4
  47. package/dist/commands/channel/supervisor/inbox.d.ts.map +1 -1
  48. package/dist/commands/channel/supervisor/inbox.js +22 -22
  49. package/dist/commands/channel/supervisor/inbox.js.map +1 -1
  50. package/dist/commands/channel/supervisor/shutdown.d.ts +3 -1
  51. package/dist/commands/channel/supervisor/shutdown.d.ts.map +1 -1
  52. package/dist/commands/channel/supervisor/shutdown.js +4 -1
  53. package/dist/commands/channel/supervisor/shutdown.js.map +1 -1
  54. package/dist/commands/channel/supervisor/turns.d.ts +11 -0
  55. package/dist/commands/channel/supervisor/turns.d.ts.map +1 -1
  56. package/dist/commands/channel/supervisor/turns.js +19 -2
  57. package/dist/commands/channel/supervisor/turns.js.map +1 -1
  58. package/dist/commands/channel/supervisor.d.ts +6 -0
  59. package/dist/commands/channel/supervisor.d.ts.map +1 -1
  60. package/dist/commands/channel/supervisor.js +43 -3
  61. package/dist/commands/channel/supervisor.js.map +1 -1
  62. package/dist/commands/channel/wait.d.ts +0 -1
  63. package/dist/commands/channel/wait.d.ts.map +1 -1
  64. package/dist/commands/channel/wait.js +0 -1
  65. package/dist/commands/channel/wait.js.map +1 -1
  66. package/dist/migrations/manifests/0.5.16.json +9 -0
  67. package/dist/migrations/manifests/0.5.17.json +9 -0
  68. package/dist/migrations/manifests/0.6.0-beta.18.json +16 -0
  69. package/dist/migrations/manifests/0.6.0-beta.19.json +9 -0
  70. package/dist/templates/codex/config.toml +5 -3
  71. package/dist/templates/pi/extensions/trellis/index.ts.txt +1339 -913
  72. package/dist/templates/pi/settings.json +0 -9
  73. package/dist/templates/trellis/config.yaml +20 -0
  74. package/dist/templates/trellis/scripts/common/task_store.py +55 -7
  75. package/dist/templates/trellis/workflow.md +1 -0
  76. package/package.json +2 -2
@@ -8,14 +8,5 @@
8
8
  ],
9
9
  "prompts": [
10
10
  "./prompts"
11
- ],
12
- "packages": [
13
- {
14
- "source": "npm:pi-subagents",
15
- "extensions": [],
16
- "skills": [],
17
- "prompts": [],
18
- "themes": []
19
- }
20
11
  ]
21
12
  }
@@ -76,6 +76,26 @@ max_journal_lines: 2000
76
76
  # Default package used when --package is not specified.
77
77
  # default_package: frontend
78
78
 
79
+ #-------------------------------------------------------------------------------
80
+ # Channel worker OOM guard
81
+ #-------------------------------------------------------------------------------
82
+ # Default safeguards for `trellis channel spawn` workers. The guard runs
83
+ # at spawn time (cleans expired idle workers, then enforces the live-worker
84
+ # budget) and inside each supervisor (self-terminates a worker that stays
85
+ # continuously idle past `idle_timeout`).
86
+ #
87
+ # Precedence: CLI flag > env var (TRELLIS_CHANNEL_WORKER_IDLE_TIMEOUT /
88
+ # TRELLIS_CHANNEL_MAX_LIVE_WORKERS) > this config > built-in default.
89
+ #
90
+ # `idle_timeout: 0` disables idle cleanup (workers can sit idle forever
91
+ # unless explicitly killed or given `--timeout`).
92
+ # `max_live_workers: 0` disables the spawn-time budget check.
93
+ #
94
+ channel:
95
+ worker_guard:
96
+ idle_timeout: 5m
97
+ max_live_workers: 6
98
+
79
99
  #-------------------------------------------------------------------------------
80
100
  # Codex (dispatch behavior)
81
101
  #-------------------------------------------------------------------------------
@@ -83,6 +83,30 @@ def ensure_tasks_dir(repo_root: Path) -> Path:
83
83
  return tasks_dir
84
84
 
85
85
 
86
+ def _find_archived_task_by_dir_name(tasks_dir: Path, dir_name: str) -> Path | None:
87
+ """Find an archived task directory with the exact active-task dir name."""
88
+ archive_dir = tasks_dir / DIR_ARCHIVE
89
+ if not archive_dir.is_dir():
90
+ return None
91
+
92
+ for month_dir in sorted(archive_dir.iterdir()):
93
+ if not month_dir.is_dir():
94
+ continue
95
+ candidate = month_dir / dir_name
96
+ if candidate.is_dir():
97
+ return candidate
98
+
99
+ return None
100
+
101
+
102
+ def _repo_relative_path(path: Path, repo_root: Path) -> str:
103
+ """Format a path relative to the repo root when possible."""
104
+ try:
105
+ return path.relative_to(repo_root).as_posix()
106
+ except ValueError:
107
+ return str(path)
108
+
109
+
86
110
  # =============================================================================
87
111
  # Sub-agent platform detection + JSONL seeding
88
112
  # =============================================================================
@@ -219,6 +243,13 @@ def cmd_create(args: argparse.Namespace) -> int:
219
243
  task_dir = tasks_dir / dir_name
220
244
  task_json_path = task_dir / FILE_TASK_JSON
221
245
 
246
+ archived_task_dir = _find_archived_task_by_dir_name(tasks_dir, dir_name)
247
+ if archived_task_dir:
248
+ print(colored(f"Error: Task already archived: {dir_name}", Colors.RED), file=sys.stderr)
249
+ print(f"Archived at: {_repo_relative_path(archived_task_dir, repo_root)}", file=sys.stderr)
250
+ print("Use a new slug if you intend to create a new task.", file=sys.stderr)
251
+ return 1
252
+
222
253
  if task_dir.exists():
223
254
  print(colored(f"Warning: Task directory already exists: {dir_name}", Colors.YELLOW), file=sys.stderr)
224
255
  else:
@@ -411,7 +442,16 @@ def cmd_archive(args: argparse.Namespace) -> int:
411
442
 
412
443
  # Auto-commit unless --no-commit
413
444
  if not getattr(args, "no_commit", False):
414
- _auto_commit_archive(dir_name, repo_root, modified_children)
445
+ if not _auto_commit_archive(dir_name, repo_root, modified_children):
446
+ print(
447
+ colored(
448
+ "Archive moved on disk, but git auto-commit did not complete. "
449
+ "Resolve `git status` before continuing.",
450
+ Colors.RED,
451
+ ),
452
+ file=sys.stderr,
453
+ )
454
+ return 1
415
455
 
416
456
  # Return the archive path
417
457
  print(f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}/{year_month}/{dir_name}")
@@ -428,7 +468,7 @@ def _auto_commit_archive(
428
468
  task_name: str,
429
469
  repo_root: Path,
430
470
  modified_children: list[str] | None = None,
431
- ) -> None:
471
+ ) -> bool:
432
472
  """Stage Trellis-owned task paths and commit after archive.
433
473
 
434
474
  Scoped narrowly to the archived task's source + destination paths
@@ -450,14 +490,21 @@ def _auto_commit_archive(
450
490
  "[OK] session_auto_commit: false — skipping git stage/commit.",
451
491
  file=sys.stderr,
452
492
  )
453
- return
493
+ return True
494
+
495
+ source_rel = f"{DIR_WORKFLOW}/{DIR_TASKS}/{task_name}"
496
+ rc, tracked_out, _ = run_git(
497
+ ["ls-files", "--", source_rel],
498
+ cwd=repo_root,
499
+ )
500
+ source_was_tracked = rc == 0 and bool(tracked_out.strip())
454
501
 
455
502
  paths = safe_archive_paths_to_add(
456
503
  repo_root, task_name=task_name, modified_children=modified_children
457
504
  )
458
505
  if not paths:
459
506
  print("[OK] No task changes to commit.", file=sys.stderr)
460
- return
507
+ return True
461
508
 
462
509
  success, _, err = safe_git_add(paths, repo_root)
463
510
  if not success:
@@ -468,7 +515,7 @@ def _auto_commit_archive(
468
515
  f"[WARN] git add failed: {err.strip() if err else 'unknown error'}",
469
516
  file=sys.stderr,
470
517
  )
471
- return
518
+ return not source_was_tracked
472
519
 
473
520
  # Belt-and-suspenders for the phantom-delete bug: `safe_git_add` uses
474
521
  # `git add` (no -A) which only stages additions/modifications. The
@@ -479,7 +526,6 @@ def _auto_commit_archive(
479
526
  #
480
527
  # `--ignore-unmatch` makes this a no-op when the task was never tracked
481
528
  # (e.g. archiving a task that lived only in working tree).
482
- source_rel = f"{DIR_WORKFLOW}/{DIR_TASKS}/{task_name}"
483
529
  run_git(
484
530
  ["rm", "-r", "--cached", "--ignore-unmatch", "--", source_rel],
485
531
  cwd=repo_root,
@@ -491,14 +537,16 @@ def _auto_commit_archive(
491
537
  )
492
538
  if rc == 0:
493
539
  print("[OK] No task changes to commit.", file=sys.stderr)
494
- return
540
+ return True
495
541
 
496
542
  commit_msg = f"chore(task): archive {task_name}"
497
543
  rc, _, err = run_git(["commit", "-m", commit_msg], cwd=repo_root)
498
544
  if rc == 0:
499
545
  print(f"[OK] Auto-committed: {commit_msg}", file=sys.stderr)
546
+ return True
500
547
  else:
501
548
  print(f"[WARN] Auto-commit failed: {err.strip()}", file=sys.stderr)
549
+ return not source_was_tracked
502
550
 
503
551
 
504
552
  # =============================================================================
@@ -223,6 +223,7 @@ Inline mode: skip jsonl curation; Phase 2 reads artifacts/specs via `trellis-bef
223
223
  Sub-agent dispatch protocol applies to all platforms and all sub-agents, including class-2 Codex/Copilot/Gemini/Qoder and `trellis-research`: every dispatch prompt starts with `Active task: <task path from task.py current>` before role-specific instructions.
224
224
 
225
225
  [workflow-state:in_progress]
226
+ Tools: `trellis-implement` / `trellis-research` are sub-agent types only (Task/Agent tool, NOT Skill; there is no skill by these names). `trellis-update-spec` is a skill. `trellis-check` exists as both; prefer the Agent form when verifying after code changes.
226
227
  Flow: `trellis-implement` -> `trellis-check` -> `trellis-update-spec` -> commit (Phase 3.4) -> `/trellis:finish-work`.
227
228
  Main-session default: dispatch implement/check sub-agents. Sub-agent self-exemption: if already running as `trellis-implement`, do NOT spawn another `trellis-implement` or `trellis-check`; if already running as `trellis-check`, do NOT spawn another `trellis-check` or `trellis-implement`. Dispatch is main session only.
228
229
  Dispatch prompt starts with `Active task: <task path from task.py current>`. Read context: jsonl entries -> `prd.md` -> `design.md if present` -> `implement.md if present`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindfoldhq/trellis",
3
- "version": "0.6.0-beta.17",
3
+ "version": "0.6.0-beta.19",
4
4
  "description": "AI capabilities grow like ivy — Trellis provides the structure to guide them along a disciplined path",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -34,7 +34,7 @@
34
34
  "inquirer": "^9.3.7",
35
35
  "undici": "^6.21.0",
36
36
  "zod": "^4.4.2",
37
- "@mindfoldhq/trellis-core": "0.6.0-beta.17"
37
+ "@mindfoldhq/trellis-core": "0.6.0-beta.19"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@eslint/js": "^9.18.0",