@event4u/agent-config 3.1.1 → 3.3.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 (96) hide show
  1. package/.agent-src/commands/agent-status.md +1 -1
  2. package/.agent-src/commands/analytics/prune.md +78 -0
  3. package/.agent-src/commands/analytics/show.md +107 -0
  4. package/.agent-src/commands/analytics.md +64 -0
  5. package/.agent-src/commands/knowledge/forget.md +104 -0
  6. package/.agent-src/commands/knowledge/ingest.md +122 -0
  7. package/.agent-src/commands/knowledge/list.md +102 -0
  8. package/.agent-src/commands/knowledge.md +75 -0
  9. package/.agent-src/scripts/update_roadmap_progress.py +1 -1
  10. package/.agent-src/skills/compress-memory/SKILL.md +1 -1
  11. package/.agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  12. package/.claude-plugin/marketplace.json +8 -1
  13. package/AGENTS.md +5 -4
  14. package/CHANGELOG.md +54 -222
  15. package/README.md +12 -2
  16. package/dist/discovery/deprecation-report.md +1 -1
  17. package/dist/discovery/discovery-manifest.json +164 -10
  18. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  19. package/dist/discovery/discovery-manifest.summary.md +3 -3
  20. package/dist/discovery/orphan-report.md +1 -1
  21. package/dist/discovery/packs.json +12 -5
  22. package/dist/discovery/trust-report.md +2 -2
  23. package/dist/discovery/workspaces.json +11 -4
  24. package/dist/mcp/mcp-cloudflare-catalogue.json +2 -0
  25. package/dist/mcp/registry-manifest.json +5 -3
  26. package/docs/architecture.md +1 -1
  27. package/docs/archive/CHANGELOG-pre-3.2.0.md +268 -0
  28. package/docs/benchmarks.md +4 -4
  29. package/docs/catalog.md +9 -2
  30. package/docs/contracts/CHANGELOG-conventions.md +20 -1
  31. package/docs/contracts/adr-mcp-runtime.md +1 -1
  32. package/docs/contracts/at-rest-encryption.md +146 -0
  33. package/docs/contracts/benchmark-corpus-spec.md +3 -3
  34. package/docs/contracts/benchmark-report-schema.md +5 -5
  35. package/docs/contracts/caveman-telemetry.md +4 -4
  36. package/docs/contracts/compression-default-kill-criterion.md +5 -5
  37. package/docs/contracts/cost-enforcement.md +1 -1
  38. package/docs/contracts/daily-workspace.md +137 -0
  39. package/docs/contracts/explain-modes.md +146 -0
  40. package/docs/contracts/host-agent-protocol.md +88 -0
  41. package/docs/contracts/local-analytics.md +148 -0
  42. package/docs/contracts/local-knowledge-ingestion.md +96 -0
  43. package/docs/contracts/mcp-beta-criteria.md +1 -1
  44. package/docs/contracts/mcp-cloud-scope.md +4 -4
  45. package/docs/contracts/mcp-registry-manifest.schema.json +1 -1
  46. package/docs/contracts/mcp-tool-inventory.md +1 -1
  47. package/docs/contracts/mcp-tool-stub-envelope.md +1 -1
  48. package/docs/contracts/measurement-baseline.md +6 -6
  49. package/docs/contracts/role-experience.md +121 -0
  50. package/docs/contracts/workspace-documents.md +140 -0
  51. package/docs/decisions/ADR-022-daily-workspace-decomposition.md +140 -0
  52. package/docs/decisions/ADR-023-host-agent-protocol.md +129 -0
  53. package/docs/decisions/ADR-024-workspace-v0-feature-floor.md +126 -0
  54. package/docs/decisions/ADR-025-workspace-chrome.md +119 -0
  55. package/docs/decisions/ADR-026-explain-mode-translation.md +117 -0
  56. package/docs/decisions/ADR-027-changelog-machine-vs-manual.md +129 -0
  57. package/docs/decisions/ADR-028-root-layout.md +147 -0
  58. package/docs/decisions/ADR-029-multi-workspace-deferred.md +122 -0
  59. package/docs/decisions/INDEX.md +8 -0
  60. package/docs/deploy/small-team-recipe.md +148 -0
  61. package/docs/deploy/team-deployment-posture.md +91 -0
  62. package/docs/getting-started-by-role.md +27 -0
  63. package/docs/getting-started.md +1 -1
  64. package/docs/guides/local-analytics.md +125 -0
  65. package/docs/guides/local-knowledge.md +127 -0
  66. package/docs/mcp-server.md +1 -1
  67. package/docs/parity/bench-ruflo.json +3 -3
  68. package/docs/parity/ruflo.md +1 -1
  69. package/docs/setup/mcp-client-config.md +1 -1
  70. package/docs/setup/mcp-cloud-endpoints.md +1 -1
  71. package/docs/setup/mcp-cloud-setup.md +2 -2
  72. package/docs/setup/mcp-r2-bootstrap.md +1 -1
  73. package/package.json +4 -2
  74. package/scripts/__pycache__/validate_frontmatter.cpython-312.pyc +0 -0
  75. package/scripts/_lib/__pycache__/__init__.cpython-312.pyc +0 -0
  76. package/scripts/_lib/__pycache__/agent_src.cpython-312.pyc +0 -0
  77. package/scripts/_lib/bench_caveman.py +2 -2
  78. package/scripts/_lib/bench_caveman_report.py +1 -1
  79. package/scripts/_lib/bench_cost.py +2 -2
  80. package/scripts/_lib/bench_report.py +2 -2
  81. package/scripts/_lib/changelog_eras.py +330 -0
  82. package/scripts/audit_mcp_tools.py +1 -1
  83. package/scripts/bench_baseline_ready.py +3 -3
  84. package/scripts/bench_compress_memory.py +4 -4
  85. package/scripts/bench_drift_check.py +2 -2
  86. package/scripts/bench_per_tool.py +2 -2
  87. package/scripts/bench_run.py +4 -4
  88. package/scripts/build_mcp_registry_manifest.py +2 -2
  89. package/scripts/mcp_server/__init__.py +1 -1
  90. package/scripts/mcp_server/catalog.py +1 -1
  91. package/scripts/mcp_server/consumer_tool_catalog.json +1 -1
  92. package/scripts/mcp_server/tools.py +1 -1
  93. package/scripts/memory_lookup.py +78 -1
  94. package/scripts/pack_mcp_content.py +6 -6
  95. package/scripts/release.py +93 -3
  96. package/scripts/skill_trigger_eval.py +2 -2
