agentpack-cli 0.1.14__tar.gz → 0.1.15__tar.gz

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 (83) hide show
  1. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/PKG-INFO +1 -1
  2. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/pyproject.toml +1 -1
  3. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/analysis/ranking.py +75 -0
  4. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/application/pack_service.py +10 -2
  5. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/install.py +3 -2
  6. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/config.py +4 -0
  7. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/git.py +20 -0
  8. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/installers/claude.py +5 -6
  9. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/installers/codex.py +5 -6
  10. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/installers/cursor.py +11 -8
  11. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/installers/windsurf.py +5 -3
  12. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/.gitignore +0 -0
  13. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/LICENSE +0 -0
  14. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/README.md +0 -0
  15. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/__init__.py +0 -0
  16. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/adapters/__init__.py +0 -0
  17. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/adapters/antigravity.py +0 -0
  18. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/adapters/base.py +0 -0
  19. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/adapters/claude.py +0 -0
  20. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/adapters/codex.py +0 -0
  21. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/adapters/cursor.py +0 -0
  22. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/adapters/detect.py +0 -0
  23. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/adapters/generic.py +0 -0
  24. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/adapters/windsurf.py +0 -0
  25. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/analysis/__init__.py +0 -0
  26. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/analysis/dependency_graph.py +0 -0
  27. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/analysis/go_imports.py +0 -0
  28. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/analysis/java_imports.py +0 -0
  29. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/analysis/js_ts_imports.py +0 -0
  30. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/analysis/python_imports.py +0 -0
  31. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/analysis/rust_imports.py +0 -0
  32. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/analysis/symbols.py +0 -0
  33. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/analysis/tests.py +0 -0
  34. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/application/__init__.py +0 -0
  35. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/cli.py +0 -0
  36. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/__init__.py +0 -0
  37. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/_shared.py +0 -0
  38. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/benchmark.py +0 -0
  39. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/claude_cmd.py +0 -0
  40. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/diff.py +0 -0
  41. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/doctor.py +0 -0
  42. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/explain.py +0 -0
  43. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/init.py +0 -0
  44. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/mcp_cmd.py +0 -0
  45. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/monitor.py +0 -0
  46. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/pack.py +0 -0
  47. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/scan.py +0 -0
  48. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/stats.py +0 -0
  49. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/status.py +0 -0
  50. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/summarize.py +0 -0
  51. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/commands/watch.py +0 -0
  52. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/__init__.py +0 -0
  53. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/bootstrap.py +0 -0
  54. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/cache.py +0 -0
  55. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/context_pack.py +0 -0
  56. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/diff.py +0 -0
  57. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/git_hooks.py +0 -0
  58. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/global_install.py +0 -0
  59. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/ignore.py +0 -0
  60. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/merkle.py +0 -0
  61. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/models.py +0 -0
  62. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/redactor.py +0 -0
  63. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/scanner.py +0 -0
  64. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/snapshot.py +0 -0
  65. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/token_estimator.py +0 -0
  66. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/core/vscode_tasks.py +0 -0
  67. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/data/agentpack.md +0 -0
  68. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/installers/__init__.py +0 -0
  69. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/installers/antigravity.py +0 -0
  70. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/integrations/__init__.py +0 -0
  71. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/integrations/git_hooks.py +0 -0
  72. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/integrations/global_install.py +0 -0
  73. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/integrations/vscode_tasks.py +0 -0
  74. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/mcp_server.py +0 -0
  75. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/renderers/__init__.py +0 -0
  76. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/renderers/compact.py +0 -0
  77. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/renderers/markdown.py +0 -0
  78. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/renderers/receipts.py +0 -0
  79. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/session/__init__.py +0 -0
  80. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/session/state.py +0 -0
  81. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/summaries/__init__.py +0 -0
  82. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/summaries/base.py +0 -0
  83. {agentpack_cli-0.1.14 → agentpack_cli-0.1.15}/src/agentpack/summaries/offline.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentpack-cli
