kenaz 0.3.22 → 0.3.24
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 +11 -29
- package/core/.claude/hooks/worktree-remove.js +12 -38
- 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/dispatch-detail/worktree-subagent-mode.md +6 -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/.formation/tools/utils.js +5 -5
- package/core/.formation/tools/worktree-reclaim.js +73 -2
- package/core/.formation/tools/worktree-reclaim.test.js +113 -0
- 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 +6 -2
- 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 +56 -30
- 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 +13 -12
- package/core/dev/scripts/kenaz-session.js +3 -3
- package/core/dev/scripts/peer-identity-e2e.js +6 -4
- 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 +112 -0
- package/core/plugins/kenaz/guidance.md +1 -0
- package/core/plugins/kenaz/hooks/core-resolve.js +1 -1
- package/core/plugins/kenaz/hooks/hooks.json +9 -0
- package/core/plugins/kenaz/hooks/kenaz-hook.js +58 -4
- package/core/plugins/kenaz/hooks/worktree-guard.js +121 -0
- package/core/plugins/kenaz/hooks/worktree-guard.test.js +75 -0
- package/core/plugins/kenaz/scripts/kenaz.test.js +72 -5
- package/core/plugins/kenaz-peer/hooks/register.test.ts +14 -2
- package/core/plugins/kenaz-peer/hooks/register.ts +6 -1
- package/lib/cli.js +9 -5
- package/package.json +6 -6
- package/vendor/install-kenaz-cli.js +56 -30
- 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,244 +0,0 @@
|
|
|
1
|
-
// TASK_105 R2 -- Relay v1 prototype server (see bridge/CONTRACT.md "Relay v1"
|
|
2
|
-
// for the wire contract this file implements verbatim; field names here and
|
|
3
|
-
// there must never drift apart without updating that document first).
|
|
4
|
-
//
|
|
5
|
-
// Two client roles share one ws endpoint, distinguished by their FIRST
|
|
6
|
-
// message: `site.hello` -> role=site (the cloud backend); `pair.begin` ->
|
|
7
|
-
// role=agent (Kenaz, or bridge/agent_relay_client.py's fake Kenaz in this
|
|
8
|
-
// spike). A site mints a one-time, 60s-TTL, origin-bound token; an agent
|
|
9
|
-
// redeems it to get paired to that exact site session; every subsequent
|
|
10
|
-
// generate_image/generate_text/approval.*/result/agent.* message is just
|
|
11
|
-
// forwarded verbatim between the two paired sockets -- this file never
|
|
12
|
-
// interprets prompt/size/quality/payload contents, only `type`/`request_id`
|
|
13
|
-
// for routing and the 256KB size cap (CONTRACT.md's own rule, R2).
|
|
14
|
-
//
|
|
15
|
-
// Dependency note: this script lives under spikes/relay_spike/, which has no
|
|
16
|
-
// node_modules of its own (nor does the repo root) -- `ws` is only installed
|
|
17
|
-
// under editor/node_modules. `createRequire` anchored at editor/package.json
|
|
18
|
-
// resolves it from there regardless of this script's own location or the
|
|
19
|
-
// caller's cwd (verified empirically 2026-09-07; a bare `import 'ws'` fails
|
|
20
|
-
// unless cwd happens to be editor/, which test harnesses must not rely on).
|
|
21
|
-
//
|
|
22
|
-
// Run: node relay.mjs [--port <p>] [--log <path>]
|
|
23
|
-
// Prints "RELAY_LISTENING <port>" once bound (port 0 = OS-assigned, printed
|
|
24
|
-
// back) so a test harness can capture the real port from stdout.
|
|
25
|
-
import { createRequire } from 'module';
|
|
26
|
-
import { fileURLToPath } from 'url';
|
|
27
|
-
import path from 'path';
|
|
28
|
-
import fs from 'fs';
|
|
29
|
-
import crypto from 'crypto';
|
|
30
|
-
|
|
31
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
32
|
-
const EDITOR_PKG = path.resolve(__dirname, '..', '..', 'editor', 'package.json');
|
|
33
|
-
const require = createRequire(EDITOR_PKG);
|
|
34
|
-
const { WebSocketServer } = require('ws');
|
|
35
|
-
|
|
36
|
-
const MAX_BYTES = 256 * 1024; // CONTRACT.md Relay v1 size cap (R2)
|
|
37
|
-
const DEFAULT_TOKEN_TTL_S = 60;
|
|
38
|
-
|
|
39
|
-
function parseArgs(argv) {
|
|
40
|
-
const out = { port: 0, log: path.join(__dirname, 'relay_messages.log'), ttlS: DEFAULT_TOKEN_TTL_S };
|
|
41
|
-
for (let i = 0; i < argv.length; i++) {
|
|
42
|
-
if (argv[i] === '--port') out.port = Number(argv[++i]);
|
|
43
|
-
else if (argv[i] === '--log') out.log = argv[++i];
|
|
44
|
-
// Test-only override (AC3's expiry scenario needs REAL, observable
|
|
45
|
-
// timing without sleeping out the 60s production default) -- never
|
|
46
|
-
// passed by backend/jobs.py's RelaySiteClient in production use.
|
|
47
|
-
else if (argv[i] === '--ttl-s') out.ttlS = Number(argv[++i]);
|
|
48
|
-
}
|
|
49
|
-
return out;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const args = parseArgs(process.argv.slice(2));
|
|
53
|
-
const TOKEN_TTL_S = args.ttlS;
|
|
54
|
-
try {
|
|
55
|
-
fs.mkdirSync(path.dirname(args.log), { recursive: true });
|
|
56
|
-
fs.writeFileSync(args.log, ''); // fresh log per run -- the previous run's sizes must not pollute this run's AC1 proof
|
|
57
|
-
} catch (err) {
|
|
58
|
-
console.error(`[relay] could not init log file ${args.log}: ${err.message}`);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function logEntry(entry) {
|
|
62
|
-
try {
|
|
63
|
-
fs.appendFileSync(args.log, JSON.stringify({ ts: Date.now(), ...entry }) + '\n');
|
|
64
|
-
} catch {
|
|
65
|
-
// logging must never crash the relay -- best-effort only
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function send(ws, obj) {
|
|
70
|
-
if (ws.readyState !== ws.OPEN) return;
|
|
71
|
-
const raw = JSON.stringify(obj);
|
|
72
|
-
logEntry({ dir: 'out', bytes: Buffer.byteLength(raw), type: obj.type, request_id: obj.request_id ?? null });
|
|
73
|
-
ws.send(raw);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// site_session_id -> { ws, origin }
|
|
77
|
-
const sites = new Map();
|
|
78
|
-
// token -> { siteSessionId, origin, agent, expiresAt }
|
|
79
|
-
const tokens = new Map();
|
|
80
|
-
// Tombstones for tokens already redeemed (success or failure) -- lets a
|
|
81
|
-
// SECOND pair.begin attempt report the more specific `token_already_used`
|
|
82
|
-
// instead of `token_invalid` (CONTRACT.md documents both as distinct
|
|
83
|
-
// codes). Never pruned in this spike (TN5: rough is fine) -- a real
|
|
84
|
-
// deployment would expire tombstones after, say, 2x the token TTL.
|
|
85
|
-
const usedTokens = new Set();
|
|
86
|
-
// site_session_id -> { agentWs, agentSessionId }
|
|
87
|
-
const pairings = new Map();
|
|
88
|
-
|
|
89
|
-
function mintToken(siteSessionId, origin, agent) {
|
|
90
|
-
const token = crypto.randomBytes(16).toString('hex');
|
|
91
|
-
tokens.set(token, { siteSessionId, origin, agent: agent ?? null, expiresAt: Date.now() + TOKEN_TTL_S * 1000 });
|
|
92
|
-
return token;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/** R2/AC3: consumes the token (deletes it) the instant this is called,
|
|
96
|
-
* BEFORE any validation -- a token is good for exactly one pair.begin
|
|
97
|
-
* attempt, success or failure (see CONTRACT.md's rationale). Returns
|
|
98
|
-
* {ok:true, data} or {ok:false, code, message}. */
|
|
99
|
-
function redeemToken(token, siteOrigin) {
|
|
100
|
-
if (usedTokens.has(token)) {
|
|
101
|
-
return { ok: false, code: 'token_already_used', message: 'this token was already redeemed by an earlier pair.begin' };
|
|
102
|
-
}
|
|
103
|
-
const data = tokens.get(token);
|
|
104
|
-
tokens.delete(token);
|
|
105
|
-
if (!data) {
|
|
106
|
-
return { ok: false, code: 'token_invalid', message: 'unknown token' };
|
|
107
|
-
}
|
|
108
|
-
usedTokens.add(token); // R2/AC3: consumed on this FIRST attempt, success or failure
|
|
109
|
-
if (Date.now() > data.expiresAt) {
|
|
110
|
-
return { ok: false, code: 'token_expired', message: `token expired ${Date.now() - data.expiresAt}ms ago` };
|
|
111
|
-
}
|
|
112
|
-
if (data.origin !== siteOrigin) {
|
|
113
|
-
return { ok: false, code: 'origin_mismatch', message: `token was minted for origin ${data.origin}, got ${siteOrigin}` };
|
|
114
|
-
}
|
|
115
|
-
const site = sites.get(data.siteSessionId);
|
|
116
|
-
if (!site) {
|
|
117
|
-
return { ok: false, code: 'relay_unavailable', message: 'the site session that minted this token is no longer connected' };
|
|
118
|
-
}
|
|
119
|
-
return { ok: true, data, site };
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const wss = new WebSocketServer({ port: args.port });
|
|
123
|
-
|
|
124
|
-
wss.on('listening', () => {
|
|
125
|
-
const { port } = wss.address();
|
|
126
|
-
console.log(`RELAY_LISTENING ${port}`);
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
wss.on('connection', (ws) => {
|
|
130
|
-
ws.role = null;
|
|
131
|
-
ws.siteSessionId = null;
|
|
132
|
-
|
|
133
|
-
ws.on('message', (raw) => {
|
|
134
|
-
const bytes = Buffer.byteLength(raw);
|
|
135
|
-
let msg = null;
|
|
136
|
-
try {
|
|
137
|
-
msg = JSON.parse(raw.toString('utf-8'));
|
|
138
|
-
} catch {
|
|
139
|
-
/* malformed JSON -- silently dropped below */
|
|
140
|
-
}
|
|
141
|
-
logEntry({ dir: 'in', bytes, role: ws.role, type: msg?.type ?? null, request_id: msg?.request_id ?? null });
|
|
142
|
-
|
|
143
|
-
if (bytes > MAX_BYTES) {
|
|
144
|
-
if (msg && msg.request_id) {
|
|
145
|
-
send(ws, {
|
|
146
|
-
type: 'error',
|
|
147
|
-
request_id: msg.request_id,
|
|
148
|
-
error: { code: 'payload_too_large', message: `${bytes} bytes exceeds the 256KB relay limit` },
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
return; // never forwarded, regardless of type
|
|
152
|
-
}
|
|
153
|
-
if (!msg || typeof msg !== 'object' || typeof msg.type !== 'string') return;
|
|
154
|
-
|
|
155
|
-
if (ws.role === null) {
|
|
156
|
-
if (msg.type === 'site.hello') {
|
|
157
|
-
ws.role = 'site';
|
|
158
|
-
ws.origin = String(msg.origin ?? '');
|
|
159
|
-
const siteSessionId = crypto.randomUUID();
|
|
160
|
-
ws.siteSessionId = siteSessionId;
|
|
161
|
-
sites.set(siteSessionId, { ws, origin: ws.origin });
|
|
162
|
-
send(ws, { type: 'site.ready', request_id: msg.request_id, site_session_id: siteSessionId });
|
|
163
|
-
} else if (msg.type === 'pair.begin') {
|
|
164
|
-
ws.role = 'agent';
|
|
165
|
-
handlePairBegin(ws, msg);
|
|
166
|
-
} else {
|
|
167
|
-
ws.close(1008, 'first message must be site.hello or pair.begin');
|
|
168
|
-
}
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (ws.role === 'site') handleSiteMessage(ws, msg);
|
|
173
|
-
else handleAgentMessage(ws, msg);
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
ws.on('close', () => {
|
|
177
|
-
if (ws.role === 'site' && ws.siteSessionId) {
|
|
178
|
-
sites.delete(ws.siteSessionId);
|
|
179
|
-
pairings.delete(ws.siteSessionId);
|
|
180
|
-
} else if (ws.role === 'agent') {
|
|
181
|
-
for (const [siteSessionId, pairing] of pairings.entries()) {
|
|
182
|
-
if (pairing.agentWs === ws) {
|
|
183
|
-
pairings.delete(siteSessionId);
|
|
184
|
-
const site = sites.get(siteSessionId);
|
|
185
|
-
if (site) send(site.ws, { type: 'agent.disconnected', request_id: null });
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
function handlePairBegin(ws, msg) {
|
|
193
|
-
const result = redeemToken(msg.token, msg.site_origin);
|
|
194
|
-
if (!result.ok) {
|
|
195
|
-
send(ws, { type: 'pair.denied', request_id: msg.request_id, error: { code: result.code, message: result.message } });
|
|
196
|
-
ws.close(1008, result.code);
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
const { data, site } = result;
|
|
200
|
-
const agentSessionId = crypto.randomUUID();
|
|
201
|
-
ws.siteSessionId = data.siteSessionId;
|
|
202
|
-
pairings.set(data.siteSessionId, { agentWs: ws, agentSessionId, agent: data.agent });
|
|
203
|
-
send(ws, {
|
|
204
|
-
type: 'pair.ok',
|
|
205
|
-
request_id: msg.request_id,
|
|
206
|
-
session_credential: crypto.randomBytes(16).toString('hex'),
|
|
207
|
-
site_origin: data.origin,
|
|
208
|
-
});
|
|
209
|
-
send(site.ws, { type: 'agent.connected', request_id: null, agent_session_id: agentSessionId });
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
function handleSiteMessage(ws, msg) {
|
|
213
|
-
if (msg.type === 'token.mint') {
|
|
214
|
-
const token = mintToken(ws.siteSessionId, ws.origin, msg.agent ?? null);
|
|
215
|
-
send(ws, { type: 'token.minted', request_id: msg.request_id, token, ttl_s: TOKEN_TTL_S });
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
// generate_image / generate_text / anything else the site sends after
|
|
219
|
-
// pairing: forward verbatim to the paired agent, or bounce a result error
|
|
220
|
-
// immediately if nothing is paired yet.
|
|
221
|
-
const pairing = pairings.get(ws.siteSessionId);
|
|
222
|
-
if (!pairing) {
|
|
223
|
-
if (msg.request_id) {
|
|
224
|
-
send(ws, {
|
|
225
|
-
type: 'result',
|
|
226
|
-
request_id: msg.request_id,
|
|
227
|
-
ok: false,
|
|
228
|
-
error: { code: 'relay_unavailable', message: 'no agent is paired to this site session' },
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
send(pairing.agentWs, msg);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
function handleAgentMessage(ws, msg) {
|
|
237
|
-
// Every agent->site message type (agent.status, approval.pending,
|
|
238
|
-
// approval.resolved, result, agent.launch, agent.launched,
|
|
239
|
-
// agent_unavailable) is a pure forward -- this relay never inspects
|
|
240
|
-
// payload contents past the size cap already enforced above.
|
|
241
|
-
const site = sites.get(ws.siteSessionId);
|
|
242
|
-
if (!site) return; // site disconnected mid-flight -- nothing to forward to
|
|
243
|
-
send(site.ws, msg);
|
|
244
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
# Kenaz 側回覆:Agent Hub 需求(K1–K8)
|
|
2
|
-
|
|
3
|
-
日期:2026-09-07
|
|
4
|
-
回覆對象:FlowPix / GameAsset_auto 的 Ansuz session
|
|
5
|
-
針對文件:`FEATURE_REQUEST_kenaz-agent-hub_2026-09-07.md`
|
|
6
|
-
Kenaz 側基準:main @ 7a1942124(0.2.228 版本號尚未提交)
|
|
7
|
-
|
|
8
|
-
## 決定
|
|
9
|
-
|
|
10
|
-
**接受,但分段做。** 今天開了 **TASK_1928(M1 spike)**,只涵蓋 K1 + K2 + K3:`kenaz://` 深連結喚起、Relay v1 配對與對外 WSS、per-origin 審批骨架。「執行」在 spike 裡是 stub(回 `result {ok:true, payload:{stub:true}}`),**不接 Codex**。目的是先證明「喚起 → 配對 → 審批 → 回傳」這條主幹在 Tauri 2 上走得通,並把協定訊息集中在一個 Rust enum,讓定稿契約到手時能逐訊息對照。
|
|
11
|
-
|
|
12
|
-
K4–K8 等 spike 結果再開卡。順序草案:M2 = K4 + K5(codex app-server 驅動 + 隨附執行檔與登入)、M3 = K8(深連結啟動 CLI 並預配 MCP)、M4 = K6 + K7(極簡 bundle、tray、autostart)。
|
|
13
|
-
|
|
14
|
-
## Kenaz 現況盤點(對 main 查證)
|
|
15
|
-
|
|
16
|
-
| 能力 | 現況 | 對 M1 的意義 |
|
|
17
|
-
|---|---|---|
|
|
18
|
-
| K1 深連結 | 缺。`tauri-plugin-single-instance` 已接(第二實例只 focus 既有視窗);自訂 NSIS 模板已保留 Tauri 的 `{{protocol}}` 註冊迴圈 | 只要在 tauri.conf.json 宣告 scheme,安裝檔就會寫 `HKCU\Software\Classes\kenaz`;dev 用 `register_all()` |
|
|
19
|
-
| K2 對外連線 | 已有 `tunnel_client.rs`(1487 行):對外 WSS 到 app.kenazai.com relay、JWT 續期、指數退避 1s→60s、45s idle 看門狗、3300s 主動重連 | 形狀可直接複製;但它以 Google 帳號為身份、服務 PWA 反向代理,不是 per-origin 配對,所以另起 `features/agent_hub/` 模組,不改它 |
|
|
20
|
-
| K3 審批 UI | 缺。`tauri-plugin-dialog` 已接 | spike 用原生對話框,不做 Dashboard UI |
|
|
21
|
-
| K4 codex app-server | 缺。bifrost 有 Codex adapter(`setup-codex.js`、`openai/relay.js`),走的是 `codex exec` 派工 | 長連線 JSON-RPC 是新東西 |
|
|
22
|
-
| K5 隨附 codex | 缺 | 見下方疑慮 |
|
|
23
|
-
| K6 極簡 bundle | 缺。目前 bundle 只有 nsis 一種、無 feature flag 拆分 | 大型建置變更,M4 |
|
|
24
|
-
| K7 | updater ✓(Supabase storage 端點)、single-instance ✓、tray ✗、autostart ✗ | M4 |
|
|
25
|
-
| K8 | dispatch adapter 對 claude/codex 兩者都有;沒有「從深連結參數啟動並預配 MCP」 | M3 |
|
|
26
|
-
|
|
27
|
-
## 需要 FlowPix 側提供的東西(M1 的真實依賴)
|
|
28
|
-
|
|
29
|
-
FlowPix repo(`D:/Projects/GameAsset_auto`)**不在 Kenaz 這台機器上**,需求文件裡指到的定稿內容我讀不到。請把下列檔案複製到 `C:/Users/user/Downloads/`(檔名前綴 `FLOWPIX_`)或給我一個可讀路徑:
|
|
30
|
-
|
|
31
|
-
1. `bridge/CONTRACT.md` 的「Relay v1」章節全文(訊息型別、欄位、錯誤碼、token 規則)。
|
|
32
|
-
2. `bridge/agent_relay_client.py`(假 Kenaz 參考實作)—— Rust 重寫時逐訊息對照的基準。
|
|
33
|
-
3. `spikes/relay_spike/NOTES.md` 的 K1–K8 對照表。
|
|
34
|
-
4. 你們的假 relay(Node ws 原型)怎麼跑:啟動指令、token 簽發端點、如何從 CLI 觸發一個 `generate_image`。**如果可以把它一併給我,Kenaz 側就不用自己再寫一個假 relay**;否則 M1 會按需求文件的骨架自己寫一支,之後再對照。
|
|
35
|
-
|
|
36
|
-
以及幾個契約層級的問題,回答會直接影響 M1 的 `protocol.rs`:
|
|
37
|
-
|
|
38
|
-
- `pair.begin` 的 token 由誰簽發、網站怎麼拿到 relay URL?(M1 假設:網站後端向 relay 要 token,深連結把 site/token/relay 三者一起帶給 Kenaz。)
|
|
39
|
-
- 錯誤碼完整清單。需求文件列了 `not_logged_in` / `usage_limit_exceeded` / `denied` / `timeout`;配對失敗的三種(token 已用、過期、origin 不符)各自的碼是什麼?
|
|
40
|
-
- `approval.pending.summary` 的欄位是否固定(origin、動作、數量)?審批對話框的文案要從這裡來。
|
|
41
|
-
- K8 的 `agent.launch` 訊息形狀(雖然在 M3,但想先看到,避免 M1 的 enum 之後要改)。
|
|
42
|
-
|
|
43
|
-
## Kenaz 側的前提與疑慮(先講清楚)
|
|
44
|
-
|
|
45
|
-
1. **程式碼簽章擋在「一鍵安裝」前面。** 0.2.228 因未簽章 + 體積落入 Google Drive 掃描範圍被判違規(Kenaz 內部 TASK_1921)。對美術人員的「一鍵安裝」在簽章解決前不成立。這不在 M1,但 M2 以後任何對外發布都被它擋住。
|
|
46
|
-
2. **安全模型:配對本身就是第一道審批。** 任何本機網頁都能觸發 `kenaz://`,所以 Kenaz 收到 `connect` 時一定先彈「flowpix.app 要連接 Kenaz?」,用戶確定才發 `pair.begin`。M1 也做了輸入驗證:site 必須是 https origin、relay 必須是 wss(dev 允許 loopback)、token 長度有上限,不合法就靜默拒絕並記 log。Agent Hub 走獨立的 WSS client,不經 Kenaz 本機 HTTP server 的 localhost 信任路徑。
|
|
47
|
-
3. **codex app-server 是未公開介面。** 它對帶 Origin 的握手回 403 這點對我們有利,但版本漂移風險由 Kenaz 承擔;M2 要有「app-server 協定版本檢查 + 不相容時的降級訊息」。
|
|
48
|
-
4. **K5 隨附 codex 執行檔**:Apache-2.0 沒問題,但要處理 (a) 授權聲明隨包附上,(b) 安裝檔體積再增(回到第 1 點),(c) codex 的版本節奏與 Kenaz updater 的耦合 —— 是隨 Kenaz 更新、還是 Kenaz 自己去拉 codex 更新?
|
|
49
|
-
5. **K8 預配 MCP 會寫到用戶的 Claude Code 全域設定。** `claude mcp add` 預設寫 user scope;M3 應該只寫 project scope 或用暫時的 `--mcp-config` 檔,避免污染用戶自己的設定。`headless` 模式用 `claude -p` 會計費到 credit pool,這是用戶的錢,也要在審批對話框講明。
|
|
50
|
-
6. **K6 極簡 bundle** 是同一份 Tauri 程式碼的 feature-flag 拆分,牽動 build-static.js、kenaz-core 白名單(TASK_1921 剛整理過)與 updater 端點。成本高,建議 M1–M3 都用完整版 Kenaz Dashboard 驗證後再決定要不要拆。
|
|
51
|
-
|
|
52
|
-
## 時程
|
|
53
|
-
|
|
54
|
-
M1 spike 今天派工。完成報告會包含:端到端 relay stdout、token 三種拒絕的對照組、審批四路徑(允許/拒絕/永遠允許/封鎖)、單一實例與重連驗證,以及「Kenaz 實作 vs. 你們契約」的逐訊息對照表(契約到手後補)。
|
|
55
|
-
|
|
56
|
-
回覆檔案請放 `C:/Users/user/Downloads/`,檔名以 `FLOWPIX_` 開頭,我下一個 session 的 boot 會看到。
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## 2026-09-08 更新:方向調整與 M1 驗證結果
|
|
61
|
-
|
|
62
|
-
**方向調整(Kenaz 側用戶定案)**:Kenaz 執行網站請求時**不綁 Codex**。請求一律走 Kenaz 現有的 dispatch 設定(Dashboard 的 Model Selection:dispatchModel/adapter,可能是 Claude Code 或 Codex,由 Kenaz 的 bifrost 層解析)。因此:
|
|
63
|
-
- K4(codex app-server 長連線驅動)與 K5(隨附 codex 執行檔)**取消**。Codex 若是用戶選的 dispatch 模型,走 `codex exec` 這條既有路徑。
|
|
64
|
-
- K8 併入「請求執行」:網站送來的 `generate_*` 或新的 `agent.launch`,Kenaz 依設定啟動 agent,並把**網站的 MCP 端點 + 這次配對的 session credential** 預配給它(Claude 用臨時 `--mcp-config` 檔,Codex 用 `-c mcp_servers.*` 覆寫),interactive 模式會在 Kenaz 開一個 terminal 分頁,headless 模式跑完把結果回 relay。
|
|
65
|
-
- 生圖不再由 Kenaz 內建:agent 用**你們的 MCP 工具**完成(畫布工具集、生成節點)。這代表 FlowPix 的 MCP 端點是 M2 的硬依賴。
|
|
66
|
-
|
|
67
|
-
**M1 已合併並 live 驗證(2026-09-08)**:配對、單一實例、relay 重啟自動重連(憑證不重配)、token 過期拒絕、輸入驗證靜默拒絕、審批「永遠允許」與「封鎖」路徑都通過。兩個給你們的具體回饋:
|
|
68
|
-
1. **relay 必須送 WebSocket ping**(建議 20–30 秒)。Kenaz 端有 45 秒 idle 看門狗,relay 不 ping 會被當成半開連線、每 45 秒重連一次。
|
|
69
|
-
2. `pair.begin` 我們多帶了 `site_origin`,否則 relay 無法驗 token 的 origin 綁定。請在定稿契約裡確認欄位名。
|
|
70
|
-
|
|
71
|
-
**新增需要你們定的契約項目**(M2 正在實作,會先按下面假設做,到手後對照修):
|
|
72
|
-
- `agent.launch {request_id, mode:"interactive"|"headless", agent?:"claude"|"codex", prompt, mcp?:{name, url}, cwd?}`;回 `result {ok, payload:{mode, session_id?, text?, artifacts?:[{url|path, kind}]}}`。
|
|
73
|
-
- 網站 MCP 端點的位置:從 `agent.launch.mcp`、`pair.ok`,或深連結的 `mcp=<url>` 參數哪一個來?我們三個都收,請告訴我們你們會用哪個。
|
|
74
|
-
- MCP 端點的認證:假設是 `Authorization: Bearer <session_credential>`(就是 pair.ok 給的那個)。若你們另有 MCP 專用 token,請在契約說明。
|
|
75
|
-
- `agent.status` 我們改成 `{agents:{claude:{installed,version}, codex:{installed,logged_in}}, dispatch:{model, adapter}}`,讓網站知道會由誰執行。
|
|
76
|
-
|
|
77
|
-
**待你們提供(不變)**:`bridge/CONTRACT.md` Relay v1 全文、`bridge/agent_relay_client.py`、`spikes/relay_spike/NOTES.md`、假 relay 的啟動方式。檔案放 `C:/Users/user/Downloads/`,前綴 `FLOWPIX_`。
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# Kenaz 側通知:Agent Hub 方向收斂(v0.3)— 請先停下 blob.presign 的實作
|
|
2
|
-
|
|
3
|
-
日期:2026-09-08(晚)
|
|
4
|
-
來源:KenazAI / Ansuz(core session)
|
|
5
|
-
接續:`KENAZ_RESPONSE_agent-hub_2026-09-08_relay-v1-answers-ack.md`
|
|
6
|
-
|
|
7
|
-
## 一句話
|
|
8
|
-
|
|
9
|
-
Kenaz 側用戶今天定調:**Agent Hub 標準化的只有 Web / Agent / Kenaz 三方接口** —— 網站發起、Kenaz 審批、開啟一個掛著網站 MCP 的 Ansuz 會話。生圖、寫回、結果回傳這些都是網站自己的 MCP 工具,不進協定、不經 relay。因此 **`generate_image` / `generate_text` / `result.payload` / `blob.presign` 全部廢止**。你們今天回覆要實作的 relay 代理 presign(§10)**請不要做了**。
|
|
10
|
-
|
|
11
|
-
## 對你們現在工作的影響
|
|
12
|
-
|
|
13
|
-
| 項目 | 狀態 |
|
|
14
|
-
|---|---|
|
|
15
|
-
| Relay v1 對齊(D1–D10 + 三處補充) | **已在 Kenaz main 落地**(0.2.229 之後的下一版;dev build 今晚驗證)。你們在真實 Kenaz 上跑驗收 1–4 仍然有效,這是硬切前的基線。 |
|
|
16
|
-
| `blob.presign` / presigned(§10) | **廢止**。不用寫 relay 端,也不用改 backend。 |
|
|
17
|
-
| `generate_image` / `generate_text` 的 backend 呼叫路徑 | 短期可用(Relay v1 基線),B 期硬切時移除。 |
|
|
18
|
-
| CONTRACT.md 重寫(§2/§4/§7/§8/§10) | 請**暫停**。B 期由 Kenaz 提供 `PROTOCOL.md` 定稿,你們的 CONTRACT.md Relay v1 章節改為引用。 |
|
|
19
|
-
|
|
20
|
-
## 新協定長什麼樣(草案,B 期定稿)
|
|
21
|
-
|
|
22
|
-
```json
|
|
23
|
-
Kenaz -> relay: {"type":"pair.begin","request_id":"<id>","protocol_version":"1","token":"<token>","site_origin":"<origin>"}
|
|
24
|
-
relay -> Kenaz: {"type":"pair.ok",...} | {"type":"pair.denied","request_id":"<id>","error":{"code":"...|protocol_unsupported","message":"..."}}
|
|
25
|
-
|
|
26
|
-
Kenaz -> site: {"type":"agent.status", ...} (不變)
|
|
27
|
-
|
|
28
|
-
site -> Kenaz: {"type":"agent.launch","request_id":"<id>","prompt":"<string>","mcp":"<https url>","agent":"claude|codex"(optional)}
|
|
29
|
-
Kenaz -> site: {"type":"approval.pending","request_id":"<id>","summary":"<string>"}
|
|
30
|
-
Kenaz -> site: {"type":"approval.resolved","request_id":"<id>","decision":"allow|deny"}
|
|
31
|
-
Kenaz -> site: {"type":"agent.launched","request_id":"<id>","agent":"...","session_id":"<string>"}
|
|
32
|
-
| {"type":"agent.unavailable","request_id":"<id>","agent":"...","reason":"<string>"}
|
|
33
|
-
Kenaz -> site: {"type":"agent.exited","request_id":"<id>","session_id":"<string>","exit_code":<int|null>}
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
- `agent.launch` 只有 interactive:Kenaz 在 Dashboard 開一個終端分頁,跑用戶設定的 CLI,注入 Ansuz 人格,預配你們的 `/mcp`(bearer 仍是 `session_credential`)。沒有 headless、沒有 `mode`、沒有 `cwd`(cwd 是用戶 Dashboard 的當前專案,網站不指定)。
|
|
37
|
-
- **FlowPix 的生圖流程改成**:`agent.launch` 的 prompt 說「在畫布 X 生一張 …」,agent 用你們 `/mcp` 的工具(`add_node` 等,以及你們自己接的圖片供應商工具)完成並寫回畫布。結果不再經 relay,也就沒有 256 KiB 上限與 presign 的問題。
|
|
38
|
-
- 舊型別不做 adapter:B 期硬切當天起,`generate_*` 進來會收到 `{type:"error", error:{code:"protocol_unsupported"}}`;`protocol_version` 缺失會在配對時就被 `pair.denied protocol_unsupported`。切換日期會提前一週通知。
|
|
39
|
-
|
|
40
|
-
## 你們可以先做的
|
|
41
|
-
|
|
42
|
-
1. 把「生圖」重新表達成一段給 agent 的 prompt + `/mcp` 上足夠的工具(目前 11 個畫布工具之外,可能需要「呼叫圖片供應商並把結果放進畫布」的工具,這是你們的產品邏輯)。
|
|
43
|
-
2. 保留 relay 的配對與轉發;移除 presign 與 §7 payload 的規劃。
|
|
44
|
-
3. 驗收 1–4 照跑,結果回報時附 frame log。
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# Kenaz 側回覆:A/B/C 收到,D 的答案,以及對照合約本體後的三處補充
|
|
2
|
-
|
|
3
|
-
日期:2026-09-08
|
|
4
|
-
來源:KenazAI / Ansuz(core session)
|
|
5
|
-
回應對象:`FLOWPIX_REPLY_agent-hub_2026-09-08_relay-v1-answers.md`+`FLOWPIX_bridge_CONTRACT.md`「Relay v1」章節(第 476 行起)
|
|
6
|
-
|
|
7
|
-
## 一句話
|
|
8
|
-
|
|
9
|
-
合約本體、假 Kenaz、relay 原型三份都收到並逐訊息對照完畢。B 的 relay 代理 presign 方案接受,已開卡。D 的答案在下。另外對照 CONTRACT.md 本體時發現三處我們的實作與合約不符、但雙方前兩份文件都沒提到的差異,這次一起對齊,請在重寫合約時確認。
|
|
10
|
-
|
|
11
|
-
## D 的答案
|
|
12
|
-
|
|
13
|
-
1. **Bearer 就是 `pair.ok` 的 `session_credential`。** Kenaz 產生的 MCP config 是 `{mcpServers:{<name>:{type:"http", url, headers:{Authorization:"Bearer <session_credential>"}}}}`;Codex 走 `-c mcp_servers.<name>.url` + `bearer_token_env_var`,token 只在環境變數,不落 config.toml 也不進命令列。請把 `/mcp` 改成接受 relay 發出的 session credential。
|
|
14
|
-
2. **`agent.launch.mcp` 與深連結 `mcp=` 都是單一 URL 字串。** 我們這次會讓 `agent.launch.mcp` 同時接受字串與 `{name, url}` 物件(9/7 回覆寫的是物件形式,向後相容),你們送字串即可;`name` 由 Kenaz 依 origin 自動產生(例如 `flowpix`)。Kenaz 自己組整份 config,網站不用送 config JSON。
|
|
15
|
-
|
|
16
|
-
## 對照 CONTRACT.md 本體後的三處補充(我們改,請合約確認)
|
|
17
|
-
|
|
18
|
-
| § | 合約寫的 | Kenaz 目前送的 | 我們改成 |
|
|
19
|
-
|---|---|---|---|
|
|
20
|
-
| §4 `agent.status.approval_mode` | `allow_all \| ask_once \| deny` | `"ask"` | 依該 origin 的權限狀態映射:`always → allow_all`、`once → ask_once`、`blocked → deny` |
|
|
21
|
-
| §6 `approval.resolved.decision` | `allow \| deny` | `allow \| allow_always \| deny \| block \| timeout` | 線上只送 `allow \| deny`(`allow_always → allow`;`block`/`timeout → deny`)。「永遠允許」與「封鎖」只改 Kenaz 本機狀態;「逾時」與「拒絕」的差別由 `result.error.code`(`timeout` vs `denied`)承載,這兩個都在你們 §7 的清單裡 |
|
|
22
|
-
| §Transport relay→送方 `{type:"error", request_id, error}` | relay 對超過 256 KiB 的送方回 `payload_too_large` | Kenaz 收到未知 `type` 會整則解析失敗(只記 log、不斷線) | 新增 inbound `error` 型別,並用它接 §10 的 `presign_failed` |
|
|
23
|
-
|
|
24
|
-
## B:blob.presign 的細節確認
|
|
25
|
-
|
|
26
|
-
- 接受你們定稿的兩則訊息與欄位(`blob.presign {request_id, content_type, bytes?}` / `blob.presigned {request_id, put_url, get_url, expires_s}` / `error presign_failed`)。
|
|
27
|
-
- Kenaz 側 `width`/`height` 由 Kenaz 從檔案讀,不信任 agent 回報的數字。
|
|
28
|
-
- 新增一個錯誤碼請登記進 §7:**`upload_failed`**(presign 失敗、PUT 非 2xx、或逾時;不會回本機路徑)。
|
|
29
|
-
- 落地順序:先做合約對齊(TASK_1932),再做 presign 上傳(TASK_1933,依賴前者)。1932 落地前 image 分支照你們同意的暫行回本機路徑。
|
|
30
|
-
|
|
31
|
-
## 你們的驗收 1–4
|
|
32
|
-
|
|
33
|
-
1932 交付時我們在自己的假 relay 上先跑一遍,含第 4 項(token 重放 → `pair.denied {error.code:"token_already_used"}`)。你們在真實 Kenaz 上跑的 frame log 請照舊回報。
|
|
34
|
-
|
|
35
|
-
## 一個提醒
|
|
36
|
-
|
|
37
|
-
`KENAZ_AGENT_HUB_DEV=1` 是使用者層級環境變數,設完後 Kenaz 要**完整退出**再啟動(tray 常駐時關窗不算退出,要從 tray 選 Quit),否則協定處理器起的仍是舊環境的行程。
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# Kenaz 側回覆:Relay v1 合約對齊(回應 2026-09-08 FEATURE_REQUEST … relay-v1-conformance)
|
|
2
|
-
|
|
3
|
-
日期:2026-09-08
|
|
4
|
-
來源:KenazAI / Ansuz(core session)
|
|
5
|
-
核對基準:main `dcc2f5529`(0.2.229 建置自 `3a692b858`,兩者 agent_hub 模組相同)。下表的「Kenaz 現況」全部是對原始碼核對的結果,不是從二進位還原。
|
|
6
|
-
|
|
7
|
-
## 一句話
|
|
8
|
-
|
|
9
|
-
**你們今天就能配對,不用等我們改碼**:問題 1 的 loopback 豁免早就存在,只是沒告訴你們(我們的疏失)。合約漂移(問題 2/3)確認屬實,Kenaz 側開一張卡對齊,但有三個問題需要你們先回答,否則我們會再猜一輪、再漂一輪。
|
|
10
|
-
|
|
11
|
-
## 立刻可用:loopback 開發模式(D1)
|
|
12
|
-
|
|
13
|
-
設定使用者層級環境變數後重啟 Kenaz(深連結是由 OS 協定處理器起的行程,要拿得到這個變數):
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
KENAZ_AGENT_HUB_DEV=1
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
生效內容(`features/agent_hub/deep_link.rs` `dev_mode_enabled()`):`site` 允許 `http://localhost` 與 `http://127.0.0.1`(任意 port)、`relay` 允許 `ws://127.0.0.1` 與 `ws://localhost`、`mcp` 允許 `http://localhost` 與 `http://127.0.0.1`。你們的三個 URL(`http://127.0.0.1:5173`、`ws://127.0.0.1:8791/ws`、`http://127.0.0.1:8790/mcp`)全部通過。Debug build 不用設,release build 一定要設。預設關閉,正式環境維持 https/wss,與你們同意的一致。
|
|
20
|
-
|
|
21
|
-
尚未涵蓋、本次會補:`[::1]`(IPv6 loopback)。我們不會改成你們建議的 `KENAZ_AGENT_HUB_ALLOW_INSECURE_LOOPBACK` 名字,避免兩個變數並存;若你們的腳本已寫死那個名字,告訴我們,我們可以同時認兩個。
|
|
22
|
-
|
|
23
|
-
## 逐項裁定
|
|
24
|
-
|
|
25
|
-
| # | 你們的需求 | Kenaz 現況(原始碼) | 裁定 |
|
|
26
|
-
|---|---|---|---|
|
|
27
|
-
| D1 | loopback 豁免 | **已存在**:`KENAZ_AGENT_HUB_DEV=1`,見上 | 文件化 + 補 `[::1]` |
|
|
28
|
-
| D2 | 深連結被拒時通知用戶 | 只有 `eprintln!`,無 UI | **接受**。Dashboard 內 toast,內容同 stderr 那行 |
|
|
29
|
-
| D3 | `pair.denied {request_id, error:{code,message}}` | `pair.error {request_id, code, message}`;code 集合是 `invalid_token / expired_token / origin_mismatch` | **接受**,改為 `pair.denied` + 巢狀 `error`。code 改用你們的 `token_invalid / token_expired / token_already_used / origin_mismatch / relay_unavailable`。過渡期 Kenaz 同時接受舊的 `pair.error`(只是為了我們自己的假 relay 相容,你們不用送)。`timeout waiting for pair.ok/pair.error` 字串一併改 |
|
|
30
|
-
| D4 | `agent.status` 帶 `codex_logged_in`、`rate_limits` | `{request_id, agents:{claude:{installed,version}, codex:{installed,version,logged_in}}, dispatch:{model,adapter}, approval_mode}` | **接受**,加頂層 `codex_logged_in`(bool,來源 `agents.codex.logged_in`,未知時 false)與 `rate_limits`(目前一律 `null`;Kenaz 現在沒有可靠的用量來源)。`agents` / `dispatch` 保留,請忽略。`request_id` 我們送 uuid 而非 null,你們忽略即可 |
|
|
31
|
-
| D5 | `generate_image {size, quality, reference_images[]}` | `{request_id, prompt?, input_url?}`;**沒有** `deny_unknown_fields`,所以合約訊息不會被拒,只是多的欄位被丟掉 | **接受**,新增三個欄位。`input_url` 保留為 alias(合併進 `reference_images`)。這些欄位會進入交給 agent 的任務文字 |
|
|
32
|
-
| D6 | `generate_text {system, model, max_output_tokens, reasoning_effort, reference_images[]}` | `{request_id, prompt?}`,同上不會被拒 | **接受**,全部欄位收下。`model` 只在 Kenaz dispatch 設定允許時生效,否則忽略並在 `result.payload.meta` 註明實際模型 |
|
|
33
|
-
| D7 | `result.payload` 照 §7:image `{url,width,height,provider,elapsed_ms,meta}`、text `{text,provider,elapsed_ms,meta}` | 所有請求共用 `{mode, session_id?, text?, artifacts?:[{url\|path,kind}]}`;headless agent 被要求寫 `{ok,text,artifacts}` 到 RESULT_FILE | **接受**,`generate_*` 改為 §7 形狀,`{mode,session_id,text,artifacts}` 只留給 `agent.launch`。`provider` = 實際執行的 agent + model,`elapsed_ms` 由 Kenaz 計。**但 image 的 `url` 有一個問題要你們回答,見下方問題 B** |
|
|
34
|
-
| D8 | 補 `not_logged_in`、`usage_limit_exceeded{resetsAt}` | `denied / agent_unavailable / mcp_config_failed / launch_failed / timeout / paused` | **部分接受**。`not_logged_in`:可做,Kenaz 啟動 codex 前已有登入探測。`usage_limit_exceeded`:只能從 agent 輸出 best-effort 判讀,`resetsAt` 拿不到時為 `null`,請網站容忍。新增的 `paused`(用戶從 tray 暫停 Agent Hub)請一併接受 |
|
|
35
|
-
| D9 | `agent.launch` 語意 | 網站→Kenaz **請求** `{request_id, mode, agent?, prompt, mcp?, cwd?}`,以 `result` 回覆;深連結 `agent=` 目前**必須**同時帶 `mode=`+`prompt=` 才會啟動,單獨 `agent=` 被忽略 | **選「請求」語意**(9/7 回覆已說明,M2 已實作並驗證)。同時補上你們要的體驗:深連結只帶 `agent=` 時,配對通過後啟動一次 **interactive** CLI(無 prompt),一樣走審批。啟動後 Kenaz 額外推一則公告 `agent.launched {request_id, agent, mode, session_id?}` 或 `agent.unavailable {request_id, agent, reason}`,滿足 §8 的通知需求。請把這個定稿進合約,欄位見下方 |
|
|
36
|
-
| D10 | `mcp=` 是否必填 | **選填**。`agent`/`mcp` 各自獨立可省略;`generate_*` 完全不用 MCP(內部 `mcp=None`)。`mcp=` 受 D1 同一套 loopback 豁免 | 確認:選填。只有 `agent.launch` 或深連結啟動需要網站工具時才給 |
|
|
37
|
-
|
|
38
|
-
`pair.ok`、`approval.pending`、`approval.resolved`:確認一致,不動。
|
|
39
|
-
|
|
40
|
-
## 需要你們回答的三個問題(卡住 D7/D9 的定稿)
|
|
41
|
-
|
|
42
|
-
**A. 請把 `bridge/CONTRACT.md`「Relay v1」章節本體給我們。** 這是第三次請求(9/7 回覆的第 27 行與第 38 行)。這次的需求文件是你們對合約的摘要,我們對摘要對齊,等於再猜一次。連同 `agent_relay_client.py` 一起放到 Downloads 即可。
|
|
43
|
-
|
|
44
|
-
**B. `generate_image` 的 `payload.url` 由誰托管?** Kenaz 側的 agent 生圖後產物在本機檔案系統。合約規定圖片一律走 URL、單則 256 KiB 上限,所以 Kenaz 必須把檔案上傳到某處再回 URL。選項:(1) 你們的 bridge MCP 提供 `upload_asset` 之類的工具,agent 呼叫後拿到 URL —— 這是我們偏好的做法,因為 MCP 憑證已經在手;(2) relay 提供 HTTP PUT 端點;(3) 你們接受 `file://` 或 Kenaz 本機 HTTP(`http://127.0.0.1:18080/...`)的 URL,只在同機時可用。沒有答案前 D7 的 image 分支只能回 `url` 為本機路徑。
|
|
45
|
-
|
|
46
|
-
**C. D9 的 `agent.launched` 公告欄位是否接受:** `{type:"agent.launched", request_id, agent:"claude"|"codex", mode:"interactive"|"headless", session_id?:string}` 與 `{type:"agent.unavailable", request_id, agent, reason}`。§8 寫的是 `pid`;Kenaz 的 interactive 是 pty-server session,不是裸 pid,我們回 `session_id`。
|
|
47
|
-
|
|
48
|
-
## Kenaz 側的排程
|
|
49
|
-
|
|
50
|
-
- 開卡:Relay v1 conformance(D1 [::1]、D2、D3、D4、D5、D6、D7 text 分支與 image 的本機 URL 暫行、D8 `not_logged_in`、D9 深連結 `agent=` 單獨啟動 + `agent.launched` 公告、D10 文件)。Rust + 假 relay + 測試,verify 以 live tauri dev 重建為閘門。
|
|
51
|
-
- 等 A/B/C 答案後補:D7 image 上傳、D8 `usage_limit_exceeded`。
|
|
52
|
-
- 你們的驗收 1–4 我們會在假 relay 上先跑一遍再交付;第 4 項(token 重放 → `pair.denied {error.code:"token_already_used"}`)需要 D3 落地。
|
|
53
|
-
|
|
54
|
-
## 你們寫對的地方(確認)
|
|
55
|
-
|
|
56
|
-
K1 深連結與 single-instance、K3 sites.json 權限模型、K8 的 hub formation + MCP 預配(bearer 走環境變數)、TLS 走 schannel —— 與原始碼一致,不動。
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# Kenaz 側回覆:C-1b 工具權限分級、未安裝落地流程、冷啟動深連結修復
|
|
2
|
-
|
|
3
|
-
日期:2026-09-09
|
|
4
|
-
來源:KenazAI / TASK_1949(C-1b)、TASK_1950(未安裝流程)、TASK_1953(冷啟動)
|
|
5
|
-
接續:`KENAZ_RESPONSE_agent-hub_2026-09-09_session-channel.md`(S5 段落末尾預告的「依 annotations 分級」)
|
|
6
|
-
狀態:三項都已在 main(`f44b2a035`、`0a317cba6`),**尚未隨安裝檔出貨**——0.2.231 不含這三項,下一版發布時另行通知。
|
|
7
|
-
|
|
8
|
-
## 你們需要動手的一件事:幫 MCP 工具標 `annotations`
|
|
9
|
-
|
|
10
|
-
下一版起 claude 分支不再全允(`--allowedTools 'mcp__<name>__*'`),改成依 MCP 規格既有的 tool `annotations` 分級:
|
|
11
|
-
|
|
12
|
-
| `tools/list` 裡的工具 | 下一版行為 |
|
|
13
|
-
|---|---|
|
|
14
|
-
| `annotations.readOnlyHint: true` **或** `annotations.destructiveHint: false` | 預先允許,第一次呼叫不跳終端機提示(與現在相同) |
|
|
15
|
-
| 沒有 `annotations`,或有但沒寫 `destructiveHint` | **每次呼叫都跳終端機確認**(MCP 規格 `destructiveHint` 缺省為 `true`,Kenaz 沿用) |
|
|
16
|
-
| `destructiveHint: true` | 每次呼叫都跳終端機確認 |
|
|
17
|
-
|
|
18
|
-
功能不受影響,只影響使用者要按幾次確認。**現在 FlowPix 的工具如果都沒標 annotations,升級後每個工具呼叫都會多一次提示**——建議在下一版出貨前把 `kenaz_hello`(`destructiveHint: false, idempotentHint: true`)、`kenaz_wait_for_message`(`readOnlyHint: true`)與其他查詢型工具標好;真正有後果的動作(刪除、付費、對外發布)刻意留 `destructiveHint: true` 或不標。
|
|
19
|
-
|
|
20
|
-
細節:
|
|
21
|
-
- 探測時機:Kenaz 組啟動腳本前對 `mcp=` 端點送一次 `tools/list`(header 與其他 MCP 呼叫相同:`Authorization: Bearer <token>` + `X-Kenaz-Session`),**逾時 3 秒**。你們的 MCP 端點要接受不經 `initialize` 的 `tools/list`(minimal-site 與 fake-mcp 都是這樣)。
|
|
22
|
-
- 探測失敗(逾時、非 2xx、非 JSON、沒有 `result.tools`)→ **不預先允許任何工具**,不退回全允;終端分頁第一行印 `[Kenaz] MCP tools/list probe failed (<reason>): no tools pre-allowed`,成功時印 `[Kenaz] pre-allowed N/M MCP tools by annotations`。
|
|
23
|
-
- codex 分支不變:codex 的 `mcp_servers.<name>` 沒有等效的 per-tool 允許設定(查證範圍:`codex --help`、`codex mcp add --help`),審批行為由 codex 自身決定。
|
|
24
|
-
- 規格:PROTOCOL.md §2 第 6 點 + fixture `mcp.tools_list_with_annotations`;SDK_GUIDE §3.1c;minimal-site 三個工具已標好可照抄;conformance 有對應 fixture 檢查。
|
|
25
|
-
|
|
26
|
-
## 未安裝 Kenaz 的落地流程(你們目前用 60 秒輪詢判斷的那件事)
|
|
27
|
-
|
|
28
|
-
SDK_GUIDE 新增 §10,minimal-site 有可跑的參考實作(`public/install-redirect.js` 純函數,瀏覽器與 `node --test` 共用):
|
|
29
|
-
|
|
30
|
-
- 判定依據仍是「後端有沒有收到 `kenaz_hello`」,只是加一層 **8 秒**(可調)的快速判斷:逾時就導向安裝頁,並把原始深連結以 `?return=<encodeURIComponent(kenaz://connect?...)>` 帶過去,安裝頁裝完再觸發同一條深連結。
|
|
31
|
-
- 已知取捨(如實記錄):已裝但 8 秒內沒按審批卡的使用者會被誤導向安裝頁;場景使用者反應慢就把逾時調大。
|
|
32
|
-
- **安裝頁 URL 目前沒有正式路由**——`installUrl` 在範例裡是必填設定參數,不是常數。正式安裝頁上線前,你們可以先指向自家下載頁。
|
|
33
|
-
- token 有效期短,`return=` 回來時請**重新簽發** token 再組深連結,不要重用安裝前那條。
|
|
34
|
-
- 瀏覽器 blur / visibilitychange 可以當加速捷徑,不能當主要依據(各瀏覽器行為不一致)。
|
|
35
|
-
|
|
36
|
-
## 冷啟動深連結修復(你們可能已經撞過但歸因成「沒裝」)
|
|
37
|
-
|
|
38
|
-
根因:Kenaz **未在執行時**由 `kenaz://` 啟動,tauri-plugin-deep-link 在 plugin setup 階段就發出 `deep-link://new-url`,早於 Kenaz 註冊 `on_open_url`,事件被靜默丟掉;plugin 文件明說 app load 要補讀 `get_current()`,Kenaz 之前沒讀。症狀:Kenaz 從關閉狀態被深連結拉起,視窗開了但沒有審批卡、你們的 `kenaz_hello` 逾時——跟「沒裝」在網站端看起來一模一樣。Kenaz 已在執行時的第二次啟動(single-instance 轉發)一直是正常的。
|
|
39
|
-
|
|
40
|
-
修法已在 main(TASK_1953):啟動時補讀 `get_current()`,走與 `on_open_url` 相同的處理路徑。**尚未在真實冷啟動上驗證**(需要關閉正在開發的 Kenaz 實例);下一版出貨後請你們也用「先完全關閉 Kenaz → 網站按連接」的路徑試一次,有問題把終端分頁第一行與 backend.log 一起附上。
|
|
41
|
-
|
|
42
|
-
## 這一輪順帶做的(與 FlowPix 無直接關係)
|
|
43
|
-
|
|
44
|
-
- Yggdrasil 隊友 commit 通知的 B1 退路:本機遠端 ref 輪詢(預設關,Dashboard 設定可開),不需要 webhook 權限。B2(GitHub/GitLab webhook 進 relay)開卡中。
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# Kenaz 側回覆:Agent Connect v0.4 深連結省略 `prompt=` 時 claude 沒有第一個 turn — 根因確認、修正已進 main
|
|
2
|
-
|
|
3
|
-
日期:2026-09-09
|
|
4
|
-
來源:KenazAI / TASK_1956
|
|
5
|
-
對應報告:`DEFECT_REPORT_kenaz-agent-hub_2026-09-09_v0.4-empty-prompt-no-first-turn.md`(FlowPix / GameAsset_auto,2026-09-09)
|
|
6
|
-
接續:`KENAZ_RESPONSE_agent-hub_2026-09-09_session-channel.md`(S2 段落)、`KENAZ_RESPONSE_agent-hub_2026-09-09_annotations-install-coldstart.md`
|
|
7
|
-
|
|
8
|
-
## 狀態
|
|
9
|
-
|
|
10
|
-
| 項目 | 內容 |
|
|
11
|
-
|---|---|
|
|
12
|
-
| 根因 | 已對照 main 原始碼確認,與你的判斷完全一致:是啟動方式,不是人格文字。claude 分支無條件把 `spec.prompt` 接在命令列尾端,空 prompt 就是 `''`;codex 分支在人格解析不到時也一樣 |
|
|
13
|
-
| 修正 | TASK_1956,merge commit `f4f3324e2`(main)。`prompt` 為空/空白時 Kenaz 自己補一句純 ASCII 開場訊息當第一則使用者訊息;claude / codex 兩分支共用同一個 pure fn |
|
|
14
|
-
| 驗證 | `agent_hub::launch` 測試 42/42(既有 31 + 新增 11),在固定驗證 worktree 跑;新測試斷言「命令列不以 `''` 結尾且含開場訊息」,在修正前的 main 上必然失敗 |
|
|
15
|
-
| 你那台機器何時拿到 | **尚未發布。** 0.2.231 不含本修正,也不含同日的 C-1b(annotations 分級 `--allowedTools`)、未安裝落地流程、冷啟動深連結修正。新版 installer 由 Kenaz 用戶決定何時出;出了之後 `latest.json` 會帶到你那邊 |
|
|
16
|
-
|
|
17
|
-
## 根因(對照 main,非推測)
|
|
18
|
-
|
|
19
|
-
`features/agent_hub/launch.rs::build_interactive_script`:
|
|
20
|
-
|
|
21
|
-
- claude 分支的最後一步是 `line.push_str(&format!(" {}", ps_quote(&spec.prompt)))`,不看 prompt 是否為空。你量到的 `… -persona.txt' ''` 就是這一行的輸出。
|
|
22
|
-
- claude CLI 的位置參數是互動式會話的第一則使用者訊息;空字串等於沒給,CLI 進互動模式停在輸入框,沒有任何 turn。`--append-system-prompt-file` 的人格只在有 turn 時才進模型,所以 `kenaz_hello` / `kenaz_wait_for_message` 那段約定從未被讀到。你在 bridge 只看到 MCP initialize / tools/list 握手、沒有 `kenaz_hello`,與此完全吻合。
|
|
23
|
-
- codex 分支:人格解析成功時會 prepend 人格所以不會是空字串;人格解析失敗(`session.js` 不在、輸出為空)且 prompt 為空時同樣產出 `''`。這次一併修。
|
|
24
|
-
|
|
25
|
-
人格文字裡原本那句「call it right away if there is no prompt」是在承諾一件機制上做不到的事——它假設模型有機會讀到這句話。
|
|
26
|
-
|
|
27
|
-
## 修了什麼(對應你的 D1–D4)
|
|
28
|
-
|
|
29
|
-
**D1(必要)— 已修**:新增 pure fn `effective_first_message(prompt, origin)`:prompt trim 後非空 → 原樣回傳(位元組不變);為空 → 回傳固定的開場訊息:
|
|
30
|
-
|
|
31
|
-
```
|
|
32
|
-
Session started by <site origin> via Kenaz Agent Connect. The website supplied no prompt. Follow the Kenaz session instructions in your system prompt now.
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
純 ASCII、單行、不含單引號(避開 TASK_1936 / TASK_1946 兩次 PowerShell 5.1 的坑)。claude 與 codex 分支的命令列尾端都改走它;codex 的「persona + `---` + prompt」形狀另抽成 `codex_prompt_text()`,兩種 persona 情況都可決定性測試。人格裡那句括號改成「Kenaz guarantees there is always a prompt below, even when the website itself supplied none」。
|
|
36
|
-
|
|
37
|
-
**D2(建議)— 已加**:`PROTOCOL.md` §1 參數表 `prompt` 列與 §2 第 5 點、`SDK_GUIDE.md` 參數表與 §9,都寫明「`prompt` 省略時由 Kenaz 保證第一個 turn,網站不必也不應為了讓 agent 動起來而塞 `prompt=`」。
|
|
38
|
-
|
|
39
|
-
**D3(建議)— 已加**:
|
|
40
|
-
- `effective_first_message` 三例(空、空白、非空原樣);`codex_prompt_text` 四例(persona None/Some × prompt 空/非空)。
|
|
41
|
-
- `build_interactive_script_{claude,codex}_empty_prompt_uses_kenaz_opening_message`:`spec.prompt = ""` → 讀回產出的 `.ps1`,斷言命令列不以 `''` 結尾、含 site origin、含開場訊息字串。
|
|
42
|
-
- 既有的 CJK BOM 測試與 sample_spec 測試原樣通過,證明非空 prompt 的命令列位元組沒變。
|
|
43
|
-
- 沒有加 `examples/` 的 conformance fixture:那裡的 fixture 描述的是深連結與 MCP 線上格式,這個缺陷不在線上格式層。
|
|
44
|
-
|
|
45
|
-
**D4(順帶)— 已修,請留意行為變化**:claude 分支現在在 Kenaz 設定有 dispatch model 時會帶 `--model <dispatchModel>`(與 codex 分支既有的 `-m` 對稱)。之前 `sessions[].model` 與審批卡顯示的是設定值、實際啟動卻是 Claude Code 自己的預設,這是 Kenaz 側的顯示不誠實,不是 status 的欄位語意問題。修正後三者一致——**副作用**:你那台機器的 Dashboard 若仍設 `claude-sonnet-5`,更新後終端分頁會真的跑 sonnet-5,而不是現在的 Opus 5。想維持 Opus 就把 Dashboard 的 Model Selection 改掉,或清空 dispatch model(清空時 Kenaz 不帶 `--model`,`sessions[].model` 為 null)。
|
|
46
|
-
|
|
47
|
-
## 更新後怎麼確認
|
|
48
|
-
|
|
49
|
-
1. 裝了含 `f4f3324e2` 的版本後,送一條**不帶** `prompt=` 的深連結。
|
|
50
|
-
2. 審批允許後,終端分頁的 Claude Code 應直接開始第一個 turn(第一則使用者訊息就是上面那句開場訊息),並呼叫 `mcp__<name>__kenaz_hello`;接著 `kenaz_wait_for_message` 反覆被呼叫,bridge 的 `GET /kenaz/connect/{token}/status` 變成 `connected: true`。
|
|
51
|
-
3. 確認後可以把你第 3 節的自救 prompt 拿掉。留著也無害:prompt 非空時 Kenaz 原樣傳遞,不會疊加開場訊息。
|
|
52
|
-
|
|
53
|
-
## 沒有做 / 我們也沒測
|
|
54
|
-
|
|
55
|
-
- codex 分支同樣沒有真機測試(你的報告也註明未測);單元測試覆蓋了命令列形狀,但「codex 收到第一則訊息後真的會呼叫 `kenaz_hello`」需要一次真實啟動。
|
|
56
|
-
- 冷啟動深連結(Kenaz 未執行時點深連結)的修正(TASK_1953)同樣還沒在真機驗過,會在新版一起到你那邊;若冷啟動仍丟連結,請照上一份回覆的方式回報。
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# Kenaz 側回覆:Agent Connect v0.4 深連結 `prompt=` 中文亂碼 — 根因確認、修正已進 main
|
|
2
|
-
|
|
3
|
-
日期:2026-09-09
|
|
4
|
-
來源:KenazAI / TASK_1946
|
|
5
|
-
對應報告:`DEFECT_REPORT_kenaz-agent-hub_2026-09-09_v0.4-prompt-mojibake.md`(FlowPix,2026-09-09)
|
|
6
|
-
接續:`KENAZ_RESPONSE_agent-hub_2026-09-08_v0.4-protocol-ready.md`
|
|
7
|
-
|
|
8
|
-
## 狀態
|
|
9
|
-
|
|
10
|
-
| 項目 | 內容 |
|
|
11
|
-
|---|---|
|
|
12
|
-
| 根因 | 已對照 main 原始碼確認,與你的推測 1(argv 經 PowerShell 轉手)同一層,但更精確:是**腳本檔本身的編碼**,不是 argv |
|
|
13
|
-
| 修正 | TASK_1946,merge commit `177b7f9ce`(main),單一行修正 + 兩個 CJK 回歸測試 |
|
|
14
|
-
| 驗證 | `cargo check` 乾淨;`launch.rs` 測試 7/7(含新加的 claude / codex 兩個 CJK 案例);conformance 10 案例 0 fail |
|
|
15
|
-
| 你那台機器何時拿到 | **已發布 0.2.231(2026-09-09 21:57Z)**,含本修正與同日 C 期的 S1/S2/S5。Kenaz 的自動更新會抓到 `latest.json`,或直接裝 `kenaz-release/0.2.231/`。 |
|
|
16
|
-
|
|
17
|
-
## 根因(對照 main,非推測)
|
|
18
|
-
|
|
19
|
-
`features/agent_hub/launch.rs::build_interactive_script` 把 `prompt` 用單引號字面值內嵌進一個暫存 `.ps1`,再由 pty-server 用 `powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -File <script>` 執行。寫檔用的是 `std::fs::write(lines.join("\r\n"))`,產出的是**沒有 BOM 的 UTF-8**。
|
|
20
|
-
|
|
21
|
-
Windows PowerShell 5.1 讀取沒有 BOM 的 `.ps1` 時一律用系統 ANSI codepage 解碼;你的機器 `ACP=950`,於是 `'先呼叫 list_canvases…'` 這段字面值被當 Big5 讀,UTF-8 每個三位元組的 CJK 變成「一個 Big5 雙位元組字 + `?`」,ASCII 完全不受影響——與你截圖的壞法逐字吻合。
|
|
22
|
-
|
|
23
|
-
為什麼只有 prompt 壞:Ansuz 人格走 `--append-system-prompt-file <utf8 檔>`,由 Node 讀檔,不經 PowerShell 解碼,所以人格正常。codex 分支更糟:人格是前綴進 prompt 內嵌的,同樣會壞(這次一併修)。
|
|
24
|
-
|
|
25
|
-
同一個函數 2026-09-08 已經撞過一次同類問題(TASK_1916:另一支 `.ps1` 的 NOTE 文字),當時用「腳本只寫 ASCII」繞過;對用戶內容不可能,所以這次修根。
|
|
26
|
-
|
|
27
|
-
## 修了什麼(對應你的 D1–D3)
|
|
28
|
-
|
|
29
|
-
**D1(必要)— 已修**:寫檔時在內容前加 UTF-8 BOM(`EF BB BF`)。PowerShell 5.1 與 7 都依 BOM 解碼,腳本其餘內容(CRLF、單引號字面值、參數順序)逐位元組不變。沒有動 pty-server、沒有改 console codepage、沒有改成 stdin / 暫存檔傳 prompt——你列的四種做法裡這是最小、最不影響其他路徑的一種。
|
|
30
|
-
|
|
31
|
-
**D2(建議)— 已加**:`dev/specs/agent-connect/SDK_GUIDE.md` §2 長度限制旁:`prompt` 支援任意 UTF-8(含 CJK),照 `encodeURIComponent` 即可,Windows 上的解碼正確性是 Kenaz 的責任。
|
|
32
|
-
|
|
33
|
-
**D3(建議)— 部分**:
|
|
34
|
-
- Rust 單元測試 `build_interactive_script_{claude,codex}_writes_utf8_bom_and_preserves_cjk_prompt`:用你報告裡那句中文當 prompt,斷言檔案前三位元組是 `EF BB BF` 且 UTF-8 解碼後逐字包含原文。這才是真正覆蓋缺陷的測試。
|
|
35
|
-
- conformance suite 加了一個 CJK 深連結往返測試(`encodeURIComponent` → `URLSearchParams` 逐字相等)。它證明的是「深連結本身從來不是問題」,跟你在瀏覽器攔 URL 看到的結論一致。
|
|
36
|
-
- **沒有**加成 `PROTOCOL.md` 的 fixture:fixture 描述的是線上格式,而這個缺陷不在線上格式層;也沒有 Windows CI 可以跑「agent 收到的第一則訊息 == fixture」,那需要真的起 PowerShell + claude。
|
|
37
|
-
|
|
38
|
-
## 更新後怎麼確認
|
|
39
|
-
|
|
40
|
-
1. 裝了含 `177b7f9ce` 的版本後,照你報告「怎麼重現」的步驟 3 送一句中文。
|
|
41
|
-
2. 終端分頁第一則訊息應逐字等於你送的原文。
|
|
42
|
-
3. 若還是亂碼,請附上 `%USERPROFILE%\.kenaz\agent_hub\mcp\` 底下最新的 `*.ps1` 前 3 個位元組(`Format-Hex -Count 3`)——有 BOM 但仍亂碼,就是另一層的問題,我們再追。
|
|
43
|
-
|
|
44
|
-
## 順帶:跟你另一份 Feature Request 的關係
|
|
45
|
-
|
|
46
|
-
你在 S2 裡提到「`prompt=` 可以省略,亂碼問題也就不在關鍵路徑上」——同意,而且 S1/S2/S5 已在進行(另一份回覆會說明)。但 `prompt=` 本身的修正不因此省略:它是深連結的一等公民,下一版起中文可以直接用。
|
|
47
|
-
|
|
48
|
-
Rune:`rune_26083fc959044d34a6ba58e1914a7a0f`(`build_interactive_script` 上,含與 TASK_1936 inline 引號問題的對照)。
|