@event4u/agent-config 6.0.0 → 6.1.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/.claude-plugin/marketplace.json +5 -5
- package/CHANGELOG.md +167 -440
- package/README.md +3 -3
- package/dist/agent-src/commands/agent-handoff.md +5 -4
- package/dist/agent-src/commands/agent-status.md +1 -0
- package/dist/agent-src/commands/agents/audit.md +1 -0
- package/dist/agent-src/commands/agents/init.md +3 -0
- package/dist/agent-src/commands/agents/optimize.md +1 -0
- package/dist/agent-src/commands/agents/user/accept.md +1 -0
- package/dist/agent-src/commands/agents/user/init.md +1 -0
- package/dist/agent-src/commands/agents/user/review.md +1 -0
- package/dist/agent-src/commands/agents/user/show.md +1 -0
- package/dist/agent-src/commands/agents/user/update.md +1 -0
- package/dist/agent-src/commands/agents/user.md +1 -0
- package/dist/agent-src/commands/agents.md +1 -0
- package/dist/agent-src/commands/analytics/prune.md +3 -2
- package/dist/agent-src/commands/analytics/show.md +3 -2
- package/dist/agent-src/commands/analytics.md +3 -2
- package/dist/agent-src/commands/analyze-reference-repo.md +1 -0
- package/dist/agent-src/commands/bug-fix.md +1 -0
- package/dist/agent-src/commands/bug-investigate.md +1 -0
- package/dist/agent-src/commands/challenge-me/vision.md +3 -2
- package/dist/agent-src/commands/challenge-me/with-docs.md +3 -2
- package/dist/agent-src/commands/challenge-me.md +3 -2
- package/dist/agent-src/commands/chat-history/import.md +9 -9
- package/dist/agent-src/commands/chat-history.md +32 -30
- package/dist/agent-src/commands/check-current-md.md +1 -0
- package/dist/agent-src/commands/commit/in-chunks.md +1 -0
- package/dist/agent-src/commands/commit.md +1 -0
- package/dist/agent-src/commands/condense.md +1 -0
- package/dist/agent-src/commands/context/create.md +1 -0
- package/dist/agent-src/commands/context/refactor.md +1 -0
- package/dist/agent-src/commands/context.md +1 -0
- package/dist/agent-src/commands/cost-report.md +5 -4
- package/dist/agent-src/commands/council/analysis.md +3 -2
- package/dist/agent-src/commands/council/debate.md +5 -4
- package/dist/agent-src/commands/council/default.md +3 -2
- package/dist/agent-src/commands/council/design.md +3 -2
- package/dist/agent-src/commands/council/optimize.md +3 -2
- package/dist/agent-src/commands/council/pr.md +3 -2
- package/dist/agent-src/commands/council.md +4 -3
- package/dist/agent-src/commands/e2e-heal.md +1 -0
- package/dist/agent-src/commands/e2e-plan.md +1 -0
- package/dist/agent-src/commands/estimate-ticket.md +1 -0
- package/dist/agent-src/commands/feature/dev.md +1 -0
- package/dist/agent-src/commands/feature/explore.md +1 -0
- package/dist/agent-src/commands/feature/plan.md +6 -6
- package/dist/agent-src/commands/feature/refactor.md +1 -0
- package/dist/agent-src/commands/feature/roadmap.md +1 -0
- package/dist/agent-src/commands/feature.md +1 -0
- package/dist/agent-src/commands/fix/ci.md +1 -0
- package/dist/agent-src/commands/fix/portability.md +1 -0
- package/dist/agent-src/commands/fix/pr-comments.md +147 -15
- package/dist/agent-src/commands/fix/refs.md +1 -0
- package/dist/agent-src/commands/fix/seeder.md +1 -0
- package/dist/agent-src/commands/fix.md +8 -8
- package/dist/agent-src/commands/ghostwriter/delete.md +1 -0
- package/dist/agent-src/commands/ghostwriter/fetch.md +1 -0
- package/dist/agent-src/commands/ghostwriter/list.md +1 -0
- package/dist/agent-src/commands/ghostwriter/show.md +1 -0
- package/dist/agent-src/commands/ghostwriter/write.md +1 -0
- package/dist/agent-src/commands/ghostwriter.md +1 -0
- package/dist/agent-src/commands/grill-me.md +3 -2
- package/dist/agent-src/commands/image/analyse.md +1 -0
- package/dist/agent-src/commands/image/create.md +1 -0
- package/dist/agent-src/commands/image/verify.md +1 -0
- package/dist/agent-src/commands/image.md +1 -0
- package/dist/agent-src/commands/implement-ticket.md +1 -0
- package/dist/agent-src/commands/jira-ticket.md +1 -0
- package/dist/agent-src/commands/judge/on-diff.md +1 -0
- package/dist/agent-src/commands/judge/solo.md +1 -0
- package/dist/agent-src/commands/judge/steps.md +1 -0
- package/dist/agent-src/commands/judge.md +1 -0
- package/dist/agent-src/commands/knowledge/cross-repo.md +1 -0
- package/dist/agent-src/commands/knowledge/forget.md +1 -0
- package/dist/agent-src/commands/knowledge/ingest.md +1 -0
- package/dist/agent-src/commands/knowledge/list.md +1 -0
- package/dist/agent-src/commands/knowledge.md +1 -0
- package/dist/agent-src/commands/memory/add.md +8 -6
- package/dist/agent-src/commands/memory/learn-low-impact.md +3 -2
- package/dist/agent-src/commands/memory/load.md +7 -7
- package/dist/agent-src/commands/memory/mine-session.md +39 -12
- package/dist/agent-src/commands/memory/promote.md +3 -2
- package/dist/agent-src/commands/memory/propose.md +7 -6
- package/dist/agent-src/commands/memory.md +3 -2
- package/dist/agent-src/commands/mode.md +1 -0
- package/dist/agent-src/commands/module/create.md +1 -0
- package/dist/agent-src/commands/module/explore.md +1 -0
- package/dist/agent-src/commands/module.md +1 -0
- package/dist/agent-src/commands/optimize/agents-dir.md +1 -0
- package/dist/agent-src/commands/optimize/augmentignore.md +1 -0
- package/dist/agent-src/commands/optimize/rtk.md +1 -0
- package/dist/agent-src/commands/optimize/skills.md +1 -0
- package/dist/agent-src/commands/optimize-prompt.md +1 -0
- package/dist/agent-src/commands/optimize.md +1 -0
- package/dist/agent-src/commands/orchestrate.md +1 -0
- package/dist/agent-src/commands/override/create.md +1 -0
- package/dist/agent-src/commands/override/manage.md +1 -0
- package/dist/agent-src/commands/override.md +1 -0
- package/dist/agent-src/commands/package-reset.md +1 -0
- package/dist/agent-src/commands/package-test.md +1 -0
- package/dist/agent-src/commands/post-as/ghostwriter.md +1 -0
- package/dist/agent-src/commands/post-as/me.md +1 -0
- package/dist/agent-src/commands/post-as.md +1 -0
- package/dist/agent-src/commands/pr/create/description-only.md +1 -0
- package/dist/agent-src/commands/pr/create.md +25 -0
- package/dist/agent-src/commands/prediction-pool.md +1 -0
- package/dist/agent-src/commands/prepare-for-review.md +1 -0
- package/dist/agent-src/commands/profile/activate.md +1 -0
- package/dist/agent-src/commands/profile/deactivate.md +1 -0
- package/dist/agent-src/commands/profile/show.md +1 -0
- package/dist/agent-src/commands/profile.md +1 -0
- package/dist/agent-src/commands/project-analyze.md +1 -0
- package/dist/agent-src/commands/project-health.md +1 -0
- package/dist/agent-src/commands/quality-fix.md +1 -0
- package/dist/agent-src/commands/refine-ticket.md +1 -0
- package/dist/agent-src/commands/research/deep.md +1 -0
- package/dist/agent-src/commands/research/report.md +1 -0
- package/dist/agent-src/commands/research.md +1 -0
- package/dist/agent-src/commands/review-changes.md +1 -0
- package/dist/agent-src/commands/review-routing.md +1 -0
- package/dist/agent-src/commands/roadmap/ai-council.md +1 -0
- package/dist/agent-src/commands/roadmap/create.md +1 -0
- package/dist/agent-src/commands/roadmap/process-full.md +1 -0
- package/dist/agent-src/commands/roadmap/process-phase.md +1 -0
- package/dist/agent-src/commands/roadmap/process-step.md +1 -0
- package/dist/agent-src/commands/roadmap.md +1 -0
- package/dist/agent-src/commands/rule-compliance-audit.md +1 -0
- package/dist/agent-src/commands/security-audit-config.md +84 -0
- package/dist/agent-src/commands/set-cost-profile.md +1 -0
- package/dist/agent-src/commands/skill/preview.md +1 -0
- package/dist/agent-src/commands/skill.md +1 -0
- package/dist/agent-src/commands/skills/discover.md +1 -0
- package/dist/agent-src/commands/skills.md +1 -0
- package/dist/agent-src/commands/sync-agent-settings.md +1 -0
- package/dist/agent-src/commands/sync-gitignore/fix.md +1 -0
- package/dist/agent-src/commands/sync-gitignore.md +1 -0
- package/dist/agent-src/commands/tests/create.md +1 -0
- package/dist/agent-src/commands/tests/execute.md +1 -0
- package/dist/agent-src/commands/tests.md +1 -0
- package/dist/agent-src/commands/threat-model.md +1 -0
- package/dist/agent-src/commands/update-form-request-messages.md +1 -0
- package/dist/agent-src/commands/upstream-contribute.md +1 -0
- package/dist/agent-src/commands/video/from-script.md +1 -0
- package/dist/agent-src/commands/video/from-song.md +1 -0
- package/dist/agent-src/commands/video/scene.md +1 -0
- package/dist/agent-src/commands/video/stitch.md +1 -0
- package/dist/agent-src/commands/video/storyboard.md +1 -0
- package/dist/agent-src/commands/video.md +1 -0
- package/dist/agent-src/commands/work.md +1 -0
- package/dist/agent-src/contexts/augment-infrastructure.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +2 -2
- package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +6 -6
- package/dist/agent-src/contexts/contracts/consumer-agents-md-guide.md +2 -2
- package/dist/agent-src/contexts/execution/rdp-gate.md +75 -0
- package/dist/agent-src/contexts/subagent-configuration.md +1 -0
- package/dist/agent-src/personas/advisors/contrarian.md +1 -1
- package/dist/agent-src/personas/advisors/executor.md +1 -1
- package/dist/agent-src/personas/advisors/expansionist.md +1 -1
- package/dist/agent-src/personas/advisors/first-principles.md +1 -1
- package/dist/agent-src/personas/advisors/outsider.md +1 -1
- package/dist/agent-src/rules/autonomous-execution.md +12 -0
- package/dist/agent-src/rules/external-reference-deep-dive.md +1 -1
- package/dist/agent-src/rules/git-history-discipline.md +47 -1
- package/dist/agent-src/rules/improve-before-implement.md +12 -0
- package/dist/agent-src/rules/lethal-trifecta-guard.md +80 -0
- package/dist/agent-src/rules/no-pr-progress-comments.md +3 -4
- package/dist/agent-src/rules/notes-first-reasoning.md +71 -0
- package/dist/agent-src/rules/roadmap-progress-sync.md +48 -31
- package/dist/agent-src/rules/security-sensitive-stop.md +14 -1
- package/dist/agent-src/rules/source-confidentiality.md +97 -0
- package/dist/agent-src/rules/think-before-action.md +9 -1
- package/dist/agent-src/rules/untrusted-input-defense.md +76 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.py +171 -0
- package/dist/agent-src/skills/adversarial-review/SKILL.md +14 -0
- package/dist/agent-src/skills/agent-security-review/SKILL.md +113 -0
- package/dist/agent-src/skills/agent-security-review/evals/triggers.json +51 -0
- package/dist/agent-src/skills/ai-council/SKILL.md +3 -3
- package/dist/agent-src/skills/async-python-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/blast-radius-analyzer/SKILL.md +12 -11
- package/dist/agent-src/skills/command-routing/SKILL.md +1 -1
- package/dist/agent-src/skills/complexity-first-planning/SKILL.md +96 -0
- package/dist/agent-src/skills/complexity-first-planning/evals/triggers.json +16 -0
- package/dist/agent-src/skills/copilot-config/SKILL.md +3 -4
- package/dist/agent-src/skills/defense-in-depth/SKILL.md +1 -1
- package/dist/agent-src/skills/developer-like-execution/SKILL.md +5 -4
- package/dist/agent-src/skills/error-handling-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/feature-planning/SKILL.md +2 -2
- package/dist/agent-src/skills/mcp-builder/SKILL.md +1 -1
- package/dist/agent-src/skills/memory-consolidation/SKILL.md +63 -17
- package/dist/agent-src/skills/prompt-engineering-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/readme-writing-package/SKILL.md +1 -1
- package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +119 -0
- package/dist/agent-src/skills/reasoning-orchestrator/evals/triggers.json +16 -0
- package/dist/agent-src/skills/receiving-code-review/SKILL.md +6 -6
- package/dist/agent-src/skills/refine-prompt/SKILL.md +1 -1
- package/dist/agent-src/skills/refine-ticket/SKILL.md +1 -1
- package/dist/agent-src/skills/repomix-packer/SKILL.md +1 -1
- package/dist/agent-src/skills/secrets-management/SKILL.md +1 -1
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +10 -3
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +1 -1
- package/dist/agent-src/skills/token-optimizer/SKILL.md +1 -1
- package/dist/agent-src/templates/agents/.gitattributes.fragment +0 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +4 -4
- package/dist/agent-src/templates/scripts/check_memory.py +1 -2
- package/dist/agent-src/templates/scripts/check_memory_proposal.py +1 -1
- package/dist/agent-src/templates/scripts/memory_lookup.py +148 -289
- package/dist/agent-src/templates/scripts/memory_report.py +132 -2
- package/dist/agent-src/templates/scripts/memory_signal.py +7 -9
- package/dist/agent-src/templates/scripts/memory_status.py +25 -206
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/memory.py +6 -6
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/_passthrough.py +3 -3
- package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.py +0 -1
- package/dist/cli/agent-config.js +31 -300
- package/dist/cli/agent-config.js.map +1 -1
- package/dist/cli/commands/commands.js +10 -5
- package/dist/cli/commands/commands.js.map +1 -1
- package/dist/cli/discovery/loadManifest.js.map +1 -1
- package/dist/cli/main.js +309 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +645 -342
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +8 -5
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +149 -37
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +61 -36
- package/dist/mcp/registry-manifest.json +4 -4
- package/dist/router.json +1 -1
- package/dist/server/routes/wizard.js +4 -3
- package/dist/server/routes/wizard.js.map +1 -1
- package/dist/server/schemas/settings.js +18 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/docs/MIGRATION.md +1 -1
- package/docs/adrs/cost/0001-hard-stop-hook.md +5 -5
- package/docs/adrs/memory/0001-consumer-side-snapshot.md +15 -7
- package/docs/adrs/memory/README.md +6 -5
- package/docs/adrs/router/0001-three-tier-routing.md +2 -2
- package/docs/adrs/schema/0001-json-schema-frontmatter.md +2 -2
- package/docs/adrs/smoke/0001-per-tier-smoke-scripts.md +5 -5
- package/docs/adrs/telegraph/0001-default-off-until-bench.md +3 -3
- package/docs/architecture.md +9 -9
- package/docs/archive/CHANGELOG-pre-2.2.0.md +30 -30
- package/docs/archive/CHANGELOG-pre-2.25.0.md +1 -1
- package/docs/archive/CHANGELOG-pre-4.5.0.md +1 -1
- package/docs/archive/CHANGELOG-pre-6.0.0.md +473 -0
- package/docs/benchmark.md +54 -53
- package/docs/benchmarks.md +2 -2
- package/docs/case-studies/{frontend-design-vs-ui-ux-pro-max.md → frontend-design-positioning.md} +4 -4
- package/docs/catalog.md +20 -13
- package/docs/command-flows.md +90 -92
- package/docs/contracts/adr-layout.md +2 -3
- package/docs/contracts/adr-level-6-productization.md +1 -1
- package/docs/contracts/ai-council-config.md +42 -7
- package/docs/contracts/command-clusters.md +1 -1
- package/docs/contracts/cost-enforcement.md +1 -1
- package/docs/contracts/cost-summary-schema.md +1 -1
- package/docs/contracts/daily-workspace.md +1 -0
- package/docs/contracts/discovery-manifest.schema.json +4 -2
- package/docs/contracts/explain-modes.md +1 -1
- package/docs/contracts/implement-ticket-flow.md +6 -7
- package/docs/contracts/mcp-tool-inventory.md +10 -10
- package/docs/contracts/measurement-baseline.md +1 -1
- package/docs/contracts/memory-visibility-v1.md +1 -5
- package/docs/contracts/namespace.md +1 -1
- package/docs/contracts/persona-schema.md +1 -1
- package/docs/contracts/rule-interactions.md +1 -1
- package/docs/contracts/smoke-contracts.md +1 -1
- package/docs/contracts/universal-skills.md +0 -1
- package/docs/contracts/workspace-boundary.md +84 -0
- package/docs/customization.md +3 -3
- package/docs/decisions/ADR-009-event4u-namespace.md +1 -1
- package/docs/decisions/ADR-013-discovery-frontmatter-contract.md +1 -1
- package/docs/decisions/ADR-026-explain-mode-translation.md +1 -1
- package/docs/decisions/ADR-088-no-external-runtime-federation.md +26 -27
- package/docs/decisions/ADR-090-visibility-command-frontmatter-field.md +95 -0
- package/docs/decisions/ADR-091-split-meta-capability-packs.md +113 -0
- package/docs/decisions/ADR-092-defer-command-tier-alias-removal.md +93 -0
- package/docs/decisions/ADR-093-ai-council-config-user-global.md +111 -0
- package/docs/decisions/ADR-094-agent-memory-layer-removal.md +94 -0
- package/docs/decisions/ADR-095-workspace-boundary-contract.md +108 -0
- package/docs/decisions/INDEX.md +6 -0
- package/docs/development.md +5 -7
- package/docs/getting-started.md +4 -4
- package/docs/guidelines/agent-infra/5w2h-analysis.md +1 -1
- package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
- package/docs/guidelines/agent-infra/corpus-grounding-authoring.md +1 -1
- package/docs/guidelines/agent-infra/critical-thinking.md +1 -1
- package/docs/guidelines/agent-infra/engineering-memory-data-format.md +1 -5
- package/docs/guidelines/agent-infra/first-principles.md +1 -1
- package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +164 -0
- package/docs/guidelines/agent-infra/inversion-thinking.md +1 -1
- package/docs/guidelines/agent-infra/ios-simulator-guide.md +9 -14
- package/docs/guidelines/agent-infra/mcp-request-signing.md +19 -22
- package/docs/guidelines/agent-infra/memory-access.md +25 -31
- package/docs/guidelines/agent-infra/mental-models.md +1 -1
- package/docs/guidelines/agent-infra/model-recommendation.md +29 -0
- package/docs/guidelines/agent-infra/scqa-framework.md +3 -3
- package/docs/guidelines/agent-infra/security-lint-containment.md +81 -0
- package/docs/guidelines/agent-infra/six-hats.md +1 -1
- package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
- package/docs/guidelines/agent-infra/untrusted-input-spotlighting.md +72 -0
- package/docs/installation.md +1 -1
- package/docs/mcp.md +2 -2
- package/docs/parity/{bench-ruflo.json → bench-external.json} +10 -10
- package/docs/parity/{ruflo.md → external-runtime.md} +9 -9
- package/docs/quality.md +3 -3
- package/docs/safety.md +3 -3
- package/docs/skills-catalog.md +4 -1
- package/llms.txt +3 -0
- package/package.json +1 -1
- package/src/config/agent-settings.template.yml +65 -3
- package/src/config/discovery/packs.yml +29 -0
- package/src/config/discovery/workspaces.yml +3 -1
- package/src/config/gitignore-block.txt +6 -0
- package/src/scripts/__pycache__/validate_frontmatter.cpython-312.pyc +0 -0
- package/src/scripts/_cli/cmd_doctor.py +99 -13
- package/src/scripts/_lib/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/scripts/_lib/__pycache__/agent_src.cpython-312.pyc +0 -0
- package/src/scripts/_lib/bench_ab_scoring_v2.py +227 -0
- package/src/scripts/_lib/global_deploy_inventory.py +39 -9
- package/src/scripts/_lib/link_crypto.py +206 -0
- package/src/scripts/_lib/security_lint.py +228 -0
- package/src/scripts/ai_council/clients.py +2 -2
- package/src/scripts/ai_council/config.py +55 -0
- package/src/scripts/audit_adr_coverage.py +0 -2
- package/src/scripts/audit_command_surface.py +18 -5
- package/src/scripts/audit_mcp_tools.py +2 -2
- package/src/scripts/audit_skill_descriptions.py +2 -2
- package/src/scripts/bench_ab_clone.py +62 -12
- package/src/scripts/bench_ab_task_runner.py +475 -30
- package/src/scripts/bench_ab_v2_run.py +247 -0
- package/src/scripts/bench_ab_v2_stats.py +347 -0
- package/src/scripts/bench_run.py +1 -1
- package/src/scripts/build_discovery_manifest.py +10 -0
- package/src/scripts/check_bite_sized_granularity.py +1 -2
- package/src/scripts/check_memory.py +49 -63
- package/src/scripts/check_memory_proposal.py +1 -1
- package/src/scripts/check_no_external_sources.py +101 -0
- package/src/scripts/check_references.py +2 -0
- package/src/scripts/cost_by_conversation.py +1 -1
- package/src/scripts/council_cli.py +28 -14
- package/src/scripts/external_sources_denylist.json +91 -0
- package/src/scripts/hook_manifest.yaml +14 -6
- package/src/scripts/injection_scan_hook.py +145 -0
- package/src/scripts/install-hooks.sh +11 -0
- package/src/scripts/install.py +88 -13
- package/src/scripts/lint_agent_security.py +112 -0
- package/src/scripts/lint_bench_ab.py +5 -4
- package/src/scripts/lint_command_tiers.py +63 -22
- package/src/scripts/lint_discovery_vocabulary.py +2 -0
- package/src/scripts/lint_empty_roadmaps.py +80 -0
- package/src/scripts/lint_hidden_unicode.py +132 -0
- package/src/scripts/lint_instruction_smuggling.py +107 -0
- package/src/scripts/lint_marketplace.py +1 -1
- package/src/scripts/lint_mcp_config_security.py +124 -0
- package/src/scripts/lint_skill_frontmatter_safety.py +144 -0
- package/src/scripts/lint_workspace_boundary.py +122 -0
- package/src/scripts/mcp_server/consumer_tool_catalog.json +2 -3
- package/src/scripts/mcp_server/tools.py +8 -32
- package/src/scripts/memory_lookup.py +27 -296
- package/src/scripts/memory_report.py +1 -23
- package/src/scripts/memory_signal.py +6 -53
- package/src/scripts/memory_status.py +25 -206
- package/src/scripts/mine_session.py +118 -41
- package/src/scripts/pack_dependency_allowlist.json +2 -2
- package/src/scripts/render_benchmark_md.py +141 -52
- package/src/scripts/schemas/command.schema.json +6 -1
- package/src/scripts/security_audit_config.py +153 -0
- package/dist/agent-src/commands/chat-history/learn.md +0 -184
- package/dist/agent-src/commands/chat-history/show.md +0 -113
- package/dist/agent-src/commands/fix/pr-bot-comments.md +0 -157
- package/dist/agent-src/commands/fix/pr-developer-comments.md +0 -163
- package/dist/agent-src/templates/agents/memory/architecture-decisions.example.yml +0 -95
- package/docs/contracts/agent-memory-contract.md +0 -159
|
@@ -1,46 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
2
|
+
"""File-backed memory status (no external backend).
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
(`scripts/memory_lookup.py`)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
* `absent` — package not installed or CLI not on PATH
|
|
11
|
-
* `misconfigured` — installed but `health()` fails within the timeout
|
|
12
|
-
* `present` — installed, healthy, usable now
|
|
13
|
-
|
|
14
|
-
Result is cached per process under `os.environ["AGENT_MEMORY_STATUS"]`
|
|
15
|
-
and (optionally) under `.agent-memory/status.cache` per session.
|
|
4
|
+
The optional `@event4u/agent-memory` package was removed; retrieval
|
|
5
|
+
(`scripts/memory_lookup.py`) and signal-writing (`scripts/memory_signal.py`)
|
|
6
|
+
are entirely file-backed now. `status()` / `health()` report the file
|
|
7
|
+
backend so the v1 retrieval-contract health envelope stays stable for
|
|
8
|
+
consumers (e.g. the MCP `memory_status` tool).
|
|
16
9
|
|
|
17
10
|
Usage:
|
|
18
11
|
python3 scripts/memory_status.py # human-readable line
|
|
19
12
|
python3 scripts/memory_status.py --format json # stable JSON
|
|
20
|
-
|
|
13
|
+
python3 scripts/memory_status.py --health # v1 health envelope
|
|
14
|
+
from scripts.memory_status import status, health # Python import
|
|
21
15
|
"""
|
|
22
16
|
|
|
23
17
|
from __future__ import annotations
|
|
24
18
|
|
|
25
19
|
import argparse
|
|
26
20
|
import json
|
|
27
|
-
import os
|
|
28
|
-
import shutil
|
|
29
|
-
import subprocess
|
|
30
21
|
import sys
|
|
31
|
-
import time
|
|
32
22
|
from dataclasses import dataclass, asdict
|
|
33
|
-
from pathlib import Path
|
|
34
|
-
from typing import Literal
|
|
35
23
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
_CLI_CANDIDATES = ("memory", "agent-memory", "agentmem")
|
|
39
|
-
_HEALTH_TIMEOUT_SECONDS = 2.0
|
|
40
|
-
_CACHE_ENV = "AGENT_MEMORY_STATUS"
|
|
41
|
-
_CACHE_FILE = Path(".agent-memory") / "status.cache"
|
|
42
|
-
|
|
43
|
-
# Retrieval contract version served by the file-backed fallback.
|
|
24
|
+
# Retrieval contract version served by the file-backed backend.
|
|
44
25
|
# Source of truth: internal/schemas/retrieval-v1.schema.json.
|
|
45
26
|
CONTRACT_VERSION = 1
|
|
46
27
|
_FILE_BACKEND_VERSION = "0.0.0-file"
|
|
@@ -49,184 +30,24 @@ _FILE_BACKEND_FEATURES = ("file-fallback",)
|
|
|
49
30
|
|
|
50
31
|
@dataclass
|
|
51
32
|
class Result:
|
|
52
|
-
status:
|
|
53
|
-
backend: str
|
|
54
|
-
reason: str
|
|
55
|
-
elapsed_ms: int
|
|
56
|
-
cli_path: str = "" # resolved CLI path, if any
|
|
57
|
-
# Populated only when status == "present" — sourced from the
|
|
58
|
-
# `health` CLI envelope so the v1 health() reports real package
|
|
59
|
-
# capabilities instead of file-fallback placeholders.
|
|
60
|
-
backend_version: str = ""
|
|
61
|
-
features: tuple = ()
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def _find_cli() -> str:
|
|
65
|
-
for name in _CLI_CANDIDATES:
|
|
66
|
-
path = shutil.which(name)
|
|
67
|
-
if path:
|
|
68
|
-
return path
|
|
69
|
-
return ""
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def _parse_health_envelope(stdout: str) -> dict | None:
|
|
73
|
-
"""Extract the v1 health envelope from `memory health` stdout.
|
|
74
|
-
|
|
75
|
-
The package emits a single JSON object on stdout (pino structured
|
|
76
|
-
logs go to stderr). We tolerate older builds that may have leaked
|
|
77
|
-
log lines into stdout by scanning for the first top-level object
|
|
78
|
-
that carries ``contract_version``.
|
|
79
|
-
"""
|
|
80
|
-
text = (stdout or "").strip()
|
|
81
|
-
if not text:
|
|
82
|
-
return None
|
|
83
|
-
try:
|
|
84
|
-
obj = json.loads(text)
|
|
85
|
-
except ValueError:
|
|
86
|
-
obj = None
|
|
87
|
-
if isinstance(obj, dict) and obj.get("contract_version"):
|
|
88
|
-
return obj
|
|
89
|
-
# Fallback: line-by-line scan for an envelope-shaped object — covers
|
|
90
|
-
# the case where structured logs accidentally share stdout.
|
|
91
|
-
for line in text.splitlines():
|
|
92
|
-
line = line.strip()
|
|
93
|
-
if not line.startswith("{"):
|
|
94
|
-
continue
|
|
95
|
-
try:
|
|
96
|
-
cand = json.loads(line)
|
|
97
|
-
except ValueError:
|
|
98
|
-
continue
|
|
99
|
-
if isinstance(cand, dict) and cand.get("contract_version"):
|
|
100
|
-
return cand
|
|
101
|
-
return None
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
def _probe_health(cli_path: str) -> tuple[bool, str, dict | None]:
|
|
105
|
-
"""Returns (healthy, reason, envelope).
|
|
106
|
-
|
|
107
|
-
On success ``envelope`` is the parsed v1 health envelope (may still
|
|
108
|
-
be ``None`` for very old CLIs that don't emit one). On failure it
|
|
109
|
-
is always ``None``.
|
|
110
|
-
"""
|
|
111
|
-
try:
|
|
112
|
-
out = subprocess.run(
|
|
113
|
-
[cli_path, "health"],
|
|
114
|
-
capture_output=True, text=True,
|
|
115
|
-
timeout=_HEALTH_TIMEOUT_SECONDS,
|
|
116
|
-
)
|
|
117
|
-
except subprocess.TimeoutExpired:
|
|
118
|
-
return False, f"health() timed out after {_HEALTH_TIMEOUT_SECONDS}s", None
|
|
119
|
-
except FileNotFoundError:
|
|
120
|
-
return False, "CLI vanished between which() and invoke", None
|
|
121
|
-
if out.returncode != 0:
|
|
122
|
-
# First line of combined output, capped, for the reason field.
|
|
123
|
-
msg = (out.stderr or out.stdout or "exit != 0").strip().splitlines()
|
|
124
|
-
head = msg[0][:120] if msg else "exit != 0"
|
|
125
|
-
return False, f"health() returned {out.returncode}: {head}", None
|
|
126
|
-
envelope = _parse_health_envelope(out.stdout)
|
|
127
|
-
return True, "ok", envelope
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
def _read_cache() -> Result | None:
|
|
131
|
-
cached = os.environ.get(_CACHE_ENV)
|
|
132
|
-
if cached:
|
|
133
|
-
try:
|
|
134
|
-
data = json.loads(cached)
|
|
135
|
-
return Result(**data)
|
|
136
|
-
except (ValueError, TypeError):
|
|
137
|
-
pass
|
|
138
|
-
if _CACHE_FILE.is_file():
|
|
139
|
-
try:
|
|
140
|
-
data = json.loads(_CACHE_FILE.read_text(encoding="utf-8"))
|
|
141
|
-
return Result(**data)
|
|
142
|
-
except (OSError, ValueError, TypeError):
|
|
143
|
-
pass
|
|
144
|
-
return None
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
def _write_cache(result: Result) -> None:
|
|
148
|
-
payload = json.dumps(asdict(result))
|
|
149
|
-
os.environ[_CACHE_ENV] = payload
|
|
150
|
-
try:
|
|
151
|
-
_CACHE_FILE.parent.mkdir(parents=True, exist_ok=True)
|
|
152
|
-
_CACHE_FILE.write_text(payload, encoding="utf-8")
|
|
153
|
-
except OSError:
|
|
154
|
-
# Best-effort cache; skills MUST still work without it.
|
|
155
|
-
pass
|
|
33
|
+
status: str = "file" # always "file" — no external backend
|
|
34
|
+
backend: str = "file"
|
|
35
|
+
reason: str = "file-backed memory (no external backend)"
|
|
36
|
+
elapsed_ms: int = 0
|
|
156
37
|
|
|
157
38
|
|
|
158
39
|
def status(refresh: bool = False) -> Result:
|
|
159
|
-
"""Return the
|
|
160
|
-
|
|
161
|
-
Always returns in well under ``_HEALTH_TIMEOUT_SECONDS`` seconds on
|
|
162
|
-
cache hit; bounded by the timeout on cache miss. Never raises —
|
|
163
|
-
probe failures degrade to ``absent`` / ``misconfigured`` rather than
|
|
164
|
-
surfacing exceptions.
|
|
165
|
-
"""
|
|
166
|
-
if not refresh:
|
|
167
|
-
cached = _read_cache()
|
|
168
|
-
if cached is not None:
|
|
169
|
-
cached.elapsed_ms = 0
|
|
170
|
-
return cached
|
|
171
|
-
t0 = time.monotonic()
|
|
172
|
-
cli = _find_cli()
|
|
173
|
-
if not cli:
|
|
174
|
-
result = Result("absent", "file",
|
|
175
|
-
"agent-memory CLI not on PATH", 0)
|
|
176
|
-
else:
|
|
177
|
-
healthy, reason, envelope = _probe_health(cli)
|
|
178
|
-
elapsed = int((time.monotonic() - t0) * 1000)
|
|
179
|
-
if healthy:
|
|
180
|
-
backend_version = ""
|
|
181
|
-
features: tuple = ()
|
|
182
|
-
if isinstance(envelope, dict):
|
|
183
|
-
bv = envelope.get("backend_version")
|
|
184
|
-
if isinstance(bv, str):
|
|
185
|
-
backend_version = bv
|
|
186
|
-
feats = envelope.get("features")
|
|
187
|
-
if isinstance(feats, list) and all(
|
|
188
|
-
isinstance(f, str) for f in feats
|
|
189
|
-
):
|
|
190
|
-
features = tuple(feats)
|
|
191
|
-
result = Result("present", "package", reason, elapsed, cli,
|
|
192
|
-
backend_version=backend_version,
|
|
193
|
-
features=features)
|
|
194
|
-
else:
|
|
195
|
-
result = Result("misconfigured", "file", reason, elapsed, cli)
|
|
196
|
-
_write_cache(result)
|
|
197
|
-
return result
|
|
40
|
+
"""Return the (constant) file-backend status. Never raises."""
|
|
41
|
+
return Result()
|
|
198
42
|
|
|
199
43
|
|
|
200
44
|
def health(refresh: bool = False) -> dict:
|
|
201
|
-
"""Return a v1 retrieval-contract health envelope.
|
|
202
|
-
|
|
203
|
-
Schema: ``internal/schemas/retrieval-v1.schema.json`` (HealthResponse).
|
|
204
|
-
Maps the three-state :func:`status` result onto the contract's
|
|
205
|
-
``ok | degraded | error`` so consumers can read
|
|
206
|
-
``contract_version`` without caring about the file-vs-package split.
|
|
207
|
-
|
|
208
|
-
When the package backs the call (``status == "present"``), the
|
|
209
|
-
envelope reports the package's own ``backend_version`` and
|
|
210
|
-
``features`` so consumers can feature-detect against real
|
|
211
|
-
capabilities. Otherwise the file-fallback markers are returned.
|
|
212
|
-
"""
|
|
213
|
-
r = status(refresh=refresh)
|
|
214
|
-
envelope_status = {
|
|
215
|
-
"present": "ok",
|
|
216
|
-
"misconfigured": "degraded",
|
|
217
|
-
"absent": "ok",
|
|
218
|
-
}[r.status]
|
|
219
|
-
if r.status == "present" and (r.backend_version or r.features):
|
|
220
|
-
backend_version = r.backend_version or _FILE_BACKEND_VERSION
|
|
221
|
-
features = list(r.features) if r.features else list(_FILE_BACKEND_FEATURES)
|
|
222
|
-
else:
|
|
223
|
-
backend_version = _FILE_BACKEND_VERSION
|
|
224
|
-
features = list(_FILE_BACKEND_FEATURES)
|
|
45
|
+
"""Return a v1 retrieval-contract health envelope (file backend)."""
|
|
225
46
|
return {
|
|
226
47
|
"contract_version": CONTRACT_VERSION,
|
|
227
|
-
"status":
|
|
228
|
-
"backend_version":
|
|
229
|
-
"features":
|
|
48
|
+
"status": "ok",
|
|
49
|
+
"backend_version": _FILE_BACKEND_VERSION,
|
|
50
|
+
"features": list(_FILE_BACKEND_FEATURES),
|
|
230
51
|
}
|
|
231
52
|
|
|
232
53
|
|
|
@@ -234,22 +55,20 @@ def main() -> int:
|
|
|
234
55
|
ap = argparse.ArgumentParser(description=__doc__)
|
|
235
56
|
ap.add_argument("--format", choices=["text", "json"], default="text")
|
|
236
57
|
ap.add_argument("--refresh", action="store_true",
|
|
237
|
-
help="
|
|
58
|
+
help="No-op (kept for back-compat); status is constant")
|
|
238
59
|
ap.add_argument("--health", action="store_true",
|
|
239
60
|
help="Emit a v1 retrieval-contract health envelope "
|
|
240
|
-
"instead of the
|
|
61
|
+
"instead of the status line")
|
|
241
62
|
args = ap.parse_args()
|
|
242
63
|
if args.health:
|
|
243
|
-
print(json.dumps(health(
|
|
64
|
+
print(json.dumps(health()))
|
|
244
65
|
return 0
|
|
245
|
-
r = status(
|
|
66
|
+
r = status()
|
|
246
67
|
if args.format == "json":
|
|
247
68
|
print(json.dumps(asdict(r)))
|
|
248
69
|
else:
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
f"elapsed={r.elapsed_ms}ms reason={r.reason}")
|
|
252
|
-
# `absent` is a valid operational state, not a failure.
|
|
70
|
+
print(f" ℹ️ backend={r.backend} status={r.status} "
|
|
71
|
+
f"reason={r.reason}")
|
|
253
72
|
return 0
|
|
254
73
|
|
|
255
74
|
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""Mine session
|
|
2
|
+
"""Mine a session for memory signals — the engine behind `/memory mine`.
|
|
3
3
|
|
|
4
|
-
Implements the GATHER SIGNAL phase of the `memory-consolidation` skill
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
Implements the GATHER SIGNAL phase of the `memory-consolidation` skill.
|
|
5
|
+
The canonical, **cross-host** source is the chat-history JSONL log
|
|
6
|
+
(``agents/runtime/.agent-chat-history``, written by platform hooks for
|
|
7
|
+
every host); the per-host Claude-Code transcript
|
|
8
|
+
(``~/.claude/projects/*.jsonl``) is a fallback when the log is absent.
|
|
9
|
+
|
|
10
|
+
``--mode``: ``signals`` (default) extracts normalised facts → intake
|
|
11
|
+
preview / ``--commit-intake``; ``proposals`` frames the facts as
|
|
12
|
+
candidate rule/skill learnings (the `/memory mine` command then runs
|
|
13
|
+
``learning-to-rule-or-skill`` on them); ``both`` renders both.
|
|
9
14
|
|
|
10
15
|
Strict gates: opt-in transcript access (``--confirm-transcript-access``
|
|
11
16
|
required per invocation), ≤ 5 normalised facts per cycle, redaction
|
|
12
17
|
applied to every yielded text. See
|
|
13
|
-
|
|
14
|
-
authored spec.
|
|
18
|
+
``src/domains/meta/memory/mine-session/command.md`` for the authored spec.
|
|
15
19
|
"""
|
|
16
20
|
|
|
17
21
|
from __future__ import annotations
|
|
@@ -28,6 +32,7 @@ from typing import Any, Iterable
|
|
|
28
32
|
|
|
29
33
|
ROOT = Path(__file__).resolve().parent.parent.parent
|
|
30
34
|
INTAKE_ROOT = Path("agents/memory/intake")
|
|
35
|
+
CHAT_HISTORY_LOG = Path("agents/runtime/.agent-chat-history")
|
|
31
36
|
DEFAULT_WINDOW_DAYS = 14
|
|
32
37
|
MAX_FACTS = 5
|
|
33
38
|
|
|
@@ -84,7 +89,32 @@ def _iter_claude_code_jsonl(path: Path) -> Iterable[dict[str, Any]]:
|
|
|
84
89
|
continue
|
|
85
90
|
|
|
86
91
|
|
|
92
|
+
def _iter_chat_history(path: Path) -> Iterable[dict[str, Any]]:
|
|
93
|
+
"""Yield body entries from the cross-host chat-history JSONL log.
|
|
94
|
+
|
|
95
|
+
Skips the ``{"t": "header"}`` line. Each body entry carries a flat
|
|
96
|
+
``text`` field, a ``ts`` timestamp, a ``t`` role (user/agent/tool/
|
|
97
|
+
phase), and a session tag ``s`` — see ``scripts/chat_history.py``.
|
|
98
|
+
"""
|
|
99
|
+
with path.open(encoding="utf-8") as f:
|
|
100
|
+
for line in f:
|
|
101
|
+
line = line.strip()
|
|
102
|
+
if not line:
|
|
103
|
+
continue
|
|
104
|
+
try:
|
|
105
|
+
obj = json.loads(line)
|
|
106
|
+
except json.JSONDecodeError:
|
|
107
|
+
continue
|
|
108
|
+
if isinstance(obj, dict) and obj.get("t") != "header":
|
|
109
|
+
yield obj
|
|
110
|
+
|
|
111
|
+
|
|
87
112
|
def _turn_text(turn: dict[str, Any]) -> str:
|
|
113
|
+
# Chat-history log entries carry a flat `text` string.
|
|
114
|
+
flat = turn.get("text")
|
|
115
|
+
if isinstance(flat, str):
|
|
116
|
+
return flat
|
|
117
|
+
# Claude-Code transcript shape: message.content (str or block list).
|
|
88
118
|
msg = turn.get("message") or {}
|
|
89
119
|
content = msg.get("content")
|
|
90
120
|
if isinstance(content, str):
|
|
@@ -142,17 +172,23 @@ def _session_id(transcript: Path) -> str:
|
|
|
142
172
|
return h[:16]
|
|
143
173
|
|
|
144
174
|
|
|
145
|
-
def mine(
|
|
146
|
-
extra_patterns: list[re.Pattern[str]]
|
|
147
|
-
|
|
148
|
-
|
|
175
|
+
def mine(entries: Iterable[dict[str, Any]], since: dt.datetime,
|
|
176
|
+
extra_patterns: list[re.Pattern[str]],
|
|
177
|
+
session_id: str) -> list[dict[str, Any]]:
|
|
178
|
+
"""Return up to MAX_FACTS normalised facts (preview shape).
|
|
179
|
+
|
|
180
|
+
``entries`` is any iterable of turn-shaped dicts (chat-history log
|
|
181
|
+
body entries or Claude-Code transcript turns). ``session_id`` is the
|
|
182
|
+
fallback tag when an entry carries no ``s`` field.
|
|
183
|
+
"""
|
|
184
|
+
turns_in_window = [t for t in entries
|
|
149
185
|
if _within_window(_turn_ts(t), since)]
|
|
150
186
|
facts: list[dict[str, Any]] = []
|
|
151
|
-
session_id = _session_id(transcript)
|
|
152
187
|
for turn in turns_in_window:
|
|
153
188
|
text = _turn_text(turn)
|
|
154
189
|
if not text:
|
|
155
190
|
continue
|
|
191
|
+
sid = turn.get("s") or session_id
|
|
156
192
|
for tag, family in SIGNAL_FAMILIES.items():
|
|
157
193
|
if not family.search(text):
|
|
158
194
|
continue
|
|
@@ -166,7 +202,7 @@ def mine(transcript: Path, since: dt.datetime,
|
|
|
166
202
|
"key": _key_of(text),
|
|
167
203
|
"observation": obs,
|
|
168
204
|
"source": "agent",
|
|
169
|
-
"session_id":
|
|
205
|
+
"session_id": sid,
|
|
170
206
|
"tags": [tag],
|
|
171
207
|
})
|
|
172
208
|
break
|
|
@@ -207,17 +243,47 @@ def commit_intake(facts: list[dict[str, Any]], intake_root: Path) -> int:
|
|
|
207
243
|
return written
|
|
208
244
|
|
|
209
245
|
|
|
210
|
-
def
|
|
246
|
+
def render_proposal_seeds(facts: list[dict[str, Any]],
|
|
247
|
+
project: str, window: str) -> str:
|
|
248
|
+
"""Frame mined facts as candidate rule/skill learnings.
|
|
249
|
+
|
|
250
|
+
The `/memory mine` command feeds these into `learning-to-rule-or-skill`;
|
|
251
|
+
this engine only surfaces the seeds — it does not author proposals.
|
|
252
|
+
"""
|
|
253
|
+
if not facts:
|
|
254
|
+
return (f"## Proposal seeds — {project} · {window}\n\n"
|
|
255
|
+
"_No signals matched — nothing to propose._\n")
|
|
256
|
+
lines = [f"## Proposal seeds — {project} · {window}", "",
|
|
257
|
+
"Run `learning-to-rule-or-skill` on each durable seed below:",
|
|
258
|
+
""]
|
|
259
|
+
for i, f in enumerate(facts, 1):
|
|
260
|
+
lines.append(f"{i}. **{f['type']}** · `{f['key']}` — {f['observation']}")
|
|
261
|
+
return "\n".join(lines) + "\n"
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def _resolve_source(source: str, host: str,
|
|
265
|
+
override: str | None) -> tuple[Path | None, str]:
|
|
266
|
+
"""Return (path, kind). kind ∈ {chat-history, claude-code}.
|
|
267
|
+
|
|
268
|
+
Default ``source=auto`` prefers the cross-host chat-history log, then
|
|
269
|
+
falls back to the per-host Claude-Code transcript.
|
|
270
|
+
"""
|
|
211
271
|
if override:
|
|
212
|
-
return Path(override)
|
|
272
|
+
return Path(override), ("claude-code" if host == "claude-code"
|
|
273
|
+
else "chat-history")
|
|
274
|
+
if source in ("auto", "chat-history") and CHAT_HISTORY_LOG.exists():
|
|
275
|
+
return CHAT_HISTORY_LOG, "chat-history"
|
|
276
|
+
if source == "chat-history":
|
|
277
|
+
return None, "chat-history"
|
|
278
|
+
# claude-code fallback
|
|
213
279
|
if host != "claude-code":
|
|
214
|
-
return None
|
|
280
|
+
return None, host
|
|
215
281
|
home = Path(os.path.expanduser("~/.claude/projects"))
|
|
216
282
|
if not home.exists():
|
|
217
|
-
return None
|
|
283
|
+
return None, "claude-code"
|
|
218
284
|
candidates = sorted(home.rglob("*.jsonl"),
|
|
219
285
|
key=lambda p: p.stat().st_mtime, reverse=True)
|
|
220
|
-
return candidates[0] if candidates else None
|
|
286
|
+
return (candidates[0] if candidates else None), "claude-code"
|
|
221
287
|
|
|
222
288
|
|
|
223
289
|
def main(argv: list[str] | None = None) -> int:
|
|
@@ -227,51 +293,62 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
227
293
|
ap.add_argument("--confirm-transcript-access", action="store_true")
|
|
228
294
|
ap.add_argument("--preview", action="store_true", default=True)
|
|
229
295
|
ap.add_argument("--commit-intake", action="store_true")
|
|
296
|
+
ap.add_argument("--mode", choices=["signals", "proposals", "both"],
|
|
297
|
+
default="signals",
|
|
298
|
+
help="signals → intake facts (default); proposals → "
|
|
299
|
+
"proposal seeds for learning-to-rule-or-skill; both")
|
|
300
|
+
ap.add_argument("--source", choices=["auto", "chat-history", "claude-code"],
|
|
301
|
+
default="auto",
|
|
302
|
+
help="auto (default) prefers the cross-host chat-history "
|
|
303
|
+
"log, then the Claude-Code transcript")
|
|
230
304
|
ap.add_argument("--host", default="claude-code")
|
|
231
305
|
ap.add_argument("--transcript", default=None,
|
|
232
|
-
help="Override
|
|
306
|
+
help="Override source path (testing)")
|
|
233
307
|
ap.add_argument("--intake-root", default=str(INTAKE_ROOT))
|
|
234
308
|
ap.add_argument("--project", default=Path.cwd().name)
|
|
235
309
|
ns = ap.parse_args(argv)
|
|
236
310
|
|
|
237
|
-
if ns.commit_intake
|
|
238
|
-
ns.preview = False
|
|
239
|
-
if ns.commit_intake and ns.preview:
|
|
311
|
+
if ns.commit_intake:
|
|
240
312
|
ns.preview = False # commit-intake wins
|
|
241
313
|
|
|
242
314
|
if not ns.confirm_transcript_access:
|
|
243
|
-
print("> Mining reads your session transcript
|
|
315
|
+
print("> Mining reads your session log / transcript. Re-run with\n"
|
|
244
316
|
"> --confirm-transcript-access to proceed. The flag is "
|
|
245
317
|
"per-invocation\n> and not persisted.")
|
|
246
318
|
return 0
|
|
247
319
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
"
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
transcript = _resolve_transcript(ns.host, ns.transcript)
|
|
255
|
-
if transcript is None or not transcript.exists():
|
|
256
|
-
print("> No transcript found for host=claude-code. "
|
|
257
|
-
"Use /memory propose.")
|
|
320
|
+
path, kind = _resolve_source(ns.source, ns.host, ns.transcript)
|
|
321
|
+
if path is None or not path.exists():
|
|
322
|
+
print("> No session source found (no chat-history log, no "
|
|
323
|
+
"Claude-Code transcript). Use /memory propose to record "
|
|
324
|
+
"signals manually.")
|
|
258
325
|
return 0
|
|
259
326
|
|
|
327
|
+
entries = (_iter_chat_history(path) if kind == "chat-history"
|
|
328
|
+
else _iter_claude_code_jsonl(path))
|
|
260
329
|
since = (dt.datetime.fromisoformat(ns.since)
|
|
261
330
|
.replace(tzinfo=dt.timezone.utc) if ns.since
|
|
262
331
|
else dt.datetime.now(dt.timezone.utc)
|
|
263
332
|
- dt.timedelta(days=DEFAULT_WINDOW_DAYS))
|
|
264
|
-
facts = mine(
|
|
333
|
+
facts = mine(entries, since, extra_patterns=[],
|
|
334
|
+
session_id=_session_id(path))
|
|
265
335
|
window = f"since {since.date().isoformat()}"
|
|
266
336
|
|
|
267
|
-
if
|
|
268
|
-
|
|
337
|
+
if ns.commit_intake:
|
|
338
|
+
written = commit_intake(facts, Path(ns.intake_root))
|
|
339
|
+
files_touched = len({f["type"] for f in facts})
|
|
340
|
+
print(f"✅ Appended {written} intake lines across {files_touched} "
|
|
341
|
+
"files.\n Next: /memory promote to lift validated lines "
|
|
342
|
+
"into curated YAML.")
|
|
269
343
|
return 0
|
|
270
344
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
345
|
+
# Preview mode — render per --mode.
|
|
346
|
+
out: list[str] = []
|
|
347
|
+
if ns.mode in ("signals", "both"):
|
|
348
|
+
out.append(render_preview(facts, ns.project, window, kind))
|
|
349
|
+
if ns.mode in ("proposals", "both"):
|
|
350
|
+
out.append(render_proposal_seeds(facts, ns.project, window))
|
|
351
|
+
print("\n".join(out), end="")
|
|
275
352
|
return 0
|
|
276
353
|
|
|
277
354
|
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"reason": "no such skill — drop deferred to 6.1"
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
|
-
"pack": "
|
|
30
|
+
"pack": "memory",
|
|
31
31
|
"slug": "chat-history",
|
|
32
|
-
"reason": "command-routing target (commands/chat-history/*) listed under skills: — move to routes_to: in 6.1"
|
|
32
|
+
"reason": "command-routing target (commands/chat-history/*) listed under skills: — move to routes_to: in 6.1 (pack migrated meta→memory in ADR-091)"
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
"pack": "meta",
|