@event4u/agent-config 3.1.0 → 3.2.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.
- package/.agent-src/commands/analytics/prune.md +78 -0
- package/.agent-src/commands/analytics/show.md +107 -0
- package/.agent-src/commands/analytics.md +64 -0
- package/.agent-src/commands/knowledge/forget.md +104 -0
- package/.agent-src/commands/knowledge/ingest.md +122 -0
- package/.agent-src/commands/knowledge/list.md +102 -0
- package/.agent-src/commands/knowledge.md +75 -0
- package/.agent-src/scripts/update_roadmap_progress.py +1 -1
- package/.agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/.claude-plugin/marketplace.json +8 -1
- package/CHANGELOG.md +38 -218
- package/README.md +12 -2
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +162 -8
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +12 -5
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +11 -4
- package/dist/mcp/mcp-cloudflare-catalogue.json +2 -0
- package/dist/mcp/registry-manifest.json +5 -3
- package/docs/architecture.md +1 -1
- package/docs/archive/CHANGELOG-pre-3.2.0.md +268 -0
- package/docs/catalog.md +9 -2
- package/docs/contracts/CHANGELOG-conventions.md +19 -0
- package/docs/contracts/at-rest-encryption.md +146 -0
- package/docs/contracts/daily-workspace.md +137 -0
- package/docs/contracts/explain-modes.md +146 -0
- package/docs/contracts/host-agent-protocol.md +88 -0
- package/docs/contracts/local-analytics.md +148 -0
- package/docs/contracts/local-knowledge-ingestion.md +96 -0
- package/docs/contracts/role-experience.md +121 -0
- package/docs/contracts/workspace-documents.md +140 -0
- package/docs/decisions/ADR-022-daily-workspace-decomposition.md +140 -0
- package/docs/decisions/ADR-023-host-agent-protocol.md +129 -0
- package/docs/decisions/ADR-024-workspace-v0-feature-floor.md +126 -0
- package/docs/decisions/ADR-025-workspace-chrome.md +119 -0
- package/docs/decisions/ADR-026-explain-mode-translation.md +117 -0
- package/docs/deploy/small-team-recipe.md +148 -0
- package/docs/deploy/team-deployment-posture.md +91 -0
- package/docs/getting-started-by-role.md +27 -0
- package/docs/getting-started.md +1 -1
- package/docs/guides/local-analytics.md +125 -0
- package/docs/guides/local-knowledge.md +127 -0
- package/package.json +4 -2
- package/scripts/__pycache__/validate_frontmatter.cpython-312.pyc +0 -0
- package/scripts/_lib/__pycache__/__init__.cpython-312.pyc +0 -0
- package/scripts/_lib/__pycache__/agent_src.cpython-312.pyc +0 -0
- package/scripts/_lib/changelog_eras.py +330 -0
- package/scripts/memory_lookup.py +78 -1
- package/scripts/release.py +115 -5
package/scripts/release.py
CHANGED
|
@@ -12,7 +12,11 @@ Pipeline:
|
|
|
12
12
|
since the last tag, render CHANGELOG section.
|
|
13
13
|
3. Confirm — show preview, ask once (skippable with --yes).
|
|
14
14
|
4. Branch + bump — create `release/X.Y.Z`, update package.json,
|
|
15
|
-
.claude-plugin/marketplace.json, CHANGELOG.md
|
|
15
|
+
.claude-plugin/marketplace.json, CHANGELOG.md,
|
|
16
|
+
then run `task release-prepare` so pack
|
|
17
|
+
manifests and tool projections pick up the
|
|
18
|
+
new version (otherwise the PR's own consistency
|
|
19
|
+
check fails — see PR #226 post-mortem).
|
|
16
20
|
5. Commit + push — `release: X.Y.Z`, push branch, open PR.
|
|
17
21
|
6. Wait for CI — `gh pr checks --watch` (skippable with --no-wait).
|
|
18
22
|
7. Merge — `gh pr merge --merge --delete-branch`.
|
|
@@ -43,6 +47,16 @@ from dataclasses import dataclass
|
|
|
43
47
|
from datetime import date as _date
|
|
44
48
|
from pathlib import Path
|
|
45
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
|
+
|
|
46
60
|
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
47
61
|
PACKAGE_JSON = REPO_ROOT / "package.json"
|
|
48
62
|
MARKETPLACE_JSON = REPO_ROOT / ".claude-plugin" / "marketplace.json"
|
|
@@ -92,6 +106,10 @@ class Plan:
|
|
|
92
106
|
last_tag: str | None
|
|
93
107
|
changelog_body: str # rendered body (without the heading)
|
|
94
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
|
|
95
113
|
|
|
96
114
|
|
|
97
115
|
# ─── utilities ────────────────────────────────────────────────────────────────
|
|
@@ -449,16 +467,32 @@ def _render_test_trend_line(prev_tag: str | None) -> str | None:
|
|
|
449
467
|
|
|
450
468
|
|
|
451
469
|
def prepend_changelog(path: Path, entry: str) -> None:
|
|
452
|
-
"""Insert
|
|
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
|
+
"""
|
|
453
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.
|
|
454
489
|
marker_re = re.compile(r"^## \[?\d+\.\d+\.\d+", re.MULTILINE)
|
|
455
490
|
m = marker_re.search(text)
|
|
456
491
|
if not m:
|
|
457
|
-
# No prior release heading — append after the introduction.
|
|
458
492
|
path.write_text(text.rstrip() + "\n\n" + entry, encoding="utf-8")
|
|
459
493
|
return
|
|
460
494
|
before = text[: m.start()]
|
|
461
|
-
after = text[m.start()
|
|
495
|
+
after = text[m.start():]
|
|
462
496
|
path.write_text(before + entry + "\n" + after, encoding="utf-8")
|
|
463
497
|
|
|
464
498
|
|
|
@@ -573,6 +607,16 @@ def print_preview(plan: Plan) -> None:
|
|
|
573
607
|
print(f" · {PACKAGE_JSON.relative_to(REPO_ROOT)}")
|
|
574
608
|
print(f" · {MARKETPLACE_JSON.relative_to(REPO_ROOT)}")
|
|
575
609
|
print(f" · {CHANGELOG.relative_to(REPO_ROOT)}")
|
|
610
|
+
print(" · regenerated derived files via `task release-prepare`")
|
|
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}")
|
|
576
620
|
print()
|
|
577
621
|
print("Changelog section:")
|
|
578
622
|
print("─" * 72)
|
|
@@ -629,6 +673,39 @@ def execute(
|
|
|
629
673
|
_step(1, total, f"Create branch {branch}")
|
|
630
674
|
run("git", "checkout", "-b", branch)
|
|
631
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
|
+
|
|
632
709
|
# ─── 2. file mutations ──────────────────────────────────────────────────
|
|
633
710
|
if pr_merged:
|
|
634
711
|
_step(2, total, "PR already merged — skip file bumps")
|
|
@@ -642,6 +719,15 @@ def execute(
|
|
|
642
719
|
set_marketplace_version(MARKETPLACE_JSON, plan.target)
|
|
643
720
|
prepend_changelog(CHANGELOG, plan.changelog_entry)
|
|
644
721
|
|
|
722
|
+
# Regenerate derived files (pack manifests, .agent-src/, tool
|
|
723
|
+
# projections) so the PR's own consistency check passes. Without
|
|
724
|
+
# this the bump only lands in package.json + marketplace.json and
|
|
725
|
+
# the Sync + Generate Tools Consistency gate fails on the release
|
|
726
|
+
# PR itself — exactly the failure mode PR #226 hit. `task
|
|
727
|
+
# release-prepare` is idempotent, so resume runs are safe.
|
|
728
|
+
_step(2, total, "Regenerate derived files (`task release-prepare`)")
|
|
729
|
+
run("task", "release-prepare")
|
|
730
|
+
|
|
645
731
|
# ─── 3. commit ──────────────────────────────────────────────────────────
|
|
646
732
|
if pr_merged:
|
|
647
733
|
_step(3, total, "PR already merged — skip commit")
|
|
@@ -652,7 +738,12 @@ def execute(
|
|
|
652
738
|
_step(3, total, f"Last commit already `release: {plan.target}` and tree clean — skip")
|
|
653
739
|
else:
|
|
654
740
|
_step(3, total, f"Commit `release: {plan.target}`")
|
|
655
|
-
|
|
741
|
+
# `git add -A` stages the three primary bump files AND every
|
|
742
|
+
# regenerated derived file (packages/*/pack.yaml + README.md,
|
|
743
|
+
# .agent-src/, .augment/, tool projections). Listing them
|
|
744
|
+
# explicitly would silently drift the moment a new generated
|
|
745
|
+
# tree is added.
|
|
746
|
+
run("git", "add", "-A")
|
|
656
747
|
run("git", "commit", "-m", f"release: {plan.target}")
|
|
657
748
|
|
|
658
749
|
# ─── 4. push ────────────────────────────────────────────────────────────
|
|
@@ -863,6 +954,24 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
863
954
|
full, body = render_changelog_entry(
|
|
864
955
|
target, prev, commits, today, test_trend_line=test_trend_line
|
|
865
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
|
+
|
|
866
975
|
plan = Plan(
|
|
867
976
|
current=current,
|
|
868
977
|
target=target,
|
|
@@ -871,6 +980,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
871
980
|
last_tag=prev,
|
|
872
981
|
changelog_body=body,
|
|
873
982
|
changelog_entry=full,
|
|
983
|
+
split_plan=split,
|
|
874
984
|
)
|
|
875
985
|
print_preview(plan)
|
|
876
986
|
if args.resume:
|