@event4u/agent-config 1.18.0 → 1.20.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.
Files changed (181) hide show
  1. package/.agent-src/commands/agent-handoff.md +14 -10
  2. package/.agent-src/commands/chat-history/import.md +170 -0
  3. package/.agent-src/commands/chat-history/learn.md +178 -0
  4. package/.agent-src/commands/chat-history/show.md +17 -18
  5. package/.agent-src/commands/chat-history.md +26 -25
  6. package/.agent-src/commands/council/default.md +77 -82
  7. package/.agent-src/commands/create-pr.md +28 -8
  8. package/.agent-src/commands/feature/roadmap.md +22 -0
  9. package/.agent-src/commands/roadmap/create.md +38 -6
  10. package/.agent-src/commands/roadmap/execute.md +36 -9
  11. package/.agent-src/commands/sync-gitignore.md +1 -1
  12. package/.agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +76 -0
  13. package/.agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +3 -3
  14. package/.agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +5 -12
  15. package/.agent-src/rules/agent-authority.md +1 -0
  16. package/.agent-src/rules/agent-docs.md +1 -0
  17. package/.agent-src/rules/analysis-skill-routing.md +1 -0
  18. package/.agent-src/rules/architecture.md +1 -0
  19. package/.agent-src/rules/artifact-drafting-protocol.md +1 -0
  20. package/.agent-src/rules/artifact-engagement-recording.md +1 -0
  21. package/.agent-src/rules/ask-when-uncertain.md +1 -0
  22. package/.agent-src/rules/augment-portability.md +1 -0
  23. package/.agent-src/rules/augment-source-of-truth.md +1 -0
  24. package/.agent-src/rules/autonomous-execution.md +1 -0
  25. package/.agent-src/rules/capture-learnings.md +1 -0
  26. package/.agent-src/rules/cli-output-handling.md +2 -2
  27. package/.agent-src/rules/command-suggestion-policy.md +1 -0
  28. package/.agent-src/rules/commit-conventions.md +1 -0
  29. package/.agent-src/rules/commit-policy.md +1 -0
  30. package/.agent-src/rules/context-hygiene.md +22 -0
  31. package/.agent-src/rules/direct-answers.md +11 -2
  32. package/.agent-src/rules/docker-commands.md +1 -0
  33. package/.agent-src/rules/docs-sync.md +1 -0
  34. package/.agent-src/rules/downstream-changes.md +1 -0
  35. package/.agent-src/rules/e2e-testing.md +1 -0
  36. package/.agent-src/rules/guidelines.md +1 -0
  37. package/.agent-src/rules/improve-before-implement.md +1 -0
  38. package/.agent-src/rules/language-and-tone.md +38 -6
  39. package/.agent-src/rules/laravel-translations.md +1 -0
  40. package/.agent-src/rules/markdown-safe-codeblocks.md +1 -0
  41. package/.agent-src/rules/minimal-safe-diff.md +1 -0
  42. package/.agent-src/rules/missing-tool-handling.md +1 -0
  43. package/.agent-src/rules/model-recommendation.md +1 -0
  44. package/.agent-src/rules/no-attribution-footers.md +48 -0
  45. package/.agent-src/rules/no-cheap-questions.md +1 -0
  46. package/.agent-src/rules/no-roadmap-references.md +2 -1
  47. package/.agent-src/rules/non-destructive-by-default.md +1 -0
  48. package/.agent-src/rules/onboarding-gate.md +26 -0
  49. package/.agent-src/rules/package-ci-checks.md +1 -0
  50. package/.agent-src/rules/php-coding.md +1 -0
  51. package/.agent-src/rules/preservation-guard.md +1 -0
  52. package/.agent-src/rules/review-routing-awareness.md +1 -0
  53. package/.agent-src/rules/reviewer-awareness.md +1 -0
  54. package/.agent-src/rules/roadmap-progress-sync.md +22 -0
  55. package/.agent-src/rules/role-mode-adherence.md +2 -2
  56. package/.agent-src/rules/rule-type-governance.md +1 -0
  57. package/.agent-src/rules/runtime-safety.md +1 -0
  58. package/.agent-src/rules/scope-control.md +1 -0
  59. package/.agent-src/rules/security-sensitive-stop.md +1 -0
  60. package/.agent-src/rules/size-enforcement.md +1 -0
  61. package/.agent-src/rules/skill-improvement-trigger.md +1 -0
  62. package/.agent-src/rules/skill-quality.md +50 -0
  63. package/.agent-src/rules/slash-command-routing-policy.md +39 -0
  64. package/.agent-src/rules/think-before-action.md +1 -0
  65. package/.agent-src/rules/token-efficiency.md +1 -0
  66. package/.agent-src/rules/tool-safety.md +1 -0
  67. package/.agent-src/rules/ui-audit-gate.md +1 -0
  68. package/.agent-src/rules/upstream-proposal.md +1 -0
  69. package/.agent-src/rules/user-interaction.md +22 -5
  70. package/.agent-src/rules/verify-before-complete.md +1 -0
  71. package/.agent-src/skills/ai-council/SKILL.md +4 -5
  72. package/.agent-src/skills/dcf-modeling/SKILL.md +89 -0
  73. package/.agent-src/skills/funnel-analysis/SKILL.md +100 -0
  74. package/.agent-src/skills/md-language-check/SKILL.md +1 -1
  75. package/.agent-src/skills/okr-tree-modeling/SKILL.md +93 -0
  76. package/.agent-src/skills/rice-prioritization/SKILL.md +100 -0
  77. package/.agent-src/skills/roadmap-management/SKILL.md +29 -4
  78. package/.agent-src/skills/subagent-orchestration/SKILL.md +34 -2
  79. package/.agent-src/skills/unit-economics-modeling/SKILL.md +104 -0
  80. package/.agent-src/skills/using-git-worktrees/SKILL.md +1 -0
  81. package/.agent-src/skills/verify-completion-evidence/SKILL.md +8 -1
  82. package/.agent-src/templates/agent-settings.md +21 -26
  83. package/.agent-src/templates/roadmaps.md +8 -3
  84. package/.agent-src/templates/scripts/work_engine/hook_bootstrap.py +16 -5
  85. package/.agent-src/templates/scripts/work_engine/hooks/__init__.py +4 -4
  86. package/.agent-src/templates/scripts/work_engine/hooks/builtin/__init__.py +4 -4
  87. package/.agent-src/templates/scripts/work_engine/hooks/builtin/_chat_history_base.py +7 -51
  88. package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_append.py +1 -2
  89. package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_halt_append.py +1 -2
  90. package/.agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.py +163 -0
  91. package/.agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.py +110 -0
  92. package/.agent-src/templates/scripts/work_engine/hooks/settings.py +36 -0
  93. package/.agent-src/templates/scripts/work_engine/scoring/decision_trace.py +141 -0
  94. package/.agent-src/templates/scripts/work_engine/scoring/memory_visibility.py +125 -0
  95. package/.agent-src/templates/skill.md +30 -1
  96. package/.claude-plugin/marketplace.json +8 -4
  97. package/AGENTS.md +44 -3
  98. package/CHANGELOG.md +173 -0
  99. package/README.md +22 -22
  100. package/config/agent-settings.template.yml +42 -13
  101. package/config/gitignore-block.txt +4 -4
  102. package/docs/architecture.md +3 -3
  103. package/docs/catalog.md +18 -13
  104. package/docs/contracts/adr-chat-history-split.md +10 -1
  105. package/docs/contracts/adr-settings-sync-engine.md +127 -0
  106. package/docs/contracts/command-clusters.md +1 -1
  107. package/docs/contracts/cross-wing-handoff.md +133 -0
  108. package/docs/contracts/decision-trace-v1.md +146 -0
  109. package/docs/contracts/file-ownership-matrix.json +348 -126
  110. package/docs/contracts/hook-architecture-v1.md +220 -0
  111. package/docs/contracts/memory-visibility-v1.md +122 -0
  112. package/docs/contracts/one-off-script-lifecycle.md +109 -0
  113. package/docs/contracts/rule-interactions.yml +22 -0
  114. package/docs/customization.md +2 -1
  115. package/docs/development.md +4 -1
  116. package/docs/getting-started.md +21 -29
  117. package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +1 -1
  118. package/docs/guidelines/agent-infra/layered-settings.md +32 -13
  119. package/docs/hook-payload-capture.md +221 -0
  120. package/docs/migrations/commands-1.15.0.md +17 -12
  121. package/docs/skills-catalog.md +5 -4
  122. package/llms.txt +4 -3
  123. package/package.json +1 -1
  124. package/scripts/agent-config +45 -1
  125. package/scripts/ai_council/_default_prices.py +4 -4
  126. package/scripts/ai_council/bundler.py +3 -3
  127. package/scripts/ai_council/clients.py +25 -9
  128. package/scripts/ai_council/modes.py +3 -4
  129. package/scripts/ai_council/one_off_archive/2026-05/README.md +22 -0
  130. package/scripts/ai_council/one_off_archive/2026-05/_one_off_roundtrip.py +13 -8
  131. package/scripts/ai_council/one_off_archive/2026-05/_one_off_tier_retrofit.py +180 -0
  132. package/scripts/ai_council/pricing.py +10 -9
  133. package/scripts/ai_council/session.py +92 -0
  134. package/scripts/build_rule_trigger_matrix.py +1 -9
  135. package/scripts/capture_showcase_session.py +361 -0
  136. package/scripts/chat_history.py +963 -597
  137. package/scripts/check_always_budget.py +7 -2
  138. package/scripts/check_references.py +12 -2
  139. package/scripts/context_hygiene_hook.py +14 -6
  140. package/scripts/council_cli.py +407 -0
  141. package/scripts/hook_manifest.yaml +217 -0
  142. package/scripts/hooks/__init__.py +1 -0
  143. package/scripts/hooks/augment-chat-history.sh +10 -0
  144. package/scripts/hooks/augment-dispatcher.sh +72 -0
  145. package/scripts/hooks/cline-dispatcher.sh +86 -0
  146. package/scripts/hooks/cowork-dispatcher.sh +98 -0
  147. package/scripts/hooks/cursor-dispatcher.sh +76 -0
  148. package/scripts/hooks/dispatch_hook.py +383 -0
  149. package/scripts/hooks/envelope.py +98 -0
  150. package/scripts/hooks/gemini-dispatcher.sh +117 -0
  151. package/scripts/hooks/state_io.py +122 -0
  152. package/scripts/hooks/windsurf-dispatcher.sh +123 -0
  153. package/scripts/hooks_status.py +157 -0
  154. package/scripts/install-hooks.sh +2 -2
  155. package/scripts/install.py +725 -87
  156. package/scripts/install.sh +38 -1
  157. package/scripts/lint_handoffs.py +214 -0
  158. package/scripts/lint_hook_manifest.py +217 -0
  159. package/scripts/lint_one_off_age.py +184 -0
  160. package/scripts/lint_rule_tiers.py +78 -0
  161. package/scripts/lint_showcase_sessions.py +148 -0
  162. package/scripts/minimal_safe_diff_hook.py +245 -0
  163. package/scripts/onboarding_gate_hook.py +13 -8
  164. package/scripts/readme_linter.py +12 -3
  165. package/scripts/redact_hook_capture.py +148 -0
  166. package/scripts/roadmap_progress_hook.py +5 -0
  167. package/scripts/schemas/skill.schema.json +5 -0
  168. package/scripts/skill_linter.py +163 -1
  169. package/scripts/sync_agent_settings.py +32 -129
  170. package/scripts/sync_yaml_rt.py +734 -0
  171. package/scripts/update_prices.py +3 -3
  172. package/scripts/verify_before_complete_hook.py +216 -0
  173. package/.agent-src/commands/chat-history/checkpoint.md +0 -126
  174. package/.agent-src/commands/chat-history/clear.md +0 -103
  175. package/.agent-src/commands/chat-history/resume.md +0 -183
  176. package/.agent-src/rules/chat-history-cadence.md +0 -109
  177. package/.agent-src/rules/chat-history-ownership.md +0 -123
  178. package/.agent-src/rules/chat-history-visibility.md +0 -96
  179. package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_heartbeat.py +0 -50
  180. package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_turn_check.py +0 -49
  181. package/scripts/check_phase_coupling.py +0 -148
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- """Refresh `.agent-prices.md` from the LiteLLM model-prices feed.
2
+ """Refresh `agents/.agent-prices.md` from the LiteLLM model-prices feed.
3
3
 
