@event4u/agent-config 4.2.0 → 4.5.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 (65) hide show
  1. package/.agent-src/commands/agents/user/init.md +7 -13
  2. package/.agent-src/commands/agents/user/show.md +4 -4
  3. package/.agent-src/commands/post-as/me.md +6 -6
  4. package/.agent-src/contexts/execution/autonomy-mechanics.md +1 -1
  5. package/.agent-src/contexts/execution/cheap-question-mechanics.md +4 -0
  6. package/.agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  7. package/.claude-plugin/marketplace.json +1 -1
  8. package/CHANGELOG.md +126 -66
  9. package/config/discovery/packs.yml +9 -1
  10. package/config/discovery/workspaces.yml +14 -1
  11. package/dist/cli/agent-config.js +14 -4
  12. package/dist/cli/agent-config.js.map +1 -1
  13. package/dist/cli/commands/uiServe.js +28 -12
  14. package/dist/cli/commands/uiServe.js.map +1 -1
  15. package/dist/cli/initRouting.js +101 -0
  16. package/dist/cli/initRouting.js.map +1 -0
  17. package/dist/discovery/deprecation-report.md +1 -1
  18. package/dist/discovery/discovery-manifest.json +51 -8
  19. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  20. package/dist/discovery/discovery-manifest.summary.md +3 -3
  21. package/dist/discovery/orphan-report.md +1 -1
  22. package/dist/discovery/packs.json +25 -4
  23. package/dist/discovery/trust-report.md +1 -1
  24. package/dist/discovery/workspaces.json +4 -4
  25. package/dist/install/selectedTools.js +52 -0
  26. package/dist/install/selectedTools.js.map +1 -0
  27. package/dist/install/toolDetection.js +104 -0
  28. package/dist/install/toolDetection.js.map +1 -0
  29. package/dist/mcp/registry-manifest.json +2 -2
  30. package/dist/server/app.js +36 -0
  31. package/dist/server/app.js.map +1 -1
  32. package/dist/server/routes/ping.js +17 -0
  33. package/dist/server/routes/ping.js.map +1 -1
  34. package/dist/server/routes/wizard.js +240 -28
  35. package/dist/server/routes/wizard.js.map +1 -1
  36. package/dist/server/serverInfo.js +54 -0
  37. package/dist/server/serverInfo.js.map +1 -0
  38. package/dist/shared/userMd/formAdapter.js +1 -5
  39. package/dist/shared/userMd/formAdapter.js.map +1 -1
  40. package/dist/shared/userMd/schema.js +2 -1
  41. package/dist/shared/userMd/schema.js.map +1 -1
  42. package/dist/ui/assets/index-J0-0d7RC.js +40 -0
  43. package/dist/ui/assets/index-J0-0d7RC.js.map +1 -0
  44. package/dist/ui/assets/index-ZiC8PbdW.css +1 -0
  45. package/dist/ui/index.html +2 -2
  46. package/docs/archive/CHANGELOG-pre-4.0.0.md +80 -0
  47. package/docs/contracts/agent-user-schema.md +1 -3
  48. package/docs/contracts/discovery-manifest.schema.json +3 -1
  49. package/docs/contracts/gui-wizard.md +113 -18
  50. package/docs/decisions/ADR-013-discovery-frontmatter-contract.md +27 -0
  51. package/docs/decisions/ADR-021-deployment-shape.md +2 -2
  52. package/docs/deploy/connector-setup.md +2 -2
  53. package/docs/deploy/policy-cookbook.md +2 -2
  54. package/docs/examples/agent-user.example.md +0 -1
  55. package/package.json +1 -1
  56. package/scripts/__pycache__/validate_frontmatter.cpython-312.pyc +0 -0
  57. package/scripts/_lib/__pycache__/__init__.cpython-312.pyc +0 -0
  58. package/scripts/_lib/__pycache__/agent_src.cpython-312.pyc +0 -0
  59. package/scripts/build_discovery_manifest.py +4 -0
  60. package/scripts/condense_memory.py +8 -2
  61. package/scripts/install.py +73 -0
  62. package/scripts/lint_discovery_vocabulary.py +8 -0
  63. package/dist/ui/assets/index-BDAhhpDV.js +0 -40
  64. package/dist/ui/assets/index-BDAhhpDV.js.map +0 -1
  65. package/dist/ui/assets/index-BXZILUxe.css +0 -1
