@ohos-cpf/3rdloop 0.0.2 → 0.0.3
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/README.md +244 -244
- package/bin/3rdloop.mjs +46 -46
- package/lib/cli.js +781 -781
- package/lib/config-cmd.js +451 -451
- package/lib/config.js +318 -318
- package/lib/doctor.js +113 -113
- package/lib/exit-codes.js +30 -30
- package/lib/opencode.js +155 -155
- package/lib/orch.js +426 -426
- package/lib/queries.js +263 -263
- package/lib/step.js +325 -325
- package/lib/ui.js +222 -222
- package/lib/update.js +279 -279
- package/lib/workflow.js +308 -308
- package/lib/workflows.js +131 -131
- package/package.json +50 -50
- package/vendor/Server/Agent/SkillSelector/README.md +343 -343
- package/vendor/Server/Agent/SkillSelector/core/Agent.js +207 -207
- package/vendor/Server/Agent/SkillSelector/index.js +14 -14
- package/vendor/Server/Agent/SkillSelector/llm/llmClient.js +313 -313
- package/vendor/Server/Agent/SkillSelector/llm/prompts.js +161 -161
- package/vendor/Server/Agent/SkillSelector/llm/reactSteps.js +144 -144
- package/vendor/Server/Agent/SkillSelector/matcher/fuzzyMatcher.js +433 -433
- package/vendor/Server/Agent/SkillSelector/scanner/skillScanner.js +382 -382
- package/vendor/Server/Agent/SkillSelector/utils/actionWords.js +59 -59
- package/vendor/Server/Brain/AnalysisStrategies.js +422 -422
- package/vendor/Server/Brain/Brain.js +686 -686
- package/vendor/Server/Brain/DecompositionStrategies.js +621 -621
- package/vendor/Server/Brain/PlanPersistence.js +196 -196
- package/vendor/Server/Brain/SkillExecutor.js +251 -251
- package/vendor/Server/Brain/index.js +11 -11
- package/vendor/Server/CLI/cli.js +275 -275
- package/vendor/Server/CLI/deveco-code/index.js +71 -71
- package/vendor/Server/CLI/deveco-code.js +5 -5
- package/vendor/Server/CLI/opencode/index.js +817 -818
- package/vendor/Server/CLI/opencode.js +5 -5
- package/vendor/Server/DbUse/MessageArchive.js +61 -61
- package/vendor/Server/DbUse/StorageManager.js +107 -107
- package/vendor/Server/DbUse/adapters/BaseAdapter.js +94 -94
- package/vendor/Server/DbUse/adapters/FileAdapter.js +138 -138
- package/vendor/Server/DbUse/adapters/JsonAdapter.js +138 -138
- package/vendor/Server/DbUse/adapters/JsonlAdapter.js +114 -114
- package/vendor/Server/DbUse/adapters/SqliteAdapter.js +157 -157
- package/vendor/Server/DbUse/index.js +160 -160
- package/vendor/Server/DbUse/stores/SessionStore.js +279 -279
- package/vendor/Server/DbUse/stores/TaskExecutionStore.js +133 -133
- package/vendor/Server/DbUse/stores/TaskRegistryStore.js +262 -262
- package/vendor/Server/DbUse/stores/TaskStepStore.js +279 -279
- package/vendor/Server/FlexRunner/FlexRunner.js +1759 -1759
- package/vendor/Server/FlexRunner/index.js +12 -12
- package/vendor/Server/Knowledge/KnowledgeImporter.js +523 -523
- package/vendor/Server/Knowledge/KnowledgeManager.js +341 -341
- package/vendor/Server/Knowledge/index.js +33 -33
- package/vendor/Server/LoopEngine/LoopEngine.js +1133 -1133
- package/vendor/Server/LoopEngine/index.js +11 -11
- package/vendor/Server/Orchestrator/Orchestrator.js +0 -3
- package/vendor/Server/Orchestrator/StepNode.js +312 -312
- package/vendor/Server/Orchestrator/index.js +13 -13
- package/vendor/Server/Routes/controllers/BrainController.js +241 -241
- package/vendor/Server/Routes/controllers/FlexRunnerController.js +1125 -1125
- package/vendor/Server/Routes/controllers/HealthController.js +44 -44
- package/vendor/Server/Routes/controllers/KnowledgeImportController.js +355 -355
- package/vendor/Server/Routes/controllers/LoopEngineController.js +788 -788
- package/vendor/Server/Routes/controllers/StatsController.js +57 -57
- package/vendor/Server/Routes/controllers/StreamController.js +67 -67
- package/vendor/Server/Routes/library/logger.js +179 -179
- package/vendor/Server/Routes/library/zipArchive.js +172 -172
- package/vendor/Server/Routes/router/Router.js +204 -204
- package/vendor/Server/Routes/routes/brain.js +47 -47
- package/vendor/Server/Routes/routes/flexrunner.js +72 -72
- package/vendor/Server/Routes/routes/health.js +28 -28
- package/vendor/Server/Routes/routes/index.js +57 -57
- package/vendor/Server/Routes/routes/knowledge.js +55 -55
- package/vendor/Server/Routes/routes/loopengine.js +58 -58
- package/vendor/Server/Routes/routes/orchestrator.js +61 -61
- package/vendor/Server/Routes/routes/registry.js +97 -97
- package/vendor/Server/Routes/routes/stats.js +23 -23
- package/vendor/Server/Routes/routes/stream.js +30 -30
- package/vendor/Server/Routes/server.js +203 -203
- package/vendor/Server/Routes/sse/SseHub.js +308 -308
- package/vendor/Server/Skills/acceptance-check/SKILL.md +191 -191
- package/vendor/Server/Skills/acceptance-check/references/PHASE1_ARTIFACT_COLLECTION.md +52 -52
- package/vendor/Server/Skills/acceptance-check/references/PHASE2_CRITERIA_EVALUATION.md +77 -77
- package/vendor/Server/Skills/acceptance-check/references/PHASE2_EVIDENCE_VERIFICATION.md +70 -70
- package/vendor/Server/Skills/arkts-code-check/SKILL.md +320 -320
- package/vendor/Server/Skills/arkts-code-check/references/CODE_CHECK_GUIDE.md +210 -210
- package/vendor/Server/Skills/arkts-code-check/references/FILE_TYPE_GUIDE.md +28 -28
- package/vendor/Server/Skills/arkts-code-check/references/PHASE1_INFO_COLLECTION.md +233 -233
- package/vendor/Server/Skills/arkts-code-check/references/REPORT_TEMPLATE.md +219 -219
- package/vendor/Server/Skills/arkts-library-compile-validate/SKILL.md +328 -328
- package/vendor/Server/Skills/arkts-library-compile-validate/scripts/build.ps1 +93 -93
- package/vendor/Server/Skills/arkts-library-compile-validate/scripts/code-linter.cjs +432 -432
- package/vendor/Server/Skills/arkts-library-compile-validate/scripts/migrate.cjs +851 -851
- package/vendor/Server/Skills/arkts-library-compile-validate/scripts/ohpm-switch.cjs +788 -788
- package/vendor/Server/Skills/arkts-library-demo-code/SKILL.md +291 -291
- package/vendor/Server/Skills/arkts-library-demo-code/references/API_SIGNATURE_CHECKS.md +68 -68
- package/vendor/Server/Skills/arkts-library-demo-code/references/BUILD_VALIDATION.md +184 -184
- package/vendor/Server/Skills/arkts-library-demo-code/references/CODE_STANDARDS.md +337 -337
- package/vendor/Server/Skills/arkts-library-demo-code/references/EXAMPLES.md +400 -400
- package/vendor/Server/Skills/arkts-library-demo-code/references/SYSTEM_API_LOOKUP.md +98 -98
- package/vendor/Server/Skills/arkts-library-demo-code/references/TEMPLATE.md +544 -544
- package/vendor/Server/Skills/arkts-library-demo-code/scripts/build.ps1 +93 -93
- package/vendor/Server/Skills/arkts-library-demo-code/scripts/code-linter.cjs +432 -432
- package/vendor/Server/Skills/arkts-library-demo-code/scripts/migrate.cjs +851 -851
- package/vendor/Server/Skills/arkts-library-demo-code/scripts/ohpm-switch.cjs +788 -788
- package/vendor/Server/Skills/arkts-library-demo-coverage/SKILL.md +174 -174
- package/vendor/Server/Skills/arkts-library-demo-scenario/SKILL.md +321 -321
- package/vendor/Server/Skills/arkts-library-demo-scenario/references/EXAMPLES.md +100 -100
- package/vendor/Server/Skills/arkts-library-demo-scenario/references/TEMPLATE.md +185 -185
- package/vendor/Server/Skills/arkts-library-documentation-quality-check/SKILL.md +233 -233
- package/vendor/Server/Skills/arkts-library-documentation-quality-check/assets/REPORT_TEMPLATE.md +102 -102
- package/vendor/Server/Skills/arkts-library-documentation-quality-check/references/CHECK_DIMENSIONS.md +89 -89
- package/vendor/Server/Skills/arkts-library-documentation-quality-check/references/COMPLIANCE_CHECKLIST.md +62 -62
- package/vendor/Server/Skills/arkts-library-documentation-quality-check/references/KB_QUERY_GUIDE.md +107 -107
- package/vendor/Server/Skills/arkts-library-documentation-quality-check/references/MCP_TOOL_DISCOVERY.md +124 -124
- package/vendor/Server/Skills/arkts-library-documentation-quality-check/references/REPORT_TEMPLATE.md +90 -90
- package/vendor/Server/Skills/arkts-library-documentation-quality-check/references/SCORING_FORMULA.md +57 -57
- package/vendor/Server/Skills/arkts-library-documentation-quality-check/scripts/validate-skill.cjs +259 -259
- package/vendor/Server/Skills/arkts-library-interface-spec/SKILL.md +97 -97
- package/vendor/Server/Skills/arkts-library-memory-leak-check/SKILL.md +391 -391
- package/vendor/Server/Skills/arkts-library-source-clone/SKILL.md +113 -113
- package/vendor/Server/Skills/arkts-library-stability-check/SKILL.md +312 -312
- package/vendor/Server/Skills/arkts-library-stability-check/assets/REPORT_TEMPLATE.md +154 -154
- package/vendor/Server/Skills/arkts-library-stability-check/references/CHECKLIST.md +165 -165
- package/vendor/Server/Skills/arkts-library-stability-check/references/CODE_EXAMPLES.md +308 -308
- package/vendor/Server/Skills/arkts-library-stability-check/references/SCORING_RULES.md +90 -90
- package/vendor/Server/Skills/arkts-library-stability-check/scripts/validate-skill.cjs +282 -282
- package/vendor/Server/Skills/arkts-library-test-coverage-check/SKILL.md +360 -360
- package/vendor/Server/Skills/arkts-library-test-coverage-check/assets/REPORT_TEMPLATE.md +145 -145
- package/vendor/Server/Skills/arkts-library-test-coverage-check/references/CHECKLIST.md +252 -252
- package/vendor/Server/Skills/arkts-library-test-coverage-check/references/MCP_TOOL_USAGE.md +114 -114
- package/vendor/Server/Skills/arkts-library-test-coverage-check/scripts/validate-skill.cjs +262 -262
- package/vendor/Server/Skills/arkts-library-xts-code/SKILL.md +455 -455
- package/vendor/Server/Skills/arkts-library-xts-code/assets/report-template.md +60 -60
- package/vendor/Server/Skills/arkts-library-xts-code/references/ACCESS_MODIFIER_PRECHECK.md +76 -76
- package/vendor/Server/Skills/arkts-library-xts-code/references/BUILD_VERIFICATION.md +200 -200
- package/vendor/Server/Skills/arkts-library-xts-code/references/CODE_STANDARDS.md +518 -518
- package/vendor/Server/Skills/arkts-library-xts-code/references/SUBAGENT_PROMPT_TEMPLATE.md +276 -276
- package/vendor/Server/Skills/arkts-library-xts-code/references/SYSTEM_API_LOOKUP.md +92 -92
- package/vendor/Server/Skills/arkts-library-xts-code/references/XTS_TEMPLATE.md +767 -767
- package/vendor/Server/Skills/arkts-library-xts-code/scripts/build.ps1 +93 -93
- package/vendor/Server/Skills/arkts-library-xts-code/scripts/code-linter.cjs +432 -432
- package/vendor/Server/Skills/arkts-library-xts-code/scripts/migrate.cjs +851 -851
- package/vendor/Server/Skills/arkts-library-xts-code/scripts/ohpm-switch.cjs +788 -788
- package/vendor/Server/Skills/arkts-library-xts-code/scripts/precheck-access-modifiers.cjs +221 -221
- package/vendor/Server/Skills/arkts-library-xts-code-fix/SKILL.md +228 -228
- package/vendor/Server/Skills/arkts-library-xts-coverage/SKILL.md +97 -97
- package/vendor/Server/Skills/arkts-library-xts-doc/SKILL.md +194 -194
- package/vendor/Server/Skills/arkts-library-xts-doc/references/EXAMPLES.md +575 -575
- package/vendor/Server/Skills/arkts-library-xts-doc/references/TEMPLATE.md +574 -574
- package/vendor/Server/Skills/arkts-library-xts-doc/references/TESTABILITY_GUIDE.md +182 -182
- package/vendor/Server/Skills/arkts-library-xts-execution/SKILL.md +490 -490
- package/vendor/Server/Skills/arkts-library-xts-execution/references/error-fixing-examples.md +217 -217
- package/vendor/Server/Skills/arkts-library-xts-execution/scripts/build.ps1 +93 -93
- package/vendor/Server/Skills/arkts-library-xts-execution/scripts/code-linter.cjs +432 -432
- package/vendor/Server/Skills/arkts-library-xts-execution/scripts/migrate.cjs +851 -851
- package/vendor/Server/Skills/arkts-library-xts-execution/scripts/ohpm-switch.cjs +788 -788
- package/vendor/Server/Skills/flutter-code-check/SKILL.md +299 -299
- package/vendor/Server/Skills/flutter-code-check/assets/OUTPUT_TEMPLATE.md +311 -311
- package/vendor/Server/Skills/flutter-code-check/references/CHECKLIST.md +190 -190
- package/vendor/Server/Skills/flutter-code-check/references/PLATFORMS.md +133 -133
- package/vendor/Server/Skills/flutter-code-check/scripts/validate-skill.cjs +259 -259
- package/vendor/Server/Skills/flutter-interface/README.md +75 -75
- package/vendor/Server/Skills/flutter-interface/SKILL.md +291 -291
- package/vendor/Server/Skills/flutter-interface/references/EXAMPLES.md +336 -336
- package/vendor/Server/Skills/flutter-interface/references/GIT_CLONE_GUIDE.md +190 -190
- package/vendor/Server/Skills/flutter-interface/references/SCRIPT_REFERENCE.md +258 -258
- package/vendor/Server/Skills/flutter-interface/references/TEMPLATE.md +254 -254
- package/vendor/Server/Skills/flutter-library-consistency-check/SKILL.md +517 -517
- package/vendor/Server/Skills/flutter-library-consistency-check/references/CHECKLIST.md +381 -381
- package/vendor/Server/Skills/flutter-library-consistency-check/references/FUNCTION_COMPARISON_GUIDE.md +341 -341
- package/vendor/Server/Skills/flutter-library-consistency-check/references/PLATFORM_LIMITATION_GUIDE.md +71 -71
- package/vendor/Server/Skills/flutter-library-documentation-quality-check/SKILL.md +518 -518
- package/vendor/Server/Skills/flutter-library-documentation-quality-check/references/CHECKLIST.md +406 -406
- package/vendor/Server/Skills/flutter-library-memory-leak-check/SKILL.md +652 -652
- package/vendor/Server/Skills/flutter-library-memory-leak-check/references/CHECKLIST.md +396 -396
- package/vendor/Server/Skills/flutter-library-stability-check/SKILL.md +744 -744
- package/vendor/Server/Skills/flutter-library-stability-check/references/CHECKLIST.md +720 -720
- package/vendor/Server/Skills/flutter-library-test-coverage-check/SKILL.md +414 -414
- package/vendor/Server/Skills/flutter-library-test-coverage-check/assets/REPORT_TEMPLATE.md +150 -150
- package/vendor/Server/Skills/flutter-library-test-coverage-check/references/CHECKLIST.md +304 -304
- package/vendor/Server/Skills/flutter-library-test-coverage-check/references/SCORING_RULES.md +265 -265
- package/vendor/Server/Skills/flutter-library-test-coverage-check/references/SCRIPT_USAGE.md +286 -286
- package/vendor/Server/Skills/knowledge-import/SKILL.md +383 -383
- package/vendor/Server/Skills/knowledge-import/references/MCP_TOOL_USAGE.md +165 -165
- package/vendor/Server/Skills/knowledge-import/references/SKILL_LOCATOR_GUIDE.md +91 -91
- package/vendor/Server/Skills/knowledge-import/references/SKILL_OPTIMIZATION_GUIDE.md +127 -127
- package/vendor/Server/Skills/ohos-lib-pr-push/SKILL.md +453 -301
- package/vendor/Server/Skills/ohos-lib-pr-push/assets/PR_CHECKLIST.md +151 -0
- package/vendor/Server/Skills/ohos-lib-pr-push/assets/PR_ISSUE_TEMPLATE.md +257 -105
- package/vendor/Server/Skills/ohos-lib-pr-push/references/GITCODE_API.md +191 -127
- package/vendor/Server/Skills/ohos-lib-pr-push/scripts/gitcode-api.cjs +317 -208
- package/vendor/Server/Skills/rn-code-check/SKILL.md +320 -320
- package/vendor/Server/Skills/rn-code-check/references/API-GUIDE.md +234 -234
- package/vendor/Server/Skills/rn-code-check/references/CHECKLIST.md +188 -188
- package/vendor/Server/Skills/rn-code-check/references/REPORT-TEMPLATE.md +246 -246
- package/vendor/Server/Skills/rn-lib-add-example/SKILL.md +198 -198
- package/vendor/Server/Skills/rn-lib-add-example/references/APP_RENAME_GUIDE.md +40 -40
- package/vendor/Server/Skills/rn-lib-add-example/references/SHELL_ADAPTATION_CHECKLIST.md +78 -78
- package/vendor/Server/Skills/rn-lib-add-example/references/TEMPLATE_REPO_GUIDE.md +70 -70
- package/vendor/Server/Skills/rn-lib-add-example/references/VERIFICATION_GUIDE.md +47 -47
- package/vendor/Server/Skills/rn-lib-add-example/scripts/create-example.cjs +252 -252
- package/vendor/Server/Skills/rn-lib-update-doc/SKILL.md +176 -176
- package/vendor/Server/Skills/rn-lib-update-doc/config.json +5 -5
- package/vendor/Server/Skills/rn-lib-update-doc/references/changelog-template.md +35 -35
- package/vendor/Server/Skills/rn-lib-update-doc/references/format-diff.md +137 -137
- package/vendor/Server/Skills/rn-lib-update-doc/references/link-registry.json +33 -33
- package/vendor/Server/Skills/rn-lib-update-doc/references/model-0.4.2-overview.md +40 -40
- package/vendor/Server/Skills/rn-lib-update-doc/references/model-0.4.2.md +429 -429
- package/vendor/Server/Skills/rn-lib-update-doc/scripts/detect-readme-format.cjs +105 -105
- package/vendor/Server/Skills/rn-lib-update-doc/scripts/find-usage-doc.cjs +90 -90
- package/vendor/Server/Skills/rn-lib-update-doc/scripts/link-verify.cjs +213 -213
- package/vendor/Server/Skills/rn-lib-update-doc/scripts/normalize-changelog.cjs +73 -73
- package/vendor/Server/Skills/rn-lib-update-doc/scripts/normalize-package-meta.cjs +258 -258
- package/vendor/Server/Skills/rn-lib-update-doc/scripts/normalize-readme-links.cjs +341 -341
- package/vendor/Server/Skills/rn-lib-update-doc/scripts/resolve-usage-docs.cjs +67 -67
- package/vendor/Server/Skills/rn-library-consistency-check/SKILL.md +299 -299
- package/vendor/Server/Skills/rn-library-consistency-check/assets/REPORT_TEMPLATE.md +293 -293
- package/vendor/Server/Skills/rn-library-consistency-check/references/ARKTS_COMPONENT_CHECK_GUIDE.md +857 -857
- package/vendor/Server/Skills/rn-library-consistency-check/references/ARKTS_TURBOMODULE_CHECK_GUIDE.md +856 -856
- package/vendor/Server/Skills/rn-library-consistency-check/references/CHECKLIST.md +157 -157
- package/vendor/Server/Skills/rn-library-consistency-check/references/CPP_COMPONENT_CHECK_GUIDE.md +801 -801
- package/vendor/Server/Skills/rn-library-consistency-check/references/CPP_TURBOMODULE_CHECK_GUIDE.md +683 -683
- package/vendor/Server/Skills/rn-library-consistency-check/references/FUNCTION_COMPARISON_GUIDE.md +233 -233
- package/vendor/Server/Skills/rn-library-consistency-check/references/NATIVE_COMPONENT_IDENTIFICATION.md +1373 -1373
- package/vendor/Server/Skills/rn-library-consistency-check/references/SCORING_STANDARD.md +220 -220
- package/vendor/Server/Skills/rn-library-consistency-check/scripts/validate-skill.py +245 -245
- package/vendor/Server/Skills/rn-library-documentation-quality-check/SKILL.md +263 -263
- package/vendor/Server/Skills/rn-library-documentation-quality-check/assets/MODEL.md +414 -414
- package/vendor/Server/Skills/rn-library-documentation-quality-check/assets/MODEL_en.md +413 -413
- package/vendor/Server/Skills/rn-library-documentation-quality-check/assets/REPORT_TEMPLATE.md +311 -311
- package/vendor/Server/Skills/rn-library-documentation-quality-check/references/CHECK_CHECKLIST.md +355 -355
- package/vendor/Server/Skills/rn-library-documentation-quality-check/references/CROSS_VALIDATION_GUIDE.md +115 -115
- package/vendor/Server/Skills/rn-library-documentation-quality-check/references/DOC_COLLECTION_GUIDE.md +139 -139
- package/vendor/Server/Skills/rn-library-documentation-quality-check/references/EXAMPLES.md +586 -586
- package/vendor/Server/Skills/rn-library-documentation-quality-check/references/GOTCHAS.md +57 -57
- package/vendor/Server/Skills/rn-library-documentation-quality-check/scripts/validate-skill.py +259 -259
- package/vendor/Server/Skills/rn-library-interface-analyzer/SKILL.md +301 -301
- package/vendor/Server/Skills/rn-library-interface-analyzer/assets/REPORT_TEMPLATE.md +148 -148
- package/vendor/Server/Skills/rn-library-interface-analyzer/references/DOC_ANNOTATION_GUIDE.md +118 -118
- package/vendor/Server/Skills/rn-library-interface-analyzer/references/SCRIPT_USAGE_GUIDE.md +168 -168
- package/vendor/Server/Skills/rn-library-interface-analyzer/references/URL_PARSING_RULES.md +176 -176
- package/vendor/Server/Skills/rn-library-issue-generalizer/SKILL.md +274 -274
- package/vendor/Server/Skills/rn-library-issue-generalizer/assets/case-template.md +45 -45
- package/vendor/Server/Skills/rn-library-issue-generalizer/assets/rule-template.md +25 -25
- package/vendor/Server/Skills/rn-library-issue-generalizer/references/PR_FETCH_GUIDE.md +61 -61
- package/vendor/Server/Skills/rn-library-issue-generalizer/references/RULE_TEMPLATE_GUIDE.md +165 -165
- package/vendor/Server/Skills/rn-library-issue-generalizer/scripts/fetch-pr-info.py +239 -239
- package/vendor/Server/Skills/rn-library-known-issue-check/SKILL.md +263 -263
- package/vendor/Server/Skills/rn-library-known-issue-check/assets/REPORT_TEMPLATE.md +96 -96
- package/vendor/Server/Skills/rn-library-known-issue-check/references/COMPLIANCE_CHECKLIST.md +57 -57
- package/vendor/Server/Skills/rn-library-known-issue-check/references/INSPECTION_GUIDE.md +99 -99
- package/vendor/Server/Skills/rn-library-known-issue-check/references/PRESCREEN_GUIDE.md +64 -64
- package/vendor/Server/Skills/rn-library-known-issue-check/references/SOURCE_PREP_GUIDE.md +74 -74
- package/vendor/Server/Skills/rn-library-known-issue-check/scripts/validate-known-issue-report.py +164 -164
- package/vendor/Server/Skills/rn-library-memory-leak-check/SKILL.md +356 -339
- package/vendor/Server/Skills/rn-library-memory-leak-check/assets/REPORT_TEMPLATE.md +85 -83
- package/vendor/Server/Skills/rn-library-memory-leak-check/references/CHECKLIST.md +905 -859
- package/vendor/Server/Skills/rn-library-memory-leak-check/references/HARMONY_CODE_PATTERNS.md +124 -122
- package/vendor/Server/Skills/rn-library-memory-leak-check/scripts/scan_harmony_code.py +287 -279
- package/vendor/Server/Skills/rn-library-stability-check/SKILL.md +273 -273
- package/vendor/Server/Skills/rn-library-stability-check/assets/REPORT_TEMPLATE.md +129 -129
- package/vendor/Server/Skills/rn-library-stability-check/references/CHECKLIST.md +581 -581
- package/vendor/Server/Skills/rn-library-stability-check/references/SCORING_RULES.md +138 -138
- package/vendor/Server/Skills/rn-library-stability-check/scripts/scan-harmony-code.py +168 -168
- package/vendor/Server/Skills/rn-library-test-coverage-check/SKILL.md +526 -506
- package/vendor/Server/Skills/rn-library-test-coverage-check/references/CHECKLIST.md +321 -280
- package/vendor/Server/Skills/rn-library-test-coverage-check/references/DEMO_LOCATION.md +221 -221
- package/vendor/Server/Skills/rn-library-test-coverage-check/references/REPORT_TEMPLATE.md +220 -209
- package/vendor/Server/Skills/rn-library-test-coverage-check/references/SCRIPT_USAGE.md +325 -325
- package/vendor/Server/Skills/rn-ohos-xts-generator/SKILL.md +279 -279
- package/vendor/Server/Skills/rn-ohos-xts-generator/assets/TEST_FILE_TEMPLATES.md +404 -404
- package/vendor/Server/Skills/rn-ohos-xts-generator/references/BUILD_TROUBLESHOOTING.md +185 -185
- package/vendor/Server/Skills/rn-ohos-xts-generator/references/BUILD_WORKFLOW.md +265 -265
- package/vendor/Server/Skills/rn-ohos-xts-generator/references/COMMON_CONFIG.md +189 -189
- package/vendor/Server/Skills/rn-ohos-xts-generator/references/CONFIG_GUIDE.md +203 -203
- package/vendor/Server/Skills/rn-ohos-xts-generator/references/COVERAGE_ANALYZER.md +147 -147
- package/vendor/Server/Skills/rn-ohos-xts-generator/references/DESIGN_DOC_GUIDE.md +148 -148
- package/vendor/Server/Skills/rn-ohos-xts-generator/references/GENERATION_FLOW.md +165 -165
- package/vendor/Server/Skills/rn-ohos-xts-generator/references/GENERATION_STRATEGY.md +195 -195
- package/vendor/Server/Skills/rn-ohos-xts-generator/references/HARMONY_SCANNER.md +249 -249
- package/vendor/Server/Skills/rn-ohos-xts-generator/references/JEST_FRAMEWORK.md +235 -235
- package/vendor/Server/Skills/rn-ohos-xts-generator/references/PLATFORM_COMPAT.md +161 -161
- package/vendor/Server/Skills/rn-ohos-xts-generator/references/RN_TEST_PATTERNS.md +413 -413
- package/vendor/Server/Skills/rn-ohos-xts-generator/references/SOURCE_PARSER.md +235 -235
- package/vendor/Server/Skills/rn-ohos-xts-generator/references/TEST_CONVENTIONS.md +245 -245
- package/vendor/Server/Skills/rn-ohos-xts-generator/references/TROUBLESHOOTING.md +282 -282
- package/vendor/Server/Skills/rn-ohos-xts-generator/references/USAGE_GUIDE.md +251 -251
- package/vendor/Server/Skills/rnoh-cptf-api-test/SKILL.md +469 -469
- package/vendor/Server/Skills/rnoh-cptf-api-test/assets/CPTF_TEST_TEMPLATE.md +310 -310
- package/vendor/Server/Skills/rnoh-cptf-api-test/assets/DEMO_PAGE_TEMPLATE.md +303 -303
- package/vendor/Server/Skills/rnoh-cptf-api-test/references/CPTF_TEST_GENERATION_GUIDE.md +421 -421
- package/vendor/Server/Skills/rnoh-cptf-api-test/references/DEMO_GENERATION_GUIDE.md +358 -358
- package/vendor/Server/Skills/rnoh-cptf-api-test/references/QUALITY_CHECKLIST.md +114 -114
- package/vendor/Server/Skills/rnoh-cptf-api-test/references/SPEC_PARSING_GUIDE.md +274 -274
- package/vendor/Server/Skills/rnoh-cptf-api-test/scripts/validate-rnoh-cptf-api-test.sh +185 -185
- package/vendor/Server/Skills/rnoh-cptf-demo-test/SKILL.md +191 -191
- package/vendor/Server/Skills/rnoh-cptf-demo-test/assets/TEST_TEMPLATE.md +216 -216
- package/vendor/Server/Skills/rnoh-cptf-demo-test/references/CPTF_SETUP.md +107 -107
- package/vendor/Server/Skills/rnoh-cptf-demo-test/references/DEMO_ANALYSIS.md +120 -120
- package/vendor/Server/Skills/rnoh-cptf-demo-test/scripts/validate-rnoh-cptf-test.sh +108 -108
- package/vendor/Server/Skills/rnoh-cptf-test-run/SKILL.md +237 -237
- package/vendor/Server/Skills/rnoh-cptf-test-run/references/DEBUG_PLAYBOOK.md +261 -261
- package/vendor/Server/Skills/rnoh-cptf-test-run/scripts/validate-run-env.sh +112 -112
- package/vendor/Server/Skills/rnoh-lib-code-adapt/SKILL.md +497 -497
- package/vendor/Server/Skills/rnoh-lib-code-adapt/references/adapt-checklist.md +270 -270
- package/vendor/Server/Skills/rnoh-lib-code-adapt/references/api-migration-checklist.md +164 -164
- package/vendor/Server/Skills/rnoh-lib-code-adapt/references/common-compile-errors.md +556 -556
- package/vendor/Server/Skills/rnoh-lib-code-adapt/references/deveco-cli-tools.md +459 -459
- package/vendor/Server/Skills/rnoh-lib-code-adapt/references/edge-cases.md +65 -65
- package/vendor/Server/Skills/rnoh-lib-code-adapt/references/har-tgz-build.md +512 -512
- package/vendor/Server/Skills/rnoh-lib-code-adapt/references/version-compat-matrix.md +132 -132
- package/vendor/Server/Skills/rnoh-lib-code-adapt/scripts/auto-integrate.sh +424 -424
- package/vendor/Server/Skills/rnoh-lib-demo-coverage/SKILL.md +137 -137
- package/vendor/Server/Skills/rnoh-lib-demo-create/SKILL.md +306 -306
- package/vendor/Server/Skills/rnoh-lib-demo-create/assets/DEMO_PAGE_TEMPLATE.md +485 -485
- package/vendor/Server/Skills/rnoh-lib-demo-create/assets/INDEX_TEMPLATE.md +172 -172
- package/vendor/Server/Skills/rnoh-lib-demo-create/references/DEMO_CODE_RULES.md +422 -422
- package/vendor/Server/Skills/rnoh-lib-demo-create/references/QUALITY_CHECKLIST.md +95 -95
- package/vendor/Server/Skills/rnoh-lib-demo-create/references/SOURCE_EXPLORATION.md +169 -169
- package/vendor/Server/Skills/rnoh-lib-demo-doc/SKILL.md +554 -554
- package/vendor/Server/Skills/rnoh-lib-demo-doc/assets/DEMO_DOC_TEMPLATE.md +106 -106
- package/vendor/Server/Skills/rnoh-lib-demo-doc/references/COVERAGE_INCREMENTAL.md +216 -216
- package/vendor/Server/Skills/rnoh-lib-demo-doc/references/DEMO_DESIGN_RULES.md +413 -413
- package/vendor/Server/Skills/rnoh-lib-demo-doc/references/OUTPUT_FORMAT.md +269 -269
- package/vendor/Server/Skills/rnoh-lib-demo-doc/references/QUALITY_CHECKLIST.md +98 -98
- package/vendor/Server/Skills/rnoh-lib-func-test/SKILL.md +337 -337
- package/vendor/Server/Skills/rnoh-lib-rnt-search/SKILL.md +722 -722
- package/vendor/Server/Skills/rnoh-lib-rnt-search/assets/PORT_REPORT_TEMPLATE.md +219 -219
- package/vendor/Server/Skills/rnoh-lib-rnt-search/references/DEMO_PORTING_GUIDE.md +345 -345
- package/vendor/Server/Skills/rnoh-lib-rnt-search/references/PORT_VERIFICATION.md +269 -269
- package/vendor/Server/Skills/rnoh-lib-rnt-search/references/RNT_PROJECT_STRUCTURE.md +173 -173
- package/vendor/Server/Skills/rnoh-lib-rnt-search/scripts/analyze-demo-deps.cjs +267 -267
- package/vendor/Server/Skills/rnoh-lib-rnt-search/scripts/detect-rnoh-version.cjs +174 -174
- package/vendor/Server/Skills/rnoh-lib-rnt-search/scripts/find-rnt-demo.sh +111 -111
- package/vendor/Server/Skills/rnoh-lib-rnt-search/scripts/port-demo.sh +186 -186
- package/vendor/Server/Skills/rnoh-lib-rnt-search/scripts/read-lib-meta.cjs +150 -150
- package/vendor/Server/Skills/rnoh-lib-test-align/SKILL.md +296 -296
- package/vendor/Server/Skills/rnoh-lib-test-align/references/jest-troubleshooting.md +371 -371
- package/vendor/Server/Skills/rnoh-lib-test-align/references/port-test-demo-guide.md +212 -212
- package/vendor/Server/Skills/rnoh-lib-test-align/references/runtime-troubleshooting.md +345 -345
- package/vendor/Server/Skills/rnoh-lib-test-align/references/unit-test-template.md +223 -223
- package/vendor/Server/Skills/rnoh-lib-test-align/scripts/port-test-demo.sh +1053 -1053
- package/vendor/Server/Skills/rnoh-lib-version-diff/SKILL.md +295 -255
- package/vendor/Server/Skills/rnoh-lib-version-diff/references/OHOS_ADAPTATION.md +82 -77
- package/vendor/Server/Skills/rnoh-lib-version-diff/references/OHOS_API_LOOKUP.md +224 -224
- package/vendor/Server/Skills/rnoh-lib-version-diff/references/script-reference.md +175 -174
- package/vendor/Server/Skills/rnoh-lib-version-diff/scripts/detect-upstream-version.js +967 -967
- package/vendor/Server/Skills/rnoh-lib-version-diff/scripts/generate-diff.js +1798 -1798
- package/vendor/Server/Skills/rnoh-lib-version-diff/scripts/package.json +5 -5
- package/vendor/Server/Skills/rnoh-lib-version-diff/templates/report-template.md +180 -137
- package/vendor/Server/Skills/rnoh-lib-xts-coverage/SKILL.md +145 -145
- package/vendor/Server/Skills/skill-generator/SKILL.md +365 -365
- package/vendor/Server/Skills/skill-generator/assets/SKILL_TEMPLATE.md +183 -183
- package/vendor/Server/Skills/skill-generator/references/COMPLIANCE_CHECKLIST.md +82 -82
- package/vendor/Server/Skills/skill-generator/references/KB_QUERY_GUIDE.md +110 -110
- package/vendor/Server/Skills/skill-generator/references/MCP_TOOL_DISCOVERY.md +122 -122
- package/vendor/Server/Skills/skill-generator/references/SKILL_SPEC.md +121 -121
- package/vendor/Server/Skills/skill-generator/scripts/validate-skill.cjs +259 -259
- package/vendor/Server/Skills/task-analysis/SKILL.md +234 -234
- package/vendor/Server/Skills/task-analysis/assets/OUTPUT_EXAMPLES.md +160 -160
- package/vendor/Server/Skills/task-analysis/references/ACCEPTANCE_CRITERIA_GUIDE.md +190 -190
- package/vendor/Server/Skills/task-analysis/references/ANALYSIS_SCHEMA.md +224 -224
- package/vendor/Server/Skills/task-analysis/references/INTEGRATION_CONTEXT.md +162 -162
- package/vendor/Server/Skills/task-analysis/references/LESSONS_LEARNED.md +55 -55
- package/vendor/Server/Skills/task-analysis/references/REPLAN_CONTEXT_GUIDE.md +126 -126
- package/vendor/Server/Skills/task-analysis/scripts/validate-analysis-output.sh +256 -256
- package/vendor/Server/Skills/task-decomposition/SKILL.md +528 -528
- package/vendor/Server/Skills/task-decomposition/assets/OUTPUT_EXAMPLES.md +451 -451
- package/vendor/Server/Skills/task-decomposition/references/ACCEPTANCE_CRITERIA_GUIDE.md +179 -179
- package/vendor/Server/Skills/task-decomposition/references/DEPENDENCY_GRAPH_GUIDE.md +152 -152
- package/vendor/Server/Skills/task-decomposition/references/INTEGRATION_CONTEXT.md +175 -175
- package/vendor/Server/Skills/task-decomposition/references/REPLAN_CONTEXT_GUIDE.md +195 -195
- package/vendor/Server/Skills/task-decomposition/references/TASK_DECOMPOSITION_TEMPLATES.md +226 -226
- package/vendor/Server/Skills/task-decomposition/scripts/list-available-skills.cjs +263 -263
- package/vendor/Server/Skills/task-decomposition/scripts/skill-blacklist.json +29 -29
- package/vendor/Server/Skills/task-decomposition/scripts/validate-decomposition-output.cjs +376 -376
- package/vendor/Server/Skills/task-decomposition/scripts/validate-param-consistency.cjs +259 -259
- package/vendor/Server/Skills/task-decomposition/scripts/validate-specified-skills.cjs +216 -216
- package/vendor/Server/Skills/task-decomposition/scripts/validate-step-graph.cjs +424 -424
- package/vendor/Server/Skills/tpc-cpp-check/SKILL.md +427 -427
- package/vendor/Server/Skills/tpc-cpp-check/references/CHECKLIST.md +214 -214
- package/vendor/Server/Skills/tpc-cpp-check/references/HPKBUILD_GUIDE.md +235 -235
- package/vendor/Server/Skills/tpc-cpp-check/references/REPORT_TEMPLATE.md +250 -250
- package/vendor/Server/TestCheck/TestCheck.js +775 -775
- package/vendor/Server/TestCheck/index.js +11 -11
- package/vendor/Server/library/McpToolGuide.js +280 -280
- package/vendor/Server/library/StatsService.js +126 -126
- package/vendor/Server/library/cstTime.js +16 -16
- package/vendor/VERSION +3 -3
- package/workflows/pr-check.mjs +105 -105
- package/workflows/pr-push.mjs +192 -192
- package/vendor/Server/Agent/SkillSelector/types.js +0 -63
package/lib/orch.js
CHANGED
|
@@ -1,427 +1,427 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* orch.js —— 编排层命令(Orchestrator 多步骤依赖)
|
|
3
|
-
*
|
|
4
|
-
* 命令:
|
|
5
|
-
* orch run <task-def.json> 加载任务定义 + 启动编排,阻塞到终态
|
|
6
|
-
* orch load <task-def.json> 仅加载任务定义,落盘 orchestration.json 后返回
|
|
7
|
-
* orch start <taskId> 从磁盘恢复 LOADED 状态并启动,阻塞到终态
|
|
8
|
-
* orch progress <taskId> [--loop N] 查询编排进度(磁盘直读 orchestration.json)
|
|
9
|
-
* orch abort|pause|resume <taskId> 控制编排(尽力而为)
|
|
10
|
-
* orch tasks 列出编排任务(仅统计有 orchestration.json 的任务)
|
|
11
|
-
*
|
|
12
|
-
* 与 3rdloop step 的区别:
|
|
13
|
-
* - step 是单步 FlexRunner 直连,不经 Orchestrator
|
|
14
|
-
* - orch 走多步骤依赖编排(loadTask → start),对应 HTTP /api/orchestrator/load|start
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import fs from 'node:fs';
|
|
18
|
-
import { EXIT } from './exit-codes.js';
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* 3rdloop orch 命令二段分发。
|
|
22
|
-
* @returns {Promise<number>}
|
|
23
|
-
*/
|
|
24
|
-
export async function cmdOrch({ flags, rest, projectRoot, dataDir, skillDir, jsonMode, quiet, verbose, out, u }) {
|
|
25
|
-
const fRest = flags.rest || [];
|
|
26
|
-
const sub = fRest[0];
|
|
27
|
-
const subRest = fRest.slice(1);
|
|
28
|
-
switch (sub) {
|
|
29
|
-
case 'run':
|
|
30
|
-
return cmdOrchRun({ flags, rest: subRest, projectRoot, dataDir, skillDir, jsonMode, quiet, verbose, out, u });
|
|
31
|
-
case 'load':
|
|
32
|
-
return cmdOrchLoad({ flags, rest: subRest, projectRoot, dataDir, skillDir, jsonMode, quiet, verbose, out, u });
|
|
33
|
-
case 'start':
|
|
34
|
-
return cmdOrchStart({ flags, rest: subRest, projectRoot, dataDir, skillDir, jsonMode, quiet, verbose, out, u });
|
|
35
|
-
case 'progress':
|
|
36
|
-
return cmdOrchProgress({ flags, rest: subRest, dataDir, jsonMode, out, u });
|
|
37
|
-
case 'abort':
|
|
38
|
-
case 'pause':
|
|
39
|
-
case 'resume':
|
|
40
|
-
return cmdOrchControl(sub, { flags, rest: subRest, projectRoot, dataDir, skillDir, jsonMode, out, u });
|
|
41
|
-
case 'tasks':
|
|
42
|
-
return cmdOrchTasks({ flags, rest: subRest, dataDir, jsonMode, out, u });
|
|
43
|
-
default:
|
|
44
|
-
process.stderr.write(`缺少或未知的 orch 子命令: ${sub || '(空)'}\n`);
|
|
45
|
-
process.stderr.write('用法: 3rdloop orch run|load|start|progress|abort|pause|resume|tasks ...\n');
|
|
46
|
-
return EXIT.ERROR;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// ─── 位置参数提取 ──────────────────────────────────────────────────────────
|
|
51
|
-
|
|
52
|
-
/** orch 子命令专用 flags(带值),从参数中剔除以提取位置参数。 */
|
|
53
|
-
const ORCH_FLAG_NAMES = ['task-id', 'loop', 'task-dir', 'max-retries', 'input-report'];
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* 从参数数组提取位置参数(task-def 文件 / taskId)。
|
|
57
|
-
* 结构与 step.js 的 _positionalArgs 对齐。
|
|
58
|
-
*/
|
|
59
|
-
function _positionalArgs(args) {
|
|
60
|
-
const out = [];
|
|
61
|
-
for (let i = 0; i < args.length; i++) {
|
|
62
|
-
const arg = args[i];
|
|
63
|
-
if (arg.startsWith('--')) {
|
|
64
|
-
const name = arg.slice(2);
|
|
65
|
-
if (ORCH_FLAG_NAMES.includes(name)) i++; // 跳过该 flag 的值
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
out.push(arg);
|
|
69
|
-
}
|
|
70
|
-
return out;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function _parseIntFlag(flags, name, def) {
|
|
74
|
-
const idx = flags.rest.indexOf(`--${name}`);
|
|
75
|
-
const raw = idx !== -1 ? flags.rest[idx + 1] : undefined;
|
|
76
|
-
const n = parseInt(raw, 10);
|
|
77
|
-
return Number.isFinite(n) ? n : def;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function _stringFlag(flags, name) {
|
|
81
|
-
const idx = flags.rest.indexOf(`--${name}`);
|
|
82
|
-
return idx !== -1 ? flags.rest[idx + 1] : undefined;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/** 惰性加载 runner(避免未用到时启动完整引擎)。 */
|
|
86
|
-
function _runner() {
|
|
87
|
-
return import('./runner.js');
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/** 惰性加载 queries。 */
|
|
91
|
-
function _queries() {
|
|
92
|
-
return import('./queries.js');
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/** 读取并校验 task-def JSON 文件。 */
|
|
96
|
-
function _readTaskDef(file) {
|
|
97
|
-
if (!file) {
|
|
98
|
-
throw new Error('缺少任务定义文件。用法: 3rdloop orch load <task-def.json>');
|
|
99
|
-
}
|
|
100
|
-
if (!fs.existsSync(file)) {
|
|
101
|
-
throw new Error(`任务定义文件不存在: ${file}`);
|
|
102
|
-
}
|
|
103
|
-
let taskDef;
|
|
104
|
-
try {
|
|
105
|
-
taskDef = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
106
|
-
} catch (err) {
|
|
107
|
-
throw new Error(`任务定义文件解析失败: ${file}, ${err.message}`);
|
|
108
|
-
}
|
|
109
|
-
if (!taskDef.taskId) {
|
|
110
|
-
throw new Error('task-def 中缺少 taskId');
|
|
111
|
-
}
|
|
112
|
-
if (!Array.isArray(taskDef.steps) || taskDef.steps.length === 0) {
|
|
113
|
-
throw new Error('task-def 中 steps 为必填项且不能为空');
|
|
114
|
-
}
|
|
115
|
-
return taskDef;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// ─── run / load ─────────────────────────────────────────────────────────────
|
|
119
|
-
|
|
120
|
-
/** 加载任务定义 + 启动编排,阻塞到终态(推荐入口)。 */
|
|
121
|
-
async function cmdOrchRun({ flags, rest, projectRoot, dataDir, skillDir, jsonMode, quiet, verbose, out, u }) {
|
|
122
|
-
const positional = _positionalArgs(rest);
|
|
123
|
-
const taskDefFile = positional[0];
|
|
124
|
-
let taskDef;
|
|
125
|
-
try {
|
|
126
|
-
taskDef = _readTaskDef(taskDefFile);
|
|
127
|
-
} catch (err) {
|
|
128
|
-
if (jsonMode) out({ ok: false, error: err.message });
|
|
129
|
-
else process.stderr.write(`${err.message}\n`);
|
|
130
|
-
return EXIT.ERROR;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (!quiet && !jsonMode) {
|
|
134
|
-
u.logProgress(`${u.C.cyan}编排任务已提交: ${u.C.reset}${u.C.bold}${taskDef.taskId}${u.C.reset}`);
|
|
135
|
-
u.logProgress(` 任务定义: ${taskDefFile}`);
|
|
136
|
-
u.logProgress(` 步骤数: ${taskDef.steps.length}`);
|
|
137
|
-
if (taskDef.steps.length <= 8) {
|
|
138
|
-
for (const s of taskDef.steps) {
|
|
139
|
-
u.logProgress(` step ${s.stepId}: ${String(s.taskDescription || '').slice(0, 60)}${s.dependId ? ` [依赖 ${s.dependId}]` : ''}`);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const r = await _runner();
|
|
145
|
-
const ctx = r.createRunContext({ projectRoot, dataDir, skillDir, cliType: 'opencode', verbose });
|
|
146
|
-
|
|
147
|
-
// 挂载 opencode 生命周期
|
|
148
|
-
const oc = await _ensureOpcodene(ctx, u, jsonMode, out);
|
|
149
|
-
if (!oc) return EXIT.ERROR;
|
|
150
|
-
|
|
151
|
-
// 信号处理
|
|
152
|
-
let interrupted = false;
|
|
153
|
-
const exitHandler = async (sig) => {
|
|
154
|
-
if (interrupted) return;
|
|
155
|
-
interrupted = true;
|
|
156
|
-
try { await r.orchControl(ctx, taskDef.taskId, 'abort'); } catch { /* 忽略 */ }
|
|
157
|
-
await oc.stop();
|
|
158
|
-
process.stderr.write(`\n已中止(${sig})\n`);
|
|
159
|
-
process.exit(sig === 'SIGINT' ? EXIT.SIGINT : EXIT.SIGTERM);
|
|
160
|
-
};
|
|
161
|
-
process.once('SIGINT', () => exitHandler('SIGINT'));
|
|
162
|
-
process.once('SIGTERM', () => exitHandler('SIGTERM'));
|
|
163
|
-
|
|
164
|
-
const started = Date.now();
|
|
165
|
-
try {
|
|
166
|
-
// load + start(阻塞)
|
|
167
|
-
await r.orchLoad(ctx, taskDef);
|
|
168
|
-
const result = await _startAndRender(ctx, r, taskDef.taskId, { jsonMode, quiet, verbose, out, u, started, dataDir });
|
|
169
|
-
return result.passed ? EXIT.OK : EXIT.TASK_FAILED;
|
|
170
|
-
} catch (err) {
|
|
171
|
-
await oc.stop();
|
|
172
|
-
if (jsonMode) out({ ok: false, error: err.message, taskId: taskDef.taskId });
|
|
173
|
-
else process.stderr.write(`\n编排失败: ${err.message}\n`);
|
|
174
|
-
return EXIT.ERROR;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/** 仅加载任务定义,落盘 orchestration.json 后返回。 */
|
|
179
|
-
async function cmdOrchLoad({ flags, rest, projectRoot, dataDir, skillDir, jsonMode, quiet, verbose, out, u }) {
|
|
180
|
-
const positional = _positionalArgs(rest);
|
|
181
|
-
const taskDefFile = positional[0];
|
|
182
|
-
let taskDef;
|
|
183
|
-
try {
|
|
184
|
-
taskDef = _readTaskDef(taskDefFile);
|
|
185
|
-
} catch (err) {
|
|
186
|
-
if (jsonMode) out({ ok: false, error: err.message });
|
|
187
|
-
else process.stderr.write(`${err.message}\n`);
|
|
188
|
-
return EXIT.ERROR;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
const r = await _runner();
|
|
192
|
-
const ctx = r.createRunContext({ projectRoot, dataDir, skillDir, verbose });
|
|
193
|
-
try {
|
|
194
|
-
const res = await r.orchLoad(ctx, taskDef);
|
|
195
|
-
if (!quiet) {
|
|
196
|
-
u.logProgress(`编排任务已加载: ${taskDef.taskId}(步骤 ${taskDef.steps.length})`);
|
|
197
|
-
}
|
|
198
|
-
if (jsonMode) {
|
|
199
|
-
out({ ok: true, taskId: taskDef.taskId, status: 'loaded', stepCount: taskDef.steps.length });
|
|
200
|
-
} else {
|
|
201
|
-
process.stdout.write(`${taskDef.taskId}\n`);
|
|
202
|
-
}
|
|
203
|
-
return EXIT.OK;
|
|
204
|
-
} catch (err) {
|
|
205
|
-
if (jsonMode) out({ ok: false, error: err.message });
|
|
206
|
-
else process.stderr.write(`加载失败: ${err.message}\n`);
|
|
207
|
-
return EXIT.ERROR;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// ─── start(从磁盘恢复) ───────────────────────────────────────────────────
|
|
212
|
-
|
|
213
|
-
/** 从磁盘恢复 LOADED 状态并启动编排,阻塞到终态。 */
|
|
214
|
-
async function cmdOrchStart({ flags, rest, projectRoot, dataDir, skillDir, jsonMode, quiet, verbose, out, u }) {
|
|
215
|
-
const positional = _positionalArgs(rest);
|
|
216
|
-
const taskId = positional[0];
|
|
217
|
-
if (!taskId) {
|
|
218
|
-
if (jsonMode) out({ ok: false, error: '缺少 taskId。用法: 3rdloop orch start <taskId>' });
|
|
219
|
-
else process.stderr.write('缺少 taskId。用法: 3rdloop orch start <taskId>\n');
|
|
220
|
-
return EXIT.ERROR;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
const r = await _runner();
|
|
224
|
-
const ctx = r.createRunContext({ projectRoot, dataDir, skillDir, cliType: 'opencode', verbose });
|
|
225
|
-
const oc = await _ensureOpcodene(ctx, u, jsonMode, out);
|
|
226
|
-
if (!oc) return EXIT.ERROR;
|
|
227
|
-
|
|
228
|
-
let interrupted = false;
|
|
229
|
-
const exitHandler = async (sig) => {
|
|
230
|
-
if (interrupted) return;
|
|
231
|
-
interrupted = true;
|
|
232
|
-
try { await r.orchControl(ctx, taskId, 'abort'); } catch { /* 忽略 */ }
|
|
233
|
-
await oc.stop();
|
|
234
|
-
process.stderr.write(`\n已中止(${sig})\n`);
|
|
235
|
-
process.exit(sig === 'SIGINT' ? EXIT.SIGINT : EXIT.SIGTERM);
|
|
236
|
-
};
|
|
237
|
-
process.once('SIGINT', () => exitHandler('SIGINT'));
|
|
238
|
-
process.once('SIGTERM', () => exitHandler('SIGTERM'));
|
|
239
|
-
|
|
240
|
-
const started = Date.now();
|
|
241
|
-
try {
|
|
242
|
-
const result = await _startAndRender(ctx, r, taskId, { jsonMode, quiet, verbose, out, u, started, dataDir });
|
|
243
|
-
return result.passed ? EXIT.OK : EXIT.TASK_FAILED;
|
|
244
|
-
} catch (err) {
|
|
245
|
-
await oc.stop();
|
|
246
|
-
if (jsonMode) out({ ok: false, error: err.message, taskId });
|
|
247
|
-
else process.stderr.write(`\n编排启动失败: ${err.message}\n`);
|
|
248
|
-
return EXIT.ERROR;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/** 调用 orchStart 并渲染进度(run / start 共用)。 */
|
|
253
|
-
async function _startAndRender(ctx, r, taskId, { jsonMode, quiet, verbose, out, u, started, dataDir }) {
|
|
254
|
-
const q = await _queries();
|
|
255
|
-
let prev = null;
|
|
256
|
-
let finished = false;
|
|
257
|
-
|
|
258
|
-
// 后台轮询编排磁盘快照(每次步骤状态变化 Orchestrator 都会 _persistState),
|
|
259
|
-
// diff 渲染中间进度。只有非 --json 模式才打印,避免污染 stdout。
|
|
260
|
-
// 首帧只记录不打印(prev=null 时不输出),避免启动失败(如状态非 LOADED)
|
|
261
|
-
// 时打印误导性的概览行;最终变化由 orchStart 返回后一次性补齐。
|
|
262
|
-
const poll = (async () => {
|
|
263
|
-
if (jsonMode) return;
|
|
264
|
-
while (!finished) {
|
|
265
|
-
const state = q.readOrchestrationState(dataDir, taskId);
|
|
266
|
-
if (state && prev) {
|
|
267
|
-
const lines = u.diffOrchestration(prev, state, { verbose });
|
|
268
|
-
for (const line of lines) u.logProgress(line);
|
|
269
|
-
}
|
|
270
|
-
if (state) prev = state;
|
|
271
|
-
await new Promise(res => setTimeout(res, 3000));
|
|
272
|
-
}
|
|
273
|
-
})();
|
|
274
|
-
|
|
275
|
-
try {
|
|
276
|
-
const result = await r.orchStart(ctx, taskId);
|
|
277
|
-
finished = true;
|
|
278
|
-
await poll;
|
|
279
|
-
|
|
280
|
-
// 补齐首帧到终态的变化行
|
|
281
|
-
if (!jsonMode) {
|
|
282
|
-
const lines = u.diffOrchestration(prev, result.progress, { verbose });
|
|
283
|
-
for (const line of lines) u.logProgress(line);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const elapsedSec = ((Date.now() - started) / 1000).toFixed(0);
|
|
287
|
-
|
|
288
|
-
if (jsonMode) {
|
|
289
|
-
out({
|
|
290
|
-
ok: result.passed,
|
|
291
|
-
taskId,
|
|
292
|
-
status: result.status,
|
|
293
|
-
passed: result.passed,
|
|
294
|
-
stats: result.progress.stats || null,
|
|
295
|
-
steps: result.progress.steps || [],
|
|
296
|
-
error: result.error,
|
|
297
|
-
resultPaths: result.resultPaths || [],
|
|
298
|
-
elapsedSec: Number(elapsedSec),
|
|
299
|
-
});
|
|
300
|
-
} else {
|
|
301
|
-
u.logProgress(`\n${result.passed ? u.C.green : u.C.red}编排完成: ${u.C.reset}${result.status}`);
|
|
302
|
-
u.logProgress(` 耗时: ${elapsedSec}s`);
|
|
303
|
-
const stats = result.progress.stats || {};
|
|
304
|
-
u.logProgress(` 步骤: 完成 ${stats.completed || 0} / 失败 ${stats.failed || 0}`);
|
|
305
|
-
if (result.error) u.logProgress(` 错误: ${result.error}`);
|
|
306
|
-
for (const item of result.resultPaths || []) {
|
|
307
|
-
u.logProgress(` 产物 ${item.stepId}: ${item.resultPath}`);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
return result;
|
|
311
|
-
} catch (err) {
|
|
312
|
-
finished = true;
|
|
313
|
-
throw err;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// ─── progress ───────────────────────────────────────────────────────────────
|
|
318
|
-
|
|
319
|
-
/** 查询编排进度(磁盘直读 orchestration.json)。 */
|
|
320
|
-
async function cmdOrchProgress({ flags, rest, dataDir, jsonMode, out, u }) {
|
|
321
|
-
const positional = _positionalArgs(rest);
|
|
322
|
-
const taskId = positional[0];
|
|
323
|
-
if (!taskId) {
|
|
324
|
-
if (jsonMode) out({ ok: false, error: '缺少 taskId。用法: 3rdloop orch progress <taskId> [--loop N]' });
|
|
325
|
-
else process.stderr.write('缺少 taskId。用法: 3rdloop orch progress <taskId> [--loop N]\n');
|
|
326
|
-
return EXIT.ERROR;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
const loop = _parseIntFlag(flags, 'loop', undefined);
|
|
330
|
-
const q = await _queries();
|
|
331
|
-
const state = q.readOrchestrationState(dataDir, taskId, loop);
|
|
332
|
-
|
|
333
|
-
if (!state) {
|
|
334
|
-
if (jsonMode) out({ ok: false, error: '编排任务不存在', taskId, loop: loop ?? null });
|
|
335
|
-
else process.stderr.write(`编排任务不存在: ${taskId}${loop != null ? ` (loop=${loop})` : ''}\n`);
|
|
336
|
-
return EXIT.ERROR;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
const lines = u.diffOrchestration(null, state, { verbose: false });
|
|
340
|
-
if (jsonMode) {
|
|
341
|
-
// 结构化输出:保持与 HTTP GET /orchestrator/progress 一致形态
|
|
342
|
-
out({ ok: true, taskId, status: state.status, loop: loop ?? null, progress: state });
|
|
343
|
-
return EXIT.OK;
|
|
344
|
-
}
|
|
345
|
-
for (const line of lines) u.logProgress(line);
|
|
346
|
-
// 追加步骤明细
|
|
347
|
-
const steps = state.steps || [];
|
|
348
|
-
for (const s of steps) {
|
|
349
|
-
const icon = s.status === 'completed' ? '✓' : (s.status === 'failed' ? '✗' : (s.status === 'running' ? '▶' : '·'));
|
|
350
|
-
u.logProgress(` ${icon} step ${String(s.stepId).padEnd(4)} ${(s.status || '').padEnd(10)} ${String(s.taskDescription || '').slice(0, 50)}`);
|
|
351
|
-
}
|
|
352
|
-
return EXIT.OK;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
// ─── 控制 ───────────────────────────────────────────────────────────────────
|
|
356
|
-
|
|
357
|
-
/** 终止 / 暂停 / 恢复编排(尽力而为,跨进程无法中断另一进程运行中的任务)。 */
|
|
358
|
-
async function cmdOrchControl(action, { flags, rest, projectRoot, dataDir, skillDir, jsonMode, out, u }) {
|
|
359
|
-
const positional = _positionalArgs(rest);
|
|
360
|
-
const taskId = positional[0];
|
|
361
|
-
if (!taskId) {
|
|
362
|
-
if (jsonMode) out({ ok: false, error: `缺少 taskId。用法: 3rdloop orch ${action} <taskId>` });
|
|
363
|
-
else process.stderr.write(`缺少 taskId。用法: 3rdloop orch ${action} <taskId>\n`);
|
|
364
|
-
return EXIT.ERROR;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
const r = await _runner();
|
|
368
|
-
const ctx = r.createRunContext({ projectRoot, dataDir, skillDir, verbose: false });
|
|
369
|
-
const result = await r.orchControl(ctx, taskId, action);
|
|
370
|
-
|
|
371
|
-
if (jsonMode) {
|
|
372
|
-
out({ ok: result.ok, taskId, action, status: result.status, error: result.error });
|
|
373
|
-
} else {
|
|
374
|
-
if (result.ok) {
|
|
375
|
-
process.stderr.write(`编排已${action === 'abort' ? '终止' : (action === 'pause' ? '暂停' : '恢复')}: ${taskId}\n`);
|
|
376
|
-
} else {
|
|
377
|
-
process.stderr.write(`${result.error || `操作 ${action} 未生效(可能未在运行中): ${taskId}`}\n`);
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
return result.ok ? EXIT.OK : EXIT.ERROR;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// ─── tasks ──────────────────────────────────────────────────────────────────
|
|
384
|
-
|
|
385
|
-
/** 列出编排任务。 */
|
|
386
|
-
async function cmdOrchTasks({ flags, rest, dataDir, jsonMode, out, u }) {
|
|
387
|
-
const q = await _queries();
|
|
388
|
-
const tasks = q.listOrchestrationTasks(dataDir);
|
|
389
|
-
|
|
390
|
-
if (jsonMode) {
|
|
391
|
-
out({ total: tasks.length, tasks });
|
|
392
|
-
return EXIT.OK;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
if (tasks.length === 0) {
|
|
396
|
-
process.stdout.write('(暂无编排任务)\n');
|
|
397
|
-
return EXIT.OK;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
process.stdout.write(`共 ${tasks.length} 个编排任务:\n`);
|
|
401
|
-
for (const t of tasks) {
|
|
402
|
-
const icon = t.status === 'completed' ? u.C.green + '✓' + u.C.reset
|
|
403
|
-
: (t.status === 'running') ? u.C.cyan + '▶' + u.C.reset
|
|
404
|
-
: u.C.red + '✗' + u.C.reset;
|
|
405
|
-
const stepInfo = `步骤 ${t.stepCompleted}/${t.stepCount}`;
|
|
406
|
-
process.stdout.write(` ${icon} ${t.taskId.padEnd(40)} ${(t.status || '').padEnd(10)} ${stepInfo.padEnd(12)} ${t.startTime || ''}\n`);
|
|
407
|
-
}
|
|
408
|
-
return EXIT.OK;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
// ─── 工具 ──────────────────────────────────────────────────────────────────
|
|
412
|
-
|
|
413
|
-
/** 确保 opencode serve 运行(run/start 需要执行环境;load/progress 不需要)。 */
|
|
414
|
-
async function _ensureOpcodene(ctx, u, jsonMode, out) {
|
|
415
|
-
const { OpencodeManager } = await import('./opencode.js');
|
|
416
|
-
const oc = new OpencodeManager({ projectRoot: ctx.projectRoot });
|
|
417
|
-
const ocHealth = await oc.ensureRunning();
|
|
418
|
-
if (!ocHealth.ok) {
|
|
419
|
-
if (jsonMode) out({ ok: false, error: ocHealth.message });
|
|
420
|
-
process.stderr.write(`\n错误: ${ocHealth.message}\n`);
|
|
421
|
-
process.stderr.write('请先启动 opencode serve(项目上一级目录: opencode serve)后重试。\n');
|
|
422
|
-
await oc.stop();
|
|
423
|
-
return null;
|
|
424
|
-
}
|
|
425
|
-
if (ocHealth.spawned) process.stderr.write(`${ocHealth.message}\n`);
|
|
426
|
-
return oc;
|
|
1
|
+
/**
|
|
2
|
+
* orch.js —— 编排层命令(Orchestrator 多步骤依赖)
|
|
3
|
+
*
|
|
4
|
+
* 命令:
|
|
5
|
+
* orch run <task-def.json> 加载任务定义 + 启动编排,阻塞到终态
|
|
6
|
+
* orch load <task-def.json> 仅加载任务定义,落盘 orchestration.json 后返回
|
|
7
|
+
* orch start <taskId> 从磁盘恢复 LOADED 状态并启动,阻塞到终态
|
|
8
|
+
* orch progress <taskId> [--loop N] 查询编排进度(磁盘直读 orchestration.json)
|
|
9
|
+
* orch abort|pause|resume <taskId> 控制编排(尽力而为)
|
|
10
|
+
* orch tasks 列出编排任务(仅统计有 orchestration.json 的任务)
|
|
11
|
+
*
|
|
12
|
+
* 与 3rdloop step 的区别:
|
|
13
|
+
* - step 是单步 FlexRunner 直连,不经 Orchestrator
|
|
14
|
+
* - orch 走多步骤依赖编排(loadTask → start),对应 HTTP /api/orchestrator/load|start
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import fs from 'node:fs';
|
|
18
|
+
import { EXIT } from './exit-codes.js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 3rdloop orch 命令二段分发。
|
|
22
|
+
* @returns {Promise<number>}
|
|
23
|
+
*/
|
|
24
|
+
export async function cmdOrch({ flags, rest, projectRoot, dataDir, skillDir, jsonMode, quiet, verbose, out, u }) {
|
|
25
|
+
const fRest = flags.rest || [];
|
|
26
|
+
const sub = fRest[0];
|
|
27
|
+
const subRest = fRest.slice(1);
|
|
28
|
+
switch (sub) {
|
|
29
|
+
case 'run':
|
|
30
|
+
return cmdOrchRun({ flags, rest: subRest, projectRoot, dataDir, skillDir, jsonMode, quiet, verbose, out, u });
|
|
31
|
+
case 'load':
|
|
32
|
+
return cmdOrchLoad({ flags, rest: subRest, projectRoot, dataDir, skillDir, jsonMode, quiet, verbose, out, u });
|
|
33
|
+
case 'start':
|
|
34
|
+
return cmdOrchStart({ flags, rest: subRest, projectRoot, dataDir, skillDir, jsonMode, quiet, verbose, out, u });
|
|
35
|
+
case 'progress':
|
|
36
|
+
return cmdOrchProgress({ flags, rest: subRest, dataDir, jsonMode, out, u });
|
|
37
|
+
case 'abort':
|
|
38
|
+
case 'pause':
|
|
39
|
+
case 'resume':
|
|
40
|
+
return cmdOrchControl(sub, { flags, rest: subRest, projectRoot, dataDir, skillDir, jsonMode, out, u });
|
|
41
|
+
case 'tasks':
|
|
42
|
+
return cmdOrchTasks({ flags, rest: subRest, dataDir, jsonMode, out, u });
|
|
43
|
+
default:
|
|
44
|
+
process.stderr.write(`缺少或未知的 orch 子命令: ${sub || '(空)'}\n`);
|
|
45
|
+
process.stderr.write('用法: 3rdloop orch run|load|start|progress|abort|pause|resume|tasks ...\n');
|
|
46
|
+
return EXIT.ERROR;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ─── 位置参数提取 ──────────────────────────────────────────────────────────
|
|
51
|
+
|
|
52
|
+
/** orch 子命令专用 flags(带值),从参数中剔除以提取位置参数。 */
|
|
53
|
+
const ORCH_FLAG_NAMES = ['task-id', 'loop', 'task-dir', 'max-retries', 'input-report'];
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 从参数数组提取位置参数(task-def 文件 / taskId)。
|
|
57
|
+
* 结构与 step.js 的 _positionalArgs 对齐。
|
|
58
|
+
*/
|
|
59
|
+
function _positionalArgs(args) {
|
|
60
|
+
const out = [];
|
|
61
|
+
for (let i = 0; i < args.length; i++) {
|
|
62
|
+
const arg = args[i];
|
|
63
|
+
if (arg.startsWith('--')) {
|
|
64
|
+
const name = arg.slice(2);
|
|
65
|
+
if (ORCH_FLAG_NAMES.includes(name)) i++; // 跳过该 flag 的值
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
out.push(arg);
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function _parseIntFlag(flags, name, def) {
|
|
74
|
+
const idx = flags.rest.indexOf(`--${name}`);
|
|
75
|
+
const raw = idx !== -1 ? flags.rest[idx + 1] : undefined;
|
|
76
|
+
const n = parseInt(raw, 10);
|
|
77
|
+
return Number.isFinite(n) ? n : def;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function _stringFlag(flags, name) {
|
|
81
|
+
const idx = flags.rest.indexOf(`--${name}`);
|
|
82
|
+
return idx !== -1 ? flags.rest[idx + 1] : undefined;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** 惰性加载 runner(避免未用到时启动完整引擎)。 */
|
|
86
|
+
function _runner() {
|
|
87
|
+
return import('./runner.js');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** 惰性加载 queries。 */
|
|
91
|
+
function _queries() {
|
|
92
|
+
return import('./queries.js');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** 读取并校验 task-def JSON 文件。 */
|
|
96
|
+
function _readTaskDef(file) {
|
|
97
|
+
if (!file) {
|
|
98
|
+
throw new Error('缺少任务定义文件。用法: 3rdloop orch load <task-def.json>');
|
|
99
|
+
}
|
|
100
|
+
if (!fs.existsSync(file)) {
|
|
101
|
+
throw new Error(`任务定义文件不存在: ${file}`);
|
|
102
|
+
}
|
|
103
|
+
let taskDef;
|
|
104
|
+
try {
|
|
105
|
+
taskDef = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
106
|
+
} catch (err) {
|
|
107
|
+
throw new Error(`任务定义文件解析失败: ${file}, ${err.message}`);
|
|
108
|
+
}
|
|
109
|
+
if (!taskDef.taskId) {
|
|
110
|
+
throw new Error('task-def 中缺少 taskId');
|
|
111
|
+
}
|
|
112
|
+
if (!Array.isArray(taskDef.steps) || taskDef.steps.length === 0) {
|
|
113
|
+
throw new Error('task-def 中 steps 为必填项且不能为空');
|
|
114
|
+
}
|
|
115
|
+
return taskDef;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ─── run / load ─────────────────────────────────────────────────────────────
|
|
119
|
+
|
|
120
|
+
/** 加载任务定义 + 启动编排,阻塞到终态(推荐入口)。 */
|
|
121
|
+
async function cmdOrchRun({ flags, rest, projectRoot, dataDir, skillDir, jsonMode, quiet, verbose, out, u }) {
|
|
122
|
+
const positional = _positionalArgs(rest);
|
|
123
|
+
const taskDefFile = positional[0];
|
|
124
|
+
let taskDef;
|
|
125
|
+
try {
|
|
126
|
+
taskDef = _readTaskDef(taskDefFile);
|
|
127
|
+
} catch (err) {
|
|
128
|
+
if (jsonMode) out({ ok: false, error: err.message });
|
|
129
|
+
else process.stderr.write(`${err.message}\n`);
|
|
130
|
+
return EXIT.ERROR;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (!quiet && !jsonMode) {
|
|
134
|
+
u.logProgress(`${u.C.cyan}编排任务已提交: ${u.C.reset}${u.C.bold}${taskDef.taskId}${u.C.reset}`);
|
|
135
|
+
u.logProgress(` 任务定义: ${taskDefFile}`);
|
|
136
|
+
u.logProgress(` 步骤数: ${taskDef.steps.length}`);
|
|
137
|
+
if (taskDef.steps.length <= 8) {
|
|
138
|
+
for (const s of taskDef.steps) {
|
|
139
|
+
u.logProgress(` step ${s.stepId}: ${String(s.taskDescription || '').slice(0, 60)}${s.dependId ? ` [依赖 ${s.dependId}]` : ''}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const r = await _runner();
|
|
145
|
+
const ctx = r.createRunContext({ projectRoot, dataDir, skillDir, cliType: 'opencode', verbose });
|
|
146
|
+
|
|
147
|
+
// 挂载 opencode 生命周期
|
|
148
|
+
const oc = await _ensureOpcodene(ctx, u, jsonMode, out);
|
|
149
|
+
if (!oc) return EXIT.ERROR;
|
|
150
|
+
|
|
151
|
+
// 信号处理
|
|
152
|
+
let interrupted = false;
|
|
153
|
+
const exitHandler = async (sig) => {
|
|
154
|
+
if (interrupted) return;
|
|
155
|
+
interrupted = true;
|
|
156
|
+
try { await r.orchControl(ctx, taskDef.taskId, 'abort'); } catch { /* 忽略 */ }
|
|
157
|
+
await oc.stop();
|
|
158
|
+
process.stderr.write(`\n已中止(${sig})\n`);
|
|
159
|
+
process.exit(sig === 'SIGINT' ? EXIT.SIGINT : EXIT.SIGTERM);
|
|
160
|
+
};
|
|
161
|
+
process.once('SIGINT', () => exitHandler('SIGINT'));
|
|
162
|
+
process.once('SIGTERM', () => exitHandler('SIGTERM'));
|
|
163
|
+
|
|
164
|
+
const started = Date.now();
|
|
165
|
+
try {
|
|
166
|
+
// load + start(阻塞)
|
|
167
|
+
await r.orchLoad(ctx, taskDef);
|
|
168
|
+
const result = await _startAndRender(ctx, r, taskDef.taskId, { jsonMode, quiet, verbose, out, u, started, dataDir });
|
|
169
|
+
return result.passed ? EXIT.OK : EXIT.TASK_FAILED;
|
|
170
|
+
} catch (err) {
|
|
171
|
+
await oc.stop();
|
|
172
|
+
if (jsonMode) out({ ok: false, error: err.message, taskId: taskDef.taskId });
|
|
173
|
+
else process.stderr.write(`\n编排失败: ${err.message}\n`);
|
|
174
|
+
return EXIT.ERROR;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** 仅加载任务定义,落盘 orchestration.json 后返回。 */
|
|
179
|
+
async function cmdOrchLoad({ flags, rest, projectRoot, dataDir, skillDir, jsonMode, quiet, verbose, out, u }) {
|
|
180
|
+
const positional = _positionalArgs(rest);
|
|
181
|
+
const taskDefFile = positional[0];
|
|
182
|
+
let taskDef;
|
|
183
|
+
try {
|
|
184
|
+
taskDef = _readTaskDef(taskDefFile);
|
|
185
|
+
} catch (err) {
|
|
186
|
+
if (jsonMode) out({ ok: false, error: err.message });
|
|
187
|
+
else process.stderr.write(`${err.message}\n`);
|
|
188
|
+
return EXIT.ERROR;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const r = await _runner();
|
|
192
|
+
const ctx = r.createRunContext({ projectRoot, dataDir, skillDir, verbose });
|
|
193
|
+
try {
|
|
194
|
+
const res = await r.orchLoad(ctx, taskDef);
|
|
195
|
+
if (!quiet) {
|
|
196
|
+
u.logProgress(`编排任务已加载: ${taskDef.taskId}(步骤 ${taskDef.steps.length})`);
|
|
197
|
+
}
|
|
198
|
+
if (jsonMode) {
|
|
199
|
+
out({ ok: true, taskId: taskDef.taskId, status: 'loaded', stepCount: taskDef.steps.length });
|
|
200
|
+
} else {
|
|
201
|
+
process.stdout.write(`${taskDef.taskId}\n`);
|
|
202
|
+
}
|
|
203
|
+
return EXIT.OK;
|
|
204
|
+
} catch (err) {
|
|
205
|
+
if (jsonMode) out({ ok: false, error: err.message });
|
|
206
|
+
else process.stderr.write(`加载失败: ${err.message}\n`);
|
|
207
|
+
return EXIT.ERROR;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ─── start(从磁盘恢复) ───────────────────────────────────────────────────
|
|
212
|
+
|
|
213
|
+
/** 从磁盘恢复 LOADED 状态并启动编排,阻塞到终态。 */
|
|
214
|
+
async function cmdOrchStart({ flags, rest, projectRoot, dataDir, skillDir, jsonMode, quiet, verbose, out, u }) {
|
|
215
|
+
const positional = _positionalArgs(rest);
|
|
216
|
+
const taskId = positional[0];
|
|
217
|
+
if (!taskId) {
|
|
218
|
+
if (jsonMode) out({ ok: false, error: '缺少 taskId。用法: 3rdloop orch start <taskId>' });
|
|
219
|
+
else process.stderr.write('缺少 taskId。用法: 3rdloop orch start <taskId>\n');
|
|
220
|
+
return EXIT.ERROR;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const r = await _runner();
|
|
224
|
+
const ctx = r.createRunContext({ projectRoot, dataDir, skillDir, cliType: 'opencode', verbose });
|
|
225
|
+
const oc = await _ensureOpcodene(ctx, u, jsonMode, out);
|
|
226
|
+
if (!oc) return EXIT.ERROR;
|
|
227
|
+
|
|
228
|
+
let interrupted = false;
|
|
229
|
+
const exitHandler = async (sig) => {
|
|
230
|
+
if (interrupted) return;
|
|
231
|
+
interrupted = true;
|
|
232
|
+
try { await r.orchControl(ctx, taskId, 'abort'); } catch { /* 忽略 */ }
|
|
233
|
+
await oc.stop();
|
|
234
|
+
process.stderr.write(`\n已中止(${sig})\n`);
|
|
235
|
+
process.exit(sig === 'SIGINT' ? EXIT.SIGINT : EXIT.SIGTERM);
|
|
236
|
+
};
|
|
237
|
+
process.once('SIGINT', () => exitHandler('SIGINT'));
|
|
238
|
+
process.once('SIGTERM', () => exitHandler('SIGTERM'));
|
|
239
|
+
|
|
240
|
+
const started = Date.now();
|
|
241
|
+
try {
|
|
242
|
+
const result = await _startAndRender(ctx, r, taskId, { jsonMode, quiet, verbose, out, u, started, dataDir });
|
|
243
|
+
return result.passed ? EXIT.OK : EXIT.TASK_FAILED;
|
|
244
|
+
} catch (err) {
|
|
245
|
+
await oc.stop();
|
|
246
|
+
if (jsonMode) out({ ok: false, error: err.message, taskId });
|
|
247
|
+
else process.stderr.write(`\n编排启动失败: ${err.message}\n`);
|
|
248
|
+
return EXIT.ERROR;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/** 调用 orchStart 并渲染进度(run / start 共用)。 */
|
|
253
|
+
async function _startAndRender(ctx, r, taskId, { jsonMode, quiet, verbose, out, u, started, dataDir }) {
|
|
254
|
+
const q = await _queries();
|
|
255
|
+
let prev = null;
|
|
256
|
+
let finished = false;
|
|
257
|
+
|
|
258
|
+
// 后台轮询编排磁盘快照(每次步骤状态变化 Orchestrator 都会 _persistState),
|
|
259
|
+
// diff 渲染中间进度。只有非 --json 模式才打印,避免污染 stdout。
|
|
260
|
+
// 首帧只记录不打印(prev=null 时不输出),避免启动失败(如状态非 LOADED)
|
|
261
|
+
// 时打印误导性的概览行;最终变化由 orchStart 返回后一次性补齐。
|
|
262
|
+
const poll = (async () => {
|
|
263
|
+
if (jsonMode) return;
|
|
264
|
+
while (!finished) {
|
|
265
|
+
const state = q.readOrchestrationState(dataDir, taskId);
|
|
266
|
+
if (state && prev) {
|
|
267
|
+
const lines = u.diffOrchestration(prev, state, { verbose });
|
|
268
|
+
for (const line of lines) u.logProgress(line);
|
|
269
|
+
}
|
|
270
|
+
if (state) prev = state;
|
|
271
|
+
await new Promise(res => setTimeout(res, 3000));
|
|
272
|
+
}
|
|
273
|
+
})();
|
|
274
|
+
|
|
275
|
+
try {
|
|
276
|
+
const result = await r.orchStart(ctx, taskId);
|
|
277
|
+
finished = true;
|
|
278
|
+
await poll;
|
|
279
|
+
|
|
280
|
+
// 补齐首帧到终态的变化行
|
|
281
|
+
if (!jsonMode) {
|
|
282
|
+
const lines = u.diffOrchestration(prev, result.progress, { verbose });
|
|
283
|
+
for (const line of lines) u.logProgress(line);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const elapsedSec = ((Date.now() - started) / 1000).toFixed(0);
|
|
287
|
+
|
|
288
|
+
if (jsonMode) {
|
|
289
|
+
out({
|
|
290
|
+
ok: result.passed,
|
|
291
|
+
taskId,
|
|
292
|
+
status: result.status,
|
|
293
|
+
passed: result.passed,
|
|
294
|
+
stats: result.progress.stats || null,
|
|
295
|
+
steps: result.progress.steps || [],
|
|
296
|
+
error: result.error,
|
|
297
|
+
resultPaths: result.resultPaths || [],
|
|
298
|
+
elapsedSec: Number(elapsedSec),
|
|
299
|
+
});
|
|
300
|
+
} else {
|
|
301
|
+
u.logProgress(`\n${result.passed ? u.C.green : u.C.red}编排完成: ${u.C.reset}${result.status}`);
|
|
302
|
+
u.logProgress(` 耗时: ${elapsedSec}s`);
|
|
303
|
+
const stats = result.progress.stats || {};
|
|
304
|
+
u.logProgress(` 步骤: 完成 ${stats.completed || 0} / 失败 ${stats.failed || 0}`);
|
|
305
|
+
if (result.error) u.logProgress(` 错误: ${result.error}`);
|
|
306
|
+
for (const item of result.resultPaths || []) {
|
|
307
|
+
u.logProgress(` 产物 ${item.stepId}: ${item.resultPath}`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return result;
|
|
311
|
+
} catch (err) {
|
|
312
|
+
finished = true;
|
|
313
|
+
throw err;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// ─── progress ───────────────────────────────────────────────────────────────
|
|
318
|
+
|
|
319
|
+
/** 查询编排进度(磁盘直读 orchestration.json)。 */
|
|
320
|
+
async function cmdOrchProgress({ flags, rest, dataDir, jsonMode, out, u }) {
|
|
321
|
+
const positional = _positionalArgs(rest);
|
|
322
|
+
const taskId = positional[0];
|
|
323
|
+
if (!taskId) {
|
|
324
|
+
if (jsonMode) out({ ok: false, error: '缺少 taskId。用法: 3rdloop orch progress <taskId> [--loop N]' });
|
|
325
|
+
else process.stderr.write('缺少 taskId。用法: 3rdloop orch progress <taskId> [--loop N]\n');
|
|
326
|
+
return EXIT.ERROR;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const loop = _parseIntFlag(flags, 'loop', undefined);
|
|
330
|
+
const q = await _queries();
|
|
331
|
+
const state = q.readOrchestrationState(dataDir, taskId, loop);
|
|
332
|
+
|
|
333
|
+
if (!state) {
|
|
334
|
+
if (jsonMode) out({ ok: false, error: '编排任务不存在', taskId, loop: loop ?? null });
|
|
335
|
+
else process.stderr.write(`编排任务不存在: ${taskId}${loop != null ? ` (loop=${loop})` : ''}\n`);
|
|
336
|
+
return EXIT.ERROR;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const lines = u.diffOrchestration(null, state, { verbose: false });
|
|
340
|
+
if (jsonMode) {
|
|
341
|
+
// 结构化输出:保持与 HTTP GET /orchestrator/progress 一致形态
|
|
342
|
+
out({ ok: true, taskId, status: state.status, loop: loop ?? null, progress: state });
|
|
343
|
+
return EXIT.OK;
|
|
344
|
+
}
|
|
345
|
+
for (const line of lines) u.logProgress(line);
|
|
346
|
+
// 追加步骤明细
|
|
347
|
+
const steps = state.steps || [];
|
|
348
|
+
for (const s of steps) {
|
|
349
|
+
const icon = s.status === 'completed' ? '✓' : (s.status === 'failed' ? '✗' : (s.status === 'running' ? '▶' : '·'));
|
|
350
|
+
u.logProgress(` ${icon} step ${String(s.stepId).padEnd(4)} ${(s.status || '').padEnd(10)} ${String(s.taskDescription || '').slice(0, 50)}`);
|
|
351
|
+
}
|
|
352
|
+
return EXIT.OK;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// ─── 控制 ───────────────────────────────────────────────────────────────────
|
|
356
|
+
|
|
357
|
+
/** 终止 / 暂停 / 恢复编排(尽力而为,跨进程无法中断另一进程运行中的任务)。 */
|
|
358
|
+
async function cmdOrchControl(action, { flags, rest, projectRoot, dataDir, skillDir, jsonMode, out, u }) {
|
|
359
|
+
const positional = _positionalArgs(rest);
|
|
360
|
+
const taskId = positional[0];
|
|
361
|
+
if (!taskId) {
|
|
362
|
+
if (jsonMode) out({ ok: false, error: `缺少 taskId。用法: 3rdloop orch ${action} <taskId>` });
|
|
363
|
+
else process.stderr.write(`缺少 taskId。用法: 3rdloop orch ${action} <taskId>\n`);
|
|
364
|
+
return EXIT.ERROR;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const r = await _runner();
|
|
368
|
+
const ctx = r.createRunContext({ projectRoot, dataDir, skillDir, verbose: false });
|
|
369
|
+
const result = await r.orchControl(ctx, taskId, action);
|
|
370
|
+
|
|
371
|
+
if (jsonMode) {
|
|
372
|
+
out({ ok: result.ok, taskId, action, status: result.status, error: result.error });
|
|
373
|
+
} else {
|
|
374
|
+
if (result.ok) {
|
|
375
|
+
process.stderr.write(`编排已${action === 'abort' ? '终止' : (action === 'pause' ? '暂停' : '恢复')}: ${taskId}\n`);
|
|
376
|
+
} else {
|
|
377
|
+
process.stderr.write(`${result.error || `操作 ${action} 未生效(可能未在运行中): ${taskId}`}\n`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return result.ok ? EXIT.OK : EXIT.ERROR;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// ─── tasks ──────────────────────────────────────────────────────────────────
|
|
384
|
+
|
|
385
|
+
/** 列出编排任务。 */
|
|
386
|
+
async function cmdOrchTasks({ flags, rest, dataDir, jsonMode, out, u }) {
|
|
387
|
+
const q = await _queries();
|
|
388
|
+
const tasks = q.listOrchestrationTasks(dataDir);
|
|
389
|
+
|
|
390
|
+
if (jsonMode) {
|
|
391
|
+
out({ total: tasks.length, tasks });
|
|
392
|
+
return EXIT.OK;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (tasks.length === 0) {
|
|
396
|
+
process.stdout.write('(暂无编排任务)\n');
|
|
397
|
+
return EXIT.OK;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
process.stdout.write(`共 ${tasks.length} 个编排任务:\n`);
|
|
401
|
+
for (const t of tasks) {
|
|
402
|
+
const icon = t.status === 'completed' ? u.C.green + '✓' + u.C.reset
|
|
403
|
+
: (t.status === 'running') ? u.C.cyan + '▶' + u.C.reset
|
|
404
|
+
: u.C.red + '✗' + u.C.reset;
|
|
405
|
+
const stepInfo = `步骤 ${t.stepCompleted}/${t.stepCount}`;
|
|
406
|
+
process.stdout.write(` ${icon} ${t.taskId.padEnd(40)} ${(t.status || '').padEnd(10)} ${stepInfo.padEnd(12)} ${t.startTime || ''}\n`);
|
|
407
|
+
}
|
|
408
|
+
return EXIT.OK;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// ─── 工具 ──────────────────────────────────────────────────────────────────
|
|
412
|
+
|
|
413
|
+
/** 确保 opencode serve 运行(run/start 需要执行环境;load/progress 不需要)。 */
|
|
414
|
+
async function _ensureOpcodene(ctx, u, jsonMode, out) {
|
|
415
|
+
const { OpencodeManager } = await import('./opencode.js');
|
|
416
|
+
const oc = new OpencodeManager({ projectRoot: ctx.projectRoot });
|
|
417
|
+
const ocHealth = await oc.ensureRunning();
|
|
418
|
+
if (!ocHealth.ok) {
|
|
419
|
+
if (jsonMode) out({ ok: false, error: ocHealth.message });
|
|
420
|
+
process.stderr.write(`\n错误: ${ocHealth.message}\n`);
|
|
421
|
+
process.stderr.write('请先启动 opencode serve(项目上一级目录: opencode serve)后重试。\n');
|
|
422
|
+
await oc.stop();
|
|
423
|
+
return null;
|
|
424
|
+
}
|
|
425
|
+
if (ocHealth.spawned) process.stderr.write(`${ocHealth.message}\n`);
|
|
426
|
+
return oc;
|
|
427
427
|
}
|