@@ -47,6 +47,16 @@ from dataclasses import dataclass
47
47
  from datetime import date as _date
48
48
  from pathlib import Path
49
49
 
50
+ from _lib.changelog_eras import (
51
+ CURRENT_ERA_BODY_CAP,
52
+ SplitPlan,
53
+ current_era_body_size,
54
+ current_era_insertion_point,
55
+ perform_split,
56
+ plan_split,
57
+ read_changelog_lines,
58
+ )
59
+
50
60
  REPO_ROOT = Path(__file__).resolve().parent.parent
51
61
  PACKAGE_JSON = REPO_ROOT / "package.json"
52
62
  MARKETPLACE_JSON = REPO_ROOT / ".claude-plugin" / "marketplace.json"
@@ -96,6 +106,10 @@ class Plan:
96
106
  last_tag: str | None
97
107
  changelog_body: str # rendered body (without the heading)
98
108
  changelog_entry: str # full entry including heading, for CHANGELOG.md
109
+ # Populated only when the release crosses an era boundary AND the
110
+ # current era body has grown past CURRENT_ERA_BODY_CAP. None for
111
+ # patch releases and for minor/major bumps where the era still fits.
112
+ split_plan: SplitPlan | None = None
99
113
 
100
114
 
101
115
  # ─── utilities ────────────────────────────────────────────────────────────────
@@ -453,16 +467,32 @@ def _render_test_trend_line(prev_tag: str | None) -> str | None:
453
467
 
454
468
 
455
469
  def prepend_changelog(path: Path, entry: str) -> None:
456
- """Insert `entry` directly above the most recent `## [` heading."""
470
+ """Insert ``entry`` inside the current era block.
471
+
472
+ Strategy delegates to ``current_era_insertion_point`` so a fresh
473
+ era (no version headings yet, just the intro blockquote) places the
474
+ new entry after the intro instead of appended at end-of-file. When
475
+ no current era header exists, falls back to the legacy "above the
476
+ most recent ## [" heuristic for safety.
477
+ """
457
478
  text = path.read_text(encoding="utf-8")
479
+ lines = text.splitlines()
480
+ insert_at = current_era_insertion_point(lines)
481
+ if insert_at is not None:
482
+ before = "\n".join(lines[:insert_at])
483
+ after = "\n".join(lines[insert_at:])
484
+ head = before + ("\n" if before else "")
485
+ path.write_text(head + entry + "\n" + after + "\n", encoding="utf-8")
486
+ return
487
+
488
+ # Legacy fallback — no era header present at all.
458
489
  marker_re = re.compile(r"^## \[?\d+\.\d+\.\d+", re.MULTILINE)
459
490
  m = marker_re.search(text)
460
491
  if not m:
461
- # No prior release heading — append after the introduction.
462
492
  path.write_text(text.rstrip() + "\n\n" + entry, encoding="utf-8")
463
493
  return
464
494
  before = text[: m.start()]
465
- after = text[m.start() :]
495
+ after = text[m.start():]
466
496
  path.write_text(before + entry + "\n" + after, encoding="utf-8")
467
497
 
468
498
 
@@ -579,6 +609,14 @@ def print_preview(plan: Plan) -> None:
579
609
  print(f" · {CHANGELOG.relative_to(REPO_ROOT)}")
580
610
  print(" · regenerated derived files via `task release-prepare`")
581
611
  print(" (packages/*/pack.yaml + README.md, .agent-src/, tool projections)")
