principles-disciple 1.71.0 → 1.73.0
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/openclaw.plugin.json +10 -5
- package/package.json +17 -19
- package/scripts/acceptance-test.mjs +16 -73
- package/scripts/sync-plugin.mjs +382 -77
- package/src/commands/archive-impl.ts +2 -1
- package/src/commands/capabilities.ts +2 -2
- package/src/commands/context.ts +2 -2
- package/src/commands/disable-impl.ts +2 -1
- package/src/commands/evolution-status.ts +16 -16
- package/src/commands/export.ts +12 -67
- package/src/commands/pain.ts +91 -1
- package/src/commands/principle-rollback.ts +2 -1
- package/src/commands/promote-impl.ts +7 -43
- package/src/commands/rollback-impl.ts +2 -1
- package/src/commands/rollback.ts +2 -1
- package/src/commands/samples.ts +2 -1
- package/src/commands/thinking-os.ts +2 -1
- package/src/config/errors.ts +18 -2
- package/src/constants/diagnostician.ts +2 -2
- package/src/constants/tools.ts +2 -1
- package/src/core/__tests__/focus-history.test.ts +210 -0
- package/src/core/config.ts +1 -1
- package/src/core/confirm-first-gate.ts +255 -0
- package/src/core/correction-cue-learner.ts +2 -136
- package/src/core/correction-types.ts +16 -88
- package/src/core/dictionary.ts +19 -20
- package/src/core/empathy-keyword-matcher.ts +17 -289
- package/src/core/empathy-types.ts +18 -229
- package/src/core/event-log.ts +38 -132
- package/src/core/evolution-reducer.ts +21 -2
- package/src/core/evolution-types.ts +76 -464
- package/src/core/file-store.ts +80 -0
- package/src/core/focus-history.ts +228 -955
- package/src/core/local-worker-routing.ts +34 -314
- package/src/core/merge-gate-audit.ts +0 -195
- package/src/core/pain-diagnostic-gate.ts +154 -0
- package/src/core/pain-signal.ts +21 -138
- package/src/core/pain.ts +15 -88
- package/src/core/pd-task-reconciler.ts +26 -115
- package/src/core/pd-task-service.ts +9 -9
- package/src/core/pd-task-types.ts +23 -127
- package/src/core/principle-compiler/__tests__/compiler-replay-gate.test.ts +174 -0
- package/src/core/principle-compiler/code-validator.ts +15 -42
- package/src/core/principle-compiler/compiler.ts +100 -15
- package/src/core/principle-compiler/index.ts +5 -2
- package/src/core/principle-compiler/template-generator.ts +4 -104
- package/src/core/principle-injection.ts +10 -202
- package/src/core/principle-internalization/filesystem-lifecycle-datasource.ts +42 -0
- package/src/core/principle-internalization/lifecycle-read-model.ts +39 -242
- package/src/core/principle-internalization/principle-lifecycle-service.ts +12 -10
- package/src/core/principle-tree-ledger-adapter.ts +145 -0
- package/src/core/principle-tree-ledger.ts +8 -6
- package/src/core/reflection/reflection-context.ts +14 -109
- package/src/core/replay-engine.ts +8 -500
- package/src/core/rule-host-helpers.ts +5 -35
- package/src/core/rule-host-types.ts +10 -82
- package/src/core/rule-host.ts +6 -63
- package/src/core/runtime-v2-prompt-activation-reader.ts +231 -0
- package/src/core/session-tracker.ts +87 -101
- package/src/core/shadow-observation-registry.ts +19 -48
- package/src/core/trajectory.ts +3 -1
- package/src/core/workflow-funnel-loader.ts +62 -68
- package/src/core/workspace-context.ts +46 -0
- package/src/core/workspace-dir-service.ts +1 -1
- package/src/core/workspace-dir-validation.ts +18 -9
- package/src/hooks/AGENTS.md +1 -1
- package/src/hooks/gate-block-helper.ts +46 -44
- package/src/hooks/gate.ts +207 -7
- package/src/hooks/lifecycle.ts +30 -32
- package/src/hooks/llm.ts +60 -32
- package/src/hooks/pain.ts +297 -103
- package/src/hooks/prompt.ts +469 -339
- package/src/hooks/subagent.ts +2 -29
- package/src/i18n/commands.ts +2 -10
- package/src/index.ts +95 -85
- package/src/openclaw-sdk.ts +311 -0
- package/src/service/central-database.ts +8 -4
- package/src/service/evolution-queue-migration.ts +2 -1
- package/src/service/evolution-worker.ts +163 -1786
- package/src/service/internalization-trigger-adapter.ts +302 -0
- package/src/service/keyword-optimization-service.ts +4 -4
- package/src/service/monitoring-query-service.ts +1 -215
- package/src/service/queue-io.ts +60 -331
- package/src/service/runtime-summary-service.ts +115 -18
- package/src/service/subagent-workflow/index.ts +0 -41
- package/src/service/subagent-workflow/types.ts +9 -120
- package/src/service/subagent-workflow/workflow-store.ts +2 -119
- package/src/service/workflow-watchdog.ts +0 -43
- package/src/types/event-payload.ts +16 -74
- package/src/types/event-types.ts +39 -547
- package/src/types/hygiene-types.ts +7 -30
- package/src/types/principle-tree-schema.ts +20 -222
- package/src/types/queue.ts +15 -70
- package/src/types/runtime-summary.ts +5 -49
- package/src/utils/io.ts +10 -0
- package/src/utils/retry.ts +1 -1
- package/src/utils/shadow-fingerprint.ts +2 -2
- package/src/utils/workspace-resolver.ts +50 -0
- package/templates/langs/en/core/AGENTS.md +2 -2
- package/templates/langs/en/core/BOOT.md +1 -1
- package/templates/langs/en/core/HEARTBEAT.md +2 -2
- package/templates/langs/en/skills/ai-sprint-orchestration/references/agent-registry.json +1 -72
- package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +6 -6
- package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +6 -6
- package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +2 -12
- package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +2 -12
- package/templates/langs/en/skills/ai-sprint-orchestration/runtime/.gitignore +2 -2
- package/templates/langs/en/skills/ai-sprint-orchestration/scripts/run.mjs +51 -15
- package/templates/langs/en/skills/evolve-task/SKILL.md +1 -1
- package/templates/langs/en/skills/pd-cli-operator/SKILL.md +67 -0
- package/templates/langs/en/skills/pd-diagnostician/SKILL.md +1 -1
- package/templates/langs/en/skills/pd-mentor/SKILL.md +1 -1
- package/templates/langs/en/skills/pd-pain-signal/SKILL.md +17 -39
- package/templates/langs/en/skills/pd-runtime-v2/SKILL.md +61 -0
- package/templates/langs/zh/core/AGENTS.md +2 -2
- package/templates/langs/zh/core/BOOT.md +1 -1
- package/templates/langs/zh/core/HEARTBEAT.md +2 -2
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/agent-registry.json +1 -72
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +6 -6
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +6 -6
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/nocturnal-trinity-quality-enhancement.json +8 -8
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +2 -12
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +2 -12
- package/templates/langs/zh/skills/ai-sprint-orchestration/runtime/.gitignore +2 -2
- package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/run.mjs +51 -15
- package/templates/langs/zh/skills/ai-sprint-orchestration/test/run.test.mjs +21 -5
- package/templates/langs/zh/skills/evolve-task/SKILL.md +2 -2
- package/templates/langs/zh/skills/pd-cli-operator/SKILL.md +67 -0
- package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +1 -1
- package/templates/langs/zh/skills/pd-mentor/SKILL.md +1 -1
- package/templates/langs/zh/skills/pd-pain-signal/SKILL.md +17 -38
- package/templates/langs/zh/skills/pd-runtime-v2/SKILL.md +61 -0
- package/tests/build-artifacts.test.ts +1 -3
- package/tests/commands/evolution-status.test.ts +0 -118
- package/tests/core/bootstrap-rules.test.ts +1 -1
- package/tests/core/config.test.ts +1 -1
- package/tests/core/event-log.test.ts +35 -0
- package/tests/core/evolution-engine.test.ts +610 -0
- package/tests/core/file-store.test.ts +102 -0
- package/tests/core/focus-history.test.ts +203 -11
- package/tests/core/merge-gate-audit.test.ts +2 -169
- package/tests/core/model-deployment-registry.test.ts +7 -1
- package/tests/core/model-training-registry.test.ts +19 -0
- package/tests/core/observability.test.ts +0 -1
- package/tests/core/pain-diagnostic-gate.test.ts +498 -0
- package/tests/core/pain.test.ts +0 -1
- package/tests/core/principle-internalization/deprecated-readiness.test.ts +2 -2
- package/tests/core/principle-internalization/lifecycle-metrics.test.ts +2 -2
- package/tests/core/principle-internalization/{internalization-routing-policy.test.ts → lifecycle-routing-policy.test.ts} +6 -6
- package/tests/core/principle-internalization/lineage-source-retired.test.ts +56 -0
- package/tests/core/principle-internalization/principle-lifecycle-service.test.ts +1 -23
- package/tests/core/principle-tree-ledger-adapter.test.ts +253 -0
- package/tests/core/reflection-context.test.ts +0 -14
- package/tests/core/replay-engine.test.ts +127 -215
- package/tests/core/rule-host-helpers.test.ts +2 -2
- package/tests/core/rule-implementation-runtime.test.ts +0 -27
- package/tests/core/workflow-funnel-loader.test.ts +162 -0
- package/tests/core/workspace-dir-validation.test.ts +8 -1
- package/tests/core-anti-growth.test.ts +192 -0
- package/tests/hook-workspace-nextaction-contract.test.ts +42 -0
- package/tests/hooks/confirm-first-gate.test.ts +333 -0
- package/tests/hooks/gate-auto-correct-shadow.test.ts +310 -0
- package/tests/hooks/gate-auto-correct.test.ts +665 -0
- package/tests/hooks/gate-rule-host-pipeline.test.ts +2 -1
- package/tests/hooks/pain.test.ts +269 -12
- package/tests/hooks/prompt-characterization.test.ts +500 -0
- package/tests/hooks/prompt-size-guard.test.ts +329 -0
- package/tests/hooks/runtime-v2-prompt-activation.test.ts +869 -0
- package/tests/index.test.ts +94 -1
- package/tests/integration/auto-entry-gate.test.ts +248 -0
- package/tests/integration/internalization-trigger-guard.test.ts +69 -0
- package/tests/integration/m8-legacy-paths.test.ts +63 -0
- package/tests/integration/runtime-v2-pain-guard.test.ts +125 -0
- package/tests/plugin-config-resolution-cutover.test.ts +359 -0
- package/tests/runtime-v2-discovery-guard.test.ts +154 -0
- package/tests/service/central-database.test.ts +457 -0
- package/tests/service/evolution-worker.correction-observer.test.ts +173 -0
- package/tests/service/evolution-worker.timeout.test.ts +11 -129
- package/tests/service/internalization-trigger-adapter.test.ts +251 -0
- package/tests/service/monitoring-query-service.test.ts +1 -47
- package/tests/service/queue-io.test.ts +1 -62
- package/tests/service/runtime-summary-service.test.ts +184 -3
- package/tests/service/workflow-watchdog.test.ts +0 -91
- package/tests/utils/file-lock.test.ts +5 -3
- package/tests/utils/session-key.test.ts +52 -0
- package/tests/utils/subagent-probe.test.ts +48 -1
- package/vitest.config.ts +4 -11
- package/.planning/codebase/ARCHITECTURE.md +0 -157
- package/.planning/codebase/CONCERNS.md +0 -145
- package/.planning/codebase/CONVENTIONS.md +0 -148
- package/.planning/codebase/INTEGRATIONS.md +0 -81
- package/.planning/codebase/STACK.md +0 -87
- package/.planning/codebase/STRUCTURE.md +0 -193
- package/.planning/codebase/TESTING.md +0 -243
- package/.planning/phases/01-basic-visualization/01-GAP-CLOSURE-VERIFICATION.md +0 -113
- package/docs/COMMAND_REFERENCE.md +0 -76
- package/docs/COMMAND_REFERENCE_EN.md +0 -79
- package/scripts/build-web.mjs +0 -46
- package/scripts/diagnose-nocturnal.mjs +0 -537
- package/scripts/seed-nocturnal-scenarios.mjs +0 -384
- package/src/commands/nocturnal-review.ts +0 -322
- package/src/commands/nocturnal-rollout.ts +0 -790
- package/src/commands/nocturnal-train.ts +0 -986
- package/src/commands/pd-reflect.ts +0 -88
- package/src/core/adaptive-thresholds.ts +0 -478
- package/src/core/diagnostician-task-store.ts +0 -192
- package/src/core/nocturnal-arbiter.ts +0 -715
- package/src/core/nocturnal-artifact-lineage.ts +0 -116
- package/src/core/nocturnal-artificer.ts +0 -257
- package/src/core/nocturnal-candidate-scoring.ts +0 -530
- package/src/core/nocturnal-compliance.ts +0 -1146
- package/src/core/nocturnal-dataset.ts +0 -763
- package/src/core/nocturnal-executability.ts +0 -428
- package/src/core/nocturnal-export.ts +0 -499
- package/src/core/nocturnal-paths.ts +0 -240
- package/src/core/nocturnal-reasoning-deriver.ts +0 -343
- package/src/core/nocturnal-rule-implementation-validator.ts +0 -246
- package/src/core/nocturnal-snapshot-contract.ts +0 -99
- package/src/core/nocturnal-trajectory-extractor.ts +0 -512
- package/src/core/nocturnal-trinity-types.ts +0 -218
- package/src/core/nocturnal-trinity.ts +0 -2680
- package/src/core/principle-internalization/deprecated-readiness.ts +0 -93
- package/src/core/principle-internalization/internalization-routing-policy.ts +0 -208
- package/src/core/principle-internalization/lifecycle-metrics.ts +0 -152
- package/src/http/principles-console-route.ts +0 -709
- package/src/service/central-health-service.ts +0 -49
- package/src/service/central-overview-service.ts +0 -138
- package/src/service/control-ui-query-service.ts +0 -900
- package/src/service/cooldown-strategy.ts +0 -97
- package/src/service/evolution-pain-context.ts +0 -79
- package/src/service/evolution-query-service.ts +0 -407
- package/src/service/health-query-service.ts +0 -1038
- package/src/service/nocturnal-config.ts +0 -214
- package/src/service/nocturnal-runtime.ts +0 -734
- package/src/service/nocturnal-service.ts +0 -1605
- package/src/service/nocturnal-target-selector.ts +0 -545
- package/src/service/sleep-cycle.ts +0 -157
- package/src/service/startup-reconciler.ts +0 -112
- package/src/service/subagent-workflow/correction-observer-types.ts +0 -82
- package/src/service/subagent-workflow/correction-observer-workflow-manager.ts +0 -250
- package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +0 -1
- package/src/service/subagent-workflow/dynamic-timeout.ts +0 -30
- package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +0 -268
- package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +0 -795
- package/src/service/subagent-workflow/runtime-direct-driver.ts +0 -268
- package/src/service/subagent-workflow/workflow-manager-base.ts +0 -580
- package/src/tools/write-pain-flag.ts +0 -215
- package/tests/commands/nocturnal-review.test.ts +0 -448
- package/tests/commands/nocturnal-train.test.ts +0 -97
- package/tests/commands/pd-reflect.test.ts +0 -49
- package/tests/core/adaptive-thresholds.test.ts +0 -261
- package/tests/core/nocturnal-arbiter.test.ts +0 -559
- package/tests/core/nocturnal-artifact-lineage.test.ts +0 -53
- package/tests/core/nocturnal-artificer.test.ts +0 -241
- package/tests/core/nocturnal-candidate-scoring.test.ts +0 -532
- package/tests/core/nocturnal-compliance-p-principles.test.ts +0 -133
- package/tests/core/nocturnal-compliance.test.ts +0 -646
- package/tests/core/nocturnal-dataset.test.ts +0 -892
- package/tests/core/nocturnal-e2e.test.ts +0 -234
- package/tests/core/nocturnal-executability.test.ts +0 -357
- package/tests/core/nocturnal-export.test.ts +0 -517
- package/tests/core/nocturnal-reasoning-deriver.test.ts +0 -372
- package/tests/core/nocturnal-reviewed-subset-comparison.test.ts +0 -428
- package/tests/core/nocturnal-rule-implementation-validator.test.ts +0 -127
- package/tests/core/nocturnal-snapshot-contract.test.ts +0 -121
- package/tests/core/nocturnal-trajectory-extractor.test.ts +0 -634
- package/tests/core/nocturnal-trinity.test.ts +0 -2053
- package/tests/core/pain-auto-repair.test.ts +0 -96
- package/tests/core/pain-integration.test.ts +0 -510
- package/tests/fixtures/nocturnal-reviewed-subset.json +0 -183
- package/tests/http/principles-console-route.test.ts +0 -162
- package/tests/integration/chaos-resilience.test.ts +0 -348
- package/tests/integration/empathy-workflow-integration.test.ts +0 -626
- package/tests/integration/pain-diagnostician-loop.e2e.test.ts +0 -380
- package/tests/service/control-ui-query-service.test.ts +0 -121
- package/tests/service/cooldown-strategy.test.ts +0 -164
- package/tests/service/data-endpoints-regression.test.ts +0 -834
- package/tests/service/empathy-observer-workflow-manager.test.ts +0 -175
- package/tests/service/evolution-worker.nocturnal.test.ts +0 -601
- package/tests/service/nocturnal-runtime-hardening.test.ts +0 -118
- package/tests/service/nocturnal-runtime.test.ts +0 -473
- package/tests/service/nocturnal-service-code-candidate.test.ts +0 -330
- package/tests/service/nocturnal-target-selector.test.ts +0 -615
- package/tests/service/startup-reconciler.test.ts +0 -148
- package/tests/tools/write-pain-flag.test.ts +0 -358
- package/ui/src/App.tsx +0 -45
- package/ui/src/api.ts +0 -220
- package/ui/src/charts.tsx +0 -955
- package/ui/src/components/ErrorState.tsx +0 -6
- package/ui/src/components/Loading.tsx +0 -13
- package/ui/src/components/ProtectedRoute.tsx +0 -12
- package/ui/src/components/Shell.tsx +0 -91
- package/ui/src/components/WorkspaceConfig.tsx +0 -178
- package/ui/src/components/index.ts +0 -5
- package/ui/src/context/auth.tsx +0 -80
- package/ui/src/context/theme.tsx +0 -66
- package/ui/src/hooks/useAutoRefresh.ts +0 -39
- package/ui/src/i18n/ui.ts +0 -473
- package/ui/src/main.tsx +0 -16
- package/ui/src/pages/EvolutionPage.tsx +0 -333
- package/ui/src/pages/FeedbackPage.tsx +0 -138
- package/ui/src/pages/GateMonitorPage.tsx +0 -136
- package/ui/src/pages/LoginPage.tsx +0 -89
- package/ui/src/pages/OverviewPage.tsx +0 -599
- package/ui/src/pages/SamplesPage.tsx +0 -174
- package/ui/src/pages/ThinkingModelsPage.tsx +0 -702
- package/ui/src/styles.css +0 -2020
- package/ui/src/types.ts +0 -384
- package/ui/src/utils/format.ts +0 -15
package/scripts/sync-plugin.mjs
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* --help Show help message
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { copyFileSync, cpSync, existsSync, lstatSync, rmSync, readFileSync, readFileSync as readFileSyncRaw, mkdirSync, writeFileSync, readdirSync } from 'fs';
|
|
20
|
+
import { chmodSync, copyFileSync, cpSync, existsSync, lstatSync, rmSync, readFileSync, readFileSync as readFileSyncRaw, mkdirSync, writeFileSync, readdirSync } from 'fs';
|
|
21
21
|
import { createHash } from 'crypto';
|
|
22
22
|
import { join, dirname } from 'path';
|
|
23
23
|
import { fileURLToPath } from 'url';
|
|
@@ -27,6 +27,8 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
27
27
|
const __dirname = dirname(__filename);
|
|
28
28
|
|
|
29
29
|
const SOURCE_DIR = join(__dirname, '..');
|
|
30
|
+
const ROOT_DIR = join(SOURCE_DIR, '..', '..');
|
|
31
|
+
const PD_CLI_SOURCE_DIR = join(ROOT_DIR, 'packages', 'pd-cli');
|
|
30
32
|
|
|
31
33
|
/**
|
|
32
34
|
* Cross-platform home directory resolution.
|
|
@@ -42,6 +44,8 @@ function getHomeDir() {
|
|
|
42
44
|
|
|
43
45
|
const OPENCLAW_DIR = join(getHomeDir(), '.openclaw');
|
|
44
46
|
const INSTALL_DIR = join(OPENCLAW_DIR, 'extensions', 'principles-disciple');
|
|
47
|
+
const INSTALLED_PD_CLI_DIR = join(INSTALL_DIR, 'pd-cli');
|
|
48
|
+
const INSTALLED_BIN_DIR = join(INSTALL_DIR, 'bin');
|
|
45
49
|
function getConfiguredWorkspaceDir() {
|
|
46
50
|
const configPath = join(OPENCLAW_DIR, 'openclaw.json');
|
|
47
51
|
try {
|
|
@@ -58,13 +62,15 @@ function getConfiguredWorkspaceDir() {
|
|
|
58
62
|
return join(OPENCLAW_DIR, 'workspace-main');
|
|
59
63
|
}
|
|
60
64
|
|
|
61
|
-
// Files and directories to sync
|
|
65
|
+
// Files and directories to sync.
|
|
66
|
+
// NOTE: openclaw.plugin.json is NOT included here — it is synced separately
|
|
67
|
+
// via syncFilteredManifest() which filters the skills array by language
|
|
68
|
+
// BEFORE writing to the install target, preventing the en/zh collision.
|
|
62
69
|
const SYNC_ITEMS = [
|
|
63
70
|
'dist',
|
|
64
71
|
'templates',
|
|
65
72
|
'scripts',
|
|
66
73
|
'docs',
|
|
67
|
-
'openclaw.plugin.json',
|
|
68
74
|
'package.json',
|
|
69
75
|
];
|
|
70
76
|
|
|
@@ -371,10 +377,6 @@ function buildPlugin() {
|
|
|
371
377
|
cwd: SOURCE_DIR,
|
|
372
378
|
stdio: 'inherit'
|
|
373
379
|
});
|
|
374
|
-
execSync('node scripts/build-web.mjs --production', {
|
|
375
|
-
cwd: SOURCE_DIR,
|
|
376
|
-
stdio: 'inherit'
|
|
377
|
-
});
|
|
378
380
|
} catch (error) {
|
|
379
381
|
console.error('\n❌ Build failed');
|
|
380
382
|
console.error(` ${error.message}`);
|
|
@@ -384,6 +386,36 @@ function buildPlugin() {
|
|
|
384
386
|
verifyBundleContents();
|
|
385
387
|
}
|
|
386
388
|
|
|
389
|
+
/**
|
|
390
|
+
* Build the Runtime V2 CLI that agents invoke through the `pd` command.
|
|
391
|
+
* This is intentionally part of plugin sync so installed OpenClaw agents do not
|
|
392
|
+
* depend on a repo checkout, stale global npm package, or guessed CLI path.
|
|
393
|
+
*/
|
|
394
|
+
function buildPdCli() {
|
|
395
|
+
console.log('\n🔨 Building PD CLI...');
|
|
396
|
+
|
|
397
|
+
if (!existsSync(join(PD_CLI_SOURCE_DIR, 'package.json'))) {
|
|
398
|
+
console.error(`❌ PD CLI package not found: ${PD_CLI_SOURCE_DIR}`);
|
|
399
|
+
process.exit(1);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
try {
|
|
403
|
+
execSync('npm run build --workspace=@principles/core', {
|
|
404
|
+
cwd: ROOT_DIR,
|
|
405
|
+
stdio: 'inherit'
|
|
406
|
+
});
|
|
407
|
+
execSync('npm run build --workspace=@principles/pd-cli', {
|
|
408
|
+
cwd: ROOT_DIR,
|
|
409
|
+
stdio: 'inherit'
|
|
410
|
+
});
|
|
411
|
+
console.log('✅ PD CLI built');
|
|
412
|
+
} catch (error) {
|
|
413
|
+
console.error('\n❌ PD CLI build failed');
|
|
414
|
+
console.error(` ${error.message}`);
|
|
415
|
+
process.exit(1);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
387
419
|
/**
|
|
388
420
|
* Verify the built bundle contains all critical symbols.
|
|
389
421
|
*/
|
|
@@ -400,7 +432,6 @@ function verifyBundleContents() {
|
|
|
400
432
|
{ name: 'checkPainFlag', reason: 'pain flag detection' },
|
|
401
433
|
{ name: 'processEvolutionQueue', reason: 'queue processing' },
|
|
402
434
|
{ name: 'acquireQueueLock', reason: 'queue lock for pd-reflect and worker' },
|
|
403
|
-
{ name: 'write_pain_flag', reason: 'pain signal recording tool' },
|
|
404
435
|
];
|
|
405
436
|
|
|
406
437
|
const missing = [];
|
|
@@ -472,11 +503,6 @@ function writeBuildFingerprint() {
|
|
|
472
503
|
console.warn(`⚠️ Could not write fingerprint: ${err.message}`);
|
|
473
504
|
}
|
|
474
505
|
|
|
475
|
-
try {
|
|
476
|
-
const rootManifest = JSON.parse(readFileSync(manifestSrc, 'utf-8'));
|
|
477
|
-
rootManifest.buildFingerprint = manifest.buildFingerprint;
|
|
478
|
-
writeFileAtomic(manifestSrc, JSON.stringify(rootManifest, null, 2) + '\n');
|
|
479
|
-
} catch { /* ignore */ }
|
|
480
506
|
}
|
|
481
507
|
|
|
482
508
|
/**
|
|
@@ -525,22 +551,33 @@ function verifyInstalledFingerprint() {
|
|
|
525
551
|
}
|
|
526
552
|
|
|
527
553
|
/**
|
|
528
|
-
* Update the plugin version in
|
|
529
|
-
*
|
|
554
|
+
* Update the plugin version in installs.json after successful sync.
|
|
555
|
+
* OpenClaw manages install records in ~/.openclaw/plugins/installs.json,
|
|
556
|
+
* NOT in openclaw.json (plugins.installs is a legacy/transient field).
|
|
530
557
|
*/
|
|
531
558
|
function updateInstalledPluginVersion(version) {
|
|
532
|
-
const
|
|
559
|
+
const installsDir = join(OPENCLAW_DIR, 'plugins');
|
|
560
|
+
const installsPath = join(installsDir, 'installs.json');
|
|
533
561
|
try {
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
if (config?.plugins?.installs?.['principles-disciple']) {
|
|
537
|
-
config.plugins.installs['principles-disciple'].version = version;
|
|
538
|
-
config.plugins.installs['principles-disciple'].installedAt = new Date().toISOString();
|
|
539
|
-
writeFileAtomic(configPath, JSON.stringify(config, null, 2) + '\n');
|
|
540
|
-
console.log(`✅ openclaw.json updated: version=${version}`);
|
|
562
|
+
if (!existsSync(installsDir)) {
|
|
563
|
+
mkdirSync(installsDir, { recursive: true });
|
|
541
564
|
}
|
|
565
|
+
let installs = { version: 1, installRecords: {} };
|
|
566
|
+
if (existsSync(installsPath)) {
|
|
567
|
+
const raw = readFileSync(installsPath, 'utf-8');
|
|
568
|
+
installs = JSON.parse(raw);
|
|
569
|
+
}
|
|
570
|
+
if (!installs.installRecords) installs.installRecords = {};
|
|
571
|
+
installs.installRecords['principles-disciple'] = {
|
|
572
|
+
source: 'path',
|
|
573
|
+
installPath: INSTALL_DIR,
|
|
574
|
+
version: version,
|
|
575
|
+
installedAt: new Date().toISOString(),
|
|
576
|
+
};
|
|
577
|
+
writeFileAtomic(installsPath, JSON.stringify(installs, null, 2) + '\n');
|
|
578
|
+
console.log(`✅ installs.json updated: version=${version}`);
|
|
542
579
|
} catch (err) {
|
|
543
|
-
console.warn(`⚠️ Could not update
|
|
580
|
+
console.warn(`⚠️ Could not update installs.json: ${err.message}`);
|
|
544
581
|
}
|
|
545
582
|
}
|
|
546
583
|
|
|
@@ -604,36 +641,93 @@ function ensureInstallDir() {
|
|
|
604
641
|
}
|
|
605
642
|
|
|
606
643
|
/**
|
|
607
|
-
* Sync
|
|
608
|
-
*
|
|
609
|
-
*
|
|
644
|
+
* Sync the openclaw.plugin.json manifest but filter the skills array to only
|
|
645
|
+
* include paths matching the selected language (zh or en).
|
|
646
|
+
*
|
|
647
|
+
* This MUST run BEFORE syncSkillDirs, and it should
|
|
648
|
+
* never be done via syncItem('openclaw.plugin.json') + subsequent modification
|
|
649
|
+
* because the post-modification step can fail silently (catch block) leaving
|
|
650
|
+
* both en/zh skills in the manifest, which triggers OpenClaw's "plugin skill
|
|
651
|
+
* name collision" warning on startup.
|
|
610
652
|
*/
|
|
611
|
-
function
|
|
612
|
-
const
|
|
613
|
-
|
|
653
|
+
function syncFilteredManifest(lang) {
|
|
654
|
+
const sourcePath = join(SOURCE_DIR, 'openclaw.plugin.json');
|
|
655
|
+
const targetPath = join(INSTALL_DIR, 'openclaw.plugin.json');
|
|
656
|
+
|
|
657
|
+
if (!existsSync(sourcePath)) return;
|
|
658
|
+
|
|
659
|
+
console.log(` 📄 openclaw.plugin.json (filtered for lang: ${lang})`);
|
|
614
660
|
|
|
615
|
-
let
|
|
661
|
+
let manifest;
|
|
616
662
|
try {
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
663
|
+
manifest = JSON.parse(readFileSync(sourcePath, 'utf-8'));
|
|
664
|
+
} catch (err) {
|
|
665
|
+
console.error(`❌ Failed to read source manifest: ${err.message}`);
|
|
666
|
+
process.exit(1);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
if (!manifest.skills || !Array.isArray(manifest.skills)) return;
|
|
670
|
+
|
|
671
|
+
const selectedLang = (lang || 'zh').toLowerCase();
|
|
672
|
+
if (!['zh', 'en'].includes(selectedLang)) {
|
|
673
|
+
console.error(`❌ Invalid language: ${selectedLang}. Expected zh or en.`);
|
|
674
|
+
process.exit(1);
|
|
621
675
|
}
|
|
622
676
|
|
|
623
|
-
|
|
677
|
+
const filtered = manifest.skills.filter(sp => {
|
|
678
|
+
if (typeof sp !== 'string') return false;
|
|
679
|
+
return sp.includes(`/langs/${selectedLang}/`);
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
if (filtered.length === 0) {
|
|
683
|
+
console.error(`❌ No skills match language "${selectedLang}" in source manifest`);
|
|
684
|
+
process.exit(1);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
manifest.skills = filtered;
|
|
688
|
+
|
|
689
|
+
// Use syncItem semantics: remove target, then write freshly
|
|
690
|
+
if (existsSync(targetPath)) {
|
|
691
|
+
rmSync(targetPath, { force: true });
|
|
692
|
+
}
|
|
693
|
+
writeFileSync(targetPath, JSON.stringify(manifest, null, 2) + '\n', 'utf-8');
|
|
694
|
+
console.log(` ✅ skills filtered to lang: ${selectedLang} (${filtered.length} path(s))`);
|
|
695
|
+
}
|
|
624
696
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
697
|
+
/**
|
|
698
|
+
* @deprecated Replaced by syncFilteredManifest(). Kept for backwards
|
|
699
|
+
* compatibility with old installs that may call it externally.
|
|
700
|
+
* syncFilteredManifest filters the skills array BEFORE writing the manifest
|
|
701
|
+
* to disk, avoiding the en/zh collision window entirely.
|
|
702
|
+
*/
|
|
703
|
+
function filterInstalledManifestSkills(lang) {
|
|
704
|
+
const installedManifestPath = join(INSTALL_DIR, 'openclaw.plugin.json');
|
|
705
|
+
if (!existsSync(installedManifestPath)) return;
|
|
706
|
+
|
|
707
|
+
try {
|
|
708
|
+
const manifest = JSON.parse(readFileSync(installedManifestPath, 'utf-8'));
|
|
709
|
+
if (!manifest.skills || !Array.isArray(manifest.skills)) return;
|
|
710
|
+
|
|
711
|
+
const selectedLang = (lang || 'zh').toLowerCase();
|
|
712
|
+
if (!['zh', 'en'].includes(selectedLang)) {
|
|
713
|
+
console.error(`❌ Invalid language: ${selectedLang}. Expected zh or en.`);
|
|
714
|
+
process.exit(1);
|
|
633
715
|
}
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
716
|
+
const filtered = manifest.skills.filter(sp => {
|
|
717
|
+
if (typeof sp !== 'string') return false;
|
|
718
|
+
return sp.includes(`/langs/${selectedLang}/`);
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
if (filtered.length === 0) {
|
|
722
|
+
console.error(`❌ No skills match language "${selectedLang}" in installed manifest`);
|
|
723
|
+
process.exit(1);
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
manifest.skills = filtered;
|
|
727
|
+
writeFileSync(installedManifestPath, JSON.stringify(manifest, null, 2) + '\n', 'utf-8');
|
|
728
|
+
console.log(` 📄 openclaw.plugin.json skills filtered to lang: ${selectedLang}`);
|
|
729
|
+
} catch (err) {
|
|
730
|
+
console.warn(` ⚠️ Failed to filter installed manifest skills: ${err.message}`);
|
|
637
731
|
}
|
|
638
732
|
}
|
|
639
733
|
|
|
@@ -653,6 +747,113 @@ function syncItem(item) {
|
|
|
653
747
|
}
|
|
654
748
|
}
|
|
655
749
|
|
|
750
|
+
function quoteCmdPath(filePath) {
|
|
751
|
+
return filePath.replace(/"/g, '""');
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* Copy the built pd-cli package into the plugin install directory and create
|
|
756
|
+
* deterministic shims. The global shim points at the installed plugin copy, not
|
|
757
|
+
* at a developer checkout.
|
|
758
|
+
*/
|
|
759
|
+
function syncPdCli() {
|
|
760
|
+
console.log('\n📦 Syncing PD CLI...');
|
|
761
|
+
|
|
762
|
+
const distDir = join(PD_CLI_SOURCE_DIR, 'dist');
|
|
763
|
+
if (!existsSync(join(distDir, 'index.js'))) {
|
|
764
|
+
console.error('❌ PD CLI dist/index.js missing. Run without --skip-build or build @principles/pd-cli first.');
|
|
765
|
+
process.exit(1);
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
rmSync(INSTALLED_PD_CLI_DIR, { recursive: true, force: true });
|
|
769
|
+
mkdirSync(INSTALLED_PD_CLI_DIR, { recursive: true });
|
|
770
|
+
cpSync(distDir, join(INSTALLED_PD_CLI_DIR, 'dist'), { recursive: true });
|
|
771
|
+
copyFileSync(join(PD_CLI_SOURCE_DIR, 'package.json'), join(INSTALLED_PD_CLI_DIR, 'package.json'));
|
|
772
|
+
|
|
773
|
+
mkdirSync(INSTALLED_BIN_DIR, { recursive: true });
|
|
774
|
+
const installedEntry = join(INSTALLED_PD_CLI_DIR, 'dist', 'index.js');
|
|
775
|
+
|
|
776
|
+
if (isWindows()) {
|
|
777
|
+
const cmdShim = [
|
|
778
|
+
'@echo off',
|
|
779
|
+
`node "${quoteCmdPath(installedEntry)}" %*`,
|
|
780
|
+
'',
|
|
781
|
+
].join('\r\n');
|
|
782
|
+
const psShim = [
|
|
783
|
+
'$ErrorActionPreference = "Stop"',
|
|
784
|
+
`$entry = "${installedEntry.replace(/`/g, '``').replace(/"/g, '`"')}"`,
|
|
785
|
+
'& node $entry @args',
|
|
786
|
+
'exit $LASTEXITCODE',
|
|
787
|
+
'',
|
|
788
|
+
].join('\r\n');
|
|
789
|
+
writeFileSync(join(INSTALLED_BIN_DIR, 'pd.cmd'), cmdShim, 'utf-8');
|
|
790
|
+
writeFileSync(join(INSTALLED_BIN_DIR, 'pd.ps1'), psShim, 'utf-8');
|
|
791
|
+
} else {
|
|
792
|
+
const shShim = [
|
|
793
|
+
'#!/usr/bin/env sh',
|
|
794
|
+
`exec node "${installedEntry.replace(/"/g, '\\"')}" "$@"`,
|
|
795
|
+
'',
|
|
796
|
+
].join('\n');
|
|
797
|
+
const target = join(INSTALLED_BIN_DIR, 'pd');
|
|
798
|
+
writeFileSync(target, shShim, 'utf-8');
|
|
799
|
+
chmodSync(target, 0o755);
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
installGlobalPdShim();
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
function getNpmGlobalBinDir() {
|
|
806
|
+
try {
|
|
807
|
+
const prefix = execSync('npm prefix -g', { encoding: 'utf-8' }).trim();
|
|
808
|
+
if (!prefix) return null;
|
|
809
|
+
return process.platform === 'win32' ? prefix : join(prefix, 'bin');
|
|
810
|
+
} catch {
|
|
811
|
+
return null;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
function installGlobalPdShim() {
|
|
816
|
+
const globalBin = getNpmGlobalBinDir();
|
|
817
|
+
if (!globalBin) {
|
|
818
|
+
console.warn('⚠️ Could not resolve npm global bin directory. Use plugin-local bin/pd shim.');
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
try {
|
|
823
|
+
mkdirSync(globalBin, { recursive: true });
|
|
824
|
+
if (isWindows()) {
|
|
825
|
+
const pluginCmd = join(INSTALLED_BIN_DIR, 'pd.cmd');
|
|
826
|
+
const pluginPs = join(INSTALLED_BIN_DIR, 'pd.ps1');
|
|
827
|
+
writeFileSync(join(globalBin, 'pd.cmd'), `@echo off\r\ncall "${quoteCmdPath(pluginCmd)}" %*\r\n`, 'utf-8');
|
|
828
|
+
writeFileSync(
|
|
829
|
+
join(globalBin, 'pd.ps1'),
|
|
830
|
+
`$shim = "${pluginPs.replace(/`/g, '``').replace(/"/g, '`"')}"\r\n& $shim @args\r\nexit $LASTEXITCODE\r\n`,
|
|
831
|
+
'utf-8'
|
|
832
|
+
);
|
|
833
|
+
} else {
|
|
834
|
+
const pluginSh = join(INSTALLED_BIN_DIR, 'pd');
|
|
835
|
+
const globalSh = join(globalBin, 'pd');
|
|
836
|
+
writeFileSync(globalSh, `#!/usr/bin/env sh\nexec "${pluginSh.replace(/"/g, '\\"')}" "$@"\n`, 'utf-8');
|
|
837
|
+
chmodSync(globalSh, 0o755);
|
|
838
|
+
}
|
|
839
|
+
console.log(`✅ Global pd shim installed: ${globalBin}`);
|
|
840
|
+
} catch (err) {
|
|
841
|
+
console.warn(`⚠️ Could not install global pd shim: ${err.message}`);
|
|
842
|
+
console.warn(` Use plugin-local shim: ${join(INSTALLED_BIN_DIR, isWindows() ? 'pd.cmd' : 'pd')}`);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
function verifyPdCliShim() {
|
|
847
|
+
const localShim = join(INSTALLED_BIN_DIR, isWindows() ? 'pd.cmd' : 'pd');
|
|
848
|
+
try {
|
|
849
|
+
execSync(`"${localShim}" --version`, { stdio: 'pipe', shell: true });
|
|
850
|
+
console.log(`✅ PD CLI shim verified: ${localShim}`);
|
|
851
|
+
} catch (err) {
|
|
852
|
+
console.error(`❌ PD CLI shim verification failed: ${err.message}`);
|
|
853
|
+
process.exit(1);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
|
|
656
857
|
/**
|
|
657
858
|
* Recursive directory copy (Windows-safe, no symlinks).
|
|
658
859
|
*/
|
|
@@ -711,7 +912,7 @@ function injectLocalWorkspacePackages() {
|
|
|
711
912
|
function installTargetDependencies() {
|
|
712
913
|
console.log('\n📦 Installing production dependencies in target...');
|
|
713
914
|
try {
|
|
714
|
-
execSync('npm install --
|
|
915
|
+
execSync('npm install --omit=dev --no-audit --no-fund --prefer-offline', {
|
|
715
916
|
cwd: INSTALL_DIR,
|
|
716
917
|
stdio: 'inherit'
|
|
717
918
|
});
|
|
@@ -770,6 +971,35 @@ function getTempDir() {
|
|
|
770
971
|
return '/tmp';
|
|
771
972
|
}
|
|
772
973
|
|
|
974
|
+
/**
|
|
975
|
+
* Strip Anaconda/Miniconda entries from PATH on Windows.
|
|
976
|
+
*
|
|
977
|
+
* Anaconda ships an ancient cygpath (2016, at
|
|
978
|
+
* D:\ProgramData\anaconda3\Library\usr\bin\cygpath) that converts Unix-style
|
|
979
|
+
* paths INCORRECTLY in MINGW/MSYS — e.g. "/c/Users/..." becomes
|
|
980
|
+
* "D:\ProgramData\anaconda3\Library\c\Users\..." instead of "C:\Users\...".
|
|
981
|
+
* npm-installed CLI POSIX shims (openclaw, pd, etc.) call cygpath -w for path
|
|
982
|
+
* conversion and break when the wrong cygpath is found first in PATH.
|
|
983
|
+
*
|
|
984
|
+
* This does not affect schtasks (runs in a clean session) or PowerShell
|
|
985
|
+
* Start-Process (uses Split-Path, not cygpath). It protects the port check
|
|
986
|
+
* and error-recovery paths that execSync child processes.
|
|
987
|
+
*/
|
|
988
|
+
function sanitizePathForWindows() {
|
|
989
|
+
const pathSep = isWindows() ? ';' : ':';
|
|
990
|
+
const originalPath = process.env.PATH || '';
|
|
991
|
+
const entries = originalPath.split(pathSep).filter(Boolean);
|
|
992
|
+
const sanitized = entries.filter(entry => {
|
|
993
|
+
const lower = entry.toLowerCase().replace(/[/\\]/g, '/');
|
|
994
|
+
return !lower.includes('/anaconda') && !lower.includes('/conda') && !lower.includes('/miniconda');
|
|
995
|
+
});
|
|
996
|
+
if (sanitized.length !== entries.length) {
|
|
997
|
+
const removed = entries.length - sanitized.length;
|
|
998
|
+
process.env.PATH = sanitized.join(pathSep);
|
|
999
|
+
console.log(` 🧹 Sanitized PATH: removed ${removed} Anaconda/Conda entr${removed > 1 ? 'ies' : 'y'} (fixes cygpath bug on MINGW/MSYS)`);
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
|
|
773
1003
|
/**
|
|
774
1004
|
* Restart OpenClaw Gateway (cross-platform).
|
|
775
1005
|
*/
|
|
@@ -791,6 +1021,10 @@ function restartGateway() {
|
|
|
791
1021
|
function restartGatewayWindows() {
|
|
792
1022
|
const logPath = join(getTempDir(), 'openclaw-auto-restart.log');
|
|
793
1023
|
|
|
1024
|
+
// Strip Anaconda from PATH so any execSync child process (especially the
|
|
1025
|
+
// port-check Test-NetConnection shell) does not inherit poisoned cygpath.
|
|
1026
|
+
sanitizePathForWindows();
|
|
1027
|
+
|
|
794
1028
|
try {
|
|
795
1029
|
// Kill existing gateway processes first — taskkill fails across Windows sessions,
|
|
796
1030
|
// use WMIC which can terminate processes regardless of session boundary.
|
|
@@ -832,40 +1066,66 @@ function restartGatewayWindows() {
|
|
|
832
1066
|
|
|
833
1067
|
// Trigger via schtasks — reliable, avoids CLI busy-port misdetection
|
|
834
1068
|
console.log(' Starting gateway via scheduled task...');
|
|
835
|
-
|
|
1069
|
+
let gatewayStarted = false;
|
|
1070
|
+
try {
|
|
1071
|
+
execSync('schtasks /Run /TN "OpenClaw Gateway"', { stdio: 'pipe' });
|
|
1072
|
+
gatewayStarted = true;
|
|
1073
|
+
} catch {
|
|
1074
|
+
// schtasks failed — try direct CLI fallback via PowerShell
|
|
1075
|
+
// PowerShell shim resolves paths correctly in Anaconda environments
|
|
1076
|
+
// where cmd /c can produce wrong path prefixes (e.g. conda prefix + npm path)
|
|
1077
|
+
console.log(' Scheduled task not available, trying direct gateway start via PowerShell...');
|
|
1078
|
+
try {
|
|
1079
|
+
execSync(
|
|
1080
|
+
'powershell -NoProfile -Command "Start-Process -WindowStyle Hidden -FilePath \'openclaw\' -ArgumentList \'gateway\'"',
|
|
1081
|
+
{ stdio: 'pipe', timeout: 5000 }
|
|
1082
|
+
);
|
|
1083
|
+
gatewayStarted = true;
|
|
1084
|
+
} catch {
|
|
1085
|
+
// Gateway may already be running or no perms — not fatal
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
836
1088
|
|
|
837
1089
|
// Wait for gateway to be listening on port (同步等待,不异步)
|
|
838
1090
|
const port = 18789;
|
|
839
|
-
const deadline = Date.now() +
|
|
840
|
-
const pollInterval = 1000;
|
|
1091
|
+
const deadline = Date.now() + 60000; // Gateway 初始化可能需要 20+ 秒 (如 Windows schtasks 重启)
|
|
841
1092
|
let gatewayListening = false;
|
|
842
1093
|
|
|
843
1094
|
while (Date.now() < deadline) {
|
|
844
1095
|
try {
|
|
1096
|
+
// 使用 Test-NetConnection 替代有语法问题的 Get-NetTCPConnection + Measure-Object
|
|
845
1097
|
const result = execSync(
|
|
846
|
-
`powershell -NoProfile -Command "
|
|
1098
|
+
`powershell -NoProfile -Command "(Test-NetConnection -ComputerName localhost -Port ${port} -WarningAction SilentlyContinue).TcpTestSucceeded"`,
|
|
847
1099
|
{ encoding: 'utf-8', timeout: 5000 }
|
|
848
1100
|
).trim();
|
|
849
|
-
if (
|
|
1101
|
+
if (result === 'True') {
|
|
850
1102
|
gatewayListening = true;
|
|
851
1103
|
break;
|
|
852
1104
|
}
|
|
853
1105
|
} catch { /* port not listening yet */ }
|
|
854
|
-
|
|
1106
|
+
try {
|
|
1107
|
+
execSync('timeout /t 1 /nobreak > nul', { shell: true, stdio: 'ignore' });
|
|
1108
|
+
} catch { /* ignore */ }
|
|
855
1109
|
}
|
|
856
1110
|
|
|
857
1111
|
if (!gatewayListening) {
|
|
858
|
-
console.
|
|
859
|
-
console.
|
|
860
|
-
|
|
1112
|
+
console.warn('\n⚠️ Gateway may not be running on port 18789 (plugin files are installed).');
|
|
1113
|
+
console.warn(' If the gateway was started but is unreachable, try:');
|
|
1114
|
+
console.warn(' 1. From PowerShell: openclaw gateway start');
|
|
1115
|
+
console.warn(' 2. If using Git Bash, strip Anaconda from PATH first:');
|
|
1116
|
+
console.warn(' PATH=$(echo "$PATH" | tr ":" "\\n" | grep -iv anaconda | tr "\\n" ":") openclaw gateway start');
|
|
1117
|
+
return false;
|
|
861
1118
|
}
|
|
862
1119
|
|
|
863
1120
|
console.log(' ✅ Gateway is listening on port 18789');
|
|
1121
|
+
return true;
|
|
864
1122
|
|
|
865
1123
|
} catch (error) {
|
|
866
|
-
console.
|
|
867
|
-
console.
|
|
868
|
-
|
|
1124
|
+
console.warn(`\n⚠️ Gateway restart failed: ${error.message}`);
|
|
1125
|
+
console.warn(' Plugin files are installed. Run "openclaw gateway start" manually.');
|
|
1126
|
+
console.warn(' If using Git Bash with Anaconda in PATH, first run:');
|
|
1127
|
+
console.warn(' export PATH=$(echo "$PATH" | tr ":" "\\n" | grep -iv anaconda | tr "\\n" ":")');
|
|
1128
|
+
return false;
|
|
869
1129
|
}
|
|
870
1130
|
}
|
|
871
1131
|
|
|
@@ -906,7 +1166,7 @@ function restartGatewayLinux() {
|
|
|
906
1166
|
console.warn(`⚠️ Post-restart verification skipped: ${e.message}`);
|
|
907
1167
|
}
|
|
908
1168
|
}, 8000);
|
|
909
|
-
return;
|
|
1169
|
+
return true; // systemctl restart triggered successfully
|
|
910
1170
|
} catch { /* systemctl not available, fall through to manual restart */ }
|
|
911
1171
|
|
|
912
1172
|
// Manual process management
|
|
@@ -919,22 +1179,29 @@ function restartGatewayLinux() {
|
|
|
919
1179
|
|
|
920
1180
|
console.log(` Starting new gateway (logs: ${logPath})...`);
|
|
921
1181
|
execSync(`nohup openclaw gateway --force > ${logPath} 2>&1 &`, { stdio: 'ignore' });
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
1182
|
+
|
|
1183
|
+
// Wait for process to actually start (up to 15s)
|
|
1184
|
+
const deadline = Date.now() + 15000;
|
|
1185
|
+
while (Date.now() < deadline) {
|
|
1186
|
+
try {
|
|
1187
|
+
const running = execSync(
|
|
1188
|
+
'pgrep -f "openclaw-gateway|openclaw gateway"',
|
|
1189
|
+
{ encoding: 'utf-8', stdio: 'pipe' }
|
|
1190
|
+
).trim();
|
|
1191
|
+
if (running) {
|
|
1192
|
+
console.log('✅ Gateway restart triggered.');
|
|
1193
|
+
return true;
|
|
932
1194
|
}
|
|
933
|
-
}
|
|
934
|
-
|
|
1195
|
+
} catch { /* not ready yet */ }
|
|
1196
|
+
execSync('sleep 1');
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
console.error(`❌ Gateway did not come back up. Check ${logPath}`);
|
|
1200
|
+
return false;
|
|
1201
|
+
|
|
935
1202
|
} catch (error) {
|
|
936
1203
|
console.error(`\n❌ Failed to restart gateway: ${error.message}`);
|
|
937
|
-
|
|
1204
|
+
return false;
|
|
938
1205
|
}
|
|
939
1206
|
}
|
|
940
1207
|
|
|
@@ -968,16 +1235,41 @@ function main() {
|
|
|
968
1235
|
|
|
969
1236
|
if (!args.skipDeps) installDependencies();
|
|
970
1237
|
|
|
971
|
-
|
|
1238
|
+
if (!args.skipBuild) {
|
|
1239
|
+
buildPlugin();
|
|
1240
|
+
buildPdCli();
|
|
1241
|
+
} else {
|
|
1242
|
+
console.log('\n⏭️ Skipping build step (--skip-build)');
|
|
1243
|
+
}
|
|
972
1244
|
cleanTargetDir(args.force);
|
|
973
1245
|
ensureInstallDir();
|
|
974
1246
|
|
|
975
1247
|
console.log('\n📦 Syncing files to OpenClaw...');
|
|
976
1248
|
for (const item of SYNC_ITEMS) syncItem(item);
|
|
977
|
-
|
|
1249
|
+
|
|
1250
|
+
// After syncing templates, remove the non-selected language to avoid
|
|
1251
|
+
// waste on disk. OpenClaw only loads skills declared in the filtered
|
|
1252
|
+
// manifest (syncFilteredManifest), but having unselected lang files on
|
|
1253
|
+
// disk inflates the install footprint and confuses inspection.
|
|
1254
|
+
{
|
|
1255
|
+
const langsDir = join(INSTALL_DIR, 'templates', 'langs');
|
|
1256
|
+
if (existsSync(langsDir)) {
|
|
1257
|
+
const normalizedLang = (args.lang || 'zh').toLowerCase();
|
|
1258
|
+
const unselectedLang = normalizedLang === 'zh' ? 'en' : 'zh';
|
|
1259
|
+
const unselectedPath = join(langsDir, unselectedLang);
|
|
1260
|
+
if (existsSync(unselectedPath)) {
|
|
1261
|
+
rmSync(unselectedPath, { recursive: true, force: true });
|
|
1262
|
+
console.log(` 🗑️ removed templates/langs/${unselectedLang} (lang: ${normalizedLang})`);
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
syncFilteredManifest(args.lang);
|
|
1268
|
+
syncPdCli();
|
|
978
1269
|
|
|
979
1270
|
injectLocalWorkspacePackages();
|
|
980
1271
|
installTargetDependencies();
|
|
1272
|
+
verifyPdCliShim();
|
|
981
1273
|
|
|
982
1274
|
console.log('\n🔍 Verifying installed plugin can load native dependencies...');
|
|
983
1275
|
try {
|
|
@@ -1040,7 +1332,20 @@ function main() {
|
|
|
1040
1332
|
console.log('╚════════════════════════════════════════════════════════════╝');
|
|
1041
1333
|
|
|
1042
1334
|
if (args.restart) {
|
|
1043
|
-
restartGateway();
|
|
1335
|
+
const restarted = restartGateway();
|
|
1336
|
+
if (!restarted) {
|
|
1337
|
+
console.warn('\n⚠️ Plugin files installed but gateway restart was not confirmed.');
|
|
1338
|
+
console.warn(' The gateway may already be running. Verify with:');
|
|
1339
|
+
console.warn(' PowerShell: openclaw gateway status');
|
|
1340
|
+
console.warn(' Git Bash: Test-NetConnection -ComputerName localhost -Port 18789');
|
|
1341
|
+
console.warn('');
|
|
1342
|
+
console.warn(' If "openclaw gateway start" fails with a path error on Git Bash:');
|
|
1343
|
+
console.warn(' this is caused by Anaconda\'s old cygpath tool polluting PATH.');
|
|
1344
|
+
console.warn(' Run: export PATH=$(echo "$PATH" | tr ":" "\\n" | grep -iv anaconda | tr "\\n" ":")');
|
|
1345
|
+
console.warn(' Then: openclaw gateway start');
|
|
1346
|
+
console.warn('');
|
|
1347
|
+
console.warn(' Or simply restart from PowerShell (not affected by the cygpath bug).');
|
|
1348
|
+
}
|
|
1044
1349
|
} else {
|
|
1045
1350
|
console.log('\n💡 Restart OpenClaw Gateway to load the new version.');
|
|
1046
1351
|
console.log(' (Plugin code changes require a full gateway restart)');
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
import type { Implementation, ImplementationLifecycleState } from '../types/principle-tree-schema.js';
|
|
21
21
|
import type { PluginCommandContext, PluginCommandResult } from '../openclaw-sdk.js';
|
|
22
22
|
import { resolvePluginCommandWorkspaceDir } from '../utils/workspace-resolver.js';
|
|
23
|
+
import { normalizeCommandArgs } from '../utils/io.js';
|
|
23
24
|
|
|
24
25
|
/**
|
|
25
26
|
* Get all implementations from the ledger.
|
|
@@ -49,7 +50,7 @@ export function handleArchiveImplCommand(ctx: PluginCommandContext): PluginComma
|
|
|
49
50
|
const lang = (ctx.config?.language as string) || 'en';
|
|
50
51
|
const isZh = lang === 'zh';
|
|
51
52
|
|
|
52
|
-
const args = (ctx.args
|
|
53
|
+
const args = normalizeCommandArgs(ctx.args).trim().split(/\s+/);
|
|
53
54
|
const subcommand = args[0] || '';
|
|
54
55
|
|
|
55
56
|
// Subcommand: list
|
|
@@ -3,7 +3,7 @@ import * as fs from 'fs';
|
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import type { PluginCommandContext, PluginCommandResult } from '../openclaw-sdk.js';
|
|
5
5
|
import { WorkspaceContext } from '../core/workspace-context.js';
|
|
6
|
-
import { atomicWriteFileSync } from '../utils/io.js';
|
|
6
|
+
import { atomicWriteFileSync, normalizeCommandArgs } from '../utils/io.js';
|
|
7
7
|
import { resolvePluginCommandWorkspaceDir } from '../utils/workspace-resolver.js';
|
|
8
8
|
|
|
9
9
|
const TOOLS_TO_SCAN = [
|
|
@@ -75,7 +75,7 @@ export function handleBootstrapTools(ctx: PluginCommandContext): PluginCommandRe
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
export function handleResearchTools(ctx: PluginCommandContext): PluginCommandResult {
|
|
78
|
-
const category = ctx.args
|
|
78
|
+
const category = normalizeCommandArgs(ctx.args).trim() || "modern high-performance CLI tools for coding and architecture";
|
|
79
79
|
|
|
80
80
|
return {
|
|
81
81
|
text:
|