kenaz 0.3.22 → 0.3.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/.claude/hooks/_user-scope.js +1 -1
- package/core/.claude/hooks/core-resolve.js +1 -1
- package/core/.claude/hooks/worktree-create.js +6 -6
- package/core/.claude/hooks/worktree-remove.js +4 -4
- package/core/.collaboration/core/reconcile.js +16 -1
- package/core/.collaboration/core/task-2467-lifecycle.test.js +63 -0
- package/core/.collaboration/core/task-api.js +37 -7
- package/core/.formation/bifrost/launch.js +1 -1
- package/core/.formation/tools/kenaz-stats.js +1 -1
- package/core/.formation/tools/post-complete/git-merge.js +1 -1
- package/core/.formation/tools/prompt.js +1 -1
- package/core/.kenaz/specialist/ansuz_rules.yaml +7 -51
- package/core/.kenaz/specialist/ansuz_session_handoff.schema.json +2 -6
- package/core/.rule/general/project-self-containment.yaml +2 -2
- package/core/.specialist/Amelia/README.md +1 -1
- package/core/.specialist/Amelia/rule.yaml +1 -1
- package/core/.specialist/Ansuz/RULES.md +1 -1
- package/core/.specialist/Ansuz/concepts/commitment_layer.yaml +1 -1
- package/core/.specialist/Ansuz/concepts/evolvable_guardrails.yaml +1 -1
- package/core/.specialist/Ansuz/knowledge.yaml +1 -3
- package/core/.specialist/tools/__tests__/task-2409-lessons.test.js +10 -0
- package/core/.specialist/tools/__tests__/task-2427-harvest.test.js +25 -0
- package/core/.specialist/tools/ansuz-boot-fast.js +1 -1
- package/core/.specialist/tools/failure-detector.js +4 -4
- package/core/.specialist/tools/handoff-doc.js +1 -1
- package/core/.specialist/tools/lessons.js +2 -2
- package/core/CLAUDE.md +5 -5
- package/core/KENAZ_CORE_VERSION +1 -1
- package/core/dashboard/scripts/install-kenaz-cli.js +21 -6
- package/core/dev/scripts/check-file-size.js +1 -1
- package/core/dev/scripts/ci-feedback.js +1 -1
- package/core/dev/scripts/gc-agent-worktrees.js +11 -11
- package/core/dev/scripts/kenaz-session.js +3 -3
- package/core/dev/scripts/peer-identity-e2e.js +3 -3
- package/core/dev/scripts/run-rust-tests.js +2 -2
- package/core/dev/scripts/skill-routing-replay.js +3 -3
- package/core/dev/scripts/task1961/selftest.js +2 -2
- package/core/dev/scripts/windows-hide-guard.test.js +97 -0
- package/core/plugins/kenaz/guidance.md +1 -0
- package/core/plugins/kenaz/hooks/core-resolve.js +1 -1
- package/core/plugins/kenaz/hooks/kenaz-hook.js +52 -4
- package/core/plugins/kenaz/scripts/kenaz.test.js +72 -5
- package/lib/cli.js +9 -5
- package/package.json +6 -6
- package/vendor/install-kenaz-cli.js +21 -6
- package/core/.kenaz/designs/METAPLASTICITY_CONFIDENCE_DESIGN.md +0 -537
- package/core/.kenaz/designs/REFLEX_INITIATOR_DESIGN.md +0 -501
- package/core/.kenaz/designs/TASK_1385_handoff_mcp_design.md +0 -426
- package/core/.kenaz/designs/TASK_932_hippocampus_consolidation.md +0 -103
- package/core/.kenaz/designs/TASK_934_efe_signal_engine.md +0 -97
- package/core/.kenaz/designs/TASK_935_self_evolution_framework.md +0 -154
- package/core/.kenaz/designs/VISION_cognitive_architecture_roadmap.md +0 -159
- package/core/.kenaz/designs/metaplasticity_simulation_results.json +0 -696
- package/core/.kenaz/main-memory/README.md +0 -230
- package/core/.kenaz/main-memory/kenaz/cortex/001_cortex_overview.md +0 -168
- package/core/.kenaz/main-memory/kenaz/cortex/001_rag_engine_overview.md +0 -30
- package/core/.kenaz/main-memory/kenaz/memory-system/001_three_tier_architecture.md +0 -361
- package/core/.kenaz/main-memory/kenaz/pipeline/001_task_execution_flow.md +0 -117
- package/core/.kenaz/main-memory/kenaz/pipeline/001_task_granularity.md +0 -154
- package/core/.kenaz/main-memory/kenaz/pipeline/002_team_priority.md +0 -51
- package/core/.kenaz/main-memory/kenaz/pipeline/003_feature_id_system.md +0 -46
- package/core/.kenaz/main-memory/kenaz/rules/001_gen_007_self_containment.md +0 -108
- package/core/.kenaz/main-memory/kenaz/rules/001_rule_priority_system.md +0 -121
- package/core/.kenaz/main-memory/kenaz/rules/002_agt_006_pre_check.md +0 -0
- package/core/.kenaz/main-memory/kenaz/rules/003_ppl_002_task_archival.md +0 -48
- package/core/.kenaz/main-memory/kenaz/system/001_dual_track_task_system.md +0 -197
- package/core/.kenaz/main-memory/knowledge/patterns/001_json_bom_issue.md +0 -78
- package/core/.kenaz/main-memory/knowledge/patterns/001_leader_worker_pattern.md +0 -0
- package/core/.kenaz/main-memory/knowledge/patterns/002_scope_path_conflict.md +0 -115
- package/core/.kenaz/main-memory/knowledge/patterns/002_task_dependency_resolution.md +0 -223
- package/core/.kenaz/main-memory/knowledge/patterns/003_question_protocol.md +0 -242
- package/core/.kenaz/main-memory/knowledge/patterns/004_user_insight_value.md +0 -111
- package/core/.kenaz/main-memory/knowledge/patterns/005_file_lock_pattern.md +0 -274
- package/core/.kenaz/main-memory/knowledge/references/001_ppl_rules.md +0 -28
- package/core/.kenaz/main-memory/knowledge/solutions/001_json_bom_issue.md +0 -137
- package/core/.kenaz/main-memory/knowledge/solutions/001_team_invocation.md +0 -0
- package/core/.kenaz/main-memory/knowledge/solutions/002_passive_monitoring.md +0 -0
- package/core/.kenaz/main-memory/knowledge/solutions/003_windows_file_race_condition.md +0 -239
- package/core/.kenaz/main-memory/registry.json +0 -326
- package/core/.kenaz/main-memory/version.yaml +0 -58
- package/core/.kenaz/specialist/memory_guard_fired.json +0 -1
- package/core/.kenaz/specialist/memory_guard_trigger_cache.json +0 -1
- package/core/.kenaz/specialist/memory_source_priority.yaml +0 -260
- package/core/.kenaz/specialist/prompt_1775.txt +0 -317
- package/core/.kenaz/specialist/prompt_1776.txt +0 -326
- package/core/.kenaz/specialist/prompt_1791.txt +0 -320
- package/core/.kenaz/specialist/prompt_1792.txt +0 -320
- package/core/.kenaz/specialist/prompt_1795.txt +0 -281
- package/core/.kenaz/specialist/prompt_1813.txt +0 -332
- package/core/.kenaz/specialist/prompt_1814.txt +0 -401
- package/core/.kenaz/specialist/prompt_1815.txt +0 -394
- package/core/.kenaz/specialist/prompt_1816.txt +0 -437
- package/core/.kenaz/specialist/prompt_1818.txt +0 -361
- package/core/.kenaz/specialist/prompt_1819.txt +0 -421
- package/core/.kenaz/specialist/prompt_1821.txt +0 -345
- package/core/.kenaz/specialist/prompt_1822.txt +0 -313
- package/core/.kenaz/specialist/prompt_1824.txt +0 -348
- package/core/.kenaz/specialist/prompt_1826.txt +0 -388
- package/core/.kenaz/specialist/rune_efe_salience_gap.md +0 -21
- package/core/.kenaz/specialist/task1825_update.json +0 -43
- package/core/.kenaz/specialist/taskgen/consolidation_i.json +0 -38
- package/core/.kenaz/specialist/taskgen/csharp_a.json +0 -44
- package/core/.kenaz/specialist/taskgen/csharp_b.json +0 -40
- package/core/.kenaz/specialist/taskgen/embedding_e.json +0 -34
- package/core/.kenaz/specialist/taskgen/hygiene_fg.json +0 -39
- package/core/.kenaz/specialist/taskgen/pathology_h.json +0 -36
- package/core/.kenaz/specialist/taskgen/unity_noise_d.json +0 -38
- package/core/.kenaz/specialist/taskgen/visibility_c.json +0 -38
- package/core/.specialist/Ansuz/decisions/ADR-requirement-graph-layer.md +0 -390
- package/core/.specialist/Ansuz/self_model_seed.backup.json +0 -100
- package/core/.specialist/ansuz_session_handoff.json +0 -96
- package/core/dev/ALAYA_FIELD_FEEDBACK_DESIGN.md +0 -126
- package/core/dev/ANSUZ_SCAFFOLD_DIET_2026-09-20.md +0 -231
- package/core/dev/ANSUZ_STARTUP_INJECTION_REVIEW.md +0 -355
- package/core/dev/ANSUZ_WORKFLOW_MODERNIZATION.md +0 -143
- package/core/dev/CORTEX_META_GRAPH_ASSESSMENT.md +0 -99
- package/core/dev/FREYA_DOWNSTREAM_BUGS_2026-09-19.md +0 -44
- package/core/dev/GLOBAL_MEMORY_IDENTITY_CONSOLIDATION.md +0 -263
- package/core/dev/GUARD_EFFECTIVENESS_DESIGN.md +0 -180
- package/core/dev/HEALTH_GATE_VARIANCE_ASSESSMENT.md +0 -271
- package/core/dev/HOOK_DIET_2026-09-21.md +0 -126
- package/core/dev/JEV_INTEGRATION_PLAN.md +0 -189
- package/core/dev/KENAZ_AGENT_CONNECT_v1_SPEC.md +0 -139
- package/core/dev/MOBILE_DESIGN_SPEC.md +0 -569
- package/core/dev/MULTI_ANSUZ_SPEC.md +0 -136
- package/core/dev/MUNINN_RETIREMENT.md +0 -115
- package/core/dev/PHASE3_ATTRIBUTION_POPULATION_DIAGNOSIS.md +0 -211
- package/core/dev/PHASE3_P3-2B_TASKLEVEL_PROBE.md +0 -83
- package/core/dev/PHASE3_P3-2_POPULATION_DISJOINTNESS.md +0 -83
- package/core/dev/PHASE3_P3-2_REMEASURE_REPORT.md +0 -231
- package/core/dev/PREDICTION_GROUNDING_DESIGN.md +0 -376
- package/core/dev/PRODUCT_SPEC.md +0 -317
- package/core/dev/PROJECT_REGISTRY_DUPLICATE_ASSESSMENT.md +0 -86
- package/core/dev/STARTUP_TIMELINE_TASK_1995.md +0 -181
- package/core/dev/SYNAPSE_WORKER_PER_PROJECT.md +0 -881
- package/core/dev/TASK_1680_P3-3_DISPATCH_SPEC.md +0 -96
- package/core/dev/TASK_1684_CALIBRATION_IMPACT_ANALYSIS.md +0 -170
- package/core/dev/TASK_1684_FORK_A_GOODHART_DESIGN.md +0 -171
- package/core/dev/TASK_1684_P3_2_REMEASURE_VALIDATION.md +0 -262
- package/core/dev/TASK_1903_SIGNAL_AUC_MEASUREMENT.md +0 -207
- package/core/dev/TASK_1904_BRANCH_INTEGRITY_AUDIT.md +0 -146
- package/core/dev/ansuz-eval/README.md +0 -38
- package/core/dev/ansuz-eval/build-fixtures.js +0 -87
- package/core/dev/ansuz-eval/grade.js +0 -96
- package/core/dev/ansuz-eval/grader.test.js +0 -117
- package/core/dev/ansuz-eval/tasks.md +0 -32
- package/core/dev/archive/ansuz/BOOT_FULL.md +0 -141
- package/core/dev/archive/ansuz/agents/ansuz-boot.md +0 -176
- package/core/dev/archive/ansuz/designs/alaya-passive-surfacing.md +0 -84
- package/core/dev/archive/ansuz/designs/cc_memory_indexing.md +0 -307
- package/core/dev/archive/ansuz/designs/check_guard.md +0 -322
- package/core/dev/archive/ansuz/designs/consequence_loop.md +0 -227
- package/core/dev/archive/ansuz/designs/mcp_kuzudb_lock_architecture.md +0 -312
- package/core/dev/archive/ansuz/designs/phase0_git_enrichment.md +0 -278
- package/core/dev/archive/ansuz/designs/refactor_mcp_tools_synapse.md +0 -490
- package/core/dev/archive/ansuz/designs/semantic_markdown_extraction.md +0 -167
- package/core/dev/archive/ansuz/designs/task_1372_prompt_injects_into.md +0 -193
- package/core/dev/archive/ansuz/designs/thought_stack.md +0 -286
- package/core/dev/archive/ansuz/investigations/reachability_unified_api_2026-04-11.md +0 -330
- package/core/dev/archive/ansuz/investigations/synapse_orphans_indexing_bug_2026-04-11.md +0 -352
- package/core/dev/archive/ansuz/investigations/synapse_orphans_reindex_verification_2026-04-11.md +0 -48
- package/core/dev/archive/ansuz/investigations/synapse_orphans_verification_2026-04-11.md +0 -170
- package/core/dev/archive/ansuz/legacy/kernel.yaml +0 -399
- package/core/dev/archive/ansuz/legacy/phases/phase_0.yaml +0 -418
- package/core/dev/archive/ansuz/legacy/phases/phase_1.yaml +0 -376
- package/core/dev/archive/ansuz/legacy/phases/phase_10.yaml +0 -35
- package/core/dev/archive/ansuz/legacy/phases/phase_11.yaml +0 -582
- package/core/dev/archive/ansuz/legacy/phases/phase_2.yaml +0 -94
- package/core/dev/archive/ansuz/legacy/phases/phase_3.yaml +0 -274
- package/core/dev/archive/ansuz/legacy/phases/phase_4.yaml +0 -67
- package/core/dev/archive/ansuz/legacy/phases/phase_5.yaml +0 -32
- package/core/dev/archive/ansuz/legacy/phases/phase_6.yaml +0 -91
- package/core/dev/archive/ansuz/legacy/phases/phase_7.yaml +0 -58
- package/core/dev/archive/ansuz/legacy/phases/phase_8.yaml +0 -146
- package/core/dev/archive/ansuz/legacy/phases/phase_9.yaml +0 -424
- package/core/dev/archive/ansuz/specs/INDEX_bifrost_hook_parity.yaml +0 -92
- package/core/dev/archive/ansuz/specs/active-inference-formation.yaml +0 -453
- package/core/dev/archive/ansuz/specs/brief_TASK_1228_userpromptsubmit.yaml +0 -191
- package/core/dev/archive/ansuz/specs/brief_TASK_1229_pretooluse_posttooluse.yaml +0 -250
- package/core/dev/archive/ansuz/specs/brief_TASK_1230_sessionstart_stop.yaml +0 -301
- package/core/dev/archive/ansuz/specs/brief_TASK_1231_verification.yaml +0 -272
- package/core/dev/archive/skills/feature_agent/SKILL.md +0 -289
- package/core/dev/design/PHASE4_DESIGN.md +0 -559
- package/core/dev/design/dashboard_docs_integration_PLAN.md +0 -388
- package/core/dev/design/matrix_format_ABBREVIATIONS.md +0 -655
- package/core/dev/design/matrix_format_DESIGN_SPEC.md +0 -601
- package/core/dev/design/matrix_format_DISCUSSION_SUMMARY.md +0 -484
- package/core/dev/design/matrix_format_EXAMPLE_memory.matrix +0 -13
- package/core/dev/design/matrix_format_EXAMPLE_project_status.matrix +0 -9
- package/core/dev/design/matrix_format_EXAMPLE_tasks.matrix +0 -14
- package/core/dev/design/matrix_format_SYNTAX_BNF.md +0 -754
- package/core/dev/design/matrix_format_TOKEN_COMPARISON.md +0 -484
- package/core/dev/design/matrix_v2_COGNITIVE_DESIGN.md +0 -503
- package/core/dev/design/matrix_v2_DISCUSSION_SUMMARY.md +0 -414
- package/core/dev/design/matrix_v2_EXAMPLE.matrix +0 -67
- package/core/dev/designs/EXPANDABLE_CARD_DESIGN_SPEC.md +0 -509
- package/core/dev/jev-eval/ACTIVE_CORRECTION.md +0 -52
- package/core/dev/jev-eval/ANNOTATION_GUIDE.md +0 -68
- package/core/dev/jev-eval/BASELINE_COMPARISON.md +0 -45
- package/core/dev/jev-eval/CONTEXT_REVIEW.md +0 -31
- package/core/dev/jev-eval/EVALUATION_STATUS.md +0 -39
- package/core/dev/jev-eval/HISTORICAL_CORPUS.md +0 -33
- package/core/dev/jev-eval/PACKAGING_VERIFICATION.md +0 -42
- package/core/dev/jev-eval/README.md +0 -101
- package/core/dev/jev-eval/THALAMUS_RANKING.md +0 -58
- package/core/dev/jev-eval/VALIDATION_PROGRESS.md +0 -54
- package/core/dev/jev-eval/cli.mjs +0 -50
- package/core/dev/jev-eval/context.mjs +0 -183
- package/core/dev/jev-eval/corpus.mjs +0 -186
- package/core/dev/jev-eval/fixtures/conversation-review.seed.jsonl +0 -6
- package/core/dev/jev-eval/fixtures/synthetic.jsonl +0 -11
- package/core/dev/jev-eval/metrics.mjs +0 -67
- package/core/dev/jev-eval/muninn-baseline.mjs +0 -119
- package/core/dev/jev-eval/providers.mjs +0 -95
- package/core/dev/jev-eval/reports/annotation-pilot-2026-09-20.json +0 -32
- package/core/dev/jev-eval/reports/context-review-2026-09-20.json +0 -48
- package/core/dev/jev-eval/reports/conversation-review.pending.json +0 -151
- package/core/dev/jev-eval/reports/history-corpus-2026-09-20.json +0 -52
- package/core/dev/jev-eval/reports/length-probe-2026-09-20.json +0 -133
- package/core/dev/jev-eval/reports/live-smoke-2026-09-20.json +0 -616
- package/core/dev/jev-eval/reports/muninn-baseline-2026-09-20.json +0 -52
- package/core/dev/jev-eval/reports/resilience-2026-09-20.json +0 -520
- package/core/dev/jev-eval/reports/rules-baseline.json +0 -197
- package/core/dev/jev-eval/reports/synthetic-review.pending.json +0 -357
- package/core/dev/jev-eval/resilience.mjs +0 -71
- package/core/dev/jev-eval/review.mjs +0 -78
- package/core/dev/jev-eval/schema.mjs +0 -87
- package/core/dev/jev-eval/test/context.test.mjs +0 -95
- package/core/dev/jev-eval/test/corpus.test.mjs +0 -102
- package/core/dev/jev-eval/test/eval.test.mjs +0 -146
- package/core/dev/jev-eval/test/muninn-baseline.test.mjs +0 -71
- package/core/dev/jev-eval/test/resilience.test.mjs +0 -72
- package/core/dev/jev-eval/test/review.test.mjs +0 -61
- package/core/dev/pipeline/PHASE3_PLANNING_SUMMARY.md +0 -338
- package/core/dev/pipeline/PROGRESS.md +0 -113
- package/core/dev/pipeline/PROGRESS_template.md +0 -860
- package/core/dev/pipeline/QA_REPORT_F008.md +0 -431
- package/core/dev/pipeline/QA_REPORT_LOCAL_CLAUDE_DIAGNOSIS.md +0 -583
- package/core/dev/pipeline/README.md +0 -210
- package/core/dev/pipeline/WORKFLOW_GUIDE.md +0 -824
- package/core/dev/pipeline/archived/TASK_015_tauri_init.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_016_tauri_commands.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_017_rust_pty.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_018_tauri_bundle.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_019_release_workflow.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_020_update_ui.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_021_update_notification_ui.yaml +0 -55
- package/core/dev/pipeline/archived/TASK_022_remove_node_pty.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_023_api_routes_migration.yaml +0 -86
- package/core/dev/pipeline/archived/TASK_024_feature_id_system.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_025_executable_acceptance.yaml +0 -66
- package/core/dev/pipeline/archived/TASK_026_spec_versioning.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_027_drift_detection.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_028_tauri_pty_manager.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_029_tauri_pty_commands.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_030_frontend_session_adapter.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_031_terminal_tauri_events.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_041_scheduler_data_models.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_042_path_lock_manager.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_043_process_manager.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_044_git_integration.yaml +0 -85
- package/core/dev/pipeline/archived/TASK_045_task_queue_manager.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_046_scheduler_dispatcher.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_047_tauri_scheduler_commands.yaml +0 -55
- package/core/dev/pipeline/archived/TASK_048_realtime_status_push.yaml +0 -92
- package/core/dev/pipeline/archived/TASK_049_frontend_scheduler_integration.yaml +0 -58
- package/core/dev/pipeline/archived/TASK_050_error_recovery.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_051_optimization_proposals_backend.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_052_optimization_proposals_ui.yaml +0 -58
- package/core/dev/pipeline/archived/TASK_053_optimization_proposals_diff_view.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_054_multi_project_scheduler_state.yaml +0 -76
- package/core/dev/pipeline/archived/TASK_055_scheduler_api_project_scope.yaml +0 -64
- package/core/dev/pipeline/archived/TASK_056_frontend_scheduler_project_scope.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_057_scheduler_module_structure.yaml +0 -54
- package/core/dev/pipeline/archived/TASK_058_scheduler_models_extract.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_059_scheduler_core_extract.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_060_scheduler_commands_extract.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_061_scheduler_specialized_commands.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_062_process_manager_module_structure.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_063_process_manager_core_extract.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_064_recovery_module_structure.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_065_recovery_core_extract.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_066_self_enhancement_scheduler_models.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_067_agents_section_quick_actions.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_067_self_enhancement_scheduler_core.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_068_agent_workflow_rule_enhancement.yaml +0 -46
- package/core/dev/pipeline/archived/TASK_068_self_enhancement_tauri_commands.yaml +0 -61
- package/core/dev/pipeline/archived/TASK_069_agent_wizard_responsive.yaml +0 -46
- package/core/dev/pipeline/archived/TASK_069_self_enhancement_ui.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_070_preview_panel_redesign.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_070_self_enhancement_integration.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_071_preview_panel_qa.yaml +0 -98
- package/core/dev/pipeline/archived/TASK_071_single_agent_config.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_072_preview_modal_esc_fix.yaml +0 -71
- package/core/dev/pipeline/archived/TASK_072_product_review_module.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_073_agents_page_component_refactor.yaml +0 -68
- package/core/dev/pipeline/archived/TASK_073_rename_single_agent.yaml +0 -64
- package/core/dev/pipeline/archived/TASK_074_preview_mode_ui_diagnosis.yaml +0 -71
- package/core/dev/pipeline/archived/TASK_074_single_agent_ui_toggle.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_075_agents_page_component_refactor.yaml +0 -69
- package/core/dev/pipeline/archived/TASK_075_single_agent_integration_test.yaml +0 -75
- package/core/dev/pipeline/archived/TASK_076_preview_mode_ui_diagnosis.yaml +0 -70
- package/core/dev/pipeline/archived/TASK_076_single_agent_continuous_mode.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_077_failure_directory_structure.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_077_single_agent_typescript_types.yaml +0 -59
- package/core/dev/pipeline/archived/TASK_078_fail_001_agent_no_output.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_078_single_agent_ui_simplify.yaml +0 -74
- package/core/dev/pipeline/archived/TASK_079_dashboard_rwd_responsive.yaml +0 -63
- package/core/dev/pipeline/archived/TASK_079_fail_002_json_bom.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_080_fail_003_queue_pollution.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_080_http_server_module.yaml +0 -55
- package/core/dev/pipeline/archived/TASK_081_failure_logging_tools.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_081_http_api_routes.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_082_frontend_api_adapter.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_082_integrate_failure_to_workflow.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_083_cleanup_nextjs_api.yaml +0 -48
- package/core/dev/pipeline/archived/TASK_083_task_queue_cleanup.yaml +0 -67
- package/core/dev/pipeline/archived/TASK_084_rust_dead_code_cleanup.yaml +0 -66
- package/core/dev/pipeline/archived/TASK_084_scheduler_sync_logic_fix.yaml +0 -68
- package/core/dev/pipeline/archived/TASK_085_http_api_web_mode_fixes.yaml +0 -46
- package/core/dev/pipeline/archived/TASK_085_memory_consolidation_0204_0205.yaml +0 -98
- package/core/dev/pipeline/archived/TASK_086_collapsible_preview_panel.yaml +0 -161
- package/core/dev/pipeline/archived/TASK_086_web_mode_feature_parity.yaml +0 -62
- package/core/dev/pipeline/archived/TASK_087_manual_memory_archival.yaml +0 -163
- package/core/dev/pipeline/archived/TASK_087_mobile_http_control.yaml +0 -68
- package/core/dev/pipeline/archived/TASK_088_fail_003_to_ppl_002_rule.yaml +0 -63
- package/core/dev/pipeline/archived/TASK_088_mobile_http_qa.yaml +0 -121
- package/core/dev/pipeline/archived/TASK_089_agent_collaboration_topic.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_089_web_mode_monitor_fix.yaml +0 -58
- package/core/dev/pipeline/archived/TASK_090_cli_detection_fix.yaml +0 -61
- package/core/dev/pipeline/archived/TASK_090_ui_ux_lessons_topic.yaml +0 -63
- package/core/dev/pipeline/archived/TASK_091_expandable_card_design.yaml +0 -56
- package/core/dev/pipeline/archived/TASK_091_move_agent_section_components.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_092_expandable_card_component.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_092_refactor_agent_create_wizard.yaml +0 -84
- package/core/dev/pipeline/archived/TASK_093_taskcard_detail_integration.yaml +0 -57
- package/core/dev/pipeline/archived/TASK_093_update_barrel_exports_test.yaml +0 -84
- package/core/dev/pipeline/archived/TASK_094_ai_agent_generation_enhancement.yaml +0 -115
- package/core/dev/pipeline/archived/TASK_094_proposalcard_detail_integration.yaml +0 -55
- package/core/dev/pipeline/archived/TASK_095_preview_fixes.yaml +0 -129
- package/core/dev/pipeline/archived/TASK_095_single_agent_task_selector.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_096_agents_page_ux_improvements.yaml +0 -163
- package/core/dev/pipeline/archived/TASK_096_single_agent_status_sync.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_097_local_claude_error_logging.yaml +0 -59
- package/core/dev/pipeline/archived/TASK_097_single_agent_monitor_events.yaml +0 -59
- package/core/dev/pipeline/archived/TASK_098_product_manager_team_phase2.yaml +0 -60
- package/core/dev/pipeline/archived/TASK_098_single_agent_refactor_test.yaml +0 -58
- package/core/dev/pipeline/archived/TASK_099_backend_team_creation.yaml +0 -258
- package/core/dev/pipeline/archived/TASK_100_frontend_team_creation.yaml +0 -61
- package/core/dev/pipeline/archived/TASK_101_orchestrator_system.yaml +0 -403
- package/core/dev/pipeline/archived/TASK_102_designer_sre_teams.yaml +0 -90
- package/core/dev/pipeline/archived/TASK_103_integration_testing.yaml +0 -86
- package/core/dev/pipeline/archived/TASK_128_integration_testing.yaml +0 -83
- package/core/dev/pipeline/archived/TASK_134_cortex_v2_phase3_file_watcher.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_134_team_http_api.yaml +0 -96
- package/core/dev/pipeline/archived/TASK_135_cortex_v2_phase3_git_monitor.yaml +0 -63
- package/core/dev/pipeline/archived/TASK_136_cortex_v2_phase3_change_analyzer.yaml +0 -69
- package/core/dev/pipeline/archived/TASK_137_cortex_v2_phase3_cache_invalidator.yaml +0 -67
- package/core/dev/pipeline/archived/TASK_137_team_orchestrator_integration.yaml +0 -93
- package/core/dev/pipeline/archived/TASK_138_cortex_v2_phase3_distributed_cache.yaml +0 -68
- package/core/dev/pipeline/archived/TASK_138_matrix_folder_structure.yaml +0 -61
- package/core/dev/pipeline/archived/TASK_139_cortex_v2_phase3_cache_prewarming.yaml +0 -65
- package/core/dev/pipeline/archived/TASK_146_unified_documentation.yaml +0 -141
- package/core/dev/pipeline/archived/TASK_147_pipeline_execution_rules.yaml +0 -76
- package/core/dev/pipeline/archived/TASK_148_update_claude_md.yaml +0 -77
- package/core/dev/pipeline/archived/TASK_149_fix_nextjs_mdx_serialization.yaml +0 -63
- package/core/dev/pipeline/archived/TASK_149_update_team_docs.yaml +0 -77
- package/core/dev/pipeline/archived/TASK_150_pipeline_workflow_guide.yaml +0 -82
- package/core/dev/pipeline/archived/TASK_164_fix_smart_context_switch.yaml +0 -49
- package/core/dev/pipeline/archived/TASK_165_ctags_symbol_index.yaml +0 -53
- package/core/dev/pipeline/archived/TASK_166_symbol_search_mcp_tool.yaml +0 -48
- package/core/dev/pipeline/archived/TASK_167_llm_module_summary.yaml +0 -55
- package/core/dev/pipeline/archived/TASK_168_map_reduce_context.yaml +0 -51
- package/core/dev/pipeline/archived/TASK_169_v2_integration_testing.yaml +0 -52
- package/core/dev/pipeline/backups/archive_2026-02-04T22-07-22/TASK_QUEUE_backup.json +0 -95
- package/core/dev/pipeline/docs/multi-agent-coordination.md +0 -446
- package/core/dev/pipeline/docs/overview.md +0 -406
- package/core/dev/pipeline/docs/task-management.md +0 -412
- package/core/dev/pipeline/docs/workflows.md +0 -32
- package/core/dev/pipeline/orchestrator/schemas/task_queue_schema.json +0 -58
- package/core/dev/pipeline/orchestrator/schemas/task_schema.json +0 -139
- package/core/dev/pipeline/plans/PLAN_task_cli_refactor.md +0 -281
- package/core/dev/pipeline/test_results/TASK_TEST_PARALLEL_002_result.txt +0 -27
- package/core/dev/plans/ANSUZ_SLIM_PLAN.md +0 -68
- package/core/dev/plans/CLI_FIRST_INSTALL_FLOW.md +0 -120
- package/core/dev/plans/FORMATION_RETIREMENT_PLAN.md +0 -313
- package/core/dev/plans/KUZU_REPLACEMENT_PLAN.md +0 -126
- package/core/dev/scripts/CRASH_DIAGNOSIS.md +0 -47
- package/core/dev/scripts/README.md +0 -142
- package/core/dev/scripts/RUN_ONCE.bat +0 -40
- package/core/dev/scripts/START_DEV_AGENT.bat +0 -63
- package/core/dev/scripts/START_MULTI_AGENT.bat +0 -80
- package/core/dev/scripts/dev_agent_scheduler.ps1 +0 -536
- package/core/dev/scripts/init_git.ps1 +0 -396
- package/core/dev/scripts/init_git.sh +0 -337
- package/core/dev/scripts/init_project.ps1 +0 -851
- package/core/dev/scripts/init_project.sh +0 -477
- package/core/dev/scripts/multi_agent_scheduler.ps1 +0 -2021
- package/core/dev/scripts/multi_agent_scheduler.sh +0 -1344
- package/core/dev/scripts/run_once.sh +0 -47
- package/core/dev/scripts/setup_rag.ps1 +0 -304
- package/core/dev/scripts/setup_rag.sh +0 -230
- package/core/dev/scripts/start_dev_agent.sh +0 -137
- package/core/dev/scripts/start_multi_agent.sh +0 -41
- package/core/dev/scripts/sync_task_queue.ps1 +0 -505
- package/core/dev/scripts/sync_task_queue.sh +0 -392
- package/core/dev/specs/agent-connect/PROTOCOL.md +0 -177
- package/core/dev/specs/agent-connect/SDK_GUIDE.md +0 -915
- package/core/dev/specs/agent-connect/examples/minimal-site/README.md +0 -137
- package/core/dev/specs/agent-connect/examples/minimal-site/package.json +0 -12
- package/core/dev/specs/agent-connect/examples/minimal-site/public/index.html +0 -116
- package/core/dev/specs/agent-connect/examples/minimal-site/public/install-redirect.js +0 -73
- package/core/dev/specs/agent-connect/examples/minimal-site/server.js +0 -516
- package/core/dev/specs/agent-connect/examples/minimal-site/test/smoke.test.mjs +0 -263
- package/core/dev/specs/agent-connect/history/DEFECT_REPORT_kenaz-agent-hub_2026-09-09_v0.4-empty-prompt-no-first-turn.md +0 -77
- package/core/dev/specs/agent-connect/history/DEFECT_REPORT_kenaz-agent-hub_2026-09-09_v0.4-prompt-mojibake.md +0 -90
- package/core/dev/specs/agent-connect/history/FEATURE_REQUEST_kenaz-agent-hub_2026-09-07.md +0 -61
- package/core/dev/specs/agent-connect/history/FEATURE_REQUEST_kenaz-agent-hub_2026-09-08_relay-v1-conformance.md +0 -76
- package/core/dev/specs/agent-connect/history/FEATURE_REQUEST_kenaz-agent-hub_2026-09-09_v0.4-session-channel.md +0 -87
- package/core/dev/specs/agent-connect/history/FLOWPIX_REPLY_agent-hub_2026-09-08_relay-v1-answers.md +0 -68
- package/core/dev/specs/agent-connect/history/FLOWPIX_bridge_CONTRACT.md +0 -642
- package/core/dev/specs/agent-connect/history/FLOWPIX_spikes_relay_spike_relay.mjs +0 -244
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-07.md +0 -77
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-08_direction-change-v0.3.md +0 -44
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-08_relay-v1-answers-ack.md +0 -37
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-08_relay-v1-conformance.md +0 -56
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_annotations-install-coldstart.md +0 -44
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_empty-prompt-first-turn.md +0 -56
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_prompt-mojibake-fixed.md +0 -48
- package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_session-channel.md +0 -57
- package/core/dev/specs/agent-connect/history/PROTOCOL_v0.3_snapshot.md +0 -379
- package/core/dev/specs/agent-connect/history/README.md +0 -47
- package/core/dev/specs/peer/CODEX_INTERACTIVE_PUSH.md +0 -65
- package/core/dev/specs/peer/CODEX_MANAGED_DAEMON.md +0 -54
- package/core/dev/specs/peer/CODEX_PEER_PULL_SPIKE.md +0 -54
- package/core/dev/specs/peer/MODS_SPIKE.md +0 -133
- package/core/dev/specs/peer/PER_PROJECT_ADDRESSING.md +0 -143
- package/core/dev/specs/peer/SWARM_PROTOCOLS.md +0 -256
- package/core/dev/specs/peer/codex-hook-shim-peer.test.js +0 -113
- package/core/dev/specs/peer/codex-push-launcher.test.js +0 -142
- package/core/dev/specs/peer/setup-codex-hooks.test.js +0 -60
- package/core/dev/specs/peer-ansuz/DELIVERY_SPIKE.md +0 -397
- package/core/dev/specs/peer-ansuz/DESIGN.md +0 -109
- package/core/dev/specs/peer-ansuz/spike/claude_poke.js +0 -129
- package/core/dev/specs/peer-ansuz/spike/claude_session_start_hook.js +0 -37
- package/core/dev/specs/peer-ansuz/spike/claude_settings_hook.json +0 -14
- package/core/dev/specs/peer-ansuz/spike/codex_appserver_client.js +0 -105
- package/core/dev/specs/peer-ansuz/spike/codex_appserver_query.js +0 -29
- package/core/dev/specs/peer-ansuz/spike/extract_timeline.js +0 -26
- package/core/dev/specs/synapse/SYMBOL_IDENTITY.md +0 -305
- package/core/dev/spikes/A4-cypher-varlen.md +0 -176
- package/core/dev/spikes/bloat-rounds.sh +0 -25
- package/core/dev/spikes/mods/clean-claude.js +0 -9
- package/core/dev/spikes/mods/drive-probe.js +0 -29
- package/core/dev/spikes/mods/e2e-peer.js +0 -71
- package/core/dev/spikes/mods/evidence/e2e-peer-control.json +0 -17
- package/core/dev/spikes/mods/evidence/e2e-peer-mod.json +0 -17
- package/core/dev/spikes/mods/evidence/probe-006a6e65-d807-4bc1-b648-fd7d1edfe0b4.jsonl +0 -4
- package/core/dev/spikes/mods/evidence/probe-cebdf1f7-f9c4-47a8-83cd-7c0786177404.jsonl +0 -12
- package/core/dev/spikes/mods/evidence/probe-eb21147d-10ce-4c32-93ed-37ca37d88d5a.jsonl +0 -11
- package/core/dev/spikes/mods/evidence/stream-cebdf1f7.jsonl +0 -18
- package/core/dev/spikes/mods/kenaz-mod-probe/.claude-plugin/plugin.json +0 -1
- package/core/dev/spikes/mods/kenaz-mod-probe/hooks/hooks.json +0 -1
- package/core/dev/spikes/mods/kenaz-mod-probe/hooks/register.ts +0 -65
- package/core/dev/spikes/mods/kenaz-mod-probe/tsconfig.json +0 -3
|
@@ -328,7 +328,7 @@ function captureGitCommitSnapshot(taskId) {
|
|
|
328
328
|
try {
|
|
329
329
|
const logOutput = execFileSync(
|
|
330
330
|
'git', ['log', branch, '--not', 'main', '--oneline'],
|
|
331
|
-
{ cwd: PROJECT_DIR, stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 }
|
|
331
|
+
{ windowsHide: true, cwd: PROJECT_DIR, stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 }
|
|
332
332
|
).toString().trim();
|
|
333
333
|
snapshot.logOk = true;
|
|
334
334
|
snapshot.commitLines = logOutput ? logOutput.split('\n').filter(Boolean) : [];
|
|
@@ -339,7 +339,7 @@ function captureGitCommitSnapshot(taskId) {
|
|
|
339
339
|
try {
|
|
340
340
|
snapshot.numstatOutput = execFileSync(
|
|
341
341
|
'git', ['log', branch, '--not', 'main', '--numstat', '--format='],
|
|
342
|
-
{ cwd: PROJECT_DIR, stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 }
|
|
342
|
+
{ windowsHide: true, cwd: PROJECT_DIR, stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 }
|
|
343
343
|
).toString().trim();
|
|
344
344
|
} catch {
|
|
345
345
|
// No numstat — non-fatal, mirrors original tolerance for this failure
|
|
@@ -446,7 +446,7 @@ function detectGitCommitPattern(taskId, guard, taskData, postCompleteResult) {
|
|
|
446
446
|
try {
|
|
447
447
|
logOutput = execFileSync(
|
|
448
448
|
'git', ['log', branch, '--not', 'main', '--oneline'],
|
|
449
|
-
{ cwd: PROJECT_DIR, stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 }
|
|
449
|
+
{ windowsHide: true, cwd: PROJECT_DIR, stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 }
|
|
450
450
|
).toString().trim();
|
|
451
451
|
} catch {
|
|
452
452
|
return { result: null, reason: 'git_log_failed' };
|
|
@@ -463,7 +463,7 @@ function detectGitCommitPattern(taskId, guard, taskData, postCompleteResult) {
|
|
|
463
463
|
try {
|
|
464
464
|
numstatOutput = execFileSync(
|
|
465
465
|
'git', ['log', branch, '--not', 'main', '--numstat', '--format='],
|
|
466
|
-
{ cwd: PROJECT_DIR, stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 }
|
|
466
|
+
{ windowsHide: true, cwd: PROJECT_DIR, stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 }
|
|
467
467
|
).toString().trim();
|
|
468
468
|
} catch {
|
|
469
469
|
// No numstat — still evaluate revert/signature above
|
|
@@ -24,7 +24,7 @@ function stamp(d) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
function git(projectPath, args) {
|
|
27
|
-
try { return execFileSync('git', args, { cwd: projectPath, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim(); } catch { return ''; }
|
|
27
|
+
try { return execFileSync('git', args, { windowsHide: true, cwd: projectPath, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim(); } catch { return ''; }
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
function template({ topic, session, projectPath, now }) {
|
|
@@ -258,13 +258,13 @@ function rm(id, o = {}) {
|
|
|
258
258
|
return l;
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
/** Project lessons for the dispatch prompt: facts
|
|
261
|
+
/** Project lessons for the dispatch prompt: facts and checks whose paths overlap scope_paths (no paths = every card); bounded, most-fired first. */
|
|
262
262
|
function dispatchLessons(projectPath, scopePaths = [], { home, now } = {}) {
|
|
263
263
|
const norm = (s) => String(s).replace(/\\/g, '/').toLowerCase();
|
|
264
264
|
const scope = scopePaths.map(norm);
|
|
265
265
|
const overlaps = (l) => !l.paths.length || l.paths.some((p) => scope.some((s) => s.includes(norm(p)) || norm(p).includes(s)));
|
|
266
266
|
const pick = listLayer('project', { projectPath, home, now })
|
|
267
|
-
.filter((l) => !l.triggers.length && (
|
|
267
|
+
.filter((l) => !l.triggers.length && (l.type === 'fact' || l.type === 'check') && overlaps(l));
|
|
268
268
|
const out = { facts: [], checks: [] };
|
|
269
269
|
let bytes = 0, lines = 0;
|
|
270
270
|
for (const l of pick) {
|
package/core/CLAUDE.md
CHANGED
|
@@ -61,7 +61,7 @@ harness 預設「每條記憶都在 MEMORY.md 加一行」;本專案改為三
|
|
|
61
61
|
KenazAI 是一個 Claude Code 多 Agent 協作系統,包含:
|
|
62
62
|
- **kenaz-server**:Rust 後端(`dashboard/src-tauri/`,npm `@kenazai/server-*`);Dashboard 桌面版已於 2026-10-11 退役(TASK_2396)
|
|
63
63
|
- **Specialist 系統**:AI Agent 調度引擎(`.specialist/`)
|
|
64
|
-
- **Formation
|
|
64
|
+
- **Formation 工具**:subagent worktree 派工與合併工具(`.formation/tools/`);unit/solo/squad/legion 與 `kenaz_dispatch` 已退役,只剩 subagent 派工
|
|
65
65
|
|
|
66
66
|
技術棧:Rust(kenaz-server)、Node.js(kenaz CLI、hooks、工具)、SQLite
|
|
67
67
|
|
|
@@ -72,7 +72,7 @@ KenazAI 是一個 Claude Code 多 Agent 協作系統,包含:
|
|
|
72
72
|
| Specialist | 定位 | 指令 |
|
|
73
73
|
|-----------|------|------|
|
|
74
74
|
| **Ansuz** ᚨ | 產品全生命週期引擎(需求→架構→任務→執行) | `/Ansuz` |
|
|
75
|
-
| **Amelia** |
|
|
75
|
+
| **Amelia** | 多 Agent 協作調度者 | `/Amelia` |
|
|
76
76
|
|
|
77
77
|
文檔:`.specialist/Ansuz/SYSTEM_DOC.md`、`.specialist/Amelia/README.md`
|
|
78
78
|
|
|
@@ -128,7 +128,7 @@ node .collaboration/core/task-api.js move TASK_XXX active # 移動狀態
|
|
|
128
128
|
| 規則庫 | `.rule/` | 最高優先級規則,見 `INDEX.yaml` |
|
|
129
129
|
| 失敗學習 | `.failure/` | 已知失敗模式,Agent 執行前應檢查 |
|
|
130
130
|
| Rust 測試 | `npm run test:rust -- <filter>` | 主目錄直接可跑;用共用短路徑 target,不和其他建置搶 `target/` 鎖。勿直接 `cargo test` |
|
|
131
|
-
| Formation | `.formation/` |
|
|
131
|
+
| Formation | `.formation/` | subagent 派工與合併工具,見 `README.md` |
|
|
132
132
|
| Skills | `.claude/skills/` | Agent 行為定義(40+ skills) |
|
|
133
133
|
| 外部 Skills | `.agents/skills/` | `vercel-react-best-practices`、`supabase-postgres-best-practices` |
|
|
134
134
|
|
|
@@ -137,7 +137,7 @@ node .collaboration/core/task-api.js move TASK_XXX active # 移動狀態
|
|
|
137
137
|
KenazAI 支援管理子專案。Core 擁有系統檔,子專案只存 `.kenaz/`(tasks + logs + project.yaml)。
|
|
138
138
|
|
|
139
139
|
子專案工作時:讀取 `.kenaz/project.yaml` 的 `core_path` 確定系統檔來源。
|
|
140
|
-
task-api 和
|
|
140
|
+
task-api 和 `.formation/tools/dispatch.js` 都支援 `--project-path` 參數。
|
|
141
141
|
|
|
142
142
|
文檔:`.system/collaboration/README.md`
|
|
143
143
|
|
|
@@ -155,7 +155,7 @@ DB: postgresql://postgres:postgres@127.0.0.1:54322/postgres
|
|
|
155
155
|
.rule/ # 規則庫(最高優先級)
|
|
156
156
|
.specialist/ # Specialist 系統(Ansuz、Amelia)
|
|
157
157
|
.collaboration/ # 任務系統
|
|
158
|
-
.formation/ #
|
|
158
|
+
.formation/ # subagent 派工與合併工具
|
|
159
159
|
.failure/ # 失敗學習系統
|
|
160
160
|
.memory/ # (歷史)舊記憶資料,記憶系統已移除
|
|
161
161
|
.claude/ # Skills、Commands、Hooks
|
package/core/KENAZ_CORE_VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.3.
|
|
1
|
+
0.3.23
|
|
@@ -22,6 +22,8 @@ const MIN_CLI = [2, 1, 287];
|
|
|
22
22
|
const SEP = process.platform === 'win32' ? ';' : ':';
|
|
23
23
|
const TASK_NAME = 'KenazServer';
|
|
24
24
|
const LABEL = 'ai.kenaz.server';
|
|
25
|
+
const BATTERY_PS = '$s = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit ([TimeSpan]::Zero); Set-ScheduledTask -TaskName ' + TASK_NAME + ' -Settings $s';
|
|
26
|
+
const linuxUser = () => { try { return os.userInfo().username; } catch (_) { return process.env.USER || ''; } };
|
|
25
27
|
|
|
26
28
|
const norm = (e) => {
|
|
27
29
|
const s = String(e).trim().replace(/\\/g, '/').replace(/\/+$/, '');
|
|
@@ -136,8 +138,8 @@ function retireDashboardHooks(file, dry) {
|
|
|
136
138
|
|
|
137
139
|
function claudeVersion() {
|
|
138
140
|
const r = process.platform === 'win32' // one string with shell (.cmd shim): args + shell:true is deprecated (DEP0190)
|
|
139
|
-
? spawnSync('claude --version', { encoding: 'utf8', shell: true, timeout: 15000 })
|
|
140
|
-
: spawnSync('claude', ['--version'], { encoding: 'utf8', timeout: 15000 });
|
|
141
|
+
? spawnSync('claude --version', { windowsHide: true, encoding: 'utf8', shell: true, timeout: 15000 })
|
|
142
|
+
: spawnSync('claude', ['--version'], { windowsHide: true, encoding: 'utf8', timeout: 15000 });
|
|
141
143
|
return r.status === 0 ? parseVersion(r.stdout) : null;
|
|
142
144
|
}
|
|
143
145
|
|
|
@@ -208,7 +210,7 @@ function servicePlan(home, bin, core, platform = process.platform, caps = { syst
|
|
|
208
210
|
const p = path.join(home, '.config', 'systemd', 'user', 'kenaz-server.service');
|
|
209
211
|
return { kind: 'systemd', files: [[p, systemdUnit(bin, core)]], unit: p };
|
|
210
212
|
}
|
|
211
|
-
const sh = (cmd, args, opts) => spawnSync(cmd, args, { encoding: 'utf8', ...(opts || {}) });
|
|
213
|
+
const sh = (cmd, args, opts) => spawnSync(cmd, args, { windowsHide: true, encoding: 'utf8', ...(opts || {}) });
|
|
212
214
|
|
|
213
215
|
// crontab -l: null = no crontab binary; '' = binary present, no crontab yet. All through the injected `run`.
|
|
214
216
|
function readCron(run) {
|
|
@@ -303,8 +305,13 @@ function serviceInstall(plan, dry, log, run = sh, uid) {
|
|
|
303
305
|
log('schtasks /Create /TN ' + TASK_NAME + ' /SC ONLOGON /TR ' + tr + ' /F (fallback: ' + plan.fallbackFile + ')');
|
|
304
306
|
if (dry) return;
|
|
305
307
|
const r = sh('schtasks', ['/Create', '/TN', TASK_NAME, '/SC', 'ONLOGON', '/TR', tr, '/F']);
|
|
306
|
-
if (r.status === 0)
|
|
307
|
-
|
|
308
|
+
if (r.status === 0) {
|
|
309
|
+
// Task Scheduler defaults refuse to start on battery and stop the task when going on battery:
|
|
310
|
+
// a laptop unplugged at logon never got the server (TASK_2468). Re-running install fixes an old task.
|
|
311
|
+
const b = sh('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', BATTERY_PS]);
|
|
312
|
+
if (b.status !== 0) log('WARNING: could not set the task to run on battery (exit ' + b.status + '); on a laptop the server may not start unplugged. Run in PowerShell: ' + BATTERY_PS);
|
|
313
|
+
sh('schtasks', ['/Run', '/TN', TASK_NAME]);
|
|
314
|
+
} else { // ONLOGON tasks can need elevation: a Startup-folder launcher is the per-user equivalent
|
|
308
315
|
fs.mkdirSync(path.dirname(plan.fallbackFile), { recursive: true });
|
|
309
316
|
fs.copyFileSync(plan.files[0][0], plan.fallbackFile);
|
|
310
317
|
sh('wscript.exe', [plan.files[0][0]]);
|
|
@@ -326,6 +333,10 @@ function serviceInstall(plan, dry, log, run = sh, uid) {
|
|
|
326
333
|
} else {
|
|
327
334
|
log('systemctl --user enable --now kenaz-server');
|
|
328
335
|
if (!dry) { sh('systemctl', ['--user', 'daemon-reload']); sh('systemctl', ['--user', 'enable', '--now', 'kenaz-server']); }
|
|
336
|
+
// Without linger the user service starts only at login (headless boxes: never). Best effort.
|
|
337
|
+
const u = linuxUser();
|
|
338
|
+
log('loginctl enable-linger ' + u);
|
|
339
|
+
if (!dry && sh('loginctl', ['enable-linger', u]).status !== 0) log('WARNING: could not enable linger; the server starts at boot only after you log in. Run: loginctl enable-linger ' + u + ' (may need sudo)');
|
|
329
340
|
serviceRestart(plan, dry, log, sh, uid);
|
|
330
341
|
}
|
|
331
342
|
}
|
|
@@ -365,7 +376,11 @@ function detectServiceMode(home, core, run = sh, platform = process.platform) {
|
|
|
365
376
|
return fs.existsSync(p) ? { mode: 'launchd', detail: p } : { mode: 'manual', detail: 'no launchd agent; run `kenaz install`' };
|
|
366
377
|
}
|
|
367
378
|
const unit = servicePlan(home, '', core, 'linux').unit;
|
|
368
|
-
if (fs.existsSync(unit) && probeLinux(run).systemd)
|
|
379
|
+
if (fs.existsSync(unit) && probeLinux(run).systemd) {
|
|
380
|
+
const u = linuxUser();
|
|
381
|
+
const off = /Linger=no/.test(run('loginctl', ['show-user', u, '-p', 'Linger']).stdout || '');
|
|
382
|
+
return off ? { mode: 'systemd', detail: unit + '; linger is off, the server starts only after login: run loginctl enable-linger ' + u, warn: true } : { mode: 'systemd', detail: unit };
|
|
383
|
+
}
|
|
369
384
|
const c = readCron(run);
|
|
370
385
|
if (c && c.includes(CRON_MARK)) return { mode: 'cron', detail: '@reboot crontab entry (no systemd user session)' };
|
|
371
386
|
return { mode: 'manual', detail: 'no systemd unit or cron entry; run `kenaz install`' };
|
|
@@ -103,7 +103,7 @@ function countLines(text) {
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
function git(args, cwd) {
|
|
106
|
-
const result = spawnSync('git', args, { cwd, encoding: 'utf8' });
|
|
106
|
+
const result = spawnSync('git', args, { windowsHide: true, cwd, encoding: 'utf8' });
|
|
107
107
|
return result;
|
|
108
108
|
}
|
|
109
109
|
|
|
@@ -40,7 +40,7 @@ const TASK_API = path.join(ROOT, '.collaboration', 'core', 'task-api.js');
|
|
|
40
40
|
// ─────────────────────────────────────────
|
|
41
41
|
|
|
42
42
|
function runTaskApi(...args) {
|
|
43
|
-
const result = spawnSync('node', [TASK_API, ...args], {
|
|
43
|
+
const result = spawnSync('node', [TASK_API, ...args], { windowsHide: true,
|
|
44
44
|
encoding: 'utf8',
|
|
45
45
|
timeout: 15000,
|
|
46
46
|
cwd: ROOT,
|
|
@@ -72,11 +72,11 @@ const DRY_RUN = !process.argv.includes('--apply');
|
|
|
72
72
|
// ─── Git helpers (GEN-008: dynamic root, never hardcoded) ────────────────────
|
|
73
73
|
|
|
74
74
|
function gitRoot() {
|
|
75
|
-
return execSync('git rev-parse --show-toplevel', { encoding: 'utf8' }).trim();
|
|
75
|
+
return execSync('git rev-parse --show-toplevel', { windowsHide: true, encoding: 'utf8' }).trim();
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
function currentBranch() {
|
|
79
|
-
return execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }).trim();
|
|
79
|
+
return execSync('git rev-parse --abbrev-ref HEAD', { windowsHide: true, encoding: 'utf8' }).trim();
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/**
|
|
@@ -84,7 +84,7 @@ function currentBranch() {
|
|
|
84
84
|
* Uses exit code of `git merge-base --is-ancestor <commit> HEAD`.
|
|
85
85
|
*/
|
|
86
86
|
function isAncestorOfHead(tipCommit) {
|
|
87
|
-
const result = spawnSync('git', ['merge-base', '--is-ancestor', tipCommit, 'HEAD'], {
|
|
87
|
+
const result = spawnSync('git', ['merge-base', '--is-ancestor', tipCommit, 'HEAD'], { windowsHide: true,
|
|
88
88
|
encoding: 'utf8',
|
|
89
89
|
});
|
|
90
90
|
return result.status === 0;
|
|
@@ -95,7 +95,7 @@ function isAncestorOfHead(tipCommit) {
|
|
|
95
95
|
* Each entry: { path, head, branch, locked, lockReason }
|
|
96
96
|
*/
|
|
97
97
|
function listWorktrees() {
|
|
98
|
-
const raw = execSync('git worktree list --porcelain', { encoding: 'utf8' });
|
|
98
|
+
const raw = execSync('git worktree list --porcelain', { windowsHide: true, encoding: 'utf8' });
|
|
99
99
|
const entries = [];
|
|
100
100
|
let current = null;
|
|
101
101
|
|
|
@@ -199,7 +199,7 @@ function listUntrackedAgentDirs(root, trackedPaths) {
|
|
|
199
199
|
function listDanglingAgentBranches(trackedBranches) {
|
|
200
200
|
let raw = '';
|
|
201
201
|
try {
|
|
202
|
-
raw = execSync('git branch --list "worktree-agent-*" --format="%(refname:short)"', { encoding: 'utf8' });
|
|
202
|
+
raw = execSync('git branch --list "worktree-agent-*" --format="%(refname:short)"', { windowsHide: true, encoding: 'utf8' });
|
|
203
203
|
} catch {
|
|
204
204
|
return [];
|
|
205
205
|
}
|
|
@@ -209,7 +209,7 @@ function listDanglingAgentBranches(trackedBranches) {
|
|
|
209
209
|
const b = line.trim();
|
|
210
210
|
if (!b || trackedSet.has(b)) continue;
|
|
211
211
|
let tip = '';
|
|
212
|
-
try { tip = execSync(`git rev-parse "${b}"`, { encoding: 'utf8' }).trim(); } catch { /* ignore */ }
|
|
212
|
+
try { tip = execSync(`git rev-parse "${b}"`, { windowsHide: true, encoding: 'utf8' }).trim(); } catch { /* ignore */ }
|
|
213
213
|
out.push({ branch: b, tip, integrated: tip ? isAncestorOfHead(tip) : false });
|
|
214
214
|
}
|
|
215
215
|
return out;
|
|
@@ -354,7 +354,7 @@ function main() {
|
|
|
354
354
|
// Unlock if locked (harness may have left lock even after pid is gone)
|
|
355
355
|
if (wt.locked) {
|
|
356
356
|
try {
|
|
357
|
-
execSync(`git worktree unlock "${wt.path}"`, { encoding: 'utf8' });
|
|
357
|
+
execSync(`git worktree unlock "${wt.path}"`, { windowsHide: true, encoding: 'utf8' });
|
|
358
358
|
} catch {
|
|
359
359
|
// unlock may fail if git disagrees — proceed, remove --force handles it
|
|
360
360
|
}
|
|
@@ -374,7 +374,7 @@ function main() {
|
|
|
374
374
|
|
|
375
375
|
// Remove worktree (--force bypasses remaining lock metadata)
|
|
376
376
|
try {
|
|
377
|
-
execSync(`git worktree remove --force "${wt.path}"`, { encoding: 'utf8' });
|
|
377
|
+
execSync(`git worktree remove --force "${wt.path}"`, { windowsHide: true, encoding: 'utf8' });
|
|
378
378
|
} catch (err) {
|
|
379
379
|
console.log(` FAILED (worktree remove): ${err.message.trim()}`);
|
|
380
380
|
failedCount++;
|
|
@@ -384,7 +384,7 @@ function main() {
|
|
|
384
384
|
// Delete the branch (best-effort; branch may already be deleted or missing)
|
|
385
385
|
if (wt.branch) {
|
|
386
386
|
try {
|
|
387
|
-
execSync(`git branch -D "${wt.branch}"`, { encoding: 'utf8' });
|
|
387
|
+
execSync(`git branch -D "${wt.branch}"`, { windowsHide: true, encoding: 'utf8' });
|
|
388
388
|
} catch {
|
|
389
389
|
// Branch may already be deleted — not an error
|
|
390
390
|
}
|
|
@@ -396,7 +396,7 @@ function main() {
|
|
|
396
396
|
|
|
397
397
|
// Prune stale worktree admin dirs (idempotent, always safe)
|
|
398
398
|
try {
|
|
399
|
-
execSync('git worktree prune', { encoding: 'utf8' });
|
|
399
|
+
execSync('git worktree prune', { windowsHide: true, encoding: 'utf8' });
|
|
400
400
|
console.log('\n git worktree prune done');
|
|
401
401
|
} catch (err) {
|
|
402
402
|
console.log(`\n git worktree prune FAILED (non-fatal): ${err.message.trim()}`);
|
|
@@ -419,7 +419,7 @@ function main() {
|
|
|
419
419
|
for (const b of danglingBranches) {
|
|
420
420
|
if (!b.integrated) continue; // keep not-in-HEAD branches for salvage
|
|
421
421
|
try {
|
|
422
|
-
execSync(`git branch -D "${b.branch}"`, { encoding: 'utf8' });
|
|
422
|
+
execSync(`git branch -D "${b.branch}"`, { windowsHide: true, encoding: 'utf8' });
|
|
423
423
|
danglingDeleted++;
|
|
424
424
|
} catch { /* already gone — not an error */ }
|
|
425
425
|
}
|
|
@@ -218,7 +218,7 @@ function parseCliArgs(argv) {
|
|
|
218
218
|
function resolveExecutableWindows(whereFn) {
|
|
219
219
|
whereFn = whereFn || function runWhere() {
|
|
220
220
|
try {
|
|
221
|
-
return cp.execSync('where claude', { encoding: 'utf8' });
|
|
221
|
+
return cp.execSync('where claude', { windowsHide: true, encoding: 'utf8' });
|
|
222
222
|
} catch (e) {
|
|
223
223
|
return '';
|
|
224
224
|
}
|
|
@@ -263,13 +263,13 @@ function escapeCmdExe(exe) {
|
|
|
263
263
|
|
|
264
264
|
function launch(exec, cwd, argv) {
|
|
265
265
|
if (exec.useShell) {
|
|
266
|
-
return cp.spawn(escapeCmdExe(exec.command), argv.map(escapeCmdArg), {
|
|
266
|
+
return cp.spawn(escapeCmdExe(exec.command), argv.map(escapeCmdArg), { windowsHide: true,
|
|
267
267
|
cwd,
|
|
268
268
|
stdio: 'inherit',
|
|
269
269
|
shell: true,
|
|
270
270
|
});
|
|
271
271
|
}
|
|
272
|
-
return cp.spawn(exec.command, argv, { cwd, stdio: 'inherit', shell: false });
|
|
272
|
+
return cp.spawn(exec.command, argv, { windowsHide: true, cwd, stdio: 'inherit', shell: false });
|
|
273
273
|
}
|
|
274
274
|
|
|
275
275
|
// ---- main ----
|
|
@@ -59,12 +59,12 @@ function start(name, exe, args, env, cwd) {
|
|
|
59
59
|
}
|
|
60
60
|
async function stop(p) {
|
|
61
61
|
if (!p || p.exited) return;
|
|
62
|
-
if (process.platform === 'win32') spawnSync('taskkill', ['/PID', String(p.pid), '/T', '/F'], { stdio: 'ignore' }); // our PID only
|
|
62
|
+
if (process.platform === 'win32') spawnSync('taskkill', ['/PID', String(p.pid), '/T', '/F'], { windowsHide: true, stdio: 'ignore' }); // our PID only
|
|
63
63
|
else p.child.kill('SIGKILL');
|
|
64
64
|
await until(`${p.name} exit`, () => p.exited, 15000, 100).catch(() => {});
|
|
65
65
|
}
|
|
66
66
|
function sh(cmd, args, env) {
|
|
67
|
-
const r = spawnSync(cmd, args, { env: { ...process.env, ...env }, encoding: 'utf8' });
|
|
67
|
+
const r = spawnSync(cmd, args, { windowsHide: true, env: { ...process.env, ...env }, encoding: 'utf8' });
|
|
68
68
|
return { code: r.status, out: `${r.stdout || ''}${r.stderr || ''}`.trim() };
|
|
69
69
|
}
|
|
70
70
|
function sqlite(file, readOnly = true) {
|
|
@@ -398,5 +398,5 @@ async function main() {
|
|
|
398
398
|
return bad ? 1 : 0;
|
|
399
399
|
}
|
|
400
400
|
|
|
401
|
-
process.on('SIGINT', () => { for (const p of procs) if (!p.exited) { if (process.platform === 'win32') spawnSync('taskkill', ['/PID', String(p.pid), '/T', '/F'], { stdio: 'ignore' }); else p.child.kill('SIGKILL'); } process.exit(130); });
|
|
401
|
+
process.on('SIGINT', () => { for (const p of procs) if (!p.exited) { if (process.platform === 'win32') spawnSync('taskkill', ['/PID', String(p.pid), '/T', '/F'], { windowsHide: true, stdio: 'ignore' }); else p.child.kill('SIGKILL'); } process.exit(130); });
|
|
402
402
|
main().then((c) => process.exit(c), (e) => { console.error(e); process.exit(1); });
|
|
@@ -142,7 +142,7 @@ function main() {
|
|
|
142
142
|
const build = spawnSync(
|
|
143
143
|
'cargo',
|
|
144
144
|
['test', '--lib', '--no-run', '--message-format=json'],
|
|
145
|
-
{ cwd: crateDir, encoding: 'utf8', shell: false, maxBuffer: 256 * 1024 * 1024, env }
|
|
145
|
+
{ windowsHide: true, cwd: crateDir, encoding: 'utf8', shell: false, maxBuffer: 256 * 1024 * 1024, env }
|
|
146
146
|
);
|
|
147
147
|
if (build.status !== 0) {
|
|
148
148
|
const compilerErrors = renderCompilerErrors(build.stdout);
|
|
@@ -180,7 +180,7 @@ function main() {
|
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
// 3. Run the artifact directly.
|
|
183
|
-
const run = spawnSync(testExe, exeArgs, { stdio: 'inherit' });
|
|
183
|
+
const run = spawnSync(testExe, exeArgs, { windowsHide: true, stdio: 'inherit' });
|
|
184
184
|
process.exit(run.status ?? 1);
|
|
185
185
|
}
|
|
186
186
|
|
|
@@ -36,7 +36,7 @@ function evaluate(streamText, expected) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
function copyRepo(dest) {
|
|
39
|
-
const files = execFileSync('git', ['ls-files', '-z'], { cwd: REPO, encoding: 'utf8', maxBuffer: 1 << 28 }).split('\0').filter(Boolean);
|
|
39
|
+
const files = execFileSync('git', ['ls-files', '-z'], { windowsHide: true, cwd: REPO, encoding: 'utf8', maxBuffer: 1 << 28 }).split('\0').filter(Boolean);
|
|
40
40
|
for (const f of files) {
|
|
41
41
|
const from = path.join(REPO, f);
|
|
42
42
|
if (!fs.existsSync(from)) continue;
|
|
@@ -49,11 +49,11 @@ function runScenario(sc, opts) {
|
|
|
49
49
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'skill-replay-'));
|
|
50
50
|
try {
|
|
51
51
|
copyRepo(dir);
|
|
52
|
-
execFileSync('git', ['init', '-q'], { cwd: dir });
|
|
52
|
+
execFileSync('git', ['init', '-q'], { windowsHide: true, cwd: dir });
|
|
53
53
|
const prompt = (sc.prefix === undefined ? '/Ansuz ' : sc.prefix) + sc.message;
|
|
54
54
|
// Prompt goes on stdin: with shell:true (needed on Windows) argv is concatenated unquoted, which split the message.
|
|
55
55
|
const r = spawnSync('claude', ['-p', '--output-format', 'stream-json', '--verbose', '--max-turns', String(opts.maxTurns)],
|
|
56
|
-
{ cwd: dir, input: prompt, encoding: 'utf8', maxBuffer: 1 << 28, timeout: opts.timeoutMs, shell: process.platform === 'win32' });
|
|
56
|
+
{ windowsHide: true, cwd: dir, input: prompt, encoding: 'utf8', maxBuffer: 1 << 28, timeout: opts.timeoutMs, shell: process.platform === 'win32' });
|
|
57
57
|
const ev = evaluate(r.stdout || '', sc.expected);
|
|
58
58
|
return { id: sc.id, expected: sc.expected, hit: ev.hit, calls: ev.calls, exit: r.status, error: r.error && r.error.message };
|
|
59
59
|
} finally {
|
|
@@ -120,7 +120,7 @@ async function testSlowServe() {
|
|
|
120
120
|
KENAZ_FIXTURE_SLOW_PHASE_MS: '4000',
|
|
121
121
|
});
|
|
122
122
|
const spawnedAt = Date.now();
|
|
123
|
-
const child = spawn(process.execPath, [SLOW_SERVE], { env, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
123
|
+
const child = spawn(process.execPath, [SLOW_SERVE], { windowsHide: true, env, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
124
124
|
spawnedPids.push(child.pid);
|
|
125
125
|
let out = '';
|
|
126
126
|
child.stdout.on('data', (d) => (out += d.toString()));
|
|
@@ -166,7 +166,7 @@ async function testSlowServe() {
|
|
|
166
166
|
|
|
167
167
|
async function testNeverListens() {
|
|
168
168
|
console.log('\n[selftest] never-listens.server.js');
|
|
169
|
-
const child = spawn(process.execPath, [NEVER_LISTENS], { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
169
|
+
const child = spawn(process.execPath, [NEVER_LISTENS], { windowsHide: true, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
170
170
|
spawnedPids.push(child.pid);
|
|
171
171
|
let exited = false;
|
|
172
172
|
child.on('exit', () => {
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// TASK_2474 guard: every child process Kenaz starts must be hidden on Windows.
|
|
3
|
+
// - Node: spawn/exec* calls in shipped JS must pass windowsHide (inline in the call, or on an options
|
|
4
|
+
// object defined in the same file). JS_ALLOW = intentionally visible terminals, with reasons.
|
|
5
|
+
// - Rust: Command::new in non-test Rust files outside common/process.rs must be hidden_command.
|
|
6
|
+
const test = require('node:test');
|
|
7
|
+
const assert = require('node:assert');
|
|
8
|
+
const fs = require('node:fs');
|
|
9
|
+
const path = require('node:path');
|
|
10
|
+
|
|
11
|
+
const ROOT = path.resolve(__dirname, '..', '..');
|
|
12
|
+
const JS_DIRS = ['.specialist/tools', '.formation', '.claude/hooks', 'plugins/kenaz/hooks', 'plugins/kenaz/scripts',
|
|
13
|
+
'.collaboration/core', 'packages/kenaz/lib', 'packages/kenaz/bin', 'dashboard/scripts', 'dev/scripts'];
|
|
14
|
+
const RS_DIR = 'dashboard/src-tauri/src';
|
|
15
|
+
|
|
16
|
+
// "relative/path.js:line" -> reason. Intentionally visible terminals only.
|
|
17
|
+
const JS_ALLOW = {
|
|
18
|
+
'dev/scripts/task1961/selftest.js:132': 'false positive: "spawn (took ..." inside a template-string message, not a call',
|
|
19
|
+
};
|
|
20
|
+
// "relative/path.rs" -> reason (whole file may use raw Command::new outside #[cfg(test)]).
|
|
21
|
+
const RS_ALLOW = {
|
|
22
|
+
'dashboard/src-tauri/src/common/process.rs': 'the hidden_command constructors themselves',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function walk(dir, exts, out = []) {
|
|
26
|
+
const abs = path.join(ROOT, dir);
|
|
27
|
+
if (!fs.existsSync(abs)) return out;
|
|
28
|
+
for (const e of fs.readdirSync(abs, { withFileTypes: true })) {
|
|
29
|
+
if (['node_modules', '.git', 'target', 'dist', 'fixtures'].includes(e.name)) continue;
|
|
30
|
+
const rel = dir + '/' + e.name;
|
|
31
|
+
if (e.isDirectory()) walk(rel, exts, out);
|
|
32
|
+
else if (exts.some((x) => e.name.endsWith(x)) && !/\.test\.[cm]?js$/.test(e.name)) out.push(rel);
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// plugins/kenaz/hooks/core-resolve.js is generated (gitignored) from .claude/hooks/core-resolve.js
|
|
38
|
+
const isGenerated = (rel) => rel === 'plugins/kenaz/hooks/core-resolve.js';
|
|
39
|
+
|
|
40
|
+
function matchParen(src, open) {
|
|
41
|
+
let depth = 0, q = null;
|
|
42
|
+
for (let i = open; i < src.length; i++) {
|
|
43
|
+
const c = src[i];
|
|
44
|
+
if (q) { if (c === '\\') i++; else if (c === q) q = null; continue; }
|
|
45
|
+
if (c === '"' || c === "'" || c === '`') { q = c; continue; }
|
|
46
|
+
if (c === '(') depth++;
|
|
47
|
+
else if (c === ')' && --depth === 0) return i;
|
|
48
|
+
}
|
|
49
|
+
return src.length;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function scanJs(rel, src) {
|
|
53
|
+
if (!/child_process/.test(src)) return [];
|
|
54
|
+
const bad = [];
|
|
55
|
+
// blank block comments and whole-line // comments (offsets and line numbers preserved)
|
|
56
|
+
src = src.replace(/\/\*[\s\S]*?\*\//g, (c) => c.replace(/[^\n]/g, ' ')).replace(/^[ \t]*\/\/.*$/gm, (c) => ' '.repeat(c.length));
|
|
57
|
+
const re = /(?<![\w$.])(?:(?:cp|child_process|childProcess|proc)\.)?(spawn|spawnSync|exec|execSync|execFile|execFileSync)\s*\(/g;
|
|
58
|
+
let m;
|
|
59
|
+
while ((m = re.exec(src))) {
|
|
60
|
+
const open = m.index + m[0].length - 1;
|
|
61
|
+
const args = src.slice(open, matchParen(src, open) + 1);
|
|
62
|
+
if (/windowsHide/.test(args)) continue;
|
|
63
|
+
// options passed as a bare identifier: accept when that identifier is defined with windowsHide in the file
|
|
64
|
+
const last = args.slice(1, -1).split(',').pop().trim();
|
|
65
|
+
if (/^[A-Za-z_$][\w$]*$/.test(last) && new RegExp(`${last}\\s*=\\s*\\{[^;]*windowsHide`).test(src)) continue;
|
|
66
|
+
const line = src.slice(0, m.index).split('\n').length;
|
|
67
|
+
if (JS_ALLOW[`${rel}:${line}`]) continue;
|
|
68
|
+
bad.push(`${rel}:${line} ${m[1]}`);
|
|
69
|
+
}
|
|
70
|
+
return bad;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function scanRs(rel, src) {
|
|
74
|
+
if (RS_ALLOW[rel]) return [];
|
|
75
|
+
const cut = src.search(/#\[cfg\(test\)\]/);
|
|
76
|
+
const body = cut >= 0 ? src.slice(0, cut) : src;
|
|
77
|
+
const bad = [];
|
|
78
|
+
body.split('\n').forEach((ln, i) => {
|
|
79
|
+
if (/^\s*\/\//.test(ln)) return;
|
|
80
|
+
if (/Command::new\s*\(/.test(ln) && !/hidden_/.test(ln)) bad.push(`${rel}:${i + 1}`);
|
|
81
|
+
});
|
|
82
|
+
return bad;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
test('Node: every child_process call passes windowsHide', () => {
|
|
86
|
+
const files = JS_DIRS.flatMap((d) => walk(d, ['.js', '.cjs', '.mjs'])).filter((f) => !isGenerated(f));
|
|
87
|
+
const bad = files.flatMap((f) => scanJs(f, fs.readFileSync(path.join(ROOT, f), 'utf8')));
|
|
88
|
+
console.log(`node violations: ${bad.length}`);
|
|
89
|
+
assert.deepStrictEqual(bad, []);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('Rust: no raw Command::new in production code outside common/process.rs', () => {
|
|
93
|
+
const files = walk(RS_DIR, ['.rs']).filter((f) => !/(^|\/)tests?\.rs$|_tests?\.rs$|\/tests\//.test(f));
|
|
94
|
+
const bad = files.flatMap((f) => scanRs(f, fs.readFileSync(path.join(ROOT, f), 'utf8')));
|
|
95
|
+
console.log(`rust violations: ${bad.length}`);
|
|
96
|
+
assert.deepStrictEqual(bad, []);
|
|
97
|
+
});
|
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
- Code navigation: kenaz_lsp_callers / kenaz_lsp_references / kenaz_lsp_definition / kenaz_lsp_symbols (always pass projectPath). Text search: Grep/Glob.
|
|
3
3
|
- Collaboration: kenaz_peer_send / kenaz_peer_threads (other sessions, other machines, Codex), /kenaz ygg status|join.
|
|
4
4
|
- Rooms: when the user pastes a room key or asks to join/create a room, run `kenaz ygg join <key>` / `kenaz ygg create` yourself (never ask them to type it), then relay the status block and any "restart Claude Code" note.
|
|
5
|
+
- Reporting a Kenaz problem or idea: call kenaz_wish_create (scope kenaz) yourself; it uploads to the Kenaz mother (Alaya) automatically, no user step. Claude Code's SendFeedback tool and /feedback go to Anthropic, never to Kenaz.
|
|
5
6
|
- Reply in the user's language. Commands: /Ansuz, /Amelia, /review, /security, /incident, /spec.
|
|
6
7
|
- Switch: /kenaz off | assist | full (or env KENAZ_MODE). off disables every Kenaz hook.
|
|
@@ -221,7 +221,7 @@ if (require.main === module) {
|
|
|
221
221
|
if (!result) process.exit(0); // silent -- non-blocking hook
|
|
222
222
|
|
|
223
223
|
try {
|
|
224
|
-
execFileSync("node", [result.resolved, ...result.args], { stdio: "inherit" });
|
|
224
|
+
execFileSync("node", [result.resolved, ...result.args], { stdio: "inherit", windowsHide: true });
|
|
225
225
|
} catch {
|
|
226
226
|
// Hook errors should not block
|
|
227
227
|
}
|
|
@@ -13,7 +13,8 @@ const fs = require('fs');
|
|
|
13
13
|
const path = require('path');
|
|
14
14
|
const net = require('net');
|
|
15
15
|
const http = require('http');
|
|
16
|
-
const
|
|
16
|
+
const os = require('os');
|
|
17
|
+
const { spawn, spawnSync } = require('child_process');
|
|
17
18
|
const { resolveMode, allows, projectDir } = require('./mode');
|
|
18
19
|
const { isSdkSession } = require('./sdk-gate');
|
|
19
20
|
|
|
@@ -49,6 +50,42 @@ function backendUp(cb) {
|
|
|
49
50
|
s.on('error', () => done(false));
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
// TASK_2468: after a reboot nothing has started kenaz-server yet (the plugin MCP is a static http URL).
|
|
54
|
+
// Start the installed binary detached, the way the installer does; never by process name, and only
|
|
55
|
+
// called after the port probe failed (a second server is never started over an answering one).
|
|
56
|
+
function startServer(dir) {
|
|
57
|
+
try {
|
|
58
|
+
const home = os.homedir();
|
|
59
|
+
const meta = JSON.parse(fs.readFileSync(path.join(home, '.kenaz', 'install.json'), 'utf8'));
|
|
60
|
+
const bin = meta && meta.serverBin;
|
|
61
|
+
if (!bin || !fs.existsSync(bin)) return false;
|
|
62
|
+
const vbs = path.join(home, '.kenaz', 'kenaz-server.vbs');
|
|
63
|
+
const core = coreDir(dir);
|
|
64
|
+
const env = Object.assign({}, process.env, core ? { KENAZ_SOURCE_DIR: core } : {});
|
|
65
|
+
const opts = { env, detached: true, stdio: 'ignore', windowsHide: true };
|
|
66
|
+
const viaNode = /\.js$/.test(bin); // a script (tests) runs under node; the real server is a binary
|
|
67
|
+
let child;
|
|
68
|
+
if (process.platform === 'win32') {
|
|
69
|
+
child = fs.existsSync(vbs) ? spawn('wscript.exe', [vbs], opts) : viaNode ? spawn(process.execPath, [bin], opts) : spawn(bin, [], opts);
|
|
70
|
+
} else {
|
|
71
|
+
const log = path.join(home, '.kenaz', 'kenaz-server.log');
|
|
72
|
+
const sq = (v) => "'" + String(v).replace(/'/g, "'\\''") + "'";
|
|
73
|
+
const cmd = 'if command -v setsid >/dev/null 2>&1; then S=setsid; else S=; fi; $S nohup ' +
|
|
74
|
+
(viaNode ? sq(process.execPath) + ' ' : '') + sq(bin) + ' >> ' + sq(log) + ' 2>&1 < /dev/null &';
|
|
75
|
+
child = spawn('sh', ['-c', cmd], opts);
|
|
76
|
+
}
|
|
77
|
+
child.on('error', () => {});
|
|
78
|
+
child.unref();
|
|
79
|
+
return true;
|
|
80
|
+
} catch (_) { return false; }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function waitForBackend(ms, cb) {
|
|
84
|
+
const end = Date.now() + ms;
|
|
85
|
+
const tick = () => backendUp((ok) => { if (ok || Date.now() >= end) return cb(ok); setTimeout(tick, 150); });
|
|
86
|
+
tick();
|
|
87
|
+
}
|
|
88
|
+
|
|
52
89
|
function post(body, cb) {
|
|
53
90
|
const r = http.request({ hostname: HOST, port: PORT, path: '/api/rust/agent-flow/hook', method: 'POST',
|
|
54
91
|
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) }, timeout: 3000 },
|
|
@@ -75,7 +112,7 @@ function run(spec, stdin, dir) {
|
|
|
75
112
|
const stdio = ['pipe', 'inherit', 'ignore'];
|
|
76
113
|
if (spec.kind === 'core-script') {
|
|
77
114
|
const target = path.join(core, spec.rel);
|
|
78
|
-
if (fs.existsSync(target)) spawnSync(process.execPath, [target, ...(spec.args || [])], { cwd: dir, env, input: stdin, stdio, timeout: 10000 });
|
|
115
|
+
if (fs.existsSync(target)) spawnSync(process.execPath, [target, ...(spec.args || [])], { cwd: dir, env, input: stdin, stdio, timeout: 10000, windowsHide: true });
|
|
79
116
|
return;
|
|
80
117
|
}
|
|
81
118
|
const file = path.join(core, '.claude', 'hooks', spec.file);
|
|
@@ -83,7 +120,7 @@ function run(spec, stdin, dir) {
|
|
|
83
120
|
// Same shape as the core's own `node -e "chdir; require(hook)"` wrappers (require.main stays undefined).
|
|
84
121
|
const code = 'process.chdir(process.env.CLAUDE_PROJECT_DIR);const m=require(process.argv[1]);' +
|
|
85
122
|
(spec.call ? 'm[process.argv[2]]();' : '');
|
|
86
|
-
spawnSync(process.execPath, ['-e', code, file, spec.call || ''], { cwd: dir, env, input: stdin, stdio, timeout: 10000 });
|
|
123
|
+
spawnSync(process.execPath, ['-e', code, file, spec.call || ''], { cwd: dir, env, input: stdin, stdio, timeout: 10000, windowsHide: true });
|
|
87
124
|
}
|
|
88
125
|
|
|
89
126
|
function main() {
|
|
@@ -105,7 +142,18 @@ function main() {
|
|
|
105
142
|
}
|
|
106
143
|
run(spec, stdin, dir);
|
|
107
144
|
};
|
|
108
|
-
if (spec.backend)
|
|
145
|
+
if (!spec.backend) return go();
|
|
146
|
+
backendUp((ok) => {
|
|
147
|
+
if (ok) return go();
|
|
148
|
+
if (spec.kind !== 'session-start') return;
|
|
149
|
+
const finish = (up) => {
|
|
150
|
+
if (up) go();
|
|
151
|
+
process.stdout.write(up
|
|
152
|
+
? 'kenaz-server was not running; the Kenaz hook started it on ' + HOST + ':' + PORT + '. If the kenaz MCP tools (kenaz-dashboard) show as failed, ask the user to run /mcp to reconnect them (they connected before the server was up).\n'
|
|
153
|
+
: 'kenaz-server is not running on ' + HOST + ':' + PORT + ', so the kenaz MCP tools are unavailable. Ask the user to run `! npx kenaz install` (registers the boot service and starts it), then /mcp to reconnect kenaz-dashboard.\n');
|
|
154
|
+
};
|
|
155
|
+
if (startServer(dir)) waitForBackend(3000, finish); else finish(false);
|
|
156
|
+
});
|
|
109
157
|
}
|
|
110
158
|
|
|
111
159
|
process.on('uncaughtException', () => process.exit(0));
|