principles-disciple 1.8.0 → 1.8.2
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/ADVANCED_CONFIG_ZH.md +97 -0
- package/AGENT_INSTALL.md +173 -0
- package/AGENT_INSTALL_EN.md +173 -0
- package/INSTALL.md +256 -0
- package/SKILL.md +63 -0
- package/docs/COMMAND_REFERENCE.md +76 -0
- package/docs/COMMAND_REFERENCE_EN.md +79 -0
- package/esbuild.config.js +75 -0
- package/openclaw.plugin.json +6 -1
- package/package.json +13 -15
- package/scripts/build-web.mjs +46 -0
- package/scripts/install-dependencies.cjs +47 -0
- package/scripts/sync-plugin.mjs +802 -0
- package/scripts/verify-build.mjs +109 -0
- package/src/agents/nocturnal-dreamer.md +152 -0
- package/src/agents/nocturnal-philosopher.md +138 -0
- package/src/agents/nocturnal-reflector.md +126 -0
- package/src/agents/nocturnal-scribe.md +164 -0
- package/src/commands/capabilities.ts +85 -0
- package/{dist/commands/context.js → src/commands/context.ts} +78 -38
- package/src/commands/evolution-status.ts +146 -0
- package/src/commands/export.ts +111 -0
- package/src/commands/focus.ts +533 -0
- package/src/commands/nocturnal-review.ts +311 -0
- package/src/commands/nocturnal-rollout.ts +763 -0
- package/src/commands/nocturnal-train.ts +1002 -0
- package/{dist/commands/pain.js → src/commands/pain.ts} +68 -49
- package/src/commands/principle-rollback.ts +27 -0
- package/{dist/commands/rollback.js → src/commands/rollback.ts} +44 -12
- package/src/commands/samples.ts +60 -0
- package/src/commands/strategy.ts +38 -0
- package/{dist/commands/thinking-os.js → src/commands/thinking-os.ts} +59 -36
- package/src/commands/workflow-debug.ts +128 -0
- package/{dist/config/defaults/runtime.js → src/config/defaults/runtime.ts} +12 -5
- package/src/config/errors.ts +163 -0
- package/{dist/config/index.d.ts → src/config/index.ts} +2 -1
- package/src/constants/diagnostician.ts +66 -0
- package/src/constants/tools.ts +62 -0
- package/src/core/adaptive-thresholds.ts +476 -0
- package/{dist/core/config-service.js → src/core/config-service.ts} +7 -4
- package/{dist/core/config.js → src/core/config.ts} +158 -46
- package/src/core/control-ui-db.ts +435 -0
- package/{dist/core/detection-funnel.js → src/core/detection-funnel.ts} +36 -21
- package/{dist/core/detection-service.js → src/core/detection-service.ts} +7 -4
- package/{dist/core/dictionary-service.js → src/core/dictionary-service.ts} +7 -4
- package/{dist/core/dictionary.js → src/core/dictionary.ts} +57 -34
- package/src/core/empathy-keyword-matcher.ts +327 -0
- package/src/core/empathy-types.ts +218 -0
- package/src/core/event-log.ts +544 -0
- package/src/core/evolution-engine.ts +612 -0
- package/src/core/evolution-logger.ts +353 -0
- package/src/core/evolution-migration.ts +77 -0
- package/src/core/evolution-reducer.ts +731 -0
- package/src/core/evolution-types.ts +456 -0
- package/src/core/external-training-contract.ts +527 -0
- package/src/core/focus-history.ts +1458 -0
- package/src/core/hygiene/tracker.ts +117 -0
- package/{dist/core/init.js → src/core/init.ts} +39 -26
- package/src/core/local-worker-routing.ts +617 -0
- package/{dist/core/migration.js → src/core/migration.ts} +18 -11
- package/src/core/model-deployment-registry.ts +722 -0
- package/src/core/model-training-registry.ts +813 -0
- package/src/core/nocturnal-arbiter.ts +706 -0
- package/src/core/nocturnal-candidate-scoring.ts +392 -0
- package/src/core/nocturnal-compliance.ts +1075 -0
- package/src/core/nocturnal-dataset.ts +668 -0
- package/src/core/nocturnal-executability.ts +428 -0
- package/src/core/nocturnal-export.ts +390 -0
- package/{dist/core/nocturnal-paths.js → src/core/nocturnal-paths.ts} +49 -23
- package/src/core/nocturnal-trajectory-extractor.ts +484 -0
- package/src/core/nocturnal-trinity.ts +1384 -0
- package/src/core/pain.ts +122 -0
- package/{dist/core/path-resolver.js → src/core/path-resolver.ts} +157 -36
- package/{dist/core/paths.js → src/core/paths.ts} +13 -4
- package/src/core/principle-training-state.ts +450 -0
- package/src/core/profile.ts +226 -0
- package/src/core/promotion-gate.ts +822 -0
- package/{dist/core/risk-calculator.js → src/core/risk-calculator.ts} +42 -16
- package/{dist/core/session-tracker.js → src/core/session-tracker.ts} +185 -63
- package/src/core/shadow-observation-registry.ts +534 -0
- package/{dist/core/system-logger.js → src/core/system-logger.ts} +9 -5
- package/src/core/thinking-models.ts +217 -0
- package/src/core/training-program.ts +630 -0
- package/src/core/trajectory-types.ts +243 -0
- package/src/core/trajectory.ts +1673 -0
- package/{dist/core/workspace-context.js → src/core/workspace-context.ts} +57 -32
- package/src/hooks/bash-risk.ts +171 -0
- package/src/hooks/edit-verification.ts +295 -0
- package/src/hooks/gate-block-helper.ts +160 -0
- package/src/hooks/gate.ts +210 -0
- package/src/hooks/gfi-gate.ts +177 -0
- package/src/hooks/lifecycle.ts +326 -0
- package/{dist/hooks/llm.js → src/hooks/llm.ts} +166 -139
- package/src/hooks/message-sanitize.ts +45 -0
- package/src/hooks/pain.ts +384 -0
- package/src/hooks/progressive-trust-gate.ts +174 -0
- package/src/hooks/prompt.ts +920 -0
- package/src/hooks/subagent.ts +207 -0
- package/src/hooks/thinking-checkpoint.ts +73 -0
- package/src/hooks/trajectory-collector.ts +290 -0
- package/src/http/principles-console-route.ts +716 -0
- package/src/i18n/commands.ts +117 -0
- package/src/index.ts +694 -0
- package/src/service/central-database.ts +831 -0
- package/src/service/control-ui-query-service.ts +888 -0
- package/src/service/evolution-query-service.ts +405 -0
- package/src/service/evolution-worker.ts +1646 -0
- package/src/service/health-query-service.ts +836 -0
- package/{dist/service/nocturnal-runtime.js → src/service/nocturnal-runtime.ts} +263 -36
- package/src/service/nocturnal-service.ts +1015 -0
- package/src/service/nocturnal-target-selector.ts +532 -0
- package/src/service/phase3-input-filter.ts +237 -0
- package/src/service/runtime-summary-service.ts +757 -0
- package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +513 -0
- package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +603 -0
- package/src/service/subagent-workflow/index.ts +51 -0
- package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +856 -0
- package/src/service/subagent-workflow/runtime-direct-driver.ts +166 -0
- package/src/service/subagent-workflow/types.ts +378 -0
- package/src/service/subagent-workflow/workflow-store.ts +328 -0
- package/src/service/trajectory-service.ts +15 -0
- package/{dist/tools/critique-prompt.js → src/tools/critique-prompt.ts} +25 -8
- package/src/tools/deep-reflect.ts +349 -0
- package/{dist/tools/model-index.js → src/tools/model-index.ts} +33 -17
- package/src/types/event-types.ts +453 -0
- package/src/types/hygiene-types.ts +31 -0
- package/src/types/principle-tree-schema.ts +244 -0
- package/src/types/runtime-summary.ts +49 -0
- package/src/types.ts +74 -0
- package/src/utils/file-lock.ts +391 -0
- package/{dist/utils/glob-match.js → src/utils/glob-match.ts} +21 -20
- package/{dist/utils/hashing.js → src/utils/hashing.ts} +6 -4
- package/src/utils/io.ts +110 -0
- package/{dist/utils/nlp.js → src/utils/nlp.ts} +19 -12
- package/{dist/utils/plugin-logger.js → src/utils/plugin-logger.ts} +33 -8
- package/src/utils/subagent-probe.ts +94 -0
- package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +70 -1
- package/templates/pain_settings.json +2 -1
- package/tests/README.md +120 -0
- package/tests/build-artifacts.test.ts +111 -0
- package/tests/commands/evolution-status.test.ts +222 -0
- package/tests/commands/evolver.test.ts +22 -0
- package/tests/commands/export.test.ts +78 -0
- package/tests/commands/nocturnal-review.test.ts +448 -0
- package/tests/commands/nocturnal-train.test.ts +97 -0
- package/tests/commands/pain.test.ts +108 -0
- package/tests/commands/samples.test.ts +65 -0
- package/tests/commands/strategy.test.ts +34 -0
- package/tests/commands/thinking-os.test.ts +88 -0
- package/tests/core/adaptive-thresholds.test.ts +261 -0
- package/tests/core/config-service.test.ts +89 -0
- package/tests/core/config.test.ts +90 -0
- package/tests/core/control-ui-db.test.ts +75 -0
- package/tests/core/core-template-guidance.test.ts +21 -0
- package/tests/core/detection-funnel.test.ts +63 -0
- package/tests/core/detection-service.test.ts +50 -0
- package/tests/core/dictionary-service.test.ts +116 -0
- package/tests/core/dictionary.test.ts +168 -0
- package/tests/core/empathy-keyword-matcher.test.ts +209 -0
- package/tests/core/event-log.test.ts +181 -0
- package/tests/core/evolution-e2e.test.ts +58 -0
- package/tests/core/evolution-engine-gate-integration.test.ts +543 -0
- package/tests/core/evolution-engine.test.ts +562 -0
- package/tests/core/evolution-logger.test.ts +148 -0
- package/tests/core/evolution-migration.test.ts +50 -0
- package/tests/core/evolution-paths.test.ts +21 -0
- package/tests/core/evolution-reducer.detector-metadata.test.ts +602 -0
- package/tests/core/evolution-reducer.test.ts +180 -0
- package/tests/core/evolution-types-loop.test.ts +48 -0
- package/tests/core/evolution-user-stories.e2e.test.ts +249 -0
- package/tests/core/external-training-contract.test.ts +463 -0
- package/tests/core/focus-history.test.ts +682 -0
- package/tests/core/init-flatten.test.ts +69 -0
- package/tests/core/init-refactor.test.ts +87 -0
- package/tests/core/init-v1.3.test.ts +46 -0
- package/tests/core/init.test.ts +190 -0
- package/tests/core/local-worker-routing.test.ts +757 -0
- package/tests/core/migration.test.ts +84 -0
- package/tests/core/model-deployment-registry.test.ts +845 -0
- package/tests/core/model-training-registry.test.ts +889 -0
- package/tests/core/nocturnal-arbiter.test.ts +494 -0
- package/tests/core/nocturnal-candidate-scoring.test.ts +400 -0
- package/tests/core/nocturnal-compliance.test.ts +646 -0
- package/tests/core/nocturnal-dataset.test.ts +892 -0
- package/tests/core/nocturnal-executability.test.ts +357 -0
- package/tests/core/nocturnal-export.test.ts +462 -0
- package/tests/core/nocturnal-reviewed-subset-comparison.test.ts +428 -0
- package/tests/core/nocturnal-trajectory-extractor.test.ts +634 -0
- package/tests/core/nocturnal-trinity.test.ts +953 -0
- package/tests/core/pain.test.ts +33 -0
- package/tests/core/path-resolver.test.ts +57 -0
- package/tests/core/paths-refactor.test.ts +42 -0
- package/tests/core/phase7-rollout-integration.test.ts +477 -0
- package/tests/core/principle-training-state.test.ts +712 -0
- package/tests/core/profile.test.ts +56 -0
- package/tests/core/promotion-gate.test.ts +556 -0
- package/tests/core/risk-calculator.test.ts +168 -0
- package/tests/core/session-tracker.test.ts +191 -0
- package/tests/core/training-program.test.ts +472 -0
- package/tests/core/trajectory.test.ts +265 -0
- package/tests/core/workspace-context-factory.test.ts +18 -0
- package/tests/core/workspace-context.test.ts +134 -0
- package/tests/fixtures/nocturnal-reviewed-subset.json +183 -0
- package/tests/fixtures/production-compatibility.test.ts +147 -0
- package/tests/fixtures/production-mock-generator.ts +282 -0
- package/tests/hooks/bash-risk-integration.test.ts +137 -0
- package/tests/hooks/bash-risk.test.ts +81 -0
- package/tests/hooks/edit-verification.test.ts +678 -0
- package/tests/hooks/gate-edit-verification-p1.test.ts +632 -0
- package/tests/hooks/gate-edit-verification.test.ts +435 -0
- package/tests/hooks/gate-pipeline-integration.test.ts +404 -0
- package/tests/hooks/gate.test.ts +271 -0
- package/tests/hooks/gfi-gate-unit.test.ts +422 -0
- package/tests/hooks/gfi-gate.test.ts +669 -0
- package/tests/hooks/lifecycle.test.ts +248 -0
- package/tests/hooks/llm.test.ts +308 -0
- package/tests/hooks/message-sanitize.test.ts +36 -0
- package/tests/hooks/pain.test.ts +141 -0
- package/tests/hooks/progressive-trust-gate.test.ts +277 -0
- package/tests/hooks/prompt.test.ts +1411 -0
- package/tests/hooks/subagent.test.ts +467 -0
- package/tests/hooks/thinking-gate.test.ts +313 -0
- package/tests/http/principles-console-route.test.ts +140 -0
- package/tests/hygiene-tracker.test.ts +77 -0
- package/tests/index.integration.test.ts +179 -0
- package/tests/index.shadow-routing.integration.test.ts +140 -0
- package/tests/index.test.ts +9 -0
- package/tests/integration/empathy-workflow-integration.test.ts +627 -0
- package/tests/service/control-ui-query-service.test.ts +121 -0
- package/tests/service/empathy-observer-workflow-manager.test.ts +176 -0
- package/tests/service/evolution-worker.test.ts +585 -0
- package/tests/service/nocturnal-runtime.test.ts +470 -0
- package/tests/service/nocturnal-service.test.ts +577 -0
- package/tests/service/nocturnal-target-selector.test.ts +615 -0
- package/tests/service/nocturnal-workflow-manager.test.ts +439 -0
- package/tests/service/phase3-input-filter.test.ts +289 -0
- package/tests/service/runtime-summary-service.test.ts +919 -0
- package/tests/task-compliance.test.ts +166 -0
- package/tests/test-utils.ts +48 -0
- package/tests/tools/critique-prompt.test.ts +260 -0
- package/tests/tools/deep-reflect.test.ts +232 -0
- package/tests/tools/model-index.test.ts +246 -0
- package/tests/ui/app.test.tsx +114 -0
- package/tests/utils/file-lock.test.ts +407 -0
- package/tests/utils/hashing.test.ts +32 -0
- package/tests/utils/io.test.ts +39 -0
- package/tests/utils/nlp.test.ts +53 -0
- package/tests/utils/plugin-logger.test.ts +156 -0
- package/tsconfig.json +16 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/ui/src/App.tsx +45 -0
- package/ui/src/api.ts +216 -0
- package/ui/src/charts.tsx +586 -0
- package/ui/src/components/ErrorState.tsx +6 -0
- package/ui/src/components/Loading.tsx +13 -0
- package/ui/src/components/ProtectedRoute.tsx +12 -0
- package/ui/src/components/Shell.tsx +91 -0
- package/ui/src/components/WorkspaceConfig.tsx +146 -0
- package/ui/src/components/index.ts +5 -0
- package/ui/src/context/auth.tsx +80 -0
- package/ui/src/context/theme.tsx +66 -0
- package/ui/src/hooks/useAutoRefresh.ts +39 -0
- package/ui/src/i18n/ui.ts +363 -0
- package/ui/src/main.tsx +16 -0
- package/ui/src/pages/EvolutionPage.tsx +352 -0
- package/ui/src/pages/FeedbackPage.tsx +140 -0
- package/ui/src/pages/GateMonitorPage.tsx +136 -0
- package/ui/src/pages/LoginPage.tsx +88 -0
- package/ui/src/pages/OverviewPage.tsx +238 -0
- package/ui/src/pages/SamplesPage.tsx +174 -0
- package/ui/src/pages/ThinkingModelsPage.tsx +127 -0
- package/ui/src/styles.css +1661 -0
- package/ui/src/types.ts +368 -0
- package/ui/src/utils/format.ts +15 -0
- package/vitest.config.ts +23 -0
- package/dist/commands/capabilities.d.ts +0 -3
- package/dist/commands/capabilities.js +0 -73
- package/dist/commands/context.d.ts +0 -5
- package/dist/commands/evolution-status.d.ts +0 -4
- package/dist/commands/evolution-status.js +0 -117
- package/dist/commands/evolver.d.ts +0 -9
- package/dist/commands/evolver.js +0 -26
- package/dist/commands/export.d.ts +0 -2
- package/dist/commands/export.js +0 -98
- package/dist/commands/focus.d.ts +0 -14
- package/dist/commands/focus.js +0 -457
- package/dist/commands/nocturnal-review.d.ts +0 -24
- package/dist/commands/nocturnal-review.js +0 -265
- package/dist/commands/nocturnal-rollout.d.ts +0 -27
- package/dist/commands/nocturnal-rollout.js +0 -671
- package/dist/commands/nocturnal-train.d.ts +0 -25
- package/dist/commands/nocturnal-train.js +0 -919
- package/dist/commands/pain.d.ts +0 -5
- package/dist/commands/principle-rollback.d.ts +0 -4
- package/dist/commands/principle-rollback.js +0 -22
- package/dist/commands/rollback.d.ts +0 -19
- package/dist/commands/samples.d.ts +0 -2
- package/dist/commands/samples.js +0 -55
- package/dist/commands/strategy.d.ts +0 -3
- package/dist/commands/strategy.js +0 -29
- package/dist/commands/thinking-os.d.ts +0 -2
- package/dist/config/defaults/runtime.d.ts +0 -40
- package/dist/config/errors.d.ts +0 -84
- package/dist/config/errors.js +0 -94
- package/dist/config/index.js +0 -7
- package/dist/constants/diagnostician.d.ts +0 -12
- package/dist/constants/diagnostician.js +0 -56
- package/dist/constants/tools.d.ts +0 -17
- package/dist/constants/tools.js +0 -54
- package/dist/core/adaptive-thresholds.d.ts +0 -186
- package/dist/core/adaptive-thresholds.js +0 -300
- package/dist/core/config-service.d.ts +0 -15
- package/dist/core/config.d.ts +0 -127
- package/dist/core/control-ui-db.d.ts +0 -95
- package/dist/core/control-ui-db.js +0 -292
- package/dist/core/detection-funnel.d.ts +0 -33
- package/dist/core/detection-service.d.ts +0 -15
- package/dist/core/dictionary-service.d.ts +0 -15
- package/dist/core/dictionary.d.ts +0 -38
- package/dist/core/event-log.d.ts +0 -82
- package/dist/core/event-log.js +0 -463
- package/dist/core/evolution-engine.d.ts +0 -118
- package/dist/core/evolution-engine.js +0 -464
- package/dist/core/evolution-logger.d.ts +0 -137
- package/dist/core/evolution-logger.js +0 -256
- package/dist/core/evolution-migration.d.ts +0 -5
- package/dist/core/evolution-migration.js +0 -65
- package/dist/core/evolution-reducer.d.ts +0 -98
- package/dist/core/evolution-reducer.js +0 -465
- package/dist/core/evolution-types.d.ts +0 -287
- package/dist/core/evolution-types.js +0 -78
- package/dist/core/external-training-contract.d.ts +0 -276
- package/dist/core/external-training-contract.js +0 -269
- package/dist/core/focus-history.d.ts +0 -210
- package/dist/core/focus-history.js +0 -1185
- package/dist/core/hygiene/tracker.d.ts +0 -22
- package/dist/core/hygiene/tracker.js +0 -106
- package/dist/core/init.d.ts +0 -12
- package/dist/core/local-worker-routing.d.ts +0 -175
- package/dist/core/local-worker-routing.js +0 -525
- package/dist/core/migration.d.ts +0 -6
- package/dist/core/model-deployment-registry.d.ts +0 -218
- package/dist/core/model-deployment-registry.js +0 -503
- package/dist/core/model-training-registry.d.ts +0 -295
- package/dist/core/model-training-registry.js +0 -475
- package/dist/core/nocturnal-arbiter.d.ts +0 -159
- package/dist/core/nocturnal-arbiter.js +0 -534
- package/dist/core/nocturnal-candidate-scoring.d.ts +0 -137
- package/dist/core/nocturnal-candidate-scoring.js +0 -266
- package/dist/core/nocturnal-compliance.d.ts +0 -175
- package/dist/core/nocturnal-compliance.js +0 -824
- package/dist/core/nocturnal-dataset.d.ts +0 -224
- package/dist/core/nocturnal-dataset.js +0 -443
- package/dist/core/nocturnal-executability.d.ts +0 -85
- package/dist/core/nocturnal-executability.js +0 -331
- package/dist/core/nocturnal-export.d.ts +0 -124
- package/dist/core/nocturnal-export.js +0 -275
- package/dist/core/nocturnal-paths.d.ts +0 -124
- package/dist/core/nocturnal-trajectory-extractor.d.ts +0 -242
- package/dist/core/nocturnal-trajectory-extractor.js +0 -307
- package/dist/core/nocturnal-trinity.d.ts +0 -311
- package/dist/core/nocturnal-trinity.js +0 -880
- package/dist/core/pain.d.ts +0 -4
- package/dist/core/pain.js +0 -70
- package/dist/core/path-resolver.d.ts +0 -46
- package/dist/core/paths.d.ts +0 -65
- package/dist/core/principle-training-state.d.ts +0 -121
- package/dist/core/principle-training-state.js +0 -321
- package/dist/core/profile.d.ts +0 -62
- package/dist/core/profile.js +0 -210
- package/dist/core/promotion-gate.d.ts +0 -238
- package/dist/core/promotion-gate.js +0 -529
- package/dist/core/risk-calculator.d.ts +0 -22
- package/dist/core/session-tracker.d.ts +0 -99
- package/dist/core/shadow-observation-registry.d.ts +0 -217
- package/dist/core/shadow-observation-registry.js +0 -308
- package/dist/core/system-logger.d.ts +0 -8
- package/dist/core/thinking-models.d.ts +0 -38
- package/dist/core/thinking-models.js +0 -170
- package/dist/core/training-program.d.ts +0 -233
- package/dist/core/training-program.js +0 -433
- package/dist/core/trajectory.d.ts +0 -411
- package/dist/core/trajectory.js +0 -1307
- package/dist/core/workspace-context.d.ts +0 -71
- package/dist/hooks/bash-risk.d.ts +0 -57
- package/dist/hooks/bash-risk.js +0 -137
- package/dist/hooks/edit-verification.d.ts +0 -62
- package/dist/hooks/edit-verification.js +0 -256
- package/dist/hooks/gate-block-helper.d.ts +0 -44
- package/dist/hooks/gate-block-helper.js +0 -119
- package/dist/hooks/gate.d.ts +0 -24
- package/dist/hooks/gate.js +0 -173
- package/dist/hooks/gfi-gate.d.ts +0 -40
- package/dist/hooks/gfi-gate.js +0 -113
- package/dist/hooks/lifecycle.d.ts +0 -5
- package/dist/hooks/lifecycle.js +0 -284
- package/dist/hooks/llm.d.ts +0 -12
- package/dist/hooks/message-sanitize.d.ts +0 -3
- package/dist/hooks/message-sanitize.js +0 -37
- package/dist/hooks/pain.d.ts +0 -5
- package/dist/hooks/pain.js +0 -301
- package/dist/hooks/progressive-trust-gate.d.ts +0 -51
- package/dist/hooks/progressive-trust-gate.js +0 -89
- package/dist/hooks/prompt.d.ts +0 -47
- package/dist/hooks/prompt.js +0 -884
- package/dist/hooks/subagent.d.ts +0 -10
- package/dist/hooks/subagent.js +0 -387
- package/dist/hooks/thinking-checkpoint.d.ts +0 -37
- package/dist/hooks/thinking-checkpoint.js +0 -51
- package/dist/hooks/trajectory-collector.d.ts +0 -32
- package/dist/hooks/trajectory-collector.js +0 -256
- package/dist/http/principles-console-route.d.ts +0 -9
- package/dist/http/principles-console-route.js +0 -567
- package/dist/i18n/commands.d.ts +0 -26
- package/dist/i18n/commands.js +0 -116
- package/dist/index.d.ts +0 -7
- package/dist/index.js +0 -581
- package/dist/service/central-database.d.ts +0 -104
- package/dist/service/central-database.js +0 -649
- package/dist/service/control-ui-query-service.d.ts +0 -221
- package/dist/service/control-ui-query-service.js +0 -543
- package/dist/service/empathy-observer-manager.d.ts +0 -52
- package/dist/service/empathy-observer-manager.js +0 -229
- package/dist/service/evolution-query-service.d.ts +0 -155
- package/dist/service/evolution-query-service.js +0 -258
- package/dist/service/evolution-worker.d.ts +0 -101
- package/dist/service/evolution-worker.js +0 -974
- package/dist/service/nocturnal-runtime.d.ts +0 -183
- package/dist/service/nocturnal-service.d.ts +0 -163
- package/dist/service/nocturnal-service.js +0 -787
- package/dist/service/nocturnal-target-selector.d.ts +0 -145
- package/dist/service/nocturnal-target-selector.js +0 -315
- package/dist/service/phase3-input-filter.d.ts +0 -73
- package/dist/service/phase3-input-filter.js +0 -172
- package/dist/service/runtime-summary-service.d.ts +0 -122
- package/dist/service/runtime-summary-service.js +0 -485
- package/dist/service/trajectory-service.d.ts +0 -2
- package/dist/service/trajectory-service.js +0 -15
- package/dist/tools/critique-prompt.d.ts +0 -14
- package/dist/tools/deep-reflect.d.ts +0 -39
- package/dist/tools/deep-reflect.js +0 -350
- package/dist/tools/model-index.d.ts +0 -9
- package/dist/types/event-types.d.ts +0 -306
- package/dist/types/event-types.js +0 -106
- package/dist/types/hygiene-types.d.ts +0 -20
- package/dist/types/hygiene-types.js +0 -12
- package/dist/types/runtime-summary.d.ts +0 -47
- package/dist/types/runtime-summary.js +0 -1
- package/dist/types.d.ts +0 -50
- package/dist/types.js +0 -22
- package/dist/utils/file-lock.d.ts +0 -71
- package/dist/utils/file-lock.js +0 -309
- package/dist/utils/glob-match.d.ts +0 -28
- package/dist/utils/hashing.d.ts +0 -9
- package/dist/utils/io.d.ts +0 -6
- package/dist/utils/io.js +0 -106
- package/dist/utils/nlp.d.ts +0 -9
- package/dist/utils/plugin-logger.d.ts +0 -39
- package/dist/utils/subagent-probe.d.ts +0 -34
- package/dist/utils/subagent-probe.js +0 -81
|
@@ -0,0 +1,802 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Principles Disciple Plugin Installer
|
|
5
|
+
*
|
|
6
|
+
* A complete installation script that can run after cloning the repo.
|
|
7
|
+
* Handles dependencies, build, and sync to OpenClaw installation directory.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* node scripts/sync-plugin.mjs [options]
|
|
11
|
+
*
|
|
12
|
+
* Options:
|
|
13
|
+
* --lang <zh|en> Language for skills (default: zh)
|
|
14
|
+
* --skip-build Skip build step (use existing dist/)
|
|
15
|
+
* --skip-deps Skip dependency installation
|
|
16
|
+
* --force Force overwrite without prompts
|
|
17
|
+
* --help Show help message
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { copyFileSync, cpSync, existsSync, rmSync, readFileSync, readFileSync as readFileSyncRaw, mkdirSync, writeFileSync, readdirSync } from 'fs';
|
|
21
|
+
import { createHash } from 'crypto';
|
|
22
|
+
import { join, dirname } from 'path';
|
|
23
|
+
import { fileURLToPath } from 'url';
|
|
24
|
+
import { execSync } from 'child_process';
|
|
25
|
+
|
|
26
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
27
|
+
const __dirname = dirname(__filename);
|
|
28
|
+
|
|
29
|
+
const SOURCE_DIR = join(__dirname, '..');
|
|
30
|
+
const OPENCLAW_DIR = join(process.env.HOME, '.openclaw');
|
|
31
|
+
const INSTALL_DIR = join(OPENCLAW_DIR, 'extensions', 'principles-disciple');
|
|
32
|
+
|
|
33
|
+
// Files and directories to sync
|
|
34
|
+
const SYNC_ITEMS = [
|
|
35
|
+
'dist',
|
|
36
|
+
'templates',
|
|
37
|
+
'scripts',
|
|
38
|
+
'docs',
|
|
39
|
+
'openclaw.plugin.json',
|
|
40
|
+
'package.json',
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
// Minimum Node.js version
|
|
44
|
+
const MIN_NODE_VERSION = '18.0.0';
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Parse command line arguments
|
|
48
|
+
*/
|
|
49
|
+
function parseArgs() {
|
|
50
|
+
const args = {
|
|
51
|
+
lang: process.env.OPENCLAW_LANGUAGE || 'zh',
|
|
52
|
+
skipBuild: false,
|
|
53
|
+
skipDeps: false,
|
|
54
|
+
force: false,
|
|
55
|
+
restart: false,
|
|
56
|
+
dev: false,
|
|
57
|
+
help: false,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const argv = process.argv.slice(2);
|
|
61
|
+
for (let i = 0; i < argv.length; i++) {
|
|
62
|
+
const arg = argv[i];
|
|
63
|
+
switch (arg) {
|
|
64
|
+
case '--lang':
|
|
65
|
+
args.lang = argv[++i];
|
|
66
|
+
break;
|
|
67
|
+
case '--skip-build':
|
|
68
|
+
args.skipBuild = true;
|
|
69
|
+
break;
|
|
70
|
+
case '--skip-deps':
|
|
71
|
+
args.skipDeps = true;
|
|
72
|
+
break;
|
|
73
|
+
case '--restart':
|
|
74
|
+
args.restart = true;
|
|
75
|
+
break;
|
|
76
|
+
case '--dev':
|
|
77
|
+
case '-d':
|
|
78
|
+
args.dev = true;
|
|
79
|
+
args.force = true;
|
|
80
|
+
args.restart = true;
|
|
81
|
+
break;
|
|
82
|
+
case '--force':
|
|
83
|
+
case '-f':
|
|
84
|
+
args.force = true;
|
|
85
|
+
break;
|
|
86
|
+
case '--help':
|
|
87
|
+
case '-h':
|
|
88
|
+
args.help = true;
|
|
89
|
+
break;
|
|
90
|
+
default:
|
|
91
|
+
if (arg.startsWith('--')) {
|
|
92
|
+
console.error(`Unknown option: ${arg}`);
|
|
93
|
+
args.help = true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return args;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Show help message
|
|
102
|
+
*/
|
|
103
|
+
function showHelp() {
|
|
104
|
+
console.log(`
|
|
105
|
+
Principles Disciple Plugin Installer
|
|
106
|
+
|
|
107
|
+
Usage:
|
|
108
|
+
node scripts/sync-plugin.mjs [options]
|
|
109
|
+
|
|
110
|
+
Options:
|
|
111
|
+
--lang <zh|en> Language for skills (default: zh)
|
|
112
|
+
--skip-build Skip build step (use existing dist/)
|
|
113
|
+
--skip-deps Skip dependency installation
|
|
114
|
+
--restart Automatically restart OpenClaw gateway after installation
|
|
115
|
+
--dev, -d Developer mode: --force + --restart + clean stale backups (default for local dev)
|
|
116
|
+
--force, -f Force overwrite without prompts
|
|
117
|
+
--help, -h Show this help message
|
|
118
|
+
|
|
119
|
+
Examples:
|
|
120
|
+
# Full installation with Chinese skills
|
|
121
|
+
node scripts/sync-plugin.mjs
|
|
122
|
+
|
|
123
|
+
# Install with English skills
|
|
124
|
+
node scripts/sync-plugin.mjs --lang en
|
|
125
|
+
|
|
126
|
+
# Developer mode: build, deploy, restart, clean up (recommended for debugging)
|
|
127
|
+
node scripts/sync-plugin.mjs --dev
|
|
128
|
+
|
|
129
|
+
# Quick sync after local build
|
|
130
|
+
node scripts/sync-plugin.mjs --skip-deps --skip-build
|
|
131
|
+
|
|
132
|
+
Environment Variables:
|
|
133
|
+
OPENCLAW_LANGUAGE Default language for skills (zh or en)
|
|
134
|
+
`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Compare semver versions
|
|
139
|
+
*/
|
|
140
|
+
function compareVersions(a, b) {
|
|
141
|
+
const partsA = a.split('.').map(Number);
|
|
142
|
+
const partsB = b.split('.').map(Number);
|
|
143
|
+
for (let i = 0; i < 3; i++) {
|
|
144
|
+
if (partsA[i] > partsB[i]) return 1;
|
|
145
|
+
if (partsA[i] < partsB[i]) return -1;
|
|
146
|
+
}
|
|
147
|
+
return 0;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Main function
|
|
152
|
+
*/
|
|
153
|
+
function checkPrerequisites() {
|
|
154
|
+
// Check Node.js version
|
|
155
|
+
const nodeVersion = process.version.replace(/^v/, '');
|
|
156
|
+
if (compareVersions(nodeVersion, MIN_NODE_VERSION) < 0) {
|
|
157
|
+
console.error(`❌ Node.js ${MIN_NODE_VERSION}+ required, got ${nodeVersion}`);
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
console.log(`✅ Node.js ${nodeVersion} (>= ${MIN_NODE_VERSION})`);
|
|
161
|
+
|
|
162
|
+
// Check npm
|
|
163
|
+
try {
|
|
164
|
+
const npmVersion = execSync('npm --version', { encoding: 'utf-8' }).trim();
|
|
165
|
+
console.log(`✅ npm ${npmVersion}`);
|
|
166
|
+
|
|
167
|
+
// Check for global package conflicts that cause module resolution traps
|
|
168
|
+
console.log('🔍 Checking for global package conflicts...');
|
|
169
|
+
try {
|
|
170
|
+
const globalConflict = execSync('npm list -g principles-disciple --depth=0 2>/dev/null', { encoding: 'utf-8' });
|
|
171
|
+
if (globalConflict.includes('principles-disciple')) {
|
|
172
|
+
console.error('\n❌ CONFLICT DETECTED: A version of "principles-disciple" is installed globally via npm.');
|
|
173
|
+
console.error('This will block OpenClaw from loading the extension version you are trying to install.');
|
|
174
|
+
console.error('\nACTION REQUIRED: Please run the following command first:');
|
|
175
|
+
console.error(' npm uninstall -g principles-disciple\n');
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
} catch (e) {
|
|
179
|
+
// npm list returns non-zero if not found, which is what we want
|
|
180
|
+
console.log('✅ No global package conflicts detected.');
|
|
181
|
+
}
|
|
182
|
+
} catch {
|
|
183
|
+
console.error('❌ npm not found. Please install Node.js with npm.');
|
|
184
|
+
process.exit(1);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Check if we're in the plugin directory
|
|
188
|
+
if (!existsSync(join(SOURCE_DIR, 'package.json'))) {
|
|
189
|
+
console.error('❌ Not in plugin directory. package.json not found.');
|
|
190
|
+
console.error(' Run this script from packages/openclaw-plugin/');
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Extract version from package.json
|
|
197
|
+
*/
|
|
198
|
+
function getVersion(dir) {
|
|
199
|
+
const pkgPath = join(dir, 'package.json');
|
|
200
|
+
if (!existsSync(pkgPath)) return null;
|
|
201
|
+
try {
|
|
202
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
203
|
+
return pkg.version;
|
|
204
|
+
} catch {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Install project dependencies
|
|
211
|
+
*/
|
|
212
|
+
function installDependencies() {
|
|
213
|
+
console.log('\n📦 Installing project dependencies...');
|
|
214
|
+
|
|
215
|
+
const nodeModulesDir = join(SOURCE_DIR, 'node_modules');
|
|
216
|
+
const needsInstall = !existsSync(nodeModulesDir) ||
|
|
217
|
+
!existsSync(join(nodeModulesDir, 'better-sqlite3'));
|
|
218
|
+
|
|
219
|
+
if (!needsInstall) {
|
|
220
|
+
console.log('✅ Dependencies already installed');
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
try {
|
|
225
|
+
execSync('npm install', {
|
|
226
|
+
cwd: SOURCE_DIR,
|
|
227
|
+
stdio: 'inherit'
|
|
228
|
+
});
|
|
229
|
+
console.log('✅ Dependencies installed');
|
|
230
|
+
} catch (error) {
|
|
231
|
+
console.error('❌ Failed to install dependencies');
|
|
232
|
+
process.exit(1);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Build the plugin.
|
|
238
|
+
* Always runs build:production to ensure dist/bundle.js (the actual shipped artifact)
|
|
239
|
+
* is always fresh. We no longer compare timestamps because:
|
|
240
|
+
* 1. tsc alone updates index.js without updating bundle.js
|
|
241
|
+
* 2. Comparing index.js vs src files falsely claims "up to date"
|
|
242
|
+
* 3. The cost of a extra ~10s build is far cheaper than shipping stale bundles
|
|
243
|
+
*
|
|
244
|
+
* Use --skip-build only in CI where you know dist/ is already fresh.
|
|
245
|
+
*/
|
|
246
|
+
function buildPlugin() {
|
|
247
|
+
console.log('\n🔨 Building plugin (esbuild only — bypassing tsc which may fail on unrelated files)...');
|
|
248
|
+
|
|
249
|
+
try {
|
|
250
|
+
// Run esbuild directly — it compiles TS on the fly and doesn't care about
|
|
251
|
+
// tsc errors in unrelated files (e.g. subagent-workflow type errors).
|
|
252
|
+
execSync('node esbuild.config.js --production', {
|
|
253
|
+
cwd: SOURCE_DIR,
|
|
254
|
+
stdio: 'inherit'
|
|
255
|
+
});
|
|
256
|
+
// Copy templates and manifest
|
|
257
|
+
execSync('node scripts/build-web.mjs --production', {
|
|
258
|
+
cwd: SOURCE_DIR,
|
|
259
|
+
stdio: 'inherit'
|
|
260
|
+
});
|
|
261
|
+
} catch (error) {
|
|
262
|
+
console.error('\n❌ Build failed');
|
|
263
|
+
console.error(` ${error.message}`);
|
|
264
|
+
process.exit(1);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Post-build verification: ensure critical symbols made it into bundle.js
|
|
268
|
+
verifyBundleContents();
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Verify the built bundle contains all critical symbols.
|
|
273
|
+
* This catches build failures where tsc succeeds but esbuild/bundling silently drops code.
|
|
274
|
+
*/
|
|
275
|
+
function verifyBundleContents() {
|
|
276
|
+
const bundleJs = join(SOURCE_DIR, 'dist', 'bundle.js');
|
|
277
|
+
if (!existsSync(bundleJs)) {
|
|
278
|
+
console.error('❌ dist/bundle.js missing after build.');
|
|
279
|
+
process.exit(1);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const content = readFileSync(bundleJs, 'utf-8');
|
|
283
|
+
|
|
284
|
+
// Structural markers that survive minification (module exports, log prefixes).
|
|
285
|
+
// These are more stable than class/function names which get mangled.
|
|
286
|
+
// Add/remove markers as the codebase evolves — keep this list minimal.
|
|
287
|
+
const requiredSymbols = [
|
|
288
|
+
{ name: 'EvolutionWorkerService', reason: 'main plugin service export' },
|
|
289
|
+
{ name: 'checkPainFlag', reason: 'pain flag detection' },
|
|
290
|
+
{ name: 'processEvolutionQueue', reason: 'queue processing' },
|
|
291
|
+
];
|
|
292
|
+
|
|
293
|
+
const missing = [];
|
|
294
|
+
for (const sym of requiredSymbols) {
|
|
295
|
+
if (!content.includes(sym.name)) {
|
|
296
|
+
missing.push(` - ${sym.name}: ${sym.reason}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (missing.length > 0) {
|
|
301
|
+
console.warn('\n⚠️ Bundle verification warning — symbols not found (may be minified):');
|
|
302
|
+
missing.forEach(m => console.warn(m));
|
|
303
|
+
console.warn(' This is a warning, not an error. Minification may have renamed these.');
|
|
304
|
+
console.warn(' If the plugin actually fails to load, check for build issues.');
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
console.log('✅ Bundle verification passed — all critical symbols present');
|
|
308
|
+
|
|
309
|
+
// Write build fingerprint to dist/openclaw.plugin.json
|
|
310
|
+
writeBuildFingerprint();
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Write a build fingerprint (git SHA + bundle MD5) into dist/openclaw.plugin.json.
|
|
315
|
+
* This allows post-install verification to detect stale installations.
|
|
316
|
+
*/
|
|
317
|
+
function writeBuildFingerprint() {
|
|
318
|
+
const bundleJs = join(SOURCE_DIR, 'dist', 'bundle.js');
|
|
319
|
+
const manifestSrc = join(SOURCE_DIR, 'openclaw.plugin.json');
|
|
320
|
+
const manifestDist = join(SOURCE_DIR, 'dist', 'openclaw.plugin.json');
|
|
321
|
+
|
|
322
|
+
// Get git SHA of current commit
|
|
323
|
+
let gitSha = 'unknown';
|
|
324
|
+
try {
|
|
325
|
+
gitSha = execSync('git rev-parse HEAD', {
|
|
326
|
+
cwd: SOURCE_DIR,
|
|
327
|
+
encoding: 'utf-8',
|
|
328
|
+
timeout: 10000,
|
|
329
|
+
}).trim().slice(0, 12);
|
|
330
|
+
} catch {
|
|
331
|
+
console.warn('⚠️ Could not get git SHA, fingerprint will be incomplete');
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Compute MD5 of bundle.js
|
|
335
|
+
let bundleMd5 = 'unknown';
|
|
336
|
+
try {
|
|
337
|
+
const bundleContent = readFileSyncRaw(bundleJs);
|
|
338
|
+
bundleMd5 = createHash('md5').update(bundleContent).digest('hex');
|
|
339
|
+
} catch {
|
|
340
|
+
console.warn('⚠️ Could not compute bundle MD5, fingerprint will be incomplete');
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Read manifest
|
|
344
|
+
let manifest;
|
|
345
|
+
try {
|
|
346
|
+
manifest = JSON.parse(readFileSync(manifestDist, 'utf-8'));
|
|
347
|
+
} catch {
|
|
348
|
+
try {
|
|
349
|
+
manifest = JSON.parse(readFileSync(manifestSrc, 'utf-8'));
|
|
350
|
+
} catch {
|
|
351
|
+
console.warn('⚠️ Could not read openclaw.plugin.json, skipping fingerprint');
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Attach fingerprint
|
|
357
|
+
manifest.buildFingerprint = {
|
|
358
|
+
gitSha,
|
|
359
|
+
bundleMd5,
|
|
360
|
+
builtAt: new Date().toISOString(),
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
// Write back to dist/openclaw.plugin.json (this is what gets synced)
|
|
364
|
+
try {
|
|
365
|
+
mkdirSync(join(SOURCE_DIR, 'dist'), { recursive: true });
|
|
366
|
+
writeFileAtomic(manifestDist, JSON.stringify(manifest, null, 2) + '\n');
|
|
367
|
+
console.log(`✅ Build fingerprint: git=${gitSha} bundleMd5=${bundleMd5}`);
|
|
368
|
+
} catch (err) {
|
|
369
|
+
console.warn(`⚠️ Could not write fingerprint to dist/openclaw.plugin.json: ${err.message}`);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Also update the root openclaw.plugin.json so that both synced files have the fingerprint.
|
|
373
|
+
// This ensures fingerprint verification works whether OpenClaw loads from dist/ or root manifest.
|
|
374
|
+
try {
|
|
375
|
+
const rootManifest = JSON.parse(readFileSync(manifestSrc, 'utf-8'));
|
|
376
|
+
rootManifest.buildFingerprint = manifest.buildFingerprint;
|
|
377
|
+
writeFileAtomic(manifestSrc, JSON.stringify(rootManifest, null, 2) + '\n');
|
|
378
|
+
} catch {
|
|
379
|
+
// Non-fatal — root manifest may be identical in content
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Atomic file write (write to temp then rename, to avoid partial writes).
|
|
385
|
+
*/
|
|
386
|
+
function writeFileAtomic(filePath, content) {
|
|
387
|
+
const tmp = filePath + '.tmp.' + Date.now();
|
|
388
|
+
writeFileSync(tmp, content, 'utf-8');
|
|
389
|
+
rmSync(filePath, { force: true });
|
|
390
|
+
copyFileSync(tmp, filePath);
|
|
391
|
+
rmSync(tmp, { force: true });
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Verify the installed plugin matches the source fingerprint.
|
|
396
|
+
* If fingerprint in installed manifest differs from source manifest → abort.
|
|
397
|
+
* This catches the case where a previous sync synced a stale bundle.
|
|
398
|
+
*/
|
|
399
|
+
function verifyInstalledFingerprint() {
|
|
400
|
+
// Read from dist/ manifests because:
|
|
401
|
+
// - dist/openclaw.plugin.json has the buildFingerprint written by writeBuildFingerprint()
|
|
402
|
+
// - Root openclaw.plugin.json is copied from SOURCE_DIR (no fingerprint, not updated by writeBuildFingerprint)
|
|
403
|
+
const sourceManifest = join(SOURCE_DIR, 'dist', 'openclaw.plugin.json');
|
|
404
|
+
const installedManifest = join(INSTALL_DIR, 'dist', 'openclaw.plugin.json');
|
|
405
|
+
|
|
406
|
+
if (!existsSync(installedManifest)) {
|
|
407
|
+
console.error('\n❌ Installed manifest not found — sync may have failed.');
|
|
408
|
+
process.exit(1);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
let sourceFp, installedFp;
|
|
412
|
+
try {
|
|
413
|
+
const sm = JSON.parse(readFileSync(sourceManifest, 'utf-8'));
|
|
414
|
+
const im = JSON.parse(readFileSync(installedManifest, 'utf-8'));
|
|
415
|
+
sourceFp = sm.buildFingerprint;
|
|
416
|
+
installedFp = im.buildFingerprint;
|
|
417
|
+
} catch {
|
|
418
|
+
// If we can't read/parse, skip verification
|
|
419
|
+
console.warn('⚠️ Could not read fingerprints, skipping fingerprint verification');
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (!sourceFp || !installedFp) {
|
|
424
|
+
console.warn('⚠️ Missing fingerprint in one or both manifests, skipping verification.');
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
const gitMismatch = sourceFp.gitSha !== installedFp.gitSha;
|
|
429
|
+
const md5Mismatch = sourceFp.bundleMd5 !== installedFp.bundleMd5;
|
|
430
|
+
|
|
431
|
+
if (gitMismatch || md5Mismatch) {
|
|
432
|
+
console.error('\n❌ INSTALLED PLUGIN IS STALE — FINGERPRINT MISMATCH');
|
|
433
|
+
console.error(' This means the installed plugin bundle does not match the current source build.');
|
|
434
|
+
if (gitMismatch) {
|
|
435
|
+
console.error(` Source git SHA: ${sourceFp.gitSha} (current)`);
|
|
436
|
+
console.error(` Installed git SHA: ${installedFp.gitSha} (old)`);
|
|
437
|
+
}
|
|
438
|
+
if (md5Mismatch) {
|
|
439
|
+
console.error(` Source bundle MD5: ${sourceFp.bundleMd5} (current)`);
|
|
440
|
+
console.error(` Installed bundle: ${installedFp.bundleMd5} (old)`);
|
|
441
|
+
}
|
|
442
|
+
console.error('\n → Run WITHOUT --skip-build to rebuild and reinstall:');
|
|
443
|
+
console.error(` cd ${SOURCE_DIR} && node scripts/sync-plugin.mjs`);
|
|
444
|
+
process.exit(1);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
console.log('✅ Installed fingerprint verified — matches current source build');
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Verify build exists and bundle contains critical symbols.
|
|
452
|
+
* Called when --skip-build is used (e.g., in CI with fresh dist/).
|
|
453
|
+
* Still verifies critical symbols to catch any pre-existing build issues.
|
|
454
|
+
*/
|
|
455
|
+
function verifyBuild() {
|
|
456
|
+
const distDir = join(SOURCE_DIR, 'dist');
|
|
457
|
+
const indexJs = join(distDir, 'index.js');
|
|
458
|
+
const bundleJs = join(distDir, 'bundle.js');
|
|
459
|
+
|
|
460
|
+
if (!existsSync(distDir)) {
|
|
461
|
+
console.error('❌ dist/ directory not found.');
|
|
462
|
+
console.error(' Run without --skip-build to build automatically.');
|
|
463
|
+
process.exit(1);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
if (!existsSync(indexJs) && !existsSync(bundleJs)) {
|
|
467
|
+
console.error('❌ dist/index.js or dist/bundle.js not found.');
|
|
468
|
+
console.error(' Run without --skip-build to build automatically.');
|
|
469
|
+
process.exit(1);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// Verify critical symbols even when skipping build
|
|
473
|
+
// (catches stale dist from previous failed builds)
|
|
474
|
+
try {
|
|
475
|
+
verifyBundleContents();
|
|
476
|
+
} catch {
|
|
477
|
+
// verifyBundleContents already exits on failure
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
console.log('✅ Build verified');
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Remove existing installation directory (clean slate)
|
|
485
|
+
* This ensures no stale files remain from old versions.
|
|
486
|
+
*/
|
|
487
|
+
function cleanTargetDir(force) {
|
|
488
|
+
if (!existsSync(INSTALL_DIR)) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
if (!force) {
|
|
493
|
+
const installedVersion = getVersion(INSTALL_DIR);
|
|
494
|
+
if (installedVersion && installedVersion !== getVersion(SOURCE_DIR)) {
|
|
495
|
+
console.error(`\n❌ VERSION CONFLICT:`);
|
|
496
|
+
console.error(` Installed: v${installedVersion}`);
|
|
497
|
+
console.error(` Source: v${getVersion(SOURCE_DIR)}`);
|
|
498
|
+
console.error(` Run with --force to overwrite, or uninstall first.`);
|
|
499
|
+
process.exit(1);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
console.log('\n🗑️ Removing existing installation...');
|
|
504
|
+
rmSync(INSTALL_DIR, { recursive: true, force: true });
|
|
505
|
+
console.log(` Removed: ${INSTALL_DIR}`);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Ensure installation directory exists
|
|
510
|
+
*/
|
|
511
|
+
function ensureInstallDir() {
|
|
512
|
+
if (existsSync(INSTALL_DIR)) {
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
console.log('\n📁 Creating installation directory...');
|
|
517
|
+
|
|
518
|
+
// Check if OpenClaw is installed
|
|
519
|
+
if (!existsSync(OPENCLAW_DIR)) {
|
|
520
|
+
console.error(`❌ OpenClaw installation not found: ${OPENCLAW_DIR}`);
|
|
521
|
+
console.error(' Please install OpenClaw first.');
|
|
522
|
+
process.exit(1);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// Create extensions directory if needed
|
|
526
|
+
const extensionsDir = join(OPENCLAW_DIR, 'extensions');
|
|
527
|
+
if (!existsSync(extensionsDir)) {
|
|
528
|
+
mkdirSync(extensionsDir, { recursive: true });
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// Create plugin directory
|
|
532
|
+
mkdirSync(INSTALL_DIR, { recursive: true });
|
|
533
|
+
console.log(`✅ Created: ${INSTALL_DIR}`);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Sync skills from templates to installation directory
|
|
538
|
+
*/
|
|
539
|
+
function syncSkills(lang) {
|
|
540
|
+
const skillsSource = join(SOURCE_DIR, 'templates', 'langs', lang, 'skills');
|
|
541
|
+
const skillsTarget = join(INSTALL_DIR, 'skills');
|
|
542
|
+
|
|
543
|
+
if (!existsSync(skillsSource)) {
|
|
544
|
+
console.log(` ⚠️ Skills not found for language: ${lang}`);
|
|
545
|
+
return false;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// Remove existing skills
|
|
549
|
+
if (existsSync(skillsTarget)) {
|
|
550
|
+
rmSync(skillsTarget, { recursive: true, force: true });
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// Copy skills
|
|
554
|
+
cpSync(skillsSource, skillsTarget, { recursive: true });
|
|
555
|
+
console.log(` 📄 skills (from templates/langs/${lang}/skills)`);
|
|
556
|
+
return true;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* Sync a single item
|
|
561
|
+
*/
|
|
562
|
+
function syncItem(item) {
|
|
563
|
+
const source = join(SOURCE_DIR, item);
|
|
564
|
+
const target = join(INSTALL_DIR, item);
|
|
565
|
+
|
|
566
|
+
if (!existsSync(source)) {
|
|
567
|
+
console.log(` ⚠️ Skipping ${item} (not found)`);
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
console.log(` 📄 ${item}`);
|
|
572
|
+
|
|
573
|
+
// Remove existing item in install directory
|
|
574
|
+
if (existsSync(target)) {
|
|
575
|
+
rmSync(target, { recursive: true, force: true });
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// Copy item
|
|
579
|
+
try {
|
|
580
|
+
cpSync(source, target, { recursive: true });
|
|
581
|
+
} catch {
|
|
582
|
+
copyFileSync(source, target);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Install production dependencies in target directory
|
|
588
|
+
*/
|
|
589
|
+
function installTargetDependencies() {
|
|
590
|
+
console.log('\n📦 Installing production dependencies in target...');
|
|
591
|
+
|
|
592
|
+
try {
|
|
593
|
+
execSync('npm install --production --no-audit --no-fund', {
|
|
594
|
+
cwd: INSTALL_DIR,
|
|
595
|
+
stdio: 'inherit'
|
|
596
|
+
});
|
|
597
|
+
console.log('✅ Dependencies installed');
|
|
598
|
+
} catch (error) {
|
|
599
|
+
console.error('\n❌ FAILED to install production dependencies in target directory.');
|
|
600
|
+
console.error(` ${error.message}`);
|
|
601
|
+
console.error('\n Without these dependencies, the plugin will fail to load at runtime.');
|
|
602
|
+
console.error(` Run manually: cd ${INSTALL_DIR} && npm install --production`);
|
|
603
|
+
process.exit(1);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Clean stale backup directories in extensions/
|
|
609
|
+
* These are left behind from old sync runs and can confuse OpenClaw's
|
|
610
|
+
* extension loader (it scans all directories by name).
|
|
611
|
+
*/
|
|
612
|
+
function cleanStaleBackups() {
|
|
613
|
+
const extensionsDir = join(OPENCLAW_DIR, 'extensions');
|
|
614
|
+
if (!existsSync(extensionsDir)) return;
|
|
615
|
+
|
|
616
|
+
const entries = readdirSync(extensionsDir);
|
|
617
|
+
const backups = entries.filter(e =>
|
|
618
|
+
e.startsWith('principles-disciple.backup') ||
|
|
619
|
+
e.startsWith('principles-disciple.old')
|
|
620
|
+
);
|
|
621
|
+
|
|
622
|
+
if (backups.length === 0) return;
|
|
623
|
+
|
|
624
|
+
console.log('\n🧹 Cleaning stale backup directories...');
|
|
625
|
+
for (const backup of backups) {
|
|
626
|
+
const path = join(extensionsDir, backup);
|
|
627
|
+
rmSync(path, { recursive: true, force: true });
|
|
628
|
+
console.log(` Removed: ${backup}`);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* Restart OpenClaw Gateway via systemctl, with verification.
|
|
634
|
+
*/
|
|
635
|
+
function restartGateway() {
|
|
636
|
+
console.log('\n🔄 Restarting OpenClaw Gateway...');
|
|
637
|
+
try {
|
|
638
|
+
// Try systemd first (most common deployment)
|
|
639
|
+
try {
|
|
640
|
+
execSync('systemctl --user is-active openclaw-gateway.service', { stdio: 'pipe' });
|
|
641
|
+
console.log(' Detected systemd service. Restarting via systemctl...');
|
|
642
|
+
execSync('systemctl --user restart openclaw-gateway.service', { stdio: 'inherit' });
|
|
643
|
+
console.log('✅ Gateway restarted via systemctl.');
|
|
644
|
+
// Verify it started successfully
|
|
645
|
+
setTimeout(() => {
|
|
646
|
+
try {
|
|
647
|
+
const status = execSync('systemctl --user is-active openclaw-gateway.service', { encoding: 'utf-8' }).trim();
|
|
648
|
+
if (status === 'active') {
|
|
649
|
+
console.log('✅ Gateway is running.');
|
|
650
|
+
} else {
|
|
651
|
+
console.error(`❌ Gateway status: ${status}. Check logs: journalctl --user -u openclaw-gateway.service --since "1 min ago"`);
|
|
652
|
+
}
|
|
653
|
+
} catch { /* ignore */ }
|
|
654
|
+
}, 3000);
|
|
655
|
+
return;
|
|
656
|
+
} catch {
|
|
657
|
+
// Not a systemd service — fall through to manual restart
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// Manual restart: find and kill existing gateway processes
|
|
661
|
+
const pids = execSync('pgrep -f "openclaw-gateway|openclaw gateway"', { encoding: 'utf-8' }).trim();
|
|
662
|
+
if (pids) {
|
|
663
|
+
console.log(` Found gateway process(es). Terminating...`);
|
|
664
|
+
execSync(`echo "${pids}" | xargs kill -TERM 2>/dev/null || true`);
|
|
665
|
+
execSync('sleep 3');
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// Start new gateway
|
|
669
|
+
const logPath = '/tmp/openclaw-auto-restart.log';
|
|
670
|
+
console.log(` Starting new gateway (logs: ${logPath})...`);
|
|
671
|
+
execSync(`nohup openclaw gateway --force > ${logPath} 2>&1 &`, { stdio: 'ignore' });
|
|
672
|
+
console.log('✅ Gateway restart triggered.');
|
|
673
|
+
console.log(` Check logs: tail -f ${logPath}`);
|
|
674
|
+
} catch (error) {
|
|
675
|
+
console.error(`\n❌ Failed to restart gateway: ${error.message}`);
|
|
676
|
+
console.error(' Manual restart: systemctl --user restart openclaw-gateway.service');
|
|
677
|
+
process.exit(1);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Main function
|
|
683
|
+
*/
|
|
684
|
+
function main() {
|
|
685
|
+
const args = parseArgs();
|
|
686
|
+
|
|
687
|
+
if (args.help) {
|
|
688
|
+
showHelp();
|
|
689
|
+
process.exit(0);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
console.log('╔════════════════════════════════════════════════════════════╗');
|
|
693
|
+
console.log('║ Principles Disciple Plugin Installer ║');
|
|
694
|
+
console.log('╚════════════════════════════════════════════════════════════╝\n');
|
|
695
|
+
|
|
696
|
+
// Dev mode: auto-force, auto-restart, clean stale backups
|
|
697
|
+
if (args.dev) {
|
|
698
|
+
console.log('🛠️ DEV MODE: force + restart + stale backup cleanup\n');
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// Get source version
|
|
702
|
+
const sourceVersion = getVersion(SOURCE_DIR);
|
|
703
|
+
if (!sourceVersion) {
|
|
704
|
+
console.error('❌ Cannot determine source version. Check package.json.');
|
|
705
|
+
process.exit(1);
|
|
706
|
+
}
|
|
707
|
+
console.log(`📋 Plugin version: v${sourceVersion}`);
|
|
708
|
+
console.log(`🌍 Language: ${args.lang}`);
|
|
709
|
+
|
|
710
|
+
// Step 1: Check prerequisites
|
|
711
|
+
console.log('\n🔍 Checking prerequisites...');
|
|
712
|
+
checkPrerequisites();
|
|
713
|
+
|
|
714
|
+
// Step 2: Install dependencies (if needed)
|
|
715
|
+
if (!args.skipDeps) {
|
|
716
|
+
installDependencies();
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
// Step 3: ALWAYS rebuild — esbuild is fast (~2s) and compiles TS directly.
|
|
720
|
+
// dist/ .js files from tsc may be stale when tsc has errors in other files.
|
|
721
|
+
// We always rebuild to guarantee the synced code matches current source.
|
|
722
|
+
buildPlugin();
|
|
723
|
+
|
|
724
|
+
// Step 4: Clean existing installation (must happen after build so we know what's current)
|
|
725
|
+
cleanTargetDir(args.force);
|
|
726
|
+
|
|
727
|
+
// Step 5: Ensure installation directory exists
|
|
728
|
+
ensureInstallDir();
|
|
729
|
+
|
|
730
|
+
// Step 6: Sync files
|
|
731
|
+
console.log('\n📦 Syncing files to OpenClaw...');
|
|
732
|
+
for (const item of SYNC_ITEMS) {
|
|
733
|
+
syncItem(item);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// Step 7: Sync skills
|
|
737
|
+
syncSkills(args.lang);
|
|
738
|
+
|
|
739
|
+
// Step 8: Install production dependencies in target (ALWAYS — cleanTargetDir wiped node_modules)
|
|
740
|
+
// --skip-deps only applies to SOURCE directory deps, not the installed plugin.
|
|
741
|
+
installTargetDependencies();
|
|
742
|
+
|
|
743
|
+
// Step 9: Verify installed bundle can load its native dependencies
|
|
744
|
+
console.log('\n🔍 Verifying installed plugin can load native dependencies...');
|
|
745
|
+
try {
|
|
746
|
+
execSync(`node -e "require('better-sqlite3')"`, {
|
|
747
|
+
cwd: INSTALL_DIR,
|
|
748
|
+
stdio: 'pipe'
|
|
749
|
+
});
|
|
750
|
+
console.log('✅ Native dependencies verified (better-sqlite3 loads correctly)');
|
|
751
|
+
} catch {
|
|
752
|
+
console.error('\n❌ Installed plugin cannot load native dependencies!');
|
|
753
|
+
console.error(' This usually means npm install failed to compile better-sqlite3.');
|
|
754
|
+
console.error(` Fix: cd ${INSTALL_DIR} && npm rebuild better-sqlite3`);
|
|
755
|
+
process.exit(1);
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
// Step 10: Verify installation
|
|
759
|
+
const installedVersion = getVersion(INSTALL_DIR);
|
|
760
|
+
if (installedVersion !== sourceVersion) {
|
|
761
|
+
console.error('\n❌ VERSION MISMATCH after sync!');
|
|
762
|
+
console.error(` Expected: v${sourceVersion}`);
|
|
763
|
+
console.error(` Got: v${installedVersion}`);
|
|
764
|
+
process.exit(1);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
// Step 10: Verify installed fingerprint matches current source
|
|
768
|
+
verifyInstalledFingerprint();
|
|
769
|
+
|
|
770
|
+
// Step 11: Clean stale backup directories (dev mode or explicit restart)
|
|
771
|
+
if (args.dev || args.restart) {
|
|
772
|
+
cleanStaleBackups();
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
// Build fingerprint info for report
|
|
776
|
+
let fpReport = '';
|
|
777
|
+
try {
|
|
778
|
+
const sourceManifest = JSON.parse(readFileSync(join(SOURCE_DIR, 'dist', 'openclaw.plugin.json'), 'utf-8'));
|
|
779
|
+
const fp = sourceManifest.buildFingerprint;
|
|
780
|
+
if (fp) {
|
|
781
|
+
fpReport = `\n Build: ${fp.gitSha} / MD5 ${fp.bundleMd5.slice(0, 8)}…`;
|
|
782
|
+
}
|
|
783
|
+
} catch { /* ignore */ }
|
|
784
|
+
|
|
785
|
+
// Success!
|
|
786
|
+
console.log('\n╔════════════════════════════════════════════════════════════╗');
|
|
787
|
+
console.log('║ ✅ Installation Complete ║');
|
|
788
|
+
console.log('╚════════════════════════════════════════════════════════════╝');
|
|
789
|
+
console.log(`\n Version: v${sourceVersion}${fpReport}`);
|
|
790
|
+
console.log(` Language: ${args.lang}`);
|
|
791
|
+
console.log(` Source: ${SOURCE_DIR}`);
|
|
792
|
+
console.log(` Target: ${INSTALL_DIR}`);
|
|
793
|
+
|
|
794
|
+
// Handle automatic restart if requested
|
|
795
|
+
if (args.restart) {
|
|
796
|
+
restartGateway();
|
|
797
|
+
} else {
|
|
798
|
+
console.log('\n💡 Restart OpenClaw Gateway to load the new version.');
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
main();
|