4
4
  Source: https://raw.githubusercontent.com/BerriAI/litellm/main/
5
5
  model_prices_and_context_window.json
@@ -9,7 +9,7 @@ Network failure or invalid response → fall back to
9
9
  always written. Stdlib only; no extra dependency.
10
10
 
11
11
  Usage:
12
- python3 scripts/update_prices.py # writes .agent-prices.md
12
+ python3 scripts/update_prices.py # writes agents/.agent-prices.md
13
13
  python3 scripts/update_prices.py --check # exit 1 if file is stale
14
14
  """
15
15
 
@@ -81,7 +81,7 @@ def _to_rows_from_litellm(payload: dict[str, dict[str, object]]) -> list[tuple[s
81
81
 
82
82
 
83
83
  def refresh(path: Path = PRICES_FILE) -> str:
84
- """Write a fresh `.agent-prices.md`. Returns the source label used."""
84
+ """Write a fresh `agents/.agent-prices.md`. Returns the source label used."""
85
85
  payload = _fetch_litellm()
86
86
  if payload is not None:
87
87
  rows = _to_rows_from_litellm(payload)
@@ -0,0 +1,216 @@
1
+ #!/usr/bin/env python3
2
+ """Platform-agnostic hook for the `verify-before-complete` rule.
3
+
4
+ Records observable evidence that a verification command (tests, quality
5
+ tools, build) ran. The rule body cites the resulting state file as the
6
+ source of truth for the "have I verified this turn?" question. The hook
7
+ itself never blocks — it is observability infra, not control flow.
8
+
9
+ Wired to multiple events via the manifest:
10
+ - session_start / user_prompt_submit → reset turn-scoped counters
11
+ - post_tool_use → inspect tool + command, record verifications
12
+ - stop → record stop fired (claim-done window)
13
+
14
+ Output: `agents/state/verify-before-complete.json`
15
+ {
16
+ "schema_version": 1,
17
+ "session_id": "<str>",
18
+ "turn_started_at": "<iso8601|null>",
19
+ "last_verification": {"command": ..., "tool": ..., "at": ...} | null,
20
+ "verifications_this_turn": <int>,
21
+ "verifications_this_session": <int>,
22
+ "last_stop_at": "<iso8601|null>",
23
+ "verified_this_turn": <bool>,
24
+ "checked_at": "<iso8601>"
25
+ }
26
+
27
+ Exit code is always 0.
28
+ """
29
+ from __future__ import annotations
30
+
31
+ import argparse
32
+ import datetime as _dt
33
+ import json
34
+ import re
35
+ import sys
36
+ from pathlib import Path
37
+
38
+ sys.path.insert(0, str(Path(__file__).resolve().parent))
39
+ from hooks.state_io import atomic_write_json # noqa: E402
40
+
41
+ STATE_FILE = Path("agents") / "state" / "verify-before-complete.json"
42
+
43
+ # Tool names across platforms whose `command` / `tool_input.command` field
44
+ # carries a shell command we can inspect. Edit tools are deliberately
45
+ # excluded — they cannot run verification.
46
+ COMMAND_TOOLS = frozenset({
47
+ "launch-process", "launch_process", # Augment
48
+ "Bash", "BashTool", # Claude Code
49
+ "run-process", "runProcess", # variants
50
+ "shell", "execute_shell", # generic / Cline
51
+ "RunShellCommand", # Cursor
52
+ })
53
+
54
+ # Permissive verification-command pattern. Observability — false positives
55
+ # are cheaper than false negatives. Word-boundary anchored on common
56
+ # shell separators so chained commands (`task sync && task ci`) match.
57
+ _VERIFICATION_RE = re.compile(
58
+ r'(?:^|[\s;&|`(])('
59
+ r'task\s+(?:ci|test|tests|lint|check|qa|phpstan|rector|ecs|pest|pytest)'
60
+ r'|(?:\./|\.venv/bin/|vendor/bin/)?(?:pest|phpunit|phpstan|psalm|rector|ecs)\b'
61
+ r'|(?:python3?|\.venv/bin/python3?)\s+-m\s+pytest'
62
+ r'|pytest\b'
63
+ r'|(?:npm|pnpm|yarn|bun)\s+(?:run\s+)?(?:test|check|lint|typecheck|tsc)'
64
+ r'|cargo\s+(?:test|check|clippy)'
65
+ r'|go\s+test'
66
+ r'|make\s+(?:test|check|lint)'
67
+ r'|composer\s+(?:test|check|lint|phpstan)'
68
+ r'|(?:php\s+)?artisan\s+test'
69
+ r')',
70
+ re.IGNORECASE,
71
+ )
72
+
73
+
74
+ def _now() -> str:
75
+ return _dt.datetime.now(_dt.timezone.utc).isoformat(timespec="seconds")
76
+
77
+
78
+ def _empty_state() -> dict:
79
+ return {
80
+ "schema_version": 1,
81
+ "session_id": "",
82
+ "turn_started_at": None,
83
+ "last_verification": None,
84
+ "verifications_this_turn": 0,
85
+ "verifications_this_session": 0,
86
+ "last_stop_at": None,
87
+ "verified_this_turn": False,
88
+ "checked_at": _now(),
89
+ }
90
+
91
+
92
+ def _load_state(target: Path) -> dict:
93
+ if not target.is_file():
94
+ return _empty_state()
95
+ try:
96
+ decoded = json.loads(target.read_text(encoding="utf-8"))
97
+ if isinstance(decoded, dict):
98
+ return {**_empty_state(), **decoded}
99
+ except (OSError, json.JSONDecodeError):
100
+ pass
101
+ return _empty_state()
102
+
103
+
104
+ def _extract_command(payload: dict) -> tuple[str | None, str | None]:
105
+ """Return (tool_name, command_text) from a tool-event payload."""
106
+ tool = (payload.get("tool_name") or payload.get("toolName")
107
+ or payload.get("tool"))
108
+ if not isinstance(tool, str) or tool not in COMMAND_TOOLS:
109
+ return (tool if isinstance(tool, str) else None, None)
110
+ ti = payload.get("tool_input")
111
+ if isinstance(ti, dict):
112
+ for key in ("command", "cmd", "shell_command"):
113
+ v = ti.get(key)
114
+ if isinstance(v, str) and v:
115
+ return (tool, v)
116
+ # Some platforms surface the command at the top level.
117
+ for key in ("command", "cmd"):
118
+ v = payload.get(key)
119
+ if isinstance(v, str) and v:
120
+ return (tool, v)
121
+ return (tool, None)
122
+
123
+
124
+ def _is_verification(command: str) -> bool:
125
+ return bool(_VERIFICATION_RE.search(command))
126
+
127
+
128
+ def _reset_turn(state: dict, session_id: str) -> dict:
129
+ state["session_id"] = session_id or state.get("session_id") or ""
130
+ state["turn_started_at"] = _now()
131
+ state["verifications_this_turn"] = 0
132
+ state["verified_this_turn"] = False
133
+ return state
134
+
135
+
136
+ def _update(state: dict, event: str, envelope: dict) -> dict:
137
+ session_id = envelope.get("session_id") or state.get("session_id") or ""
138
+ if session_id and session_id != state.get("session_id"):
139
+ # Session boundary — reset session-scoped counters.
140
+ state["session_id"] = session_id
141
+ state["verifications_this_session"] = 0
142
+ state = _reset_turn(state, session_id)
143
+
144
+ payload = envelope.get("payload") or {}
145
+ if not isinstance(payload, dict):
146
+ payload = {}
147
+
148
+ if event in ("session_start", "user_prompt_submit"):
149
+ state = _reset_turn(state, session_id)
150
+ elif event == "post_tool_use":
151
+ tool, cmd = _extract_command(payload)
152
+ if cmd and _is_verification(cmd):
153
+ state["last_verification"] = {
154
+ "command": cmd[:512],
155
+ "tool": tool,
156
+ "at": _now(),
157
+ "platform": envelope.get("platform") or "",
158
+ }
159
+ state["verifications_this_turn"] = int(
160
+ state.get("verifications_this_turn") or 0) + 1
161
+ state["verifications_this_session"] = int(
162
+ state.get("verifications_this_session") or 0) + 1
163
+ state["verified_this_turn"] = True
164
+ elif event == "stop":
165
+ state["last_stop_at"] = _now()
166
+
167
+ state["checked_at"] = _now()
168
+ return state
169
+
170
+
171
+ def run(stdin_text: str, *, consumer_root: Path, verbose: bool = False) -> int:
172
+ envelope: dict = {}
173
+ if stdin_text.strip():
174
+ try:
175
+ decoded = json.loads(stdin_text)
176
+ if isinstance(decoded, dict):
177
+ envelope = decoded
178
+ except json.JSONDecodeError:
179
+ envelope = {}
180
+
181
+ event = envelope.get("event") or ""
182
+ target = consumer_root / STATE_FILE
183
+ state = _load_state(target)
184
+ state = _update(state, event, envelope)
185
+
186
+ try:
187
+ atomic_write_json(target, state)
188
+ except OSError:
189
+ if verbose:
190
+ print("verify-before-complete-hook: state write failed",
191
+ file=sys.stderr)
192
+ return 0
193
+
194
+ if verbose:
195
+ print(
196
+ f"verify-before-complete-hook: event={event} "
197
+ f"verified_this_turn={state.get('verified_this_turn')} "
198
+ f"verifications_this_turn={state.get('verifications_this_turn')}",
199
+ file=sys.stderr,
200
+ )
201
+ return 0
202
+
203
+
204
+ def main(argv: list[str] | None = None) -> int:
205
+ parser = argparse.ArgumentParser(description=__doc__)
206
+ parser.add_argument("--platform", default="generic",
207
+ help="informational platform tag")
208
+ parser.add_argument("--verbose", action="store_true",
209
+ help="emit one stderr line per invocation")
210
+ args = parser.parse_args(argv)
211
+ return run(sys.stdin.read(), consumer_root=Path.cwd(),
212
+ verbose=args.verbose)
213
+
214
+
215
+ if __name__ == "__main__": # pragma: no cover
216
+ sys.exit(main())
@@ -1,126 +0,0 @@
1
- ---
2
- name: chat-history:checkpoint
3
- cluster: chat-history
4
- sub: checkpoint
5
- description: Append a phase-boundary entry to .agent-chat-history — CHECKPOINT fallback for platforms without a native hook (Augment IDE, Cursor pre-1.7, Cline non-Mac/Linux). ~1s.
6
- disable-model-invocation: true
7
- suggestion:
8
- eligible: true
9
- trigger_description: "User wants to flush a chat-history phase boundary on a CHECKPOINT-class platform (Augment IDE, Cursor < 1.7, Cline on Windows) — phrases like 'checkpoint chat history', 'log a phase boundary', 'manual chat-history append'."
10
- trigger_context: "chat_history.path == checkpoint AND a phase-shaped boundary just completed (decision recorded, multi-tool sequence finished, task-list item closed)."
11
- ---
12
- <!-- cloud_safe: noop -->
13
-
14
- # /chat-history checkpoint
15
- Force-append a `phase`-typed entry to `.agent-chat-history`. CHECKPOINT
16
- fallback for platforms without native hooks — see
17
- [`agents/contexts/chat-history-platform-hooks.md`](../../../agents/contexts/chat-history-platform-hooks.md)
18
- for the per-platform classification.
19
-
20
- Use this at decision points, end of phase, or after a meaningful tool
21
- sequence on a CHECKPOINT/MANUAL platform. On HOOK platforms (Claude
22
- Code, Augment CLI, Cursor 1.7+, Cline non-Windows, Windsurf, Gemini
23
- CLI), the platform fires hooks automatically — manual use is allowed
24
- but rarely needed.
25
-
26
- ## When to use
27
-
28
- - IDE plugin without hooks (Augment Code IDE plugin as of 2026-04-30).
29
- - Long-running tool sequence on any platform that did not flush.
30
- - Explicit phase-boundary marker after a multi-tool refactor.
31
- - Crash-recovery rehearsal — verifies the append path works before a
32
- real outage.
33
-
34
- ## When NOT to use
35
-
36
- - HOOK platform mid-session — the platform already records turn-level
37
- cadence; an extra checkpoint just adds noise.
38
- - After every line of agent output — that's `per_turn` cadence and is
39
- configured in `.agent-settings.yml`, not via this command.
40
- - To inspect the log → [`/chat-history`](chat-history.md).
41
- - To wipe the log → [`/chat-history-clear`](chat-history-clear.md).
42
- - To reload the log into context → [`/chat-history-resume`](chat-history-resume.md).
43
-
44
- ## Steps
45
-
46
- ### 1. Check if enabled
47
-
48
- Read `chat_history.enabled` from `.agent-settings.yml`. If `false` or
49
- the section is missing, say so and stop:
50
-
51
- ```
52
- > 📒 chat-history is disabled (chat_history.enabled = false).
53
- > Nothing to checkpoint. Enable in .agent-settings.yml first.
54
- ```
55
-
56
- ### 2. Determine the phase label
57
-
58
- Pick a short label (2–6 words) that names what just happened:
59
-
60
- - "phase-1-done", "refactor-extracted", "tests-green",
61
- "review-comments-fixed", "merge-ready".
62
-
63
- If the user invoked the command without context, ask once with
64
- numbered options per [`user-interaction`](../rules/user-interaction.md):
65
-
66
- ```
67
- > 1. Use a free-text label — type 2–6 words for the checkpoint
68
- > 2. Use a generic "manual-checkpoint" label
69
- > 3. Skip — close without writing
70
- ```
71
-
72
- ### 3. Append the checkpoint
73
-
74
- Invoke the master CLI:
75
-
76
- ```
77
- ./agent-config chat-history:checkpoint \
78
- --first-user-msg "<the conversation's first user message>" \
79
- --payload '{"phase": "<label>"}'
80
- ```
81
-
82
- The wrapper delegates to `scripts/chat_history.py hook-append --event phase`,
83
- which performs cadence filtering and ownership checks. Cadence is read
84
- from `chat_history.frequency` in `.agent-settings.yml` — `per_turn` /
85
- `per_phase` / `per_tool`. `per_tool` cadence drops the `phase` event;
86
- say so explicitly if that is the active mode.
87
-
88
- ### 4. Confirm
89
-
90
- Render a one-line confirmation, mirroring the user's language:
91
-
92
- ```
93
- > 📒 Checkpoint logged: <label> (entries: N → N+1)
94
- ```
95
-
96
- If the helper returned `skipped_cadence`, surface it:
97
-
98
- ```
99
- > 📒 Checkpoint skipped — current cadence is per_tool, phase events are dropped.
100
- > Switch chat_history.frequency to per_phase or per_turn to capture phase boundaries.
101
- ```
102
-
103
- ## Gotchas
104
-
105
- - The command writes through the same ownership-state machine as
106
- hooks — a `foreign` log triggers the
107
- [`chat-history`](../rules/chat-history-ownership.md) Foreign-Prompt before any
108
- append. This is intentional; the checkpoint must not silently
109
- hijack another session's log.
110
- - The `phase` payload key is required. Other keys are accepted but
111
- ignored by the JSONL schema (forward-compat — they may be promoted
112
- to first-class fields later).
113
- - On HOOK platforms, hook entries and checkpoint entries coexist
114
- cleanly. The schema does not deduplicate; if you checkpoint
115
- immediately after a hook fires, expect two adjacent entries with
116
- different `source` values.
117
-
118
- ## See also
119
-
120
- - [`chat-history`](../rules/chat-history-ownership.md) — the rule defining the
121
- conditional Iron Law (HOOK platforms vs CHECKPOINT/MANUAL platforms)
122
- - [`/chat-history`](chat-history.md) — read-only status display
123
- - [`/chat-history-resume`](chat-history-resume.md) — adopt + load
124
- - [`/chat-history-clear`](chat-history-clear.md) — wipe
125
- - [`agents/contexts/chat-history-platform-hooks.md`](../../../agents/contexts/chat-history-platform-hooks.md) — per-platform strategy table
126
- - [`scripts/chat_history.py`](../../../scripts/chat_history.py) — `hook-append` API
@@ -1,103 +0,0 @@
1
- ---
2
- name: chat-history:clear
3
- cluster: chat-history
4
- sub: clear
5
- description: Manually delete the persistent chat-history log — asks for confirmation, optionally archives to a timestamped backup before wiping
6
- disable-model-invocation: true
7
- suggestion:
8
- eligible: false
9
- rationale: "Destructive log wipe — must be deliberate."
10
- ---
11
- <!-- cloud_safe: noop -->
12
-
13
- # /chat-history clear
14
- Wipes `.agent-chat-history`. Use when the log is stale (wrong session),
15
- bloated beyond usefulness, or contains information you do not want
16
- persisted on disk.
17
-
18
- This command is **destructive** — always asks for confirmation before
19
- touching the file, unless the file does not exist in the first place.
20
-
21
- ## When NOT to use
22
-
23
- - Inspect before deleting → [`/chat-history`](chat-history.md).
24
- - Keep the entries but re-point the header → [`/chat-history-resume`](chat-history-resume.md).
25
- - Disable logging entirely → set `chat_history.enabled: false` in
26
- `.agent-settings.yml`; see
27
- [`layered-settings`](../../docs/guidelines/agent-infra/layered-settings.md#section-aware-merge-rules).
28
- Disabling does not delete the existing file; run this command
29
- afterwards if you also want it gone.
30
-
31
- ## Steps
32
-
33
- ### 1. Check current state
34
-
35
- Run `scripts/chat_history.py status`. If `exists: false`, tell the user
36
- and stop:
37
-
38
- ```
39
- > 📒 No .agent-chat-history to clear.
40
- ```
41
-
42
- ### 2. Show what is about to be deleted
43
-
44
- Render a short preview so the user sees what they are wiping:
45
-
46
- ```
47
- > 📒 About to clear .agent-chat-history
48
- >
49
- > Size: {size_kb} KB
50
- > Entries: {entries}
51
- > Session: {short_fp} (started {created_at_relative})
52
- >
53
- > 1. Archive — rename to .agent-chat-history.{YYYYMMDD-HHMMSS}.bak, then start fresh
54
- > 2. Delete — permanent, no backup
55
- > 3. Cancel — keep the file as-is
56
- ```
57
-
58
- ### 3. Act on the choice
59
-
60
- - `1` (Archive) → `mv .agent-chat-history
61
- .agent-chat-history.{timestamp}.bak`. The rule will create a fresh
62
- file on the next append.
63
- - `2` (Delete) → run `scripts/chat_history.py clear`. Permanent.
64
- - `3` (Cancel) → stop. Make no changes.
65
-
66
- Free-text replies ("abbrechen", "keep it", "nevermind") count as `3`.
67
- An unrecognized reply also counts as `3` — never delete on ambiguous
68
- input.
69
-
70
- ### 4. Confirm
71
-
72
- After a successful archive or delete, print a one-line confirmation:
73
-
74
- ```
75
- > 📒 Archived to .agent-chat-history.{timestamp}.bak
76
- ```
77
-
78
- or
79
-
80
- ```
81
- > 📒 .agent-chat-history deleted.
82
- ```
83
-
84
- Do **not** re-enable logging or change `.agent-settings.yml` as a side
85
- effect — this command is scoped to the file on disk only.
86
-
87
- ## Gotchas
88
-
89
- - `.agent-chat-history.*.bak` files are also git-ignored by the
90
- installer's `.gitignore` block. They accumulate if archived often —
91
- users can delete them manually.
92
- - If `chat_history.enabled: false`, the file will **not** be recreated
93
- after clearing. That is usually fine, but mention it so the user
94
- knows the log is now silent.
95
- - Deletion cannot be undone. When in doubt, prefer option `1` (Archive).
96
-
97
- ## See also
98
-
99
- - [`chat-history`](../rules/chat-history-ownership.md) — the rule that writes the file
100
- - [`/chat-history`](chat-history.md) — status inspection
101
- - [`/chat-history-resume`](chat-history-resume.md) — load + adopt instead of wipe
102
- - [`agent-settings` template](../templates/agent-settings.md) — `chat_history.*` reference
103
- - [`scripts/chat_history.py`](../../../scripts/chat_history.py) — helper API
@@ -1,183 +0,0 @@
1
- ---
2
- name: chat-history:resume
3
- cluster: chat-history
4
- sub: resume
5
- description: Load the persistent chat-history log into the current conversation — picks match/returning/foreign flow and supports resume, merge, replace, or continue
6
- disable-model-invocation: true
7
- suggestion:
8
- eligible: false
9
- rationale: "Explicit resume mechanic with foreign/returning state machine."
10
- ---
11
- <!-- cloud_safe: noop -->
12
-
13
- # /chat-history resume
14
- Reconnects the current conversation with an existing `.agent-chat-history`
15
- file. Depending on the 4-state ownership check, it routes to the right
16
- flow: silent summarize, adopt, merge, or replace.
17
-
18
- Use after a crashed chat, after switching tools (Augment → Claude Code),
19
- or when the agent showed the foreign- or returning-session prompt from
20
- the [`chat-history`](../rules/chat-history-ownership.md) rule and the user picked
21
- "resume".
22
-
23
- ## When NOT to use
24
-
25
- - Just inspect metadata → [`/chat-history`](chat-history.md).
26
- - Start fresh instead of resuming → [`/chat-history-clear`](chat-history-clear.md)
27
- or pick "New start" in the foreign prompt.
28
- - Logging is disabled (`chat_history.enabled: false`) → enable it in
29
- `.agent-settings.yml` first; this command refuses to run otherwise.
30
-
31
- ## Preconditions
32
-
33
- - `.agent-settings.yml` exists and `chat_history.enabled: true`.
34
- - `.agent-chat-history` exists at the project root.
35
-
36
- If either is missing, tell the user and stop — do not create files here.
37
-
38
- ## Steps
39
-
40
- ### 1. Load status
41
-
42
- Run `scripts/chat_history.py status`. If `exists: false` or
43
- `entries: 0`, tell the user there is nothing to resume and stop.
44
-
45
- ### 2. Determine ownership state
46
-
47
- Run `scripts/chat_history.py state --first-user-msg "<current first user
48
- message>"`. Branch on the result:
49
-
50
- - `match` → step 3a (already owner)
51
- - `returning` → step 3b (pick Merge / Replace / Continue)
52
- - `foreign` → step 3c (pick Resume / New start / Ignore)
53
- - `missing` → header corrupt; tell the user and suggest
54
- `/chat-history-clear` to start fresh. Stop.
55
-
56
- ### 3a. `match` — already owner
57
-
58
- Nothing to adopt. Skip to step 4 (summarize) for the user's benefit.
59
-
60
- ### 3b. `returning` — this chat once owned the file
61
-
62
- Another session took over. Present the Returning-Prompt from the rule
63
- and wait for a number:
64
-
65
- ```
66
- > 📒 Welcome back. This chat once owned the history file; another
67
- > session has written to it since.
68
- >
69
- > On-file entries: {N} Size: {X} KB
70
- >
71
- > 1. Merge — my in-memory history first, the foreign entries after
72
- > 2. Replace — wipe the foreign entries, keep only my history
73
- > 3. Continue — leave the file as-is; only new entries from now on
74
- ```
75
-
76
- - **1 (Merge)** — build the in-memory entries list (see below), then:
77
- ```bash
78
- scripts/chat_history.py prepend --entries-json '<list>'
79
- scripts/chat_history.py adopt --first-user-msg "<msg>"
80
- ```
81
- - **2 (Replace)** — build the in-memory entries list, then:
82
- ```bash
83
- scripts/chat_history.py reset --first-user-msg "<msg>" \
84
- --freq <frequency> --entries-json '<list>'
85
- ```
86
- - **3 (Continue)** —
87
- ```bash
88
- scripts/chat_history.py adopt --first-user-msg "<msg>"
89
- ```
90
-
91
- ### 3c. `foreign` — new chat finds an unknown session's file
92
-
93
- Present the Foreign-Prompt from the rule and wait for a number:
94
-
95
- ```
96
- > 📒 Found chat history from an unknown session.
97
- >
98
- > Entries on file: {N} Size: {X} KB
99
- >
100
- > 1. Resume — adopt this file, load entries as context, keep appending
101
- > 2. New start — archive to .agent-chat-history.bak, init fresh
102
- > 3. Ignore — leave the file untouched, disable logging for this session
103
- ```
104
-
105
- - **1 (Resume)** — `adopt --first-user-msg "<msg>"`.
106
- - **2 (New start)** — rename file to `.agent-chat-history.bak`, run
107
- `init --first-user-msg "<msg>" --freq <frequency>`. Skip summary.
108
- - **3 (Ignore)** — do nothing. Report that logging is off for this
109
- conversation. Stop.
110
-
111
- ### 3d. Building the in-memory entries list (Merge / Replace)
112
-
113
- Reconstruct the agent's prior turns as a JSON array:
114
-
115
- - one `{"t":"user","text":"<preview>","ts":"<iso>"}` per user message
116
- - one `{"t":"agent","text":"<preview>","ts":"<iso>"}` per agent reply
117
- - `text` previews capped at ~200 chars (whitespace flattened)
118
- - timestamps in ISO-8601 UTC (current time is acceptable if exact times
119
- are unknown; order is what matters)
120
- - no tool-call payloads, no file contents, no secrets
121
-
122
- If the list is large (>30 KB), stream it via stdin:
123
- `prepend --entries-stdin` or `reset --entries-stdin`.
124
-
125
- ### 4. Overflow check
126
-
127
- After any Merge or Replace, run
128
- `scripts/chat_history.py rotate --max-kb <max_size_kb>
129
- --mode <on_overflow>` so the combined body stays within the user's
130
- budget.
131
-
132
- ### 5. Summarize into conversation context
133
-
134
- Read the entries via the helper (`read --all` or `read --last N` for
135
- bounded). Produce a short, structured summary — **not** a verbatim dump:
136
-
137
- ```
138
- > 📒 Resumed chat-history ({entries} entries, {age})
139
- >
140
- > ## What was done
141
- > - {1–3 bullets from agent/decision entries}
142
- >
143
- > ## Open threads
144
- > - {1–3 bullets from the most recent entries and any pending questions}
145
- >
146
- > ## Key decisions
147
- > - {decisions captured during the prior session}
148
- >
149
- > Ready to continue. What would you like to do?
150
- ```
151
-
152
- Keep the summary under ~25 lines. Rationale: this is input into the new
153
- turn, not a display artifact (see
154
- [`token-efficiency`](../rules/token-efficiency.md)).
155
-
156
- ### 6. Hand control back to the user
157
-
158
- After presenting the summary, stop and wait. Do not auto-resume work —
159
- the user decides what to do next.
160
-
161
- ## Gotchas
162
-
163
- - **Iron law — one question at a time.** Even if the log contains
164
- several open threads, ask about one at a time after the summary
165
- (see [`ask-when-uncertain`](../rules/ask-when-uncertain.md)).
166
- - `adopt` rewrites the header in place and pushes the previous fp into
167
- `former_fps` (capped at 10). No backup is created — use
168
- `/chat-history-clear` first if you want a clean slate.
169
- - `reset` discards whatever was on disk. Only use it when the user
170
- explicitly picks "Replace".
171
- - The summary is derived from the agent's reading of the JSONL. Old
172
- entries may be incomplete (especially under `per_turn` with
173
- previews only). Flag gaps explicitly.
174
-
175
- ## See also
176
-
177
- - [`chat-history`](../rules/chat-history-ownership.md) — the rule that triggers
178
- this command via the foreign- and returning-session prompts
179
- - [`/chat-history`](chat-history.md) — status inspection without adopting
180
- - [`/chat-history-clear`](chat-history-clear.md) — wipe instead of adopt
181
- - [`/agent-handoff`](agent-handoff.md) — complementary: generates a
182
- paste-into-new-chat prompt (no disk file)
183
- - [`scripts/chat_history.py`](../../../scripts/chat_history.py) — helper API