kenaz 0.3.22 → 0.3.23
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/core/.claude/hooks/_user-scope.js +1 -1
- package/core/.claude/hooks/core-resolve.js +1 -1
- package/core/.claude/hooks/worktree-create.js +6 -6
- package/core/.claude/hooks/worktree-remove.js +4 -4
- package/core/.collaboration/core/reconcile.js +16 -1
- package/core/.collaboration/core/task-2467-lifecycle.test.js +63 -0
- package/core/.collaboration/core/task-api.js +37 -7
- package/core/.formation/bifrost/launch.js +1 -1
- package/core/.formation/tools/kenaz-stats.js +1 -1
- package/core/.formation/tools/post-complete/git-merge.js +1 -1
- package/core/.formation/tools/prompt.js +1 -1
- package/core/.kenaz/specialist/ansuz_rules.yaml +7 -51
- package/core/.kenaz/specialist/ansuz_session_handoff.schema.json +2 -6
- package/core/.rule/general/project-self-containment.yaml +2 -2
- package/core/.specialist/Amelia/README.md +1 -1
- package/core/.specialist/Amelia/rule.yaml +1 -1
- package/core/.specialist/Ansuz/RULES.md +1 -1
- package/core/.specialist/Ansuz/concepts/commitment_layer.yaml +1 -1
- package/core/.specialist/Ansuz/concepts/evolvable_guardrails.yaml +1 -1
- package/core/.specialist/Ansuz/knowledge.yaml +1 -3
- package/core/.specialist/tools/__tests__/task-2409-lessons.test.js +10 -0
- package/core/.specialist/tools/__tests__/task-2427-harvest.test.js +25 -0
- package/core/.specialist/tools/ansuz-boot-fast.js +1 -1
- package/core/.specialist/tools/failure-detector.js +4 -4
- package/core/.specialist/tools/handoff-doc.js +1 -1
- package/core/.specialist/tools/lessons.js +2 -2
- package/core/CLAUDE.md +5 -5
- package/core/KENAZ_CORE_VERSION +1 -1
- package/core/dashboard/scripts/install-kenaz-cli.js +21 -6
- package/core/dev/scripts/check-file-size.js +1 -1
- package/core/dev/scripts/ci-feedback.js +1 -1
- package/core/dev/scripts/gc-agent-worktrees.js +11 -11
- package/core/dev/scripts/kenaz-session.js +3 -3
- package/core/dev/scripts/peer-identity-e2e.js +3 -3
- package/core/dev/scripts/run-rust-tests.js +2 -2
- package/core/dev/scripts/skill-routing-replay.js +3 -3
- package/core/dev/scripts/task1961/selftest.js +2 -2
- package/core/dev/scripts/windows-hide-guard.test.js +97 -0
- package/core/plugins/kenaz/guidance.md +1 -0
- package/core/plugins/kenaz/hooks/core-resolve.js +1 -1
- package/core/plugins/kenaz/hooks/kenaz-hook.js +52 -4
- package/core/plugins/kenaz/scripts/kenaz.test.js +72 -5
- package/lib/cli.js +9 -5
- package/package.json +6 -6
- package/vendor/install-kenaz-cli.js +21 -6
- package/core/.kenaz/designs/METAPLASTICITY_CONFIDENCE_DESIGN.md +0 -537
- package/core/.kenaz/designs/REFLEX_INITIATOR_DESIGN.md +0 -501
- package/core/.kenaz/designs/TASK_1385_handoff_mcp_design.md +0 -426
- package/core/.kenaz/designs/TASK_932_hippocampus_consolidation.md +0 -103
- package/core/.kenaz/designs/TASK_934_efe_signal_engine.md +0 -97
- package/core/.kenaz/designs/TASK_935_self_evolution_framework.md +0 -154
- package/core/.kenaz/designs/VISION_cognitive_architecture_roadmap.md +0 -159
- package/core/.kenaz/designs/metaplasticity_simulation_results.json +0 -696
- package/core/.kenaz/main-memory/README.md +0 -230
- package/core/.kenaz/main-memory/kenaz/cortex/001_cortex_overview.md +0 -168
- package/core/.kenaz/main-memory/kenaz/cortex/001_rag_engine_overview.md +0 -30
- package/core/.kenaz/main-memory/kenaz/memory-system/001_three_tier_architecture.md +0 -361
- package/core/.kenaz/main-memory/kenaz/pipeline/001_task_execution_flow.md +0 -117
- package/core/.kenaz/main-memory/kenaz/pipeline/001_task_granularity.md +0 -154
- package/core/.kenaz/main-memory/kenaz/pipeline/002_team_priority.md +0 -51
- package/core/.kenaz/main-memory/kenaz/pipeline/003_feature_id_system.md +0 -46
- package/core/.kenaz/main-memory/kenaz/rules/001_gen_007_self_containment.md +0 -108
- package/core/.kenaz/main-memory/kenaz/rules/001_rule_priority_system.md +0 -121
- package/core/.kenaz/main-memory/kenaz/rules/002_agt_006_pre_check.md +0 -0
- package/core/.kenaz/main-memory/kenaz/rules/003_ppl_002_task_archival.md +0 -48
- package/core/.kenaz/main-memory/kenaz/system/001_dual_track_task_system.md +0 -197
- package/core/.kenaz/main-memory/knowledge/patterns/001_json_bom_issue.md +0 -78
- package/core/.kenaz/main-memory/knowledge/patterns/001_leader_worker_pattern.md +0 -0
- package/core/.kenaz/main-memory/knowledge/patterns/002_scope_path_conflict.md +0 -115
- package/core/.kenaz/main-memory/knowledge/patterns/002_task_dependency_resolution.md +0 -223
- package/core/.kenaz/main-memory/knowledge/patterns/003_question_protocol.md +0 -242
- package/core/.kenaz/main-memory/knowledge/patterns/004_user_insight_value.md +0 -111
- package/core/.kenaz/main-memory/knowledge/patterns/005_file_lock_pattern.md +0 -274
- package/core/.kenaz/main-memory/knowledge/references/001_ppl_rules.md +0 -28
- package/core/.kenaz/main-memory/knowledge/solutions/001_json_bom_issue.md +0 -137
- package/core/.kenaz/main-memory/knowledge/solutions/001_team_invocation.md +0 -0
- package/core/.kenaz/main-memory/knowledge/solutions/002_passive_monitoring.md +0 -0
- package/core/.kenaz/main-memory/knowledge/solutions/003_windows_file_race_condition.md +0 -239
- package/core/.kenaz/main-memory/registry.json +0 -326
- package/core/.kenaz/main-memory/version.yaml +0 -58
- package/core/.kenaz/specialist/memory_guard_fired.json +0 -1
- package/core/.kenaz/specialist/memory_guard_trigger_cache.json +0 -1
- package/core/.kenaz/specialist/memory_source_priority.yaml +0 -260
- package/core/.kenaz/specialist/prompt_1775.txt +0 -317
- package/core/.kenaz/specialist/prompt_1776.txt +0 -326
- package/core/.kenaz/specialist/prompt_1791.txt +0 -320
- package/core/.kenaz/specialist/prompt_1792.txt +0 -320
- package/core/.kenaz/specialist/prompt_1795.txt +0 -281
- package/core/.kenaz/specialist/prompt_1813.txt +0 -332
- package/core/.kenaz/specialist/prompt_1814.txt +0 -401
- package/core/.kenaz/specialist/prompt_1815.txt +0 -394
- package/core/.kenaz/specialist/prompt_1816.txt +0 -437
- package/core/.kenaz/specialist/prompt_1818.txt +0 -361
- package/core/.kenaz/specialist/prompt_1819.txt +0 -421
- package/core/.kenaz/specialist/prompt_1821.txt +0 -345
- package/core/.kenaz/specialist/prompt_1822.txt +0 -313
- package/core/.kenaz/specialist/prompt_1824.txt +0 -348
- package/core/.kenaz/specialist/prompt_1826.txt +0 -388
- package/core/.kenaz/specialist/rune_efe_salience_gap.md +0 -21
- package/core/.kenaz/specialist/task1825_update.json +0 -43
- package/core/.kenaz/specialist/taskgen/consolidation_i.json +0 -38
- package/core/.kenaz/specialist/taskgen/csharp_a.json +0 -44
- package/core/.kenaz/specialist/taskgen/csharp_b.json +0 -40
- package/core/.kenaz/specialist/taskgen/embedding_e.json +0 -34
- package/core/.kenaz/specialist/taskgen/hygiene_fg.json +0 -39
- package/core/.kenaz/specialist/taskgen/pathology_h.json +0 -36
- package/core/.kenaz/specialist/taskgen/unity_noise_d.json +0 -38
- package/core/.kenaz/specialist/taskgen/visibility_c.json +0 -38
- package/core/.specialist/Ansuz/decisions/ADR-requirement-graph-layer.md +0 -390
- package/core/.specialist/Ansuz/self_model_seed.backup.json +0 -100
- package/core/.specialist/ansuz_session_handoff.json +0 -96
- package/core/dev/ALAYA_FIELD_FEEDBACK_DESIGN.md +0 -126
- package/core/dev/ANSUZ_SCAFFOLD_DIET_2026-09-20.md +0 -231
- package/core/dev/ANSUZ_STARTUP_INJECTION_REVIEW.md +0 -355
- package/core/dev/ANSUZ_WORKFLOW_MODERNIZATION.md +0 -143
- package/core/dev/CORTEX_META_GRAPH_ASSESSMENT.md +0 -99
- package/core/dev/FREYA_DOWNSTREAM_BUGS_2026-09-19.md +0 -44
- package/core/dev/GLOBAL_MEMORY_IDENTITY_CONSOLIDATION.md +0 -263
- package/core/dev/GUARD_EFFECTIVENESS_DESIGN.md +0 -180
- package/core/dev/HEALTH_GATE_VARIANCE_ASSESSMENT.md +0 -271
- package/core/dev/HOOK_DIET_2026-09-21.md +0 -126
- package/core/dev/JEV_INTEGRATION_PLAN.md +0 -189
- package/core/dev/KENAZ_AGENT_CONNECT_v1_SPEC.md +0 -139
- package/core/dev/MOBILE_DESIGN_SPEC.md +0 -569
- package/core/dev/MULTI_ANSUZ_SPEC.md +0 -136
- package/core/dev/MUNINN_RETIREMENT.md +0 -115
- package/core/dev/PHASE3_ATTRIBUTION_POPULATION_DIAGNOSIS.md +0 -211
- package/core/dev/PHASE3_P3-2B_TASKLEVEL_PROBE.md +0 -83
- package/core/dev/PHASE3_P3-2_POPULATION_DISJOINTNESS.md +0 -83
- package/core/dev/PHASE3_P3-2_REMEASURE_REPORT.md +0 -231
- package/core/dev/PREDICTION_GROUNDING_DESIGN.md +0 -376
- package/core/dev/PRODUCT_SPEC.md +0 -317
- package/core/dev/PROJECT_REGISTRY_DUPLICATE_ASSESSMENT.md +0 -86
- package/core/dev/STARTUP_TIMELINE_TASK_1995.md +0 -181
- package/core/dev/SYNAPSE_WORKER_PER_PROJECT.md +0 -881
- package/core/dev/TASK_1680_P3-3_DISPATCH_SPEC.md +0 -96
- package/core/dev/TASK_1684_CALIBRATION_IMPACT_ANALYSIS.md +0 -170
- package/core/dev/TASK_1684_FORK_A_GOODHART_DESIGN.md +0 -171
- package/core/dev/TASK_1684_P3_2_REMEASURE_VALIDATION.md +0 -262
- package/core/dev/TASK_1903_SIGNAL_AUC_MEASUREMENT.md +0 -207
- package/core/dev/TASK_1904_BRANCH_INTEGRITY_AUDIT.md +0 -146
- package/core/dev/ansuz-eval/README.md +0 -38
- package/core/dev/ansuz-eval/build-fixtures.js +0 -87
- package/core/dev/ansuz-eval/grade.js +0 -96
- package/core/dev/ansuz-eval/grader.test.js +0 -117
- package/core/dev/ansuz-eval/tasks.md +0 -32
- package/core/dev/archive/ansuz/BOOT_FULL.md +0 -141
- package/core/dev/archive/ansuz/agents/ansuz-boot.md +0 -176
- package/core/dev/archive/ansuz/designs/alaya-passive-surfacing.md +0 -84
- package/core/dev/archive/ansuz/designs/cc_memory_indexing.md +0 -307
- package/core/dev/archive/ansuz/designs/check_guard.md +0 -322
- package/core/dev/archive/ansuz/designs/consequence_loop.md +0 -227
- package/core/dev/archive/ansuz/designs/mcp_kuzudb_lock_architecture.md +0 -312
- package/core/dev/archive/ansuz/designs/phase0_git_enrichment.md +0 -278
- package/core/dev/archive/ansuz/designs/refactor_mcp_tools_synapse.md +0 -490
- package/core/dev/archive/ansuz/designs/semantic_markdown_extraction.md +0 -167
- package/core/dev/archive/ansuz/designs/task_1372_prompt_injects_into.md +0 -193
- package/core/dev/archive/ansuz/designs/thought_stack.md +0 -286
- package/core/dev/archive/ansuz/investigations/reachability_unified_api_2026-04-11.md +0 -330
- package/core/dev/archive/ansuz/investigations/synapse_orphans_indexing_bug_2026-04-11.md +0 -352
- package/core/dev/archive/ansuz/investigations/synapse_orphans_reindex_verification_2026-04-11.md +0 -48
- package/core/dev/archive/ansuz/investigations/synapse_orphans_verification_2026-04-11.md +0 -170
- package/core/dev/archive/ansuz/legacy/kernel.yaml +0 -399
- package/core/dev/archive/ansuz/legacy/phases/phase_0.yaml +0 -418
- package/core/dev/archive/ansuz/legacy/phases/phase_1.yaml +0 -376
- package/core/dev/archive/ansuz/legacy/phases/phase_10.yaml +0 -35
- package/core/dev/archive/ansuz/legacy/phases/phase_11.yaml +0 -582
- package/core/dev/archive/ansuz/legacy/phases/phase_2.yaml +0 -94
- package/core/dev/archive/ansuz/legacy/phases/phase_3.yaml +0 -274
- package/core/dev/archive/ansuz/legacy/phases/phase_4.yaml +0 -67
- package/core/dev/archive/ansuz/legacy/phases/phase_5.yaml +0 -32
- package/core/dev/archive/ansuz/legacy/phases/phase_6.yaml +0 -91
- package/core/dev/archive/ansuz/legacy/phases/phase_7.yaml +0 -58
- package/core/dev/archive/ansuz/legacy/phases/phase_8.yaml +0 -146
- package/core/dev/archive/ansuz/legacy/phases/phase_9.yaml +0 -424
- package/core/dev/archive/ansuz/specs/INDEX_bifrost_hook_parity.yaml +0 -92
- package/core/dev/archive/ansuz/specs/active-inference-formation.yaml +0 -453
- package/core/dev/archive/ansuz/specs/brief_TASK_1228_userpromptsubmit.yaml +0 -191
- package/core/dev/archive/ansuz/specs/brief_TASK_1229_pretooluse_posttooluse.yaml +0 -250
- package/core/dev/archive/ansuz/specs/brief_TASK_1230_sessionstart_stop.yaml +0 -301
- package/core/dev/archive/ansuz/specs/brief_TASK_1231_verification.yaml +0 -272
- package/core/dev/archive/skills/feature_agent/SKILL.md +0 -289
- package/core/dev/design/PHASE4_DESIGN.md +0 -559
- package/core/dev/design/dashboard_docs_integration_PLAN.md +0 -388
- package/core/dev/design/matrix_format_ABBREVIATIONS.md +0 -655
- package/core/dev/design/matrix_format_DESIGN_SPEC.md +0 -601
- package/core/dev/design/matrix_format_DISCUSSION_SUMMARY.md +0 -484
- package/core/dev/design/matrix_format_EXAMPLE_memory.matrix +0 -13
- package/core/dev/design/matrix_format_EXAMPLE_project_status.matrix +0 -9
- package/core/dev/design/matrix_format_EXAMPLE_tasks.matrix +0 -14
- package/core/dev/design/matrix_format_SYNTAX_BNF.md +0 -754
- package/core/dev/design/matrix_format_TOKEN_COMPARISON.md +0 -484
- package/core/dev/design/matrix_v2_COGNITIVE_DESIGN.md +0 -503
- package/core/dev/design/matrix_v2_DISCUSSION_SUMMARY.md +0 -414
- package/core/dev/design/matrix_v2_EXAMPLE.matrix +0 -67
- package/core/dev/designs/EXPANDABLE_CARD_DESIGN_SPEC.md +0 -509
- package/core/dev/jev-eval/ACTIVE_CORRECTION.md +0 -52
- package/core/dev/jev-eval/ANNOTATION_GUIDE.md +0 -68
- package/core/dev/jev-eval/BASELINE_COMPARISON.md +0 -45
- package/core/dev/jev-eval/CONTEXT_REVIEW.md +0 -31
- package/core/dev/jev-eval/EVALUATION_STATUS.md +0 -39
- package/core/dev/jev-eval/HISTORICAL_CORPUS.md +0 -33
- package/core/dev/jev-eval/PACKAGING_VERIFICATION.md +0 -42
- package/core/dev/jev-eval/README.md +0 -101
- package/core/dev/jev-eval/THALAMUS_RANKING.md +0 -58
- package/core/dev/jev-eval/VALIDATION_PROGRESS.md +0 -54
- package/core/dev/jev-eval/cli.mjs +0 -50
- package/core/dev/jev-eval/context.mjs +0 -183
- package/core/dev/jev-eval/corpus.mjs +0 -186
- package/core/dev/jev-eval/fixtures/conversation-review.seed.jsonl +0 -6
- package/core/dev/jev-eval/fixtures/synthetic.jsonl +0 -11
- package/core/dev/jev-eval/metrics.mjs +0 -67
- package/core/dev/jev-eval/muninn-baseline.mjs +0 -119
- package/core/dev/jev-eval/providers.mjs +0 -95
- package/core/dev/jev-eval/reports/annotation-pilot-2026-09-20.json +0 -32
- package/core/dev/jev-eval/reports/context-review-2026-09-20.json +0 -48
- package/core/dev/jev-eval/reports/conversation-review.pending.json +0 -151
- package/core/dev/jev-eval/reports/history-corpus-2026-09-20.json +0 -52
- package/core/dev/jev-eval/reports/length-probe-2026-09-20.json +0 -133
- package/core/dev/jev-eval/reports/live-smoke-2026-09-20.json +0 -616
- package/core/dev/jev-eval/reports/muninn-baseline-2026-09-20.json +0 -52
- package/core/dev/jev-eval/reports/resilience-2026-09-20.json +0 -520
- package/core/dev/jev-eval/reports/rules-baseline.json +0 -197
- package/core/dev/jev-eval/reports/synthetic-review.pending.json +0 -357
- package/core/dev/jev-eval/resilience.mjs +0 -71
- package/core/dev/jev-eval/review.mjs +0 -78
- package/core/dev/jev-eval/schema.mjs +0 -87
- package/core/dev/jev-eval/test/context.test.mjs +0 -95
- package/core/dev/jev-eval/test/corpus.test.mjs +0 -102
- package/core/dev/jev-eval/test/eval.test.mjs +0 -146
- package/core/dev/jev-eval/test/muninn-baseline.test.mjs +0 -71
- package/core/dev/jev-eval/test/resilience.test.mjs +0 -72
- package/core/dev/jev-eval/test/review.test.mjs +0 -61
- package/core/dev/pipeline/PHASE3_PLANNING_SUMMARY.md +0 -338
- package/core/dev/pipeline/PROGRESS.md +0 -113
- package/core/dev/pipeline/PROGRESS_template.md +0 -860
- package/core/dev/pipeline/QA_REPORT_F008.md +0 -431
- package/core/dev/pipeline/QA_REPORT_LOCAL_CLAUDE_DIAGNOSIS.md +0 -583
- package/core/dev/pipeline/README.md +0 -210
- package/core/dev/pipeline/WORKFLOW_GUIDE.md +0 -824
- package/core/dev/pipeline/archived/TASK_015_tauri_init.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_016_tauri_commands.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_017_rust_pty.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_018_tauri_bundle.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_019_release_workflow.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_020_update_ui.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_021_update_notification_ui.yaml +0 -55
- package/core/dev/pipeline/archived/TASK_022_remove_node_pty.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_023_api_routes_migration.yaml +0 -86
- package/core/dev/pipeline/archived/TASK_024_feature_id_system.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_025_executable_acceptance.yaml +0 -66
- package/core/dev/pipeline/archived/TASK_026_spec_versioning.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_027_drift_detection.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_028_tauri_pty_manager.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_029_tauri_pty_commands.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_030_frontend_session_adapter.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_031_terminal_tauri_events.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_041_scheduler_data_models.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_042_path_lock_manager.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_043_process_manager.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_044_git_integration.yaml +0 -85
- package/core/dev/pipeline/archived/TASK_045_task_queue_manager.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_046_scheduler_dispatcher.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_047_tauri_scheduler_commands.yaml +0 -55
- package/core/dev/pipeline/archived/TASK_048_realtime_status_push.yaml +0 -92
- package/core/dev/pipeline/archived/TASK_049_frontend_scheduler_integration.yaml +0 -58
- package/core/dev/pipeline/archived/TASK_050_error_recovery.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_051_optimization_proposals_backend.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_052_optimization_proposals_ui.yaml +0 -58
- package/core/dev/pipeline/archived/TASK_053_optimization_proposals_diff_view.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_054_multi_project_scheduler_state.yaml +0 -76
- package/core/dev/pipeline/archived/TASK_055_scheduler_api_project_scope.yaml +0 -64
- package/core/dev/pipeline/archived/TASK_056_frontend_scheduler_project_scope.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_057_scheduler_module_structure.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_058_scheduler_models_extract.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_059_scheduler_core_extract.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_060_scheduler_commands_extract.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_061_scheduler_specialized_commands.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_062_process_manager_module_structure.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_063_process_manager_core_extract.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_064_recovery_module_structure.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_065_recovery_core_extract.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_066_self_enhancement_scheduler_models.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_067_agents_section_quick_actions.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_067_self_enhancement_scheduler_core.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_068_agent_workflow_rule_enhancement.yaml +0 -46
- package/core/dev/pipeline/archived/TASK_068_self_enhancement_tauri_commands.yaml +0 -61
- package/core/dev/pipeline/archived/TASK_069_agent_wizard_responsive.yaml +0 -46
- package/core/dev/pipeline/archived/TASK_069_self_enhancement_ui.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_070_preview_panel_redesign.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_070_self_enhancement_integration.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_071_preview_panel_qa.yaml +0 -98
- package/core/dev/pipeline/archived/TASK_071_single_agent_config.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_072_preview_modal_esc_fix.yaml +0 -71
- package/core/dev/pipeline/archived/TASK_072_product_review_module.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_073_agents_page_component_refactor.yaml +0 -68
- package/core/dev/pipeline/archived/TASK_073_rename_single_agent.yaml +0 -64
- package/core/dev/pipeline/archived/TASK_074_preview_mode_ui_diagnosis.yaml +0 -71
- package/core/dev/pipeline/archived/TASK_074_single_agent_ui_toggle.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_075_agents_page_component_refactor.yaml +0 -69
- package/core/dev/pipeline/archived/TASK_075_single_agent_integration_test.yaml +0 -75
- package/core/dev/pipeline/archived/TASK_076_preview_mode_ui_diagnosis.yaml +0 -70
- package/core/dev/pipeline/archived/TASK_076_single_agent_continuous_mode.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_077_failure_directory_structure.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_077_single_agent_typescript_types.yaml +0 -59
- package/core/dev/pipeline/archived/TASK_078_fail_001_agent_no_output.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_078_single_agent_ui_simplify.yaml +0 -74
- package/core/dev/pipeline/archived/TASK_079_dashboard_rwd_responsive.yaml +0 -63
- package/core/dev/pipeline/archived/TASK_079_fail_002_json_bom.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_080_fail_003_queue_pollution.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_080_http_server_module.yaml +0 -55
- package/core/dev/pipeline/archived/TASK_081_failure_logging_tools.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_081_http_api_routes.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_082_frontend_api_adapter.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_082_integrate_failure_to_workflow.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_083_cleanup_nextjs_api.yaml +0 -48
- package/core/dev/pipeline/archived/TASK_083_task_queue_cleanup.yaml +0 -67
- package/core/dev/pipeline/archived/TASK_084_rust_dead_code_cleanup.yaml +0 -66
- package/core/dev/pipeline/archived/TASK_084_scheduler_sync_logic_fix.yaml +0 -68
- package/core/dev/pipeline/archived/TASK_085_http_api_web_mode_fixes.yaml +0 -46
- package/core/dev/pipeline/archived/TASK_085_memory_consolidation_0204_0205.yaml +0 -98
- package/core/dev/pipeline/archived/TASK_086_collapsible_preview_panel.yaml +0 -161
- package/core/dev/pipeline/archived/TASK_086_web_mode_feature_parity.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_087_manual_memory_archival.yaml +0 -163
- package/core/dev/pipeline/archived/TASK_087_mobile_http_control.yaml +0 -68
- package/core/dev/pipeline/archived/TASK_088_fail_003_to_ppl_002_rule.yaml +0 -63
- package/core/dev/pipeline/archived/TASK_088_mobile_http_qa.yaml +0 -121
- package/core/dev/pipeline/archived/TASK_089_agent_collaboration_topic.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_089_web_mode_monitor_fix.yaml +0 -58
- package/core/dev/pipeline/archived/TASK_090_cli_detection_fix.yaml +0 -61
- package/core/dev/pipeline/archived/TASK_090_ui_ux_lessons_topic.yaml +0 -63
- package/core/dev/pipeline/archived/TASK_091_expandable_card_design.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_091_move_agent_section_components.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_092_expandable_card_component.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_092_refactor_agent_create_wizard.yaml +0 -84
- package/core/dev/pipeline/archived/TASK_093_taskcard_detail_integration.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_093_update_barrel_exports_test.yaml +0 -84
- package/core/dev/pipeline/archived/TASK_094_ai_agent_generation_enhancement.yaml +0 -115
- package/core/dev/pipeline/archived/TASK_094_proposalcard_detail_integration.yaml +0 -55
- package/core/dev/pipeline/archived/TASK_095_preview_fixes.yaml +0 -129
- package/core/dev/pipeline/archived/TASK_095_single_agent_task_selector.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_096_agents_page_ux_improvements.yaml +0 -163
- package/core/dev/pipeline/archived/TASK_096_single_agent_status_sync.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_097_local_claude_error_logging.yaml +0 -59
- package/core/dev/pipeline/archived/TASK_097_single_agent_monitor_events.yaml +0 -59
- package/core/dev/pipeline/archived/TASK_098_product_manager_team_phase2.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_098_single_agent_refactor_test.yaml +0 -58
- package/core/dev/pipeline/archived/TASK_099_backend_team_creation.yaml +0 -258
- package/core/dev/pipeline/archived/TASK_100_frontend_team_creation.yaml +0 -61
- package/core/dev/pipeline/archived/TASK_101_orchestrator_system.yaml +0 -403
- package/core/dev/pipeline/archived/TASK_102_designer_sre_teams.yaml +0 -90
- package/core/dev/pipeline/archived/TASK_103_integration_testing.yaml +0 -86
- package/core/dev/pipeline/archived/TASK_128_integration_testing.yaml +0 -83
- package/core/dev/pipeline/archived/TASK_134_cortex_v2_phase3_file_watcher.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_134_team_http_api.yaml +0 -96
- package/core/dev/pipeline/archived/TASK_135_cortex_v2_phase3_git_monitor.yaml +0 -63
- package/core/dev/pipeline/archived/TASK_136_cortex_v2_phase3_change_analyzer.yaml +0 -69
- package/core/dev/pipeline/archived/TASK_137_cortex_v2_phase3_cache_invalidator.yaml +0 -67
- package/core/dev/pipeline/archived/TASK_137_team_orchestrator_integration.yaml +0 -93
- package/core/dev/pipeline/archived/TASK_138_cortex_v2_phase3_distributed_cache.yaml +0 -68
- package/core/dev/pipeline/archived/TASK_138_matrix_folder_structure.yaml +0 -61
- package/core/dev/pipeline/archived/TASK_139_cortex_v2_phase3_cache_prewarming.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_146_unified_documentation.yaml +0 -141
- package/core/dev/pipeline/archived/TASK_147_pipeline_execution_rules.yaml +0 -76
- package/core/dev/pipeline/archived/TASK_148_update_claude_md.yaml +0 -77
- package/core/dev/pipeline/archived/TASK_149_fix_nextjs_mdx_serialization.yaml +0 -63
- package/core/dev/pipeline/archived/TASK_149_update_team_docs.yaml +0 -77
- package/core/dev/pipeline/archived/TASK_150_pipeline_workflow_guide.yaml +0 -82
- package/core/dev/pipeline/archived/TASK_164_fix_smart_context_switch.yaml +0 -49
- package/core/dev/pipeline/archived/TASK_165_ctags_symbol_index.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_166_symbol_search_mcp_tool.yaml +0 -48
- package/core/dev/pipeline/archived/TASK_167_llm_module_summary.yaml +0 -55
- package/core/dev/pipeline/archived/TASK_168_map_reduce_context.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_169_v2_integration_testing.yaml +0 -52
- package/core/dev/pipeline/backups/archive_2026-02-04T22-07-22/TASK_QUEUE_backup.json +0 -95
- package/core/dev/pipeline/docs/multi-agent-coordination.md +0 -446
- package/core/dev/pipeline/docs/overview.md +0 -406
- package/core/dev/pipeline/docs/task-management.md +0 -412
- package/core/dev/pipeline/docs/workflows.md +0 -32
- package/core/dev/pipeline/orchestrator/schemas/task_queue_schema.json +0 -58
- package/core/dev/pipeline/orchestrator/schemas/task_schema.json +0 -139
- package/core/dev/pipeline/plans/PLAN_task_cli_refactor.md +0 -281
- package/core/dev/pipeline/test_results/TASK_TEST_PARALLEL_002_result.txt +0 -27
- package/core/dev/plans/ANSUZ_SLIM_PLAN.md +0 -68
- package/core/dev/plans/CLI_FIRST_INSTALL_FLOW.md +0 -120
- package/core/dev/plans/FORMATION_RETIREMENT_PLAN.md +0 -313
- package/core/dev/plans/KUZU_REPLACEMENT_PLAN.md +0 -126
- package/core/dev/scripts/CRASH_DIAGNOSIS.md +0 -47
- package/core/dev/scripts/README.md +0 -142
- package/core/dev/scripts/RUN_ONCE.bat +0 -40
- package/core/dev/scripts/START_DEV_AGENT.bat +0 -63
- package/core/dev/scripts/START_MULTI_AGENT.bat +0 -80
- package/core/dev/scripts/dev_agent_scheduler.ps1 +0 -536
- package/core/dev/scripts/init_git.ps1 +0 -396
- package/core/dev/scripts/init_git.sh +0 -337
- package/core/dev/scripts/init_project.ps1 +0 -851
- package/core/dev/scripts/init_project.sh +0 -477
- package/core/dev/scripts/multi_agent_scheduler.ps1 +0 -2021
- package/core/dev/scripts/multi_agent_scheduler.sh +0 -1344
- package/core/dev/scripts/run_once.sh +0 -47
- package/core/dev/scripts/setup_rag.ps1 +0 -304
- package/core/dev/scripts/setup_rag.sh +0 -230
- package/core/dev/scripts/start_dev_agent.sh +0 -137
- package/core/dev/scripts/start_multi_agent.sh +0 -41
- package/core/dev/scripts/sync_task_queue.ps1 +0 -505
- package/core/dev/scripts/sync_task_queue.sh +0 -392
- package/core/dev/specs/agent-connect/PROTOCOL.md +0 -177
- package/core/dev/specs/agent-connect/SDK_GUIDE.md +0 -915
- package/core/dev/specs/agent-connect/examples/minimal-site/README.md +0 -137
- package/core/dev/specs/agent-connect/examples/minimal-site/package.json +0 -12
- package/core/dev/specs/agent-connect/examples/minimal-site/public/index.html +0 -116
- package/core/dev/specs/agent-connect/examples/minimal-site/public/install-redirect.js +0 -73
- package/core/dev/specs/agent-connect/examples/minimal-site/server.js +0 -516
- package/core/dev/specs/agent-connect/examples/minimal-site/test/smoke.test.mjs +0 -263
- package/core/dev/specs/agent-connect/history/DEFECT_REPORT_kenaz-agent-hub_2026-09-09_v0.4-empty-prompt-no-first-turn.md +0 -77
- package/core/dev/specs/agent-connect/history/DEFECT_REPORT_kenaz-agent-hub_2026-09-09_v0.4-prompt-mojibake.md +0 -90
- package/core/dev/specs/agent-connect/history/FEATURE_REQUEST_kenaz-agent-hub_2026-09-07.md +0 -61
- package/core/dev/specs/agent-connect/history/FEATURE_REQUEST_kenaz-agent-hub_2026-09-08_relay-v1-conformance.md +0 -76
- package/core/dev/specs/agent-connect/history/FEATURE_REQUEST_kenaz-agent-hub_2026-09-09_v0.4-session-channel.md +0 -87
- package/core/dev/specs/agent-connect/history/FLOWPIX_REPLY_agent-hub_2026-09-08_relay-v1-answers.md +0 -68
- package/core/dev/specs/agent-connect/history/FLOWPIX_bridge_CONTRACT.md +0 -642
- package/core/dev/specs/agent-connect/history/FLOWPIX_spikes_relay_spike_relay.mjs +0 -244
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-07.md +0 -77
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-08_direction-change-v0.3.md +0 -44
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-08_relay-v1-answers-ack.md +0 -37
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-08_relay-v1-conformance.md +0 -56
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_annotations-install-coldstart.md +0 -44
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_empty-prompt-first-turn.md +0 -56
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_prompt-mojibake-fixed.md +0 -48
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_session-channel.md +0 -57
- package/core/dev/specs/agent-connect/history/PROTOCOL_v0.3_snapshot.md +0 -379
- package/core/dev/specs/agent-connect/history/README.md +0 -47
- package/core/dev/specs/peer/CODEX_INTERACTIVE_PUSH.md +0 -65
- package/core/dev/specs/peer/CODEX_MANAGED_DAEMON.md +0 -54
- package/core/dev/specs/peer/CODEX_PEER_PULL_SPIKE.md +0 -54
- package/core/dev/specs/peer/MODS_SPIKE.md +0 -133
- package/core/dev/specs/peer/PER_PROJECT_ADDRESSING.md +0 -143
- package/core/dev/specs/peer/SWARM_PROTOCOLS.md +0 -256
- package/core/dev/specs/peer/codex-hook-shim-peer.test.js +0 -113
- package/core/dev/specs/peer/codex-push-launcher.test.js +0 -142
- package/core/dev/specs/peer/setup-codex-hooks.test.js +0 -60
- package/core/dev/specs/peer-ansuz/DELIVERY_SPIKE.md +0 -397
- package/core/dev/specs/peer-ansuz/DESIGN.md +0 -109
- package/core/dev/specs/peer-ansuz/spike/claude_poke.js +0 -129
- package/core/dev/specs/peer-ansuz/spike/claude_session_start_hook.js +0 -37
- package/core/dev/specs/peer-ansuz/spike/claude_settings_hook.json +0 -14
- package/core/dev/specs/peer-ansuz/spike/codex_appserver_client.js +0 -105
- package/core/dev/specs/peer-ansuz/spike/codex_appserver_query.js +0 -29
- package/core/dev/specs/peer-ansuz/spike/extract_timeline.js +0 -26
- package/core/dev/specs/synapse/SYMBOL_IDENTITY.md +0 -305
- package/core/dev/spikes/A4-cypher-varlen.md +0 -176
- package/core/dev/spikes/bloat-rounds.sh +0 -25
- package/core/dev/spikes/mods/clean-claude.js +0 -9
- package/core/dev/spikes/mods/drive-probe.js +0 -29
- package/core/dev/spikes/mods/e2e-peer.js +0 -71
- package/core/dev/spikes/mods/evidence/e2e-peer-control.json +0 -17
- package/core/dev/spikes/mods/evidence/e2e-peer-mod.json +0 -17
- package/core/dev/spikes/mods/evidence/probe-006a6e65-d807-4bc1-b648-fd7d1edfe0b4.jsonl +0 -4
- package/core/dev/spikes/mods/evidence/probe-cebdf1f7-f9c4-47a8-83cd-7c0786177404.jsonl +0 -12
- package/core/dev/spikes/mods/evidence/probe-eb21147d-10ce-4c32-93ed-37ca37d88d5a.jsonl +0 -11
- package/core/dev/spikes/mods/evidence/stream-cebdf1f7.jsonl +0 -18
- package/core/dev/spikes/mods/kenaz-mod-probe/.claude-plugin/plugin.json +0 -1
- package/core/dev/spikes/mods/kenaz-mod-probe/hooks/hooks.json +0 -1
- package/core/dev/spikes/mods/kenaz-mod-probe/hooks/register.ts +0 -65
- package/core/dev/spikes/mods/kenaz-mod-probe/tsconfig.json +0 -3
|
@@ -1,392 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# ============================================================
|
|
3
|
-
# Sync Task Queue (macOS/Linux version)
|
|
4
|
-
# ============================================================
|
|
5
|
-
# Read YAML/Markdown task files and sync to TASK_QUEUE.json
|
|
6
|
-
# Equivalent of sync_task_queue.ps1
|
|
7
|
-
# ============================================================
|
|
8
|
-
|
|
9
|
-
set -euo pipefail
|
|
10
|
-
|
|
11
|
-
# --- Parameters ---
|
|
12
|
-
WORKING_DIRECTORY=""
|
|
13
|
-
FORCE=false
|
|
14
|
-
QUIET=false
|
|
15
|
-
|
|
16
|
-
while [[ $# -gt 0 ]]; do
|
|
17
|
-
case "$1" in
|
|
18
|
-
--working-directory|--wd) WORKING_DIRECTORY="$2"; shift 2 ;;
|
|
19
|
-
--force) FORCE=true; shift ;;
|
|
20
|
-
--quiet) QUIET=true; shift ;;
|
|
21
|
-
--nopause) QUIET=true; shift ;;
|
|
22
|
-
*) shift ;;
|
|
23
|
-
esac
|
|
24
|
-
done
|
|
25
|
-
|
|
26
|
-
# Use KENAZ_PROJECT_PATH env var if WorkingDirectory not specified
|
|
27
|
-
if [[ -z "$WORKING_DIRECTORY" ]]; then
|
|
28
|
-
if [[ -n "${KENAZ_PROJECT_PATH:-}" ]]; then
|
|
29
|
-
WORKING_DIRECTORY="$KENAZ_PROJECT_PATH"
|
|
30
|
-
else
|
|
31
|
-
WORKING_DIRECTORY="$(pwd)"
|
|
32
|
-
fi
|
|
33
|
-
fi
|
|
34
|
-
|
|
35
|
-
TASKS_DIR="$WORKING_DIRECTORY/dev/pipeline/tasks"
|
|
36
|
-
COMPLETED_DIR="$WORKING_DIRECTORY/dev/pipeline/completed"
|
|
37
|
-
QUEUE_FILE="$WORKING_DIRECTORY/dev/pipeline/TASK_QUEUE.json"
|
|
38
|
-
|
|
39
|
-
# --- Logging ---
|
|
40
|
-
info() { [[ "$QUIET" == "true" ]] || echo " $1"; }
|
|
41
|
-
success() { [[ "$QUIET" == "true" ]] || echo " OK $1"; }
|
|
42
|
-
warn() { echo " [WARN] $1" >&2; }
|
|
43
|
-
|
|
44
|
-
# --- JSON helper via python3 ---
|
|
45
|
-
# We use python3 for all JSON operations since jq may not be installed
|
|
46
|
-
py_json() {
|
|
47
|
-
python3 -c "$1"
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
# --- Parse a YAML task file (simple regex-based) ---
|
|
51
|
-
parse_yaml_task() {
|
|
52
|
-
local filepath="$1"
|
|
53
|
-
local filename
|
|
54
|
-
filename=$(basename "$filepath")
|
|
55
|
-
|
|
56
|
-
python3 << 'PYEOF' "$filepath" "$filename"
|
|
57
|
-
import sys, re, json, os
|
|
58
|
-
from datetime import datetime
|
|
59
|
-
|
|
60
|
-
filepath = sys.argv[1]
|
|
61
|
-
filename = sys.argv[2]
|
|
62
|
-
|
|
63
|
-
with open(filepath, 'r', encoding='utf-8') as f:
|
|
64
|
-
content = f.read()
|
|
65
|
-
|
|
66
|
-
# Extract task ID from filename
|
|
67
|
-
m = re.match(r'^(TASK_\d+)', filename)
|
|
68
|
-
if not m:
|
|
69
|
-
sys.exit(1)
|
|
70
|
-
task_id = m.group(1)
|
|
71
|
-
|
|
72
|
-
# Parse YAML fields
|
|
73
|
-
def extract(pattern, default=''):
|
|
74
|
-
m = re.search(pattern, content, re.MULTILINE)
|
|
75
|
-
return m.group(1).strip().strip('"') if m else default
|
|
76
|
-
|
|
77
|
-
title = extract(r'^title:\s*"?([^"\r\n]+)"?')
|
|
78
|
-
priority = extract(r'^priority:\s*"?(P[0-3])"?', 'P2')
|
|
79
|
-
status = extract(r'^status:\s*"?([^"\r\n]+)"?', 'pending')
|
|
80
|
-
agent_type = extract(r'^agent_type:\s*"?([^"\r\n]+)"?', 'dev')
|
|
81
|
-
created_at = extract(r'^\s*created_at:\s*"?([^"\r\n]+)"?', datetime.now().isoformat())
|
|
82
|
-
est_hours = extract(r'^estimated_hours:\s*(\d+\.?\d*)', '')
|
|
83
|
-
|
|
84
|
-
# Description - handle multiline with | or single line
|
|
85
|
-
description = ''
|
|
86
|
-
m = re.search(r'^description:\s*\|?\s*\n((?:[ \t]+[^\n]*\n?)+)', content, re.MULTILINE)
|
|
87
|
-
if m:
|
|
88
|
-
description = re.sub(r'(?m)^[ \t]+', '', m.group(1)).replace('\n', ' ').strip()
|
|
89
|
-
if len(description) > 200:
|
|
90
|
-
description = description[:197] + '...'
|
|
91
|
-
else:
|
|
92
|
-
description = extract(r'^description:\s*"?([^"\r\n]+)"?')
|
|
93
|
-
|
|
94
|
-
# Parse dependencies array
|
|
95
|
-
dependencies = []
|
|
96
|
-
m = re.search(r'^dependencies:\s*\n((?:[ \t]*-[^\n]*\n?)+)', content, re.MULTILINE)
|
|
97
|
-
if m:
|
|
98
|
-
dependencies = re.findall(r'-\s*"?(TASK_\d+)"?', m.group(1))
|
|
99
|
-
|
|
100
|
-
# Parse scope_paths array
|
|
101
|
-
scope_paths = []
|
|
102
|
-
m = re.search(r'^scope_paths:\s*\n((?:[ \t]*-[^\n]*\n?)+)', content, re.MULTILINE)
|
|
103
|
-
if m:
|
|
104
|
-
scope_paths = [p.strip().strip('"') for p in re.findall(r'-\s*"?([^"\n]+)"?', m.group(1))]
|
|
105
|
-
|
|
106
|
-
if not scope_paths:
|
|
107
|
-
scope_paths = ['src/']
|
|
108
|
-
|
|
109
|
-
# Skill path mapping
|
|
110
|
-
skill_map = {
|
|
111
|
-
'developer': '.claude/skills/developer/SKILL.md',
|
|
112
|
-
'backend': '.claude/skills/backend_engineer/SKILL.md',
|
|
113
|
-
'designer': '.claude/skills/designer/SKILL.md',
|
|
114
|
-
'qa': '.claude/skills/qa_engineer/SKILL.md',
|
|
115
|
-
'sre': '.claude/skills/sre_agent/SKILL.md',
|
|
116
|
-
'dev': '.claude/skills/dev_agent/SKILL.md',
|
|
117
|
-
'frontend': '.claude/skills/frontend_agent/SKILL.md',
|
|
118
|
-
'architect': '.claude/skills/architect_agent/SKILL.md',
|
|
119
|
-
}
|
|
120
|
-
skill_path = skill_map.get(agent_type, '.claude/skills/dev_agent/SKILL.md')
|
|
121
|
-
|
|
122
|
-
task = {
|
|
123
|
-
'id': task_id,
|
|
124
|
-
'title': title,
|
|
125
|
-
'description': description,
|
|
126
|
-
'priority': priority,
|
|
127
|
-
'status': status,
|
|
128
|
-
'scope_paths': scope_paths,
|
|
129
|
-
'dependencies': dependencies,
|
|
130
|
-
'source_file': filename,
|
|
131
|
-
'created_at': created_at,
|
|
132
|
-
'agent_type': agent_type,
|
|
133
|
-
'skill_path': skill_path,
|
|
134
|
-
}
|
|
135
|
-
if est_hours:
|
|
136
|
-
task['estimated_hours'] = float(est_hours)
|
|
137
|
-
|
|
138
|
-
print(json.dumps(task))
|
|
139
|
-
PYEOF
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
# --- Parse a Markdown task file ---
|
|
143
|
-
parse_md_task() {
|
|
144
|
-
local filepath="$1"
|
|
145
|
-
local filename
|
|
146
|
-
filename=$(basename "$filepath")
|
|
147
|
-
|
|
148
|
-
python3 << 'PYEOF' "$filepath" "$filename"
|
|
149
|
-
import sys, re, json
|
|
150
|
-
from datetime import datetime
|
|
151
|
-
|
|
152
|
-
filepath = sys.argv[1]
|
|
153
|
-
filename = sys.argv[2]
|
|
154
|
-
|
|
155
|
-
with open(filepath, 'r', encoding='utf-8') as f:
|
|
156
|
-
content = f.read()
|
|
157
|
-
|
|
158
|
-
# Extract task ID
|
|
159
|
-
m = re.match(r'^(TASK_\d+)', filename)
|
|
160
|
-
if not m:
|
|
161
|
-
sys.exit(1)
|
|
162
|
-
task_id = m.group(1)
|
|
163
|
-
|
|
164
|
-
# Title from first heading
|
|
165
|
-
title = ''
|
|
166
|
-
m = re.search(r'^#\s+(.+?)(?:\n|$)', content, re.MULTILINE)
|
|
167
|
-
if m:
|
|
168
|
-
title = re.sub(rf'^{re.escape(task_id)}:\s*', '', m.group(1)).strip()
|
|
169
|
-
|
|
170
|
-
# Priority
|
|
171
|
-
priority = 'P2'
|
|
172
|
-
m = re.search(r'\b(P[0-3])\b', content)
|
|
173
|
-
if m:
|
|
174
|
-
priority = m.group(1)
|
|
175
|
-
|
|
176
|
-
# Scope paths
|
|
177
|
-
scope_paths = []
|
|
178
|
-
for kw in ['dashboard/', 'src/', 'app/', 'components/', 'api/', 'tests/']:
|
|
179
|
-
if kw in content:
|
|
180
|
-
scope_paths.append(kw)
|
|
181
|
-
if not scope_paths:
|
|
182
|
-
scope_paths = ['src/']
|
|
183
|
-
scope_paths = list(set(scope_paths))
|
|
184
|
-
|
|
185
|
-
# Dependencies
|
|
186
|
-
task_num = int(re.search(r'\d+', task_id).group())
|
|
187
|
-
deps = []
|
|
188
|
-
for m in re.finditer(r'TASK_(\d+)', content):
|
|
189
|
-
dep_id = f'TASK_{m.group(1)}'
|
|
190
|
-
dep_num = int(m.group(1))
|
|
191
|
-
if dep_id != task_id and dep_num < task_num and dep_id not in deps:
|
|
192
|
-
deps.append(dep_id)
|
|
193
|
-
|
|
194
|
-
# Infer agent type
|
|
195
|
-
title_lower = title.lower()
|
|
196
|
-
agent_type = 'dev'
|
|
197
|
-
for kw in ['ui', 'ux', 'layout', 'style', 'design', 'css', 'theme', 'color']:
|
|
198
|
-
if kw in title_lower:
|
|
199
|
-
agent_type = 'designer'; break
|
|
200
|
-
else:
|
|
201
|
-
for kw in ['api', 'database', 'backend', 'endpoint', 'server', 'sql', 'migration']:
|
|
202
|
-
if kw in title_lower:
|
|
203
|
-
agent_type = 'backend'; break
|
|
204
|
-
else:
|
|
205
|
-
for kw in ['test', 'qa', 'quality', 'e2e', 'spec']:
|
|
206
|
-
if kw in title_lower:
|
|
207
|
-
agent_type = 'qa'; break
|
|
208
|
-
else:
|
|
209
|
-
for kw in ['deploy', 'ci/cd', 'monitoring', 'infrastructure', 'docker']:
|
|
210
|
-
if kw in title_lower:
|
|
211
|
-
agent_type = 'sre'; break
|
|
212
|
-
else:
|
|
213
|
-
for kw in ['component', 'react', 'frontend', 'tsx', 'jsx', 'hook', 'state']:
|
|
214
|
-
if kw in title_lower:
|
|
215
|
-
agent_type = 'developer'; break
|
|
216
|
-
|
|
217
|
-
skill_map = {
|
|
218
|
-
'developer': '.claude/skills/developer/SKILL.md',
|
|
219
|
-
'backend': '.claude/skills/backend_engineer/SKILL.md',
|
|
220
|
-
'designer': '.claude/skills/designer/SKILL.md',
|
|
221
|
-
'qa': '.claude/skills/qa_engineer/SKILL.md',
|
|
222
|
-
'sre': '.claude/skills/sre_agent/SKILL.md',
|
|
223
|
-
'dev': '.claude/skills/dev_agent/SKILL.md',
|
|
224
|
-
}
|
|
225
|
-
skill_path = skill_map.get(agent_type, '.claude/skills/dev_agent/SKILL.md')
|
|
226
|
-
|
|
227
|
-
print(json.dumps({
|
|
228
|
-
'id': task_id,
|
|
229
|
-
'title': title,
|
|
230
|
-
'priority': priority,
|
|
231
|
-
'status': 'pending',
|
|
232
|
-
'scope_paths': scope_paths,
|
|
233
|
-
'dependencies': deps,
|
|
234
|
-
'source_file': filename,
|
|
235
|
-
'created_at': datetime.now().isoformat(),
|
|
236
|
-
'agent_type': agent_type,
|
|
237
|
-
'skill_path': skill_path,
|
|
238
|
-
}))
|
|
239
|
-
PYEOF
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
# ============================================================
|
|
243
|
-
# Main
|
|
244
|
-
# ============================================================
|
|
245
|
-
|
|
246
|
-
if [[ "$QUIET" != "true" ]]; then
|
|
247
|
-
echo ""
|
|
248
|
-
echo "============================================================"
|
|
249
|
-
echo " Syncing Task Queue"
|
|
250
|
-
echo "============================================================"
|
|
251
|
-
echo ""
|
|
252
|
-
fi
|
|
253
|
-
|
|
254
|
-
# Ensure tasks directory exists
|
|
255
|
-
if [[ ! -d "$TASKS_DIR" ]]; then
|
|
256
|
-
warn "Tasks directory not found: $TASKS_DIR"
|
|
257
|
-
exit 0
|
|
258
|
-
fi
|
|
259
|
-
|
|
260
|
-
info "Scanning tasks from: $TASKS_DIR (only pending/in_progress/blocked tasks)"
|
|
261
|
-
|
|
262
|
-
# Collect all task JSON objects into a temp file
|
|
263
|
-
TASKS_TMPFILE=$(mktemp /tmp/kenaz_tasks.XXXXXX)
|
|
264
|
-
trap "rm -f '$TASKS_TMPFILE'" EXIT
|
|
265
|
-
|
|
266
|
-
# Process YAML files
|
|
267
|
-
for f in "$TASKS_DIR"/TASK_*.yaml "$TASKS_DIR"/TASK_*.yml; do
|
|
268
|
-
[[ -f "$f" ]] || continue
|
|
269
|
-
task_json=$(parse_yaml_task "$f" 2>/dev/null || echo "")
|
|
270
|
-
if [[ -n "$task_json" ]]; then
|
|
271
|
-
echo "$task_json" >> "$TASKS_TMPFILE"
|
|
272
|
-
task_id=$(echo "$task_json" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
|
|
273
|
-
task_title=$(echo "$task_json" | python3 -c "import sys,json; print(json.load(sys.stdin)['title'])")
|
|
274
|
-
task_pri=$(echo "$task_json" | python3 -c "import sys,json; print(json.load(sys.stdin)['priority'])")
|
|
275
|
-
info " Found (yaml): $task_id - $task_title [$task_pri]"
|
|
276
|
-
fi
|
|
277
|
-
done
|
|
278
|
-
|
|
279
|
-
# Process Markdown files
|
|
280
|
-
for f in "$TASKS_DIR"/TASK_*.md; do
|
|
281
|
-
[[ -f "$f" ]] || continue
|
|
282
|
-
task_json=$(parse_md_task "$f" 2>/dev/null || echo "")
|
|
283
|
-
if [[ -n "$task_json" ]]; then
|
|
284
|
-
echo "$task_json" >> "$TASKS_TMPFILE"
|
|
285
|
-
task_id=$(echo "$task_json" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
|
|
286
|
-
task_title=$(echo "$task_json" | python3 -c "import sys,json; print(json.load(sys.stdin)['title'])")
|
|
287
|
-
task_pri=$(echo "$task_json" | python3 -c "import sys,json; print(json.load(sys.stdin)['priority'])")
|
|
288
|
-
info " Found (md): $task_id - $task_title [$task_pri]"
|
|
289
|
-
fi
|
|
290
|
-
done
|
|
291
|
-
|
|
292
|
-
info "Skipping completed/ directory (completed tasks are managed in .memory/)"
|
|
293
|
-
|
|
294
|
-
# Merge and generate final TASK_QUEUE.json via Python
|
|
295
|
-
python3 << 'PYEOF' "$TASKS_TMPFILE" "$QUEUE_FILE" "$FORCE"
|
|
296
|
-
import sys, json, os
|
|
297
|
-
from datetime import datetime
|
|
298
|
-
|
|
299
|
-
tasks_file = sys.argv[1]
|
|
300
|
-
queue_file = sys.argv[2]
|
|
301
|
-
force = sys.argv[3] == 'true' if len(sys.argv) > 3 else False
|
|
302
|
-
|
|
303
|
-
# Read scanned tasks
|
|
304
|
-
tasks = []
|
|
305
|
-
if os.path.exists(tasks_file):
|
|
306
|
-
with open(tasks_file, 'r') as f:
|
|
307
|
-
for line in f:
|
|
308
|
-
line = line.strip()
|
|
309
|
-
if line:
|
|
310
|
-
try:
|
|
311
|
-
tasks.append(json.loads(line))
|
|
312
|
-
except json.JSONDecodeError:
|
|
313
|
-
pass
|
|
314
|
-
|
|
315
|
-
# Load existing queue for merge
|
|
316
|
-
existing_tasks = {}
|
|
317
|
-
if os.path.exists(queue_file) and not force:
|
|
318
|
-
try:
|
|
319
|
-
with open(queue_file, 'r', encoding='utf-8') as f:
|
|
320
|
-
existing = json.load(f)
|
|
321
|
-
for t in existing.get('tasks', []):
|
|
322
|
-
existing_tasks[t['id']] = t
|
|
323
|
-
except (json.JSONDecodeError, KeyError):
|
|
324
|
-
pass
|
|
325
|
-
|
|
326
|
-
# Merge
|
|
327
|
-
merged = []
|
|
328
|
-
for task in tasks:
|
|
329
|
-
tid = task['id']
|
|
330
|
-
if tid in existing_tasks and not force:
|
|
331
|
-
ex = existing_tasks[tid]
|
|
332
|
-
# Preserve non-pending status
|
|
333
|
-
if ex.get('status') and ex['status'] != 'pending':
|
|
334
|
-
task['status'] = ex['status']
|
|
335
|
-
# Preserve description if not in new
|
|
336
|
-
if not task.get('description') and ex.get('description'):
|
|
337
|
-
task['description'] = ex['description']
|
|
338
|
-
# Preserve estimated_hours
|
|
339
|
-
if ex.get('estimated_hours') and not task.get('estimated_hours'):
|
|
340
|
-
task['estimated_hours'] = ex['estimated_hours']
|
|
341
|
-
# Preserve agent/branch info
|
|
342
|
-
for key in ['assigned_agent', 'branch', 'started_at', 'completed_at']:
|
|
343
|
-
if ex.get(key):
|
|
344
|
-
task[key] = ex[key]
|
|
345
|
-
merged.append(task)
|
|
346
|
-
|
|
347
|
-
# Sort by priority then ID
|
|
348
|
-
priority_order = {'P0': 0, 'P1': 1, 'P2': 2, 'P3': 3}
|
|
349
|
-
merged.sort(key=lambda t: (priority_order.get(t.get('priority', 'P2'), 2), t.get('id', '')))
|
|
350
|
-
|
|
351
|
-
# Statistics
|
|
352
|
-
stats = {
|
|
353
|
-
'total': len(merged),
|
|
354
|
-
'pending': sum(1 for t in merged if t.get('status') == 'pending'),
|
|
355
|
-
'in_progress': sum(1 for t in merged if t.get('status') == 'in_progress'),
|
|
356
|
-
'completed': sum(1 for t in merged if t.get('status') == 'completed'),
|
|
357
|
-
'blocked': sum(1 for t in merged if t.get('status') == 'blocked'),
|
|
358
|
-
'cancelled': sum(1 for t in merged if t.get('status') == 'cancelled'),
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
queue = {
|
|
362
|
-
'version': '1.0.0',
|
|
363
|
-
'project': 'kenaz-dashboard',
|
|
364
|
-
'last_updated': datetime.now().isoformat(),
|
|
365
|
-
'statistics': stats,
|
|
366
|
-
'tasks': merged,
|
|
367
|
-
'metadata': {
|
|
368
|
-
'created_at': datetime.now().isoformat(),
|
|
369
|
-
'source_spec': 'dev/PRODUCT_SPEC.md',
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
os.makedirs(os.path.dirname(queue_file), exist_ok=True)
|
|
374
|
-
with open(queue_file, 'w', encoding='utf-8') as f:
|
|
375
|
-
json.dump(queue, f, indent=2, ensure_ascii=False)
|
|
376
|
-
|
|
377
|
-
# Output stats for shell
|
|
378
|
-
print(f"TOTAL={stats['total']}")
|
|
379
|
-
print(f"PENDING={stats['pending']}")
|
|
380
|
-
print(f"IN_PROGRESS={stats['in_progress']}")
|
|
381
|
-
print(f"COMPLETED={stats['completed']}")
|
|
382
|
-
print(f"BLOCKED={stats['blocked']}")
|
|
383
|
-
PYEOF
|
|
384
|
-
|
|
385
|
-
if [[ "$QUIET" != "true" ]]; then
|
|
386
|
-
echo ""
|
|
387
|
-
success "Task queue synced!"
|
|
388
|
-
echo ""
|
|
389
|
-
echo " Source: $TASKS_DIR (completed/ is ignored)"
|
|
390
|
-
echo " Queue file: $QUEUE_FILE"
|
|
391
|
-
echo ""
|
|
392
|
-
fi
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
# Kenaz Agent Connect — Protocol v0.4 (PROTOCOL.md)
|
|
2
|
-
|
|
3
|
-
- **開發者請先讀 [`SDK_GUIDE.md`](./SDK_GUIDE.md)**——那份文件是給生態系網站開發者的接入指南(10 分鐘接入、深連結參數表、MCP 約定、審批 UX、開發模式、測試、疑難排解 toast 對照表、可跑的 `examples/minimal-site/` 範例),本檔是它背後的協定權威來源。只需要接入的讀者不需要從這裡開始讀。
|
|
4
|
-
- Status: **finalized draft**, B 期(TASK_1939,2026-09-08)。取代本檔 v0.3(WebSocket relay + 配對握手協定,凍結快照在 `history/PROTOCOL_v0.3_snapshot.md`)。
|
|
5
|
-
- 標準所有權:本檔是唯一權威來源。`dev/KENAZ_AGENT_CONNECT_v1_SPEC.md` 第 2.3 節指向本檔。
|
|
6
|
-
- **v0.4 的核心收斂(用戶決定,2026-09-08 晚,spec 第 6 節 Q10):relay 整個拿掉。** 三方接口只剩兩個東西——一個 `kenaz://connect` 深連結格式、一份「網站 MCP 該長什麼樣」的最小約定。沒有 relay、沒有 WebSocket、沒有配對憑證交換、沒有線上協定訊息型別。v0.3 剩下的喚醒/憑證/狀態回報三個功能分別由深連結、網站自己簽發的一次性 token、agent 呼叫網站 MCP 得取代——見第 4 節「廢止清單」。
|
|
7
|
-
- 這份文件的每個 ```json 範例都必須是**可直接 `JSON.parse` 的合法 JSON**——不可有 `|`、不可有註解、不可有多形態塞進同一個區塊。`dashboard/scripts/agent-connect-conformance/fixtures.mjs` 直接抽取這些區塊當作 conformance suite 的唯一 fixture 來源;本檔任何一個區塊解析失敗,測試就會 fail。
|
|
8
|
-
|
|
9
|
-
## 0. 一句話
|
|
10
|
-
|
|
11
|
-
**任何網站只要照 Kenaz 的深連結格式與 MCP 約定開發,就能用一個深連結在用戶本機喚醒 Kenaz、經用戶審批後開啟一個掛著該網站 MCP 的 Ansuz 會話;之後網站與 agent 之間的一切都走網站自己的 MCP。**
|
|
12
|
-
|
|
13
|
-
三方接口:
|
|
14
|
-
- **Web → Kenaz**:深連結 `kenaz://connect?site=&mcp=&token=[&prompt=][&agent=][&v=]`。用戶按下「連接」那一下(同意深連結)就是 launch 本身——沒有另外的 launch 訊息,沒有事先的配對步驟。
|
|
15
|
-
- **Kenaz → Web**:沒有回程通道。網站靠 agent 呼叫它自己的 MCP 得知「連上了」(`kenaz_hello` 慣例工具,見第 2 節),逾時未呼叫就顯示「請安裝 Kenaz」。
|
|
16
|
-
- **Agent ↔ Web**:只透過網站的 MCP 工具,bearer = 深連結裡的一次性 token,由網站自己簽發與驗證。
|
|
17
|
-
|
|
18
|
-
明確的非目標:這不是 OAuth、不是帳號系統、不做用戶身份聯邦。「透過 Kenaz 登入 agent」的意思是把網站和本機 agent 串起來,網站不需要知道用戶是誰。
|
|
19
|
-
|
|
20
|
-
## 1. 深連結格式
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
kenaz://connect?site=<url-encoded https origin>&mcp=<url-encoded https MCP url>&token=<one-time token>[&prompt=<url-encoded text>][&agent=claude|codex][&v=1]
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
| 參數 | 必填 | 說明 |
|
|
27
|
-
|---|---|---|
|
|
28
|
-
| `site` | 是 | 網站 origin。`https://...`;開發模式(`KENAZ_AGENT_HUB_DEV=1` 或 debug build)允許 `http://localhost` / `http://127.0.0.1` / `http://[::1]`。Kenaz 用 `Url::origin().ascii_serialization()` 正規化,去掉 path/query/fragment,作為 sites.json 的 key。 |
|
|
29
|
-
| `mcp` | 是 | 網站自己的 MCP 端點,完整 URL(含 path)。scheme 規則與 `site` 相同(https;dev 模式同上放寬)。**審批卡以其 host 為主要識別**(第 3 節)——沒有 relay 就沒有「relay 驗過的 origin」,MCP URL 是 agent 真正會連的對象。 |
|
|
30
|
-
| `token` | 是 | 一次性 bearer,≤512 字元,charset 限 `[A-Za-z0-9._-]`;由網站自己簽發、綁定它自己的用戶 session、自己驗證。Kenaz 不解讀、不落盤持久化——只在這次啟動的存續期間,以環境變數形式交給 agent 當 MCP 的 `Authorization: Bearer` 值。 |
|
|
31
|
-
| `prompt` | 否 | 起始 prompt,交給 Ansuz 當第一則使用者訊息。**省略時由 Kenaz 自己補一句開場訊息**(純 ASCII,帶 `site` origin)觸發第一個 turn——網站不必也不應為了讓 agent 動起來而塞 `prompt=`(見第 2 節第 5 點 `kenaz_wait_for_message`)。深連結整體長度在 Windows 上約有 2 KB 限制——長內容請放在 MCP 工具裡讓 agent 自己取,不要塞進 `prompt=`。 |
|
|
32
|
-
| `agent` | 否 | 指定 CLI,`"claude"` 或 `"codex"`。省略時依用戶的 dispatch 設定決定;顯式指定的 CLI 未安裝時 launch 失敗(不會靜默退回預設值)。 |
|
|
33
|
-
| `v` | 否 | 協定版本,缺省 `"1"`。Kenaz 只認識自己支援的版本;不支援的版本一律 toast 拒絕("protocol version unsupported"),不出審批卡。目前只有 `"1"`。 |
|
|
34
|
-
|
|
35
|
-
任何其他/未知 query 參數(包含 v0.3 的 `relay=`)一律靜默忽略,不拒絕——只有格式不合法(scheme 錯誤、`token` 過長、`v` 不支援等)才拒絕。
|
|
36
|
-
|
|
37
|
-
#### Fixture: deep_link.valid
|
|
38
|
-
|
|
39
|
-
```json
|
|
40
|
-
{"name": "valid", "url": "kenaz://connect?site=https://flowpix.app&mcp=https://flowpix.app/mcp&token=a1b2c3d4e5f60718293a4b5c6d7e8f90&prompt=summarize+the+canvas&agent=claude"}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
#### Fixture: deep_link.missing_mcp
|
|
44
|
-
|
|
45
|
-
```json
|
|
46
|
-
{"name": "missing_mcp", "url": "kenaz://connect?site=https://flowpix.app&token=a1b2c3d4e5f60718293a4b5c6d7e8f90", "rejected_because": "missing required field: mcp"}
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
#### Fixture: deep_link.http_site_not_dev
|
|
50
|
-
|
|
51
|
-
```json
|
|
52
|
-
{"name": "http_site_not_dev", "url": "kenaz://connect?site=http://evil.example&mcp=https://flowpix.app/mcp&token=abc", "rejected_because": "site scheme not allowed: http (not localhost/127.0.0.1/[::1], or not in dev mode)"}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
#### Fixture: deep_link.unsupported_version
|
|
56
|
-
|
|
57
|
-
```json
|
|
58
|
-
{"name": "unsupported_version", "url": "kenaz://connect?site=https://flowpix.app&mcp=https://flowpix.app/mcp&token=abc&v=999", "rejected_because": "protocol version unsupported: 999"}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
Kenaz 收到後的完整流程:解析並驗證 → 若該 origin 已被封鎖,直接 toast 拒絕(不出審批卡)→ 否則出審批卡(第 3 節)→ 允許則在 Dashboard 開一個互動終端分頁:用戶配置的 CLI(`claude` 或 `codex`)+ Ansuz 人格(`session.js prompt Ansuz --mode=assembled --depth=elixir --no-muninn` 的輸出,逐字沿用)+ 預配 MCP(`{"mcpServers":{<name>:{"type":"http","url":<mcp>,"headers":{"Authorization":"Bearer <token>"}}}}`,`<name>` 由 `mcp` 的 hostname 衍生)+ `prompt` 作為第一則使用者訊息。cwd 永遠是 Dashboard 目前開啟的專案——網站不可指定。
|
|
62
|
-
|
|
63
|
-
## 2. 網站 MCP 最小約定
|
|
64
|
-
|
|
65
|
-
任何網站只要提供一個符合下列約定的 MCP 端點,就能被 Kenaz 的深連結串接:
|
|
66
|
-
|
|
67
|
-
1. **驗證 bearer**:每個請求的 `Authorization: Bearer <token>` 必須被驗證是自己簽發、未過期、未撤銷的。Kenaz 不做任何驗證——這完全是網站自己的責任,也是網站唯一需要信任的邊界(Kenaz 只是把深連結裡的 token 原樣轉交給 agent)。
|
|
68
|
-
1b. **`X-Kenaz-Session` header(TASK_1947,選讀)**:Kenaz 預配 MCP 時,除了 `Authorization: Bearer <token>` 之外,一律額外送一個 `X-Kenaz-Session: <launch_id>` header——`<launch_id>` 是 Kenaz 在這次啟動一開始就產生的 uuid v4(早於任何 pty 終端 session id 存在之前),同一次深連結啟動的存續期間固定不變。網站**不需要**讀這個 header 才能運作(bearer 仍是唯一必須驗證的邊界,見上一點);它存在的目的是讓網站能分辨「這次 MCP 呼叫屬於哪一次連接」,比單純用 token 對應更直接——同一個 token 理論上可能被同一使用者的多個分頁/連接重用,但 launch_id 保證每次啟動獨一無二。codex 分支目前用 `-c mcp_servers.<name>.env_http_headers` 覆寫達到同樣效果(見下方「codex 限制」一節);claude 分支則直接寫進預配 MCP JSON 的 `headers`。
|
|
69
|
-
2. **提供 `kenaz_hello` 工具(建議)**:無參數,成功回 `{"ok": true}`。Ansuz 人格會在會話開始時、處理 `prompt` 之前呼叫一次——這是網站得知「Kenaz 真的連上了」的唯一方式(沒有回程通道,見第 0 節)。網站建議設一個逾時(建議 60 秒):逾時未收到 `kenaz_hello` 呼叫,就顯示「請安裝 Kenaz」之類的安裝指引,而不是無限等待。
|
|
70
|
-
3. **其餘工具完全由網站自訂**:Kenaz 不列舉、不審核、不限制。網站的產品邏輯(生圖、寫回、查詢……)全部經由這些自訂工具與 agent 互動,Kenaz 對這段流量完全不可見。
|
|
71
|
-
4. **沒有結束通知**:agent 的終端分頁何時關閉,網站不會被告知。網站應以 token 撤銷或閒置逾時來回收狀態,不要假設有明確的「已結束」事件。
|
|
72
|
-
5. **可選:`kenaz_wait_for_message`(持續對話,TASK_1948,FlowPix 分靈 2026-09-09 Feature Request S2)**:`kenaz_hello` 只解決「連上了沒」,不解決「agent 會不會一直聽網站接下來說的話」——這一點刻意不留給網站自己做 prompt 工程,而是搬進 Kenaz 人格本身:網站只要在 `tools/list` 多提供一個無參數工具 `kenaz_wait_for_message`,Ansuz 人格在呼叫過 `kenaz_hello` 並處理完 `prompt` 之後,就會反覆呼叫它。**`prompt` 省略時由 Kenaz 保證仍有一個真實的第一個 turn**(TASK_1956)——CLI 的位置參數就是互動式會話的第一則使用者訊息,空字串等於沒有第一個 turn,人格與這條約定就永遠不會被讀到;Kenaz 在 `prompt` 為空/空白時會自己補一句純 ASCII 的開場訊息(帶 `site` origin)當作這個第一則訊息,網站因此完全不需要、也不應該為了觸發第一個 turn 而自己塞一句 `prompt=`。
|
|
73
|
-
- **回傳形狀**(無參數呼叫,成功時):
|
|
74
|
-
```json
|
|
75
|
-
{"message": "<string|null>", "message_id": "<string|null>", "end": false}
|
|
76
|
-
```
|
|
77
|
-
`end` 欄位可省略,省略時視為 `false`。
|
|
78
|
-
- `message` 非 `null`:agent 把它當成使用者的下一則指令執行,執行完再呼叫一次 `kenaz_wait_for_message`。
|
|
79
|
-
- `message` 為 `null`:目前沒有新訊息,不是錯誤——agent 直接再呼叫一次。
|
|
80
|
-
- `end` 為 `true`:agent 停止呼叫,告知使用者對話已結束。
|
|
81
|
-
- agent 連續呼叫這個工具失敗(逾時、拋錯、連線失敗)達 3 次,也會停止並告知使用者。
|
|
82
|
-
- 這個工具沒被列在網站的 `tools/list` 裡時,agent 完全不會呼叫它、也完全不會向使用者提起它——這段行為對沒有實作它的網站是純粹的無操作,不影響本節其餘四點的最小約定。
|
|
83
|
-
- **成本條款(強制)**:每一次 `kenaz_wait_for_message` 呼叫都是一次真實的 agent turn,成本由 Kenaz 使用者自己的訂閱額度承擔,不是網站的成本。網站**必須**用長輪詢實作——建議在伺服器端阻塞 **20-25 秒**才回傳 `message: null`,把呼叫頻率壓到最低;**不得**用短輪詢(例如每 1 秒就回一次 `null`)迫使 agent 高頻空轉,消耗使用者的訂閱額度。這是本約定唯一的強制條款,其餘都是建議。
|
|
84
|
-
6. **建議標 `tool annotations`(TASK_1949,Agent Connect C-1b)**:`tools/list` 回應裡每個工具可以帶一個 `annotations` 物件(`readOnlyHint`、`destructiveHint`、`idempotentHint`、`openWorldHint`,MCP 規格既有欄位)。claude 分支啟動前會對你的 MCP 做一次 3 秒的 `tools/list` 探測,把 `readOnlyHint: true` 或 `destructiveHint: false` 的工具直接加進 `--allowedTools`(跳過第一次呼叫的終端機權限提示);沒有 `annotations`、或有 `annotations` 但沒寫 `destructiveHint` 的工具,一律當成「有後果」(MCP 規格 `destructiveHint` 缺省即為 `true`),維持逐次詢問。探測本身逾時、回應非 2xx、JSON 解析失敗、或回應裡沒有 `result.tools` 陣列,一律不預先允許任何工具(不是退回全允、也不是整個 MCP 都不能用——只是每次呼叫都會跳終端機提示),並在啟動的終端第一行印出失敗原因。**未標 annotations 的工具在 claude 會逐次提問**——這不影響功能,只影響使用者要不要多按幾次終端機提示。
|
|
85
|
-
|
|
86
|
-
#### Fixture: mcp.tools_list_with_annotations
|
|
87
|
-
|
|
88
|
-
```json
|
|
89
|
-
{"jsonrpc": "2.0", "id": 1, "result": {"tools": [{"name": "kenaz_hello", "annotations": {"destructiveHint": false, "idempotentHint": true}}, {"name": "kenaz_wait_for_message", "annotations": {"readOnlyHint": true}}, {"name": "echo", "annotations": {"readOnlyHint": true}}, {"name": "delete_all_data", "annotations": {"destructiveHint": true}}]}}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
#### Fixture: mcp.kenaz_hello_call
|
|
93
|
-
|
|
94
|
-
```json
|
|
95
|
-
{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "kenaz_hello", "arguments": {}}}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
#### Fixture: mcp.kenaz_hello_result
|
|
99
|
-
|
|
100
|
-
```json
|
|
101
|
-
{"jsonrpc": "2.0", "id": 1, "result": {"content": [{"type": "text", "text": "{\"ok\":true}"}], "isError": false}}
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
#### Fixture: mcp.config_with_session_header
|
|
105
|
-
|
|
106
|
-
claude 分支預配的 MCP config JSON 形狀(TASK_1947)——`headers` 同時帶 `Authorization` 與 `X-Kenaz-Session`:
|
|
107
|
-
|
|
108
|
-
```json
|
|
109
|
-
{"mcpServers": {"flowpix": {"type": "http", "url": "https://flowpix.app/mcp", "headers": {"Authorization": "Bearer a1b2c3d4e5f60718293a4b5c6d7e8f90", "X-Kenaz-Session": "1b0d6b9a-8f2a-4c56-8abc-9f9e9c9d9e9f"}}}}
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
#### Fixture: mcp.kenaz_wait_for_message_call
|
|
113
|
-
|
|
114
|
-
```json
|
|
115
|
-
{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "kenaz_wait_for_message", "arguments": {}}}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
#### Fixture: mcp.kenaz_wait_for_message_result_message
|
|
119
|
-
|
|
120
|
-
```json
|
|
121
|
-
{"jsonrpc": "2.0", "id": 2, "result": {"content": [{"type": "text", "text": "{\"message\":\"add a red circle to the canvas\",\"message_id\":\"m_1\",\"end\":false}"}], "isError": false}}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
#### Fixture: mcp.kenaz_wait_for_message_result_null
|
|
125
|
-
|
|
126
|
-
```json
|
|
127
|
-
{"jsonrpc": "2.0", "id": 2, "result": {"content": [{"type": "text", "text": "{\"message\":null,\"message_id\":null}"}], "isError": false}}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
## 3. 審批與權限模型
|
|
131
|
-
|
|
132
|
-
不變於 v0.3:per-origin 四態權限,`unauthorized` / `once` / `always` / `blocked`,持久化在 `~/.kenaz/agent_hub/sites.json`。
|
|
133
|
-
|
|
134
|
-
- `unauthorized`/`once`:每次深連結請求都出一張審批卡,內容:**site origin**、**MCP host**(主要識別——沒有 relay 驗證過的 origin,MCP 端點是 agent 真正會連的對象)、要用的 `agent`/`model`、**cwd 絕對路徑**(不可省略——網站的 prompt 完全由網站決定,用戶按允許前必須知道這次操作會在哪個資料夾發生)、`prompt` 前 120 字。用戶選擇 一次允許 / 永遠允許 / 拒絕 / 封鎖此網站。
|
|
135
|
-
- `always`:跳過審批卡,直接執行(仍在本機記錄一次事件供事後稽核)。
|
|
136
|
-
- `blocked`:直接拒絕,不出審批卡,只有一個本機 toast。`blocked` 也可由手動編輯 `sites.json` 達成——每次請求都重新讀檔,不信任純記憶體快取。
|
|
137
|
-
- 一個被暫停的 Agent Hub(tray「Pause Agent Hub」)擋下所有深連結,包含 `always` 狀態的 origin,且不出審批卡。
|
|
138
|
-
|
|
139
|
-
審批卡摘要字串格式:`"{site} → MCP {mcp_host} → {agent}/{model} · cwd {絕對路徑} · {prompt 前 120 字}"`。
|
|
140
|
-
|
|
141
|
-
## 4. 廢止清單(v0.3 → v0.4,relay 全部拿掉)
|
|
142
|
-
|
|
143
|
-
以下 v0.3(WebSocket relay 協定,含它收編自 Relay v1 的配對握手)曾經存在的一切,v0.4 硬切後**不再支援**。完整的歷史協定內容見 `history/PROTOCOL_v0.3_snapshot.md`;Relay v1(FlowPix)的更早歷史見 `history/README.md`。
|
|
144
|
-
|
|
145
|
-
| 廢止項目 | 原用途 | 由什麼取代 |
|
|
146
|
-
|---|---|---|
|
|
147
|
-
| relay(整個角色,含託管 relay、`site_key`、網站註冊) | Kenaz 與網站之間的中介轉發服務 | 沒有中介——深連結直達 Kenaz,Kenaz 與網站之間再無任何直接通訊 |
|
|
148
|
-
| WebSocket 連線(`ws://`/`wss://`) | relay ↔ Kenaz、relay ↔ 網站的雙向連線 | 深連結是一次性、單向、同步的請求;沒有任何持續連線 |
|
|
149
|
-
| `site.hello` / `site.ready` | 網站向 relay 註冊一個 session | 不需要——網站不與 Kenaz 建立任何連線 |
|
|
150
|
-
| `token.mint` / `token.minted` | 網站向 relay 請求一次性配對 token | 網站自己簽發 `token`,直接放進深連結 |
|
|
151
|
-
| `pair.begin` / `pair.ok` / `pair.denied`(含 `protocol_version` 欄位) | Kenaz 向 relay 用 token 換取 `session_credential` | 深連結本身就是完整請求;`token` 直接就是 MCP bearer,不需要換發;深連結自己的 `v=` 參數取代線上版本協商 |
|
|
152
|
-
| `agent.connected` / `agent.disconnected` | relay 通知網站「Kenaz 連上/斷線了」 | 網站靠 agent 呼叫 `kenaz_hello`(第 2 節)得知連上;沒有斷線通知 |
|
|
153
|
-
| `agent.status`(含 `agents`/`dispatch`/`codex_logged_in`/`approval_mode`) | Kenaz 主動推送安裝/登入/審批狀態 | 沒有回程通道;審批狀態直接影響審批卡本身是否出現(第 3 節),網站不需要知道 |
|
|
154
|
-
| `agent.launch`(線上訊息,含 `mcp`/`agent` 欄位) | 網站透過 relay 請求啟動一個 agent | 深連結本身就是這個請求——`mcp=`/`agent=` 是深連結參數,不是另一則訊息 |
|
|
155
|
-
| `approval.pending` / `approval.resolved`(線上訊息) | Kenaz 把審批結果告知網站 | 沒有回程通道;審批只影響 Kenaz 本機是否執行 |
|
|
156
|
-
| `agent.launched` / `agent.unavailable` / `agent.exited` | Kenaz 把啟動結果/結束狀態告知網站 | 沒有回程通道;網站靠 `kenaz_hello` 得知連上,之後的一切都是網站自己 MCP 工具的呼叫紀錄 |
|
|
157
|
-
| 通用 `error {code, message}` | relay 對未知/廢止訊息型別的拒絕 | 深連結解析失敗直接 toast 拒絕(本機),沒有線上訊息可回 |
|
|
158
|
-
| `session_credential`(`sites.json` 欄位) | relay 核發、持久化以便重連 | 深連結的 `token` 每次都由網站重新提供,不持久化、不重連 |
|
|
159
|
-
| `relay_url`(`sites.json` 欄位) | 記住上次配對的 relay 端點 | 沒有 relay |
|
|
160
|
-
| `mcp_url`(`sites.json` 欄位,v0.3 的「上次用過的 MCP」) | 供重連時沿用 | 深連結每次都帶 `mcp=`,不需要記住 |
|
|
161
|
-
|
|
162
|
-
`sites.json` 的 origin 四態權限(`unauthorized`/`once`/`always`/`blocked`)**保留**,語意不變——見第 3 節。
|
|
163
|
-
|
|
164
|
-
## codex 限制(TASK_1947 查證,codex-cli 0.153.4)
|
|
165
|
-
|
|
166
|
-
- **自訂 header 支援**:codex 的 `mcp_servers.<name>` 設定支援 `env_http_headers`(header 名 → 環境變數名的對照表,值在啟動當下從環境變數讀取,同 `bearer_token_env_var` 的「值不落地在命令列/設定檔」設計)與 `http_headers`(header 名 → 字面值,直接寫死)兩種欄位——經 `codex debug models -c mcp_servers.<n>.url=... -c mcp_servers.<n>.bearer_token_env_var=... -c mcp_servers.<n>.env_http_headers={X-Kenaz-Session='<env var name>'}` 本機驗證可正常載入設定(exit 0,無錯誤)。Kenaz 因此對 codex 也送 `X-Kenaz-Session`,用 `env_http_headers` 而非 `http_headers`(維持與 bearer token 一致的「敏感/識別值只經環境變數傳遞」慣例,即使 launch_id 本身不是密鑰)。注意:`codex mcp add ... -c mcp_servers.<n>.http_headers=...`(該子指令自己的設定合併順序)會回傳 `invalid transport` 錯誤——這是 `codex mcp add` 這個子指令自己的限制,不代表 codex 整體不支援這個欄位;Kenaz 的 codex 分支走的是 `codex <prompt> -c ...` 直接呼叫,不經過 `codex mcp add`,已驗證可行。
|
|
167
|
-
- **MCP 工具呼叫是否觸發審批**:codex 的 `-a/--ask-for-approval` 只列舉兩個值(`on-request` 模型自行決定何時詢問、`never` 完全不詢問),且其說明文字只提到「執行 model-generated shell 指令」——`codex mcp add --help` 也沒有任何「MCP 工具需要額外信任/審批」的旗標。查證範圍內(`--help`、`mcp add --help`、`mcp mcp --help`)沒有找到 codex 對 MCP 工具呼叫本身有獨立審批閘門的證據,也沒有找到能反面證實的方式(需要一次真的互動 session 才能實測,超出本任務 worktree 的驗證範圍——不能對正在跑的 live tauri dev 動任何東西,見本任務 worktree 規則)。**結論:未完全驗證,文件化為已知限制**——Kenaz 目前的 codex 直接呼叫(`build_interactive_script` 的 codex 分支)刻意不加 `-a never`:那會連同「shell 指令執行」的審批也一起關掉,影響範圍比「只想讓 MCP 工具別跳審批」大得多,不是這個任務該做的取捨。若之後有人在真的互動 session 裡觀察到 MCP 工具呼叫真的卡在審批提示,才是加這個旗標(或改用更窄的等效設定)的時機。
|
|
168
|
-
- **annotations 分級不套用到 codex(TASK_1949 查證)**:codex `mcp_servers.<name>` 的設定欄位(`url`/`bearer_token_env_var`/`env_http_headers` 等,見上一點)裡沒有任何「只允許某些工具」或「依 tool annotations 分級」的等效設定;`codex mcp add --help`、`codex --help` 查證範圍內都沒有找到這類旗標。結論:codex 分支對 §2 point 6 的 `tools/list` annotations 完全不讀取、不探測——上一點記錄的「MCP 工具呼叫是否觸發審批」未完全驗證的結論同樣適用,codex 使用者的工具呼叫審批行為完全由 codex 自身決定,與這個任務新增的 claude-only 分級機制無關。
|
|
169
|
-
|
|
170
|
-
## 5. 參考來源
|
|
171
|
-
|
|
172
|
-
- `dev/specs/agent-connect/SDK_GUIDE.md`(TASK_1940,給網站開發者的接入指南——本檔的讀者導向版本)
|
|
173
|
-
- `dev/KENAZ_AGENT_CONNECT_v1_SPEC.md`(v0.4,第 0、2.2、2.3、2.4、3 節是本檔的直接依據)
|
|
174
|
-
- `history/PROTOCOL_v0.3_snapshot.md`(v0.3 凍結快照——WebSocket relay + 配對握手協定的完整內容)
|
|
175
|
-
- `history/README.md`(Relay v1/FlowPix 更早的歷史來源)
|
|
176
|
-
- 目前的 Rust 實作:`dashboard/src-tauri/src/features/agent_hub/deep_link.rs`(深連結解析)、`launch.rs`(執行)、`approval.rs`(審批卡)、`permissions.rs`(origin 四態)、`mod.rs`(串接三者)
|
|
177
|
-
- 假 MCP(conformance/live-verification 用):`dashboard/scripts/agent-hub-fake-mcp.mjs`
|