@pennixrv/trellis 0.6.32 → 0.6.34

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.
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": "0.6.32",
3
+ "description": "Exposes task lifecycle progress and completes the 0.6.32 workflow release record.",
4
+ "breaking": false,
5
+ "recommendMigrate": false,
6
+ "changelog": "**Enhancements:**\n- Exposes planned, active, completed, and child-task progress for read-only workflow consumers.\n\n**Fixes:**\n- Records the release and workflow verification changes without requiring a project migration.",
7
+ "migrations": [],
8
+ "notes": "No project migration is required. Existing projects can run the normal `trellis update` flow."
9
+ }
@@ -87,6 +87,14 @@ def find_repo_root(start_path: str) -> str | None:
87
87
  return None
88
88
 
89
89
 
90
+ def _real_path_contained(base_real: str, target_real: str) -> bool:
91
+ """Return whether a real path is inside the real base path."""
92
+ try:
93
+ return os.path.commonpath([base_real, target_real]) == base_real
94
+ except ValueError:
95
+ return False
96
+
97
+
90
98
  def _detect_platform(input_data: dict) -> str | None:
91
99
  if _hook_event_name(input_data) == "SubagentStart":
92
100
  return "codex"
@@ -167,11 +175,11 @@ def get_current_task(
167
175
 
168
176
 
169
177
  # =============================================================================
170
- # Context Injection Limits (issue #441)
178
+ # Context Injection
171
179
  #
172
- # Notice text and behavior mirrored byte-for-byte in the Pi TS extension
173
- # (templates/pi/extensions/trellis/index.ts.txt). Changing wording here
174
- # requires changing it there too.
180
+ # The shared Python projection lives in the active project's stamped
181
+ # `.trellis/scripts/common/context_projection.py`. These fallback limits keep
182
+ # the installed Hook fail-open when an older project has not been updated yet.
175
183
  # =============================================================================
176
184
 
177
185
  DEFAULT_MAX_FILE_BYTES = 32768
@@ -198,454 +206,64 @@ def _get_limits(repo_root: str) -> dict[str, int]:
198
206
  return dict(DEFAULT_LIMITS)
199
207
 
200
208
 
201
- def truncate_utf8(data: bytes, cap: int) -> bytes:
202
- """Truncate ``data`` to at most ``cap`` bytes without splitting a UTF-8
203
- multi-byte sequence.
209
+ def _project_context(repo_root: str, task_dir: str, agent_type: str):
210
+ """Load the task-owned projection evaluator for the current project.
204
211
 
205
- ``cap <= 0`` means "no limit" — returns ``data`` unchanged.
212
+ Hooks are installed outside the project, so the evaluator deliberately
213
+ resolves from the active project's stamped `.trellis/scripts` tree.
206
214
  """
207
- if cap <= 0 or len(data) <= cap:
208
- return data
209
-
210
- truncated = data[:cap]
211
- i = len(truncated)
212
- # Back off over continuation bytes (10xxxxxx) to find the lead byte.
213
- while i > 0 and (truncated[i - 1] & 0xC0) == 0x80:
214
- i -= 1
215
- if i == 0:
216
- return b""
217
-
218
- lead = truncated[i - 1]
219
- if lead & 0x80:
220
- if (lead & 0xE0) == 0xC0:
221
- seq_len = 2
222
- elif (lead & 0xF0) == 0xE0:
223
- seq_len = 3
224
- elif (lead & 0xF8) == 0xF0:
225
- seq_len = 4
226
- else:
227
- seq_len = 1
228
- # Drop the lead byte too if its full sequence didn't fit.
229
- if (i - 1) + seq_len > len(truncated):
230
- i -= 1
231
-
232
- return truncated[:i]
233
-
234
-
235
- class _Budget:
236
- """Tracks the running total of bytes emitted into the sub-agent context."""
237
-
238
- def __init__(self, max_total_bytes: int) -> None:
239
- self.max_total_bytes = max_total_bytes
240
- self.used = 0
241
-
242
- def has_room(self, size: int) -> bool:
243
- if self.max_total_bytes <= 0:
244
- return True
245
- return self.used + size <= self.max_total_bytes
246
-
247
- def add(self, size: int) -> None:
248
- self.used += size
249
-
250
-
251
- def _real_path_contained(base_real: str, target_real: str) -> bool:
252
- """Whether an already-realpath'd target sits under an already-realpath'd base.
253
-
254
- ValueError on Windows when the two sit on different drives; that is
255
- outside the base by definition, so it fails closed.
256
- """
257
- try:
258
- return os.path.commonpath([base_real, target_real]) == base_real
259
- except ValueError:
260
- return False
261
-
262
-
263
- def _read_file_bytes(base_path: str, file_path: str) -> bytes | None:
264
- """Read raw file bytes, return None if file doesn't exist."""
265
- full_path = os.path.join(base_path, file_path)
266
- try:
267
- root_real = os.path.realpath(base_path)
268
- # `.trellis` may itself be a symlink into a store outside the repo
269
- # (#567); its real location is a second legitimate containment base.
270
- workflow_real = os.path.realpath(os.path.join(base_path, ".trellis"))
271
- full_real = os.path.realpath(full_path)
272
- if not _real_path_contained(root_real, full_real) and not (
273
- _real_path_contained(workflow_real, full_real)
274
- ):
275
- return None
276
- except OSError:
277
- return None
278
- if os.path.exists(full_path) and os.path.isfile(full_path):
279
- try:
280
- with open(full_path, "rb") as f:
281
- return f.read()
282
- except Exception:
283
- return None
284
- return None
285
-
286
-
287
- def _truncate_notice(path: str, cap: int) -> str:
288
- return f"\n[Trellis: truncated at {cap} bytes — read {path} for the full content]"
289
-
290
-
291
- def _is_binary_content(data: bytes) -> bool:
292
- """Return True when raw bytes should not be decoded into model context."""
293
- if b"\x00" in data:
294
- return True
295
- try:
296
- data.decode("utf-8", errors="strict")
297
- except UnicodeDecodeError:
298
- return True
299
- return False
300
-
301
-
302
- def _binary_notice(path: str, size: int, reason: str) -> str:
303
- return (
304
- f"[Trellis: not inlined (binary file) — "
305
- f"{path} ({size} bytes): {reason}]"
306
- )
307
-
215
+ scripts_dir = Path(repo_root) / DIR_WORKFLOW / "scripts"
216
+ if str(scripts_dir) not in sys.path:
217
+ sys.path.insert(0, str(scripts_dir))
218
+ from common.context_projection import project_agent_context # type: ignore[import-not-found]
308
219
 
309
- def _index_notice(path: str, size: int, reason: str) -> str:
310
- return (
311
- f"[Trellis: not inlined (total context limit reached) — "
312
- f"{path} ({size} bytes): {reason}]"
220
+ return project_agent_context(
221
+ Path(repo_root), Path(repo_root) / task_dir, agent_type, _get_limits(repo_root)
313
222
  )
314
223
 
315
224
 
316
- def _budgeted_block(
317
- budget: _Budget,
318
- header: str,
319
- plain_path: str,
320
- content: str,
321
- reason: str,
322
- size_for_index: int,
323
- ) -> str:
324
- """Return an inlined ``=== header ===`` block, or degrade to an index
325
- notice once the total context budget is exhausted."""
326
- block = f"=== {header} ===\n{content}"
327
- block_bytes = len(block.encode("utf-8"))
328
- if not budget.has_room(block_bytes):
329
- notice = _index_notice(plain_path, size_for_index, reason)
330
- budget.add(len(notice.encode("utf-8")))
331
- return notice
332
- budget.add(block_bytes)
333
- return block
334
-
335
-
336
- def _materialize_file(
337
- base_path: str,
338
- file_path: str,
339
- reason: str,
340
- limits: dict[str, int],
341
- budget: _Budget,
342
- ) -> str | None:
343
- """Read a JSONL-referenced file, apply the per-file cap, then budget it."""
344
- data = _read_file_bytes(base_path, file_path)
345
- if data is None:
346
- return None
347
-
348
- size = len(data)
349
- if _is_binary_content(data):
350
- notice = _binary_notice(file_path, size, reason)
351
- budget.add(len(notice.encode("utf-8")))
352
- return notice
353
-
354
- cap = limits["max_file_bytes"]
355
- truncated_bytes = truncate_utf8(data, cap)
356
- content = truncated_bytes.decode("utf-8", errors="replace")
357
- if len(truncated_bytes) < size:
358
- content += _truncate_notice(file_path, cap)
359
-
360
- return _budgeted_block(budget, file_path, file_path, content, reason, size)
361
-
362
-
363
- def _materialize_directory(
364
- base_path: str,
365
- dir_path: str,
366
- reason: str,
367
- limits: dict[str, int],
368
- budget: _Budget,
369
- max_files: int = 20,
370
- ) -> list[str]:
371
- """Read all .md files in a directory, applying the same per-file and
372
- total caps as a single-file JSONL entry."""
373
- full_path = os.path.join(base_path, dir_path)
374
- if not os.path.exists(full_path) or not os.path.isdir(full_path):
375
- return []
376
-
377
- blocks: list[str] = []
378
- try:
379
- md_files = sorted(
380
- f
381
- for f in os.listdir(full_path)
382
- if f.endswith(".md") and os.path.isfile(os.path.join(full_path, f))
383
- )
384
- for filename in md_files[:max_files]:
385
- relative_path = os.path.join(dir_path, filename)
386
- block = _materialize_file(base_path, relative_path, reason, limits, budget)
387
- if block:
388
- blocks.append(block)
389
- except Exception:
390
- pass
391
-
392
- return blocks
393
-
394
-
395
225
  def read_jsonl_entries(base_path: str, jsonl_path: str) -> list[dict]:
396
- """
397
- Parse all file/directory entries referenced in a jsonl context file.
398
-
399
- Schema:
400
- {"file": "path/to/file.md", "reason": "..."}
401
- {"file": "path/to/dir/", "type": "directory", "reason": "..."}
402
- {"_example": "..."} # legacy placeholder — skipped (no `file` field)
403
-
404
- Rows without a ``file`` field (e.g. the placeholder line older Trellis
405
- versions wrote at ``task.py create`` time) are skipped silently. If the
406
- resulting entry list is empty, a stderr warning is emitted so the operator
407
- can debug missing context.
226
+ """Keep the historical probe surface while using the shared parser."""
227
+ scripts_dir = Path(base_path) / DIR_WORKFLOW / "scripts"
228
+ if str(scripts_dir) not in sys.path:
229
+ sys.path.insert(0, str(scripts_dir))
230
+ from common.context_projection import parse_context_manifest # type: ignore[import-not-found]
408
231
 
409
- Returns:
410
- [{"file": path, "type": "file" | "directory", "reason": reason}, ...]
411
- """
412
- full_path = os.path.join(base_path, jsonl_path)
413
- if not os.path.exists(full_path):
232
+ entries, _, exists = parse_context_manifest(Path(base_path) / jsonl_path)
233
+ if not exists:
414
234
  print(
415
235
  f"[inject-subagent-context] WARN: {jsonl_path} not found — "
416
- f"sub-agent will receive only task artifacts",
236
+ "sub-agent will receive only task artifacts",
417
237
  file=sys.stderr,
418
238
  )
419
- return []
420
-
421
- entries: list[dict] = []
422
- saw_real_entry = False
423
- try:
424
- with open(full_path, "r", encoding="utf-8") as f:
425
- for line in f:
426
- line = line.strip()
427
- if not line:
428
- continue
429
- try:
430
- item = json.loads(line)
431
- file_path = item.get("file") or item.get("path")
432
-
433
- if not file_path:
434
- # Seed / comment row — skip silently
435
- continue
436
-
437
- saw_real_entry = True
438
- entries.append(
439
- {
440
- "file": file_path,
441
- "type": item.get("type", "file"),
442
- "reason": item.get("reason") or "-",
443
- }
444
- )
445
- except json.JSONDecodeError:
446
- continue
447
- except Exception:
448
- pass
449
-
450
- if not saw_real_entry:
239
+ elif not entries:
451
240
  print(
452
241
  f"[inject-subagent-context] WARN: {jsonl_path} has no curated "
453
- f"entries (only seed / empty) — sub-agent will receive only "
454
- f"task artifacts. See workflow.md planning artifact guidance.",
242
+ "entries (only seed / empty) — sub-agent will receive only "
243
+ "task artifacts. See workflow.md planning artifact guidance.",
455
244
  file=sys.stderr,
456
245
  )
457
-
458
- return entries
459
-
460
-
461
- def _materialize_jsonl_entries(
462
- base_path: str, jsonl_path: str, limits: dict[str, int], budget: _Budget
463
- ) -> list[str]:
464
- """Materialize every entry in a jsonl context file into context blocks,
465
- applying per-file and total budget caps."""
466
- blocks: list[str] = []
467
- for entry in read_jsonl_entries(base_path, jsonl_path):
468
- if entry["type"] == "directory":
469
- blocks.extend(
470
- _materialize_directory(
471
- base_path, entry["file"], entry["reason"], limits, budget
472
- )
473
- )
474
- else:
475
- block = _materialize_file(
476
- base_path, entry["file"], entry["reason"], limits, budget
477
- )
478
- if block:
479
- blocks.append(block)
480
- return blocks
481
-
482
-
483
- def get_agent_context(
484
- repo_root: str,
485
- task_dir: str,
486
- agent_type: str,
487
- limits: dict[str, int],
488
- budget: _Budget,
489
- ) -> str:
490
- """
491
- Get context from {agent_type}.jsonl for the specified agent.
492
- Only reads implement.jsonl or check.jsonl (the two JSONL files the task system creates).
493
- """
494
- agent_jsonl = f"{task_dir}/{agent_type}.jsonl"
495
- blocks = _materialize_jsonl_entries(repo_root, agent_jsonl, limits, budget)
496
- if not blocks:
497
- # Zero curated context reaches the model silently otherwise — the
498
- # stderr WARN above never enters any session (#573). Put the fact in
499
- # the prompt itself so the sub-agent compensates instead of assuming
500
- # the spec context was complete.
501
- return (
502
- f"[Trellis] {agent_jsonl} has no curated entries, so no spec/research "
503
- "context was injected. Before working, read the guidelines relevant "
504
- "to the code you will touch under .trellis/spec/, and treat the task "
505
- "artifacts below as the only prepared context."
506
- )
507
- return "\n\n".join(blocks)
508
-
509
-
510
- def _materialize_artifact(
511
- base_path: str,
512
- file_path: str,
513
- header_label: str,
514
- reason: str,
515
- limits: dict[str, int],
516
- budget: _Budget,
517
- ) -> str | None:
518
- """Read a task artifact (prd/design/implement.md), apply the per-artifact
519
- cap, then budget it."""
520
- data = _read_file_bytes(base_path, file_path)
521
- if data is None:
522
- return None
523
-
524
- size = len(data)
525
- cap = limits["max_artifact_bytes"]
526
- truncated_bytes = truncate_utf8(data, cap)
527
- content = truncated_bytes.decode("utf-8", errors="replace")
528
- if len(truncated_bytes) < size:
529
- content += _truncate_notice(file_path, cap)
530
-
531
- return _budgeted_block(budget, header_label, file_path, content, reason, size)
246
+ return [
247
+ {"file": entry.path, "type": entry.entry_type, "reason": entry.reason}
248
+ for entry in entries
249
+ ]
532
250
 
533
251
 
534
252
  def get_implement_context(repo_root: str, task_dir: str) -> str:
535
- """
536
- Complete context for Implement Agent
537
-
538
- Read order:
539
- 1. All files in implement.jsonl (spec/research manifests)
540
- 2. prd.md (requirements)
541
- 3. design.md if present (technical design)
542
- 4. implement.md if present (execution plan)
543
- """
544
- limits = _get_limits(repo_root)
545
- budget = _Budget(limits["max_total_bytes"])
546
- context_parts = []
547
-
548
- # 1. Read implement.jsonl
549
- base_context = get_agent_context(repo_root, task_dir, "implement", limits, budget)
550
- if base_context:
551
- context_parts.append(base_context)
552
-
553
- # 2. Requirements document
554
- prd_block = _materialize_artifact(
555
- repo_root,
556
- f"{task_dir}/prd.md",
557
- f"{task_dir}/prd.md (Requirements)",
558
- "Requirements document",
559
- limits,
560
- budget,
561
- )
562
- if prd_block:
563
- context_parts.append(prd_block)
564
-
565
- # 3. Technical design for complex tasks
566
- design_block = _materialize_artifact(
567
- repo_root,
568
- f"{task_dir}/design.md",
569
- f"{task_dir}/design.md (Technical Design)",
570
- "Technical design document",
571
- limits,
572
- budget,
573
- )
574
- if design_block:
575
- context_parts.append(design_block)
576
-
577
- # 4. Execution plan for complex tasks
578
- implement_plan_block = _materialize_artifact(
579
- repo_root,
580
- f"{task_dir}/implement.md",
581
- f"{task_dir}/implement.md (Execution Plan)",
582
- "Execution plan document",
583
- limits,
584
- budget,
585
- )
586
- if implement_plan_block:
587
- context_parts.append(implement_plan_block)
588
-
589
- return "\n\n".join(context_parts)
253
+ """Complete Python context for an Implement subagent."""
254
+ return _project_context(repo_root, task_dir, "implement").text
590
255
 
591
256
 
592
257
  def get_check_context(repo_root: str, task_dir: str) -> str:
593
- """
594
- Context for Check Agent: check.jsonl + task artifacts.
595
- """
596
- limits = _get_limits(repo_root)
597
- budget = _Budget(limits["max_total_bytes"])
598
- context_parts = []
599
-
600
- base_context = get_agent_context(repo_root, task_dir, "check", limits, budget)
601
- if base_context:
602
- context_parts.append(base_context)
603
-
604
- prd_block = _materialize_artifact(
605
- repo_root,
606
- f"{task_dir}/prd.md",
607
- f"{task_dir}/prd.md (Requirements)",
608
- "Requirements document",
609
- limits,
610
- budget,
611
- )
612
- if prd_block:
613
- context_parts.append(prd_block)
614
-
615
- design_block = _materialize_artifact(
616
- repo_root,
617
- f"{task_dir}/design.md",
618
- f"{task_dir}/design.md (Technical Design)",
619
- "Technical design document",
620
- limits,
621
- budget,
622
- )
623
- if design_block:
624
- context_parts.append(design_block)
625
-
626
- implement_plan_block = _materialize_artifact(
627
- repo_root,
628
- f"{task_dir}/implement.md",
629
- f"{task_dir}/implement.md (Execution Plan)",
630
- "Execution plan document",
631
- limits,
632
- budget,
633
- )
634
- if implement_plan_block:
635
- context_parts.append(implement_plan_block)
636
-
637
- return "\n\n".join(context_parts)
258
+ """Complete Python context for a Check subagent."""
259
+ return _project_context(repo_root, task_dir, "check").text
638
260
 
639
261
 
640
262
  def get_finish_context(repo_root: str, task_dir: str) -> str:
641
- """
642
- Context for Finish phase: reuses check.jsonl + prd.md
643
- (Finish is a final check, same context source.)
644
- """
263
+ """Finish reuses the Check projection."""
645
264
  return get_check_context(repo_root, task_dir)
646
265
 
647
266
 
648
-
649
267
  def build_implement_prompt(original_prompt: str, context: str) -> str:
650
268
  """Build complete prompt for Implement"""
651
269
  return f"""<!-- trellis-hook-injected -->
@@ -1152,26 +770,31 @@ def main():
1152
770
  # Check for [finish] marker in prompt (check agent with finish context)
1153
771
  is_finish_phase = "[finish]" in original_prompt.lower()
1154
772
 
1155
- # Get context and build prompt based on subagent type
1156
- if subagent_type == AGENT_IMPLEMENT:
1157
- assert task_dir is not None # validated above
1158
- context = get_implement_context(repo_root, task_dir)
1159
- new_prompt = build_implement_prompt(original_prompt, context)
1160
- elif subagent_type == AGENT_CHECK:
1161
- assert task_dir is not None # validated above
1162
- if is_finish_phase:
1163
- # Finish phase: use finish context (lighter, focused on final verification)
1164
- context = get_finish_context(repo_root, task_dir)
1165
- new_prompt = build_finish_prompt(original_prompt, context)
773
+ # Get context and build prompt based on subagent type. A project can have
774
+ # an older stamped `.trellis/scripts` tree while its platform Hook is
775
+ # already refreshed; preserve the Hook's fail-open spawn contract there.
776
+ try:
777
+ if subagent_type == AGENT_IMPLEMENT:
778
+ assert task_dir is not None # validated above
779
+ context = get_implement_context(repo_root, task_dir)
780
+ new_prompt = build_implement_prompt(original_prompt, context)
781
+ elif subagent_type == AGENT_CHECK:
782
+ assert task_dir is not None # validated above
783
+ if is_finish_phase:
784
+ # Finish phase: use finish context (lighter, focused on final verification)
785
+ context = get_finish_context(repo_root, task_dir)
786
+ new_prompt = build_finish_prompt(original_prompt, context)
787
+ else:
788
+ # Regular check phase: use check context (full specs for self-fix loop)
789
+ context = get_check_context(repo_root, task_dir)
790
+ new_prompt = build_check_prompt(original_prompt, context)
791
+ elif subagent_type == AGENT_RESEARCH:
792
+ # Research can work without task directory
793
+ context = get_research_context(repo_root, task_dir)
794
+ new_prompt = build_research_prompt(original_prompt, context)
1166
795
  else:
1167
- # Regular check phase: use check context (full specs for self-fix loop)
1168
- context = get_check_context(repo_root, task_dir)
1169
- new_prompt = build_check_prompt(original_prompt, context)
1170
- elif subagent_type == AGENT_RESEARCH:
1171
- # Research can work without task directory
1172
- context = get_research_context(repo_root, task_dir)
1173
- new_prompt = build_research_prompt(original_prompt, context)
1174
- else:
796
+ sys.exit(0)
797
+ except Exception:
1175
798
  sys.exit(0)
1176
799
 
1177
800
  if not context:
@@ -34,6 +34,7 @@ export declare const commonGit: string;
34
34
  export declare const commonTypes: string;
35
35
  export declare const commonTasks: string;
36
36
  export declare const commonTaskContext: string;
37
+ export declare const commonContextProjection: string;
37
38
  export declare const commonTaskStore: string;
38
39
  export declare const commonSessionContext: string;
39
40
  export declare const commonContinuationRecord: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAcH,eAAO,MAAM,WAAW,QAAsC,CAAC;AAG/D,eAAO,MAAM,UAAU,QAA6C,CAAC;AACrE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,eAAe,QAA8C,CAAC;AAC3E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,YAAY,QAA2C,CAAC;AACrE,eAAO,MAAM,QAAQ,QAAuC,CAAC;AAC7D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAChF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,wBAAwB,QAEpC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAG9E,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAC3E,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAC7E,eAAO,MAAM,UAAU,QAAkC,CAAC;AAC1D,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAG7E,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAAgC,CAAC;AAC/D,eAAO,MAAM,qBAAqB,QAAoC,CAAC;AAMvE,eAAO,MAAM,sBAAsB,QAAsC,CAAC;AAC1E,eAAO,MAAM,kBAAkB,QAAkC,CAAC;AAClE,eAAO,MAAM,oBAAoB,QAAoC,CAAC;AACtE,eAAO,MAAM,kBAAkB,QAAqC,CAAC;AAErE;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAyCnD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAOlD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAcH,eAAO,MAAM,WAAW,QAAsC,CAAC;AAG/D,eAAO,MAAM,UAAU,QAA6C,CAAC;AACrE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,eAAe,QAA8C,CAAC;AAC3E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,YAAY,QAA2C,CAAC;AACrE,eAAO,MAAM,QAAQ,QAAuC,CAAC;AAC7D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAChF,eAAO,MAAM,uBAAuB,QAEnC,CAAC;AACF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,wBAAwB,QAEpC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAG9E,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAC3E,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAC7E,eAAO,MAAM,UAAU,QAAkC,CAAC;AAC1D,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAG7E,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAAgC,CAAC;AAC/D,eAAO,MAAM,qBAAqB,QAAoC,CAAC;AAMvE,eAAO,MAAM,sBAAsB,QAAsC,CAAC;AAC1E,eAAO,MAAM,kBAAkB,QAAkC,CAAC;AAClE,eAAO,MAAM,oBAAoB,QAAoC,CAAC;AACtE,eAAO,MAAM,kBAAkB,QAAqC,CAAC;AAErE;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA0CnD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAOlD"}
@@ -44,6 +44,7 @@ export const commonGit = readTemplate("scripts/common/git.py");
44
44
  export const commonTypes = readTemplate("scripts/common/types.py");
45
45
  export const commonTasks = readTemplate("scripts/common/tasks.py");
46
46
  export const commonTaskContext = readTemplate("scripts/common/task_context.py");
47
+ export const commonContextProjection = readTemplate("scripts/common/context_projection.py");
47
48
  export const commonTaskStore = readTemplate("scripts/common/task_store.py");
48
49
  export const commonSessionContext = readTemplate("scripts/common/session_context.py");
49
50
  export const commonContinuationRecord = readTemplate("scripts/common/continuation_record.py");
@@ -96,6 +97,7 @@ export function getAllScripts() {
96
97
  scripts.set("common/types.py", commonTypes);
97
98
  scripts.set("common/tasks.py", commonTasks);
98
99
  scripts.set("common/task_context.py", commonTaskContext);
100
+ scripts.set("common/context_projection.py", commonContextProjection);
99
101
  scripts.set("common/task_store.py", commonTaskStore);
100
102
  scripts.set("common/session_context.py", commonSessionContext);
101
103
  scripts.set("common/continuation_record.py", commonContinuationRecord);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"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"}