kenaz 0.3.21 → 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/commands/Ansuz.md +2 -0
- package/core/.claude/hooks/__tests__/peer-session-fill.test.js +37 -0
- package/core/.claude/hooks/_ansuz-conversation.js +32 -1
- package/core/.claude/hooks/_user-scope.js +1 -1
- package/core/.claude/hooks/core-resolve.js +1 -1
- package/core/.claude/hooks/peer-optin.test.js +74 -0
- package/core/.claude/hooks/peer-session-fill.js +38 -0
- package/core/.claude/hooks/turn-context.js +5 -4
- package/core/.claude/hooks/worktree-create.js +6 -6
- package/core/.claude/hooks/worktree-remove.js +4 -4
- package/core/.claude/settings.json +9 -0
- 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/bifrost/openai/codex-hook-shim.js +21 -4
- package/core/.formation/bifrost/openai/codex-peer-pull.test.js +42 -0
- package/core/.formation/bifrost/provider-launch.js +2 -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 +471 -0
- 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/commands/Ansuz.md +2 -0
- package/core/plugins/kenaz/guidance.md +2 -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 +53 -4
- package/core/plugins/kenaz/scripts/kenaz.test.js +72 -5
- package/core/plugins/kenaz/scripts/ygg.js +40 -4
- package/core/plugins/kenaz/scripts/ygg.test.js +63 -3
- package/core/plugins/kenaz-peer/hooks/register.test.ts +59 -2
- package/core/plugins/kenaz-peer/hooks/register.ts +24 -1
- 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,642 +0,0 @@
|
|
|
1
|
-
# bridge HTTP contract v1 (TASK_96)
|
|
2
|
-
|
|
3
|
-
Field names here are the wire contract -- backend/image_generation.py and
|
|
4
|
-
backend/text_generation.py (the bridge's only clients, over stdlib
|
|
5
|
-
`urllib.request`) and this document must never drift apart. Base URL
|
|
6
|
-
defaults to `http://127.0.0.1:8790`, overridable via `GAMEASSET_BRIDGE_URL`
|
|
7
|
-
on the backend side and `GAMEASSET_BRIDGE_HOST` / `GAMEASSET_BRIDGE_PORT` on
|
|
8
|
-
the bridge side.
|
|
9
|
-
|
|
10
|
-
## `GET /health`
|
|
11
|
-
|
|
12
|
-
```json
|
|
13
|
-
{
|
|
14
|
-
"ok": true,
|
|
15
|
-
"bridge_version": "1.0.0",
|
|
16
|
-
"default_provider": "codex",
|
|
17
|
-
"providers": [
|
|
18
|
-
{"id": "codex", "available": true, "detail": "codex 0.153.4, Logged in using ChatGPT; transport=appserver; usage 34% of 10080min window, resets 2026-09-14T08:33:13+00:00"},
|
|
19
|
-
{"id": "openai", "available": false, "detail": "OPENAI_API_KEY environment variable is not set"}
|
|
20
|
-
]
|
|
21
|
-
}
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
- `codex`'s `available` = `codex --version` exits 0 AND `codex login status`
|
|
25
|
-
reports `Logged in` -- independent of which transport is configured (both
|
|
26
|
-
need the same logged-in CLI).
|
|
27
|
-
- `openai`'s `available` = `OPENAI_API_KEY` has a non-empty value.
|
|
28
|
-
- `codex`'s `detail` (TASK_98 R5) always appends `; transport=<appserver|exec>`
|
|
29
|
-
(`GAMEASSET_BRIDGE_CODEX_TRANSPORT`, default `appserver`); once at least
|
|
30
|
-
one `appserver`-transport call has completed and cached an
|
|
31
|
-
`account/rateLimits/updated` notification, it further appends `; usage
|
|
32
|
-
<usedPercent>% of <windowDurationMins>min window, resets <ISO time>`. The
|
|
33
|
-
usage suffix is absent before any such call, and never appears for the
|
|
34
|
-
`exec` transport (which has no persistent connection to receive the
|
|
35
|
-
notification on).
|
|
36
|
-
|
|
37
|
-
## `POST /v1/image`
|
|
38
|
-
|
|
39
|
-
Request:
|
|
40
|
-
|
|
41
|
-
```json
|
|
42
|
-
{
|
|
43
|
-
"provider": "codex",
|
|
44
|
-
"prompt": "a three-quarter view of the attached garment",
|
|
45
|
-
"size": "1024x1024",
|
|
46
|
-
"quality": "medium",
|
|
47
|
-
"reference_images": ["<base64 PNG>", "..."]
|
|
48
|
-
}
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
`provider` is optional -- omit it (or send `null`) to let the bridge decide
|
|
52
|
-
(see "Provider selection" below).
|
|
53
|
-
|
|
54
|
-
Response (200):
|
|
55
|
-
|
|
56
|
-
```json
|
|
57
|
-
{
|
|
58
|
-
"image_png_b64": "<base64 PNG>",
|
|
59
|
-
"width": 1024,
|
|
60
|
-
"height": 1024,
|
|
61
|
-
"provider": "codex",
|
|
62
|
-
"elapsed_ms": 48213,
|
|
63
|
-
"meta": {"thread_id": "01a07574-...", "transport": "appserver", "rate_limits": {"...": "..."}}
|
|
64
|
-
}
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
`meta` is provider-specific and best-effort -- callers must not depend on
|
|
68
|
-
any particular key being present. For the `codex` provider (TASK_98 R1/R5):
|
|
69
|
-
|
|
70
|
-
- `thread_id` -- the (ephemeral) codex thread this call ran in, both
|
|
71
|
-
transports.
|
|
72
|
-
- `transport` -- `"appserver"` or `"exec"`, whichever transport actually
|
|
73
|
-
ran this call. When `GAMEASSET_BRIDGE_CODEX_TRANSPORT=appserver` (the
|
|
74
|
-
default) but the app-server subprocess could not be spawned or never
|
|
75
|
-
became healthy within 10s, THIS SINGLE CALL falls back to `exec`
|
|
76
|
-
automatically (R6) -- `transport` reads `"exec"` and an additional
|
|
77
|
-
`fallback_reason` key explains why. This is a same-provider transport
|
|
78
|
-
fallback, not the silent `codex`-to-`openai` provider substitution R3
|
|
79
|
-
forbids elsewhere in this document.
|
|
80
|
-
- `rate_limits` -- present only for the `appserver` transport, only once at
|
|
81
|
-
least one `account/rateLimits/updated` notification has been received
|
|
82
|
-
(the same object surfaced in `GET /health`'s usage summary, see above).
|
|
83
|
-
|
|
84
|
-
## `POST /v1/text`
|
|
85
|
-
|
|
86
|
-
Request:
|
|
87
|
-
|
|
88
|
-
```json
|
|
89
|
-
{
|
|
90
|
-
"provider": null,
|
|
91
|
-
"prompt": "describe this garment in under 60 words",
|
|
92
|
-
"system": "",
|
|
93
|
-
"model": "gpt-5.6-sol",
|
|
94
|
-
"max_output_tokens": 4096,
|
|
95
|
-
"reasoning_effort": "auto",
|
|
96
|
-
"reference_images": ["<base64 PNG>"]
|
|
97
|
-
}
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Response (200):
|
|
101
|
-
|
|
102
|
-
```json
|
|
103
|
-
{
|
|
104
|
-
"text": "...",
|
|
105
|
-
"provider": "openai",
|
|
106
|
-
"elapsed_ms": 3120,
|
|
107
|
-
"meta": {"model": "gpt-5.6-sol"}
|
|
108
|
-
}
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
## Provider selection (R3)
|
|
112
|
-
|
|
113
|
-
1. `request.provider`, if given explicitly.
|
|
114
|
-
2. `GAMEASSET_BRIDGE_DEFAULT_PROVIDER` environment variable, if set.
|
|
115
|
-
3. `'codex'`.
|
|
116
|
-
|
|
117
|
-
If the selected provider is not registered, or registered but its `probe()`
|
|
118
|
-
reports `available: false`, the bridge answers `422 provider_unavailable`.
|
|
119
|
-
**It never silently substitutes a different provider** -- a user who asked
|
|
120
|
-
for (or defaulted to) their ChatGPT subscription and got a silent fallback
|
|
121
|
-
to the API-key provider would be burning paid API credits without knowing
|
|
122
|
-
it.
|
|
123
|
-
|
|
124
|
-
## Errors
|
|
125
|
-
|
|
126
|
-
Every non-2xx response is:
|
|
127
|
-
|
|
128
|
-
```json
|
|
129
|
-
{"error": {"code": "provider_unavailable" | "provider_failed" | "provider_timeout" | "invalid_request", "message": "..."}}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
| HTTP status | `code` | Meaning |
|
|
133
|
-
|---|---|---|
|
|
134
|
-
| 422 | `provider_unavailable` | Unknown provider id, or the selected provider's `probe()` failed. |
|
|
135
|
-
| 422 | `invalid_request` | Malformed request body (e.g. a `reference_images` entry that isn't valid base64). |
|
|
136
|
-
| 502 | `provider_failed` | The provider ran but the generation itself failed (process error, empty response, moderation refusal, ...). |
|
|
137
|
-
| 504 | `provider_timeout` | The provider exceeded its own timeout ceiling (image: 300s, text: 180s for the codex provider; the openai provider's SDK client is configured with a 180s timeout for both). |
|
|
138
|
-
|
|
139
|
-
`message` never contains `OPENAI_API_KEY` or any other secret/token value.
|
|
140
|
-
|
|
141
|
-
## CORS (R10)
|
|
142
|
-
|
|
143
|
-
Allowed origins: `GAMEASSET_BRIDGE_ALLOWED_ORIGINS` (comma-separated),
|
|
144
|
-
default `http://localhost:5173,http://127.0.0.1:5173`. Every preflight
|
|
145
|
-
(`OPTIONS`) response additionally carries
|
|
146
|
-
`Access-Control-Allow-Private-Network: true` (Chrome's Private Network
|
|
147
|
-
Access check) -- header only, no relay/queueing logic; a future
|
|
148
|
-
cloud-hosted page proxying through this bridge is a separate card.
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
|
-
# Agent hub v1 (TASK_99)
|
|
153
|
-
|
|
154
|
-
Turns the bridge into a local relay between a CLI agent (Codex / Claude
|
|
155
|
-
Code) and the FlowPix canvas tab(s) the user has open in their browser. The
|
|
156
|
-
bridge never touches the backend's saved-workflow API for any of this --
|
|
157
|
-
every tool call below acts on a tab's LIVE, possibly-unsaved, in-page graph
|
|
158
|
-
(the page-side executor is a separate card; this document is its contract).
|
|
159
|
-
|
|
160
|
-
Implementation: `bridge/agent_hub/hub.py` (session registry + addressing +
|
|
161
|
-
request/response relay), `bridge/agent_hub/auth.py` (token + `/mcp` guard),
|
|
162
|
-
`bridge/agent_hub/tools.py` (the MCP tool set below), wired into
|
|
163
|
-
`bridge/main.py`.
|
|
164
|
-
|
|
165
|
-
## `/mcp` -- CLI agent entry point
|
|
166
|
-
|
|
167
|
-
A streamable-HTTP MCP server (python `mcp>=2.1`, `MCPServer`), mounted into
|
|
168
|
-
this same FastAPI app on the same port (8790 by default). Every request
|
|
169
|
-
must carry `Authorization: Bearer <token>`, or the guard middleware answers
|
|
170
|
-
before the request reaches MCP:
|
|
171
|
-
|
|
172
|
-
| Condition | Response |
|
|
173
|
-
|---|---|
|
|
174
|
-
| `Origin` header present at all | `403 {"error":{"code":"forbidden","message":"..."}}` -- this path is for local non-browser programs only; a real browser page always sends `Origin` cross-origin. |
|
|
175
|
-
| Missing/invalid `Authorization: Bearer <token>` | `401 {"error":{"code":"unauthorized","message":"..."}}` |
|
|
176
|
-
|
|
177
|
-
**Token** resolution (`bridge/agent_hub/auth.get_agent_token`): env var
|
|
178
|
-
`GAMEASSET_BRIDGE_AGENT_TOKEN`, else `storage/bridge/agent_token.txt`
|
|
179
|
-
(created with a fresh 32-hex-char token on first read if neither exists).
|
|
180
|
-
Never logged, never included in any error message.
|
|
181
|
-
|
|
182
|
-
At real ASGI startup the bridge prints three ready-to-paste setup steps
|
|
183
|
-
(TASK_102 -- a two-line banner that never told the user to set
|
|
184
|
-
`FLOWPIX_MCP_TOKEN` produced codex's own "Environment variable
|
|
185
|
-
FLOWPIX_MCP_TOKEN ... is not set" error the moment the user tried step 2):
|
|
186
|
-
|
|
187
|
-
```
|
|
188
|
-
1) 設定 token 環境變數
|
|
189
|
-
PowerShell: setx FLOWPIX_MCP_TOKEN "<token>"
|
|
190
|
-
bash: export FLOWPIX_MCP_TOKEN="<token>"
|
|
191
|
-
2) 接上 Codex CLI
|
|
192
|
-
PowerShell: codex mcp add flowpix --url http://127.0.0.1:<port>/mcp --bearer-token-env-var FLOWPIX_MCP_TOKEN
|
|
193
|
-
bash: codex mcp add flowpix --url http://127.0.0.1:<port>/mcp --bearer-token-env-var FLOWPIX_MCP_TOKEN
|
|
194
|
-
3) 接上 Claude Code
|
|
195
|
-
PowerShell: claude mcp add --transport http flowpix http://127.0.0.1:<port>/mcp --header "Authorization: Bearer <token>"
|
|
196
|
-
bash: claude mcp add --transport http flowpix http://127.0.0.1:<port>/mcp --header 'Authorization: Bearer <token>'
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
Shell correctness (TASK_102 R4): single quotes are NOT shell quoting in
|
|
200
|
-
cmd.exe or PowerShell -- pasting the old single-quoted `claude mcp add`
|
|
201
|
-
line there sent claude a literal `Bearer` argument with the quotes and
|
|
202
|
-
token stripped off, and claude answered `Invalid header format: "Bearer".
|
|
203
|
-
Expected format: "Header-Name: value"`. Double quotes ARE valid quoting in
|
|
204
|
-
cmd.exe, PowerShell **and** bash/zsh/sh, so every `powershell` variant
|
|
205
|
-
above uses double quotes (safe to paste into cmd.exe too); only the `bash`
|
|
206
|
-
variant still uses single quotes.
|
|
207
|
-
|
|
208
|
-
**Do not use `--dangerously-bypass-approvals-and-sandbox` for normal use.**
|
|
209
|
-
It exists only so this card's own automated test (AC5) can drive `codex
|
|
210
|
-
exec` non-interactively against a throwaway fake canvas and an empty
|
|
211
|
-
directory; a real CLI agent session should let its OWN approval mechanism
|
|
212
|
-
gate `run_workflow` (see below) -- the bridge does not gate it a second
|
|
213
|
-
time.
|
|
214
|
-
|
|
215
|
-
**Client timeout trap (TASK_106)**: a python `mcp` client built by wrapping
|
|
216
|
-
its own `httpx2.AsyncClient(headers={"Authorization": ...})` for the Bearer
|
|
217
|
-
header -- instead of `mcp.shared._httpx_utils.create_mcp_http_client()`,
|
|
218
|
-
which sets an SSE-friendly `read=300s` -- silently inherits `httpx2`'s bare
|
|
219
|
-
default `Timeout(5.0)`. Any tool call whose SSE response takes longer than
|
|
220
|
-
5s to arrive (e.g. `get_output`, whose own server-side timeout is 60s --
|
|
221
|
-
see the `canvas_timeout` row in the Errors table below) then gets its
|
|
222
|
-
connection torn down by the CLIENT itself, surfacing as `mcp`'s own
|
|
223
|
-
"SSE stream ended without a response" -- indistinguishable, from the
|
|
224
|
-
agent's side, from the bridge actually dropping the response. Any client
|
|
225
|
-
constructed here (or in a script driving this bridge) that adds its own
|
|
226
|
-
`headers=` MUST also pass an explicit `timeout=httpx2.Timeout(30.0,
|
|
227
|
-
read=900.0)` (or otherwise route through `create_mcp_http_client`) so a
|
|
228
|
-
long-running tool's own timeout error (`canvas_timeout`) has a chance to
|
|
229
|
-
reach the client before the client's own read timeout does. (TASK_107:
|
|
230
|
-
`run_workflow` itself no longer runs long enough to hit this trap -- it now
|
|
231
|
-
answers as soon as the job is accepted, same shape as a quick edit -- but
|
|
232
|
-
the trap still applies to any tool whose SSE response can legitimately take
|
|
233
|
-
more than 5s, `get_output` included.)
|
|
234
|
-
|
|
235
|
-
## `GET /agent/setup`
|
|
236
|
-
|
|
237
|
-
CORS-scoped like every other non-`/mcp` route (`GAMEASSET_BRIDGE_ALLOWED_ORIGINS`).
|
|
238
|
-
Feeds the editor's connection panel:
|
|
239
|
-
|
|
240
|
-
```json
|
|
241
|
-
{
|
|
242
|
-
"mcp_url": "http://127.0.0.1:8790/mcp",
|
|
243
|
-
"token": "<32 hex chars>",
|
|
244
|
-
"steps": [
|
|
245
|
-
{
|
|
246
|
-
"id": "set_token",
|
|
247
|
-
"title": "設定 token 環境變數",
|
|
248
|
-
"powershell": "setx FLOWPIX_MCP_TOKEN \"<token>\"",
|
|
249
|
-
"bash": "export FLOWPIX_MCP_TOKEN=\"<token>\"",
|
|
250
|
-
"note": "PowerShell(setx):設定後只對之後開啟的新終端機生效,本視窗要重開;Bash(export):只在目前這個 shell session 有效,要寫進 ~/.bashrc(或 ~/.zshrc)才能持久。"
|
|
251
|
-
},
|
|
252
|
-
{
|
|
253
|
-
"id": "codex_add",
|
|
254
|
-
"title": "接上 Codex CLI",
|
|
255
|
-
"powershell": "codex mcp add flowpix --url http://127.0.0.1:8790/mcp --bearer-token-env-var FLOWPIX_MCP_TOKEN",
|
|
256
|
-
"bash": "codex mcp add flowpix --url http://127.0.0.1:8790/mcp --bearer-token-env-var FLOWPIX_MCP_TOKEN"
|
|
257
|
-
},
|
|
258
|
-
{
|
|
259
|
-
"id": "claude_add",
|
|
260
|
-
"title": "接上 Claude Code",
|
|
261
|
-
"powershell": "claude mcp add --transport http flowpix http://127.0.0.1:8790/mcp --header \"Authorization: Bearer <token>\"",
|
|
262
|
-
"bash": "claude mcp add --transport http flowpix http://127.0.0.1:8790/mcp --header 'Authorization: Bearer <token>'"
|
|
263
|
-
}
|
|
264
|
-
],
|
|
265
|
-
"commands": {
|
|
266
|
-
"codex": "codex mcp add flowpix --url http://127.0.0.1:8790/mcp --bearer-token-env-var FLOWPIX_MCP_TOKEN",
|
|
267
|
-
"claude_code": "claude mcp add --transport http flowpix http://127.0.0.1:8790/mcp --header \"Authorization: Bearer <token>\""
|
|
268
|
-
},
|
|
269
|
-
"connected_canvases": [
|
|
270
|
-
{"session_id": "...", "tab_id": "...", "workflow_name": "...", "workflow_id": null, "dirty": false, "running": false}
|
|
271
|
-
]
|
|
272
|
-
}
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
`steps` (TASK_102) is the panel's actual data source -- an ordered array,
|
|
276
|
-
`set_token` first, with the token already substituted into every command
|
|
277
|
-
(nothing left for the user to fill in themselves). `commands` is a legacy
|
|
278
|
-
field kept for backward compatibility (TASK_100); `claude_code` there was
|
|
279
|
-
switched to the same double-quoted form as `steps.claude_add.powershell`
|
|
280
|
-
(TASK_102 R4) since double quotes work in every shell this field might be
|
|
281
|
-
pasted into.
|
|
282
|
-
|
|
283
|
-
## `/ws/canvas` -- FlowPix tab entry point
|
|
284
|
-
|
|
285
|
-
A WebSocket endpoint. One connection per browser tab; the page connects,
|
|
286
|
-
not the bridge. Origin is checked BEFORE `accept()`:
|
|
287
|
-
|
|
288
|
-
- Origin missing, or not in `GAMEASSET_BRIDGE_ALLOWED_ORIGINS` -> the
|
|
289
|
-
connection is accepted then immediately closed with code `1008` (policy
|
|
290
|
-
violation) -- no `welcome` is ever sent. (An equivalent pre-accept HTTP
|
|
291
|
-
403 denial is also acceptable to a client; the bridge currently always
|
|
292
|
-
uses accept-then-close because it does not depend on the ASGI server
|
|
293
|
-
advertising the websocket-denial-response extension.)
|
|
294
|
-
- Origin allowed -> accepted, and the tab must send `hello` as its first
|
|
295
|
-
message.
|
|
296
|
-
|
|
297
|
-
**Handshake:**
|
|
298
|
-
|
|
299
|
-
```
|
|
300
|
-
tab -> bridge: {"type": "hello", "tab_id": "<string>", "workflow_name": "<string>", "workflow_id": "<string>|null", "client_version": "<string>", "page_id": "<string>|null"}
|
|
301
|
-
bridge -> tab: {"type": "welcome", "session_id": "<string>"}
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
`page_id` (TASK_103, optional) identifies which BROWSER PAGE this tab
|
|
305
|
-
belongs to -- every tab a single page opens (see `create_canvas` below)
|
|
306
|
-
sends the SAME `page_id` in its own hello (AgentBridgeClient.ts computes it
|
|
307
|
-
once, module-level, and every AgentBridgeClient instance on that page reads
|
|
308
|
-
it). Omitted/`null` is accepted (an older client, or a test fixture) and
|
|
309
|
-
simply never groups with anything.
|
|
310
|
-
|
|
311
|
-
Anything other than `{"type": "hello", ...}` as the first message closes
|
|
312
|
-
the connection (code `1008`) without a `welcome`.
|
|
313
|
-
|
|
314
|
-
**Re-addressing** (the tab changed which workflow it shows, without
|
|
315
|
-
reconnecting):
|
|
316
|
-
|
|
317
|
-
```
|
|
318
|
-
tab -> bridge: {"type": "state", "workflow_name": "<string>", "workflow_id": "<string>|null", "dirty": <bool>, "running": <bool>}
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
Each field is optional and merged into the session (omitted fields keep
|
|
322
|
-
their previous value).
|
|
323
|
-
|
|
324
|
-
One session per connection; a session is removed the instant its
|
|
325
|
-
connection closes (any tool call still in flight for it fails immediately
|
|
326
|
-
with `canvas_disconnected` instead of waiting out its timeout).
|
|
327
|
-
|
|
328
|
-
## Tool-call relay protocol (R4)
|
|
329
|
-
|
|
330
|
-
```
|
|
331
|
-
bridge -> tab: {"type": "call", "request_id": "<string>", "tool": "<string>", "args": {...}}
|
|
332
|
-
tab -> bridge: {"type": "result", "request_id": "<string>", "ok": true, "result": <any>}
|
|
333
|
-
| {"type": "result", "request_id": "<string>", "ok": false, "error": {"code": "<string>", "message": "<string>"}}
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
- `request_id` is a fresh random id per call (never reused), so multiple
|
|
337
|
-
calls to the same tab may be in flight concurrently; the bridge matches
|
|
338
|
-
each `result` back to its own caller by `request_id` alone (never "the
|
|
339
|
-
most recent call").
|
|
340
|
-
- Timeout: 30s for every tool except `get_output` (60s). On timeout the
|
|
341
|
-
bridge answers the MCP caller with `canvas_timeout` (see Errors below);
|
|
342
|
-
it does NOT resend the call, and a result that arrives after the timeout
|
|
343
|
-
is silently dropped.
|
|
344
|
-
- `args` never includes `workflow` -- that field only selects WHICH tab
|
|
345
|
-
the call is delivered to (see Addressing below); the tab already knows
|
|
346
|
-
its own identity.
|
|
347
|
-
|
|
348
|
-
## MCP tool set v1
|
|
349
|
-
|
|
350
|
-
Every tool's first argument is `workflow: str` (a `workflow_name` or a
|
|
351
|
-
`session_id` -- see Addressing) EXCEPT `list_canvases` (takes none) and
|
|
352
|
-
`create_canvas` (takes `name: str` instead -- there is no canvas yet to
|
|
353
|
-
address).
|
|
354
|
-
`args` sent to the tab is exactly the tool's OTHER arguments, as shown per
|
|
355
|
-
tool below.
|
|
356
|
-
|
|
357
|
-
| Tool | Args to tab | Result (from tab, via MCP) |
|
|
358
|
-
|---|---|---|
|
|
359
|
-
| `list_canvases()` | -- (not forwarded; answered by the bridge itself) | `[{"session_id", "tab_id", "workflow_name", "workflow_id", "dirty", "running", "page_id"}, ...]` |
|
|
360
|
-
| `create_canvas(name)` | `{"name"}` -- forwarded to the MOST RECENTLY CONNECTED session (see below), not to an addressed `workflow` | `{"session_id", "tab_id", "workflow_name"}` for the BRAND-NEW tab |
|
|
361
|
-
| `focus_canvas(workflow)` | `{}` | `{"tab_id", "workflow_name"}` |
|
|
362
|
-
| `get_canvas(workflow)` | `{}` | `{"nodes": [{"id","type","params","position","status","error"}, ...], "edges": [...]}` |
|
|
363
|
-
| `list_node_types(workflow)` | `{}` | `[{"type_id","display_name","inputs","outputs","params": [{"name","type","default","options"?,"min"?,"max"?}]}]` |
|
|
364
|
-
| `add_node(workflow, type_id, params=None, position=None)` | `{"type_id","params","position"}` | `{"node_id": "<string>"}` |
|
|
365
|
-
| `connect_nodes(workflow, source_node, source_port, target_node, target_port)` | `{"source_node","source_port","target_node","target_port"}` | `{}` (or any tab-defined ack) |
|
|
366
|
-
| `set_params(workflow, node_id, params)` | `{"node_id","params"}` | `{}` |
|
|
367
|
-
| `delete_node(workflow, node_id)` | `{"node_id"}` | `{}` |
|
|
368
|
-
| `save_workflow(workflow)` | `{}` | `{"workflow_id": "<string>"}` |
|
|
369
|
-
| `run_workflow(workflow, ignore_cache=False)` (TASK_107: returns as soon as the job is ACCEPTED, not when it finishes -- poll `get_job` for the rest) | `{"ignore_cache"}` | `{"job_id": "<string>"}` |
|
|
370
|
-
| `get_job(workflow, job_id)` | `{"job_id"}` | `{"status": "<string>", "nodes": {"<node_id>": {"status","error"}}}` |
|
|
371
|
-
| `get_output(workflow, node_id, port=None)` | `{"node_id","port"}` | see below |
|
|
372
|
-
|
|
373
|
-
**`get_output`'s result shape from the tab** (TN5 -- the ONLY tool whose
|
|
374
|
-
tab-side result is itself typed, because the bridge must convert it into
|
|
375
|
-
real MCP content, not just relay JSON):
|
|
376
|
-
|
|
377
|
-
```json
|
|
378
|
-
{"kind": "image", "mime_type": "image/png", "data_b64": "<base64 PNG>"}
|
|
379
|
-
```
|
|
380
|
-
or
|
|
381
|
-
```json
|
|
382
|
-
{"kind": "text", "text": "<string>"}
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
The bridge turns `kind:"image"` into MCP `ImageContent(type="image",
|
|
386
|
-
mimeType, data=<the same base64>)` -- the agent sees a real image, never a
|
|
387
|
-
base64 string dressed up as text. `kind:"text"` becomes the tool's plain
|
|
388
|
-
text result.
|
|
389
|
-
|
|
390
|
-
## `create_canvas` protocol (TASK_103 R1/TN2)
|
|
391
|
-
|
|
392
|
-
`create_canvas` has no `workflow` to address by -- there is no canvas yet.
|
|
393
|
-
Instead:
|
|
394
|
-
|
|
395
|
-
1. The bridge picks the single MOST RECENTLY CONNECTED `/ws/canvas` session
|
|
396
|
-
(regardless of `workflow_name`/`page_id`) and forwards `{"tool":
|
|
397
|
-
"create_canvas", "args": {"name": name}}` to it, exactly like any other
|
|
398
|
-
tool call. Zero sessions connected at all -> `no_canvas` (the bridge
|
|
399
|
-
cannot open a browser tab on its own).
|
|
400
|
-
2. That tab opens a brand-new, empty tab named `name` and switches its own
|
|
401
|
-
UI to it, then answers the call with `{"tab_id": "<the new tab's id>"}`.
|
|
402
|
-
A tab named `name` already open -> the tab answers `{"ok": false,
|
|
403
|
-
"error": {"code": "canvas_exists", "message": "..."}}` instead (passed
|
|
404
|
-
through to the agent like any other tab-reported error -- see Errors).
|
|
405
|
-
3. The NEW tab's own `AgentBridgeClient` connects and sends its own `hello`
|
|
406
|
-
(`tab_id` = the id from step 2, `page_id` = the SAME page_id as every
|
|
407
|
-
other tab on that page) like any ordinary tab open.
|
|
408
|
-
4. The bridge waits (`GAMEASSET_BRIDGE_CREATE_CANVAS_HELLO_TIMEOUT_S`,
|
|
409
|
-
default 5s) for that exact `tab_id` to register a session, then answers
|
|
410
|
-
the MCP call with `{"session_id", "tab_id", "workflow_name"}` for the
|
|
411
|
-
NEW session. No hello within the window -> `canvas_timeout`.
|
|
412
|
-
|
|
413
|
-
## Addressing (R6)
|
|
414
|
-
|
|
415
|
-
Applies to every tool that takes a `workflow` argument -- i.e. every tool
|
|
416
|
-
except `list_canvases` and `create_canvas` (see above, its own protocol
|
|
417
|
-
section). `focus_canvas` uses this SAME resolution, unlike `create_canvas`.
|
|
418
|
-
|
|
419
|
-
`workflow` is resolved against every currently-connected `/ws/canvas`
|
|
420
|
-
session, in this order:
|
|
421
|
-
|
|
422
|
-
1. **Zero canvases connected at all** -> `no_canvas`, regardless of what
|
|
423
|
-
`workflow` was. The agent must ask the human to open FlowPix and this
|
|
424
|
-
workflow in their browser -- it must NEVER fall back to editing the
|
|
425
|
-
backend's saved workflow file.
|
|
426
|
-
2. `workflow` equals a connected session's `session_id` exactly -> that
|
|
427
|
-
session (no name lookup needed).
|
|
428
|
-
3. Otherwise, exact match against every connected session's
|
|
429
|
-
`workflow_name`:
|
|
430
|
-
- 0 matches -> `canvas_not_found`, message lists the `workflow_name`s
|
|
431
|
-
that ARE currently connected.
|
|
432
|
-
- 1 match -> that session.
|
|
433
|
-
- >1 matches (two tabs share a workflow name) -> `ambiguous_canvas`,
|
|
434
|
-
message lists the matching sessions' `session_id`s -- retry with one
|
|
435
|
-
of those as `workflow` (case 2).
|
|
436
|
-
|
|
437
|
-
## Errors
|
|
438
|
-
|
|
439
|
-
Every failure raised by a tool is an MCP tool error (`is_error: true`)
|
|
440
|
-
whose text content IS `json.dumps({"code": "<code>", "message": "<string>"})`
|
|
441
|
-
-- but **what the calling agent actually receives is not that raw JSON
|
|
442
|
-
string**. The `mcp` python SDK (and, empirically, every client built on it)
|
|
443
|
-
prefixes a tool error's text with `Error executing tool <name>: ` before the
|
|
444
|
-
JSON object, e.g.:
|
|
445
|
-
|
|
446
|
-
```
|
|
447
|
-
Error executing tool set_params: {"code": "invalid_params", "message": "unknown param 'sizee' for text_prompt"}
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
**A reader (TASK_100's frontend executor included, and any agent-side code
|
|
451
|
-
parsing this) must locate and parse the `{...}` object embedded in the
|
|
452
|
-
text, never `json.loads()` the whole string** -- the exact wording of the
|
|
453
|
-
`Error executing tool <name>: ` prefix is the MCP SDK's own, not this
|
|
454
|
-
bridge's, and is not part of this contract (do not depend on its exact
|
|
455
|
-
text, only on there being a JSON object with `code`/`message` keys
|
|
456
|
-
somewhere in the string). `bridge/agent_hub/tools.py`'s tests locate it
|
|
457
|
-
with a substring check (`'"code": "<code>"' in text`), not a full parse.
|
|
458
|
-
|
|
459
|
-
| `code` | Meaning |
|
|
460
|
-
|---|---|
|
|
461
|
-
| `no_canvas` | No `/ws/canvas` session is connected at all. |
|
|
462
|
-
| `canvas_not_found` | `workflow` matched no connected `session_id` or `workflow_name`. |
|
|
463
|
-
| `ambiguous_canvas` | `workflow` matched more than one connected `workflow_name`. |
|
|
464
|
-
| `canvas_timeout` | The addressed tab did not send a `result` within the call's timeout (30s; 60s for `get_output`; 30s for `run_workflow` too, TASK_107 -- its page-side handler now answers as soon as the job is ACCEPTED, the same shape/duration as a quick edit, so it shares the plain default value even though it keeps its own override knob; overridable in tests via `GAMEASSET_BRIDGE_CALL_TIMEOUT_S` / `GAMEASSET_BRIDGE_GET_OUTPUT_TIMEOUT_S` / `GAMEASSET_BRIDGE_RUN_WORKFLOW_TIMEOUT_S`). |
|
|
465
|
-
| `canvas_disconnected` | The tab's connection closed (or a send to it failed) while a call was in flight. |
|
|
466
|
-
| `no_output` | (tab-reported) the node has not produced output yet. |
|
|
467
|
-
| `tool_failed` | Generic fallback ONLY if a tab's `{"ok": false, "error": {...}}` result is missing `code`/`message` entirely. |
|
|
468
|
-
| *(tab-defined)* | Any other `code`/`message` a tab's `{"ok": false, "error": {...}}` result reports (e.g. `invalid_params`, `invalid_connection`) is passed through UNCHANGED -- this is how the agent learns WHY an edit was rejected, not just that it was. Covered by `test_tab_reported_error_passes_through` and mutation arm M7 (cutting this passthrough is caught). |
|
|
469
|
-
|
|
470
|
-
Never falls back to the backend's saved-workflow API for any of these --
|
|
471
|
-
that would silently act on stale data instead of surfacing the error to
|
|
472
|
-
the agent (R6).
|
|
473
|
-
|
|
474
|
-
---
|
|
475
|
-
|
|
476
|
-
# Relay v1 (TASK_105)
|
|
477
|
-
|
|
478
|
-
**This section is the wire contract Kenaz's Rust implementation targets** --
|
|
479
|
-
see `FEATURE_REQUEST_kenaz-agent-hub_2026-09-07.md` (K1-K8) in the kenaz-core
|
|
480
|
-
repo for the product-level feature list this protocol serves. Field names
|
|
481
|
-
below MUST NOT drift between the three spike implementations
|
|
482
|
-
(`spikes/relay_spike/relay.mjs`, `bridge/agent_relay_client.py`,
|
|
483
|
-
`backend/jobs.py`'s `RelaySiteClient`) without updating this document first
|
|
484
|
-
-- `test_relay_contract.py` asserts all three agree with the JSON examples
|
|
485
|
-
here (AC6).
|
|
486
|
-
|
|
487
|
-
## Why this exists (R4/K2)
|
|
488
|
-
|
|
489
|
-
The cloud website/backend never holds the user's AI credentials. Instead a
|
|
490
|
-
website's "連接 Kenaz" button opens a `kenaz://connect?...` deep link that
|
|
491
|
-
wakes the user's own local Kenaz; Kenaz then dials OUT to a relay server
|
|
492
|
-
(firewall-friendly -- the user's machine never needs an inbound port), and
|
|
493
|
-
every AI generation the website asks for is forwarded through that relay to
|
|
494
|
-
Kenaz, which runs it against the user's own ChatGPT/Codex subscription and
|
|
495
|
-
asks the user to approve it. Web3 "connect wallet" UX: connect once, approve
|
|
496
|
-
per action (or "always allow this site").
|
|
497
|
-
|
|
498
|
-
## Transport
|
|
499
|
-
|
|
500
|
-
One WS/WSS endpoint per relay process (this spike: `ws://127.0.0.1:<port>/ws`;
|
|
501
|
-
a real deployment would put this behind TLS). Every frame is UTF-8 JSON, one
|
|
502
|
-
JSON object per frame, with at least a `"type"` string field. Most also carry
|
|
503
|
-
`"request_id"` (string) that pairs a request with its response(s); a handful
|
|
504
|
-
of unsolicited pushes carry `"request_id": null`.
|
|
505
|
-
|
|
506
|
-
**Size cap (R2)**: any single frame whose UTF-8 byte length exceeds
|
|
507
|
-
**262144 bytes (256 KiB)** is rejected by the relay without being forwarded
|
|
508
|
-
-- this is why images and other large payloads travel as object-storage URLs
|
|
509
|
-
(`reference_images` entries, a `result.payload.url`), never inline base64. If
|
|
510
|
-
the oversized frame carried a `request_id`, the relay answers the SENDER
|
|
511
|
-
(not the intended recipient) with `{"type":"error","request_id":<id>,
|
|
512
|
-
"error":{"code":"payload_too_large","message":"<n> bytes exceeds the 256KB
|
|
513
|
-
relay limit"}}`; a `request_id`-less oversized frame is simply dropped and
|
|
514
|
-
logged. The relay logs every frame's direction/type/byte length (JSONL) so a
|
|
515
|
-
run can prove after the fact that nothing crossed the cap (AC1).
|
|
516
|
-
|
|
517
|
-
## Roles
|
|
518
|
-
|
|
519
|
-
- **site** -- the cloud backend acting on behalf of one website/session
|
|
520
|
-
(`backend/jobs.py`'s `RelaySiteClient` in this spike; a real deployment
|
|
521
|
-
would run this inside FlowPix's own backend process).
|
|
522
|
-
- **agent** -- Kenaz (or, in this spike, `bridge/agent_relay_client.py`
|
|
523
|
-
standing in as a "fake Kenaz").
|
|
524
|
-
|
|
525
|
-
A connection's role is fixed by its FIRST message: `site.hello` makes it a
|
|
526
|
-
site connection; `pair.begin` makes it an agent connection (an agent has no
|
|
527
|
-
separate hello step -- `pair.begin` serves both purposes).
|
|
528
|
-
|
|
529
|
-
## 1. Site handshake
|
|
530
|
-
|
|
531
|
-
```json
|
|
532
|
-
site -> relay: {"type": "site.hello", "request_id": "<id>", "origin": "<site origin, e.g. https://flowpix.app>"}
|
|
533
|
-
relay -> site: {"type": "site.ready", "request_id": "<id>", "site_session_id": "<string>"}
|
|
534
|
-
```
|
|
535
|
-
|
|
536
|
-
## 2. Pairing token (one-time, 60s TTL, origin-bound)
|
|
537
|
-
|
|
538
|
-
```json
|
|
539
|
-
site -> relay: {"type": "token.mint", "request_id": "<id>", "agent": "claude" | "codex" | null}
|
|
540
|
-
relay -> site: {"type": "token.minted", "request_id": "<id>", "token": "<32 hex chars>", "ttl_s": 60}
|
|
541
|
-
```
|
|
542
|
-
|
|
543
|
-
The token is bound to `(site_session_id, origin, agent)` at mint time and is
|
|
544
|
-
**consumed the instant a `pair.begin` referencing it is processed** --
|
|
545
|
-
regardless of whether that attempt succeeds -- so a token can only ever be
|
|
546
|
-
tried once, full stop (AC3: a stolen token cannot be retried against a
|
|
547
|
-
different origin after a first failed guess). The site backend builds the
|
|
548
|
-
deep link from this response:
|
|
549
|
-
|
|
550
|
-
```
|
|
551
|
-
kenaz://connect?site=<url-encoded origin>&token=<token>&relay=<url-encoded relay ws url>&agent=<claude|codex>
|
|
552
|
-
```
|
|
553
|
-
|
|
554
|
-
## 3. Agent pairing
|
|
555
|
-
|
|
556
|
-
```json
|
|
557
|
-
agent -> relay: {"type": "pair.begin", "request_id": "<id>", "token": "<token>", "site_origin": "<origin>"}
|
|
558
|
-
relay -> agent: {"type": "pair.ok", "request_id": "<id>", "session_credential": "<string>", "site_origin": "<origin>"}
|
|
559
|
-
| {"type": "pair.denied", "request_id": "<id>", "error": {"code": "token_invalid" | "token_expired" | "token_already_used" | "origin_mismatch" | "relay_unavailable", "message": "<string>"}}
|
|
560
|
-
relay -> site (pair.ok only): {"type": "agent.connected", "request_id": null, "agent_session_id": "<string>"}
|
|
561
|
-
```
|
|
562
|
-
|
|
563
|
-
`origin_mismatch`: `site_origin` in `pair.begin` does not equal the origin the
|
|
564
|
-
token was minted against. `relay_unavailable`: the token's site session
|
|
565
|
-
already disconnected.
|
|
566
|
-
|
|
567
|
-
## 4. Status push (agent -> site, unsolicited, forwarded verbatim)
|
|
568
|
-
|
|
569
|
-
```json
|
|
570
|
-
{"type": "agent.status", "request_id": null, "codex_logged_in": true, "rate_limits": null, "approval_mode": "allow_all" | "ask_once" | "deny"}
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
## 5. Generation requests (site -> agent, forwarded)
|
|
574
|
-
|
|
575
|
-
```json
|
|
576
|
-
{"type": "generate_image", "request_id": "<id>", "prompt": "<string>", "size": "<string>", "quality": "<string>", "reference_images": ["<url>", "..."]}
|
|
577
|
-
{"type": "generate_text", "request_id": "<id>", "prompt": "<string>", "system": "<string>", "model": "<string>", "max_output_tokens": <int>, "reasoning_effort": "<string>", "reference_images": ["<url>", "..."]}
|
|
578
|
-
```
|
|
579
|
-
|
|
580
|
-
`reference_images` are object-storage URLs (this spike: `blobstore.mjs`'s
|
|
581
|
-
fake presigned URLs), never inline base64 -- exactly why the 256KB cap above
|
|
582
|
-
is workable at all. FlowPix's canvas tool set (`list_canvases`...
|
|
583
|
-
`focus_canvas`, "Agent hub v1" above) is a SEPARATE path for a local CLI
|
|
584
|
-
agent and never travels over the relay.
|
|
585
|
-
|
|
586
|
-
## 6. Approval (agent -> site, forwarded, same `request_id` as the generate_* call)
|
|
587
|
-
|
|
588
|
-
```json
|
|
589
|
-
{"type": "approval.pending", "request_id": "<id>", "summary": "<string>"}
|
|
590
|
-
{"type": "approval.resolved", "request_id": "<id>", "decision": "allow" | "deny"}
|
|
591
|
-
```
|
|
592
|
-
|
|
593
|
-
The site shows "等待你在 Kenaz 允許" for `request_id`s between `.pending` and
|
|
594
|
-
`.resolved`/`result` (AC2).
|
|
595
|
-
|
|
596
|
-
## 7. Result (agent -> site, forwarded, same `request_id`)
|
|
597
|
-
|
|
598
|
-
```json
|
|
599
|
-
{"type": "result", "request_id": "<id>", "ok": true, "payload": {...}}
|
|
600
|
-
{"type": "result", "request_id": "<id>", "ok": false, "error": {"code": "<code>", "message": "<string>"}}
|
|
601
|
-
```
|
|
602
|
-
|
|
603
|
-
`payload` for `generate_image`: `{"url": "<blobstore url>", "width": <int>,
|
|
604
|
-
"height": <int>, "provider": "codex", "elapsed_ms": <int>, "meta": {...}}`.
|
|
605
|
-
`payload` for `generate_text`: `{"text": "<string>", "provider": "codex",
|
|
606
|
-
"elapsed_ms": <int>, "meta": {...}}`.
|
|
607
|
-
|
|
608
|
-
Error codes (`error.code`): `not_logged_in`, `usage_limit_exceeded` (carries
|
|
609
|
-
an additional `resetsAt` field), `denied`, `timeout`, `relay_unavailable`,
|
|
610
|
-
`payload_too_large`, `token_invalid`, `token_expired`, `token_already_used`,
|
|
611
|
-
`origin_mismatch`.
|
|
612
|
-
|
|
613
|
-
## 8. Agent launch (agent -> site, forwarded -- R7/K8)
|
|
614
|
-
|
|
615
|
-
Announces that Kenaz, having just paired via a deep link carrying
|
|
616
|
-
`agent=claude|codex`, is starting that CLI headless with FlowPix's `/mcp`
|
|
617
|
-
endpoint (this same bridge's Agent hub v1, above) pre-configured so the CLI
|
|
618
|
-
can `list_canvases` / `add_node` on the canvas the deep link named, without
|
|
619
|
-
the relay itself being involved in that traffic at all.
|
|
620
|
-
|
|
621
|
-
```json
|
|
622
|
-
{"type": "agent.launch", "request_id": null, "agent": "claude" | "codex", "mode": "headless" | "interactive", "prompt": "<string>" | null}
|
|
623
|
-
{"type": "agent.launched", "request_id": null, "agent": "claude" | "codex", "pid": <int> | null}
|
|
624
|
-
{"type": "agent_unavailable", "request_id": null, "agent": "claude" | "codex", "reason": "<string>"}
|
|
625
|
-
```
|
|
626
|
-
|
|
627
|
-
## 9. Disconnect
|
|
628
|
-
|
|
629
|
-
```json
|
|
630
|
-
relay -> site: {"type": "agent.disconnected", "request_id": null}
|
|
631
|
-
```
|
|
632
|
-
Sent when the paired agent's connection closes. The site's `GET`-style status
|
|
633
|
-
read (`backend/jobs.py`'s `get_kenaz_status()`) then reports `connected: false`
|
|
634
|
-
again.
|
|
635
|
-
|
|
636
|
-
## Security notes (R1/K2)
|
|
637
|
-
|
|
638
|
-
Kenaz only ever makes an OUTBOUND connection to the relay -- no inbound port
|
|
639
|
-
on the user's machine. Credentials (Codex/ChatGPT login) never leave the
|
|
640
|
-
user's machine; only the generated image/text and metadata cross the relay.
|
|
641
|
-
Each website origin gets its own pairing; nothing here lets one origin's
|
|
642
|
-
pairing be reused by another.
|