612
+ if plan.split_plan is not None:
613
+ sp = plan.split_plan
614
+ print()
615
+ print("Era split (separate commit, before release commit):")
616
+ print(f" · archive → {sp.archive_path.relative_to(REPO_ROOT)}")
617
+ print(f" · old era → pre-{sp.boundary} (archived pointer)")
618
+ print(f" · new era → {sp.new_era_label} — current (empty body)")
619
+ print(f" · subject → {sp.commit_subject}")
582
620
  print()
583
621
  print("Changelog section:")
584
622
  print("─" * 72)
@@ -635,6 +673,39 @@ def execute(
635
673
  _step(1, total, f"Create branch {branch}")
636
674
  run("git", "checkout", "-b", branch)
637
675
 
676
+ # ─── 1b. era split (optional, separate commit) ─────────────────────────
677
+ # Lands as `chore(changelog): split era ...` BEFORE the release commit
678
+ # so the split is reviewable on its own and the release commit only
679
+ # touches the bump + new entry. Idempotent: archive already on disk
680
+ # OR a prior split commit on the branch is treated as already done.
681
+ if plan.split_plan is not None and not pr_merged:
682
+ sp = plan.split_plan
683
+ split_already_committed = (
684
+ sp.commit_subject
685
+ in git("log", f"{MAIN_BRANCH}..HEAD", "--format=%s", capture=True)
686
+ .splitlines()
687
+ )
688
+ if sp.archive_path.exists() and split_already_committed:
689
+ _step(
690
+ 1, total,
691
+ f"Era split for pre-{sp.boundary} already committed — skip",
692
+ )
693
+ elif sp.archive_path.exists() and not split_already_committed:
694
+ die(
695
+ f"era archive {sp.archive_path.relative_to(REPO_ROOT)} exists "
696
+ "but no matching split commit found on this branch — inspect "
697
+ "manually before resuming"
698
+ )
699
+ else:
700
+ _step(
701
+ 1, total,
702
+ f"Split era {sp.old_era_label} → pre-{sp.boundary} "
703
+ f"(new era {sp.new_era_label})",
704
+ )
705
+ perform_split(sp)
706
+ run("git", "add", "-A")
707
+ run("git", "commit", "-m", sp.commit_subject)
708
+
638
709
  # ─── 2. file mutations ──────────────────────────────────────────────────
639
710
  if pr_merged:
640
711
  _step(2, total, "PR already merged — skip file bumps")
@@ -883,6 +954,24 @@ def main(argv: list[str] | None = None) -> int:
883
954
  full, body = render_changelog_entry(
884
955
  target, prev, commits, today, test_trend_line=test_trend_line
885
956
  )
957
+
958
+ # Era-split planning: only crosses the gate when the current era body
959
+ # has grown past the drift cap AND the release crosses a minor/major
960
+ # boundary. Patch overflow is caught by the drift test (red CI), not
961
+ # by an auto-split into a nonsensical "pre-X.Y.Z" archive.
962
+ split: SplitPlan | None = None
963
+ body_size = current_era_body_size()
964
+ if body_size > CURRENT_ERA_BODY_CAP:
965
+ candidate = plan_split(target)
966
+ if candidate is None:
967
+ die(
968
+ f"current era body is {body_size} lines (cap "
969
+ f"{CURRENT_ERA_BODY_CAP}) but release {target} is a patch "
970
+ f"within the same era — split needs a minor/major bump. "
971
+ "Cut a minor release or split CHANGELOG.md manually first."
972
+ )
973
+ split = candidate
974
+
886
975
  plan = Plan(
887
976
  current=current,
888
977
  target=target,
@@ -891,6 +980,7 @@ def main(argv: list[str] | None = None) -> int:
891
980
  last_tag=prev,
892
981
  changelog_body=body,
893
982
  changelog_entry=full,
983
+ split_plan=split,
894
984
  )
895
985
  print_preview(plan)
896
986
  if args.resume:
@@ -35,7 +35,7 @@ from typing import Callable, IO, Protocol
35
35
 
36
36
  PROJECT_ROOT = Path(__file__).resolve().parent.parent
37
37
  SKILLS_SOURCE = PROJECT_ROOT / ".agent-src.uncompressed" / "skills"
38
- RESULTS_DIR = PROJECT_ROOT / "evals" / "results"
38
+ RESULTS_DIR = PROJECT_ROOT / "internal" / "evals" / "results"
39
39
  DEFAULT_MODEL = "claude-sonnet-4-5"
40
40
 
41
41
  # Approximate Anthropic API pricing (USD per 1M tokens). Used for the
@@ -577,7 +577,7 @@ def build_arg_parser() -> argparse.ArgumentParser:
577
577
  type=Path,
578
578
  default=None,
579
579
  help=(
580
- "Path to write the result. Default: evals/results/"
580
+ "Path to write the result. Default: internal/evals/results/"
581
581
  "<timestamp>-<skill>-<model>.json (live) or "
582
582
  "<triggers-dir>/last-run.json (dry-run)."
583
583
  ),