3
- Version: 0.1.14
3
+ Version: 0.1.15
4
4
  Summary: Token-aware context packing for AI coding agents — Claude, Cursor, Windsurf, and Codex
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agentpack-cli"
3
- version = "0.1.14"
3
+ version = "0.1.15"
4
4
  description = "Token-aware context packing for AI coding agents — Claude, Cursor, Windsurf, and Codex"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -283,6 +283,7 @@ def score_files(
283
283
  include_configs: bool = True,
284
284
  weights: ScoringWeights | None = None,
285
285
  summaries: dict | None = None,
286
+ churn_counts: dict[str, int] | None = None,
286
287
  ) -> list[tuple[FileInfo, float, list[str]]]:
287
288
  from agentpack.core.models import DependencyGraph as _DG
288
289
  if not isinstance(dep_graph, _DG):
@@ -292,6 +293,12 @@ def score_files(
292
293
  results: list[tuple[FileInfo, float, list[str]]] = []
293
294
  recently_set = set(recently_modified[:20])
294
295
 
296
+ churn_threshold: int | None = None
297
+ if churn_counts:
298
+ vals = sorted(churn_counts.values(), reverse=True)
299
+ cutoff_idx = max(0, len(vals) // 10 - 1) # top 10%
300
+ churn_threshold = vals[cutoff_idx] if vals else None
301
+
295
302
  for fi in files:
296
303
  if fi.ignored or fi.binary:
297
304
  results.append((fi, w.ignored_penalty, ["ignored/binary"]))
@@ -368,10 +375,20 @@ def score_files(
368
375
  score += w.config_file
369
376
  reasons.append("config file")
370
377
 
378
+ if _is_knowledge_file(fi.path):
379
+ score += w.knowledge_file
380
+ reasons.append("knowledge/architecture doc")
381
+
371
382
  if fi.path in recently_set:
372
383
  score += w.recently_modified
373
384
  reasons.append("recently modified")
374
385
 
386
+ if churn_counts and churn_threshold is not None:
387
+ count = churn_counts.get(fi.path, 0)
388
+ if count >= churn_threshold:
389
+ score += w.churn_high
390
+ reasons.append(f"high churn ({count} commits)")
391
+
375
392
  if fi.too_large and score < 50:
376
393
  score += w.large_unrelated_penalty
377
394
  reasons.append("large unrelated file")
@@ -381,6 +398,43 @@ def score_files(
381
398
  return results
382
399
 
383
400
 
401
+ def boost_paired_tests(
402
+ scored: list[tuple[FileInfo, float, list[str]]],
403
+ weights: ScoringWeights | None = None,
404
+ ) -> list[tuple[FileInfo, float, list[str]]]:
405
+ """Boost test files that pair with high-scoring source files.
406
+
407
+ Only applies to test files not already boosted by changed_paths.
408
+ Threshold: source must score above the median non-test score.
409
+ """
410
+ w = weights or _DEFAULT_WEIGHTS
411
+ non_test_scores = [
412
+ score for fi, score, _ in scored
413
+ if not fi.ignored and not fi.binary and not _is_test_file(fi.path) and score > 0
414
+ ]
415
+ if not non_test_scores:
416
+ return scored
417
+ threshold = sorted(non_test_scores)[len(non_test_scores) // 2] # median
418
+
419
+ source_scores = {
420
+ fi.path: score for fi, score, _ in scored
421
+ if not _is_test_file(fi.path) and score >= threshold
422
+ }
423
+
424
+ result = []
425
+ for fi, score, reasons in scored:
426
+ if _is_test_file(fi.path):
427
+ already_boosted = any("test for" in r for r in reasons)
428
+ if not already_boosted:
429
+ for src_path, src_score in source_scores.items():
430
+ if _test_matches_source(fi.path, src_path):
431
+ score += w.related_test
432
+ reasons = reasons + [f"test for high-scoring {src_path}"]
433
+ break
434
+ result.append((fi, score, reasons))
435
+ return result
436
+
437
+
384
438
  def _is_test_file(path: str) -> bool:
385
439
  p = Path(path)
386
440
  return (
@@ -405,3 +459,24 @@ def _is_config_file(path: str) -> bool:
405
459
  p.suffix.lower() in CONFIG_EXTENSIONS
406
460
  or p.stem.lower() in CONFIG_NAMES
407
461
  )
462
+
463
+
464
+ _KNOWLEDGE_NAMES = {
465
+ "decisions", "adr", "architecture", "contributing", "design",
466
+ "technical", "tradeoffs", "rfc", "proposal",
467
+ }
468
+ _KNOWLEDGE_DIRS = {"adr", "adrs", "decisions", "rfcs", "proposals", "design"}
469
+
470
+
471
+ def _is_knowledge_file(path: str) -> bool:
472
+ p = Path(path)
473
+ stem_lower = p.stem.lower()
474
+ # Match ADR-NNN.md patterns and known doc names
475
+ if stem_lower in _KNOWLEDGE_NAMES:
476
+ return p.suffix.lower() == ".md"
477
+ if re.match(r"adr[-_]?\d+", stem_lower):
478
+ return True
479
+ # Any .md file in a known docs dir
480
+ if any(part.lower() in _KNOWLEDGE_DIRS for part in p.parts):
481
+ return p.suffix.lower() == ".md"
482
+ return False
@@ -16,7 +16,7 @@ from agentpack.core import git
16
16
  from agentpack.core.context_pack import select_files, save_pack_metadata
17
17
  from agentpack.core.models import ContextPack, DependencyGraph, FileInfo, ScanResult, SelectedFile, Receipt
18
18
  from agentpack.core.token_estimator import estimate_tokens
19
- from agentpack.analysis.ranking import score_files, extract_keywords, enrich_keywords_from_files
19
+ from agentpack.analysis.ranking import score_files, extract_keywords, enrich_keywords_from_files, boost_paired_tests
20
20
  from agentpack.analysis.tests import find_related_tests
21
21
  from agentpack.analysis import dependency_graph as dep_graph_mod
22
22
  from agentpack.summaries.base import build_all_summaries
@@ -128,7 +128,9 @@ class FileRanker:
128
128
  task: str,
129
129
  cfg: Any,
130
130
  summaries: dict | None = None,
131
+ root: Path | None = None,
131
132
  ) -> RankResult:
133
+ from agentpack.core import git as _git
132
134
  keywords = extract_keywords(task)
133
135
  keywords = enrich_keywords_from_files(keywords, changes.all_changed, packable)
134
136
  all_paths = {f.path for f in packable}
@@ -137,6 +139,10 @@ class FileRanker:
137
139
  tests = find_related_tests(fi.path, all_paths)
138
140
  dep_graph.nodes[fi.path].tests = tests
139
141
 
142
+ churn_counts: dict[str, int] = {}
143
+ if root is not None and _git.is_git_repo(root):
144
+ churn_counts = _git.file_churn_counts(root)
145
+
140
146
  scored = score_files(
141
147
  packable,
142
148
  changed_paths=changes.all_changed,
@@ -148,7 +154,9 @@ class FileRanker:
148
154
  include_configs=cfg.context.include_configs,
149
155
  weights=cfg.scoring,
150
156
  summaries=summaries,
157
+ churn_counts=churn_counts,
151
158
  )
159
+ scored = boost_paired_tests(scored, weights=cfg.scoring)
152
160
  return RankResult(keywords=keywords, scored=scored)
153
161
 
154
162
 
@@ -188,7 +196,7 @@ class PackPlanner:
188
196
  phase_times["changes"] = time.perf_counter() - t0
189
197
 
190
198
  t0 = time.perf_counter()
191
- rank_result = FileRanker().rank(packable, changes, dep_graph, request.task, cfg, summaries=summaries)
199
+ rank_result = FileRanker().rank(packable, changes, dep_graph, request.task, cfg, summaries=summaries, root=root)
192
200
  phase_times["rank"] = time.perf_counter() - t0
193
201
 
194
202
  t0 = time.perf_counter()
@@ -74,8 +74,9 @@ def register(app: typer.Typer) -> None:
74
74
  installer = CodexInstaller()
75
75
  action = installer.patch_agents_md(root)
76
76
  console.print(f"[green]AGENTS.md {action}.[/]")
77
- _print_auto_repack_results(installer.install_auto_repack(root))
78
- console.print(" Run [bold]agentpack pack --task \"<task>\"[/] to generate context.")
77
+ if not global_install:
78
+ _print_auto_repack_results(installer.install_auto_repack(root))
79
+ console.print(" Run [bold]agentpack pack --agent codex --task \"<task>\"[/] to generate context.")
79
80
 
80
81
  elif agent == "antigravity":
81
82
  installer = AntigravityInstaller()
@@ -61,7 +61,9 @@ class ScoringWeights(BaseModel):
61
61
  reverse_dep: float = 40
62
62
  related_test: float = 35
63
63
  config_file: float = 25
64
+ knowledge_file: float = 30
64
65
  recently_modified: float = 20
66
+ churn_high: float = 15 # file appears in top 10% by churn
65
67
  large_unrelated_penalty: float = -50
66
68
  ignored_penalty: float = -100
67
69
 
@@ -106,7 +108,9 @@ direct_dep = 50
106
108
  reverse_dep = 40
107
109
  related_test = 35
108
110
  config_file = 25
111
+ knowledge_file = 30
109
112
  recently_modified = 20
113
+ churn_high = 15
110
114
  large_unrelated_penalty = -50
111
115
  ignored_penalty = -100
112
116
  """
@@ -74,6 +74,26 @@ def changed_files_since(root: Path, ref: str) -> set[str]:
74
74
  return result
75
75
 
76
76
 
77
+ def file_churn_counts(root: Path, max_commits: int = 200) -> dict[str, int]:
78
+ """Return commit count per file from the last max_commits commits.
79
+
80
+ Uses a single git log call — O(1) subprocess, not O(n files).
81
+ Returns empty dict if not a git repo or git unavailable.
82
+ """
83
+ out = _run(
84
+ ["git", "log", "--name-only", "--format=", f"-{max_commits}"],
85
+ root,
86
+ )
87
+ if not out:
88
+ return {}
89
+ counts: dict[str, int] = {}
90
+ for line in out.splitlines():
91
+ line = line.strip()
92
+ if line:
93
+ counts[line] = counts.get(line, 0) + 1
94
+ return counts
95
+
96
+
77
97
  def infer_task_from_git(root: Path) -> str:
78
98
  """Infer a task description from branch name, changed files, and recent commits.
79
99
 
@@ -8,14 +8,13 @@ _AGENTPACK_BLOCK = """\
8
8
  <!-- agentpack:start -->
9
9
  ## AgentPack Context
10
10
 
11
- AgentPack keeps context fresh automatically. When a session is running:
11
+ At the start of every coding task:
12
12
 
13
- 1. Check `.agentpack/session.json` if `"active": true`, read `.agentpack/context.md`.
14
- 2. When the user gives you a new coding task, write a one-line summary to `.agentpack/task.md`.
15
- 3. Re-read `.agentpack/context.md` after watch mode refreshes it (a few seconds).
16
- 4. Prefer files listed in context, but verify with actual code before editing.
13
+ 1. Write a one-line task summary to `.agentpack/task.md` (overwrite the whole file).
14
+ 2. Read `.agentpack/context.claude.md` context is injected automatically via session hooks.
15
+ 3. Use files listed in context as starting points, but verify with actual code before editing.
17
16
 
18
- If no session is running, generate context manually:
17
+ If context is missing or stale, regenerate manually:
19
18
 
20
19
  ```bash
21
20
  agentpack pack --agent claude --task "<task>"
@@ -9,13 +9,12 @@ _AGENTPACK_BLOCK = """\
9
9
  <!-- agentpack:start -->
10
10
  ## AgentPack Context
11
11
 
12
- If `.agentpack/session.json` exists and `"active": true`:
12
+ At the start of every coding task:
13
13
 
14
- 1. Read `.agentpack/context.md` before making code changes.
15
- 2. For a new coding task, write a one-line summary to `.agentpack/task.md`.
16
- 3. Re-read `.agentpack/context.md` after watch mode refreshes it.
17
- 4. Use AgentPack-selected files as starting points, not as absolute truth.
18
- 5. If context is missing or stale: `agentpack session refresh`
14
+ 1. Write a one-line task summary to `.agentpack/task.md` (overwrite the whole file).
15
+ 2. Run `agentpack pack --task auto` to refresh context.
16
+ 3. Read `.agentpack/context.md` it lists the files most relevant to your task.
17
+ 4. Use those files as starting points, but verify with actual code before editing.
19
18
  <!-- agentpack:end -->"""
20
19
 
21
20
  _BLOCK_RE = re.compile(
@@ -8,9 +8,11 @@ from agentpack.integrations.vscode_tasks import install_vscode_tasks
8
8
 
9
9
  _CURSOR_RULE = """\
10
10
  <!-- agentpack:rule:start -->
11
- If `.agentpack/session.json` exists and active, read `.agentpack/context.md` at the start of every conversation.
12
- For a new task, update `.agentpack/task.md` with a one-line summary.
13
- If context is stale or missing: agentpack session refresh
11
+ At the start of every coding task:
12
+ 1. Write a one-line task summary to `.agentpack/task.md` (overwrite the whole file).
13
+ 2. Read `.agentpack/context.md` git hooks keep it fresh automatically.
14
+ 3. Use files listed in context as starting points, but verify with actual code before editing.
15
+ If context is missing: `agentpack pack --agent cursor --task "<task>"`
14
16
  <!-- agentpack:rule:end -->"""
15
17
 
16
18
  _RULE_RE = re.compile(
@@ -53,12 +55,13 @@ description: AgentPack session context injection
53
55
  alwaysApply: true
54
56
  ---
55
57
 
56
- When working in this repository:
58
+ At the start of every coding task:
57
59
 
58
- 1. Check `.agentpack/session.json` if `"active": true`, read `.agentpack/context.md` before editing code.
59
- 2. For a new user task, write a one-line summary to `.agentpack/task.md`.
60
- 3. Prefer files with high AgentPack scores as starting points.
61
- 4. If context seems unrelated to the task, run: `agentpack session refresh`
60
+ 1. Write a one-line task summary to `.agentpack/task.md` (overwrite the whole file).
61
+ 2. Read `.agentpack/context.md` git hooks keep it fresh automatically.
62
+ 3. Use files listed in context as starting points, but verify with actual code before editing.
63
+
64
+ If context is missing: `agentpack pack --agent cursor --task "<task>"`
62
65
  """
63
66
  already = mdc_path.exists()
64
67
  if already and mdc_path.read_text() == content:
@@ -8,9 +8,11 @@ from agentpack.integrations.vscode_tasks import install_vscode_tasks
8
8
 
9
9
  _WINDSURF_RULE = """\
10
10
  <!-- agentpack:rule:start -->
11
- If `.agentpack/session.json` exists and active, read `.agentpack/context.md` at the start of every conversation.
12
- For a new task, update `.agentpack/task.md` with a one-line summary.
13
- If context is stale or missing: agentpack session refresh
11
+ At the start of every coding task:
12
+ 1. Write a one-line task summary to `.agentpack/task.md` (overwrite the whole file).
13
+ 2. Read `.agentpack/context.md` git hooks keep it fresh automatically.
14
+ 3. Use files listed in context as starting points, but verify with actual code before editing.
15
+ If context is missing: `agentpack pack --agent windsurf --task "<task>"`
14
16
  <!-- agentpack:rule:end -->"""
15
17
 
16
18
  _RULE_RE = re.compile(
File without changes
File without changes