@@ -0,0 +1 @@
1
+ :root{--color-bg: #fafafa;--color-surface: #ffffff;--color-surface-alt: #f4f4f5;--color-border: #e4e4e7;--color-border-strong:#a1a1aa;--color-text: #18181b;--color-text-muted: #52525b;--color-text-subtle: #71717a;--color-text-inverse: #fafafa;--color-accent: #2563eb;--color-accent-hover: #1d4ed8;--color-accent-fg: #ffffff;--color-success: #16a34a;--color-warning: #d97706;--color-danger: #dc2626;--color-info: #0284c7;--color-focus-ring: #3b82f6;--font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;--font-mono: ui-monospace, "SFMono-Regular", "Menlo", "Consolas", monospace;--font-size-xs: .75rem;--font-size-sm: .875rem;--font-size-base: 1rem;--font-size-lg: 1.125rem;--font-size-xl: 1.25rem;--font-size-2xl: 1.5rem;--font-size-3xl: 1.875rem;--font-weight-regular:400;--font-weight-medium: 500;--font-weight-bold: 600;--line-height-tight: 1.25;--line-height-base: 1.5;--line-height-loose: 1.75;--space-1: .25rem;--space-2: .5rem;--space-3: .75rem;--space-4: 1rem;--space-5: 1.25rem;--space-6: 1.5rem;--space-8: 2rem;--space-10: 2.5rem;--space-12: 3rem;--space-16: 4rem;--radius-sm: .25rem;--radius-md: .375rem;--radius-lg: .5rem;--radius-xl: .75rem;--radius-full: 9999px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .1), 0 2px 4px -2px rgba(0, 0, 0, .1);--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -4px rgba(0, 0, 0, .1);--shadow-focus:0 0 0 2px var(--color-focus-ring);--duration-fast: .12s;--duration-base: .2s;--duration-slow: .32s;--easing-standard: cubic-bezier(.2, 0, 0, 1);--layout-max-width: 48rem;--layout-side-padding: var(--space-6);--layout-content-gap: var(--space-4);--z-base: 0;--z-overlay: 10;--z-modal: 20;--z-toast: 30}[data-theme=dark]{--color-bg: #09090b;--color-surface: #18181b;--color-surface-alt: #27272a;--color-border: #3f3f46;--color-border-strong:#52525b;--color-text: #fafafa;--color-text-muted: #a1a1aa;--color-text-subtle: #71717a;--color-text-inverse: #18181b;--color-accent: #3b82f6;--color-accent-hover: #60a5fa;--color-accent-fg: #0b1220;--color-success: #22c55e;--color-warning: #f59e0b;--color-danger: #ef4444;--color-info: #38bdf8;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .6);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .7);--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, .8)}@media (prefers-reduced-motion: reduce){:root{--duration-fast: 0ms;--duration-base: 0ms;--duration-slow: 0ms}}*{box-sizing:border-box}html,body{margin:0;padding:0;background:var(--color-bg);color:var(--color-text);font-family:var(--font-sans);font-size:var(--font-size-base);line-height:var(--line-height-base)}a{color:var(--color-accent);text-decoration:none}a:hover{text-decoration:underline}code{font-family:var(--font-mono);font-size:var(--font-size-sm);background:var(--color-surface-alt);padding:0 var(--space-1);border-radius:var(--radius-sm)}#app{min-height:100vh}.ac-dryrun-banner{position:sticky;top:0;z-index:10;padding:var(--space-2) var(--space-4);background:var(--color-warning);color:#fff;border-bottom:1px solid #b45309;font-size:var(--font-size-sm);text-align:center}.ac-dryrun-banner strong{letter-spacing:.08em;text-transform:uppercase}.ac-topnav{position:sticky;top:0;z-index:9;background:var(--color-surface);border-bottom:1px solid var(--color-border)}.ac-topnav__inner{max-width:var(--layout-max-width);margin:0 auto;padding:var(--space-3) var(--layout-side-padding);display:flex;align-items:center;gap:var(--space-4)}.ac-topnav__brand{display:flex;flex-direction:column;gap:0;margin-right:var(--space-2)}.ac-topnav__title{font-size:var(--font-size-sm);font-weight:var(--font-weight-bold);margin:0;line-height:1.2}.ac-topnav__subtitle{margin:0;color:var(--color-text-muted);font-size:var(--font-size-xs)}.ac-topnav__tabs{display:flex;gap:var(--space-1);flex:1;flex-wrap:wrap}.ac-topnav__tab{appearance:none;background:transparent;border:1px solid transparent;color:var(--color-text-muted);padding:var(--space-2) var(--space-3);font:inherit;font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);border-radius:var(--radius-md);cursor:pointer}.ac-topnav__tab:hover{background:var(--color-surface-alt);color:var(--color-text)}.ac-topnav__tab--active{background:var(--color-surface-alt);color:var(--color-accent);border-color:var(--color-border)}.ac-page{max-width:var(--layout-max-width);margin:0 auto;padding:var(--space-8) var(--layout-side-padding);display:flex;flex-direction:column;gap:var(--layout-content-gap)}.ac-page__header{display:flex;justify-content:space-between;align-items:baseline;border-bottom:1px solid var(--color-border);padding-bottom:var(--space-3)}.ac-page h1{font-size:var(--font-size-2xl);font-weight:var(--font-weight-bold);margin:0}.ac-banner{background:var(--color-surface);border:1px solid var(--color-border);border-left:3px solid var(--color-accent);padding:var(--space-3) var(--space-4);border-radius:var(--radius-md)}.ac-banner--error{border-left-color:var(--color-danger)}.ac-section{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:var(--space-5) var(--space-6)}.ac-section__title{font-size:var(--font-size-lg);margin:0 0 var(--space-2)}.ac-section__description{color:var(--color-text-muted);margin:0 0 var(--space-4)}.ac-section__fields{display:flex;flex-direction:column;gap:var(--space-4)}.ac-field{display:flex;flex-direction:column;gap:var(--space-1)}.ac-field__label{font-weight:var(--font-weight-medium);font-size:var(--font-size-sm)}.ac-field__description{color:var(--color-text-muted);font-size:var(--font-size-xs);margin:0}.ac-field__error{color:var(--color-danger);font-size:var(--font-size-xs);margin:0;border-left:3px solid var(--color-danger);padding-left:var(--space-2)}.ac-input,.ac-textarea{font:inherit;color:var(--color-text);background:var(--color-surface);border:1px solid var(--color-border-strong);border-radius:var(--radius-md);padding:var(--space-2) var(--space-3);width:100%}.ac-input:focus,.ac-textarea:focus{outline:none;box-shadow:var(--shadow-focus);border-color:var(--color-focus-ring)}.ac-input[aria-invalid=true],.ac-textarea[aria-invalid=true]{border-color:var(--color-danger)}.ac-input[aria-invalid=true]:focus,.ac-textarea[aria-invalid=true]:focus{border-color:var(--color-danger);box-shadow:0 0 0 3px var(--color-danger-soft, rgba(239, 68, 68, .18))}.ac-textarea{font-family:var(--font-mono);font-size:var(--font-size-sm);resize:vertical}.ac-toggle{display:inline-flex;gap:var(--space-2);align-items:center;cursor:pointer}.ac-radio-group{display:flex;flex-direction:column;gap:var(--space-2)}.ac-radio{display:inline-flex;gap:var(--space-2);align-items:center;cursor:pointer}.ac-field[data-invalid=true] .ac-toggle input[type=checkbox],.ac-field[data-invalid=true] .ac-radio input[type=radio]{outline:2px solid var(--color-danger);outline-offset:2px;border-radius:2px}.ac-button{font:inherit;color:var(--color-text);background:var(--color-surface);border:1px solid var(--color-border-strong);border-radius:var(--radius-md);padding:var(--space-2) var(--space-4);cursor:pointer;transition:background var(--duration-fast) var(--easing-standard)}.ac-button:hover{background:var(--color-surface-alt)}.ac-button:disabled{opacity:.6;cursor:not-allowed}.ac-button--primary{background:var(--color-accent);color:var(--color-accent-fg);border-color:var(--color-accent)}.ac-button--primary:hover{background:var(--color-accent-hover)}.ac-button:focus{outline:none;box-shadow:var(--shadow-focus)}.ac-form{display:flex;flex-direction:column;gap:var(--space-5)}.ac-form__actions{display:flex;justify-content:flex-end;gap:var(--space-2)}.ac-modal{position:fixed;inset:0;background:#00000073;display:flex;align-items:center;justify-content:center;z-index:var(--z-modal)}.ac-modal__panel{background:var(--color-surface);border-radius:var(--radius-lg);padding:var(--space-6);max-width:32rem;width:90vw;max-height:80vh;overflow:auto;box-shadow:var(--shadow-lg);display:flex;flex-direction:column;gap:var(--space-4)}.ac-modal__actions{display:flex;justify-content:flex-end;gap:var(--space-2)}.ac-diff{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:var(--space-2)}.ac-diff li{display:grid;grid-template-columns:1fr auto auto auto;gap:var(--space-2);font-size:var(--font-size-sm);align-items:center}.ac-diff__before{color:var(--color-text-muted);text-decoration:line-through}.ac-diff__arrow{color:var(--color-text-subtle)}.ac-diff__after{color:var(--color-success);font-weight:var(--font-weight-medium)}.ac-page__progress{color:var(--color-text-muted);margin:0}.ac-wizard__header{display:flex;flex-direction:column;gap:var(--space-3);align-items:stretch}.ac-wizard__header-text{display:flex;flex-direction:column;gap:var(--space-1)}.ac-wizard__subtitle{color:var(--color-text-muted);margin:0}.ac-wizard__step-count{color:var(--color-text-muted);font-size:var(--font-size-sm);margin:0}.ac-wizard__progress{display:flex;gap:var(--space-1)}.ac-wizard__progress-segment{flex:1;height:4px;background:var(--color-border);border-radius:var(--radius-sm);transition:background var(--duration-fast) var(--easing-standard)}.ac-wizard__progress-segment--filled{background:var(--color-accent)}.ac-wizard__step{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:var(--space-6)}.ac-wizard__nav{justify-content:space-between}.ac-wizard__nav .ac-button:first-child{margin-right:auto}.ac-wizard__skip{color:var(--color-text-muted)}.ac-wizard__hint{margin:var(--space-3) 0 0;color:var(--color-warning, #b45309);font-size:.875rem}.ac-wizard__review{display:flex;flex-direction:column;gap:var(--space-4)}.ac-wizard__tool-list{list-style:none;padding-left:0;margin:0;display:flex;flex-direction:column;gap:var(--space-1)}.ac-wizard__tool-row{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);padding:var(--space-2) var(--space-3);border:1px solid var(--color-border);border-radius:var(--radius-md)}.ac-wizard__tool-label{display:flex;align-items:center;gap:var(--space-2);cursor:pointer}.ac-badge{font-size:var(--font-size-xs);font-weight:var(--font-weight-medium);padding:.1rem var(--space-2);border-radius:var(--radius-sm);white-space:nowrap}.ac-badge--installed{background:var(--color-success-soft);color:var(--color-success)}.ac-badge--missing{background:var(--color-surface-alt);color:var(--color-text-muted)}.ac-badge--ws{font-size:.6875rem;padding:.05rem .4rem;background:var(--color-surface-alt);color:var(--color-text-muted);border:1px solid var(--color-border)}.ac-badge--ws-active{background:var(--color-accent);color:var(--color-accent-fg);border-color:var(--color-accent)}.ac-wizard__pack-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:var(--space-3)}.ac-pack-tile{display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-3);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface)}.ac-pack-tile__head{display:flex;align-items:center;gap:var(--space-2);cursor:pointer;font-weight:var(--font-weight-medium)}.ac-pack-tile__title{flex:1}.ac-pack-tile__role{margin:0;font-size:var(--font-size-xs);color:var(--color-text)}.ac-pack-tile__role code{font-size:var(--font-size-xs)}.ac-pack-tile__desc{margin:0;color:var(--color-text-muted);font-size:var(--font-size-xs)}.ac-pack-tile__ws{display:flex;flex-wrap:wrap;gap:var(--space-1)}.ac-pack-tile__children{display:flex;flex-direction:column;gap:var(--space-1);margin:0;padding:var(--space-2) 0 0 var(--space-4);border:0;border-top:1px solid var(--color-border)}.ac-pack-tile__children:disabled{opacity:.5}.ac-pack-tile__child{display:flex;align-items:center;gap:var(--space-2);font-size:var(--font-size-sm);cursor:pointer}.ac-wizard__module-fields{display:flex;flex-direction:column;gap:var(--space-4);margin-top:var(--space-4)}.ac-rtk-row{display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-3);margin-bottom:var(--space-4);border:1px solid var(--color-border);border-radius:var(--radius-md)}.ac-rtk-row__head{display:flex;align-items:center;gap:var(--space-2)}.ac-rtk-row__label{font-weight:var(--font-weight-medium)}.ac-rtk-row__install{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-2)}.ac-rtk-row__cmd{display:block;width:100%;padding:var(--space-2) var(--space-3);background:var(--color-surface-alt);border-radius:var(--radius-sm);font-family:var(--font-mono);font-size:var(--font-size-xs);user-select:all}.ac-council{display:flex;flex-direction:column;gap:var(--space-4)}.ac-council__master{display:flex;align-items:center;gap:var(--space-2);font-weight:var(--font-weight-medium)}.ac-council__section{display:flex;flex-direction:column;gap:var(--space-4);border:0;padding:0;margin:0}.ac-council__section:disabled{opacity:.55}.ac-council__h{margin:var(--space-2) 0 0;font-size:var(--font-size-sm);color:var(--color-text-muted)}.ac-wizard__review-nav{display:flex;flex-direction:column;gap:var(--space-2)}.ac-wizard__review-nav-label{color:var(--color-text-muted);font-size:var(--font-size-sm);margin:0}.ac-wizard__review-nav-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-1)}.ac-wizard__review-nav-button{width:100%;display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) var(--space-3);background:transparent;border:1px solid var(--color-border);border-left:3px solid var(--color-success);border-radius:var(--radius-md);color:var(--color-text);font-size:var(--font-size-sm);text-align:left;cursor:pointer;transition:background var(--duration-fast) var(--easing-standard),border-color var(--duration-fast) var(--easing-standard)}.ac-wizard__review-nav-button:hover{background:var(--color-surface);border-color:var(--color-accent);border-left-color:var(--color-success)}.ac-wizard__review-nav-button:focus-visible{outline:2px solid var(--color-accent);outline-offset:2px}.ac-wizard__review-nav-index{display:inline-flex;align-items:center;justify-content:center;min-width:1.5rem;height:1.5rem;padding:0 .375rem;background:var(--color-border);border-radius:999px;font-size:var(--font-size-xs);font-weight:600}.ac-wizard__review-nav-text{flex:1}.ac-wizard__review-nav-status{margin-left:auto;font-size:var(--font-size-xs);font-weight:var(--font-weight-medium);padding:.125rem .5rem;border-radius:999px;white-space:nowrap}.ac-wizard__review-nav-status--changed{background:var(--color-success-soft, rgba(34, 197, 94, .12));color:var(--color-success)}.ac-wizard__review-nav-status--error{background:var(--color-danger-soft, rgba(239, 68, 68, .12));color:var(--color-danger)}.ac-wizard__review-nav-button--error{border-left-color:var(--color-danger)}.ac-wizard__review-nav-button--error:hover{border-color:var(--color-accent);border-left-color:var(--color-danger)}.ac-user-md-form{display:flex;flex-direction:column;gap:var(--space-5)}.ac-chip-list{list-style:none;margin:0 0 var(--space-2);padding:0;display:flex;flex-wrap:wrap;gap:var(--space-2)}.ac-chip{display:inline-flex;align-items:center;gap:var(--space-2);padding:var(--space-1) var(--space-3);background:var(--color-surface-alt);border:1px solid var(--color-border);border-radius:999px;font-size:var(--font-size-sm)}.ac-chip__remove{appearance:none;background:transparent;border:0;color:var(--color-text-muted);cursor:pointer;font-size:1rem;line-height:1;padding:0 var(--space-1)}.ac-chip__remove:hover:not(:disabled){color:var(--color-text)}.ac-chip__remove:disabled{opacity:.4;cursor:not-allowed}.ac-role-add{display:flex;gap:var(--space-2);align-items:center}.ac-role-add .ac-input{flex:1}.ac-workspace__grid{display:grid;grid-template-columns:minmax(220px,1fr) minmax(0,2fr) minmax(260px,1fr);gap:var(--space-4);margin-top:var(--space-4)}@media (max-width: 900px){.ac-workspace__grid{grid-template-columns:1fr}}.ac-workspace__heading{font-size:var(--font-size-base);font-weight:var(--font-weight-medium);margin:0 0 var(--space-2) 0;color:var(--color-text)}.ac-workspace__empty{color:var(--color-text-muted);font-size:var(--font-size-sm)}.ac-workspace__role-grid{display:flex;flex-direction:column;gap:var(--space-2)}.ac-workspace__role{text-align:left;background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-md);padding:var(--space-3);cursor:pointer;display:grid;grid-template-columns:1fr auto;gap:var(--space-1);color:inherit;font:inherit}.ac-workspace__role:hover{border-color:var(--color-border-strong)}.ac-workspace__role--active{border-color:var(--color-primary, var(--color-text));background:var(--color-surface-alt)}.ac-workspace__role:focus-visible{outline:2px solid var(--color-primary, var(--color-text));outline-offset:2px}.ac-workspace__role-name{font-weight:var(--font-weight-medium)}.ac-workspace__role-status{font-size:var(--font-size-xs);color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.04em}.ac-workspace__role-status[data-status=stable]{color:var(--color-success, #15803d)}.ac-workspace__role-status[data-status=beta]{color:var(--color-warn, #b45309)}.ac-workspace__role-status[data-status=draft]{color:var(--color-text-muted)}.ac-workspace__role-tagline{grid-column:1 / -1;color:var(--color-text-muted);font-size:var(--font-size-sm)}.ac-workspace__main{display:flex;flex-direction:column;gap:var(--space-4)}.ac-workspace__task-list,.ac-workspace__session-list,.ac-workspace__doc-list,.ac-workspace__skill-list,.ac-workspace__citation-list{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:var(--space-2)}.ac-workspace__task{border:1px solid var(--color-border);border-radius:var(--radius-md);padding:var(--space-3);background:var(--color-surface)}.ac-workspace__task-head{display:flex;justify-content:space-between;align-items:center;gap:var(--space-2)}.ac-workspace__task-name{font-weight:var(--font-weight-medium)}.ac-workspace__task-intent{color:var(--color-text-muted);font-size:var(--font-size-sm);margin:var(--space-1) 0 0 0}.ac-workspace__task-prompt{display:inline-block;margin-top:var(--space-2);font-size:var(--font-size-xs);color:var(--color-text-muted)}.ac-workspace__session{display:grid;grid-template-columns:minmax(120px,1fr) minmax(80px,1fr) 2fr;gap:var(--space-2);font-size:var(--font-size-sm);padding:var(--space-2) var(--space-3);background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-sm)}.ac-workspace__session-id{font-family:var(--font-mono, monospace);color:var(--color-text-muted)}.ac-workspace__rail{display:flex;flex-direction:column;gap:var(--space-4)}.ac-workspace__citation{border-left:3px solid var(--color-border);padding:var(--space-1) var(--space-2)}.ac-workspace__citation-marker{font-weight:var(--font-weight-medium);margin-right:var(--space-1)}.ac-workspace__citation-source{text-decoration:none;color:var(--color-text);border-bottom:1px dotted var(--color-border-strong)}.ac-workspace__citation-source:hover{color:var(--color-primary, var(--color-text))}.ac-workspace__citation-pin{margin-left:var(--space-1);color:var(--color-warn, #b45309)}.ac-workspace__citation-excerpt{margin:var(--space-1) 0 0 0;color:var(--color-text-muted);font-size:var(--font-size-xs)}.ac-workspace__doc{display:grid;grid-template-columns:auto 1fr auto;gap:var(--space-2);align-items:center;font-size:var(--font-size-sm);padding:var(--space-2);border-radius:var(--radius-sm)}.ac-workspace__doc-type{font-size:var(--font-size-xs);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-muted);border:1px solid var(--color-border);border-radius:var(--radius-sm);padding:0 var(--space-1)}.ac-workspace__doc-time{font-family:var(--font-mono, monospace);color:var(--color-text-muted);font-size:var(--font-size-xs)}.ac-workspace__explain{border:1px solid var(--color-border);border-radius:var(--radius-md);padding:var(--space-3)}.ac-workspace__explain legend{padding:0 var(--space-1)}.ac-workspace__explain-option{display:flex;align-items:center;gap:var(--space-2);cursor:pointer;padding:var(--space-1) 0}.ac-workspace__explain-hint{margin:var(--space-2) 0 0 0;color:var(--color-text-muted);font-size:var(--font-size-xs)}
@@ -5,8 +5,8 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <meta name="robots" content="noindex" />
7
7
  <title>agent-config</title>
8
- <script type="module" crossorigin src="/assets/index-BDAhhpDV.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-BXZILUxe.css">
8
+ <script type="module" crossorigin src="/assets/index-J0-0d7RC.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-ZiC8PbdW.css">
10
10
  </head>
11
11
  <body>
12
12
  <main id="app"></main>
@@ -0,0 +1,80 @@
1
+ # Changelog Archive — pre-4.0.0
2
+
3
+ > Frozen snapshot of `event4u/agent-config` changelog entries for
4
+ > `3.2.0` and `3.3.0`, split out of the main
5
+ > [`CHANGELOG.md`](../../CHANGELOG.md) on 2026-05-27 once the active
6
+ > era's body crossed the drift cap enforced by
7
+ > `tests/test_changelog_eras.py`.
8
+ >
9
+ > **Read-only.** New entries land in `CHANGELOG.md` § "Era: 4.1.x".
10
+ > Entries here are not amended — git tags `3.2.0` and `3.3.0` remain
11
+ > the canonical source for what shipped.
12
+ >
13
+ > Entry shape follows the conventions documented in
14
+ > [`docs/contracts/CHANGELOG-conventions.md`](../contracts/CHANGELOG-conventions.md).
15
+
16
+ ## [3.3.0](https://github.com/event4u-app/agent-config/compare/3.2.0...3.3.0) (2026-05-25)
17
+
18
+ ### Features
19
+
20
+ * **scripts:** point bench / eval / mcp tooling at internal/ (ADR-028 phase 1) ([c20b515](https://github.com/event4u-app/agent-config/commit/c20b515dfc80d03244e54af7b50e07d562647799))
21
+
22
+ ### Bug Fixes
23
+
24
+ * **ci:** repoint bench/ -> internal/bench/ in projected agent-status + condense-memory ([682040b](https://github.com/event4u-app/agent-config/commit/682040b230248bd054767ab10bd1e90ed3a1d0b7))
25
+
26
+ ### Documentation
27
+
28
+ * **roadmap:** archive road-to-root-layout-cleanup at 100% complete ([948f1a8](https://github.com/event4u-app/agent-config/commit/948f1a8cd9ec63fa831d5abab25aeb3657a0a7d4))
29
+ * **adr:** land Phase 2 audit evidence + ADR-029 multi-workspace deferral ([c4dabf1](https://github.com/event4u-app/agent-config/commit/c4dabf1f718fee0d4709d727d1e3eb781f8db62f))
30
+ * **adr:** land ADR-028 + root-layout-cleanup roadmap ([7b0fd28](https://github.com/event4u-app/agent-config/commit/7b0fd281288a87f9c218d9fa9d73f01a48a56626))
31
+ * repoint bench / mcp-worker paths to internal/ (ADR-028 phase 1) ([85278dd](https://github.com/event4u-app/agent-config/commit/85278dd831d44a187dcfe7684e895bac0ca97ae4))
32
+
33
+ ### Chores
34
+
35
+ * **root:** move bench/ and workers/ under internal/ (ADR-028 phase 1) ([2a1dd1e](https://github.com/event4u-app/agent-config/commit/2a1dd1e363f9aabb59b6eebf35f64a47609abebb))
36
+ * **roadmap:** close changelog-era-auto-split (Phase 4 → ADR-027) ([b10b326](https://github.com/event4u-app/agent-config/commit/b10b32623b42739f0eba12a52173b810169929b6))
37
+
38
+ Tests: 4938 (+9 since 3.2.0)
39
+
40
+ ## [3.2.0](https://github.com/event4u-app/agent-config/compare/3.1.1...3.2.0) (2026-05-25)
41
+
42
+ ### Features
43
+
44
+ * **workspace:** GUI bridge + Workspace tab for Phases 4-8 backends ([6911b56](https://github.com/event4u-app/agent-config/commit/6911b56d1e474dace4a250d077ed93f628b029be))
45
+ * **workspace:** backend Python modules for Phases 5/6/7/8 ([c890fde](https://github.com/event4u-app/agent-config/commit/c890fde556b24e6b69409a4f0f647cace3779320))
46
+ * **memory:** wire knowledge namespace into hybrid retrieval ([a65ae2c](https://github.com/event4u-app/agent-config/commit/a65ae2c117ac10aff78ac711316b441d2ee2f42c))
47
+ * **knowledge:** implement local knowledge ingestion module ([d842ba3](https://github.com/event4u-app/agent-config/commit/d842ba350f325293f0faafe4698b8bbbe77033f8))
48
+ * **knowledge:** add /knowledge command cluster source files ([9023c17](https://github.com/event4u-app/agent-config/commit/9023c17049ea42769537919df5ca10db1cc785e7))
49
+ * **roadmap:** land road-to-employee-product-and-external-proof + consumer docs ([b2901ad](https://github.com/event4u-app/agent-config/commit/b2901ad516a6bb209b7fadae884563025a090e4d))
50
+ * **roles:** scaffold consultant, content-creator, galabau experiences ([55384df](https://github.com/event4u-app/agent-config/commit/55384df486cba24288f38275435d151c5c7b8762))
51
+
52
+ ### Bug Fixes
53
+
54
+ * **knowledge:** use agent-config-maintainer workspace per discovery vocabulary ([75f78ab](https://github.com/event4u-app/agent-config/commit/75f78ab2999ed5fbc261aecf9fadd692588a2498))
55
+ * **check-refs:** mark forward-refs to recruit-sessions with ref-ignore ([147909b](https://github.com/event4u-app/agent-config/commit/147909b4428492ad8332959635573a1ab419d865))
56
+
57
+ ### Documentation
58
+
59
+ * **roadmap:** mark Phases 4-8 backend complete + regen progress dashboard ([38b82f9](https://github.com/event4u-app/agent-config/commit/38b82f9928d57c9c7cfabd0b75f3c1284b6e2dcb))
60
+ * **roadmap:** mark Phase 2 done + sync command counts ([4089810](https://github.com/event4u-app/agent-config/commit/4089810f2123a0838e318fb442e975f6f60faf00))
61
+ * **knowledge:** add user guide and update contract for impl reality ([9fbea43](https://github.com/event4u-app/agent-config/commit/9fbea43033471e2daf2ef91342212a3480e24f93))
62
+ * **deploy:** add team-deployment-posture + small-team-recipe + stubs ([0892317](https://github.com/event4u-app/agent-config/commit/08923177dbd62346456a4992b8ab06e0442fb0cf))
63
+ * **contracts:** add 8 contracts for Daily Workspace + role experience ([34f882c](https://github.com/event4u-app/agent-config/commit/34f882c815fa2366956f2f454534bd9f18f79e04))
64
+ * **adr:** add ADR-022..026 for Daily Workspace architecture ([034eb99](https://github.com/event4u-app/agent-config/commit/034eb99569fcf388099b059ae5e8fb0537d902e3))
65
+
66
+ ### CI
67
+
68
+ * **visibility:** drop push-trigger ghost-runs from drift workflows ([1704683](https://github.com/event4u-app/agent-config/commit/1704683ff0f08985e750b7cb6c8555812f349914))
69
+
70
+ ### Chores
71
+
72
+ * **gitignore:** ignore pnpm-lock.yaml (repo uses npm) ([088fae6](https://github.com/event4u-app/agent-config/commit/088fae6ef8377200185826c31ea8adc0b97573f4))
73
+ * **counts:** sync command count to 136 (analytics cluster added) ([1d56496](https://github.com/event4u-app/agent-config/commit/1d564962bd57aedc6d4ff2ae6b757e45e8a63e2c))
74
+ * **release:** bump agent_config_version in templates to match package.json 3.1.1 ([4864332](https://github.com/event4u-app/agent-config/commit/4864332804fe9979a4f94cb053cdd13c7473ac40))
75
+ * **sync:** regenerate index + catalog for analytics commands ([77cb4fa](https://github.com/event4u-app/agent-config/commit/77cb4fa41d8b2773e7f5ece27f385d7b42862f5f))
76
+ * **sync:** regenerate condensed analytics commands + Claude skill stubs ([41728c4](https://github.com/event4u-app/agent-config/commit/41728c4400c8cabaa8966d2708fbb4f3cef64adb))
77
+ * **knowledge:** regenerate projections + manifests for /knowledge cluster ([f4c5a26](https://github.com/event4u-app/agent-config/commit/f4c5a26bffef0a25918bdde42131354c9dd5295d))
78
+ * **discovery:** add agent-skills and cinematic-ai-video to topics ([5c01d5e](https://github.com/event4u-app/agent-config/commit/5c01d5e152bda559aefd48fd8220f2a3cbd90249))
79
+
80
+ Tests: 4929 (+90 since 3.1.1)
@@ -29,7 +29,6 @@ role: # required — unordered list of role labels; ≥ 1 e
29
29
  - founder
30
30
  - engineer
31
31
  style:
32
- formality: "informal" # informal | formal
33
32
  pace: "pragmatic" # pragmatic | thorough | rapid
34
33
  voice_sample: | # required — one paste of the user's typical writing
35
34
  Mach das einfach. Wenn unklar, frag im Council.
@@ -57,7 +56,6 @@ enforced by `/agents user accept` and `/agents user update`.
57
56
  | `identity.name` | yes | How the agent addresses the user (full name or shorthand — user's choice). |
58
57
  | `language` | yes | Primary language; the agent mirrors per [`language-and-tone`](../../.agent-src/rules/language-and-tone.md). |
59
58
  | `role` | yes | Unordered list of role labels (≥ 1). Drives reviewer-voice selection and persona pairing. Seeded enum mirrors `SEED_PROFILE_IDS`; additional free-form entries accepted. |
60
- | `style.formality` | yes | `informal` (Du / first-name) or `formal` (Sie / full name). |
61
59
  | `style.pace` | yes | `pragmatic` (default), `thorough` (more verification), or `rapid` (shorter replies). |
62
60
  | `voice_sample` | yes | One representative paste — anchors mirror-back and tone calibration. |
63
61
  | `last_updated` | yes | ISO date, bumped on every accept. |
@@ -141,7 +139,7 @@ Each line is a single JSON object:
141
139
  ```
142
140
 
143
141
  Allowed `field` values mirror the schema (`identity.name`,
144
- `language`, `role`, `style.formality`, `style.pace`, `voice_sample`,
142
+ `language`, `role`, `style.pace`, `voice_sample`,
145
143
  `notes`). Anything outside that set is dropped on read.
146
144
 
147
145
  Privacy floor applies on write — never buffer credentials, third-party
@@ -84,7 +84,8 @@
84
84
  "label": { "type": "string", "minLength": 1 },
85
85
  "description": { "type": "string", "minLength": 1 },
86
86
  "default_packs": { "type": "array", "items": { "$ref": "#/$defs/pack_id" } },
87
- "optional_packs": { "type": "array", "items": { "$ref": "#/$defs/pack_id" } }
87
+ "optional_packs": { "type": "array", "items": { "$ref": "#/$defs/pack_id" } },
88
+ "example_roles": { "type": "array", "items": { "type": "string", "minLength": 1 } }
88
89
  }
89
90
  },
90
91
  "pack": {
@@ -97,6 +98,7 @@
97
98
  "description": { "type": "string", "minLength": 1 },
98
99
  "workspaces": { "type": "array", "items": { "$ref": "#/$defs/workspace_id" }, "minItems": 1 },
99
100
  "requires_hint": { "type": "array", "items": { "$ref": "#/$defs/pack_id" } },
101
+ "cluster": { "$ref": "#/$defs/pack_id" },
100
102
  "trust_level_default": { "$ref": "#/$defs/trust_level" },
101
103
  "artefact_count": { "type": "integer", "minimum": 0 },
102
104
  "human_review_required": {
@@ -41,23 +41,30 @@ no cross-origin asset, no remote endpoint — CSP
41
41
  ## Boot sequence
42
42
 
43
43
  ```
44
- agent-config install (or `setup`, or `init` scripts/install.py spawns
45
- `node dist/cli/agent-config.js install --no-open`)
44
+ agent-config install (or `setup`, or `init` when the GUI is usable)
46
45
 
47
46
  ├─► pick a free loopback port; mint a per-server bearer/CSRF token
48
47
  ├─► Fastify listen({ host: '127.0.0.1', port })
49
48
  ├─► print `WIZARD_READY <url>` on stdout (url carries `?token=…` + `#/…`)
50
49
  ├─► open the OS browser at <url> (skipped with --no-open / headless)
51
- └─► serve until Ctrl-C
50
+ └─► serve until the user finishes (Finish → install) or Ctrl-C
52
51
  ```
53
52
 
54
- `init` is the consumer entry point: it delegates to `scripts/install.py`,
55
- which on a TTY with a display and no `--no-ui` / `CI` / explicit
56
- `--tools=` spawns the `install` subcommand with `--no-open` and waits for
57
- the `WIZARD_READY <url>` handshake (progressive 10/20/40/80 s budget) before
58
- printing the URL banner. Headless / CI / `--no-ui` / explicit `--tools=`
59
- installs run the non-interactive `install.py` path directly and never boot
60
- the GUI.
53
+ `init` is the consumer entry point and the install **front-end**: the TS CLI
54
+ (`src/cli/initRouting.ts shouldInitLaunchGui`) opens the browser wizard
55
+ directly (via `runUiServe`, install mode) whenever it can actually be used —
56
+ interactive TTY, a display, and no CLI-mode flag. There is no CLI tool-picker
57
+ in that path; the wizard collects the tool/pack/settings selection and its
58
+ Finish drives the **whole** install through `POST /api/v1/wizard/apply`
59
+ `scripts/install.py --apply-payload` (one installer).
60
+
61
+ `init` falls back to the non-interactive bash CLI install (`scripts/install` →
62
+ `install.py`) — and never boots the GUI — when any of these hold: `CI` set,
63
+ `AGENT_CONFIG_NO_UI` set, stdin/stdout not a TTY, a headless host (SSH / Linux
64
+ without `DISPLAY`), or a CLI-mode flag (`--no-ui` / `--tools` / `--ai` /
65
+ `--yes` / `--quiet` / `--dry-run` / `--minimal` / `--settings-only` /
66
+ `--list-tools`). `install.py`'s own tail-launch (`_wizard_spawn`, matching the
67
+ `WIZARD_READY <url>` handshake) remains for direct `python3 install.py` runs.
61
68
 
62
69
  ### `WIZARD_READY` stdout contract
63
70
 
@@ -83,7 +90,12 @@ Versioned under `/api/v1/`. Selected routes:
83
90
  | POST | `/api/v1/wizard/state` | Persist state between steps |
84
91
  | GET | `/api/v1/wizard/manifest` | Locked discovery-manifest (extended mode) |
85
92
  | GET | `/api/v1/wizard/auto-detect` | Project-signal evidence for the `ai-tools` step (extended mode) |
93
+ | GET | `/api/v1/wizard/detect-tools` | Native AI-tool presence (home/app/`$PATH`) for Step-1 pre-select + badge |
94
+ | GET | `/api/v1/wizard/detect-rtk` | rtk presence + per-OS install hint (Editor-and-tooling step) |
95
+ | GET | `/api/v1/wizard/ai-council` | AI-council scalar subset + provider key presence (extended mode) |
96
+ | POST | `/api/v1/wizard/ai-council` | Comment-preserving scalar merge into `.ai-council.yml` |
86
97
  | POST | `/api/v1/wizard/finish` | 2PC commit of settings + user-identity |
98
+ | POST | `/api/v1/shutdown` | Browser-close shutdown beacon (`navigator.sendBeacon` target; real-serve only) |
87
99
  | POST | `/api/v1/wizard/apply` | **Single real-apply route.** `dry_run:true` → buffered plan preview; otherwise SSE-streams `scripts/install.py --apply-payload` |
88
100
  | GET | `/api/v1/install/detect` | Scope + project shape + tool presence |
89
101
  | POST | `/api/v1/install/plan` | Plan preview (per-tool file counts + conflicts) for the Review step |
@@ -100,6 +112,36 @@ an `Origin` allow-list (browser-issued requests), and a per-server bearer
100
112
  token (`Authorization: Bearer <token>`, minted at boot, surfaced in the
101
113
  `?token=` URL). A bad token / Host / Origin returns `403`.
102
114
 
115
+ ### Browser-lifecycle shutdown
116
+
117
+ In real-serve (`runUiServe`), the server stops itself when the browser that
118
+ drives it goes away — the local process should not outlive its only client:
119
+
120
+ - The SPA ([`src/ui/serverLifecycle.ts`](../../src/ui/serverLifecycle.ts))
121
+ heartbeats `GET /api/v1/ping` every 30s while the tab is visible and the
122
+ user has interacted within the last 30 min. On `pagehide` (window/tab
123
+ close) it fires `navigator.sendBeacon('/api/v1/shutdown?token=…')` (the
124
+ token rides as a query param because `sendBeacon` cannot set headers); and
125
+ once the user has been idle for 30 min it fires the same beacon instead of
126
+ a ping, so the server stops even with the tab still open.
127
+ - The server (`createApp` `idleShutdown` option, passed only by `runUiServe`)
128
+ exits on that beacon, and — as a backstop for crashes where neither beacon
129
+ is delivered — via an idle timer that **arms only after the first authed
130
+ request** (so headless / `--allow-headless` manual-connect servers are
131
+ never killed before the operator attaches) and fires after 30 min of
132
+ silence.
133
+
134
+ On boot, `runUiServe` records `{pid, port, url}` to
135
+ `~/.event4u/agent-config/local-server.json`
136
+ ([`src/server/serverInfo.ts`](../../src/server/serverInfo.ts)) and removes it
137
+ on graceful exit. A fresh `agent-config init` (via `scripts/install.py`
138
+ `_kill_stale_wizard_server`) reads that record, terminates a still-running
139
+ prior instance, and starts a new server — so init always lands on step 1.
140
+
141
+ `createApp` is inert (no watchdog, no `/api/v1/shutdown` route) unless
142
+ `idleShutdown` is supplied, so the in-process test harness
143
+ ([`tests/server/helpers.ts`](../../tests/server/helpers.ts)) is unaffected.
144
+
103
145
  ## Real apply — single source of truth
104
146
 
105
147
  `POST /api/v1/wizard/apply` is the only write path:
@@ -178,16 +220,69 @@ effect):
178
220
 
179
221
  | `extendedSteps` | Steps | Layout |
180
222
  |---|---|---|
181
- | `false` | 7 | `editor → personality → cost → roadmap-quality → memory → user-md → review` |
182
- | `true` | 9 | `ai-tools → packs → editor → personality → cost → roadmap-quality → memory → user-md → review` |
223
+ | `false` | 9 | `welcome → editor → personality → cost → roadmap-quality → memory → ai-council → user-md → review` |
224
+ | `true` | 13 | `welcome → ai-tools → roles → packs → modules → editor → personality → cost → roadmap-quality → memory → ai-council → user-md → review` |
225
+
226
+ The `welcome` step (Step 1, both modes) collects **name + language** up front —
227
+ pulled out of the user-md step so the agent knows who it's talking to before
228
+ anything else. Name pre-fills from the OS account (`GET /api/v1/ping`
229
+ `systemUser`) when empty; language pre-fills from the browser locale
230
+ (`navigator.language`) when no `.agent-user.yml` exists yet. In install mode
231
+ the user-md step hides its name + language fields (collected here); setup mode
232
+ skips the welcome step (it lands on the first settings step) and keeps those
233
+ fields in the user-md form.
234
+
235
+ The `roles` step presents the discovery **workspaces** as the *area*
236
+ (Engineering, Product, Finance, Founder, GTM, Ops, …; the maintainer workspace
237
+ is hidden) — each tile shows the area label, then advisory `example_roles`
238
+ (e.g. Engineering → "Developer, CTO"; Finance → "CFO") and the description. The
239
+ selected workspace ids become `.agent-user.yml` `role[]` (the example roles are
240
+ UI hints, not the stored value) and recommend each domain's `default_packs` on
241
+ the packs step. In install mode the user-md
242
+ step therefore hides its role field (collected here instead); setup mode keeps
243
+ the role field since it skips the roles step.
244
+
245
+ The `ai-council` step (road-to-wizard-ux-improvements § Phase 8) configures the
246
+ wizard-controlled scalar subset of `.ai-council.yml` (enable, per-member
247
+ enable + low-impact, global transport mode, debate rounds, cost budget, the
248
+ non-locked `decision_resolution` classes) via `GET`/`POST /api/v1/wizard/ai-council`;
249
+ the file is written with comment-preserving `replaceScalar` edits.
183
250
 
184
251
  The step shapes themselves are declared in
185
- [`src/ui/wizard/steps.ts`](../../src/ui/wizard/steps.ts) — the two
186
- prepended lead steps (`ai-tools`, `packs`) carry no `paths` and use
187
- dedicated renderers in `WizardPage.tsx`. `getWizardSteps({ extended })`
188
- is the single resolver; the UI consumes the active list via
189
- `getActiveSteps()` / `activeTotalSteps()` so a server toggle takes
190
- effect on the next reload without a code change.
252
+ [`src/ui/wizard/steps.ts`](../../src/ui/wizard/steps.ts) — the always-first
253
+ `welcome` step plus the four extended-only lead steps (`ai-tools`, `roles`,
254
+ `packs`, `modules`) carry no `paths` and use dedicated renderers in
255
+ `WizardPage.tsx`.
256
+ `getWizardSteps({ extended })` is the single resolver; the UI consumes the
257
+ active list via `getActiveSteps()` / `activeTotalSteps()` so a server toggle
258
+ takes effect on the next reload without a code change.
259
+
260
+ ### AI-tools / roles / packs selection rules (Steps 2-4)
261
+
262
+ - **AI-tools pre-selection.** `detect-tools` returns `tools` (installed on the
263
+ machine) and `configured` (the user's prior selection, persisted to
264
+ `~/.event4u/agent-config/wizard-tools.json` on each real apply). On a repeat
265
+ run the wizard pre-selects exactly the `configured` tools; only on a genuine
266
+ first run (no prior selection) does it fall back to pre-selecting every
267
+ installed tool.
268
+ - **Roles → packs recommendation.** Each selected role contributes its
269
+ workspace `default_packs`; the union pre-selects packs on Step 3 (plus
270
+ auto-detected project packs). The recommendation stops clobbering the
271
+ selection once the user manually edits a pack. Each pack tile also badges
272
+ the workspace(s) it belongs to (from the pack's `workspaces`), highlighting
273
+ the badges that match a role the user picked on Step 2.
274
+ - **Step 2 framework persistence.** A language tile (`cluster`, e.g. PHP)
275
+ gates its framework children in the UI but never destroys their stored
276
+ selection. Turning a language off disables — but keeps checked — its
277
+ children, so a PHP off→on round-trip restores the exact Laravel-on /
278
+ Symfony-off choice. `resolveSelectedPacks()` filters disabled children at
279
+ submit time, so a remembered-but-gated framework is not installed.
280
+ - **No-autodetect packs.** Some packs are never pre-selected from project
281
+ signals (`python` — a non-engineer may have python installed but not need
282
+ it). The pack stays available to tick manually.
283
+ - **Empty-selection gate.** The AI-tools, roles, and packs steps each block
284
+ Next until at least one effective selection exists (≥ 1 tool, ≥ 1 role, and
285
+ ≥ 1 installable pack respectively).
191
286
 
192
287
  ### `GET /api/v1/wizard/state` payload
193
288
 
@@ -219,6 +219,33 @@ examples instead. No ADR-014 issued.
219
219
 
220
220
  Driven by [`agents/roadmaps/monorepo-phase-1-frontmatter-metadata.md`](../../agents/roadmaps/monorepo-phase-1-frontmatter-metadata.md).
221
221
 
222
+ ### 2026-05-27 — Additive advisory `cluster:` key on packs
223
+
224
+ Pack entries in [`config/discovery/packs.yml`](../../config/discovery/packs.yml)
225
+ may carry an optional `cluster: <language-id>` field. It groups a framework
226
+ pack under a programming-language tile in the setup wizard's capability-packs
227
+ step (e.g. `laravel: cluster: php`, `react: cluster: typescript`). Like
228
+ `requires_hint`, it is **advisory only** — the installer does not act on it; it
229
+ drives the wizard UI's collapsible language→framework grouping. The value must
230
+ be a known pack id (and not self-referential), enforced by
231
+ [`scripts/lint_discovery_vocabulary.py`](../../scripts/lint_discovery_vocabulary.py)
232
+ and emitted into the discovery manifest. Additive, no vocabulary rename.
233
+
234
+ Driven by [`agents/roadmaps/road-to-wizard-ux-improvements.md`](../../agents/roadmaps/road-to-wizard-ux-improvements.md) § Phase 4 (AI-council-resolved: reuse `packs.yml` as the single source of truth rather than a second mapping file).
235
+
236
+ ### 2026-05-27 — Additive advisory `example_roles:` key on workspaces
237
+
238
+ Workspace entries in [`config/discovery/workspaces.yml`](../../config/discovery/workspaces.yml)
239
+ may carry an optional `example_roles: [<title>, …]` list of illustrative job
240
+ titles (e.g. `engineering: [Developer, CTO]`, `finance: [CFO]`). The wizard's
241
+ roles step shows the workspace as the *area* and these titles as examples under
242
+ it. **Advisory and free-form** — NOT a closed vocabulary: the stored
243
+ `.agent-user.yml` `role[]` is the workspace id, never these examples; nothing
244
+ acts on the strings beyond display. Emitted into the discovery manifest;
245
+ allowed by [`discovery-manifest.schema.json`](../contracts/discovery-manifest.schema.json).
246
+ Additive, no vocabulary rename. (Same change cleaned the `finance` label from
247
+ "Finance / CFO" to "Finance".)
248
+
222
249
  ## Cross-references
223
250
 
224
251
  - [ADR-007 — Agent Discovery Scopes](ADR-007-agent-discovery-scopes.md):
@@ -25,7 +25,7 @@ Companion artefacts:
25
25
  - Roadmap: [`agents/roadmaps/road-to-internal-ai-os-deployment.md`](../../agents/roadmaps/road-to-internal-ai-os-deployment.md)
26
26
  - Artefacts: [`packages/core/deploy/`](../../packages/core/deploy/)
27
27
  - Env contract: [`docs/deploy/env-vars.md`](../deploy/env-vars.md)
28
- - Council question (drafted, not invoked — no keys): [`agents/tmp/council-question-deployment-shape.md`](../../agents/tmp/old/council-question-deployment-shape.md)
28
+ - Council question (drafted, not invoked — no keys): [`agents/tmp/council-question-deployment-shape.md`](../../agents/old/council-question-deployment-shape.md)
29
29
  - Predecessor ADR: [`ADR-016`](ADR-016-installer-architecture.md) — installer architecture (agent-mode protocol the GUI server wraps).
30
30
 
31
31
  ## Context
@@ -141,7 +141,7 @@ orchestrator-agnostic.
141
141
  ## Open questions (council-deferred)
142
142
 
143
143
  The accompanying council question file
144
- [`agents/tmp/council-question-deployment-shape.md`](../../agents/tmp/old/council-question-deployment-shape.md)
144
+ [`agents/tmp/council-question-deployment-shape.md`](../../agents/old/council-question-deployment-shape.md)
145
145
  has not yet been run (no provider keys configured). A maintainer with
146
146
  keys should run it and either ratify or supersede this ADR.
147
147
 
@@ -6,7 +6,7 @@
6
6
  > and Phase 3 (central policy) shipping first.
7
7
  >
8
8
  > Open design questions live in
9
- > [`agents/tmp/council-question-connector-scope.md`](../../agents/tmp/old/council-question-connector-scope.md).
9
+ > [`agents/tmp/council-question-connector-scope.md`](../../agents/old/council-question-connector-scope.md).
10
10
 
11
11
  ## Audience
12
12
 
@@ -124,6 +124,6 @@ All of the above land in Phase 5, contingent on Phases 2 + 3.
124
124
  ## Cross-references
125
125
 
126
126
  - 🚧 Reserved ADR slot: `docs/decisions/ADR-025-connector-scope.md`.
127
- - Council question: [`agents/tmp/council-question-connector-scope.md`](../../agents/tmp/old/council-question-connector-scope.md).
127
+ - Council question: [`agents/tmp/council-question-connector-scope.md`](../../agents/old/council-question-connector-scope.md).
128
128
  - Quickstart: [`quickstart.md`](quickstart.md).
129
129
  - Policy cookbook: [`policy-cookbook.md`](policy-cookbook.md).
@@ -7,7 +7,7 @@
7
7
  > before code lands. Every section below is normative-once-shipped.
8
8
  >
9
9
  > Open design questions live in
10
- > [`agents/tmp/council-question-central-policy.md`](../../agents/tmp/old/council-question-central-policy.md).
10
+ > [`agents/tmp/council-question-central-policy.md`](../../agents/old/council-question-central-policy.md).
11
11
 
12
12
  ## Audience
13
13
 
@@ -125,6 +125,6 @@ All of the above land in Phase 3. Until then, per-user
125
125
  ## Cross-references
126
126
 
127
127
  - 🚧 Reserved ADR slot: `docs/decisions/ADR-023-central-policy.md`.
128
- - Council question: [`agents/tmp/council-question-central-policy.md`](../../agents/tmp/old/council-question-central-policy.md).
128
+ - Council question: [`agents/tmp/council-question-central-policy.md`](../../agents/old/council-question-central-policy.md).
129
129
  - Env contract: [`env-vars.md`](env-vars.md) (`POLICY_PATH`).
130
130
  - Quickstart: [`quickstart.md`](quickstart.md).
@@ -8,7 +8,6 @@ role:
8
8
  - founder
9
9
  - engineer
10
10
  style:
11
- formality: "informal"
12
11
  pace: "pragmatic"
13
12
  voice_sample: |
14
13
  Mach das einfach. Wenn unklar, frag im Council. Tokenverbrauch ist ok,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@event4u/agent-config",
3
- "version": "4.2.0",
3
+ "version": "4.5.0",
4
4
  "description": "Universal AI Agent OS \u2014 audited skills, governance rules, commands, and templates for AI coding tools (Claude Code, Cursor, Windsurf, Copilot).",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -284,6 +284,7 @@ def _build(strict: bool) -> tuple[dict[str, Any], list[dict[str, Any]]]:
284
284
  "description": w["description"],
285
285
  "default_packs": list(w.get("default_packs") or []),
286
286
  **({"optional_packs": list(w["optional_packs"])} if w.get("optional_packs") else {}),
287
+ **({"example_roles": list(w["example_roles"])} if w.get("example_roles") else {}),
287
288
  }
288
289
  for w in workspaces
289
290
  ]
@@ -302,6 +303,8 @@ def _build(strict: bool) -> tuple[dict[str, Any], list[dict[str, Any]]]:
302
303
  }
303
304
  if p.get("requires_hint"):
304
305
  item["requires_hint"] = list(p["requires_hint"])
306
+ if p.get("cluster"):
307
+ item["cluster"] = p["cluster"]
305
308
  pk_out.append(item)
306
309
 
307
310
  if strict and unassigned:
@@ -546,6 +549,7 @@ def _packs_view(manifest: dict[str, Any]) -> dict[str, Any]:
546
549
  "description": p["description"],
547
550
  "workspaces": list(p.get("workspaces", [])),
548
551
  "requires_hint": list(p.get("requires_hint", [])),
552
+ "cluster": p.get("cluster"),
549
553
  "trust_level_default": p.get("trust_level_default"),
550
554
  "artefact_count": len(ids),
551
555
  "artefacts": ids,
@@ -37,6 +37,11 @@ RE_NUMBERED = re.compile(r"^>?\s*\d+\.\s")
37
37
  RE_STATUS = re.compile(r"^\s*(?:❌|⚠️|✅)")
38
38
  RE_IRONLAW = re.compile(r"^[A-Z][A-Z0-9 ,.\-_/']{3,}$")
39
39
  RE_BACKTICK_SPAN = re.compile(r"`[^`\n]+`")
40
+ # Spans frozen byte-for-byte inside prose lines. Backtick spans first so a
41
+ # slash-bearing span inside backticks is captured whole; then any non-whitespace
42
+ # run containing `/` or `\` — bare URLs, markdown link/image targets, and file
43
+ # paths whose segments (`is`, `the`, `a`) would otherwise be eaten as drop-tokens.
44
+ RE_PRESERVE_SPAN = re.compile(r"`[^`\n]+`|\S*[/\\]\S*")
40
45
  RE_FRONTMATTER = re.compile(r"^---\s*$")
41
46
  WORD_RE = re.compile(r"\b[A-Za-z]+\b")
42
47
  DROP_TOKENS = {"the", "a", "an", "is", "are", "was", "were", "be", "been",
@@ -50,10 +55,11 @@ def _condense_words(text: str) -> str:
50
55
 
51
56
 
52
57
  def _condense_prose_line(line: str) -> str:
53
- """Condense a prose line; preserve backtick-spans byte-for-byte."""
58
+ """Condense a prose line; preserve backtick spans, URLs, link targets, and
59
+ slash-bearing paths byte-for-byte (see ``RE_PRESERVE_SPAN``)."""
54
60
  parts: list[str] = []
55
61
  last = 0
56
- for span in RE_BACKTICK_SPAN.finditer(line):
62
+ for span in RE_PRESERVE_SPAN.finditer(line):
57
63
  parts.append(_condense_words(line[last:span.start()]))
58
64
  parts.append(span.group(0))
59
65
  last = span.end()
@@ -32,6 +32,7 @@ import os
32
32
  import re
33
33
  import shlex
34
34
  import shutil
35
+ import signal
35
36
  import subprocess
36
37
  import sys
37
38
  import threading
@@ -4335,6 +4336,75 @@ def _wizard_cli_dist(project_root: Path) -> Path | None:
4335
4336
  return cli if cli.exists() else None
4336
4337
 
4337
4338
 
4339
+ def _server_info_path() -> Path:
4340
+ """Path of the running-server record written by `ui:serve`."""
4341
+ return Path.home() / ".event4u" / "agent-config" / "local-server.json"
4342
+
4343
+
4344
+ def _pid_is_agent_config(pid: int) -> bool:
4345
+ """Best-effort check that `pid` is one of our wizard servers.
4346
+
4347
+ Guards against signalling an unrelated process that recycled the pid.
4348
+ Uses `ps` (POSIX); on platforms without it we conservatively return
4349
+ False so we never kill the wrong process.
4350
+ """
4351
+ try:
4352
+ out = subprocess.run( # noqa: S603,S607 - fixed argv, pid is an int
4353
+ ["ps", "-p", str(pid), "-o", "command="],
4354
+ capture_output=True,
4355
+ text=True,
4356
+ timeout=5,
4357
+ check=False,
4358
+ )
4359
+ except (OSError, subprocess.SubprocessError):
4360
+ return False
4361
+ return "agent-config" in out.stdout.lower()
4362
+
4363
+
4364
+ def _kill_stale_wizard_server() -> None:
4365
+ """Terminate a previously-launched wizard server, if one is recorded.
4366
+
4367
+ `agent-config init` should always start fresh: a stale server (left
4368
+ from an earlier run) is stopped so the new instance owns the port and
4369
+ the wizard re-enters at step 1. Best-effort — every failure is ignored.
4370
+ """
4371
+ path = _server_info_path()
4372
+ try:
4373
+ info = json.loads(path.read_text(encoding="utf-8"))
4374
+ except (OSError, ValueError):
4375
+ return
4376
+ pid = info.get("pid")
4377
+ if not isinstance(pid, int):
4378
+ path.unlink(missing_ok=True)
4379
+ return
4380
+ try:
4381
+ os.kill(pid, 0) # liveness probe
4382
+ except OSError:
4383
+ path.unlink(missing_ok=True) # already gone
4384
+ return
4385
+ if not _pid_is_agent_config(pid):
4386
+ return # pid reused by an unrelated process — leave it alone
4387
+ try:
4388
+ os.kill(pid, signal.SIGTERM)
4389
+ except OSError:
4390
+ path.unlink(missing_ok=True)
4391
+ return
4392
+ # Wait up to ~3s for a graceful exit, then force-kill.
4393
+ for _ in range(30):
4394
+ try:
4395
+ os.kill(pid, 0)
4396
+ except OSError:
4397
+ break
4398
+ time.sleep(0.1)
4399
+ else:
4400
+ try:
4401
+ os.kill(pid, getattr(signal, "SIGKILL", signal.SIGTERM))
4402
+ except OSError:
4403
+ pass
4404
+ path.unlink(missing_ok=True)
4405
+ print("(Stopped the previous wizard server.)")
4406
+
4407
+
4338
4408
  def _wizard_spawn(project_root: Path) -> int:
4339
4409
  """Spawn the wizard, await readiness, hand off to the child.
4340
4410
 
@@ -4343,6 +4413,9 @@ def _wizard_spawn(project_root: Path) -> int:
4343
4413
  Never raises into the parent — every error surfaces as a printed
4344
4414
  fallback line and a 0 return.
4345
4415
  """
4416
+ # Always start fresh: stop any server left running by a prior init.
4417
+ _kill_stale_wizard_server()
4418
+
4346
4419
  cli = _wizard_cli_dist(project_root)
4347
4420
  if cli is None:
4348
4421
  print(